Domain 4 — Verification & Credentials
Related: business requirements — Nurse verification.
The pipeline stays data-driven: step types are rows, so a new regulatory requirement (e.g. professional liability insurance) is one INSERT. This revision adds a structured credential registry because the brand is "verified trust" and renewal tracking needs queryable license numbers, not opaque PDFs.
nurse_verifications [CORE]
Role: The master per-nurse verification record; aggregates step outcomes into one status (the single source of truth for verification state). Why a header table: one place to drive the overall lifecycle and the is_verified flip. Fields unchanged: id, nurse_id (unique), status (not_started/pending/in_review/approved/rejected/suspended), submitted_at, approved_at, rejected_at, suspended_at, rejection_reason, reviewed_by_admin_id, internal_notes, timestamps. Relations: 1:1 → nurse_profiles; 1:N → verification_steps.
verification_step_types [CORE]
Role: Admin catalog of pipeline steps with stable machine codes (identity_kyc, shahkar_match, moh_competency_license, ino_membership, criminal_record, bank_account_verification). Why rows + is_automated/automation_provider: the Iranian credential reality is fragmented across regulators and partly automatable (Shahkar, liveness) and partly manual (license PDF) — data-driving it absorbs that without code changes. Fields unchanged. Relations: 1:N → verification_steps.
verification_steps [CORE]
Role: One row per step per nurse; tracks status, the raw external_response_json (KYC vendor audit), and expires_at for time-limited steps (the عدم سوء پیشینه certificate expires → step reverts to pending + raises a support_alert). Why snapshot is_automated: historical records survive later step-type edits. Fields unchanged, with UNIQUE(nurse_verification_id, step_type_id). Relations: N:1 → nurse_verifications, verification_step_types; 1:N → verification_documents.
verification_documents [CORE]
Role: Uploaded evidence metadata (object-storage key + integrity hash); files live in S3-compatible storage behind signed URLs, never public. Why metadata-only: keeps PII bytes out of the DB and access controlled. Fields unchanged. Relations: N:1 → verification_steps.
nurse_credentials [MVP] — NEW
Role: Structured, queryable registry of the actual Iranian credentials — beyond the opaque document uploads. Why: no public B2B API exists for MoH/INO, so an admin manually verifies an uploaded credential against the official portal — but the old model gave them nowhere to record the verified license number for renewal alerts, the public trust badge, or cross-check. This makes the badge and expiry monitoring real and survives a future INO/MoH API.
| Field | Type | Notes |
|---|---|---|
id | BIGINT PK | |
nurse_id | BIGINT FK → nurse_profiles | |
credential_type | NVARCHAR(50) | moh_competency_license (پروانه صلاحیت حرفهای) / ino_membership (نظام پرستاری) / criminal_record (عدم سوء پیشینه) |
credential_number | NVARCHAR(100) (enc) | License/membership number |
holder_name_snapshot | NVARCHAR(200) | Name as printed, for ID cross-check |
issuing_authority | NVARCHAR(200) | |
issued_at, expires_at | DATE NULL | Drives renewal alerts |
verification_source | NVARCHAR(300) NULL | Portal URL / method |
verification_method | NVARCHAR(20) | manual / portal / api |
verified_by_admin_id | BIGINT FK → users NULL | |
created_at, updated_at | … |
Relations: N:1 → nurse_profiles. Cross-referenced by the relevant verification_steps.