driftdetect-dashboard 0.8.1 → 0.8.2

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.
@@ -0,0 +1,652 @@
1
+ /**
2
+ * API Routes for the Drift Dashboard
3
+ *
4
+ * Provides REST API endpoints for patterns, violations, files, stats, and config.
5
+ *
6
+ * @requirements 8.1 - GET `/api/patterns` to list all patterns
7
+ * @requirements 8.2 - GET `/api/patterns/:id` to get pattern details with locations
8
+ * @requirements 8.3 - POST `/api/patterns/:id/approve` to approve a pattern
9
+ * @requirements 8.4 - POST `/api/patterns/:id/ignore` to ignore a pattern
10
+ * @requirements 8.5 - DELETE `/api/patterns/:id` to delete a pattern
11
+ * @requirements 8.6 - GET `/api/violations` to list all violations
12
+ * @requirements 8.7 - GET `/api/files` to get the file tree
13
+ * @requirements 8.8 - GET `/api/files/:path` to get patterns and violations for a specific file
14
+ * @requirements 8.9 - GET `/api/stats` to get overview statistics
15
+ * @requirements 8.10 - GET `/api/config` to get configuration
16
+ * @requirements 8.11 - PUT `/api/config` to update configuration
17
+ * @requirements 8.12 - Return appropriate HTTP status codes and error messages
18
+ */
19
+ import { Router } from 'express';
20
+ import { DriftDataReader } from './drift-data-reader.js';
21
+ import { createGalaxyDataTransformer } from './galaxy-data-transformer.js';
22
+ import { getProjectRegistry } from 'driftdetect-core';
23
+ import { handleQualityGatesRequest } from './quality-gates-api.js';
24
+ // ============================================================================
25
+ // Error Classes
26
+ // ============================================================================
27
+ export class NotFoundError extends Error {
28
+ statusCode = 404;
29
+ constructor(message) {
30
+ super(message);
31
+ this.name = 'NotFoundError';
32
+ }
33
+ }
34
+ export class BadRequestError extends Error {
35
+ statusCode = 400;
36
+ constructor(message) {
37
+ super(message);
38
+ this.name = 'BadRequestError';
39
+ }
40
+ }
41
+ export class InternalServerError extends Error {
42
+ statusCode = 500;
43
+ constructor(message) {
44
+ super(message);
45
+ this.name = 'InternalServerError';
46
+ }
47
+ }
48
+ // ============================================================================
49
+ // API Routes Factory
50
+ // ============================================================================
51
+ /**
52
+ * Create API routes for the dashboard
53
+ * @param reader - DriftDataReader instance for accessing drift data
54
+ */
55
+ export function createApiRoutes(reader) {
56
+ const router = Router();
57
+ // ==========================================================================
58
+ // Pattern Routes
59
+ // ==========================================================================
60
+ /**
61
+ * GET /api/patterns - List all patterns with optional filters
62
+ * @requirements 8.1
63
+ */
64
+ router.get('/patterns', async (req, res, next) => {
65
+ try {
66
+ const query = {};
67
+ if (req.query['category']) {
68
+ query.category = req.query['category'];
69
+ }
70
+ if (req.query['status']) {
71
+ query.status = req.query['status'];
72
+ }
73
+ if (req.query['minConfidence']) {
74
+ query.minConfidence = parseFloat(req.query['minConfidence']);
75
+ }
76
+ if (req.query['search']) {
77
+ query.search = req.query['search'];
78
+ }
79
+ const patterns = await reader.getPatterns(query);
80
+ res.json(patterns);
81
+ }
82
+ catch (error) {
83
+ next(error);
84
+ }
85
+ });
86
+ /**
87
+ * GET /api/patterns/:id - Get pattern with locations
88
+ * @requirements 8.2
89
+ */
90
+ router.get('/patterns/:id', async (req, res, next) => {
91
+ try {
92
+ const { id } = req.params;
93
+ if (!id) {
94
+ throw new BadRequestError('Pattern ID is required');
95
+ }
96
+ const pattern = await reader.getPattern(id);
97
+ if (!pattern) {
98
+ throw new NotFoundError(`Pattern not found: ${id}`);
99
+ }
100
+ res.json(pattern);
101
+ }
102
+ catch (error) {
103
+ next(error);
104
+ }
105
+ });
106
+ /**
107
+ * POST /api/patterns/:id/approve - Approve a pattern
108
+ * @requirements 8.3
109
+ */
110
+ router.post('/patterns/:id/approve', async (req, res, next) => {
111
+ try {
112
+ const { id } = req.params;
113
+ if (!id) {
114
+ throw new BadRequestError('Pattern ID is required');
115
+ }
116
+ await reader.approvePattern(id);
117
+ res.json({ success: true, message: `Pattern ${id} approved` });
118
+ }
119
+ catch (error) {
120
+ if (error instanceof Error && error.message.includes('not found')) {
121
+ next(new NotFoundError(error.message));
122
+ }
123
+ else {
124
+ next(error);
125
+ }
126
+ }
127
+ });
128
+ /**
129
+ * POST /api/patterns/:id/ignore - Ignore a pattern
130
+ * @requirements 8.4
131
+ */
132
+ router.post('/patterns/:id/ignore', async (req, res, next) => {
133
+ try {
134
+ const { id } = req.params;
135
+ if (!id) {
136
+ throw new BadRequestError('Pattern ID is required');
137
+ }
138
+ await reader.ignorePattern(id);
139
+ res.json({ success: true, message: `Pattern ${id} ignored` });
140
+ }
141
+ catch (error) {
142
+ if (error instanceof Error && error.message.includes('not found')) {
143
+ next(new NotFoundError(error.message));
144
+ }
145
+ else {
146
+ next(error);
147
+ }
148
+ }
149
+ });
150
+ /**
151
+ * POST /api/patterns/bulk-approve - Bulk approve multiple patterns
152
+ * Accepts an array of pattern IDs to approve at once
153
+ */
154
+ router.post('/patterns/bulk-approve', async (req, res, next) => {
155
+ try {
156
+ const { ids } = req.body;
157
+ if (!ids || !Array.isArray(ids) || ids.length === 0) {
158
+ throw new BadRequestError('Array of pattern IDs is required');
159
+ }
160
+ const results = [];
161
+ for (const id of ids) {
162
+ try {
163
+ await reader.approvePattern(id);
164
+ results.push({ id, success: true });
165
+ }
166
+ catch (error) {
167
+ results.push({
168
+ id,
169
+ success: false,
170
+ error: error instanceof Error ? error.message : 'Unknown error'
171
+ });
172
+ }
173
+ }
174
+ const successCount = results.filter(r => r.success).length;
175
+ res.json({
176
+ success: true,
177
+ message: `Approved ${successCount} of ${ids.length} patterns`,
178
+ results
179
+ });
180
+ }
181
+ catch (error) {
182
+ next(error);
183
+ }
184
+ });
185
+ /**
186
+ * DELETE /api/patterns/:id - Delete a pattern
187
+ * @requirements 8.5
188
+ */
189
+ router.delete('/patterns/:id', async (req, res, next) => {
190
+ try {
191
+ const { id } = req.params;
192
+ if (!id) {
193
+ throw new BadRequestError('Pattern ID is required');
194
+ }
195
+ await reader.deletePattern(id);
196
+ res.json({ success: true, message: `Pattern ${id} deleted` });
197
+ }
198
+ catch (error) {
199
+ if (error instanceof Error && error.message.includes('not found')) {
200
+ next(new NotFoundError(error.message));
201
+ }
202
+ else {
203
+ next(error);
204
+ }
205
+ }
206
+ });
207
+ // ==========================================================================
208
+ // Violation Routes
209
+ // ==========================================================================
210
+ /**
211
+ * GET /api/violations - List all violations with optional filters
212
+ * @requirements 8.6
213
+ */
214
+ router.get('/violations', async (req, res, next) => {
215
+ try {
216
+ const query = {};
217
+ if (req.query['severity']) {
218
+ query.severity = req.query['severity'];
219
+ }
220
+ if (req.query['file']) {
221
+ query.file = req.query['file'];
222
+ }
223
+ if (req.query['patternId']) {
224
+ query.patternId = req.query['patternId'];
225
+ }
226
+ if (req.query['search']) {
227
+ query.search = req.query['search'];
228
+ }
229
+ const violations = await reader.getViolations(query);
230
+ res.json(violations);
231
+ }
232
+ catch (error) {
233
+ next(error);
234
+ }
235
+ });
236
+ /**
237
+ * GET /api/snippet - Get code snippet for a file location
238
+ */
239
+ router.get('/snippet', async (req, res, next) => {
240
+ try {
241
+ const file = req.query['file'];
242
+ const line = parseInt(req.query['line'], 10);
243
+ const context = parseInt(req.query['context'], 10) || 3;
244
+ if (!file) {
245
+ throw new BadRequestError('File path is required');
246
+ }
247
+ if (isNaN(line)) {
248
+ throw new BadRequestError('Line number is required');
249
+ }
250
+ const snippet = await reader.getCodeSnippet(file, line, context);
251
+ if (!snippet) {
252
+ throw new NotFoundError(`Could not read file: ${file}`);
253
+ }
254
+ res.json(snippet);
255
+ }
256
+ catch (error) {
257
+ next(error);
258
+ }
259
+ });
260
+ // ==========================================================================
261
+ // File Routes
262
+ // ==========================================================================
263
+ /**
264
+ * GET /api/files - Get file tree
265
+ * @requirements 8.7
266
+ */
267
+ router.get('/files', async (_req, res, next) => {
268
+ try {
269
+ const fileTree = await reader.getFileTree();
270
+ res.json(fileTree);
271
+ }
272
+ catch (error) {
273
+ next(error);
274
+ }
275
+ });
276
+ /**
277
+ * GET /api/files/* - Get file details (wildcard path)
278
+ * @requirements 8.8
279
+ */
280
+ router.get('/files/*', async (req, res, next) => {
281
+ try {
282
+ // Extract the file path from the wildcard
283
+ const filePath = req.params[0];
284
+ if (!filePath) {
285
+ throw new BadRequestError('File path is required');
286
+ }
287
+ const fileDetails = await reader.getFileDetails(filePath);
288
+ if (!fileDetails) {
289
+ throw new NotFoundError(`File not found or has no patterns/violations: ${filePath}`);
290
+ }
291
+ res.json(fileDetails);
292
+ }
293
+ catch (error) {
294
+ next(error);
295
+ }
296
+ });
297
+ // ==========================================================================
298
+ // Stats Routes
299
+ // ==========================================================================
300
+ /**
301
+ * GET /api/stats - Get dashboard statistics
302
+ * @requirements 8.9
303
+ */
304
+ router.get('/stats', async (_req, res, next) => {
305
+ try {
306
+ const stats = await reader.getStats();
307
+ res.json(stats);
308
+ }
309
+ catch (error) {
310
+ next(error);
311
+ }
312
+ });
313
+ // ==========================================================================
314
+ // Config Routes
315
+ // ==========================================================================
316
+ /**
317
+ * GET /api/config - Get configuration
318
+ * @requirements 8.10
319
+ */
320
+ router.get('/config', async (_req, res, next) => {
321
+ try {
322
+ const config = await reader.getConfig();
323
+ res.json(config);
324
+ }
325
+ catch (error) {
326
+ next(error);
327
+ }
328
+ });
329
+ /**
330
+ * PUT /api/config - Update configuration
331
+ * @requirements 8.11
332
+ */
333
+ router.put('/config', async (req, res, next) => {
334
+ try {
335
+ const partialConfig = req.body;
336
+ if (!partialConfig || typeof partialConfig !== 'object') {
337
+ throw new BadRequestError('Invalid configuration format');
338
+ }
339
+ await reader.updateConfig(partialConfig);
340
+ const updatedConfig = await reader.getConfig();
341
+ res.json(updatedConfig);
342
+ }
343
+ catch (error) {
344
+ next(error);
345
+ }
346
+ });
347
+ // ==========================================================================
348
+ // Contract Routes (BE↔FE mismatch detection)
349
+ // ==========================================================================
350
+ /**
351
+ * GET /api/contracts - List all contracts with optional filters
352
+ */
353
+ router.get('/contracts', async (req, res, next) => {
354
+ try {
355
+ const query = {};
356
+ if (req.query['status']) {
357
+ query.status = req.query['status'];
358
+ }
359
+ if (req.query['method']) {
360
+ query.method = req.query['method'];
361
+ }
362
+ if (req.query['hasMismatches'] !== undefined) {
363
+ query.hasMismatches = req.query['hasMismatches'] === 'true';
364
+ }
365
+ if (req.query['search']) {
366
+ query.search = req.query['search'];
367
+ }
368
+ const contracts = await reader.getContracts(query);
369
+ res.json(contracts);
370
+ }
371
+ catch (error) {
372
+ next(error);
373
+ }
374
+ });
375
+ /**
376
+ * GET /api/contracts/stats - Get contract statistics
377
+ */
378
+ router.get('/contracts/stats', async (_req, res, next) => {
379
+ try {
380
+ const stats = await reader.getContractStats();
381
+ res.json(stats);
382
+ }
383
+ catch (error) {
384
+ next(error);
385
+ }
386
+ });
387
+ /**
388
+ * GET /api/contracts/:id - Get contract details
389
+ */
390
+ router.get('/contracts/:id', async (req, res, next) => {
391
+ try {
392
+ const { id } = req.params;
393
+ if (!id) {
394
+ throw new BadRequestError('Contract ID is required');
395
+ }
396
+ const contract = await reader.getContract(id);
397
+ if (!contract) {
398
+ throw new NotFoundError(`Contract not found: ${id}`);
399
+ }
400
+ res.json(contract);
401
+ }
402
+ catch (error) {
403
+ next(error);
404
+ }
405
+ });
406
+ /**
407
+ * POST /api/contracts/:id/verify - Verify a contract
408
+ */
409
+ router.post('/contracts/:id/verify', async (req, res, next) => {
410
+ try {
411
+ const { id } = req.params;
412
+ if (!id) {
413
+ throw new BadRequestError('Contract ID is required');
414
+ }
415
+ await reader.verifyContract(id);
416
+ res.json({ success: true, message: `Contract ${id} verified` });
417
+ }
418
+ catch (error) {
419
+ if (error instanceof Error && error.message.includes('not found')) {
420
+ next(new NotFoundError(error.message));
421
+ }
422
+ else {
423
+ next(error);
424
+ }
425
+ }
426
+ });
427
+ /**
428
+ * POST /api/contracts/:id/ignore - Ignore a contract
429
+ */
430
+ router.post('/contracts/:id/ignore', async (req, res, next) => {
431
+ try {
432
+ const { id } = req.params;
433
+ if (!id) {
434
+ throw new BadRequestError('Contract ID is required');
435
+ }
436
+ await reader.ignoreContract(id);
437
+ res.json({ success: true, message: `Contract ${id} ignored` });
438
+ }
439
+ catch (error) {
440
+ if (error instanceof Error && error.message.includes('not found')) {
441
+ next(new NotFoundError(error.message));
442
+ }
443
+ else {
444
+ next(error);
445
+ }
446
+ }
447
+ });
448
+ // ==========================================================================
449
+ // Trend / History Routes
450
+ // ==========================================================================
451
+ /**
452
+ * GET /api/trends - Get pattern trend summary
453
+ * Query params: period (7d, 30d, 90d)
454
+ */
455
+ router.get('/trends', async (req, res, next) => {
456
+ try {
457
+ const period = req.query['period'] || '7d';
458
+ if (!['7d', '30d', '90d'].includes(period)) {
459
+ throw new BadRequestError('Invalid period. Use 7d, 30d, or 90d');
460
+ }
461
+ const trends = await reader.getTrends(period);
462
+ if (!trends) {
463
+ res.json({
464
+ message: 'Not enough history data. Run more scans to see trends.',
465
+ period,
466
+ regressions: [],
467
+ improvements: [],
468
+ stable: 0,
469
+ overallTrend: 'stable',
470
+ healthDelta: 0,
471
+ categoryTrends: {},
472
+ });
473
+ return;
474
+ }
475
+ res.json(trends);
476
+ }
477
+ catch (error) {
478
+ next(error);
479
+ }
480
+ });
481
+ /**
482
+ * GET /api/trends/snapshots - Get historical snapshots for charting
483
+ * Query params: limit (default 30)
484
+ */
485
+ router.get('/trends/snapshots', async (req, res, next) => {
486
+ try {
487
+ const limit = parseInt(req.query['limit'], 10) || 30;
488
+ const snapshots = await reader.getSnapshots(limit);
489
+ res.json(snapshots);
490
+ }
491
+ catch (error) {
492
+ next(error);
493
+ }
494
+ });
495
+ // ==========================================================================
496
+ // Galaxy Routes (3D Database Visualization)
497
+ // ==========================================================================
498
+ /**
499
+ * GET /api/galaxy - Get Galaxy visualization data
500
+ *
501
+ * Transforms boundary scanner and call graph data into the format
502
+ * required by the 3D Galaxy visualization.
503
+ */
504
+ router.get('/galaxy', async (_req, res, next) => {
505
+ try {
506
+ const transformer = createGalaxyDataTransformer(reader.directory);
507
+ const galaxyData = await transformer.transform();
508
+ res.json(galaxyData);
509
+ }
510
+ catch (error) {
511
+ next(error);
512
+ }
513
+ });
514
+ // ==========================================================================
515
+ // Project Routes (Multi-project management)
516
+ // ==========================================================================
517
+ /**
518
+ * GET /api/projects - List all registered projects
519
+ */
520
+ router.get('/projects', async (_req, res, next) => {
521
+ try {
522
+ const registry = await getProjectRegistry();
523
+ const projects = registry.getValid();
524
+ const activeProject = registry.getActive();
525
+ // Sort by last accessed
526
+ projects.sort((a, b) => new Date(b.lastAccessedAt).getTime() -
527
+ new Date(a.lastAccessedAt).getTime());
528
+ res.json({
529
+ totalProjects: registry.count,
530
+ activeProject: activeProject?.name ?? null,
531
+ projects: projects.map((p) => ({
532
+ id: p.id,
533
+ name: p.name,
534
+ path: p.path,
535
+ language: p.language,
536
+ framework: p.framework,
537
+ health: p.health,
538
+ healthScore: p.healthScore,
539
+ lastAccessedAt: p.lastAccessedAt,
540
+ isActive: p.id === activeProject?.id,
541
+ isValid: p.isValid !== false,
542
+ })),
543
+ });
544
+ }
545
+ catch (error) {
546
+ next(error);
547
+ }
548
+ });
549
+ /**
550
+ * POST /api/projects/switch - Switch active project
551
+ */
552
+ router.post('/projects/switch', async (req, res, next) => {
553
+ try {
554
+ const { projectId } = req.body;
555
+ if (!projectId) {
556
+ throw new BadRequestError('Project ID is required');
557
+ }
558
+ const registry = await getProjectRegistry();
559
+ const project = registry.get(projectId);
560
+ if (!project) {
561
+ throw new NotFoundError(`Project not found: ${projectId}`);
562
+ }
563
+ await registry.setActive(projectId);
564
+ res.json({
565
+ success: true,
566
+ message: `Switched to ${project.name}`,
567
+ project: {
568
+ id: project.id,
569
+ name: project.name,
570
+ path: project.path,
571
+ },
572
+ });
573
+ }
574
+ catch (error) {
575
+ next(error);
576
+ }
577
+ });
578
+ /**
579
+ * GET /api/projects/:id - Get project details
580
+ */
581
+ router.get('/projects/:id', async (req, res, next) => {
582
+ try {
583
+ const { id } = req.params;
584
+ if (!id) {
585
+ throw new BadRequestError('Project ID is required');
586
+ }
587
+ const registry = await getProjectRegistry();
588
+ const project = registry.get(id);
589
+ if (!project) {
590
+ throw new NotFoundError(`Project not found: ${id}`);
591
+ }
592
+ const activeProject = registry.getActive();
593
+ res.json({
594
+ ...project,
595
+ isActive: project.id === activeProject?.id,
596
+ });
597
+ }
598
+ catch (error) {
599
+ next(error);
600
+ }
601
+ });
602
+ // ==========================================================================
603
+ // Quality Gates Routes
604
+ // ==========================================================================
605
+ /**
606
+ * GET /api/quality-gates - Quality gates API
607
+ * Actions: latest, history, policies, policy
608
+ */
609
+ router.get('/quality-gates', (req, res) => {
610
+ handleQualityGatesRequest(req, res, reader.directory);
611
+ });
612
+ /**
613
+ * POST /api/quality-gates - Quality gates API (for run action)
614
+ * Actions: run
615
+ */
616
+ router.post('/quality-gates', (req, res) => {
617
+ handleQualityGatesRequest(req, res, reader.directory);
618
+ });
619
+ return router;
620
+ }
621
+ // ============================================================================
622
+ // Error Handling Middleware
623
+ // ============================================================================
624
+ /**
625
+ * Error handling middleware for API routes
626
+ * @requirements 8.12 - Return appropriate HTTP status codes and error messages
627
+ */
628
+ export function errorHandler(err, _req, res, _next) {
629
+ // Determine status code
630
+ const statusCode = 'statusCode' in err ? err.statusCode : 500;
631
+ // Log server errors
632
+ if (statusCode >= 500) {
633
+ console.error('Server error:', err);
634
+ }
635
+ // Send JSON error response
636
+ res.status(statusCode).json({
637
+ error: err.name || 'Error',
638
+ message: err.message || 'An unexpected error occurred',
639
+ statusCode,
640
+ });
641
+ }
642
+ /**
643
+ * 404 handler for unknown routes
644
+ */
645
+ export function notFoundHandler(req, res) {
646
+ res.status(404).json({
647
+ error: 'NotFound',
648
+ message: `Route not found: ${req.method} ${req.path}`,
649
+ statusCode: 404,
650
+ });
651
+ }
652
+ //# sourceMappingURL=api-routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-routes.js","sourceRoot":"","sources":["../../src/server/api-routes.ts"],"names":[],"mappings":"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"}