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 <noreply@anthropic.com>
This commit is contained in:
Jason Woltje
2026-02-05 19:26:34 -06:00
parent 722b16a903
commit 7e9022bf9b

View File

@@ -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<ActivityLog> {
async logActivity(input: CreateActivityLogInput): Promise<ActivityLog | null> {
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<ActivityLog> {
): Promise<ActivityLog | null> {
return this.logActivity({
workspaceId,
userId,
@@ -186,7 +195,7 @@ export class ActivityService {
userId: string,
taskId: string,
details?: Prisma.JsonValue
): Promise<ActivityLog> {
): Promise<ActivityLog | null> {
return this.logActivity({
workspaceId,
userId,
@@ -205,7 +214,7 @@ export class ActivityService {
userId: string,
taskId: string,
details?: Prisma.JsonValue
): Promise<ActivityLog> {
): Promise<ActivityLog | null> {
return this.logActivity({
workspaceId,
userId,
@@ -224,7 +233,7 @@ export class ActivityService {
userId: string,
taskId: string,
details?: Prisma.JsonValue
): Promise<ActivityLog> {
): Promise<ActivityLog | null> {
return this.logActivity({
workspaceId,
userId,
@@ -243,7 +252,7 @@ export class ActivityService {
userId: string,
taskId: string,
assigneeId: string
): Promise<ActivityLog> {
): Promise<ActivityLog | null> {
return this.logActivity({
workspaceId,
userId,
@@ -262,7 +271,7 @@ export class ActivityService {
userId: string,
eventId: string,
details?: Prisma.JsonValue
): Promise<ActivityLog> {
): Promise<ActivityLog | null> {
return this.logActivity({
workspaceId,
userId,
@@ -281,7 +290,7 @@ export class ActivityService {
userId: string,
eventId: string,
details?: Prisma.JsonValue
): Promise<ActivityLog> {
): Promise<ActivityLog | null> {
return this.logActivity({
workspaceId,
userId,
@@ -300,7 +309,7 @@ export class ActivityService {
userId: string,
eventId: string,
details?: Prisma.JsonValue
): Promise<ActivityLog> {
): Promise<ActivityLog | null> {
return this.logActivity({
workspaceId,
userId,
@@ -319,7 +328,7 @@ export class ActivityService {
userId: string,
projectId: string,
details?: Prisma.JsonValue
): Promise<ActivityLog> {
): Promise<ActivityLog | null> {
return this.logActivity({
workspaceId,
userId,
@@ -338,7 +347,7 @@ export class ActivityService {
userId: string,
projectId: string,
details?: Prisma.JsonValue
): Promise<ActivityLog> {
): Promise<ActivityLog | null> {
return this.logActivity({
workspaceId,
userId,
@@ -357,7 +366,7 @@ export class ActivityService {
userId: string,
projectId: string,
details?: Prisma.JsonValue
): Promise<ActivityLog> {
): Promise<ActivityLog | null> {
return this.logActivity({
workspaceId,
userId,
@@ -375,7 +384,7 @@ export class ActivityService {
workspaceId: string,
userId: string,
details?: Prisma.JsonValue
): Promise<ActivityLog> {
): Promise<ActivityLog | null> {
return this.logActivity({
workspaceId,
userId,
@@ -393,7 +402,7 @@ export class ActivityService {
workspaceId: string,
userId: string,
details?: Prisma.JsonValue
): Promise<ActivityLog> {
): Promise<ActivityLog | null> {
return this.logActivity({
workspaceId,
userId,
@@ -412,7 +421,7 @@ export class ActivityService {
userId: string,
memberId: string,
role: string
): Promise<ActivityLog> {
): Promise<ActivityLog | null> {
return this.logActivity({
workspaceId,
userId,
@@ -430,7 +439,7 @@ export class ActivityService {
workspaceId: string,
userId: string,
memberId: string
): Promise<ActivityLog> {
): Promise<ActivityLog | null> {
return this.logActivity({
workspaceId,
userId,
@@ -448,7 +457,7 @@ export class ActivityService {
workspaceId: string,
userId: string,
details?: Prisma.JsonValue
): Promise<ActivityLog> {
): Promise<ActivityLog | null> {
return this.logActivity({
workspaceId,
userId,
@@ -467,7 +476,7 @@ export class ActivityService {
userId: string,
domainId: string,
details?: Prisma.JsonValue
): Promise<ActivityLog> {
): Promise<ActivityLog | null> {
return this.logActivity({
workspaceId,
userId,
@@ -486,7 +495,7 @@ export class ActivityService {
userId: string,
domainId: string,
details?: Prisma.JsonValue
): Promise<ActivityLog> {
): Promise<ActivityLog | null> {
return this.logActivity({
workspaceId,
userId,
@@ -505,7 +514,7 @@ export class ActivityService {
userId: string,
domainId: string,
details?: Prisma.JsonValue
): Promise<ActivityLog> {
): Promise<ActivityLog | null> {
return this.logActivity({
workspaceId,
userId,
@@ -524,7 +533,7 @@ export class ActivityService {
userId: string,
ideaId: string,
details?: Prisma.JsonValue
): Promise<ActivityLog> {
): Promise<ActivityLog | null> {
return this.logActivity({
workspaceId,
userId,
@@ -543,7 +552,7 @@ export class ActivityService {
userId: string,
ideaId: string,
details?: Prisma.JsonValue
): Promise<ActivityLog> {
): Promise<ActivityLog | null> {
return this.logActivity({
workspaceId,
userId,
@@ -562,7 +571,7 @@ export class ActivityService {
userId: string,
ideaId: string,
details?: Prisma.JsonValue
): Promise<ActivityLog> {
): Promise<ActivityLog | null> {
return this.logActivity({
workspaceId,
userId,