@hamak/smart-data-dico 1.0.4 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/backend/dist/server.mjs +82213 -0
  2. package/bin/cli.js +28 -17
  3. package/package.json +28 -27
  4. package/backend/package.json +0 -51
  5. package/backend/src/__tests__/integration/api.test.ts +0 -149
  6. package/backend/src/__tests__/setup.ts +0 -24
  7. package/backend/src/__tests__/utils/testUtils.ts +0 -76
  8. package/backend/src/adapters/EntityFileAdapter.ts +0 -154
  9. package/backend/src/adapters/YamlFileInfoEnricher.ts +0 -52
  10. package/backend/src/controllers/authController.ts +0 -131
  11. package/backend/src/controllers/diagramController.ts +0 -143
  12. package/backend/src/controllers/dictionaryController.ts +0 -306
  13. package/backend/src/controllers/importExportController.ts +0 -64
  14. package/backend/src/controllers/perspectiveController.ts +0 -90
  15. package/backend/src/controllers/serviceController.ts +0 -418
  16. package/backend/src/controllers/stereotypeController.ts +0 -59
  17. package/backend/src/controllers/versionController.ts +0 -226
  18. package/backend/src/kernel/config.ts +0 -43
  19. package/backend/src/middleware/auth.ts +0 -128
  20. package/backend/src/middleware/jwtAuth.ts +0 -100
  21. package/backend/src/models/Dictionary.ts +0 -38
  22. package/backend/src/models/EntitySchema.ts +0 -393
  23. package/backend/src/models/__tests__/Dictionary.test.ts +0 -92
  24. package/backend/src/models/__tests__/EntitySchema.test.ts +0 -119
  25. package/backend/src/routes/index.ts +0 -120
  26. package/backend/src/scripts/migrate-to-uuid.ts +0 -24
  27. package/backend/src/server.ts +0 -158
  28. package/backend/src/services/__mocks__/entityService.ts +0 -38
  29. package/backend/src/services/__mocks__/serviceService.ts +0 -88
  30. package/backend/src/services/__mocks__/versionService.ts +0 -38
  31. package/backend/src/services/__tests__/dictionaryService.test.ts +0 -74
  32. package/backend/src/services/diagramService.ts +0 -165
  33. package/backend/src/services/dictionaryService.ts +0 -582
  34. package/backend/src/services/entityService.ts +0 -102
  35. package/backend/src/services/exportService.ts +0 -172
  36. package/backend/src/services/importService.ts +0 -208
  37. package/backend/src/services/perspectiveService.ts +0 -276
  38. package/backend/src/services/qualityService.ts +0 -121
  39. package/backend/src/services/serviceService.ts +0 -763
  40. package/backend/src/services/stereotypeService.ts +0 -98
  41. package/backend/src/services/versionService.ts +0 -135
  42. package/backend/src/setupTests.ts +0 -12
  43. package/backend/src/utils/__mocks__/fileOperations.ts +0 -116
  44. package/backend/src/utils/fileOperations.ts +0 -602
  45. package/backend/src/utils/logger.ts +0 -38
  46. package/backend/src/utils/migration.ts +0 -254
  47. package/backend/src/utils/swagger.ts +0 -358
  48. package/backend/src/utils/uuid.ts +0 -41
  49. package/backend/tsconfig.json +0 -20
@@ -1,131 +0,0 @@
1
- import { Request, Response } from 'express';
2
- import jwt, { SignOptions } from 'jsonwebtoken';
3
- import { logger } from '../utils/logger.js';
4
- import { User, UserRole } from '../middleware/auth.js';
5
-
6
- // Mock user database - imported from auth middleware
7
- // In a real application, this would be in a separate database module
8
- const users: Record<string, { password: string; user: User }> = {
9
- 'admin': {
10
- password: 'admin123',
11
- user: {
12
- id: '1',
13
- username: 'admin',
14
- role: UserRole.ADMIN
15
- }
16
- },
17
- 'editor': {
18
- password: 'editor123',
19
- user: {
20
- id: '2',
21
- username: 'editor',
22
- role: UserRole.EDITOR
23
- }
24
- },
25
- 'viewer': {
26
- password: 'viewer123',
27
- user: {
28
- id: '3',
29
- username: 'viewer',
30
- role: UserRole.VIEWER
31
- }
32
- }
33
- };
34
-
35
- // JWT secret key - should be in environment variables in production
36
- const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key';
37
- // Token expiration time (default: 24 hours)
38
- const TOKEN_EXPIRATION = process.env.TOKEN_EXPIRATION || '24h';
39
-
40
- /**
41
- * Login controller
42
- * Validates username and password, generates JWT token
43
- * @param req Express request
44
- * @param res Express response
45
- */
46
- export const login = (req: Request, res: Response) => {
47
- try {
48
- const { username, password } = req.body;
49
-
50
- // Validate request body
51
- if (!username || !password) {
52
- return res.status(400).json({
53
- message: 'Bad request',
54
- error: 'Username and password are required'
55
- });
56
- }
57
-
58
- // Validate credentials
59
- const userRecord = users[username];
60
-
61
- if (!userRecord || userRecord.password !== password) {
62
- logger.info(`Failed login attempt for user: ${username}`);
63
- return res.status(401).json({
64
- message: 'Authentication failed',
65
- error: 'Invalid username or password'
66
- });
67
- }
68
-
69
- // Generate JWT token
70
- const payload = {
71
- id: userRecord.user.id,
72
- username: userRecord.user.username,
73
- role: userRecord.user.role
74
- };
75
- const options: SignOptions = { expiresIn: TOKEN_EXPIRATION as any };
76
- const token = jwt.sign(payload, JWT_SECRET, options);
77
-
78
- logger.info(`User logged in: ${username}`);
79
-
80
- // Return token and user info
81
- return res.status(200).json({
82
- message: 'Authentication successful',
83
- token,
84
- user: {
85
- id: userRecord.user.id,
86
- username: userRecord.user.username,
87
- role: userRecord.user.role
88
- }
89
- });
90
- } catch (error: any) {
91
- logger.error(`Login error: ${error.message}`);
92
- return res.status(500).json({
93
- message: 'Internal server error',
94
- error: process.env.NODE_ENV === 'production' ? undefined : error.message
95
- });
96
- }
97
- };
98
-
99
- /**
100
- * Get current user controller
101
- * Returns user information based on JWT token
102
- * @param req Express request
103
- * @param res Express response
104
- */
105
- export const getCurrentUser = (req: Request, res: Response) => {
106
- try {
107
- // User should be attached to request by JWT middleware
108
- const user = (req as any).user;
109
-
110
- if (!user) {
111
- return res.status(401).json({
112
- message: 'Authentication required',
113
- error: 'User not authenticated'
114
- });
115
- }
116
-
117
- return res.status(200).json({
118
- user: {
119
- id: user.id,
120
- username: user.username,
121
- role: user.role
122
- }
123
- });
124
- } catch (error: any) {
125
- logger.error(`Get current user error: ${error.message}`);
126
- return res.status(500).json({
127
- message: 'Internal server error',
128
- error: process.env.NODE_ENV === 'production' ? undefined : error.message
129
- });
130
- }
131
- };
@@ -1,143 +0,0 @@
1
- import { Request, Response } from 'express';
2
- import { diagramService, DiagramLayout } from '../services/diagramService.js';
3
- import { logger } from '../utils/logger.js';
4
-
5
- export class DiagramController {
6
- async saveDiagramLayout(req: Request, res: Response): Promise<void> {
7
- try {
8
- const layoutData = req.body as Omit<DiagramLayout, 'createdAt' | 'updatedAt'>;
9
-
10
- if (!layoutData.id || !layoutData.name) {
11
- res.status(400).json({
12
- message: 'Missing required fields: id and name are required'
13
- });
14
- return;
15
- }
16
-
17
- const savedLayout = await diagramService.saveDiagramLayout(layoutData);
18
-
19
- res.status(201).json({
20
- message: 'Diagram layout saved successfully',
21
- data: savedLayout
22
- });
23
- } catch (error) {
24
- logger.error('Error in saveDiagramLayout:', error);
25
- res.status(500).json({
26
- message: 'Failed to save diagram layout',
27
- error: error instanceof Error ? error.message : 'Unknown error'
28
- });
29
- }
30
- }
31
-
32
- async loadDiagramLayout(req: Request, res: Response): Promise<void> {
33
- try {
34
- const { id } = req.params;
35
-
36
- if (!id) {
37
- res.status(400).json({
38
- message: 'Diagram layout ID is required'
39
- });
40
- return;
41
- }
42
-
43
- const layout = await diagramService.loadDiagramLayout(id);
44
-
45
- if (!layout) {
46
- res.status(404).json({
47
- message: 'Diagram layout not found'
48
- });
49
- return;
50
- }
51
-
52
- res.json({
53
- message: 'Diagram layout loaded successfully',
54
- data: layout
55
- });
56
- } catch (error) {
57
- logger.error('Error in loadDiagramLayout:', error);
58
- res.status(500).json({
59
- message: 'Failed to load diagram layout',
60
- error: error instanceof Error ? error.message : 'Unknown error'
61
- });
62
- }
63
- }
64
-
65
- async updateDiagramLayout(req: Request, res: Response): Promise<void> {
66
- try {
67
- const { id } = req.params;
68
- const updates = req.body;
69
-
70
- if (!id) {
71
- res.status(400).json({
72
- message: 'Diagram layout ID is required'
73
- });
74
- return;
75
- }
76
-
77
- const updatedLayout = await diagramService.updateDiagramLayout(id, updates);
78
-
79
- res.json({
80
- message: 'Diagram layout updated successfully',
81
- data: updatedLayout
82
- });
83
- } catch (error) {
84
- logger.error('Error in updateDiagramLayout:', error);
85
- if (error instanceof Error && error.message === 'Diagram layout not found') {
86
- res.status(404).json({
87
- message: 'Diagram layout not found'
88
- });
89
- } else {
90
- res.status(500).json({
91
- message: 'Failed to update diagram layout',
92
- error: error instanceof Error ? error.message : 'Unknown error'
93
- });
94
- }
95
- }
96
- }
97
-
98
- async deleteDiagramLayout(req: Request, res: Response): Promise<void> {
99
- try {
100
- const { id } = req.params;
101
-
102
- if (!id) {
103
- res.status(400).json({
104
- message: 'Diagram layout ID is required'
105
- });
106
- return;
107
- }
108
-
109
- await diagramService.deleteDiagramLayout(id);
110
-
111
- res.json({
112
- message: 'Diagram layout deleted successfully'
113
- });
114
- } catch (error) {
115
- logger.error('Error in deleteDiagramLayout:', error);
116
- res.status(500).json({
117
- message: 'Failed to delete diagram layout',
118
- error: error instanceof Error ? error.message : 'Unknown error'
119
- });
120
- }
121
- }
122
-
123
- async listDiagramLayouts(req: Request, res: Response): Promise<void> {
124
- try {
125
- const { service } = req.query;
126
-
127
- const layouts = await diagramService.listDiagramLayouts(service as string);
128
-
129
- res.json({
130
- message: 'Diagram layouts retrieved successfully',
131
- data: layouts
132
- });
133
- } catch (error) {
134
- logger.error('Error in listDiagramLayouts:', error);
135
- res.status(500).json({
136
- message: 'Failed to list diagram layouts',
137
- error: error instanceof Error ? error.message : 'Unknown error'
138
- });
139
- }
140
- }
141
- }
142
-
143
- export const diagramController = new DiagramController();
@@ -1,306 +0,0 @@
1
- import { Request, Response } from 'express';
2
-
3
- import { Dictionary } from '../models/Dictionary.js';
4
- import { Entity } from '../models/EntitySchema.js';
5
- import { dictionaryService } from '../services/dictionaryService.js';
6
- import { entityService } from '../services/entityService.js';
7
- import { logger } from '../utils/logger.js';
8
-
9
- // Dictionary controller methods
10
- export const getDictionaries = async (req: Request, res: Response) => {
11
- try {
12
- const dictionaries = await dictionaryService.getAllDictionaries();
13
- res.json({
14
- message: 'Success',
15
- data: dictionaries
16
- });
17
- } catch (error) {
18
- logger.error('Error fetching dictionaries', error);
19
- res.status(500).json({ message: 'Error fetching dictionaries', error });
20
- }
21
- };
22
-
23
- export const getDictionaryById = async (req: Request, res: Response) => {
24
- try {
25
- const { id } = req.params;
26
- const dictionary = await dictionaryService.getDictionaryById(id);
27
-
28
- if (!dictionary) {
29
- return res.status(404).json({ message: 'Dictionary not found' });
30
- }
31
-
32
- res.json({
33
- message: 'Success',
34
- data: dictionary
35
- });
36
- } catch (error) {
37
- logger.error(`Error fetching dictionary with ID: ${req.params.id}`, error);
38
- res.status(500).json({ message: 'Error fetching dictionary', error });
39
- }
40
- };
41
-
42
- export const getDictionaryEntries = async (req: Request, res: Response) => {
43
- try {
44
- const { id } = req.params;
45
- const entries = await dictionaryService.getDictionaryEntries(id);
46
-
47
- res.json({
48
- message: 'Success',
49
- data: entries
50
- });
51
- } catch (error) {
52
- logger.error(`Error in getDictionaryEntries: ${error}`);
53
- res.status(500).json({ message: 'Error fetching dictionary entries', error });
54
- }
55
- };
56
-
57
- export const getEntityAttributes = async (req: Request, res: Response) => {
58
- try {
59
- const { microservice, entityName } = req.params;
60
- const attributes = await dictionaryService.getEntityAttributes(microservice, entityName);
61
-
62
- if (attributes.length === 0) {
63
- return res.status(404).json({ message: 'Entity not found' });
64
- }
65
-
66
- res.json({
67
- message: 'Success',
68
- data: attributes
69
- });
70
- } catch (error) {
71
- logger.error(`Error in getEntityAttributes: ${error}`);
72
- res.status(500).json({ message: 'Error fetching entity attributes', error });
73
- }
74
- };
75
-
76
- export const saveEntity = async (req: Request, res: Response) => {
77
- try {
78
- const entity = req.body as Entity;
79
- const packageName = req.body.packageName || req.query.packageName as string;
80
-
81
- if (!entity) {
82
- return res.status(400).json({ message: 'Invalid entity data' });
83
- }
84
-
85
- if (!packageName) {
86
- return res.status(400).json({ message: 'packageName is required' });
87
- }
88
-
89
- const result = await entityService.saveEntity(entity, packageName);
90
-
91
- if (!result.success) {
92
- return res.status(400).json({
93
- message: 'Failed to save entity',
94
- errors: result.errors
95
- });
96
- }
97
-
98
- res.status(200).json({
99
- message: 'Entity saved successfully',
100
- data: entity
101
- });
102
- } catch (error) {
103
- logger.error(`Error in saveEntity: ${error}`);
104
- res.status(500).json({ message: 'Error saving entity', error });
105
- }
106
- };
107
-
108
- export const getRelatedEntities = async (req: Request, res: Response) => {
109
- try {
110
- const { microservice, entityName } = req.params;
111
- const relatedEntities = await entityService.getRelatedEntities(microservice, entityName);
112
-
113
- res.json({
114
- message: 'Success',
115
- data: relatedEntities
116
- });
117
- } catch (error) {
118
- logger.error(`Error in getRelatedEntities: ${error}`);
119
- res.status(500).json({ message: 'Error fetching related entities', error });
120
- }
121
- };
122
-
123
- export const createDictionary = async (req: Request, res: Response) => {
124
- try {
125
- const dictionaryData = req.body as Dictionary;
126
-
127
- if (!dictionaryData || !dictionaryData.name) {
128
- return res.status(400).json({ message: 'Dictionary name is required' });
129
- }
130
-
131
- const result = await dictionaryService.createDictionary(dictionaryData);
132
-
133
- if (result && 'error' in result) {
134
- if (result.code === 'DUPLICATE_NAME') {
135
- logger.warn(`Attempted to create dictionary with duplicate name: ${dictionaryData.name}`);
136
- return res.status(409).json({
137
- message: result.error,
138
- code: result.code
139
- });
140
- } else if (result.code === 'MISSING_NAME') {
141
- return res.status(400).json({
142
- message: result.error,
143
- code: result.code
144
- });
145
- } else {
146
- return res.status(400).json({
147
- message: result.error,
148
- code: result.code
149
- });
150
- }
151
- }
152
-
153
- if (!result) {
154
- return res.status(500).json({ message: 'Failed to create dictionary due to an unknown error' });
155
- }
156
-
157
- res.status(201).json({
158
- message: 'Dictionary created successfully',
159
- data: result
160
- });
161
- } catch (error) {
162
- logger.error(`Error in createDictionary: ${error}`);
163
- res.status(500).json({ message: 'Error creating dictionary', error });
164
- }
165
- };
166
-
167
- export const getPackageHierarchy = async (req: Request, res: Response) => {
168
- try {
169
- const { rootPackage } = req.params;
170
- const hierarchy = await dictionaryService.getPackageHierarchy(rootPackage);
171
- res.json({ message: 'Success', data: hierarchy });
172
- } catch (error) {
173
- logger.error('Error fetching package hierarchy', error);
174
- res.status(500).json({ message: 'Error fetching package hierarchy', error });
175
- }
176
- };
177
-
178
- export const getTabularData = async (req: Request, res: Response) => {
179
- try {
180
- const { rootPackage } = req.params;
181
- const tabularData = await dictionaryService.getTabularData(rootPackage);
182
- res.json({ message: 'Success', data: tabularData });
183
- } catch (error) {
184
- logger.error('Error fetching tabular data', error);
185
- res.status(500).json({ message: 'Error fetching tabular data', error });
186
- }
187
- };
188
-
189
- export const getPackageByPath = async (req: Request, res: Response) => {
190
- try {
191
- const { rootPackage } = req.params;
192
- const packagePath = req.params[0]?.split('/').filter(Boolean) || [];
193
- const pkg = await dictionaryService.getPackageByPath(rootPackage, packagePath);
194
- if (!pkg) {
195
- return res.status(404).json({ message: 'Package not found' });
196
- }
197
- res.json({ message: 'Success', data: pkg });
198
- } catch (error) {
199
- logger.error('Error fetching package by path', error);
200
- res.status(500).json({ message: 'Error fetching package by path', error });
201
- }
202
- }
203
-
204
- export const listAllPackagesAndEntities = async (req: Request, res: Response) => {
205
- try {
206
- const result = await dictionaryService.listAllPackagesAndEntities();
207
- res.json({ message: 'Success', data: result });
208
- } catch (error) {
209
- logger.error('Error listing all packages and entities', error);
210
- res.status(500).json({ message: 'Error listing all packages and entities', error });
211
- }
212
- };
213
-
214
- export const createPackageAtPath = async (req: Request, res: Response) => {
215
- try {
216
- const { rootPackage } = req.params;
217
- const packagePath = req.params[0]?.split('/').filter(Boolean) || [];
218
- const packageData = req.body;
219
- const result = await dictionaryService.createPackageAtPath(rootPackage, packagePath, packageData);
220
- if (!result.success) {
221
- return res.status(400).json({ message: 'Failed to create package', errors: result.errors });
222
- }
223
- res.status(201).json({ message: 'Package created successfully', data: result.package });
224
- } catch (error) {
225
- logger.error('Error creating package', error);
226
- res.status(500).json({ message: 'Error creating package', error });
227
- }
228
- };
229
-
230
- export const updatePackageAtPath = async (req: Request, res: Response) => {
231
- try {
232
- const { rootPackage } = req.params;
233
- const packagePath = req.params[0]?.split('/').filter(Boolean) || [];
234
- const packageData = req.body;
235
- const result = await dictionaryService.updatePackageAtPath(rootPackage, packagePath, packageData);
236
- if (!result.success) {
237
- return res.status(400).json({ message: 'Failed to update package', errors: result.errors });
238
- }
239
- res.status(200).json({ message: 'Package updated successfully', data: result.package });
240
- } catch (error) {
241
- logger.error('Error updating package', error);
242
- res.status(500).json({ message: 'Error updating package', error });
243
- }
244
- };
245
-
246
- export const createRootPackage = async (req: Request, res: Response) => {
247
- try {
248
- const { name, description, type, metadata } = req.body;
249
- if (!name) {
250
- return res.status(400).json({ message: 'Package name is required' });
251
- }
252
- const result = await dictionaryService.createPackageAtPath(name, [], { name, description, type, metadata });
253
- if (!result.success) {
254
- return res.status(400).json({ message: 'Failed to create package', errors: result.errors });
255
- }
256
- res.status(201).json({ message: 'Package created successfully', data: result.package });
257
- } catch (error) {
258
- logger.error('Error creating root package', error);
259
- res.status(500).json({ message: 'Error creating package', error });
260
- }
261
- };
262
-
263
- export const deletePackageAtPath = async (req: Request, res: Response) => {
264
- try {
265
- const { rootPackage } = req.params;
266
- const packagePath = req.params[0]?.split('/').filter(Boolean) || [];
267
- const force = req.query.force === 'true';
268
- const result = await dictionaryService.deletePackageAtPath(rootPackage, packagePath, force);
269
- if (!result.success) {
270
- return res.status(400).json({ message: 'Failed to delete package', errors: result.errors });
271
- }
272
- res.status(200).json({ message: 'Package deleted successfully' });
273
- } catch (error) {
274
- logger.error('Error deleting package', error);
275
- res.status(500).json({ message: 'Error deleting package', error });
276
- }
277
- };
278
-
279
- export const getFlatEntitiesAndAttributes = async (req: Request, res: Response) => {
280
- try {
281
- const { name, type, package: pkg } = req.query;
282
- const filters: any = {};
283
- if (name) filters.name = String(name);
284
- if (type) filters.type = String(type);
285
- if (pkg) filters.package = String(pkg);
286
- const result = await dictionaryService.getFlatEntitiesAndAttributes(filters);
287
- res.json({ message: 'Success', data: result });
288
- } catch (error) {
289
- logger.error('Error getting flat entities/attributes', error);
290
- res.status(500).json({ message: 'Error getting flat entities/attributes', error });
291
- }
292
- };
293
-
294
- export const getEntityHierarchy = async (req: Request, res: Response) => {
295
- try {
296
- const { microservice, entityName } = req.params;
297
- const result = await dictionaryService.getEntityHierarchy(microservice, entityName);
298
- if (!result) {
299
- return res.status(404).json({ message: 'Entity not found' });
300
- }
301
- res.json({ message: 'Success', data: result });
302
- } catch (error) {
303
- logger.error('Error getting entity hierarchy', error);
304
- res.status(500).json({ message: 'Error getting entity hierarchy', error });
305
- }
306
- };
@@ -1,64 +0,0 @@
1
- import { Request, Response } from 'express';
2
- import { importService } from '../services/importService.js';
3
- import { exportService } from '../services/exportService.js';
4
- import { qualityService } from '../services/qualityService.js';
5
- import { logger } from '../utils/logger.js';
6
-
7
- export const importJsonSchema = async (req: Request, res: Response) => {
8
- try {
9
- const { schema, service } = req.body;
10
- if (!schema || !service) return res.status(400).json({ message: 'schema and service are required' });
11
- const result = await importService.importFromJsonSchema(schema, service);
12
- res.json({ message: `Imported ${result.entities.length} entities`, data: result });
13
- } catch (error) {
14
- logger.error('Error importing JSON Schema', error);
15
- res.status(500).json({ message: 'Error importing JSON Schema', error });
16
- }
17
- };
18
-
19
- export const importSqlDdl = async (req: Request, res: Response) => {
20
- try {
21
- const { sql, service } = req.body;
22
- if (!sql || !service) return res.status(400).json({ message: 'sql and service are required' });
23
- const result = await importService.importFromSqlDdl(sql, service);
24
- res.json({ message: `Imported ${result.entities.length} entities`, data: result });
25
- } catch (error) {
26
- logger.error('Error importing SQL DDL', error);
27
- res.status(500).json({ message: 'Error importing SQL DDL', error });
28
- }
29
- };
30
-
31
- export const exportJsonSchema = async (req: Request, res: Response) => {
32
- try {
33
- const { service } = req.params;
34
- const schema = await exportService.exportToJsonSchema(service);
35
- res.json(schema);
36
- } catch (error) {
37
- logger.error('Error exporting JSON Schema', error);
38
- res.status(500).json({ message: 'Error exporting JSON Schema', error });
39
- }
40
- };
41
-
42
- export const exportMarkdown = async (req: Request, res: Response) => {
43
- try {
44
- const { service } = req.params;
45
- const markdown = await exportService.exportToMarkdown(service);
46
- res.setHeader('Content-Type', 'text/markdown');
47
- res.setHeader('Content-Disposition', `attachment; filename="${service}-data-dictionary.md"`);
48
- res.send(markdown);
49
- } catch (error) {
50
- logger.error('Error exporting Markdown', error);
51
- res.status(500).json({ message: 'Error exporting Markdown', error });
52
- }
53
- };
54
-
55
- export const getQualityReport = async (req: Request, res: Response) => {
56
- try {
57
- const service = req.query.service as string | undefined;
58
- const report = await qualityService.getQualityReport(service);
59
- res.json({ message: 'Success', data: report });
60
- } catch (error) {
61
- logger.error('Error getting quality report', error);
62
- res.status(500).json({ message: 'Error getting quality report', error });
63
- }
64
- };