diff --git a/src/decisions/decisions.service.ts b/src/decisions/decisions.service.ts index 911a1a2..1c40a2f 100644 --- a/src/decisions/decisions.service.ts +++ b/src/decisions/decisions.service.ts @@ -26,49 +26,53 @@ export class DecisionsService { } async create(session: AuthenticatedSession, dto: CreateDecisionDto) { - const [row] = await db - .insert(decisions) - .values({ + return db.transaction(async (tx) => { + const [row] = await tx + .insert(decisions) + .values({ + tenantId: session.tenantId, + ownerUserId: session.userId, + context: dto.context, + options: (dto.options ?? []) as unknown[], + assumptions: (dto.assumptions ?? []) as unknown[], + evidence: (dto.evidence ?? []) as unknown[], + reviewDueAt: dto.reviewDueAt ? new Date(dto.reviewDueAt) : undefined, + }) + .returning(); + await this.audit.record(tx, { tenantId: session.tenantId, - ownerUserId: session.userId, - context: dto.context, - options: (dto.options ?? []) as unknown[], - assumptions: (dto.assumptions ?? []) as unknown[], - evidence: (dto.evidence ?? []) as unknown[], - reviewDueAt: dto.reviewDueAt ? new Date(dto.reviewDueAt) : undefined, - }) - .returning(); - await this.audit.record(null, { - tenantId: session.tenantId, - actorId: session.userId, - action: 'decision.created', - resource: `decision:${row.id}`, + actorId: session.userId, + action: 'decision.created', + resource: `decision:${row.id}`, + }); + return row; }); - return row; } async update(session: AuthenticatedSession, id: string, dto: UpdateDecisionDto) { await this.getById(session, id); - const [row] = await db - .update(decisions) - .set({ - ...(dto.context !== undefined ? { context: dto.context } : {}), - ...(dto.options !== undefined ? { options: dto.options as unknown[] } : {}), - ...(dto.assumptions !== undefined ? { assumptions: dto.assumptions as unknown[] } : {}), - ...(dto.evidence !== undefined ? { evidence: dto.evidence as unknown[] } : {}), - ...(dto.selectedOption !== undefined ? { selectedOption: dto.selectedOption } : {}), - ...(dto.outcomeReview !== undefined ? { outcomeReview: dto.outcomeReview } : {}), - ...(dto.reviewDueAt !== undefined ? { reviewDueAt: new Date(dto.reviewDueAt) } : {}), - updatedAt: new Date(), - }) - .where(and(eq(decisions.id, id), eq(decisions.tenantId, session.tenantId))) - .returning(); - await this.audit.record(null, { - tenantId: session.tenantId, - actorId: session.userId, - action: dto.selectedOption !== undefined ? 'decision.option_selected' : 'decision.updated', - resource: `decision:${id}`, + return db.transaction(async (tx) => { + const [row] = await tx + .update(decisions) + .set({ + ...(dto.context !== undefined ? { context: dto.context } : {}), + ...(dto.options !== undefined ? { options: dto.options as unknown[] } : {}), + ...(dto.assumptions !== undefined ? { assumptions: dto.assumptions as unknown[] } : {}), + ...(dto.evidence !== undefined ? { evidence: dto.evidence as unknown[] } : {}), + ...(dto.selectedOption !== undefined ? { selectedOption: dto.selectedOption } : {}), + ...(dto.outcomeReview !== undefined ? { outcomeReview: dto.outcomeReview } : {}), + ...(dto.reviewDueAt !== undefined ? { reviewDueAt: new Date(dto.reviewDueAt) } : {}), + updatedAt: new Date(), + }) + .where(and(eq(decisions.id, id), eq(decisions.tenantId, session.tenantId))) + .returning(); + await this.audit.record(tx, { + tenantId: session.tenantId, + actorId: session.userId, + action: dto.selectedOption !== undefined ? 'decision.option_selected' : 'decision.updated', + resource: `decision:${id}`, + }); + return row; }); - return row; } }