Pārlūkot izejas kodu

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 mēneši atpakaļ
vecāks
revīzija
b5c7126a95
3 mainītis faili ar 633 papildinājumiem un 370 dzēšanām
  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>

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 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",

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels