@hamak/smart-data-dico 1.0.4 → 1.1.0

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 +82212 -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,602 +0,0 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
- import YAML from 'yaml';
4
- import { logger } from './logger.js';
5
- import { Entity, Relationship, Perspective, ReviewComment, validateEntity } from '../models/EntitySchema.js';
6
- import { Dictionary } from '../models/Dictionary.js';
7
- import { generateEntityFilename, extractUUIDFromFilename } from './uuid.js';
8
- import { config } from '../kernel/config.js';
9
-
10
- // Base directory for data dictionaries
11
- const DATA_DICTIONARIES_DIR = config.dataDir;
12
-
13
- // Lazy-loaded git service from @hamak/ui-remote-git-fs-backend
14
- let gitServiceInstance: any = null;
15
-
16
- async function getGitService() {
17
- if (gitServiceInstance) return gitServiceInstance;
18
- try {
19
- const gitModule = await import('@hamak/ui-remote-git-fs-backend');
20
- const workspaceRoots = new Map<string, string>([
21
- ['dictionaries', DATA_DICTIONARIES_DIR],
22
- ]);
23
- gitServiceInstance = gitModule.createGitService(workspaceRoots);
24
- return gitServiceInstance;
25
- } catch {
26
- logger.warn('Git service not available');
27
- return null;
28
- }
29
- }
30
-
31
- /**
32
- * Ensures the data dictionaries directory structure exists
33
- */
34
- export async function ensureDirectoryStructure(): Promise<void> {
35
- const baseDir = DATA_DICTIONARIES_DIR;
36
- const microservicesDir = path.join(baseDir, 'microservices');
37
-
38
- if (!fs.existsSync(baseDir)) {
39
- fs.mkdirSync(baseDir, { recursive: true });
40
- logger.info(`Created base directory: ${baseDir}`);
41
- }
42
-
43
- if (!fs.existsSync(microservicesDir)) {
44
- fs.mkdirSync(microservicesDir, { recursive: true });
45
- logger.info(`Created microservices directory: ${microservicesDir}`);
46
- }
47
-
48
- const perspectivesDir = path.join(baseDir, 'perspectives');
49
- if (!fs.existsSync(perspectivesDir)) {
50
- fs.mkdirSync(perspectivesDir, { recursive: true });
51
- logger.info(`Created perspectives directory: ${perspectivesDir}`);
52
- }
53
- }
54
-
55
- /**
56
- * Reads an entity from a YAML file
57
- * @param packageName Package (service) name
58
- * @param entityName Entity name
59
- */
60
- export async function readEntityFile(packageName: string, entityName: string): Promise<Entity | null> {
61
- const startTime = process.hrtime();
62
- try {
63
- const packagePath = path.join(DATA_DICTIONARIES_DIR, 'microservices', packageName);
64
-
65
- if (!fs.existsSync(packagePath)) {
66
- logger.warn(`Package directory not found: ${packagePath}`);
67
- return null;
68
- }
69
-
70
- // Try to find file by name (could be UUID-based or legacy name-based)
71
- const files = fs.readdirSync(packagePath)
72
- .filter(file => file.endsWith('.yaml') || file.endsWith('.yml'));
73
-
74
- let filePath: string | null = null;
75
-
76
- // First try legacy naming convention
77
- const legacyPath = path.join(packagePath, `${entityName}.yaml`);
78
- if (fs.existsSync(legacyPath)) {
79
- filePath = legacyPath;
80
- } else {
81
- // Try to find by UUID-based filename that contains the entity name
82
- for (const file of files) {
83
- if (file === 'metadata.yaml' || file === 'relationships.yaml') continue;
84
- const fullPath = path.join(packagePath, file);
85
- try {
86
- const content = fs.readFileSync(fullPath, 'utf8');
87
- const entity = YAML.parse(content) as Entity;
88
- if (entity.name === entityName) {
89
- filePath = fullPath;
90
- break;
91
- }
92
- } catch (error) {
93
- continue;
94
- }
95
- }
96
- }
97
-
98
- if (!filePath) {
99
- logger.warn(`Entity file not found: ${packageName}.${entityName}`);
100
- return null;
101
- }
102
-
103
- const readStartTime = process.hrtime();
104
- const fileContent = fs.readFileSync(filePath, 'utf8');
105
- const readEndTime = process.hrtime(readStartTime);
106
- const readTimeMs = Number((readEndTime[0] * 1e3 + readEndTime[1] / 1e6).toFixed(2));
107
-
108
- const parseStartTime = process.hrtime();
109
- const entity = YAML.parse(fileContent) as Entity;
110
- const parseEndTime = process.hrtime(parseStartTime);
111
- const parseTimeMs = Number((parseEndTime[0] * 1e3 + parseEndTime[1] / 1e6).toFixed(2));
112
-
113
- const endTime = process.hrtime(startTime);
114
- const totalTimeMs = Number((endTime[0] * 1e3 + endTime[1] / 1e6).toFixed(2));
115
-
116
- logger.debug(`Read entity ${packageName}.${entityName}: ${totalTimeMs}ms (read: ${readTimeMs}ms, parse: ${parseTimeMs}ms)`);
117
-
118
- return entity;
119
- } catch (error) {
120
- logger.error(`Error reading entity file: ${error}`);
121
- return null;
122
- }
123
- }
124
-
125
- /**
126
- * Writes an entity to a YAML file
127
- * @param entity Entity to write
128
- * @param packageName Package name (directory under microservices/)
129
- */
130
- export async function writeEntityFile(entity: Entity, packageName?: string): Promise<boolean> {
131
- try {
132
- const validation = validateEntity(entity);
133
- if (!validation.valid) {
134
- logger.error(`Invalid entity: ${validation.errors.join(', ')}`);
135
- return false;
136
- }
137
-
138
- // Use packageName parameter or fall back to a default
139
- const pkgName = packageName;
140
- if (!pkgName) {
141
- logger.error('Package name is required to write entity file');
142
- return false;
143
- }
144
-
145
- const packageDir = path.join(DATA_DICTIONARIES_DIR, 'microservices', pkgName);
146
-
147
- if (!fs.existsSync(packageDir)) {
148
- fs.mkdirSync(packageDir, { recursive: true });
149
- logger.info(`Created package directory: ${packageDir}`);
150
- }
151
-
152
- // Check if there's an existing file for this entity (by name) to remove it
153
- const existingFiles = fs.readdirSync(packageDir)
154
- .filter(file => (file.endsWith('.yaml') || file.endsWith('.yml')) && file !== 'metadata.yaml' && file !== 'relationships.yaml');
155
-
156
- for (const file of existingFiles) {
157
- const fullPath = path.join(packageDir, file);
158
- try {
159
- const content = fs.readFileSync(fullPath, 'utf8');
160
- const existingEntity = YAML.parse(content) as Entity;
161
- if (existingEntity.name === entity.name) {
162
- const newFilename = generateEntityFilename(entity.uuid, entity.name);
163
- if (file !== newFilename) {
164
- fs.unlinkSync(fullPath);
165
- logger.info(`Removed old entity file: ${fullPath}`);
166
- }
167
- break;
168
- }
169
- } catch (error) {
170
- continue;
171
- }
172
- }
173
-
174
- const filename = generateEntityFilename(entity.uuid, entity.name);
175
- const filePath = path.join(packageDir, filename);
176
- const yamlContent = YAML.stringify(entity);
177
-
178
- fs.writeFileSync(filePath, yamlContent, 'utf8');
179
- logger.info(`Entity written to file: ${filePath}`);
180
-
181
- try {
182
- await commitChanges(filePath, `Updated entity: ${entity.name} (${entity.uuid})`);
183
- } catch (gitError) {
184
- logger.warn(`Git operations failed: ${gitError}`);
185
- }
186
-
187
- return true;
188
- } catch (error) {
189
- logger.error(`Error writing entity file: ${error}`);
190
- return false;
191
- }
192
- }
193
-
194
- /**
195
- * Reads relationships from a package's relationships.yaml file
196
- */
197
- export async function readRelationshipsFile(packagePath: string): Promise<Relationship[]> {
198
- try {
199
- const filePath = path.join(packagePath, 'relationships.yaml');
200
- if (!fs.existsSync(filePath)) {
201
- return [];
202
- }
203
-
204
- const content = fs.readFileSync(filePath, 'utf8');
205
- const parsed = YAML.parse(content);
206
-
207
- if (!parsed || !Array.isArray(parsed)) {
208
- return [];
209
- }
210
-
211
- return parsed as Relationship[];
212
- } catch (error) {
213
- logger.error(`Error reading relationships file: ${error}`);
214
- return [];
215
- }
216
- }
217
-
218
- /**
219
- * Writes relationships to a package's relationships.yaml file
220
- */
221
- export async function writeRelationshipsFile(packagePath: string, relationships: Relationship[]): Promise<boolean> {
222
- try {
223
- if (!fs.existsSync(packagePath)) {
224
- fs.mkdirSync(packagePath, { recursive: true });
225
- }
226
-
227
- const filePath = path.join(packagePath, 'relationships.yaml');
228
- const yamlContent = YAML.stringify(relationships);
229
-
230
- fs.writeFileSync(filePath, yamlContent, 'utf8');
231
- logger.info(`Relationships written to file: ${filePath}`);
232
-
233
- try {
234
- await commitChanges(filePath, `Updated relationships in ${path.basename(packagePath)}`);
235
- } catch (gitError) {
236
- logger.warn(`Git operations failed: ${gitError}`);
237
- }
238
-
239
- return true;
240
- } catch (error) {
241
- logger.error(`Error writing relationships file: ${error}`);
242
- return false;
243
- }
244
- }
245
-
246
- /**
247
- * Gets the full path for a package directory
248
- */
249
- export function getPackagePath(packageName: string): string {
250
- return path.join(DATA_DICTIONARIES_DIR, 'microservices', packageName);
251
- }
252
-
253
- /**
254
- * Lists all available entities across all packages
255
- */
256
- export async function listAllEntities(): Promise<Array<{ microservice: string; name: string; path: string }>> {
257
- try {
258
- const microservicesDir = path.join(DATA_DICTIONARIES_DIR, 'microservices');
259
- const entities: Array<{ microservice: string; name: string; path: string }> = [];
260
-
261
- if (!fs.existsSync(microservicesDir)) {
262
- return entities;
263
- }
264
-
265
- const microservices = fs.readdirSync(microservicesDir)
266
- .filter((item: string) => fs.statSync(path.join(microservicesDir, item)).isDirectory());
267
-
268
- for (const microservice of microservices) {
269
- const microservicePath = path.join(microservicesDir, microservice);
270
- const files = fs.readdirSync(microservicePath)
271
- .filter((file: string) => (file.endsWith('.yaml') || file.endsWith('.yml')) && file !== 'metadata.yaml' && file !== 'relationships.yaml' && !file.endsWith('.comments.yaml'));
272
-
273
- for (const file of files) {
274
- const name = path.basename(file, path.extname(file));
275
- entities.push({
276
- microservice,
277
- name,
278
- path: path.join(microservicePath, file)
279
- });
280
- }
281
- }
282
-
283
- return entities;
284
- } catch (error) {
285
- logger.error(`Error listing entities: ${error}`);
286
- return [];
287
- }
288
- }
289
-
290
- /**
291
- * Lists all entities for a specific package
292
- */
293
- export async function listMicroserviceEntities(microservice: string): Promise<string[]> {
294
- const startTime = process.hrtime();
295
- try {
296
- const microservicePath = path.join(DATA_DICTIONARIES_DIR, 'microservices', microservice);
297
-
298
- if (!fs.existsSync(microservicePath)) {
299
- return [];
300
- }
301
-
302
- const readStartTime = process.hrtime();
303
- const allFiles = fs.readdirSync(microservicePath);
304
- const readEndTime = process.hrtime(readStartTime);
305
- const readTimeMs = Number((readEndTime[0] * 1e3 + readEndTime[1] / 1e6).toFixed(2));
306
-
307
- const processStartTime = process.hrtime();
308
- const files = allFiles
309
- .filter((file: string) => (file.endsWith('.yaml') || file.endsWith('.yml')) && file !== 'metadata.yaml' && file !== 'relationships.yaml' && !file.endsWith('.comments.yaml'))
310
- .map((file: string) => path.basename(file, path.extname(file)));
311
- const processEndTime = process.hrtime(processStartTime);
312
- const processTimeMs = Number((processEndTime[0] * 1e3 + processEndTime[1] / 1e6).toFixed(2));
313
-
314
- const endTime = process.hrtime(startTime);
315
- const totalTimeMs = Number((endTime[0] * 1e3 + endTime[1] / 1e6).toFixed(2));
316
-
317
- logger.debug(`Listed ${files.length} entities for ${microservice}: ${totalTimeMs}ms (read: ${readTimeMs}ms, process: ${processTimeMs}ms)`);
318
-
319
- return files;
320
- } catch (error) {
321
- logger.error(`Error listing microservice entities: ${error}`);
322
- return [];
323
- }
324
- }
325
-
326
- /**
327
- * Lists all available microservices
328
- */
329
- export async function listMicroservices(): Promise<string[]> {
330
- try {
331
- const microservicesDir = path.join(DATA_DICTIONARIES_DIR, 'microservices');
332
-
333
- if (!fs.existsSync(microservicesDir)) {
334
- return [];
335
- }
336
-
337
- const microservices = fs.readdirSync(microservicesDir)
338
- .filter((item: string) => fs.statSync(path.join(microservicesDir, item)).isDirectory());
339
-
340
- return microservices;
341
- } catch (error) {
342
- logger.error(`Error listing microservices: ${error}`);
343
- return [];
344
- }
345
- }
346
-
347
- /**
348
- * Commits changes to git via @hamak/ui-remote-git-fs-backend
349
- */
350
- async function commitChanges(filePath: string, message: string): Promise<void> {
351
- if (!config.git.autoCommit) return;
352
-
353
- try {
354
- const gitService = await getGitService();
355
- if (!gitService) {
356
- logger.warn('Git service not available, skipping commit');
357
- return;
358
- }
359
-
360
- await gitService.commit('dictionaries', '.', { message, paths: [filePath] });
361
- logger.info(`Changes committed: ${message}`);
362
- } catch (error) {
363
- logger.error(`Git error: ${error}`);
364
- throw error;
365
- }
366
- }
367
-
368
- /**
369
- * Deletes an entity file
370
- */
371
- export async function deleteEntityFile(microservice: string, entityName: string): Promise<boolean> {
372
- try {
373
- const microservicePath = path.join(DATA_DICTIONARIES_DIR, 'microservices', microservice);
374
-
375
- if (!fs.existsSync(microservicePath)) {
376
- logger.warn(`Package directory not found: ${microservicePath}`);
377
- return false;
378
- }
379
-
380
- const files = fs.readdirSync(microservicePath)
381
- .filter(file => (file.endsWith('.yaml') || file.endsWith('.yml')) && file !== 'metadata.yaml' && file !== 'relationships.yaml');
382
-
383
- let filePath: string | null = null;
384
-
385
- const legacyPath = path.join(microservicePath, `${entityName}.yaml`);
386
- if (fs.existsSync(legacyPath)) {
387
- filePath = legacyPath;
388
- } else {
389
- for (const file of files) {
390
- const fullPath = path.join(microservicePath, file);
391
- try {
392
- const content = fs.readFileSync(fullPath, 'utf8');
393
- const entity = YAML.parse(content) as Entity;
394
- if (entity.name === entityName) {
395
- filePath = fullPath;
396
- break;
397
- }
398
- } catch (error) {
399
- continue;
400
- }
401
- }
402
- }
403
-
404
- if (!filePath) {
405
- logger.warn(`Entity file not found for deletion: ${microservice}.${entityName}`);
406
- return false;
407
- }
408
-
409
- fs.unlinkSync(filePath);
410
- logger.info(`Entity file deleted: ${filePath}`);
411
-
412
- try {
413
- await commitChanges(filePath, `Deleted entity: ${entityName}`);
414
- } catch (gitError) {
415
- logger.warn(`Git operations failed: ${gitError}`);
416
- }
417
-
418
- return true;
419
- } catch (error) {
420
- logger.error(`Error deleting entity file: ${error}`);
421
- return false;
422
- }
423
- }
424
-
425
- /**
426
- * Writes dictionary metadata to a YAML file
427
- */
428
- export async function writeDictionaryMetadata(dictionary: Dictionary): Promise<boolean> {
429
- try {
430
- const dictionaryDir = path.join(DATA_DICTIONARIES_DIR, dictionary.id);
431
-
432
- if (!fs.existsSync(dictionaryDir)) {
433
- fs.mkdirSync(dictionaryDir, { recursive: true });
434
- logger.info(`Created dictionary directory: ${dictionaryDir}`);
435
- }
436
-
437
- const filePath = path.join(dictionaryDir, 'metadata.yaml');
438
-
439
- const metadata = {
440
- id: dictionary.id,
441
- name: dictionary.name,
442
- description: dictionary.description,
443
- metadataDefinitions: dictionary.metadataDefinitions,
444
- createdAt: dictionary.createdAt,
445
- updatedAt: dictionary.updatedAt
446
- };
447
-
448
- const yamlContent = YAML.stringify(metadata);
449
-
450
- fs.writeFileSync(filePath, yamlContent, 'utf8');
451
- logger.info(`Dictionary metadata written to file: ${filePath}`);
452
-
453
- try {
454
- await commitChanges(filePath, `Updated dictionary metadata: ${dictionary.name}`);
455
- } catch (gitError) {
456
- logger.warn(`Git operations failed: ${gitError}`);
457
- }
458
-
459
- return true;
460
- } catch (error) {
461
- logger.error(`Error writing dictionary metadata: ${error}`);
462
- return false;
463
- }
464
- }
465
-
466
- /**
467
- * Lists all available dictionaries
468
- */
469
- export async function listAllDictionaries(): Promise<string[]> {
470
- try {
471
- const baseDir = DATA_DICTIONARIES_DIR;
472
- const dictionaries: string[] = [];
473
-
474
- if (!fs.existsSync(baseDir)) {
475
- return [];
476
- }
477
-
478
- const items = fs.readdirSync(baseDir);
479
-
480
- for (const item of items) {
481
- const itemPath = path.join(baseDir, item);
482
-
483
- if (fs.statSync(itemPath).isDirectory()) {
484
- if (item === 'microservices') {
485
- const microservices = await listMicroservices();
486
- dictionaries.push(...microservices);
487
- } else {
488
- const metadataPath = path.join(itemPath, 'metadata.yaml');
489
- if (fs.existsSync(metadataPath)) {
490
- dictionaries.push(item);
491
- }
492
- }
493
- }
494
- }
495
-
496
- return dictionaries;
497
- } catch (error) {
498
- logger.error(`Error listing all dictionaries: ${error}`);
499
- return [];
500
- }
501
- }
502
-
503
- // --- Perspective file operations ---
504
-
505
- const PERSPECTIVES_DIR = path.join(DATA_DICTIONARIES_DIR, 'perspectives');
506
-
507
- export async function listPerspectives(): Promise<Perspective[]> {
508
- try {
509
- if (!fs.existsSync(PERSPECTIVES_DIR)) return [];
510
- const files = fs.readdirSync(PERSPECTIVES_DIR).filter(f => f.endsWith('.yaml'));
511
- return files.map(f => {
512
- const content = fs.readFileSync(path.join(PERSPECTIVES_DIR, f), 'utf8');
513
- return YAML.parse(content) as Perspective;
514
- }).filter(Boolean);
515
- } catch (error) {
516
- logger.error(`Error listing perspectives: ${error}`);
517
- return [];
518
- }
519
- }
520
-
521
- export async function readPerspectiveFile(uuid: string): Promise<Perspective | null> {
522
- try {
523
- const filePath = path.join(PERSPECTIVES_DIR, `${uuid}.yaml`);
524
- if (!fs.existsSync(filePath)) return null;
525
- const content = fs.readFileSync(filePath, 'utf8');
526
- return YAML.parse(content) as Perspective;
527
- } catch (error) {
528
- logger.error(`Error reading perspective ${uuid}: ${error}`);
529
- return null;
530
- }
531
- }
532
-
533
- export async function writePerspectiveFile(perspective: Perspective): Promise<boolean> {
534
- try {
535
- if (!fs.existsSync(PERSPECTIVES_DIR)) {
536
- fs.mkdirSync(PERSPECTIVES_DIR, { recursive: true });
537
- }
538
- const filePath = path.join(PERSPECTIVES_DIR, `${perspective.uuid}.yaml`);
539
- fs.writeFileSync(filePath, YAML.stringify(perspective), 'utf8');
540
- return true;
541
- } catch (error) {
542
- logger.error(`Error writing perspective: ${error}`);
543
- return false;
544
- }
545
- }
546
-
547
- export async function deletePerspectiveFile(uuid: string): Promise<boolean> {
548
- try {
549
- const filePath = path.join(PERSPECTIVES_DIR, `${uuid}.yaml`);
550
- if (!fs.existsSync(filePath)) return false;
551
- fs.unlinkSync(filePath);
552
- return true;
553
- } catch (error) {
554
- logger.error(`Error deleting perspective ${uuid}: ${error}`);
555
- return false;
556
- }
557
- }
558
-
559
- /**
560
- * Collects all relationships from all packages for cross-service BFS traversal.
561
- */
562
- export async function getAllRelationships(): Promise<{ packageName: string; relationships: Relationship[] }[]> {
563
- const result: { packageName: string; relationships: Relationship[] }[] = [];
564
- try {
565
- const microservices = await listMicroservices();
566
- for (const ms of microservices) {
567
- const pkgPath = path.join(DATA_DICTIONARIES_DIR, 'microservices', ms);
568
- const rels = await readRelationshipsFile(pkgPath);
569
- if (rels.length > 0) {
570
- result.push({ packageName: ms, relationships: rels });
571
- }
572
- }
573
- } catch (error) {
574
- logger.error(`Error collecting all relationships: ${error}`);
575
- }
576
- return result;
577
- }
578
-
579
- // --- Review comment file operations ---
580
-
581
- export async function readComments(service: string, entityUuid: string): Promise<ReviewComment[]> {
582
- try {
583
- const filePath = path.join(DATA_DICTIONARIES_DIR, 'microservices', service, `${entityUuid}.comments.yaml`);
584
- if (!fs.existsSync(filePath)) return [];
585
- const content = fs.readFileSync(filePath, 'utf8');
586
- return YAML.parse(content) || [];
587
- } catch (error) {
588
- logger.error(`Error reading comments: ${error}`);
589
- return [];
590
- }
591
- }
592
-
593
- export async function writeComments(service: string, entityUuid: string, comments: ReviewComment[]): Promise<boolean> {
594
- try {
595
- const filePath = path.join(DATA_DICTIONARIES_DIR, 'microservices', service, `${entityUuid}.comments.yaml`);
596
- fs.writeFileSync(filePath, YAML.stringify(comments), 'utf8');
597
- return true;
598
- } catch (error) {
599
- logger.error(`Error writing comments: ${error}`);
600
- return false;
601
- }
602
- }
@@ -1,38 +0,0 @@
1
- // Simple logger utility
2
-
3
- /**
4
- * Log levels
5
- */
6
- export enum LogLevel {
7
- ERROR = 'ERROR',
8
- WARN = 'WARN',
9
- INFO = 'INFO',
10
- DEBUG = 'DEBUG'
11
- }
12
-
13
- /**
14
- * Simple logger function
15
- * @param level Log level
16
- * @param message Message to log
17
- * @param meta Additional metadata
18
- */
19
- export function log(level: LogLevel, message: string, meta?: any): void {
20
- const timestamp = new Date().toISOString();
21
- const logEntry = {
22
- timestamp,
23
- level,
24
- message,
25
- ...(meta && { meta })
26
- };
27
-
28
- // In production, this would be replaced with a proper logging solution
29
- console.log(JSON.stringify(logEntry));
30
- }
31
-
32
- // Convenience methods
33
- export const logger = {
34
- error: (message: string, meta?: any) => log(LogLevel.ERROR, message, meta),
35
- warn: (message: string, meta?: any) => log(LogLevel.WARN, message, meta),
36
- info: (message: string, meta?: any) => log(LogLevel.INFO, message, meta),
37
- debug: (message: string, meta?: any) => log(LogLevel.DEBUG, message, meta)
38
- };