What every actor role can see and do — endpoints, responsibilities, and process steps. Super-admin excluded.
| Role enum | Login panel | Scope | Primary job |
|---|---|---|---|
company |
Insurer portal | Tenant-wide | View all files; manage branches, experts; run reports; rate experts |
expert |
Blame expert panel | Tenant DISAGREEMENT queue | Lock blame cases, review party submissions, submit verdict or request resend |
damage_expert |
Claim/damage panel | Tenant claim queue | Lock claims, price damage, validate repair factors, request resend/visit |
field_expert |
Field expert panel | Own created files | V2/V3 in-person blame + claim filing; also sees blame/claim review panels |
file_maker |
FileMaker panel | Own created files | V4/V5 party narrative (OTPs, inquiries, details, signatures); V5 claim approval |
file_reviewer |
FileReviewer panel | Assigned files | V4/V5 damage assessment (accident fields, parts, captures; mixed-factor priced-line acceptance when needed) |
registrar |
Registrar panel | Own created files | Office-based in-person blame + claim filing on behalf of parties |
call_center |
Call-center panel | Own created files | V6 phone-initiated blame: run inquiry, send link; user completes the rest |
One company actor per insurance-company tenant. The insurer portal is the
management layer: it can see everything under its tenant, manage the expert roster,
manage branches, configure per-tenant media settings, and pull statistical reports.
The insurer never touches blame/claim steps directly — it only observes and rates.
expert-insurer/| Method | Route | What it does |
|---|---|---|
| GET | expert-insurer/files | List all blame + claim files for the tenant (merged by publicId). Filterable by status, file type, search, sort, page. |
| GET | expert-insurer/files/:publicId | Full detail for one file by publicId. |
| GET | expert-insurer/files/:publicId/timeline | Chronological activity timeline (all history events: source, type, actor, metadata). |
| GET | expert-insurer/files/:publicId/report | Structured report data for PDF generation (owner, driver, insurance, vehicle, accident sections). |
| PUT | expert-insurer/files/:publicId/rating | Rate the experts on a file (1–5 per dimension: collision method, timeliness, cause accuracy, guilty-ID accuracy, bot rating). |
| GET | expert-insurer/report/unified-file-statuses | Unified status catalog + per-status counts for the whole tenant portfolio. Filterable by fileType and date range. |
| GET | expert-insurer/report/status-counts | Deprecated — prefer unified-file-statuses. |
expert-insurer/branches| Method | Route | What it does |
|---|---|---|
| GET | expert-insurer/branches | List all branches for this insurer. Query: search, from/to date, isActive filter. |
| POST | expert-insurer/branches | Add a new branch (name, code, address, city, phone, etc.). |
| PUT | expert-insurer/branches/:branchId/status | Activate or deactivate a branch. |
expert-insurer/experts| Method | Route | What it does |
|---|---|---|
| POST | expert-insurer/experts/blame | Create a new blame-expert account under this insurer. |
| POST | expert-insurer/experts/claim | Create a new damage-expert (claim) account under this insurer. |
| POST | expert-insurer/experts/file-maker | Create a new FileMaker account under this insurer. |
| POST | expert-insurer/experts/file-reviewer | Create a new FileReviewer account under this insurer. |
| GET | expert-insurer/experts/list | Paginated list of all expert accounts on this tenant. |
| GET | expert-insurer/experts/top | Top blame vs claim experts ranked by overall average rating (up to 10 each). |
| GET | expert-insurer/top-experts | Alias for experts/top (frontend compat). |
| GET | expert-insurer/:expertId | Files handled by one expert (slim summary rows — blame or claim depending on expert type). |
| Method | Route | What it does |
|---|---|---|
| GET | expert-insurer/statistics | KPI cards: totalFilesReviewed, averageUserRating, inPersonCount, filesThisMonth, objectionPercentage, etc. Filterable by date range. |
| GET | expert-insurer/top-files | Top 10 highest-rated claim files (combined insurer + user score). |
| GET | expert-insurer/expert-work-log | Per-expert work log: totalHandled, currentlyChecking, distinctFilesCheckedInPeriod. Filterable by expertKind and date range. |
| GET | reports/report/insurer/requests | Claim + blame status bucket counts + unified file count for the tenant. |
| GET | reports/report/insurer/per-month-requests | Same summary, broken down by the last 5 calendar months. |
| GET | reports/report/insurer/checked-requests | Same summary filtered by optional createdAt date range. |
| GET | reports/report/insurer/expert-work-log | Expert work log (blame + damage expert collections, not field experts). |
| GET | reports/report/insurer/expert-work-log/per-month | Same work log per calendar month (last 5). |
client-panel/| Method | Route | What it does |
|---|---|---|
| GET | client-panel/settings | Get per-tenant media limits (video/image/voice maxBytes) and CAR_BODY accident window (days). |
| PATCH | client-panel/settings | Update those settings (partial). Cannot exceed system-level route ceilings. |
Reviews blame files in the DISAGREEMENT queue — cases where the two parties do not
agree on who is at fault. After reviewing submitted documents and party statements
the expert locks the case, then either submits a verdict, asks the parties to resend
documents, or records an in-person visit outcome. All endpoints are under
v2/expert-blame/.
1 Browse list → 2 Assign (lock) the case → 3 Review party evidence (videos, voices, documents) → 4a Submit verdict or 4b Request document resend or 4c Record in-person visit.
v2/expert-blame/| Method | Route | What it does |
|---|---|---|
| GET | v2/expert-blame/ | List blame cases in the DISAGREEMENT queue (available, locked by me, or decided by me). Query: search, sortBy, sortOrder, page, limit, unifiedStatus, fileType. |
| GET | v2/expert-blame/:id | Full detail for one blame case (party statements, photos, voices, videos). |
| POST | v2/expert-blame/:id/assign | Check availability and lock the case to this expert. Returns assigned, already_assigned_to_you, or 409 if someone else holds it. |
| PUT | v2/expert-blame/reply/submit/:id | Submit verdict (accidentWay, accidentReason, accidentType, guilty party decision). Unlocks the case and moves it to COMPLETED. |
| PUT | v2/expert-blame/reply/resend/:id | Request parties to re-upload documents. Sets blame to WAITING_FOR_RESEND. One resend request per lifecycle. |
| PUT | v2/expert-blame/reply/inPerson/:id | Record that an in-person visit was made and submit verdict. |
| GET | v2/expert-blame/report/unified-file-statuses | Status catalog + per-status counts for this expert's portfolio. |
| GET | v2/expert-blame/report/status-counts | Deprecated — prefer unified-file-statuses. |
| PUT | v2/expert-blame/lock/:id | Deprecated lock endpoint — use POST assign. |
Reviews claim files after the user has submitted their damage evidence. The expert
prices each damaged part, optionally calculates a price-drop (depreciation), and
can ask the user to resend documents, come in person, or upload repair factor invoices
when workshop pricing is needed. All endpoints are under v2/expert-claim/.
1 Browse list → 2 Assign (lock) the claim → 3 Review damage photos and documents → 4 Optionally edit selected parts or calculate price-drop → 5a Submit priced reply or 5b Request resend or 5c Request in-person visit → 6 If factor parts present: validate uploaded factor invoices.
v2/expert-claim/| Method | Route | What it does |
|---|---|---|
| GET | v2/expert-claim/requests | List claims in WAITING_FOR_DAMAGE_EXPERT queue + factor-validation queue. Query: search, sortBy, page, limit, unifiedStatus, fileType. |
| GET | v2/expert-claim/request/:claimRequestId | Full claim detail: damaged parts, captured images, documents, priceDrop, blameCase party data, video URLs. |
| POST | v2/expert-claim/assign/:claimRequestId | Lock claim to this expert. Returns assigned, already_assigned_to_you, or 409. |
| GET | v2/expert-claim/request/:claimRequestId/price-drop | Price-drop context: severity labels, coefficient catalog, damaged parts + mapping, suggested car year from blame inquiry. |
| PUT | v2/expert-claim/request/:claimRequestId/price-drop | Calculate and persist price-drop: carPrice × yearCoeff × sumOfCoeffs ÷ 400. |
| PUT | v2/expert-claim/reply/submit/:claimRequestId | Submit damage assessment reply (priced parts list, daghi, branchId). Cap: total ≤ 53 000 000 Toman. A priced-only claim completes immediately; factor claims continue through factor collection/validation. No final owner signature or automatic Fanavaran submission. |
| PUT | v2/expert-claim/reply/resend/:claimRequestId | Request user to resend documents/photos. One resend per claim lifecycle; returns 422 if already fulfilled. |
| PATCH | v2/expert-claim/:claimRequestId/visit | Ask user to come in person. Unlocks claim, sets claimStatus to NEEDS_REVISION. |
| PATCH | v2/expert-claim/validate-factors/:claimRequestId | Validate uploaded repair factor invoices. Approve or reject each factor line with totalPayment. Cap applies across all lines (≤ 53 000 000 Toman). Auto-completes when all lines are decided. |
| PATCH | v2/expert-claim/request/:claimRequestId/damaged-parts | Edit selected damaged parts while the claim is locked by this expert (EXPERT_REVIEWING). |
| GET | v2/expert-claim/outer-parts-catalog | Fanavaran outer car-components catalog (shared with user flow). |
| GET | v2/expert-claim/inner-parts-catalog | Static inner car-parts catalog JSON. |
| GET | v2/expert-claim/branches | Insurer branches for this expert's tenant (for daghi/branch selection in reply payload). |
| GET | v2/expert-claim/stream/:id/video | Stream claim video (car-capture walk-around or accident video). Query: query=car-capture|accident. |
| GET | v2/expert-claim/report/unified-file-statuses | Status catalog + counts for this expert's claim portfolio. |
| GET | v2/expert-claim/report/status-counts | Deprecated — prefer unified-file-statuses. |
| PUT | v2/expert-claim/lock/:claimRequestId | Deprecated lock endpoint — use POST assign. |
Goes to the accident scene and fills both parties' forms in-person (V2 mirror / V3 flows). The field expert also has read access to the expert-blame and expert-claim panels (scoped to their own files). They are the only role that spans both blame filing and claim filing in the same session.
v2/expert-initiated/blame-request-management/Mirror of the user blame API. Frontend reuses same pages by swapping prefix only.
| Method | Route | What it does |
|---|---|---|
| POST | POST / | Create IN_PERSON blame file. |
| POST | send-party-otp/:id | Send OTP to one party by phone number (no invite link). |
| POST | verify-party-otp/:id | Verify one party's OTP and bind their account. |
| POST | blame-confession/:id | Record party's blame confession. |
| POST | car-body-form/:id | [CAR_BODY only] Accident type form. |
| POST | run-inquiries/:id / run-inquiries-vin/:id | Initial form / plate or VIN inquiry for current party. |
| POST | upload-video/:id | Upload first-party video. |
| POST | add-detail-location/:id | Add GPS location for current party. |
| POST | upload-voice/:id | Upload voice recording for current party. |
| POST | add-detail-description/:id | Add description for current party. |
| POST | add-second-party/:phone/:id/ | Advance to second party (no SMS link sent). |
| PUT | sign/:id | Upload party signature (FIRST then SECOND, partyRole param). |
| POST | accident-fields/:id | Save accident fields and complete blame immediately (no expert queue). |
v3/expert-initiated/blame-request-management/Reorganised step order: all party narrative first, then damage assessment. Blame and claim both handled in this single controller.
| Method | Route | What it does |
|---|---|---|
| POST | POST / → send-party-otp → verify-party-otp → run-inquiries → add-detail-* → sign (×2) | Party narrative phase (steps 1–8) — identical endpoints to mirror, same contract. |
| POST | accident-fields/:id | Step 9: save accident fields after both parties have signed. |
| GET | claim-id/:requestId | Step 10: get auto-created claim ID. |
| POST | upload-document/:claimId | Step 11: upload licence / car card documents. |
| PATCH | select-outer-parts/:claimId / select-other-parts/:claimId | Steps 12–13: select damaged parts. |
| POST | capture-part/:claimId | Step 14: capture part photos + angles. |
| PATCH | car-capture/:claimId | Step 15: walk-around video. |
| POST | upload-video/:requestId | Step 16: blame accident video (final) → WAITING_FOR_EXPERT (THIRD_PARTY) or COMPLETED (CAR_BODY). |
FIELD_EXPERT sees v2/expert-blame/ scoped to their own created files (not the disagreement queue).
They also see v2/expert-claim/ for claims linked to their blame files.
Same endpoints as blame-expert and damage-expert panels above.
The first actor in the V4/V5 split. FileMaker handles the party narrative on-site: OTPs, inquiries, location/description/voice, and signatures for both parties. They also upload the initial claim documents (licences, car cards). After the second signature the file is "sealed" for FileReviewer pickup. In V5, FileMaker comes back at the end to approve or reject the completed claim. After approval, an expert submits the case to Fanavaran manually.
v4/file-maker/blame-request-management/ and v5/…V4 and V5 endpoints are identical — only the prefix changes. V5 sets requiresFileMakerApproval=true at creation.
| Method | Route | What it does |
|---|---|---|
| POST | POST / | Create IN_PERSON blame file. |
| GET | my-files | List all blame files created by this FileMaker. |
| GET | my-files/:requestId | Full detail for one file (parties, workflow, linked claim ID). |
| GET | claim-id/:requestId | Get the auto-created claim ID after guilty-party run-inquiries. |
| POST | send-party-otp/:id / verify-party-otp/:id | Send + verify OTP for one party at a time (guilty first, then damaged). |
| POST | car-body-form/:id | [CAR_BODY only] Accident type form. |
| POST | run-inquiries/:id / run-inquiries-vin/:id | Run plate or VIN inquiry. First call = guilty (+ auto-creates claim). Second call = damaged (THIRD_PARTY only). |
| POST | add-detail-location/:id / add-detail-description/:id / upload-voice/:id | Add location, description, and voice for current party (partyRole param selects FIRST/SECOND). |
| PUT | sign/:id | Upload party signature (partyRole=FIRST then SECOND). After second signature, file is sealed. |
| POST | upload-document/:claimId | Upload licences / car cards against the auto-created claim. |
| GET | capture-requirements/:claimId | Step-aware capture requirements (phases: pre-capture docs vs damaged parts + chassis/engine). |
v5/file-maker/claim-approval/Used only in V5. After damage expert review and any required factor validation, claim enters WAITING_FOR_FILE_MAKER_APPROVAL; no final owner signature is needed.
| Method | Route | What it does |
|---|---|---|
| POST | approve/:claimId | Approve the completed claim → claim becomes COMPLETED. An expert submits to Fanavaran manually when ready. |
| POST | reject/:claimId | Reject back to FileReviewer → claim returns to WAITING_FOR_DAMAGE_EXPERT. Limit: max 2 rejections per claim; 3rd attempt returns 422 FILE_MAKER_REJECTION_LIMIT_EXCEEDED. |
The second actor in the V4/V5 split. FileReviewer picks up sealed files (after FileMaker is done) and performs the full damage assessment pass: accident fields, capture requirements lookup, document upload (chassis/engine), part selection, part photos and walk-around video. The blame is marked COMPLETED by car-capture. FileReviewer also has read access to the expert-claim panel for claims they are reviewing.
v4/file-reviewer/blame-request-management/ and v5/…V4 and V5 endpoints are identical — only the prefix changes.
| Method | Route | What it does |
|---|---|---|
| GET | my-files | List FileMaker-sealed files available to claim in this reviewer’s insurer, plus files already assigned to this FileReviewer. |
| GET | my-files/:requestId | Full detail for one available or assigned file in this reviewer’s insurer (parties, workflow, expert fields, linked claim ID). |
| GET | claim-id/:requestId | Get the auto-created claim ID (from FileMaker's guilty-party inquiry). |
| POST | accident-fields/:requestId | Step 1 (FileReviewer): save accident fields (accidentWay, accidentReason, accidentType). |
| GET | capture-requirements/:claimId | Step-aware capture requirements (pre-capture docs phase vs capture-parts phase). |
| POST | upload-document/:claimId | Upload chassis / engine / metal-plate documents. |
| PATCH | select-outer-parts/:claimId | Select outer (body) damaged parts. |
| PATCH | select-other-parts/:claimId | Select other (non-body) damaged parts. |
| POST | capture-part/:claimId | Capture part photos + angles for each selected damaged part. |
| PATCH | car-capture/:claimId | Walk-around video (final FileReviewer capture step). Claim → WAITING_FOR_DAMAGE_EXPERT, blame → COMPLETED. |
| PUT | claim-sign/:claimId | For mixed priced/factor claims only: record acceptance of priced lines before factor uploads. A final owner signature is no longer required. |
| POST | upload-video/:requestId | No-op in V4/V5 — blame already COMPLETED by car-capture. Returns idempotent success. |
FILE_REVIEWER is in the allowed roles for v2/expert-claim/.
They can view claim details and run the assign/lock flow for claims associated
with their files. They cannot initiate a damage-expert resend independently.
Office-based role that files in-person blame and claim on behalf of parties. Uses a bulk-OTP flow (both parties' OTPs sent and verified in one call each) rather than the one-at-a-time OTP used by field experts. After blame, the registrar mirrors the user claim API to fill part selection, documents, and captures. The file then enters the normal damage-expert review lifecycle.
registrar-initiated-blame/Note: @ApiExcludeController — routes exist but not surfaced in Swagger docs.
| Method | Route | What it does |
|---|---|---|
| POST | registrar-initiated-blame/create | Create IN_PERSON blame file. |
| GET | registrar-initiated-blame/my-files | List all blame files created by this registrar. |
| GET | registrar-initiated-blame/blame/:requestId | Full detail for one blame file. |
| POST | registrar-initiated-blame/send-party-otps/:id | Send OTPs to both parties simultaneously. |
| POST | registrar-initiated-blame/verify-party-otps/:id | Verify both parties' OTPs in one call. |
| POST | registrar-initiated-blame/complete-blame-data/:id | Submit all blame form data for both parties in one payload. |
| POST | registrar-initiated-blame/upload-video/:id | Upload blame video. |
| POST | registrar-initiated-blame/upload-voice/:id | Upload voice recording. |
| POST | registrar-initiated-blame/add-accident-fields/:id | Save accident fields and complete blame. |
| POST | registrar-initiated-blame/upload-party-signature/:id | Upload a party's signature (partyRole=FIRST/SECOND). |
v2/registrar/claim-request-management/Mirror of the user claim API. Frontend reuses same claim pages by swapping prefix only.
| Method | Route | What it does |
|---|---|---|
| POST | create-from-blame/:blameId | Create claim from a completed blame file. |
| GET | outer-parts-catalog / car-other-part | Parts catalogs (outer body parts + other parts JSON). |
| GET | branches/:insuranceId | Insurer branch list (for branch selection in claim sign step). |
| PATCH | select-outer-parts/:claimId | Select outer damaged parts. |
| PATCH | select-other-parts/:claimId | Select other damaged parts + bank info. |
| POST | upload-document/:claimId | Upload claim documents (licences, car card). |
| POST | capture-part/:claimId | Capture part photos + angles. |
| PATCH | car-capture/:claimId | Walk-around video (final step) → WAITING_FOR_DAMAGE_EXPERT. |
Handles V6 phone-initiated blame filing. The agent collects the guilty party's data over the phone, runs the insurance inquiry, and sends the blame link via SMS. The user then completes the rest of the form through the standard V2 flow (with the initial-form/inquiry step skipped). The call-center agent's job ends after send-link; they can monitor progress via the read endpoints.
v6/call-center-blame/| Method | Route | What it does |
|---|---|---|
| POST | create | Create a LINK blame file. Body: { type: "THIRD_PARTY" | "CAR_BODY" }. |
| POST | run-inquiry/:requestId | Run plate + national-code insurance inquiry for the guilty party. Stores result on blame document. |
| POST | run-inquiry-vin/:requestId | VIN/chassis alternative to run-inquiry. Uses ESG chassis lookup. |
| POST | send-link/:requestId | Register user if needed, store as first party, send blame invite link via SMS. Body: { phoneNumber }. |
| GET | my-files | List all blame files started by this agent. |
| GET | blame/:requestId | Current status and workflow step for one file (to check if user has opened the link and progressed). |
After send-link the user completes the form via
v2/blame-request-management/ (standard V2 flow).
The initial-form / inquiry step is automatically skipped
(skipInitialFormStep=true). Downstream claim flow is the
standard V2 claim flow.
All panel actors (every role except user) authenticate through the same
POST actor/login endpoint with captcha. Password reset is via email OTP.
Profile reads and edits are also shared.
actor/| Method | Route | What it does |
|---|---|---|
| GET | actor/captcha | Issue a new login captcha challenge (returns captchaId + SVG image). |
| POST | actor/login | Authenticate any actor role. Body: role, username/email/nationalCode, password, captchaId, captcha. Returns JWT access + refresh tokens. |
| POST | actor/forget-password | Send password-reset OTP to email. |
| POST | actor/forget-password-verify | Verify OTP and set new password. |
| GET | actor/profile | Get current actor's profile. |
| PATCH | actor/profile | Update current actor's profile. |