Added Field Expert flows, and deactivated inquiry

This commit is contained in:
2026-03-16 15:39:39 +03:30
parent b40270f058
commit fc599acf4a
10 changed files with 1067 additions and 88 deletions

View File

@@ -198,7 +198,18 @@ export class ExpertBlameService {
// Filter to show only:
// 1. Fresh requests (WAITING_FOR_EXPERT and no decision)
// 2. Requests decided by current expert
// 3. Expert-initiated: only the initiating field expert sees them
const visibleCases = (allCases as Record<string, unknown>[]).filter((doc) => {
const expertInitiated = doc.expertInitiated === true;
const initiatedByFieldExpertId = doc.initiatedByFieldExpertId;
if (expertInitiated && initiatedByFieldExpertId) {
if (String(initiatedByFieldExpertId) !== expertId) {
return false; // Only the initiating field expert can see this file
}
return true; // Initiating expert can see their expert-initiated file
}
const status = doc.status as string;
const decision = doc.expert as any;
const decidedByExpertId = decision?.decision?.decidedByExpertId;
@@ -522,13 +533,20 @@ export class ExpertBlameService {
);
}
// Access control: Check if expert has permission to view this request
const decision = (doc.expert as any)?.decision;
const decidedByExpertId = decision?.decidedByExpertId;
// Access control: Expert-initiated files only visible to the initiating field expert
const expertInitiated = doc.expertInitiated === true;
const initiatedByFieldExpertId = doc.initiatedByFieldExpertId;
if (expertInitiated && initiatedByFieldExpertId && String(initiatedByFieldExpertId) !== actorId) {
throw new ForbiddenException(
"Only the field expert who created this file can view and review it.",
);
}
// Allow if:
// 1. No decision yet (fresh request)
// 2. Decision made by current expert
const decision = (doc.expert as any)?.decision;
const decidedByExpertId = decision?.decidedByExpertId;
if (decidedByExpertId && String(decidedByExpertId) !== actorId) {
throw new ForbiddenException(
"You do not have permission to view this request. It has been handled by another expert.",
@@ -660,6 +678,17 @@ export class ExpertBlameService {
);
}
// Expert-initiated: only the initiating field expert can lock and review
if (
request.expertInitiated &&
request.initiatedByFieldExpertId &&
String(request.initiatedByFieldExpertId) !== actorDetail.sub
) {
throw new ForbiddenException(
"Only the field expert who created this file can lock and review it.",
);
}
// Check if locked and not expired
if (request.workflow?.locked) {
const lockedAt = request.workflow.lockedAt;

View File

@@ -22,7 +22,7 @@ import { ResendRequestDto } from "./dto/resend.dto";
@Controller("v2/expert-blame")
@ApiBearerAuth()
@UseGuards(LocalActorAuthGuard, RolesGuard)
@Roles(RoleEnum.EXPERT)
@Roles(RoleEnum.EXPERT, RoleEnum.FIELD_EXPERT)
export class ExpertBlameV2Controller {
constructor(private readonly expertBlameService: ExpertBlameService) {}