sync
;
This commit is contained in:
		
							parent
							
								
									3cd7496989
								
							
						
					
					
						commit
						fbe6f866d9
					
				
					 9 changed files with 933 additions and 19 deletions
				
			
		|  | @ -25,6 +25,7 @@ | ||||||
|         "js-yaml": "^4.1.0", |         "js-yaml": "^4.1.0", | ||||||
|         "loki-logger-ts": "^1.0.2", |         "loki-logger-ts": "^1.0.2", | ||||||
|         "response-time": "^2.3.3", |         "response-time": "^2.3.3", | ||||||
|  |         "swagger-ui-express": "^5.0.1", | ||||||
|         "uuid": "^11.1.0", |         "uuid": "^11.1.0", | ||||||
|         "winston": "^3.17.0", |         "winston": "^3.17.0", | ||||||
|         "winston-loki": "^6.1.3" |         "winston-loki": "^6.1.3" | ||||||
|  | @ -34,6 +35,7 @@ | ||||||
|         "@types/express": "^5.0.0", |         "@types/express": "^5.0.0", | ||||||
|         "@types/node": "^22.13.4", |         "@types/node": "^22.13.4", | ||||||
|         "@types/response-time": "^2.3.8", |         "@types/response-time": "^2.3.8", | ||||||
|  |         "@types/swagger-ui-express": "^4.1.8", | ||||||
|         "globals": "^15.15.0", |         "globals": "^15.15.0", | ||||||
|         "ts-node": "^10.9.2", |         "ts-node": "^10.9.2", | ||||||
|         "tsx": "^4.19.3", |         "tsx": "^4.19.3", | ||||||
|  |  | ||||||
|  | @ -16,6 +16,8 @@ import { getLogger, Logger } from './logging/initalize.js'; | ||||||
| import { responseTimeLogger } from './logging/responseTimeLogger.js'; | import { responseTimeLogger } from './logging/responseTimeLogger.js'; | ||||||
| import responseTime from 'response-time'; | import responseTime from 'response-time'; | ||||||
| import { EnvVars, getNumericEnvVar } from './util/envvars.js'; | import { EnvVars, getNumericEnvVar } from './util/envvars.js'; | ||||||
|  | import swaggerMiddleware from "./swagger"; | ||||||
|  | import swaggerUi from "swagger-ui-express"; | ||||||
| 
 | 
 | ||||||
| const logger: Logger = getLogger(); | const logger: Logger = getLogger(); | ||||||
| 
 | 
 | ||||||
|  | @ -23,7 +25,6 @@ const app: Express = express(); | ||||||
| const port: string | number = getNumericEnvVar(EnvVars.Port); | const port: string | number = getNumericEnvVar(EnvVars.Port); | ||||||
| 
 | 
 | ||||||
| app.use(express.json()); | app.use(express.json()); | ||||||
| app.use(responseTime(responseTimeLogger)); |  | ||||||
| 
 | 
 | ||||||
| // TODO Replace with Express routes
 | // TODO Replace with Express routes
 | ||||||
| app.get('/', (_, res: Response) => { | app.get('/', (_, res: Response) => { | ||||||
|  | @ -33,17 +34,24 @@ app.get('/', (_, res: Response) => { | ||||||
|     }); |     }); | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| app.use('/student', studentRouter); | // Routes
 | ||||||
| app.use('/group', groupRouter); | app.use('/student', studentRouter /* #swagger.tags = ['Student'] */); | ||||||
| app.use('/assignment', assignmentRouter); | app.use('/group', groupRouter /* #swagger.tags = ['Group'] */); | ||||||
| app.use('/submission', submissionRouter); | app.use('/assignment', assignmentRouter /* #swagger.tags = ['Assignment'] */); | ||||||
| app.use('/class', classRouter); | app.use('/submission', submissionRouter /* #swagger.tags = ['Submission'] */); | ||||||
| app.use('/question', questionRouter); | app.use('/class', classRouter /* #swagger.tags = ['Class'] */); | ||||||
| app.use('/login', loginRouter); | app.use('/question', questionRouter /* #swagger.tags = ['Question'] */); | ||||||
|  | app.use('/login', loginRouter /* #swagger.tags = ['Login'] */); | ||||||
| 
 | 
 | ||||||
| app.use('/theme', themeRoutes); | app.use('/theme', themeRoutes /* #swagger.tags = ['Theme'] */); | ||||||
| app.use('/learningPath', learningPathRoutes); | app.use('/learningPath', learningPathRoutes /* #swagger.tags = ['Learning Path'] */); | ||||||
| app.use('/learningObject', learningObjectRoutes); | app.use('/learningObject', learningObjectRoutes /* #swagger.tags = ['Learning Object'] */); | ||||||
|  | 
 | ||||||
|  | // Add response time loggin
 | ||||||
|  | app.use(responseTime(responseTimeLogger)); | ||||||
|  | 
 | ||||||
|  | // Swagger UI for API documentation
 | ||||||
|  | app.use('/api-docs', swaggerUi.serve, swaggerMiddleware); | ||||||
| 
 | 
 | ||||||
| async function startServer() { | async function startServer() { | ||||||
|     await initORM(); |     await initORM(); | ||||||
|  |  | ||||||
							
								
								
									
										11
									
								
								backend/src/swagger.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								backend/src/swagger.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | ||||||
|  | import { RequestHandler } from 'express'; | ||||||
|  | import swaggerUi from 'swagger-ui-express'; | ||||||
|  | import swaggerDocument from '../../docs/api/swagger.json'; | ||||||
|  | 
 | ||||||
|  | const swaggerOptions = { | ||||||
|  |     explorer: true | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const swaggerMiddleware: RequestHandler = swaggerUi.setup(swaggerDocument, swaggerOptions); | ||||||
|  | 
 | ||||||
|  | export default swaggerMiddleware; | ||||||
|  | @ -3,6 +3,7 @@ | ||||||
|     "include": ["src/**/*.ts"], |     "include": ["src/**/*.ts"], | ||||||
|     "compilerOptions": { |     "compilerOptions": { | ||||||
|         "rootDir": "./src", |         "rootDir": "./src", | ||||||
|         "outDir": "./dist" |         "outDir": "./dist", | ||||||
|  |         "resolveJsonModule": true | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										28
									
								
								docs/api/generate.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								docs/api/generate.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,28 @@ | ||||||
|  | import swaggerAutogen from "swagger-autogen"; | ||||||
|  | 
 | ||||||
|  | const doc = { | ||||||
|  |     info: { | ||||||
|  |         version: '0.1.0', | ||||||
|  |         title: 'Dwengo-1 Backend API', | ||||||
|  |         description: 'Dwengo-1 Backend API using Express, based on VZW Dwengo', | ||||||
|  |         license: { | ||||||
|  |             name: 'MIT', | ||||||
|  |             url: 'https://github.com/SELab-2/Dwengo-1/blob/336496ab6352ee3f8bf47490c90b5cf81526cef6/LICENSE' | ||||||
|  |         } | ||||||
|  |     }, | ||||||
|  |     servers: [ | ||||||
|  |         { | ||||||
|  |             url: 'http://localhost:3000/', | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             url: 'https://sel2-1.ugent.be/api' | ||||||
|  |         } | ||||||
|  |     ] | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const outputFile = './swagger.json'; | ||||||
|  | const routes = [ | ||||||
|  |     '../../backend/src/app.ts' | ||||||
|  | ]; | ||||||
|  | 
 | ||||||
|  | swaggerAutogen({ openapi: '3.1.0' })(outputFile, routes, doc); | ||||||
							
								
								
									
										712
									
								
								docs/api/swagger.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										712
									
								
								docs/api/swagger.json
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,712 @@ | ||||||
|  | { | ||||||
|  |   "openapi": "3.1.0", | ||||||
|  |   "info": { | ||||||
|  |     "version": "0.1.0", | ||||||
|  |     "title": "Dwengo-1 Backend API", | ||||||
|  |     "description": "Dwengo-1 Backend API using Express, based on VZW Dwengo", | ||||||
|  |     "license": { | ||||||
|  |       "name": "MIT", | ||||||
|  |       "url": "https://github.com/SELab-2/Dwengo-1/blob/336496ab6352ee3f8bf47490c90b5cf81526cef6/LICENSE" | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   "servers": [ | ||||||
|  |     { | ||||||
|  |       "url": "http://localhost:3000/" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "url": "https://sel2-1.ugent.be/api" | ||||||
|  |     } | ||||||
|  |   ], | ||||||
|  |   "paths": { | ||||||
|  |     "/": { | ||||||
|  |       "get": { | ||||||
|  |         "description": "", | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/student/": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Student" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/student/{id}": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Student" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "parameters": [ | ||||||
|  |           { | ||||||
|  |             "name": "id", | ||||||
|  |             "in": "path", | ||||||
|  |             "required": true, | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/student/{id}/classes": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Student" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "parameters": [ | ||||||
|  |           { | ||||||
|  |             "name": "id", | ||||||
|  |             "in": "path", | ||||||
|  |             "required": true, | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/student/{id}/submissions": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Student" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "parameters": [ | ||||||
|  |           { | ||||||
|  |             "name": "id", | ||||||
|  |             "in": "path", | ||||||
|  |             "required": true, | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/student/{id}/assignments": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Student" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "parameters": [ | ||||||
|  |           { | ||||||
|  |             "name": "id", | ||||||
|  |             "in": "path", | ||||||
|  |             "required": true, | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/student/{id}/groups": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Student" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "parameters": [ | ||||||
|  |           { | ||||||
|  |             "name": "id", | ||||||
|  |             "in": "path", | ||||||
|  |             "required": true, | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/group/": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Group" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/group/{id}": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Group" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "parameters": [ | ||||||
|  |           { | ||||||
|  |             "name": "id", | ||||||
|  |             "in": "path", | ||||||
|  |             "required": true, | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/group/{id}/question": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Group" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "parameters": [ | ||||||
|  |           { | ||||||
|  |             "name": "id", | ||||||
|  |             "in": "path", | ||||||
|  |             "required": true, | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/assignment/": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Assignment" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/assignment/{id}": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Assignment" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "parameters": [ | ||||||
|  |           { | ||||||
|  |             "name": "id", | ||||||
|  |             "in": "path", | ||||||
|  |             "required": true, | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/assignment/{id}/submissions": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Assignment" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "parameters": [ | ||||||
|  |           { | ||||||
|  |             "name": "id", | ||||||
|  |             "in": "path", | ||||||
|  |             "required": true, | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/assignment/{id}/groups": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Assignment" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "parameters": [ | ||||||
|  |           { | ||||||
|  |             "name": "id", | ||||||
|  |             "in": "path", | ||||||
|  |             "required": true, | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/assignment/{id}/questions": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Assignment" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "parameters": [ | ||||||
|  |           { | ||||||
|  |             "name": "id", | ||||||
|  |             "in": "path", | ||||||
|  |             "required": true, | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/submission/": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Submission" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/submission/{id}": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Submission" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "parameters": [ | ||||||
|  |           { | ||||||
|  |             "name": "id", | ||||||
|  |             "in": "path", | ||||||
|  |             "required": true, | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/class/": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Class" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/class/{id}": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Class" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "parameters": [ | ||||||
|  |           { | ||||||
|  |             "name": "id", | ||||||
|  |             "in": "path", | ||||||
|  |             "required": true, | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/class/{id}/invitations": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Class" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "parameters": [ | ||||||
|  |           { | ||||||
|  |             "name": "id", | ||||||
|  |             "in": "path", | ||||||
|  |             "required": true, | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/class/{id}/assignments": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Class" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "parameters": [ | ||||||
|  |           { | ||||||
|  |             "name": "id", | ||||||
|  |             "in": "path", | ||||||
|  |             "required": true, | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/class/{id}/students": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Class" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "parameters": [ | ||||||
|  |           { | ||||||
|  |             "name": "id", | ||||||
|  |             "in": "path", | ||||||
|  |             "required": true, | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/question/": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Question" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/question/{id}": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Question" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "parameters": [ | ||||||
|  |           { | ||||||
|  |             "name": "id", | ||||||
|  |             "in": "path", | ||||||
|  |             "required": true, | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/question/{id}/answers": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Question" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "parameters": [ | ||||||
|  |           { | ||||||
|  |             "name": "id", | ||||||
|  |             "in": "path", | ||||||
|  |             "required": true, | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/login/": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Login" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/theme/": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Theme" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "parameters": [ | ||||||
|  |           { | ||||||
|  |             "name": "language", | ||||||
|  |             "in": "query", | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/theme/{theme}": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Theme" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "parameters": [ | ||||||
|  |           { | ||||||
|  |             "name": "theme", | ||||||
|  |             "in": "path", | ||||||
|  |             "required": true, | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           }, | ||||||
|  |           "404": { | ||||||
|  |             "description": "Not Found" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/learningPath/": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Learning Path" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "parameters": [ | ||||||
|  |           { | ||||||
|  |             "name": "hruid", | ||||||
|  |             "in": "query", | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           }, | ||||||
|  |           { | ||||||
|  |             "name": "theme", | ||||||
|  |             "in": "query", | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           }, | ||||||
|  |           { | ||||||
|  |             "name": "search", | ||||||
|  |             "in": "query", | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           }, | ||||||
|  |           { | ||||||
|  |             "name": "language", | ||||||
|  |             "in": "query", | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           }, | ||||||
|  |           "404": { | ||||||
|  |             "description": "Not Found" | ||||||
|  |           }, | ||||||
|  |           "500": { | ||||||
|  |             "description": "Internal Server Error" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/learningObject/": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Learning Object" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "parameters": [ | ||||||
|  |           { | ||||||
|  |             "name": "hruid", | ||||||
|  |             "in": "query", | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           }, | ||||||
|  |           { | ||||||
|  |             "name": "full", | ||||||
|  |             "in": "query", | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           }, | ||||||
|  |           { | ||||||
|  |             "name": "language", | ||||||
|  |             "in": "query", | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           }, | ||||||
|  |           "400": { | ||||||
|  |             "description": "Bad Request" | ||||||
|  |           }, | ||||||
|  |           "500": { | ||||||
|  |             "description": "Internal Server Error" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "/learningObject/{hruid}": { | ||||||
|  |       "get": { | ||||||
|  |         "tags": [ | ||||||
|  |           "Learning Object" | ||||||
|  |         ], | ||||||
|  |         "description": "", | ||||||
|  |         "parameters": [ | ||||||
|  |           { | ||||||
|  |             "name": "hruid", | ||||||
|  |             "in": "path", | ||||||
|  |             "required": true, | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           }, | ||||||
|  |           { | ||||||
|  |             "name": "language", | ||||||
|  |             "in": "query", | ||||||
|  |             "schema": { | ||||||
|  |               "type": "string" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "description": "OK" | ||||||
|  |           }, | ||||||
|  |           "400": { | ||||||
|  |             "description": "Bad Request" | ||||||
|  |           }, | ||||||
|  |           "500": { | ||||||
|  |             "description": "Internal Server Error" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										14
									
								
								docs/package.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								docs/package.json
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | ||||||
|  | { | ||||||
|  |     "name": "dwengo-1-docs", | ||||||
|  |     "version": "0.0.1", | ||||||
|  |     "description": "Documentation for Dwengo-1", | ||||||
|  |     "private": true, | ||||||
|  |     "scripts": { | ||||||
|  |         "build": "npm run architecture && npm run swagger", | ||||||
|  |         "architecture": "python3 -m venv .venv && source .venv/bin/activate && pip install -r docs/requirements.txt && python docs/architecture/schema.py", | ||||||
|  |         "swagger": "tsx api/generate.ts" | ||||||
|  |     }, | ||||||
|  |     "devDependencies": { | ||||||
|  |         "swagger-autogen": "^2.23.7" | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										148
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										148
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							|  | @ -10,7 +10,8 @@ | ||||||
|             "license": "MIT", |             "license": "MIT", | ||||||
|             "workspaces": [ |             "workspaces": [ | ||||||
|                 "backend", |                 "backend", | ||||||
|                 "frontend" |                 "frontend", | ||||||
|  |                 "docs" | ||||||
|             ], |             ], | ||||||
|             "devDependencies": { |             "devDependencies": { | ||||||
|                 "@eslint/compat": "^1.2.6", |                 "@eslint/compat": "^1.2.6", | ||||||
|  | @ -39,6 +40,7 @@ | ||||||
|                 "js-yaml": "^4.1.0", |                 "js-yaml": "^4.1.0", | ||||||
|                 "loki-logger-ts": "^1.0.2", |                 "loki-logger-ts": "^1.0.2", | ||||||
|                 "response-time": "^2.3.3", |                 "response-time": "^2.3.3", | ||||||
|  |                 "swagger-ui-express": "^5.0.1", | ||||||
|                 "uuid": "^11.1.0", |                 "uuid": "^11.1.0", | ||||||
|                 "winston": "^3.17.0", |                 "winston": "^3.17.0", | ||||||
|                 "winston-loki": "^6.1.3" |                 "winston-loki": "^6.1.3" | ||||||
|  | @ -48,6 +50,7 @@ | ||||||
|                 "@types/express": "^5.0.0", |                 "@types/express": "^5.0.0", | ||||||
|                 "@types/node": "^22.13.4", |                 "@types/node": "^22.13.4", | ||||||
|                 "@types/response-time": "^2.3.8", |                 "@types/response-time": "^2.3.8", | ||||||
|  |                 "@types/swagger-ui-express": "^4.1.8", | ||||||
|                 "globals": "^15.15.0", |                 "globals": "^15.15.0", | ||||||
|                 "ts-node": "^10.9.2", |                 "ts-node": "^10.9.2", | ||||||
|                 "tsx": "^4.19.3", |                 "tsx": "^4.19.3", | ||||||
|  | @ -82,6 +85,13 @@ | ||||||
|                 "url": "https://github.com/sponsors/sindresorhus" |                 "url": "https://github.com/sponsors/sindresorhus" | ||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|  |         "docs": { | ||||||
|  |             "name": "dwengo-1-docs", | ||||||
|  |             "version": "0.0.1", | ||||||
|  |             "devDependencies": { | ||||||
|  |                 "swagger-autogen": "^2.23.7" | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|         "frontend": { |         "frontend": { | ||||||
|             "name": "dwengo-1-frontend", |             "name": "dwengo-1-frontend", | ||||||
|             "version": "0.0.1", |             "version": "0.0.1", | ||||||
|  | @ -1556,6 +1566,13 @@ | ||||||
|                 "linux" |                 "linux" | ||||||
|             ] |             ] | ||||||
|         }, |         }, | ||||||
|  |         "node_modules/@scarf/scarf": { | ||||||
|  |             "version": "1.4.0", | ||||||
|  |             "resolved": "https://registry.npmjs.org/@scarf/scarf/-/scarf-1.4.0.tgz", | ||||||
|  |             "integrity": "sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==", | ||||||
|  |             "hasInstallScript": true, | ||||||
|  |             "license": "Apache-2.0" | ||||||
|  |         }, | ||||||
|         "node_modules/@sec-ant/readable-stream": { |         "node_modules/@sec-ant/readable-stream": { | ||||||
|             "version": "0.4.1", |             "version": "0.4.1", | ||||||
|             "dev": true, |             "dev": true, | ||||||
|  | @ -1739,6 +1756,17 @@ | ||||||
|                 "@types/send": "*" |                 "@types/send": "*" | ||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|  |         "node_modules/@types/swagger-ui-express": { | ||||||
|  |             "version": "4.1.8", | ||||||
|  |             "resolved": "https://registry.npmjs.org/@types/swagger-ui-express/-/swagger-ui-express-4.1.8.tgz", | ||||||
|  |             "integrity": "sha512-AhZV8/EIreHFmBV5wAs0gzJUNq9JbbSXgJLQubCC0jtIo6prnI9MIRRxnU4MZX9RB9yXxF1V4R7jtLl/Wcj31g==", | ||||||
|  |             "dev": true, | ||||||
|  |             "license": "MIT", | ||||||
|  |             "dependencies": { | ||||||
|  |                 "@types/express": "*", | ||||||
|  |                 "@types/serve-static": "*" | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|         "node_modules/@types/tough-cookie": { |         "node_modules/@types/tough-cookie": { | ||||||
|             "version": "4.0.5", |             "version": "4.0.5", | ||||||
|             "dev": true, |             "dev": true, | ||||||
|  | @ -3300,6 +3328,16 @@ | ||||||
|             "dev": true, |             "dev": true, | ||||||
|             "license": "MIT" |             "license": "MIT" | ||||||
|         }, |         }, | ||||||
|  |         "node_modules/deepmerge": { | ||||||
|  |             "version": "4.3.1", | ||||||
|  |             "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", | ||||||
|  |             "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", | ||||||
|  |             "dev": true, | ||||||
|  |             "license": "MIT", | ||||||
|  |             "engines": { | ||||||
|  |                 "node": ">=0.10.0" | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|         "node_modules/default-browser": { |         "node_modules/default-browser": { | ||||||
|             "version": "5.2.1", |             "version": "5.2.1", | ||||||
|             "dev": true, |             "dev": true, | ||||||
|  | @ -3415,6 +3453,10 @@ | ||||||
|             "resolved": "backend", |             "resolved": "backend", | ||||||
|             "link": true |             "link": true | ||||||
|         }, |         }, | ||||||
|  |         "node_modules/dwengo-1-docs": { | ||||||
|  |             "resolved": "docs", | ||||||
|  |             "link": true | ||||||
|  |         }, | ||||||
|         "node_modules/dwengo-1-frontend": { |         "node_modules/dwengo-1-frontend": { | ||||||
|             "resolved": "frontend", |             "resolved": "frontend", | ||||||
|             "link": true |             "link": true | ||||||
|  | @ -4355,8 +4397,8 @@ | ||||||
|         }, |         }, | ||||||
|         "node_modules/fs.realpath": { |         "node_modules/fs.realpath": { | ||||||
|             "version": "1.0.0", |             "version": "1.0.0", | ||||||
|             "license": "ISC", |             "devOptional": true, | ||||||
|             "optional": true |             "license": "ISC" | ||||||
|         }, |         }, | ||||||
|         "node_modules/function-bind": { |         "node_modules/function-bind": { | ||||||
|             "version": "1.1.2", |             "version": "1.1.2", | ||||||
|  | @ -4806,8 +4848,8 @@ | ||||||
|         }, |         }, | ||||||
|         "node_modules/inflight": { |         "node_modules/inflight": { | ||||||
|             "version": "1.0.6", |             "version": "1.0.6", | ||||||
|  |             "devOptional": true, | ||||||
|             "license": "ISC", |             "license": "ISC", | ||||||
|             "optional": true, |  | ||||||
|             "dependencies": { |             "dependencies": { | ||||||
|                 "once": "^1.3.0", |                 "once": "^1.3.0", | ||||||
|                 "wrappy": "1" |                 "wrappy": "1" | ||||||
|  | @ -6230,8 +6272,8 @@ | ||||||
|         }, |         }, | ||||||
|         "node_modules/path-is-absolute": { |         "node_modules/path-is-absolute": { | ||||||
|             "version": "1.0.1", |             "version": "1.0.1", | ||||||
|  |             "devOptional": true, | ||||||
|             "license": "MIT", |             "license": "MIT", | ||||||
|             "optional": true, |  | ||||||
|             "engines": { |             "engines": { | ||||||
|                 "node": ">=0.10.0" |                 "node": ">=0.10.0" | ||||||
|             } |             } | ||||||
|  | @ -7649,6 +7691,102 @@ | ||||||
|             "version": "1.0.0", |             "version": "1.0.0", | ||||||
|             "dev": true |             "dev": true | ||||||
|         }, |         }, | ||||||
|  |         "node_modules/swagger-autogen": { | ||||||
|  |             "version": "2.23.7", | ||||||
|  |             "resolved": "https://registry.npmjs.org/swagger-autogen/-/swagger-autogen-2.23.7.tgz", | ||||||
|  |             "integrity": "sha512-vr7uRmuV0DCxWc0wokLJAwX3GwQFJ0jwN+AWk0hKxre2EZwusnkGSGdVFd82u7fQLgwSTnbWkxUL7HXuz5LTZQ==", | ||||||
|  |             "dev": true, | ||||||
|  |             "license": "MIT", | ||||||
|  |             "dependencies": { | ||||||
|  |                 "acorn": "^7.4.1", | ||||||
|  |                 "deepmerge": "^4.2.2", | ||||||
|  |                 "glob": "^7.1.7", | ||||||
|  |                 "json5": "^2.2.3" | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |         "node_modules/swagger-autogen/node_modules/acorn": { | ||||||
|  |             "version": "7.4.1", | ||||||
|  |             "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", | ||||||
|  |             "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", | ||||||
|  |             "dev": true, | ||||||
|  |             "license": "MIT", | ||||||
|  |             "bin": { | ||||||
|  |                 "acorn": "bin/acorn" | ||||||
|  |             }, | ||||||
|  |             "engines": { | ||||||
|  |                 "node": ">=0.4.0" | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |         "node_modules/swagger-autogen/node_modules/brace-expansion": { | ||||||
|  |             "version": "1.1.11", | ||||||
|  |             "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", | ||||||
|  |             "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", | ||||||
|  |             "dev": true, | ||||||
|  |             "license": "MIT", | ||||||
|  |             "dependencies": { | ||||||
|  |                 "balanced-match": "^1.0.0", | ||||||
|  |                 "concat-map": "0.0.1" | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |         "node_modules/swagger-autogen/node_modules/glob": { | ||||||
|  |             "version": "7.2.3", | ||||||
|  |             "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", | ||||||
|  |             "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", | ||||||
|  |             "deprecated": "Glob versions prior to v9 are no longer supported", | ||||||
|  |             "dev": true, | ||||||
|  |             "license": "ISC", | ||||||
|  |             "dependencies": { | ||||||
|  |                 "fs.realpath": "^1.0.0", | ||||||
|  |                 "inflight": "^1.0.4", | ||||||
|  |                 "inherits": "2", | ||||||
|  |                 "minimatch": "^3.1.1", | ||||||
|  |                 "once": "^1.3.0", | ||||||
|  |                 "path-is-absolute": "^1.0.0" | ||||||
|  |             }, | ||||||
|  |             "engines": { | ||||||
|  |                 "node": "*" | ||||||
|  |             }, | ||||||
|  |             "funding": { | ||||||
|  |                 "url": "https://github.com/sponsors/isaacs" | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |         "node_modules/swagger-autogen/node_modules/minimatch": { | ||||||
|  |             "version": "3.1.2", | ||||||
|  |             "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", | ||||||
|  |             "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", | ||||||
|  |             "dev": true, | ||||||
|  |             "license": "ISC", | ||||||
|  |             "dependencies": { | ||||||
|  |                 "brace-expansion": "^1.1.7" | ||||||
|  |             }, | ||||||
|  |             "engines": { | ||||||
|  |                 "node": "*" | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |         "node_modules/swagger-ui-dist": { | ||||||
|  |             "version": "5.20.0", | ||||||
|  |             "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.20.0.tgz", | ||||||
|  |             "integrity": "sha512-V5pozVTZxivdoQq/SQWxj3A4cOu5opk9MEbcZANX3Pj8X8xCrD1QCtBT7744Pz9msOvt0nnmy9JvM/9PGonCdg==", | ||||||
|  |             "license": "Apache-2.0", | ||||||
|  |             "dependencies": { | ||||||
|  |                 "@scarf/scarf": "=1.4.0" | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |         "node_modules/swagger-ui-express": { | ||||||
|  |             "version": "5.0.1", | ||||||
|  |             "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-5.0.1.tgz", | ||||||
|  |             "integrity": "sha512-SrNU3RiBGTLLmFU8GIJdOdanJTl4TOmT27tt3bWWHppqYmAZ6IDuEuBvMU6nZq0zLEe6b/1rACXCgLZqO6ZfrA==", | ||||||
|  |             "license": "MIT", | ||||||
|  |             "dependencies": { | ||||||
|  |                 "swagger-ui-dist": ">=5.0.0" | ||||||
|  |             }, | ||||||
|  |             "engines": { | ||||||
|  |                 "node": ">= v0.10.32" | ||||||
|  |             }, | ||||||
|  |             "peerDependencies": { | ||||||
|  |                 "express": ">=4.0.0 || >=5.0.0-beta" | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|         "node_modules/symbol-tree": { |         "node_modules/symbol-tree": { | ||||||
|             "version": "3.2.4", |             "version": "3.2.4", | ||||||
|             "dev": true, |             "dev": true, | ||||||
|  |  | ||||||
|  | @ -8,13 +8,13 @@ | ||||||
|         "build": "npm run build --ws", |         "build": "npm run build --ws", | ||||||
|         "format": "npm run format --ws", |         "format": "npm run format --ws", | ||||||
|         "format-check": "npm run format-check --ws", |         "format-check": "npm run format-check --ws", | ||||||
|         "generate-docs": "python3 -m venv .venv && source .venv/bin/activate && pip install -r docs/requirements.txt && python docs/architecture/schema.py", |  | ||||||
|         "lint": "npm run lint --ws", |         "lint": "npm run lint --ws", | ||||||
|         "test:unit": "npm run test:unit --ws" |         "test:unit": "npm run test:unit --ws" | ||||||
|     }, |     }, | ||||||
|     "workspaces": [ |     "workspaces": [ | ||||||
|         "backend", |         "backend", | ||||||
|         "frontend" |         "frontend", | ||||||
|  |         "docs" | ||||||
|     ], |     ], | ||||||
|     "repository": { |     "repository": { | ||||||
|         "type": "git", |         "type": "git", | ||||||
|  |  | ||||||
		Reference in a new issue