Add database adapter system, production deployment configs, and new dashboard components

- Add PostgreSQL and SQLite database adapters with factory pattern
- Add migration script for SQLite to PostgreSQL
- Add production Dockerfiles and docker-compose configs
- Add deployment documentation and scripts
- Add BIA sync dashboard and matching service
- Add data completeness configuration and components
- Add new dashboard components (BusinessImportanceComparison, ComplexityDynamics, etc.)
- Update various services and routes
- Remove deprecated management-parameters.json and taxonomy files
This commit is contained in:
2026-01-14 00:38:40 +01:00
parent ca21b9538d
commit a7f8301196
73 changed files with 12878 additions and 2003 deletions

View File

@@ -14,15 +14,38 @@ import type { CMDBObjectTypeName } from '../generated/jira-types.js';
const router = Router();
// Get cache status
router.get('/status', (req: Request, res: Response) => {
router.get('/status', async (req: Request, res: Response) => {
try {
const cacheStats = cacheStore.getStats();
const syncStatus = syncEngine.getStatus();
const cacheStats = await cacheStore.getStats();
const syncStatus = await syncEngine.getStatus();
// Compare cache count with Jira count for ApplicationComponent
let jiraComparison: { jiraCount?: number; cacheCount: number; difference?: number } | undefined;
if (cacheStats.objectsByType['ApplicationComponent'] !== undefined) {
try {
const { jiraAssetsClient } = await import('../services/jiraAssetsClient.js');
const { OBJECT_TYPES } = await import('../generated/jira-schema.js');
const typeDef = OBJECT_TYPES['ApplicationComponent'];
if (typeDef) {
const searchResult = await jiraAssetsClient.searchObjects(`objectType = "${typeDef.name}"`, 1, 1);
const jiraCount = searchResult.totalCount;
const cacheCount = cacheStats.objectsByType['ApplicationComponent'] || 0;
jiraComparison = {
jiraCount,
cacheCount,
difference: jiraCount - cacheCount,
};
}
} catch (err) {
logger.debug('Could not fetch Jira count for comparison', err);
}
}
res.json({
cache: cacheStats,
sync: syncStatus,
supportedTypes: Object.keys(OBJECT_TYPES),
jiraComparison,
});
} catch (error) {
logger.error('Failed to get cache status', error);
@@ -87,7 +110,7 @@ router.post('/sync/:objectType', async (req: Request, res: Response) => {
});
// Clear cache for a specific type
router.delete('/clear/:objectType', (req: Request, res: Response) => {
router.delete('/clear/:objectType', async (req: Request, res: Response) => {
try {
const { objectType } = req.params;
@@ -101,7 +124,7 @@ router.delete('/clear/:objectType', (req: Request, res: Response) => {
logger.info(`Clearing cache for ${objectType}`);
const deleted = cacheStore.clearObjectType(objectType as CMDBObjectTypeName);
const deleted = await cacheStore.clearObjectType(objectType as CMDBObjectTypeName);
res.json({
status: 'cleared',
@@ -115,11 +138,11 @@ router.delete('/clear/:objectType', (req: Request, res: Response) => {
});
// Clear entire cache
router.delete('/clear', (req: Request, res: Response) => {
router.delete('/clear', async (req: Request, res: Response) => {
try {
logger.info('Clearing entire cache');
cacheStore.clearAll();
await cacheStore.clearAll();
res.json({
status: 'cleared',