From 7e9022bf9bf4c43cc4e25ffe5021ffb1ca09093e Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Thu, 5 Feb 2026 19:26:34 -0600 Subject: [PATCH] fix(CQ-API-3): Make activity logging fire-and-forget Activity logging now catches and logs errors without propagating them. This ensures activity logging failures never break primary operations. Updated return type to ActivityLog | null to indicate potential failure. Refs #339 Co-Authored-By: Claude Opus 4.5 --- apps/api/src/activity/activity.service.ts | 61 +++++++++++++---------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/apps/api/src/activity/activity.service.ts b/apps/api/src/activity/activity.service.ts index 4271daf..ce11d50 100644 --- a/apps/api/src/activity/activity.service.ts +++ b/apps/api/src/activity/activity.service.ts @@ -18,16 +18,25 @@ export class ActivityService { constructor(private readonly prisma: PrismaService) {} /** - * Create a new activity log entry + * Create a new activity log entry (fire-and-forget) + * + * Activity logging failures are logged but never propagate to callers. + * This ensures activity logging never breaks primary operations. + * + * @returns The created ActivityLog or null if logging failed */ - async logActivity(input: CreateActivityLogInput): Promise { + async logActivity(input: CreateActivityLogInput): Promise { try { return await this.prisma.activityLog.create({ data: input as unknown as Prisma.ActivityLogCreateInput, }); } catch (error) { - this.logger.error("Failed to log activity", error); - throw error; + // Log the error but don't propagate - activity logging is fire-and-forget + this.logger.error( + `Failed to log activity: action=${input.action} entityType=${input.entityType} entityId=${input.entityId}`, + error instanceof Error ? error.stack : String(error) + ); + return null; } } @@ -167,7 +176,7 @@ export class ActivityService { userId: string, taskId: string, details?: Prisma.JsonValue - ): Promise { + ): Promise { return this.logActivity({ workspaceId, userId, @@ -186,7 +195,7 @@ export class ActivityService { userId: string, taskId: string, details?: Prisma.JsonValue - ): Promise { + ): Promise { return this.logActivity({ workspaceId, userId, @@ -205,7 +214,7 @@ export class ActivityService { userId: string, taskId: string, details?: Prisma.JsonValue - ): Promise { + ): Promise { return this.logActivity({ workspaceId, userId, @@ -224,7 +233,7 @@ export class ActivityService { userId: string, taskId: string, details?: Prisma.JsonValue - ): Promise { + ): Promise { return this.logActivity({ workspaceId, userId, @@ -243,7 +252,7 @@ export class ActivityService { userId: string, taskId: string, assigneeId: string - ): Promise { + ): Promise { return this.logActivity({ workspaceId, userId, @@ -262,7 +271,7 @@ export class ActivityService { userId: string, eventId: string, details?: Prisma.JsonValue - ): Promise { + ): Promise { return this.logActivity({ workspaceId, userId, @@ -281,7 +290,7 @@ export class ActivityService { userId: string, eventId: string, details?: Prisma.JsonValue - ): Promise { + ): Promise { return this.logActivity({ workspaceId, userId, @@ -300,7 +309,7 @@ export class ActivityService { userId: string, eventId: string, details?: Prisma.JsonValue - ): Promise { + ): Promise { return this.logActivity({ workspaceId, userId, @@ -319,7 +328,7 @@ export class ActivityService { userId: string, projectId: string, details?: Prisma.JsonValue - ): Promise { + ): Promise { return this.logActivity({ workspaceId, userId, @@ -338,7 +347,7 @@ export class ActivityService { userId: string, projectId: string, details?: Prisma.JsonValue - ): Promise { + ): Promise { return this.logActivity({ workspaceId, userId, @@ -357,7 +366,7 @@ export class ActivityService { userId: string, projectId: string, details?: Prisma.JsonValue - ): Promise { + ): Promise { return this.logActivity({ workspaceId, userId, @@ -375,7 +384,7 @@ export class ActivityService { workspaceId: string, userId: string, details?: Prisma.JsonValue - ): Promise { + ): Promise { return this.logActivity({ workspaceId, userId, @@ -393,7 +402,7 @@ export class ActivityService { workspaceId: string, userId: string, details?: Prisma.JsonValue - ): Promise { + ): Promise { return this.logActivity({ workspaceId, userId, @@ -412,7 +421,7 @@ export class ActivityService { userId: string, memberId: string, role: string - ): Promise { + ): Promise { return this.logActivity({ workspaceId, userId, @@ -430,7 +439,7 @@ export class ActivityService { workspaceId: string, userId: string, memberId: string - ): Promise { + ): Promise { return this.logActivity({ workspaceId, userId, @@ -448,7 +457,7 @@ export class ActivityService { workspaceId: string, userId: string, details?: Prisma.JsonValue - ): Promise { + ): Promise { return this.logActivity({ workspaceId, userId, @@ -467,7 +476,7 @@ export class ActivityService { userId: string, domainId: string, details?: Prisma.JsonValue - ): Promise { + ): Promise { return this.logActivity({ workspaceId, userId, @@ -486,7 +495,7 @@ export class ActivityService { userId: string, domainId: string, details?: Prisma.JsonValue - ): Promise { + ): Promise { return this.logActivity({ workspaceId, userId, @@ -505,7 +514,7 @@ export class ActivityService { userId: string, domainId: string, details?: Prisma.JsonValue - ): Promise { + ): Promise { return this.logActivity({ workspaceId, userId, @@ -524,7 +533,7 @@ export class ActivityService { userId: string, ideaId: string, details?: Prisma.JsonValue - ): Promise { + ): Promise { return this.logActivity({ workspaceId, userId, @@ -543,7 +552,7 @@ export class ActivityService { userId: string, ideaId: string, details?: Prisma.JsonValue - ): Promise { + ): Promise { return this.logActivity({ workspaceId, userId, @@ -562,7 +571,7 @@ export class ActivityService { userId: string, ideaId: string, details?: Prisma.JsonValue - ): Promise { + ): Promise { return this.logActivity({ workspaceId, userId,