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
This commit is contained in:
@@ -157,7 +157,11 @@ export class DebugController {
|
||||
*/
|
||||
async getObjectTypeStats(req: Request, res: Response): Promise<void> {
|
||||
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<void> {
|
||||
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<void> {
|
||||
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<void> {
|
||||
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,
|
||||
|
||||
@@ -14,11 +14,11 @@ export class SyncController {
|
||||
async syncSchemas(req: Request, res: Response): Promise<void> {
|
||||
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<void> {
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user