6.7 KiB
Inquiry participant identity proposal
Status: implemented on 2026-09-13
Scope: every user, expert, FileMaker, and call-center inquiry flow
Persian version: inquiry-participants-proposal.fa.md
Implemented interface
The role fields and required vehicle object shown below are accepted directly in every existing inquiry request body. This covers V2 user and expert/registrar mirror initial forms, V3 expert flow, V4/V5 FileMaker flows, V6 call-center flow, and the one-shot in-person completion paths. Plate and VIN routes share the same participant rules. Flat driver/insurer fields and phone numbers are not inquiry inputs.
Responses and file-detail views for operational actors expose normalized participants, participantRoles, vehicle.registrationState, and vehicle.previousPlateId where available.
Problem
The current inquiry contract mainly models a driver and a value named insurer. That is incomplete and the name is misleading: a person is the policyholder; the insurer is the insurance company.
Each vehicle-side Party can have these identity roles:
| Case type | Required roles |
|---|---|
THIRD_PARTY |
Driver, vehicle owner, third-party policyholder |
CAR_BODY |
Driver, vehicle owner, third-party policyholder, car-body policyholder |
One person may hold several roles, but the system must not assume that they do.
Recommendation
Add a short participant-identification step before inquiry. Ask relationship questions and collect details only for distinct people. Do not ask for every person's complete data unconditionally, and do not add pairwise flags such as driverIsOwner, ownerIsPolicyholder, and driverIsBodyPolicyholder; that becomes ambiguous and grows combinatorially.
Use explicit role references instead:
{
"driver": {
"nationalCode": "0012345678",
"birthday": "1370/01/01",
"hasDrivingLicense": true,
"licenseNumber": "123456789",
"licenseType": "1"
},
"vehicleOwner": { "sameAs": "DRIVER" },
"thirdPartyPolicyholder": { "sameAs": "VEHICLE_OWNER" },
"carBodyPolicyholder": {
"nationalCode": "0098765432",
"birthday": "1365/02/03"
}
}
carBodyPolicyholder is forbidden for THIRD_PARTY and required for CAR_BODY. A role is either a new person's identity or a sameAs reference, never both. The backend should normalize this input into unique participants plus role assignments.
For the damaged party of a THIRD_PARTY case only, the policyholder can be explicitly unresolved with "thirdPartyPolicyholder": { "unknown": true }. This is not accepted for the guilty party. Plate-based third-party-policy inquiry is recorded as intentionally skipped because it requires that identity; VIN-based lookup can still run without guessing a person. The driver, owner, personal, ownership, and licence rules remain enforced.
For Driver, hasDrivingLicense is required. When it is true, both licenseNumber and licenseType are required; when it is false, the licence inquiry is intentionally skipped.
Recent ownership transfer and previous plate
Participant roles and vehicle identifiers are separate concerns. When a vehicle has recently been sold or purchased, the current official record or policy may still be connected to its previous plate. Model this explicitly instead of replacing the current plate:
{
"vehicle": {
"registrationState": "RECENTLY_TRANSFERRED",
"currentPlate": {
"leftDigits": "44",
"centerAlphabet": "ب",
"centerDigits": "111",
"ir": "22"
},
"previousPlate": {
"leftDigits": "55",
"centerAlphabet": "ج",
"centerDigits": "222",
"ir": "33"
},
"vin": "NAAM01E15HK123456"
}
}
registrationState is CURRENT by default or RECENTLY_TRANSFERRED for this exceptional path. previousPlate is required only when registrationState=RECENTLY_TRANSFERRED. The current plate remains the vehicle's primary identifier. The inquiry orchestrator should query the current plate first and automatically try the previous plate when the current result is missing, stale, or does not find the relevant policy.
Before accepting a previous-plate result, the backend must correlate it to the same VIN/chassis. A mismatch must stop automatic selection and require correction or manual review. Both identifiers and every attempted inquiry should be retained for audit, but a previous plate must never overwrite the current plate.
Suggested UI sequence
- Collect the current plate and ask whether the vehicle was recently transferred. If yes, collect the previous plate and VIN/chassis.
- Collect driver identity and licence details.
- Ask whether the vehicle owner is the driver; collect owner identity only when different.
- Ask whether the third-party policyholder is the driver, the owner, or another person; collect identity only for “another person”.
- For
CAR_BODY, ask the same question for the car-body policyholder, allowing any already entered person or another person. - Show a short review, then run the inquiries.
This keeps the common case fast while representing all valid combinations.
Backend seam
Create one shared participant resolver used by every inquiry route. Its interface should:
- validate required roles by case type and reject circular/invalid
sameAsreferences; - return the resolved person for each role;
- route the correct identity to each inquiry: driver licence → Driver, ownership → Vehicle Owner, third-party policy → Third-party Policyholder, car-body policy → Car-body Policyholder;
- choose the current or previous plate deterministically and verify previous-plate results against VIN/chassis;
- run personal identity inquiry once per distinct person;
- persist normalized participants and role assignments on the relevant
Party.
V2 user/expert routes, V3, V4, V5, and V6 should be adapters over this shared rule set rather than implementing their own relationship logic.
Contract boundary
The structured participant and vehicle objects are the only accepted inquiry input. The backend rejects flat fields such as nationalCodeOfDriver, nationalCodeOfInsurer, driverIsInsurer, top-level plate/vin, and phoneNumber with a validation error. Phone-based authentication and party contact flows remain separate from inquiry identity collection.
Decision
Prefer conditional collection plus explicit role assignments. It provides complete data without burdening most users, prevents contradictory booleans, and gives all inquiry flows one consistent domain model.