Files
baya-monorepo/product/business/02-nurse-verification.md
T
hamid 1c266523bc backend phase 6: nurse verification & credentials (mocked vendors)
The trust engine. New `verif` schema (5 tables) + a data-driven verification
pipeline: steps are rows (6 seeded step-types), not a code enum.

- nurse_verifications.status is the single source of verification truth;
  nurse_profiles.is_verified is flipped ONLY inside the finalize transaction
  (VerificationAggregator: tracked verification + tracked profile -> one commit)
  and reversed on suspension/expiry — no in-between state.
- is_automated snapshotted onto each step at submit; steps seeded from active
  required step-types; automated runs (identity-KYC, Shahkar, IBAN ownership)
  find their step by code.
- users.national_id populated only on identity-KYC pass; Shahkar + IBAN owner
  compare against it (money-mule guard); shared-SIM -> shared_sim support alert.
- Documents are metadata-only behind signed URLs; credential_number encrypted
  and never serialized; public trust badge exposes credential TYPES, not numbers;
  holder-name cross-checked against the verified identity before recording.
- Admin-triggered credential-expiry scan reverts lapsed steps, re-gates
  bookability, raises a verification_expired alert + verification_expiry_prompt
  notification (scheduled cron deferred; config key
  verification_expiry_scan_cadence_hours).

Three new mock vendor seams (IShahkarVerifier / IIdentityKycProvider /
ICredentialVerifier) behind DI; reuses b3 IBankAccountOwnershipVerifier and
b0 IObjectStorage/IFieldEncryptor. 15 endpoints across 4 controllers.

Two migrations (tables + step-type seed). 154 tests pass, zero new warnings.
Contract dev/contracts/domains/verification.md + swagger snapshot refreshed;
handoff/report/mocks-registry updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 14:39:32 +03:30

6.7 KiB

2. Nurse Verification & Credentials

← Business Requirements

(a) Business requirements

Verified trust is the entire brand. Vetting is platform-owned, non-optional, and performed at the authoritative source — never delegated to families, and never marketed as a check the platform does not actually perform. A nurse is bookable only after all required verification steps pass.

The pipeline is data-driven: the set of steps lives as rows in verification_step_types (not a code enum), so a new regulatory requirement (e.g., professional liability insurance) is one INSERT, not a migration. Each step can be automated (a KYC vendor API call) or manual (admin reviews an uploaded document). The aggregate nurse_verifications record rolls the step outcomes into a single status; nurse_profiles.is_verified flips to true only inside the same transaction that confirms every required step is passed.

The verification steps:

  1. Identity (KYC) — automated. Match person ↔ کد ملی (national ID) ↔ phone ↔ face via one Iranian KYC vendor: national-ID validity/name match + photo/video liveness against the national-card / civil-registry (ثبت احوال) photo. Binds the profile to a real identity and a liveness selfie to defeat the stolen-identity / alias fraud pattern.
  2. Shahkar phone↔national-id binding — automated. Confirm the login SIM is registered to the nurse's own کد ملی. The binding result (when, which vendor, the reference) is recorded, and re-verification is triggered on phone change. The shared-SIM failure mode (a SIM owned by a family member) is an explicit, handled state, not an undefined edge case.
  3. MoH پروانه صلاحیت حرفه‌ای (professional-competency license) — the single most important credential. It is the MoH-mandated license for in-home nursing and already bundles the criminal-record (سوء پیشینه) screen plus scientific/ethical/health vetting. Verified against the MoH source (Rn.behdasht.gov.ir). No public B2B API exists, so the realistic method at launch is nurse-uploaded document + manual admin verification against the official record.
  4. نظام پرستاری (Iranian Nursing Organization / INO) membership — cross-check. The INO membership number is captured and cross-checked (ino.ir) as a second source. Manual at launch.
  5. عدم سوء پیشینه (criminal-record certificate). Consent-gated to the individual (obtained by the nurse via adliran.ir / their own ثنا password); no company/employer API exists. The nurse uploads it; it is time-limited — on expiry the step reverts to pending and a support alert is raised. Partly covered already by credential #3.
  6. IBAN ownership verification. The payout IBAN (Sheba) must be proven to belong to the verified nurse — the account-holder national ID must equal the verified nurse national ID. Done via automated IBAN-ownership inquiry (استعلام شبا) where available, gating the first payout, not merely an admin eyeballing the number. Prevents paying a nurse's earnings into a third party's account (money-mule risk).

Structured credential registry. Beyond opaque uploaded files, the actual license numbers, issuing authority, holder-name-as-printed, and issue/expiry dates are stored as typed, queryable rows in nurse_credentials. This powers renewal/expiry alerts, the public "verified" trust badge, cross-checking against official portals, and audit defensibility — and survives the future arrival of an MoH/INO API.

Continuous monitoring, not one-and-done: license validity and the criminal-record certificate are periodically re-verified; Shahkar is re-run on phone change. Expiring credentials raise support_alerts.

(b) Iran-specific considerations

  • The license layer is fragmented across regulators (MoH vs INO) and has no public B2B API — manual verification against the official portal is the realistic MVP method; the structured registry makes that defensible and renewable.
  • The criminal-record check is consent-gated to the person and cannot be pulled by a company — hence nurse-uploaded + re-requested periodically, leaning on the MoH license which already embeds it.
  • Identity (Shahkar, liveness, national-ID match) is the easy layer because a competitive market of Iranian e-KYC vendors (Finnotech, U-ID, Jibbit, Farashensa, Verify, Kavoshak) already holds the regulator-gated upstream agreements. Buy this, don't build it.
  • Document forgery is the documented attack (the "imposter nurse" pattern): verify at source, bind to national ID + liveness, never trust an uploaded PDF alone.

(c) MVP vs DEFERRED

  • MVP: all six steps; data-driven verification_step_types; structured nurse_credentials registry; manual MoH/INO verification; nurse-uploaded عدم سوء پیشینه with expiry; automated identity + Shahkar + IBAN-ownership via one KYC vendor; expiry-driven re-verification alerts; transactional is_verified.
  • DEFERRED: automated MoH/INO license lookup (pending a B2B API); ML-driven fraud scoring (fraud_flags is modeled but inactive); professional-liability-insurance step (addable as a row when required).

(c-bis) As-built clarifications (backend-phase-6)

Rules confirmed while building the pipeline (implementation in the verif schema):

  • Step state pending vs in_review: pending = awaiting submission/automation (a seeded or automated step not yet run); in_review = a manual step with evidence uploaded, awaiting the admin decision. The aggregate is in_review while any required step is in_review, rejected if any required step failed, and approved only when every required step is passed (the same transaction flips is_verified).
  • Renewal is an in-app notification, not only an alert: an expiry re-scan raises a verification_expired support alert (staff worklist) and sends the nurse a verification_expiry_prompt notification; the required step reverts to expired and bookability is re-gated.
  • The public trust badge exposes credential types held, never the numbers (e.g. "MoH license · INO member"); credential_number is encrypted and never serialized.
  • Shared-SIM is surfaced as a distinct shared_sim support-alert type (non-accusatory), separate from a plain phone↔national-id mismatch.

(d) Supporting database entities

nurse_verifications, verification_step_types, verification_steps, verification_documents, nurse_credentials (structured license registry), nurse_bank_accounts (IBAN ownership), support_alerts (expiry/renewal), audit_logs.

Related: Data model — Verification & Credentials; Research — Verification.