feat(decisions): add decisions.service
This commit is contained in:
parent
df054750f2
commit
b60c255080
1 changed files with 74 additions and 0 deletions
74
src/decisions/decisions.service.ts
Normal file
74
src/decisions/decisions.service.ts
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { and, desc, eq } from 'drizzle-orm';
|
||||
import { db } from '../db/client';
|
||||
import { decisions } from '../db/schema';
|
||||
import { AuditService } from '../audit/audit.service';
|
||||
import type { AuthenticatedSession } from '../auth/tenant.guard';
|
||||
import type { CreateDecisionDto, UpdateDecisionDto } from './dto';
|
||||
|
||||
@Injectable()
|
||||
export class DecisionsService {
|
||||
constructor(private readonly audit: AuditService) {}
|
||||
|
||||
async list(session: AuthenticatedSession) {
|
||||
return db.query.decisions.findMany({
|
||||
where: eq(decisions.tenantId, session.tenantId),
|
||||
orderBy: desc(decisions.createdAt),
|
||||
});
|
||||
}
|
||||
|
||||
async getById(session: AuthenticatedSession, id: string) {
|
||||
const row = await db.query.decisions.findFirst({
|
||||
where: and(eq(decisions.id, id), eq(decisions.tenantId, session.tenantId)),
|
||||
});
|
||||
if (!row) throw new NotFoundException('Decision not found');
|
||||
return row;
|
||||
}
|
||||
|
||||
async create(session: AuthenticatedSession, dto: CreateDecisionDto) {
|
||||
const [row] = await db
|
||||
.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(null, {
|
||||
tenantId: session.tenantId,
|
||||
actorId: session.userId,
|
||||
action: 'decision.created',
|
||||
resource: `decision:${row.id}`,
|
||||
});
|
||||
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 row;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue