Files
cmdb-insight/backend/src/routes/schema.ts
Bert Hausmans 6bb5907bbd Fix TypeScript compilation errors in backend
- Fix query parameter type issues (string | string[] to string) in controllers
- Add public getDatabaseAdapter() method to SchemaRepository for db access
- Fix SchemaSyncService export and import issues
- Fix referenceObject vs referenceObjectType property name
- Add missing jiraAssetsClient import in normalizedCacheStore
- Fix duplicate properties in object literals
- Add type annotations for implicit any types
- Fix type predicate issues with generics
- Fix method calls (getEnabledObjectTypes, syncAllSchemas)
- Fix type mismatches (ObjectTypeRecord vs expected types)
- Fix Buffer type issue in biaMatchingService
- Export SchemaSyncService class for ServiceFactory
2026-01-21 09:29:05 +01:00

128 lines
4.1 KiB
TypeScript

import { Router } from 'express';
import { schemaCacheService } from '../services/schemaCacheService.js';
import { schemaSyncService } from '../services/SchemaSyncService.js';
import { schemaMappingService } from '../services/schemaMappingService.js';
import { logger } from '../services/logger.js';
import { jiraAssetsClient } from '../services/jiraAssetsClient.js';
import { requireAuth, requirePermission } from '../middleware/authorization.js';
const router = Router();
// All routes require authentication and search permission
router.use(requireAuth);
router.use(requirePermission('search'));
/**
* GET /api/schema
* Returns the complete Jira Assets schema with object types, attributes, and links
* Data is fetched from database (via cache service)
*/
router.get('/', async (req, res) => {
try {
// Get schema from cache (which fetches from database)
const schema = await schemaCacheService.getSchema();
// Optionally fetch Jira counts for comparison (can be slow, so make it optional)
let jiraCounts: Record<string, number> | undefined;
const includeJiraCounts = req.query.includeJiraCounts === 'true';
if (includeJiraCounts) {
const typeNames = Object.keys(schema.objectTypes);
logger.info(`Schema: Fetching object counts from Jira Assets for ${typeNames.length} object types...`);
jiraCounts = {};
// Fetch counts in parallel for better performance, using schema mappings
const countPromises = typeNames.map(async (typeName) => {
try {
// Get schema ID for this type
const schemaId = await schemaMappingService.getSchemaId(typeName);
const count = await jiraAssetsClient.getObjectCount(typeName, schemaId);
jiraCounts![typeName] = count;
return { typeName, count };
} catch (error) {
logger.warn(`Schema: Failed to get count for ${typeName}`, error);
// Use 0 as fallback if API call fails
jiraCounts![typeName] = 0;
return { typeName, count: 0 };
}
});
await Promise.all(countPromises);
logger.info(`Schema: Fetched counts for ${Object.keys(jiraCounts).length} object types from Jira Assets`);
}
const response = {
...schema,
jiraCounts,
};
res.json(response);
} catch (error) {
logger.error('Failed to get schema:', error);
res.status(500).json({ error: 'Failed to get schema' });
}
});
/**
* GET /api/schema/object-type/:typeName
* Returns details for a specific object type
*/
router.get('/object-type/:typeName', async (req, res) => {
try {
const { typeName } = req.params;
// Get schema from cache
const schema = await schemaCacheService.getSchema();
const typeDef = schema.objectTypes[typeName];
if (!typeDef) {
return res.status(404).json({ error: `Object type '${typeName}' not found` });
}
res.json(typeDef);
} catch (error) {
logger.error('Failed to get object type:', error);
res.status(500).json({ error: 'Failed to get object type' });
}
});
/**
* POST /api/schema/discover
* Manually trigger schema synchronization from Jira API
* Requires manage_settings permission
*/
router.post('/discover', requirePermission('manage_settings'), async (req, res) => {
try {
logger.info('Schema: Manual schema sync triggered');
const result = await schemaSyncService.syncAll();
schemaCacheService.invalidate(); // Invalidate cache
res.json({
message: 'Schema synchronization completed',
...result,
});
} catch (error) {
logger.error('Failed to sync schema:', error);
res.status(500).json({
error: 'Failed to sync schema',
details: error instanceof Error ? error.message : String(error),
});
}
});
/**
* GET /api/schema/sync-progress
* Get current sync progress
*/
router.get('/sync-progress', requirePermission('manage_settings'), async (req, res) => {
try {
const progress = schemaSyncService.getProgress();
res.json(progress);
} catch (error) {
logger.error('Failed to get sync progress:', error);
res.status(500).json({ error: 'Failed to get sync progress' });
}
});
export default router;