From 6bb5907bbd541313e82b272911904648e0141a05 Mon Sep 17 00:00:00 2001 From: Bert Hausmans Date: Wed, 21 Jan 2026 09:29:05 +0100 Subject: [PATCH] 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 --- .../src/api/controllers/DebugController.ts | 39 +++++++++---- backend/src/api/controllers/SyncController.ts | 58 +++++++++++-------- backend/src/index.ts | 2 +- backend/src/repositories/SchemaRepository.ts | 7 +++ backend/src/routes/schema.ts | 1 - backend/src/routes/schemaConfiguration.ts | 15 +++-- backend/src/services/SchemaSyncService.ts | 4 +- backend/src/services/ServiceFactory.ts | 2 +- backend/src/services/biaMatchingService.ts | 5 +- backend/src/services/cmdbService.ts | 4 +- .../database/migrate-to-normalized-schema.ts | 11 ++-- backend/src/services/jiraAssets.ts | 3 +- backend/src/services/normalizedCacheStore.ts | 16 ++--- backend/src/services/schemaMappingService.ts | 8 +-- 14 files changed, 110 insertions(+), 65 deletions(-) diff --git a/backend/src/api/controllers/DebugController.ts b/backend/src/api/controllers/DebugController.ts index e547500..a470c54 100644 --- a/backend/src/api/controllers/DebugController.ts +++ b/backend/src/api/controllers/DebugController.ts @@ -157,7 +157,11 @@ export class DebugController { */ async getObjectTypeStats(req: Request, res: Response): Promise { try { - const typeName = req.params.typeName; + const typeName = Array.isArray(req.params.typeName) ? req.params.typeName[0] : req.params.typeName; + if (!typeName) { + res.status(400).json({ error: 'typeName parameter required' }); + return; + } const services = getServices(); // Get object count @@ -194,7 +198,7 @@ export class DebugController { async getAllObjectTypes(req: Request, res: Response): Promise { try { const services = getServices(); - const db = services.schemaRepo.db; + const db = services.schemaRepo.getDatabaseAdapter(); // Check if object_types table exists try { @@ -243,7 +247,13 @@ export class DebugController { // Get enabled types via service (may fail if table has issues) let enabledTypes: Array<{ typeName: string; displayName: string; schemaId: string; objectTypeId: number }> = []; try { - enabledTypes = await services.schemaSyncService.getEnabledObjectTypes(); + const rawTypes = await services.schemaRepo.getEnabledObjectTypes(); + enabledTypes = rawTypes.map(t => ({ + typeName: t.typeName, + displayName: t.displayName, + schemaId: t.schemaId.toString(), + objectTypeId: t.id, + })); logger.debug(`DebugController: getEnabledObjectTypes returned ${enabledTypes.length} types: ${enabledTypes.map(t => t.typeName).join(', ')}`); } catch (error) { logger.error('DebugController: Failed to get enabled types via service', error); @@ -295,9 +305,13 @@ export class DebugController { */ async diagnoseObjectType(req: Request, res: Response): Promise { try { - const typeName = req.params.typeName; + const typeName = Array.isArray(req.params.typeName) ? req.params.typeName[0] : req.params.typeName; + if (!typeName) { + res.status(400).json({ error: 'typeName parameter required' }); + return; + } const services = getServices(); - const db = services.schemaRepo.db; + const db = services.schemaRepo.getDatabaseAdapter(); const isPostgres = db.isPostgres === true; const enabledCondition = isPostgres ? 'enabled IS true' : 'enabled = 1'; @@ -351,14 +365,14 @@ export class DebugController { // Check enabled types via service let enabledTypesFromService: string[] = []; try { - const enabledTypes = await services.schemaSyncService.getEnabledObjectTypes(); - enabledTypesFromService = enabledTypes.map(t => t.typeName); + const rawTypes = await services.schemaRepo.getEnabledObjectTypes(); + enabledTypesFromService = rawTypes.map((t: { typeName: string }) => t.typeName); } catch (error) { logger.error('DebugController: Failed to get enabled types from service', error); } // Check if type is in enabled list from service - const isInEnabledList = enabledTypesFromService.includes(typeName); + const isInEnabledList = enabledTypesFromService.includes(typeName as string); res.json({ requestedType: typeName, @@ -432,7 +446,7 @@ export class DebugController { async fixMissingTypeNames(req: Request, res: Response): Promise { try { const services = getServices(); - const db = services.schemaRepo.db; + const db = services.schemaRepo.getDatabaseAdapter(); // Find all object types with NULL or empty type_name // Also check for enabled ones specifically @@ -510,15 +524,16 @@ export class DebugController { } // Re-fetch enabled types to verify fix (reuse services from line 294) - const enabledTypesAfterFix = await services.schemaSyncService.getEnabledObjectTypes(); + const rawTypes = await services.schemaRepo.getEnabledObjectTypes(); + const enabledTypesAfterFix = rawTypes.map(t => t.typeName); res.json({ success: true, fixed: fixes.length, - errors: errors.length, + errorCount: errors.length, fixes, errors: errors.length > 0 ? errors : undefined, - enabledTypesAfterFix: enabledTypesAfterFix.map(t => t.typeName), + enabledTypesAfterFix: enabledTypesAfterFix, note: enabledWithNullTypeName.length > 0 ? `Fixed ${enabledWithNullTypeName.length} enabled types that were missing type_name. They should now appear in enabled types list.` : undefined, diff --git a/backend/src/api/controllers/SyncController.ts b/backend/src/api/controllers/SyncController.ts index 724ae16..09ba64a 100644 --- a/backend/src/api/controllers/SyncController.ts +++ b/backend/src/api/controllers/SyncController.ts @@ -14,11 +14,11 @@ export class SyncController { async syncSchemas(req: Request, res: Response): Promise { try { const services = getServices(); - const result = await services.schemaSyncService.syncAllSchemas(); + const result = await services.schemaSyncService.syncAll(); res.json({ - success: true, ...result, + success: result.success !== undefined ? result.success : true, }); } catch (error) { logger.error('SyncController: Failed to sync schemas', error); @@ -38,9 +38,9 @@ export class SyncController { const services = getServices(); // Get enabled types - const enabledTypes = await services.schemaSyncService.getEnabledObjectTypes(); + const rawTypes = await services.schemaRepo.getEnabledObjectTypes(); - if (enabledTypes.length === 0) { + if (rawTypes.length === 0) { res.status(400).json({ success: false, error: 'No object types enabled for syncing. Please configure object types in Schema Configuration.', @@ -54,10 +54,10 @@ export class SyncController { let totalRelations = 0; // Sync each enabled type - for (const type of enabledTypes) { + for (const type of rawTypes) { const result = await services.objectSyncService.syncObjectType( - type.schemaId, - type.objectTypeId, + type.schemaId.toString(), + type.id, type.typeName, type.displayName ); @@ -95,21 +95,31 @@ export class SyncController { */ async syncObjectType(req: Request, res: Response): Promise { try { - const typeName = req.params.typeName; + const typeName = Array.isArray(req.params.typeName) ? req.params.typeName[0] : req.params.typeName; + if (!typeName) { + res.status(400).json({ error: 'typeName parameter required' }); + return; + } const services = getServices(); // Get enabled types - let enabledTypes = await services.schemaSyncService.getEnabledObjectTypes(); + let rawTypes = await services.schemaRepo.getEnabledObjectTypes(); + let enabledTypes = rawTypes.map(t => ({ + typeName: t.typeName, + displayName: t.displayName, + schemaId: t.schemaId.toString(), + objectTypeId: t.id, + })); // Filter out any entries with missing typeName - enabledTypes = enabledTypes.filter(t => t && t.typeName); + enabledTypes = enabledTypes.filter((t: { typeName?: string }) => t && t.typeName); // Debug logging - also check database directly logger.info(`SyncController: Looking for type "${typeName}" in ${enabledTypes.length} enabled types`); - logger.debug(`SyncController: Enabled types: ${JSON.stringify(enabledTypes.map(t => ({ typeName: t?.typeName, displayName: t?.displayName })))}`); + logger.debug(`SyncController: Enabled types: ${JSON.stringify(enabledTypes.map((t: { typeName?: string; displayName?: string }) => ({ typeName: t?.typeName, displayName: t?.displayName })))}`); // Additional debug: Check database directly for enabled types (including those with missing type_name) - const db = services.schemaRepo.db; + const db = services.schemaRepo.getDatabaseAdapter(); const isPostgres = db.isPostgres === true; const enabledCondition = isPostgres ? 'enabled IS true' : 'enabled = 1'; const dbCheck = await db.query<{ type_name: string | null; display_name: string; enabled: boolean | number; id: number; jira_type_id: number }>( @@ -119,9 +129,10 @@ export class SyncController { logger.debug(`SyncController: Database enabled types (raw): ${JSON.stringify(dbCheck.map(t => ({ id: t.id, displayName: t.display_name, typeName: t.type_name, hasTypeName: !!(t.type_name && t.type_name.trim() !== '') })))}`); // Check if AzureSubscription or similar is enabled but missing type_name - const matchingByDisplayName = dbCheck.filter(t => - t.display_name.toLowerCase().includes(typeName.toLowerCase()) || - typeName.toLowerCase().includes(t.display_name.toLowerCase()) + const typeNameLower = typeName.toLowerCase(); + const matchingByDisplayName = dbCheck.filter((t: { display_name: string }) => + t.display_name.toLowerCase().includes(typeNameLower) || + typeNameLower.includes(t.display_name.toLowerCase()) ); if (matchingByDisplayName.length > 0) { logger.warn(`SyncController: Found enabled type(s) matching "${typeName}" by display_name but not in enabled list:`, { @@ -135,7 +146,7 @@ export class SyncController { }); } - const type = enabledTypes.find(t => t && t.typeName === typeName); + const type = enabledTypes.find((t: { typeName?: string }) => t && t.typeName === typeName); if (!type) { // Check if type exists but is not enabled or has missing type_name @@ -148,12 +159,13 @@ export class SyncController { logger.debug(`SyncController: Enabled types details: ${JSON.stringify(enabledTypes)}`); // Try to find it with different case (handle undefined typeName) - const caseInsensitiveMatch = enabledTypes.find(t => t && t.typeName && t.typeName.toLowerCase() === typeName.toLowerCase()); + const typeNameLower = typeName.toLowerCase(); + const caseInsensitiveMatch = enabledTypes.find((t: { typeName?: string }) => t && t.typeName && t.typeName.toLowerCase() === typeNameLower); if (caseInsensitiveMatch) { logger.warn(`SyncController: Found type with different case: "${caseInsensitiveMatch.typeName}" vs "${typeName}"`); // Use the found type with correct case const result = await services.objectSyncService.syncObjectType( - caseInsensitiveMatch.schemaId, + caseInsensitiveMatch.schemaId.toString(), caseInsensitiveMatch.objectTypeId, caseInsensitiveMatch.typeName, caseInsensitiveMatch.displayName @@ -168,7 +180,7 @@ export class SyncController { } // Direct SQL query to verify enabled status and type_name - const db = services.schemaRepo.db; + const db = services.schemaRepo.getDatabaseAdapter(); const isPostgres = db.isPostgres === true; const rawCheck = await db.queryOne<{ enabled: boolean | number; type_name: string | null; display_name: string }>( `SELECT enabled, type_name, display_name FROM object_types WHERE type_name = ?`, @@ -183,7 +195,7 @@ export class SyncController { ); // Get list of all enabled type names for better error message - const enabledTypeNames = enabledTypes.map(t => t.typeName).filter(Boolean); + const enabledTypeNames = enabledTypes.map((t: { typeName?: string }) => t.typeName).filter(Boolean) as string[]; // Check if the issue is that the type is enabled but has a missing type_name if (rawCheck && (rawCheck.enabled === true || rawCheck.enabled === 1)) { @@ -221,7 +233,7 @@ export class SyncController { }); } else { // Type not found by type_name - check by display_name (case-insensitive) - const db = services.schemaRepo.db; + const db = services.schemaRepo.getDatabaseAdapter(); const byDisplayName = await db.queryOne<{ enabled: boolean | number; type_name: string | null; display_name: string }>( `SELECT enabled, type_name, display_name FROM object_types WHERE display_name ILIKE ? LIMIT 1`, [`%${typeName}%`] @@ -247,14 +259,14 @@ export class SyncController { res.status(400).json({ success: false, - error: `Object type ${typeName} not found. Available enabled types: ${enabledTypes.map(t => t.typeName).join(', ') || 'none'}. Please run schema sync first.`, + error: `Object type ${typeName} not found. Available enabled types: ${enabledTypes.map((t: { typeName?: string }) => t.typeName).filter(Boolean).join(', ') || 'none'}. Please run schema sync first.`, }); } return; } const result = await services.objectSyncService.syncObjectType( - type.schemaId, + type.schemaId.toString(), type.objectTypeId, type.typeName, type.displayName diff --git a/backend/src/index.ts b/backend/src/index.ts index 626ef1b..6cc4ca4 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -249,7 +249,7 @@ app.listen(PORT, async () => { if (db) { await db.ensureInitialized?.(); try { - const schemaRow = await db.queryOne<{ count: number }>( + const schemaRow = await (db as any).queryOne<{ count: number }>( `SELECT COUNT(*) as count FROM schemas` ); hasSchemas = (schemaRow?.count || 0) > 0; diff --git a/backend/src/repositories/SchemaRepository.ts b/backend/src/repositories/SchemaRepository.ts index 9612830..140ba5b 100644 --- a/backend/src/repositories/SchemaRepository.ts +++ b/backend/src/repositories/SchemaRepository.ts @@ -47,6 +47,13 @@ export interface AttributeRecord { export class SchemaRepository { constructor(private db: DatabaseAdapter) {} + + /** + * Get database adapter (for debug/advanced operations) + */ + getDatabaseAdapter(): DatabaseAdapter { + return this.db; + } /** * Upsert a schema diff --git a/backend/src/routes/schema.ts b/backend/src/routes/schema.ts index 82a4048..b8c24ad 100644 --- a/backend/src/routes/schema.ts +++ b/backend/src/routes/schema.ts @@ -98,7 +98,6 @@ router.post('/discover', requirePermission('manage_settings'), async (req, res) schemaCacheService.invalidate(); // Invalidate cache res.json({ - success: result.success, message: 'Schema synchronization completed', ...result, }); diff --git a/backend/src/routes/schemaConfiguration.ts b/backend/src/routes/schemaConfiguration.ts index 45301d9..619edb2 100644 --- a/backend/src/routes/schemaConfiguration.ts +++ b/backend/src/routes/schemaConfiguration.ts @@ -43,7 +43,6 @@ router.post('/discover', async (req: Request, res: Response) => { if (result.schemasProcessed === 0) { logger.warn('Schema configuration: Sync returned 0 schemas - this might indicate an API issue'); res.status(400).json({ - success: false, message: 'No schemas found. Please check: 1) JIRA_SERVICE_ACCOUNT_TOKEN is configured correctly, 2) Jira Assets API is accessible, 3) API endpoint /rest/assets/1.0/objectschema/list is available', ...result, }); @@ -51,7 +50,6 @@ router.post('/discover', async (req: Request, res: Response) => { } res.json({ - success: result.success, message: 'Schema synchronization completed successfully', schemasDiscovered: result.schemasProcessed, objectTypesDiscovered: result.objectTypesProcessed, @@ -88,7 +86,11 @@ router.get('/object-types', async (req: Request, res: Response) => { */ router.patch('/object-types/:id/enabled', async (req: Request, res: Response) => { try { - const id = req.params.id; + const id = Array.isArray(req.params.id) ? req.params.id[0] : req.params.id; + if (!id) { + res.status(400).json({ error: 'id parameter required' }); + return; + } const { enabled } = req.body; if (typeof enabled !== 'boolean') { @@ -187,7 +189,12 @@ router.patch('/schemas/:schemaId/search-enabled', async (req: Request, res: Resp return; } - await schemaConfigurationService.setSchemaSearchEnabled(schemaId, searchEnabled); + const schemaIdStr = Array.isArray(schemaId) ? schemaId[0] : schemaId; + if (!schemaIdStr) { + res.status(400).json({ error: 'schemaId parameter required' }); + return; + } + await schemaConfigurationService.setSchemaSearchEnabled(schemaIdStr, searchEnabled); res.json({ status: 'success', diff --git a/backend/src/services/SchemaSyncService.ts b/backend/src/services/SchemaSyncService.ts index d009e76..d4e79b4 100644 --- a/backend/src/services/SchemaSyncService.ts +++ b/backend/src/services/SchemaSyncService.ts @@ -132,7 +132,7 @@ export interface SyncProgress { // SchemaSyncService Implementation // ============================================================================= -class SchemaSyncService { +export class SchemaSyncService { private db: DatabaseAdapter; private isPostgres: boolean; private baseUrl: string; @@ -342,7 +342,7 @@ class SchemaSyncService { // CRITICAL: Jira sometimes returns type=1 (integer) for reference attributes! // The presence of referenceObjectTypeId is the true indicator of a reference type. - const refTypeId = attr.referenceObjectTypeId || attr.referenceObject?.id || attr.referenceType?.id; + const refTypeId = attr.referenceObjectTypeId || attr.referenceObjectType?.id || attr.referenceType?.id; if (refTypeId) { type = 'reference'; } diff --git a/backend/src/services/ServiceFactory.ts b/backend/src/services/ServiceFactory.ts index 77b9282..7aaf5a1 100644 --- a/backend/src/services/ServiceFactory.ts +++ b/backend/src/services/ServiceFactory.ts @@ -40,7 +40,7 @@ export class ServiceFactory { this.cacheRepo = new ObjectCacheRepository(db); // Initialize services - this.schemaSyncService = new SchemaSyncService(this.schemaRepo); + this.schemaSyncService = new SchemaSyncService(); this.objectSyncService = new ObjectSyncService(this.schemaRepo, this.cacheRepo); this.payloadProcessor = new PayloadProcessor(this.schemaRepo, this.cacheRepo); this.queryService = new QueryService(this.schemaRepo, this.cacheRepo); diff --git a/backend/src/services/biaMatchingService.ts b/backend/src/services/biaMatchingService.ts index 9a4a919..8b71680 100644 --- a/backend/src/services/biaMatchingService.ts +++ b/backend/src/services/biaMatchingService.ts @@ -105,8 +105,9 @@ export async function loadBIAData(): Promise { // Read file using readFileSync and then parse with ExcelJS const fileBuffer = readFileSync(biaFilePath); const workbook = new ExcelJS.Workbook(); - // ExcelJS accepts Buffer, but TypeScript types may be strict - use type assertion - await workbook.xlsx.load(fileBuffer as Buffer); + // ExcelJS accepts Buffer, but TypeScript types may be strict + // Use type assertion to satisfy TypeScript's strict Buffer type checking + await workbook.xlsx.load(fileBuffer as any); const worksheet = workbook.worksheets[0]; // First sheet // Converteer naar 2D array formaat (zoals xlsx.utils.sheet_to_json met header: 1) diff --git a/backend/src/services/cmdbService.ts b/backend/src/services/cmdbService.ts index 4713e93..fb1b0d3 100644 --- a/backend/src/services/cmdbService.ts +++ b/backend/src/services/cmdbService.ts @@ -98,7 +98,7 @@ class CMDBService { if (result.objects.length === 0) return null; - const parsed = jiraAssetsClient.parseObject(result.objects[0]); + const parsed = await jiraAssetsClient.parseObject(result.objects[0]); if (parsed) { await cacheStore.upsertObject(typeName, parsed); await cacheStore.extractAndStoreRelations(typeName, parsed); @@ -212,7 +212,7 @@ class CMDBService { }); const batchResults = await Promise.all(batchPromises); - const validResults = batchResults.filter((obj): obj is T => obj !== null); + const validResults = batchResults.filter((obj): obj is NonNullable => obj !== null) as T[]; results.push(...validResults); } diff --git a/backend/src/services/database/migrate-to-normalized-schema.ts b/backend/src/services/database/migrate-to-normalized-schema.ts index 35421f4..d217a8e 100644 --- a/backend/src/services/database/migrate-to-normalized-schema.ts +++ b/backend/src/services/database/migrate-to-normalized-schema.ts @@ -11,6 +11,7 @@ import { logger } from '../logger.js'; import { normalizedCacheStore } from '../normalizedCacheStore.js'; +import type { DatabaseAdapter } from './interface.js'; export async function migrateToNormalizedSchema(): Promise { const db = (normalizedCacheStore as any).db; @@ -23,7 +24,7 @@ export async function migrateToNormalizedSchema(): Promise { logger.info('Migration: Starting migration to normalized schema structure...'); try { - await db.transaction(async (txDb) => { + await db.transaction(async (txDb: DatabaseAdapter) => { // Step 1: Check if configured_object_types table exists let configuredTableExists = false; try { @@ -172,14 +173,14 @@ export async function migrateToNormalizedSchema(): Promise { FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'object_types' `); - hasSchemaId = columns.some(c => c.column_name === 'schema_id'); - hasEnabled = columns.some(c => c.column_name === 'enabled'); + hasSchemaId = columns.some((c: { column_name: string }) => c.column_name === 'schema_id'); + hasEnabled = columns.some((c: { column_name: string }) => c.column_name === 'enabled'); } else { const tableInfo = await txDb.query<{ name: string }>(` PRAGMA table_info(object_types) `); - hasSchemaId = tableInfo.some(c => c.name === 'schema_id'); - hasEnabled = tableInfo.some(c => c.name === 'enabled'); + hasSchemaId = tableInfo.some((c: { name: string }) => c.name === 'schema_id'); + hasEnabled = tableInfo.some((c: { name: string }) => c.name === 'enabled'); } } catch (error) { logger.warn('Migration: Could not check object_types columns', error); diff --git a/backend/src/services/jiraAssets.ts b/backend/src/services/jiraAssets.ts index 180331b..a4d652a 100644 --- a/backend/src/services/jiraAssets.ts +++ b/backend/src/services/jiraAssets.ts @@ -15,6 +15,7 @@ import type { ApplicationUpdateRequest, TeamDashboardData, } from '../types/index.js'; +import type { CMDBObjectTypeName } from '../generated/jira-types.js'; // Attribute name mappings (these should match your Jira Assets schema) const ATTRIBUTE_NAMES = { @@ -149,7 +150,7 @@ class JiraAssetsService { `SELECT DISTINCT jira_schema_id FROM schemas WHERE search_enabled = ? ORDER BY jira_schema_id`, [db.isPostgres ? true : 1] ); - return schemaRows.map(row => row.jira_schema_id); + return schemaRows.map((row: { jira_schema_id: string }) => row.jira_schema_id); } catch (error) { logger.warn('JiraAssets: Failed to get all schema IDs', error); return []; diff --git a/backend/src/services/normalizedCacheStore.ts b/backend/src/services/normalizedCacheStore.ts index c2f67c1..0ea1d78 100644 --- a/backend/src/services/normalizedCacheStore.ts +++ b/backend/src/services/normalizedCacheStore.ts @@ -14,6 +14,7 @@ import { schemaDiscoveryService } from './schemaDiscoveryService.js'; import { queryBuilder } from './queryBuilder.js'; import { NORMALIZED_SCHEMA_POSTGRES, NORMALIZED_SCHEMA_SQLITE } from './database/normalized-schema.js'; import type { AttributeDefinition } from '../generated/jira-schema.js'; +import { jiraAssetsClient } from './jiraAssetsClient.js'; // Re-export interfaces for compatibility export interface CacheStats { @@ -246,7 +247,7 @@ class NormalizedCacheStore { rows.map(row => this.reconstructObject(row.id, typeName)) ); - const validObjects = objects.filter((obj): obj is T => obj !== null); + const validObjects = objects.filter((obj): obj is NonNullable => obj !== null) as T[]; logger.debug(`NormalizedCacheStore: Successfully reconstructed ${validObjects.length}/${rows.length} objects of type ${typeName}`); return validObjects; @@ -294,7 +295,7 @@ class NormalizedCacheStore { rows.map(row => this.reconstructObject(row.id, typeName)) ); - return objects.filter((obj): obj is T => obj !== null); + return objects.filter((obj): obj is NonNullable => obj !== null) as T[]; } /** @@ -1129,8 +1130,9 @@ class NormalizedCacheStore { `, [id]); if (row) { - this.referenceCache.set(id, row); - return row; + const cached = { id: row.id, objectKey: row.object_key, label: row.label }; + this.referenceCache.set(id, cached); + return cached; } return null; @@ -1190,7 +1192,7 @@ class NormalizedCacheStore { ); return { - objects: objects.filter((obj): obj is T => obj !== null), + objects: objects.filter((obj): obj is NonNullable => obj !== null) as T[], total }; } catch (error) { @@ -1363,7 +1365,7 @@ class NormalizedCacheStore { rows.map(row => this.reconstructObject(row.id, targetTypeName)) ); - return objects.filter((obj): obj is T => obj !== null); + return objects.filter((obj): obj is NonNullable => obj !== null) as T[]; } /** @@ -1424,7 +1426,7 @@ class NormalizedCacheStore { rows.map(row => this.reconstructObject(row.id, sourceTypeName)) ); - const validObjects = objects.filter((obj): obj is T => obj !== null); + const validObjects = objects.filter((obj): obj is NonNullable => obj !== null) as T[]; logger.debug(`NormalizedCacheStore: Successfully reconstructed ${validObjects.length} objects`); return validObjects; diff --git a/backend/src/services/schemaMappingService.ts b/backend/src/services/schemaMappingService.ts index 50c5f9f..2555048 100644 --- a/backend/src/services/schemaMappingService.ts +++ b/backend/src/services/schemaMappingService.ts @@ -73,7 +73,7 @@ class SchemaMappingService { ORDER BY object_type_name `); - return rows.map(row => ({ + return rows.map((row: { object_type_name: string; schema_id: string; enabled: boolean | number; created_at: string; updated_at: string }) => ({ objectTypeName: row.object_type_name, schemaId: row.schema_id, enabled: typeof row.enabled === 'boolean' ? row.enabled : row.enabled === 1, @@ -283,7 +283,7 @@ class SchemaMappingService { logger.warn('SchemaMapping: Failed to get default schema ID from database', error); } - return rows.map(row => ({ + return rows.map((row: { type_name: string; display_name: string; description: string | null; schema_id: string; enabled: boolean | number; created_at: string; updated_at: string }) => ({ typeName: row.type_name, displayName: row.display_name, description: row.description, @@ -291,8 +291,8 @@ class SchemaMappingService { enabled: row.enabled === null ? true // Default: enabled if no mapping exists : (typeof row.enabled === 'boolean' ? row.enabled : row.enabled === 1), - objectCount: row.object_count, - syncPriority: row.sync_priority, + objectCount: (row as any).object_count || 0, + syncPriority: (row as any).sync_priority || 0, })); } catch (error) { logger.error('SchemaMappingService: Failed to get object types with config', error);