forked from Yara724/api
Fixed registrar and field expert
This commit is contained in:
@@ -4169,6 +4169,50 @@ export class ClaimRequestManagementService {
|
||||
};
|
||||
}
|
||||
|
||||
private async assertActorCanViewClaimV2(
|
||||
claim: any,
|
||||
currentUserId: string,
|
||||
actor?: { sub: string; role?: string },
|
||||
): Promise<void> {
|
||||
const ownerId = claim.owner?.userId?.toString();
|
||||
if (ownerId && ownerId === currentUserId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (actor?.role === RoleEnum.FIELD_EXPERT) {
|
||||
if (claim.initiatedByFieldExpertId?.toString() === currentUserId) {
|
||||
return;
|
||||
}
|
||||
if (claim.blameRequestId) {
|
||||
const blame = await this.blameRequestDbService.findById(
|
||||
claim.blameRequestId.toString(),
|
||||
);
|
||||
if (
|
||||
blame?.expertInitiated &&
|
||||
blame.initiatedByFieldExpertId &&
|
||||
String(blame.initiatedByFieldExpertId) === currentUserId
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (actor?.role === RoleEnum.REGISTRAR && claim.blameRequestId) {
|
||||
const blame = await this.blameRequestDbService.findById(
|
||||
claim.blameRequestId.toString(),
|
||||
);
|
||||
if (
|
||||
blame?.registrarInitiated &&
|
||||
blame.initiatedByRegistrarId &&
|
||||
String(blame.initiatedByRegistrarId) === currentUserId
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new ForbiddenException("You do not have access to this claim");
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve effective user id for claim operations.
|
||||
* For FIELD_EXPERT acting on expert-initiated IN_PERSON claim, returns the claim owner's id; otherwise returns currentUserId.
|
||||
@@ -6519,7 +6563,6 @@ export class ClaimRequestManagementService {
|
||||
.find(
|
||||
{
|
||||
expertInitiated: true,
|
||||
creationMethod: "IN_PERSON",
|
||||
initiatedByFieldExpertId: new Types.ObjectId(currentUserId),
|
||||
},
|
||||
{ select: "_id", lean: true },
|
||||
@@ -6532,6 +6575,7 @@ export class ClaimRequestManagementService {
|
||||
...(expertBlameIds.length
|
||||
? [{ blameRequestId: { $in: expertBlameIds } }]
|
||||
: []),
|
||||
{ initiatedByFieldExpertId: new Types.ObjectId(currentUserId) },
|
||||
],
|
||||
},
|
||||
{ lean: true },
|
||||
@@ -6621,17 +6665,7 @@ export class ClaimRequestManagementService {
|
||||
if (!claim) {
|
||||
throw new NotFoundException("Claim request not found");
|
||||
}
|
||||
const effectiveUserId = await this.resolveClaimEffectiveUserId(
|
||||
claim,
|
||||
currentUserId,
|
||||
actor?.role,
|
||||
);
|
||||
if (
|
||||
!claim.owner?.userId ||
|
||||
claim.owner.userId.toString() !== effectiveUserId
|
||||
) {
|
||||
throw new ForbiddenException("You do not have access to this claim");
|
||||
}
|
||||
await this.assertActorCanViewClaimV2(claim, currentUserId, actor);
|
||||
|
||||
const hasCapture = (data: any, key: string) =>
|
||||
data && (data instanceof Map ? data.get(key) : data[key]);
|
||||
@@ -6745,7 +6779,9 @@ export class ClaimRequestManagementService {
|
||||
s ? s.replace(/^(.{4})(.*)(.{4})$/, "IR$1************$3") : undefined;
|
||||
const maskNationalCode = (s?: string) =>
|
||||
s ? s.replace(/^(.{2})(.*)(.{2})$/, "$1******$3") : undefined;
|
||||
const isExpertViewer = actor?.role === RoleEnum.FIELD_EXPERT;
|
||||
const isExpertViewer =
|
||||
actor?.role === RoleEnum.FIELD_EXPERT ||
|
||||
actor?.role === RoleEnum.REGISTRAR;
|
||||
const ownerData = claim.owner
|
||||
? {
|
||||
userId: claim.owner.userId?.toString(),
|
||||
|
||||
@@ -52,7 +52,7 @@ import { ClaimVehicleTypeV2 } from "src/static/outer-car-parts-catalog";
|
||||
@Controller("v2/claim-request-management")
|
||||
@ApiBearerAuth()
|
||||
@UseGuards(GlobalGuard, RolesGuard)
|
||||
@Roles(RoleEnum.USER, RoleEnum.FIELD_EXPERT)
|
||||
@Roles(RoleEnum.USER, RoleEnum.FIELD_EXPERT, RoleEnum.REGISTRAR)
|
||||
export class ClaimRequestManagementV2Controller {
|
||||
constructor(
|
||||
private readonly claimRequestManagementService: ClaimRequestManagementService,
|
||||
@@ -63,7 +63,7 @@ export class ClaimRequestManagementV2Controller {
|
||||
@ApiOperation({
|
||||
summary: "Get My Claims (V2)",
|
||||
description:
|
||||
"Claims for the current user (or field-expert in-person files). Optional query: `search`, `sortBy` (publicId | createdAt | requestNo | status), `sortOrder`, `page`, `limit`. Without `page`/`limit`, returns the full filtered list.",
|
||||
"Claims for the current user, or claims from blame files initiated by the current FIELD_EXPERT / REGISTRAR (LINK and IN_PERSON). Optional query: `search`, `sortBy`, `sortOrder`, `page`, `limit`.",
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
@@ -97,7 +97,7 @@ export class ClaimRequestManagementV2Controller {
|
||||
@ApiOperation({
|
||||
summary: "Get Claim Details (V2)",
|
||||
description:
|
||||
"Returns the claim snapshot for **USER** (owner) or **FIELD_EXPERT** when permitted. Owners get `ownerGuidance`: `{ phaseKey, headline, nextActions[] (method + pathTemplate), objectionAllowed }` mapped from `status` / `claimStatus` / workflow so the client can show the correct screen without duplicating orchestration logic. FIELD_EXPERT does not receive `ownerGuidance`. Core payload includes documents, captures, evaluation replies, optional expert resend, and masked bank info.",
|
||||
"Returns the claim snapshot for **USER** (owner), **FIELD_EXPERT**, or **REGISTRAR** when permitted. Initiating experts/registrars see unmasked money fields; owners get `ownerGuidance`.",
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
|
||||
@@ -30,7 +30,6 @@ import { CurrentUser } from "src/decorators/user.decorator";
|
||||
import { MediaPolicyService } from "src/media-policy/media-policy.service";
|
||||
import { DEFAULT_MEDIA_MAX_BYTES } from "src/client/client.service";
|
||||
import { RoleEnum } from "src/Types&Enums/role.enum";
|
||||
import { ListQueryV2Dto } from "src/common/dto/list-query-v2.dto";
|
||||
import { ClaimVehicleTypeV2 } from "src/static/outer-car-parts-catalog";
|
||||
import { ClaimRequestManagementService } from "./claim-request-management.service";
|
||||
import {
|
||||
@@ -93,19 +92,6 @@ export class ExpertInitiatedClaimMirrorController {
|
||||
);
|
||||
}
|
||||
|
||||
@Get("requests")
|
||||
@ApiOperation({ summary: "[Expert mirror] List my (in-person) claims" })
|
||||
async getMyClaims(
|
||||
@CurrentUser() expert: any,
|
||||
@Query() query: ListQueryV2Dto,
|
||||
) {
|
||||
return this.claimRequestManagementService.getMyClaimsV2(
|
||||
expert.sub,
|
||||
expert,
|
||||
query,
|
||||
);
|
||||
}
|
||||
|
||||
@Get("outer-parts-catalog")
|
||||
@ApiOperation({
|
||||
summary: "Get outer parts catalog (V2)",
|
||||
@@ -158,24 +144,6 @@ export class ExpertInitiatedClaimMirrorController {
|
||||
);
|
||||
}
|
||||
|
||||
@Get("request/:claimRequestId")
|
||||
@ApiParam({
|
||||
name: "claimRequestId",
|
||||
description: "The claim case ID (MongoDB ObjectId)",
|
||||
example: "507f1f77bcf86cd799439011",
|
||||
})
|
||||
@ApiOperation({ summary: "[Expert mirror] Get claim details" })
|
||||
async getClaimDetails(
|
||||
@Param("claimRequestId") claimRequestId: string,
|
||||
@CurrentUser() expert: any,
|
||||
) {
|
||||
return this.claimRequestManagementService.getClaimDetailsV2(
|
||||
claimRequestId,
|
||||
expert.sub,
|
||||
expert,
|
||||
);
|
||||
}
|
||||
|
||||
@Patch("select-outer-parts/:claimRequestId")
|
||||
@ApiOperation({
|
||||
summary: "Select Damaged Outer Car Parts (V2 - Step 2)",
|
||||
|
||||
@@ -30,7 +30,6 @@ import { CurrentUser } from "src/decorators/user.decorator";
|
||||
import { MediaPolicyService } from "src/media-policy/media-policy.service";
|
||||
import { DEFAULT_MEDIA_MAX_BYTES } from "src/client/client.service";
|
||||
import { RoleEnum } from "src/Types&Enums/role.enum";
|
||||
import { ListQueryV2Dto } from "src/common/dto/list-query-v2.dto";
|
||||
import { ClaimVehicleTypeV2 } from "src/static/outer-car-parts-catalog";
|
||||
import { ClaimRequestManagementService } from "./claim-request-management.service";
|
||||
import {
|
||||
@@ -93,19 +92,6 @@ export class RegistrarClaimMirrorController {
|
||||
);
|
||||
}
|
||||
|
||||
@Get("requests")
|
||||
@ApiOperation({ summary: "[Registrar mirror] List my (in-person) claims" })
|
||||
async getMyClaims(
|
||||
@CurrentUser() registrar: any,
|
||||
@Query() query: ListQueryV2Dto,
|
||||
) {
|
||||
return this.claimRequestManagementService.getMyClaimsV2(
|
||||
registrar.sub,
|
||||
registrar,
|
||||
query,
|
||||
);
|
||||
}
|
||||
|
||||
@Get("outer-parts-catalog")
|
||||
@ApiOperation({
|
||||
summary: "Get outer parts catalog (V2)",
|
||||
@@ -158,24 +144,6 @@ export class RegistrarClaimMirrorController {
|
||||
);
|
||||
}
|
||||
|
||||
@Get("request/:claimRequestId")
|
||||
@ApiParam({
|
||||
name: "claimRequestId",
|
||||
description: "The claim case ID (MongoDB ObjectId)",
|
||||
example: "507f1f77bcf86cd799439011",
|
||||
})
|
||||
@ApiOperation({ summary: "[Registrar mirror] Get claim details" })
|
||||
async getClaimDetails(
|
||||
@Param("claimRequestId") claimRequestId: string,
|
||||
@CurrentUser() registrar: any,
|
||||
) {
|
||||
return this.claimRequestManagementService.getClaimDetailsV2(
|
||||
claimRequestId,
|
||||
registrar.sub,
|
||||
registrar,
|
||||
);
|
||||
}
|
||||
|
||||
@Patch("select-outer-parts/:claimRequestId")
|
||||
@ApiOperation({
|
||||
summary: "Select Damaged Outer Car Parts (V2 - Step 2)",
|
||||
|
||||
Reference in New Issue
Block a user