Forráskód Böngészése

feat(api-docs): replace swagger-ui with scalar api reference

Replaced the static Swagger UI React component with dynamic Scalar API Reference
for improved API documentation experience. The new implementation loads the
Scalar reference dynamically via CDN and supports auto-generated OpenAPI
specification from `/api/openapi.json`.

- Removed swagger-ui-react and swagger-jsdoc dependencies
- Added @scalar/api-reference-react and @scalar/nextjs-api-reference packages
- Updated Next.js to latest version (15.4.1)
- Simplified API docs page with dynamic script loading
- Enhanced UI with modern Scalar design system
vidane 6 hónapja
szülő
commit
b5c7126a95
3 módosított fájl, 633 hozzáadás és 370 törlés
  1. 24 221
      app/api-docs/page.tsx
  2. 605 144
      package-lock.json
  3. 4 5
      package.json

+ 24 - 221
app/api-docs/page.tsx

@@ -1,227 +1,25 @@
 'use client';
 
-import SwaggerUI from 'swagger-ui-react';
-import 'swagger-ui-react/swagger-ui.css';
+import { useEffect } from 'react';
 
 export default function ApiDocs() {
-  const spec = {
-    openapi: '3.0.0',
-    info: {
-      title: 'Vtorio API',
-      version: '1.0.0',
-      description: 'File upload and management API for Vtorio application',
-    },
-    servers: [
-      {
-        url: process.env.NODE_ENV === 'production' 
-          ? 'https://your-domain.com' 
-          : 'http://localhost:3000',
-        description: process.env.NODE_ENV === 'production' ? 'Production server' : 'Development server',
-      },
-    ],
-    paths: {
-      '/api/upload': {
-        post: {
-          summary: 'Upload a file',
-          description: 'Upload a file to the server and store it in the database',
-          tags: ['Files'],
-          requestBody: {
-            required: true,
-            content: {
-              'multipart/form-data': {
-                schema: {
-                  type: 'object',
-                  properties: {
-                    file: {
-                      type: 'string',
-                      format: 'binary',
-                      description: 'The file to upload',
-                    },
-                  },
-                  required: ['file'],
-                },
-              },
-            },
-          },
-          responses: {
-            '200': {
-              description: 'File uploaded successfully',
-              content: {
-                'application/json': {
-                  schema: {
-                    type: 'object',
-                    properties: {
-                      success: { type: 'boolean', example: true },
-                      file: {
-                        type: 'object',
-                        properties: {
-                          id: { type: 'string', example: 'clh123abc456' },
-                          filename: { type: 'string', example: 'document.pdf' },
-                          mimetype: { type: 'string', example: 'application/pdf' },
-                          size: { type: 'number', example: 1024000 },
-                          createdAt: { type: 'string', format: 'date-time' },
-                        },
-                      },
-                    },
-                  },
-                },
-              },
-            },
-            '400': {
-              description: 'Bad request - No file provided',
-              content: {
-                'application/json': {
-                  schema: {
-                    type: 'object',
-                    properties: {
-                      success: { type: 'boolean', example: false },
-                      error: { type: 'string', example: 'No file provided' },
-                    },
-                  },
-                },
-              },
-            },
-            '500': {
-              description: 'Internal server error',
-              content: {
-                'application/json': {
-                  schema: {
-                    type: 'object',
-                    properties: {
-                      success: { type: 'boolean', example: false },
-                      error: { type: 'string', example: 'Failed to upload file' },
-                    },
-                  },
-                },
-              },
-            },
-          },
-        },
-      },
-      '/api/files': {
-        get: {
-          summary: 'List all files',
-          description: 'Get a list of all uploaded files with metadata',
-          tags: ['Files'],
-          responses: {
-            '200': {
-              description: 'List of files retrieved successfully',
-              content: {
-                'application/json': {
-                  schema: {
-                    type: 'object',
-                    properties: {
-                      success: { type: 'boolean', example: true },
-                      files: {
-                        type: 'array',
-                        items: {
-                          type: 'object',
-                          properties: {
-                            id: { type: 'string', example: 'clh123abc456' },
-                            filename: { type: 'string', example: 'document.pdf' },
-                            mimetype: { type: 'string', example: 'application/pdf' },
-                            size: { type: 'number', example: 1024000 },
-                            createdAt: { type: 'string', format: 'date-time' },
-                            updatedAt: { type: 'string', format: 'date-time' },
-                          },
-                        },
-                      },
-                    },
-                  },
-                },
-              },
-            },
-            '500': {
-              description: 'Internal server error',
-              content: {
-                'application/json': {
-                  schema: {
-                    type: 'object',
-                    properties: {
-                      success: { type: 'boolean', example: false },
-                      error: { type: 'string', example: 'Failed to list files' },
-                    },
-                  },
-                },
-              },
-            },
-          },
-        },
-      },
-      '/api/files/{id}': {
-        get: {
-          summary: 'Download a file',
-          description: 'Download a specific file by its ID',
-          tags: ['Files'],
-          parameters: [
-            {
-              name: 'id',
-              in: 'path',
-              required: true,
-              description: 'The ID of the file to download',
-              schema: {
-                type: 'string',
-                example: 'clh123abc456',
-              },
-            },
-          ],
-          responses: {
-            '200': {
-              description: 'File downloaded successfully',
-              content: {
-                'application/octet-stream': {
-                  schema: {
-                    type: 'string',
-                    format: 'binary',
-                  },
-                },
-              },
-              headers: {
-                'Content-Type': {
-                  description: 'MIME type of the file',
-                  schema: { type: 'string' },
-                },
-                'Content-Disposition': {
-                  description: 'Attachment header with filename',
-                  schema: { type: 'string' },
-                },
-                'Content-Length': {
-                  description: 'Size of the file in bytes',
-                  schema: { type: 'integer' },
-                },
-              },
-            },
-            '404': {
-              description: 'File not found',
-              content: {
-                'application/json': {
-                  schema: {
-                    type: 'object',
-                    properties: {
-                      error: { type: 'string', example: 'File not found' },
-                    },
-                  },
-                },
-              },
-            },
-            '500': {
-              description: 'Internal server error',
-              content: {
-                'application/json': {
-                  schema: {
-                    type: 'object',
-                    properties: {
-                      error: { type: 'string', example: 'Failed to retrieve file' },
-                    },
-                  },
-                },
-              },
-            },
-          },
-        },
-      },
-    },
-  };
+  useEffect(() => {
+    // Load Scalar API Reference dynamically
+    const script = document.createElement('script');
+    script.src = 'https://cdn.jsdelivr.net/npm/@scalar/api-reference@latest/dist/browser/standalone.js';
+    script.async = true;
+    document.body.appendChild(script);
+
+    const style = document.createElement('link');
+    style.rel = 'stylesheet';
+    style.href = 'https://cdn.jsdelivr.net/npm/@scalar/api-reference@latest/dist/browser/style.css';
+    document.head.appendChild(style);
+
+    return () => {
+      document.body.removeChild(script);
+      document.head.removeChild(style);
+    };
+  }, []);
 
   return (
     <div className="min-h-screen bg-gray-50">
@@ -234,7 +32,12 @@ export default function ApiDocs() {
             <p className="text-gray-600 mb-6">
               Interactive API documentation for file upload and management endpoints.
             </p>
-            <SwaggerUI spec={spec} />
+            <div 
+              id="api-reference"
+              data-url="/api/openapi.json"
+              data-theme="default"
+              style={{ height: 'calc(100vh - 200px)' }}
+            />
           </div>
         </div>
       </div>

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 605 - 144
package-lock.json


+ 4 - 5
package.json

@@ -10,14 +10,13 @@
   },
   "dependencies": {
     "@prisma/client": "^6.11.1",
-    "@types/swagger-ui-react": "^5.18.0",
-    "next": "15.1.6",
+    "@scalar/api-reference-react": "^0.7.33",
+    "@scalar/nextjs-api-reference": "^0.8.12",
+    "next": "^15.4.1",
     "pg": "^8.16.3",
     "prisma": "^6.11.1",
     "react": "^19.0.0",
-    "react-dom": "^19.0.0",
-    "swagger-jsdoc": "^6.2.8",
-    "swagger-ui-react": "^5.26.2"
+    "react-dom": "^19.0.0"
   },
   "devDependencies": {
     "@eslint/eslintrc": "^3",

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott