Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions apps/web/app/api-docs/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
'use client';

import { useEffect, useRef, useState } from 'react';

export default function ApiDocsPage() {
const containerRef = useRef<HTMLDivElement>(null);
const [isLoading, setIsLoading] = useState(true);

useEffect(() => {
let mounted = true;

// Dynamically load Swagger UI
const loadSwaggerUI = async () => {
if (!containerRef.current) return;

// Check if CSS is already loaded
const existingLink = document.querySelector(
'link[href*="swagger-ui.css"]'
);
if (!existingLink) {
// Load CSS from the installed package
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href =
'/_next/static/css/swagger-ui.css';
Comment on lines +24 to +25
Copy link

Copilot AI Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CSS file path /_next/static/css/swagger-ui.css appears to be incorrect. The swagger-ui-dist package provides CSS files that should be accessed through the node_modules path or copied to the public directory. Next.js won't automatically serve CSS from swagger-ui-dist at this path.

Consider using the CSS directly from the package using an import statement or copying the CSS file to the public directory and referencing it properly. For example:

import 'swagger-ui-dist/swagger-ui.css';

Or serve it from a public asset path if you copy swagger-ui.css from the package to your public directory.

Copilot uses AI. Check for mistakes.
document.head.appendChild(link);
}

try {
// Load and initialize Swagger UI
const SwaggerUIBundle = (
await import('swagger-ui-dist/swagger-ui-es-bundle.js')
).default;

if (mounted && containerRef.current) {
SwaggerUIBundle({
domNode: containerRef.current,
url: '/api/docs/openapi.json',
deepLinking: true,
});
setIsLoading(false);
}
} catch (error) {
console.error('Failed to load Swagger UI:', error);
setIsLoading(false);
Comment on lines +43 to +45
Copy link

Copilot AI Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handling logs to console but doesn't display an error message to the user. If Swagger UI fails to load, users will see the loading message disappear but get no indication of what went wrong.

Consider showing an error message to help users understand when the API documentation fails to load:

const [error, setError] = useState<string | null>(null);

// In catch block:
setError('Failed to load API documentation. Please refresh the page.');

// In JSX:
{error && <div className="text-red-600 p-8">{error}</div>}

Copilot uses AI. Check for mistakes.
}
};

loadSwaggerUI();

Check failure on line 49 in apps/web/app/api-docs/page.tsx

View workflow job for this annotation

GitHub Actions / lint

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator

return () => {
mounted = false;
};
}, []);

return (
<div className="min-h-screen bg-white">
{isLoading && (
<div className="flex items-center justify-center p-8">
<p>Loading API documentation...</p>
</div>
)}
<div ref={containerRef} />
<style jsx global>{`
/* Swagger UI CSS is loaded via the JS bundle */
Copy link

Copilot AI Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment on line 65 mentions "Swagger UI CSS is loaded via the JS bundle", but this is misleading. The CSS is actually being loaded dynamically by manually creating a link element (lines 22-26), not through the JS bundle import. The global styles defined here only add minor adjustments to the Swagger UI styling.

Consider updating the comment to be more accurate:

/* Additional styling adjustments for Swagger UI */
Suggested change
/* Swagger UI CSS is loaded via the JS bundle */
/* Additional styling adjustments for Swagger UI */

Copilot uses AI. Check for mistakes.
.swagger-ui .info {
margin: 50px 0;
}
`}</style>
</div>
);
}
6 changes: 6 additions & 0 deletions apps/web/app/api/docs/openapi.json/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { NextResponse } from 'next/server';
import { openApiDocument } from '@repo/api';

export async function GET() {

Check failure on line 4 in apps/web/app/api/docs/openapi.json/route.ts

View workflow job for this annotation

GitHub Actions / lint

Async function 'GET' has no 'await' expression
return NextResponse.json(openApiDocument);
}
1 change: 1 addition & 0 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"sonner": "^2.0.7",
"ssh2": "^1.17.0",
"superjson": "^2.2.5",
"swagger-ui-dist": "^5.30.3",
"tailwind-merge": "^3.4.0",
"tailwindcss": "^4.1.17",
"yaml": "^2.8.1",
Expand Down
1 change: 1 addition & 0 deletions packages/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@types/ssh2": "^1.15.5",
"bullmq": "^5.63.2",
"ioredis": "^5.8.2",
"openapi3-ts": "^4.5.0",
"pino": "^10.1.0",
"pino-pretty": "^13.1.2",
"ssh2": "^1.17.0",
Expand Down
1 change: 1 addition & 0 deletions packages/api/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { appRouter } from './root';
export type { AppRouter } from './root';
export { createContext } from './context';
export { openApiDocument } from './openapi';
Loading
Loading