fix(audit): reorder routes to fix NestJS route collision

Move specific routes (logs/actions, logs/entity-types) before
parameterized route (logs/:id) to prevent NestJS from matching
'actions' and 'entity-types' as UUID parameters.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-01-25 08:40:56 -08:00
parent f95bc71254
commit ed5dc49b4a
1 changed files with 59 additions and 56 deletions

View File

@ -76,23 +76,59 @@ export class AuditController {
} }
/** /**
* GET /audit/logs/:id * GET /audit/logs/actions
* Get single audit log detail * Get list of available action types
* NOTE: This must be defined BEFORE logs/:id to avoid route collision
*/ */
@Get('logs/:id') @Get('logs/actions')
async getAuditLogDetail( async getActionTypes(
@Headers('authorization') auth: string, @Headers('authorization') auth: string,
@Param('id') id: string, ): Promise<{ actions: string[] }> {
): Promise<AuditLogDto> {
await this.verifyAdmin(auth); await this.verifyAdmin(auth);
const log = await this.auditLogService.getLog(id); // Common action types
return {
actions: [
'CREATE',
'UPDATE',
'DELETE',
'LOGIN',
'LOGOUT',
'PAYMENT',
'REFUND',
'EXPORT',
'IMPORT',
'DAILY_STATS_AGGREGATION',
'MONTHLY_REPORT_GENERATION',
],
};
}
if (!log) { /**
throw new NotFoundException('Audit log not found'); * GET /audit/logs/entity-types
} * Get list of entity types
* NOTE: This must be defined BEFORE logs/:id to avoid route collision
*/
@Get('logs/entity-types')
async getEntityTypes(
@Headers('authorization') auth: string,
): Promise<{ entityTypes: string[] }> {
await this.verifyAdmin(auth);
return log; return {
entityTypes: [
'User',
'Conversation',
'Message',
'Order',
'Payment',
'Admin',
'KnowledgeArticle',
'Experience',
'DailyStatistics',
'MonthlyFinancialReport',
],
};
} }
/** /**
@ -130,56 +166,23 @@ export class AuditController {
} }
/** /**
* GET /audit/logs/actions * GET /audit/logs/:id
* Get list of available action types * Get single audit log detail
* NOTE: This must be defined LAST to avoid matching "actions", "entity-types", etc. as :id
*/ */
@Get('logs/actions') @Get('logs/:id')
async getActionTypes( async getAuditLogDetail(
@Headers('authorization') auth: string, @Headers('authorization') auth: string,
): Promise<{ actions: string[] }> { @Param('id') id: string,
): Promise<AuditLogDto> {
await this.verifyAdmin(auth); await this.verifyAdmin(auth);
// Common action types const log = await this.auditLogService.getLog(id);
return {
actions: [
'CREATE',
'UPDATE',
'DELETE',
'LOGIN',
'LOGOUT',
'PAYMENT',
'REFUND',
'EXPORT',
'IMPORT',
'DAILY_STATS_AGGREGATION',
'MONTHLY_REPORT_GENERATION',
],
};
}
/** if (!log) {
* GET /audit/logs/entity-types throw new NotFoundException('Audit log not found');
* Get list of entity types }
*/
@Get('logs/entity-types')
async getEntityTypes(
@Headers('authorization') auth: string,
): Promise<{ entityTypes: string[] }> {
await this.verifyAdmin(auth);
return { return log;
entityTypes: [
'User',
'Conversation',
'Message',
'Order',
'Payment',
'Admin',
'KnowledgeArticle',
'Experience',
'DailyStatistics',
'MonthlyFinancialReport',
],
};
} }
} }