From bd06ef00164d274cf07201f069ea985209efe318 Mon Sep 17 00:00:00 2001 From: hamid Date: Mon, 27 Jul 2026 00:54:22 +0330 Subject: [PATCH] start of manual testing --- dev/manual-testing/image-1.png | Bin 0 -> 18639 bytes dev/manual-testing/image-2.png | Bin 0 -> 70276 bytes dev/manual-testing/image-3.png | Bin 0 -> 16077 bytes dev/manual-testing/image-4.png | Bin 0 -> 76956 bytes dev/manual-testing/image.png | Bin 0 -> 47404 bytes dev/manual-testing/improvement-and-fix-1.md | 66 ++ dev/post-phase/manual-testing-plan.md | 251 +++++++ dev/post-phase/refinement/RUNBOOK.md | 10 + server/CLAUDE.md | 16 + server/src/API/Baya.Web.Api/Program.cs | 7 +- .../Baya.Application/Baya.Application.csproj | 3 + .../Features/Identity/IdentityDefaults.cs | 6 +- .../Models/Identity/UserAccountSnapshot.cs | 9 +- .../Entities/Identity/NurseProfile.cs | 6 + .../Repositories/UserAccountRepository.cs | 38 +- .../ServiceCollectionExtensions.cs | 17 +- .../Seeding/DemoLifecycleDefinitions.cs | 103 +++ .../Seeding/DemoLifecycleSeeder.Money.cs | 372 ++++++++++ .../Seeding/DemoLifecycleSeeder.Social.cs | 485 +++++++++++++ .../Services/Seeding/DemoLifecycleSeeder.cs | 661 ++++++++++++++++++ .../Baya.Test.Api/DemoLifecycleSeederTests.cs | 251 +++++++ 21 files changed, 2289 insertions(+), 12 deletions(-) create mode 100644 dev/manual-testing/image-1.png create mode 100644 dev/manual-testing/image-2.png create mode 100644 dev/manual-testing/image-3.png create mode 100644 dev/manual-testing/image-4.png create mode 100644 dev/manual-testing/image.png create mode 100644 dev/manual-testing/improvement-and-fix-1.md create mode 100644 dev/post-phase/manual-testing-plan.md create mode 100644 server/src/Infrastructure/Baya.Infrastructure.Persistence/Services/Seeding/DemoLifecycleDefinitions.cs create mode 100644 server/src/Infrastructure/Baya.Infrastructure.Persistence/Services/Seeding/DemoLifecycleSeeder.Money.cs create mode 100644 server/src/Infrastructure/Baya.Infrastructure.Persistence/Services/Seeding/DemoLifecycleSeeder.Social.cs create mode 100644 server/src/Infrastructure/Baya.Infrastructure.Persistence/Services/Seeding/DemoLifecycleSeeder.cs create mode 100644 server/src/Tests/Baya.Test.Api/DemoLifecycleSeederTests.cs diff --git a/dev/manual-testing/image-1.png b/dev/manual-testing/image-1.png new file mode 100644 index 0000000000000000000000000000000000000000..9495e331ec9901e9fd22c1e02eb3685645087f40 GIT binary patch literal 18639 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 TIJ$s`5HWbV`njxgN@xNAL11Gm literal 0 HcmV?d00001 diff --git a/dev/manual-testing/image-2.png b/dev/manual-testing/image-2.png new file mode 100644 index 0000000000000000000000000000000000000000..af4238fd4c7bc6ecde49b80693039bcf95046ab4 GIT binary patch literal 70276 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 F|2G;!t84%O literal 0 HcmV?d00001 diff --git a/dev/manual-testing/image-3.png b/dev/manual-testing/image-3.png new file mode 100644 index 0000000000000000000000000000000000000000..d4e9896ae429294e5fed80f21d5fac9f909b071b GIT binary patch literal 16077 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%0D}F-vCc>^r>_{?Z^X!mD!@ir=cY87&@pb?t{!i)9 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 literal 0 HcmV?d00001 diff --git a/dev/manual-testing/improvement-and-fix-1.md b/dev/manual-testing/improvement-and-fix-1.md new file mode 100644 index 0000000..9260819 --- /dev/null +++ b/dev/manual-testing/improvement-and-fix-1.md @@ -0,0 +1,66 @@ +![alt text](image.png) +in the login page, the main card has a big border radius number which should be less, and in fact for all papers that should happen + +the options under the main paper should move inside the paper and have a better positioning + +there is no need for the top bar in the login page, +the language and theme switch also should be only in the settings, not in every top bar in the app, + +the icon sets should be totally replaced with a more modern icon set, and the icon mappign should be realted. + +the default route should be dynamically deteceted, +i mean now whan i open the app and go to /fa or /en +it stays there and just a loading is displayed to me but it should be infered based on the user role and navigate the user to the right path +and if the + +i get this error when i enter the phone number and submit the form +# error start +## Error Type +Console Error + +## Error Message +Functions are not valid as a React child. This may happen if you return transformed instead of from render. Or maybe you meant to call this function rather than return it. +

{transformed}

+ + + at p (:null:null) + at OtpStep (src/components/auth/OtpStep.tsx:103:9) + at LoginFlow (src/components/auth/LoginFlow.tsx:52:9) + at LoginScreen (src/app/[locale]/(public-routes)/login/LoginScreen.tsx:12:7) + at Page (src\app\[locale]\(public-routes)\login\page.tsx:12:10) + +## Code Frame + 101 | {t('otp_title')} + 102 | +> 103 | + | ^ + 104 | {t.rich('otp_sent_to', { + 105 | // isolates the masked number so the RTL sent... + 106 | // never reorders the digit/bullet runs around it (the classi... + +Next.js version: 16.2.9 (Turbopack) +# Error End + +![alt text](image-1.png) +after submitting the phone number the otp input ui needs a better spacing, the first two input are stuck together. this is in fa locale, in the en locale its ok. + + +# nurse dashboard Start +![whole nurse dashboard page](image-2.png) +![cards](image-3.png) +![alt text](image-4.png) + +this dashboard should be totally refactorred, +the ui is kinda old and not a modren and with a good ux, +some text has not proper placing and some of them are too large, +the header and the type of accessing to the dashboard is too old style, +there must not be a header like that, and a side drawer, i modern smooth bottom navbar which have only three options ( as the groups of the drawer items are ) and just a forth item for the support and setting. +so each of the gropus of the side bar should have a root page which handles the links to the sub pages. and in those root pages its better to have a summary of that domain. +two notes: +- icons should be changed till here so i don't mention them again +- ui have much work to do to be acceptable. + +there is a horizontal scroll in this page, this should not be like that, +the whole app should be scoped to a mobile size app, i mean if i scretch the chrome responsive mode, the header and the footer should have a maximum width not to strech and fit to the space +no matter what is the device view port, this should be a mobile sized app. all that sidebar in the desktop width is not needed, at least for now, we have to make the app very user friendly with a mobile user mindset + diff --git a/dev/post-phase/manual-testing-plan.md b/dev/post-phase/manual-testing-plan.md new file mode 100644 index 0000000..baf83a0 --- /dev/null +++ b/dev/post-phase/manual-testing-plan.md @@ -0,0 +1,251 @@ +# Balinyaar — Manual Testing Plan + +The flow-by-flow walkthrough for testing the whole product against the **seeded lifecycle demo world**. +Written after the UI/backend/refinement phase chains completed (2026-07-26). Companion docs: + +- **Bring-up**: [refinement/RUNBOOK.md](refinement/RUNBOOK.md) — how to boot API + client, OTP login mechanics. +- **Business rules with numbers**: `product/business/` — what "correct" means; the load-bearing numbers are + repeated inline below. + +> **How to use this doc:** pick a flow section, log in as the named account, follow the steps, compare +> against *Expected*. Anything marked ⚠ **known gap** is pre-existing and filed (REQ-xxx) — record it as +> confirmation, not as a new bug. Anything else that deviates is a genuine finding. + +--- + +## 1. Environment + +| Piece | Where | Notes | +| --- | --- | --- | +| API | `http://localhost:5002` (`cd server && dotnet run --project src/API/Baya.Web.Api/Baya.Web.Api.csproj`) | Boots in Development: migrates + seeds (reference + demo world + **lifecycle world**) against the DB in `appsettings.Development.json` — currently the **remote dev SQL Server** (`87.107.152.16`). Swagger at `/swagger`. | +| Client | `http://localhost:3000` (`cd client && npm run dev`) | `.env.development` already points at `http://localhost:5002`. | +| Crypto keys | `dotnet user-secrets` (from `server/src/API/Baya.Web.Api`) | The committed config carries `SET_VIA_USER_SECRETS_OR_ENV` placeholders. The remote DB's data is encrypted under the **dev keys** — any machine booting against it must set the same four user-secrets: `IdentitySettings:SecretKey` = `dev-only-jwe-signing-key-not-for-production-0123456789abcdef`, `IdentitySettings:Encryptkey` = `dev-only-16bytes`, `Seams:FieldEncryption:Key` = `local-dev-field-encryption-key-not-for-production`, `Seams:FieldEncryption:HashKey` = `local-dev-field-hash-key-not-for-production`. Booting with *different* field keys makes every phone lookup miss and every PII read throw `Padding is invalid`. | +| OTP codes | server console (`MOCK SMS — OTP code …`) or `GET /api/v1/dev/last_otp/{phone}` | Resend window 120 s, 5 wrong attempts per code, OTP valid 60 s. The OTP endpoints are rate-limited per IP — hammering logins in scripts will 429. | +| Reset | drop the `Baya` DB (`dotnet ef database drop --force --project src/Infrastructure/Baya.Infrastructure.Persistence --startup-project src/API/Baya.Web.Api`), reboot | Everything reseeds. Needed when the **time-relative scenarios age out** (see §3 note). | + +--- + +## 2. Test accounts + +All log in via phone-OTP at `/login`. Any listed account works immediately. + +| Phone | Actor | Who | Carries | +| --- | --- | --- | --- | +| `09120000001` | nurse (verified) | زهرا عزیزی | 4 variants (incl. the 5-session package), whole-city+2-district coverage, ★5.00 (1 published review), 3 completed bookings, a pending request in the inbox, the in-progress visit today, earnings incl. a **paid** payout and a **pending clawback** | +| `09120000002` | nurse (verified) | علی کریمی | Partner-sponsored (مرکز پرستاری آرامش), 2 completed bookings (one BNPL), a **draft** payout waiting, a hidden 1★ review, an expired request | +| `09120000003` | nurse (unverified) | مریم احمدی | Mid-pipeline verification (KYC+Shahkar passed, MoH license in review w/ document, criminal record pending) — **never searchable** | +| `09120000010` | customer | سارا محمدی | 2 patients, 1 address, 6 bookings across all states, pending/accepted/rejected requests, tickets, notifications, care records | +| `09120000011` | customer | رضا حسینی | 1 infant patient, 2 completed bookings (one BNPL w/ processing refund), expired + cancelled requests, a closed support ticket | +| `09120000020` | admin (`super_admin`) | نگار مدیری | Full `/admin` console incl. RBAC | +| `09120000021` | admin (`finance`) | کامران مالی | `/admin` scoped to money consoles (`useAdminCapabilities`) | +| `09120000030` | partner owner | بهنام رستگار | Owns the merchant-of-record center; **navigate to `/partner` manually** after login (⚠ REQ-038 — no `/me` partner signal) | +| any new `09xxxxxxxxx` | fresh user | — | Registers on first OTP verify → `/select-role` → onboarding. Use for first-run testing. | + +--- + +## 3. The seeded world at a glance + +Booking scenarios (all Tehran; seed-time-relative — **T0 = the boot that first seeded**): + +| Key | Who | State | Money / attachments | +| --- | --- | --- | --- | +| pending request | محمدی → عزیزی | `pending_nurse_response`, 24 h countdown | nurse-inbox + C5 tracker fodder | +| accepted request | محمدی → عزیزی | `accepted_awaiting_payment` (24 h demo window, not the real 30 min) | checkout entry; **1 failed card attempt** (wallet history) | +| rejected / expired / cancelled requests | mixed | terminal request states | C5 terminal cards + inbox tabs | +| B1 `upcoming` | محمدی × عزیزی | confirmed, scheduled T0+3d, care instructions written | paid (card), invoice issued, coordination ticket | +| B2 `in_progress` | محمدی × عزیزی | 5-session package: 2 done, **session 3 checked-in now**, 2 scheduled | paid, emergency ticket logged | +| B3 `completed_in_window` | محمدی × عزیزی | completed T0−1d, dispute window open until T0+2d | review **pending moderation**, care record | +| B4 `completed_paid` | محمدی × عزیزی | completed T0−10d, **paid out** | ★5 **published** review (punctual/professional), care record | +| B5 `completed_eligible` | حسینی × کریمی | completed T0−5d, in the **draft batch** | hidden 1★ review, **out-of-range EVV** (1220 m) | +| B6 `bnpl_settled` | حسینی × کریمی | completed T0−6d, paid via SnappPay (net-of-fee) | **processing `bnpl_revert` 50% refund** (ETA ~10 business days), excluded from payouts, care record | +| B7 `cancelled_refunded` | محمدی × عزیزی | cancelled ≥24 h ahead (standard_24h, 100%) | **succeeded card refund** | +| C8 `clawback` | محمدی × عزیزی | completed T0−11d, paid out, then fully refunded | **pending nurse clawback**, support alert | + +Plus: 9+ tickets (coordination per booking, 3 refund tickets, open support w/ an **internal admin note**, +closed support, emergency), notifications for every persona (mixed read/unread), 4 support alerts +(low-rating / EVV-mismatch / clawback / emergency), a paid + a draft payout batch, invoices for all 8 +bookings (کریمی's resolve to the partner center as merchant-of-record). + +> **Time decay:** the world is date-relative and ages. After ~24 h the pending request expires (the sweep +> runs every minute); after ~2 days B3's dispute window closes and the "review-eligible + in-window" state +> is gone; the accepted request's payment window lasts 24 h. **To refresh the timeline: drop the DB and +> reboot** (seeder guards make an in-place re-run a no-op, not a re-date). + +--- + +## 4. Mock-vs-real map (critical for honest testing) + +15 of 22 client domains hit the real API. **7 still run on in-browser mocks** (`USE_*_MOCK = true` in +`client/src/services/{domain}/constants.ts`) because a blocking backend REQ is deferred. On those screens +the UI shows **mock data regardless of the seeded DB** — test the UI/UX there, and verify the *server* +data through Swagger instead. + +| Mocked domain | Screens affected | Server data still verifiable via | +| --- | --- | --- | +| `verification` | nurse `/nurse/verification/*` journey, admin `/admin/verification` queue | `GET nurse_verification/status` (nurse token), Swagger | +| `refunds` | customer cancel flow + `/bookings/[id]/refund_status`, wallet «استردادها» | `GET /api/v1/refunds/by_booking/{id}`, `GET /api/v1/admin_refunds` | +| `payouts` | nurse `/nurse/earnings*`, admin `/admin/payouts` | `GET /api/v1/nurse_payouts/earnings_balance|history`, `GET /api/v1/admin_payouts/batches` | +| `admin` | `/admin/config|holidays|audit|alerts|roles|users` | b1 admin endpoints in Swagger | +| `bnpl` | the whole D1–D5 BNPL checkout + wallet «اقساط» | `GET /api/v1/admin_bnpl/{id}` | +| `partnerCenter` | `/partner/*` portal + `/admin/partners` | `GET /api/v1/admin/partner-centers` | +| `patientRecords` | E2 family care record editor + nurse visit-note panel | `GET /api/v1/patients/{id}/care_records` | + +**Real domains** (UI = server truth): auth, geography, patients, profiles, nurse-bank, addresses, +serviceAreas, catalog, search, bookingRequests, bookings, payment, reviews (incl. **admin moderation**), +tickets (incl. **admin ticket console**), notifications. + +--- + +## 5. Flow walkthroughs + +### 5.1 Auth & first-run (real) + +| # | Steps | Expected | +| --- | --- | --- | +| A1 | `/login` → fresh phone → request code → wrong code ×5 | Refused after 5 attempts until a fresh code; resend locked 120 s; no reveal whether the phone exists | +| A2 | Fresh phone, correct code | → `/select-role` (no roles yet) → pick خانواده → `/onboarding` wizard (relation → first patient) → customer home | +| A3 | Same phone again later | Straight to customer home (role remembered) | +| A4 | Nurse `09120000001` login | Routed to `/nurse` dashboard (never a flash of the customer shell) | +| A5 | Admin `09120000020` vs `09120000021` | Both land `/admin`; finance sees **only** money consoles in the sidebar | +| A6 | Deep link while logged out (e.g. `/bookings`) | → `/login?next=/bookings` → after login lands back on `/bookings` | +| A7 | Logged out, open `/` | Public landing (`/welcome` content, URL stays `/`) — ⚠ verify via `npm run build && npm start` (dev-server root-path quirk, ui-phase-13) | + +### 5.2 Customer — discovery & booking request (real) + +Login: `09120000010`. + +| # | Steps | Expected | +| --- | --- | --- | +| C1 | Home → search entry → category سالمند, region Tehran/whole city | Live count CTA > 0; unverified مریم احمدی **never** appears in any result | +| C2 | Results | عزیزی shows ★5.00 (1 نظر), 3 visits, tappable verified badge; district-3 search still shows her whole-city rows | +| C3 | Gender filter مرد | Only کریمی remains | +| C4 | Open عزیزی's profile | Trust dossier: badge → verification panel (credential **types only**, never numbers); services/prices tab; «نظرات» tab shows exactly **1** published review with tags — the pending + hidden ones never | +| C5 | «درخواست رزرو» → C4 form: patient حسن, address, tomorrow, morning window → submit | Request created; C5 tracker shows a **24 h** countdown ring | +| C6 | As عزیزی (second browser/profile): `/nurse/requests` | New request at top with urgency countdown; detail shows **only** customer notes + coarse city/district (⚠ stage-1 masked address) | +| C7 | Accept it | Customer C5 flips to accepted + **30-minute** payment window countdown (real window — the seeded one is a 24 h demo exception) | +| C8 | Reject another (with reason) | C5 terminal card + «درخواست دوباره» / «پرستاران مشابه» off-ramps | + +### 5.3 Customer — checkout & payment (real contract, mock PSP) + +| # | Steps | Expected | +| --- | --- | --- | +| P1 | C5 of the seeded accepted request → «پرداخت» → C6 | Nurse identity + `` total (variant price), reconciling breakdown, escrow explainer. ⚠ REQ-046: avatar/badge enrichment may be absent on the real path | +| P2 | «ادامه پرداخت» (card) | Initiate succeeds → browser redirects to `https://mock-psp.local/...` — a **dead page. Expected**: the mock PSP has no UI (real E2E completion needs the Phase-8 real PSP config). | +| P3 | To actually complete a payment: Swagger → `POST /api/v1/bookings/convert` body `{"bookingRequestId": }` with the **customer's** bearer token (Dev-only capture simulator) | Booking appears under «رزروها» as confirmed; coordination ticket auto-opens; invoice issued; nurse gets a notification | +| P4 | Wallet «پرداخت‌ها» | ⚠ REQ-047: **empty on the real path** (no transactions-list endpoint). The seeded failed+succeeded transactions are visible in DB/Swagger only | +| P5 | BNPL branch (D1–D5) | ⚠ Whole flow is client-**mock** (REQ-022/024); `/bookings/checkout/bnpl/gateway` only exists under `npm run dev`. Server-side BNPL truth: `admin_bnpl` via Swagger (B6 is `reverted`) | + +### 5.4 Customer — bookings lifecycle (real) + +| # | Steps | Expected | +| --- | --- | --- | +| L1 | `/bookings` tabs | «در انتظار پاسخ»: pending request w/ countdown · «فعال»: B1, B2 · «گذشته»: B3, B4, B7, C8 | +| L2 | B1 (upcoming) detail | Status timeline at تایید شده; next-session headline T0+3d; `.ics` download; address card | +| L3 | B2 (package) detail | 5 sessions listed: 2 completed, 1 **در حال ویزیت** (presence headline), 2 scheduled | +| L4 | B3 review CTA | Star strip on the completed row → review form (context recap + moderation note) — but B3 already carries a pending review, so expect the **"under review"** state, never a second form | +| L5 | B4 | «مشاهده نظر» shows the published ★5 review state | +| L6 | B1 → لغو رزرو | Off-ramps first; tier disclosure: **≥48 h → 100%، ≥24 h → 50%، <24 h → 0%** (server tiers) — ⚠ the UI copy states a single 24 h boundary (REQ-065 divergence; record the exact numbers shown). ⚠ the actual cancel + refund-status screens run on the **mock** refunds domain — server truth via Swagger | +| L7 | B7 → وضعیت استرداد | ⚠ mock domain: UI shows mock stages. Server truth: refund `succeeded`, channel `psp_card` (`GET refunds/by_booking/{B7}`) | +| L8 | `/bookings/[B1]/invoice` | Real invoice: sequential number, VAT = 10% **on the commission line only**, مودیان state `pending`. ⚠ REQ-049: payment-method/reference/seller-fiscal block may be absent | + +### 5.5 Customer — account, care circle, tickets, notifications + +| # | Steps | Expected | +| --- | --- | --- | +| E1 | `/patients` («حلقهٔ مراقبت») | حسن + فاطمه cards; add/edit/archive (real); tap → E2 record | +| E2 | `/patients/[حسن]/record` | ⚠ patientRecords domain is **mock**: meds/routine/tasks + the nurse visit-note history shown are mock data (the 2 real seeded notes are server-side only). Access-denied state testable with the mock's foreign-patient id 8888 | +| E3 | `/addresses` | Real CRUD; map is the canvas stand-in unless `NEXT_PUBLIC_NESHAN_KEY` is set | +| E4 | `/profile` | Identity header (server-masked phone), personal-info edit, language row, emergency-contact card; avatar upload round-trips | +| E5 | `/support/tickets` | Real inbox: refund tickets (`TKT-DEMORF0x`), open support `TKT-DEMOSUP1`, coordination tickets; thread of `TKT-DEMOSUP1` shows customer msg + admin reply + follow-up — **the internal admin note must never appear** | +| E6 | Send a message; send another containing `/fail` | Normal send lands; ⚠ `/fail` sentinel only drives the mock — on the real path it just sends | +| E7 | `/notifications` | Seeded rows, unread-first, day-grouped; mark-read flips the bell count. ⚠ **Notification titles/bodies are English** — server-rendered copy from the real handlers (finding F-4 §7) | + +### 5.6 Nurse — daily ops (real except earnings) + +Login: `09120000001`. + +| # | Steps | Expected | +| --- | --- | --- | +| N1 | `/nurse` dashboard | Next-visit card (B2 today), requests strip (pending w/ countdown), earnings snapshot (⚠ mock numbers — payouts domain), activation checklist collapsed to «فعال در جستجو» | +| N2 | `/nurse/visits` | Today's feed shows B2 session 3 **checked-in** → the check-out CTA is the hero action | +| N3 | Check out (confirm step) | Session completes; EVV panel updates. GPS: set `NEXT_PUBLIC_EVV_MOCK_GPS=in_range` in `client/.env.local` to force a passing location, else real geolocation runs (out-of-tolerance is **advisory** — banner + staff alert, never a block). Completing the **last** session would complete the booking and start its 72 h dispute clock | +| N4 | `/nurse/visits/[B2]` | Address card + map link (⚠ REQ-051: address may stay masked w/ quiet fallback note), gated care card (care instructions **readable** post-confirmation), visit-note composer (⚠ mock — patientRecords) | +| N5 | `/nurse/requests` | Tabs: pending (live countdown) / answered / expired. Accept behind confirm dialog → opens the payment window | +| N6 | `/nurse/earnings` + `/payouts` | ⚠ **Mock domain** — UI shows mock buckets. Server truth (Swagger, nurse token): `earnings_balance` = signed ledger sum (عزیزی: B1+B2+B3 payouts pending — B7 reversed, B4/C8 paid out), `history` shows the **paid** payout w/ masked IBAN | +| N7 | `/nurse/services` | 4 offerings incl. the package variant; edit/deactivate; the accepting-bookings toggle is real (pausing → disappears from search) | +| N8 | `/nurse/coverage` | Whole-city + districts 1&3; duplicate add → 409 message | +| N9 | `/nurse/bank` | Verified account, masked IBAN, ownership state «تأیید شده» | +| N10 | As کریمی (`09120000002`) | Draft-batch earnings waiting; B6's payout share reversed by the 50% refund; hidden review does **not** appear on his public profile (0 reviews) | +| N11 | As احمدی (`09120000003`) | Activation checklist far from complete; `/nurse/verification` — ⚠ **mock domain**: the journey UI shows mock state; the real mid-pipeline case (KYC ✓, Shahkar ✓, license in-review, criminal pending) is server-side (`nurse_verification/status` via Swagger). She must never appear in search | + +### 5.7 Admin console + +Login: `09120000020` (all consoles) and `09120000021` (money only). + +| # | Console | Real/Mock | What the seeded world provides (server-side) | +| --- | --- | --- | --- | +| AD1 | `/admin/reviews` moderation queue | **Real** | B3's pending review — publish it → عزیزی's public aggregate recomputes (★ count 2); hide/reject paths; the hidden 1★ shows the hide flow already happened | +| AD2 | `/admin/tickets` | **Real** | Full queue incl. emergency (red) + refund tickets; thread of `TKT-DEMOSUP1` **shows** the internal note distinctly; composer's internal-note mode goes amber | +| AD3 | `/admin/verification` | ⚠ Mock | Real queue data (احمدی in review + document metadata) via Swagger `admin_verifications`; the document's signed-URL fetch 404s (no real bytes — expected) | +| AD4 | `/admin/payouts` | ⚠ Mock | Real: `admin_payouts/batches` shows the **completed** batch (2 links) + the **draft** batch; `batches/{id}/process` on the draft is the demoable money-out action; `eligible` preview | +| AD5 | Refunds (via ticket RefundPanel) | ⚠ Mock | Real: `admin_refunds` lists 3 refunds; `{id}/confirm_settlement` on the **processing BNPL** refund is the demoable action (posts the clearing leg) | +| AD6 | `/admin/alerts` | ⚠ Mock | Real: 4 seeded alerts (low_rating / evv_location_mismatch / nurse_clawback / emergency) via `support_alerts` endpoints | +| AD7 | `/admin/config`, `/admin/holidays`, `/admin/audit`, `/admin/users`, `/admin/roles` | ⚠ Mock | Real: b1 endpoints (config list incl. the §6 numbers, audit trail rows for every seeded money/trust entity — actor `null` = system) | +| AD8 | `/admin/partners` | ⚠ Mock | Real: `admin/partner-centers` shows مرکز پرستاری آرامش (MoR, verified, masked IBAN), کریمی sponsored | + +### 5.8 Partner portal (⚠ mock — REQ-032/033/038) + +Login `09120000030` → navigate to `/partner` manually. UI runs on mock center data; the real center + +MoR invoice resolution (کریمی's two invoices carry `issuing_entity_type = partner_center`) is verifiable +via Swagger. Test the portal chrome, the MoR settlement view, and the CSV export against mock data. + +--- + +## 6. The numbers the UI must respect + +From seeded `platform_configs` (admins can change them; rates are **snapshotted** — a change never +re-prices an existing booking/invoice/deadline): + +| Rule | Value | +| --- | --- | +| Nurse response deadline | **24 h** (frozen per request) | +| Payment window after accept | **30 min** (frozen per request) | +| Dispute window after completion | **72 h** → then payout-eligible | +| Platform commission | **15%** of gross (`gross = commission + payout`, always) | +| VAT | **10%**, on the **commission line only** | +| Cancellation tiers | ≥48 h → 100% · ≥24 h → 50% · <24 h → 0% (⚠ client copy says a single 24 h boundary — REQ-065) | +| BNPL provider fee | **7%** — a **platform expense**; the nurse payout is payment-method-invariant | +| BNPL refund ETA | ~**10 business days** (Fridays skipped); UI copy says 7–10 | +| EVV tolerance | **200 m**, advisory only | +| No-show threshold | **60 min** after scheduled start | +| Payout cadence | weekly generation (auto, draft); **processing stays a manual admin action** | +| Review alert | rating ≤ **2** raises a staff alert | +| OTP | resend 120 s · 5 attempts · code lives 60 s · session 30 d · access token 60 min | + +--- + +## 7. Findings from this bring-up (decide / track) + +Recorded while building the seed — each needs an owner decision: + +| # | Finding | State | +| --- | --- | --- | +| F-1 | **Committed real DB credential**: `appsettings.Development.json` ships the remote server's SQL login in git (the exact thing refinement-phase-5 removed; the pre-commit hook that blocks it isn't enabled on this clone). Recommendation: move the connection strings to user-secrets like the crypto keys and restore placeholders. | **Open — decision needed** | +| F-2 | **`/me` hardcoded `hasCustomerProfile`/`hasNurseProfile`/`nurseVerificationStatus`** to `false`/`not_started` for everyone (broke the customer home profile nudge + profile-hook invalidations). | **Fixed** this session (snapshot projection + `ToMeResult`) | +| F-3 | **Stored Persian text is normalized destructively**: an `ApplicationDbContext` save hook runs `Fa2En().FixPersianChars()` over every string property — Persian digits become ASCII and **ZWNJ becomes a space** in everything persisted (e.g. «شبانه‌روزی» → «شبانه روزی»), contradicting the client's STYLE.md ZWNJ rules. Any Persian-literal equality against stored data silently misses. | **Open — decision needed** (legacy starter behavior; removing it changes stored data shape) | +| F-4 | **Notification copy is English on the real path** — the b-phase handlers write `"Booking confirmed"`-style titles/bodies straight into `ops.Notifications`; the Persian UI renders them verbatim. | **Open — decision needed** (server-side i18n or client-side type→copy mapping) | +| F-5 | Mock PSP redirect goes to a dead host (`mock-psp.local`) — in-browser card completion impossible until a real PSP is configured (`Payments:Provider=zarinpal`); the Dev `bookings/convert` affordance is the workaround (§5.3 P3). | By design (refinement-phase-8 rails exist behind config) | +| F-6 | 7 client domains still mocked (§4) — the biggest lever for "test everything for real" is flipping `verification`, `refunds`, `payouts` (user halves are contract-ready; the blocking REQs are admin-side). Flipping a shared flag turns the admin half's screens into real-API screens against missing endpoints. | **Open — decision needed** (split flags per half, or deliver the admin REQs) | +| F-7 | Seeded object-storage keys (verification document, invoice PDFs) have no real bytes — signed-URL fetches 404 in admin viewers. | Accepted for dev (never fake bytes) | + +--- + +## 8. Suggested test order + +1. **Auth & routing** (§5.1) — everything depends on it. +2. **Customer discovery → request → accept → convert → booking** (§5.2–5.4) — the core funnel, all real. +3. **Nurse ops** (§5.6) — inbox/EVV against the same bookings. +4. **Reviews + tickets + notifications** (§5.4 L4/L5, §5.5 E5–E7) — real, seeded both sides. +5. **Admin real consoles** (§5.7 AD1/AD2) — moderation + tickets. +6. **Mock-domain UI passes** (§5.3 P5, §5.5 E2, §5.6 N6/N11, §5.7 AD3–AD8, §5.8) — UX only, verify server truth via Swagger as listed. +7. Sweep §7's decisions. diff --git a/dev/post-phase/refinement/RUNBOOK.md b/dev/post-phase/refinement/RUNBOOK.md index 5a4669a..60ee5e6 100644 --- a/dev/post-phase/refinement/RUNBOOK.md +++ b/dev/post-phase/refinement/RUNBOOK.md @@ -86,6 +86,15 @@ demo nurses with priced variants + Tehran coverage (and therefore real `nurse_se customers with patients and addresses. The console logs `Demo world seeded: 3 nurse(s), 2 customer(s)…` (or `already seeded — no-op` on a subsequent run). It is **idempotent** and **never runs outside Development**. +On top of that, the **lifecycle seeder** (`DemoLifecycleSeeder`) populates every flow's mid-state so manual +testing never starts from an empty world: booking requests in every status, 8 bookings across every reachable +state (incl. a 5-session package mid-engagement and a cancelled-and-refunded one), the balanced ledger, three +refunds (card-succeeded / BNPL-processing / post-payout clawback), a **paid** and a **draft** payout batch, +reviews in all moderation states, tickets, notifications, patient care records, a merchant-of-record partner +center, and a mid-pipeline verification case. The console logs `Demo lifecycle seeded: …` (or `already +seeded — no-op`). The full scenario map + per-flow walkthroughs live in +[`dev/post-phase/manual-testing-plan.md`](../manual-testing-plan.md). + ### Terminal 2 — frontend (from `client/`) ```bash @@ -114,6 +123,7 @@ endpoint works). Use them to see the real path populated: | `09120000011` | customer | رضا حسینی (male) | 1 patient, 1 Tehran address | | `09120000020` | admin (`super_admin`) | نگار مدیری (female) | full backoffice — **lands on `/admin`**, sees every console incl. RBAC | | `09120000021` | admin (`finance`) | کامران مالی (male) | scoped backoffice — lands on `/admin`, sidebar shows only the money consoles (`useAdminCapabilities` gating) | +| `09120000030` | partner-center owner | بهنام رستگار (male) | owns مرکز پرستاری آرامش (merchant-of-record, sponsors علی کریمی). No admin/nurse role — log in, then navigate to `/partner` manually (REQ-038: no `/me` partner signal yet) | > The old username+password `admin`/`qw123321` account is **no longer auto-seeded** (refinement-phase-5 — > no committed credential). To bootstrap a break-glass username+password admin, set both secrets before boot, diff --git a/server/CLAUDE.md b/server/CLAUDE.md index 9aadb5f..2f385fb 100644 --- a/server/CLAUDE.md +++ b/server/CLAUDE.md @@ -677,6 +677,22 @@ action to `sender.Send(...)`. Full conventions are in [CONVENTIONS.md](CONVENTIO guarding each persona on its phone number so re-runs are a no-op. Invoked via `SeedDemoWorldAsync()` **only under `IsDevelopment()`** — never in Production/Staging. The demo world (phones, which nurse is verified) is in `dev/post-phase/refinement/RUNBOOK.md`. +- **Development lifecycle seeder (manual-testing bring-up).** `Persistence/Services/Seeding/DemoLifecycleSeeder.cs` + (+ `.Money.cs`/`.Social.cs` partials + `DemoLifecycleDefinitions.cs`) layers a full **lifecycle** world on the + demo personas so every flow is manually testable: booking requests in every status, 8 bookings across every + reachable state (upcoming w/ care instructions, a 5-session package mid-engagement with EVV, completed + inside/past the dispute window, BNPL-settled, cancelled-with-refund, clawed-back), the balanced payment + ledger behind each (via `LedgerPosting`), refunds on all three forks, a **paid** and a **draft** payout batch + (dispatched through the real `GeneratePayoutBatch`/`ExecutePayoutBatch` commands), moderated reviews + + recomputed nurse aggregates, tickets (incl. an `is_internal` note + coordination tickets via the real + command), notifications, patient care records, a merchant-of-record partner center (portal user + `09120000030`, linked to the second nurse), and a mid-pipeline verification case for the unverified nurse. + States are reached through the entities' guarded transition methods + `BookingFactory` (Application grants + `InternalsVisibleTo` to Persistence for this); business timestamps are backdated explicitly. Idempotent per + scenario on natural keys — **never guard on a Persian string**: the `ApplicationDbContext` save hook + normalizes Persian digits/ZWNJ in every stored string, so a Persian literal never round-trips equal. + Invoked via `SeedDemoLifecycleAsync()` after the demo-world + gateway seeds, Development-only. Scenario + table + testing plan: `dev/post-phase/manual-testing-plan.md`. --- diff --git a/server/src/API/Baya.Web.Api/Program.cs b/server/src/API/Baya.Web.Api/Program.cs index 537051b..06d140b 100644 --- a/server/src/API/Baya.Web.Api/Program.cs +++ b/server/src/API/Baya.Web.Api/Program.cs @@ -131,6 +131,7 @@ if (args.Any(a => string.Equals(a, "migrate", StringComparison.OrdinalIgnoreCase { await app.SeedPaymentGatewaysAsync(); await app.SeedDemoWorldAsync(); + await app.SeedDemoLifecycleAsync(); } return; } @@ -142,12 +143,14 @@ if (!app.Environment.IsEnvironment("Testing")) if (app.Environment.IsDevelopment()) { // Local convenience: apply migrations + seed on boot. Development-only: a sandbox payment gateway - // (all-zeros merchant id) and a demo marketplace (nurses/variants/search rows, customers/patients) so the - // real-path screens aren't empty. Neither belongs in a deployed DB — both are idempotent. + // (all-zeros merchant id), a demo marketplace (nurses/variants/search rows, customers/patients), and + // the lifecycle demo world (bookings/money/reviews/tickets in every state) so the real-path screens + // aren't empty. None of it belongs in a deployed DB — all are idempotent. await app.ApplyMigrationsAsync(); await app.SeedDefaultUsersAsync(); await app.SeedPaymentGatewaysAsync(); await app.SeedDemoWorldAsync(); + await app.SeedDemoLifecycleAsync(); } else { diff --git a/server/src/Core/Baya.Application/Baya.Application.csproj b/server/src/Core/Baya.Application/Baya.Application.csproj index 7481fea..ee4e4bf 100644 --- a/server/src/Core/Baya.Application/Baya.Application.csproj +++ b/server/src/Core/Baya.Application/Baya.Application.csproj @@ -12,6 +12,9 @@ + + diff --git a/server/src/Core/Baya.Application/Features/Identity/IdentityDefaults.cs b/server/src/Core/Baya.Application/Features/Identity/IdentityDefaults.cs index c4279bd..86e5fca 100644 --- a/server/src/Core/Baya.Application/Features/Identity/IdentityDefaults.cs +++ b/server/src/Core/Baya.Application/Features/Identity/IdentityDefaults.cs @@ -79,7 +79,7 @@ internal static class IdentityDefaults snapshot.Gender, snapshot.IsActive, snapshot.Roles, - HasCustomerProfile: false, - HasNurseProfile: false, - NurseVerificationStatus: MeResult.VerificationNotStarted); + snapshot.HasCustomerProfile, + snapshot.HasNurseProfile, + snapshot.NurseVerificationStatus); } \ No newline at end of file diff --git a/server/src/Core/Baya.Application/Models/Identity/UserAccountSnapshot.cs b/server/src/Core/Baya.Application/Models/Identity/UserAccountSnapshot.cs index 50331e3..7b85be2 100644 --- a/server/src/Core/Baya.Application/Models/Identity/UserAccountSnapshot.cs +++ b/server/src/Core/Baya.Application/Models/Identity/UserAccountSnapshot.cs @@ -1,7 +1,9 @@ #nullable enable namespace Baya.Application.Models.Identity; -/// Raw account projection for the current user (phone unmasked — handlers mask it). +/// Raw account projection for the current user (phone unmasked — handlers mask it). The profile +/// flags/verification code default to the "nothing yet" shape so test doubles that only care about the +/// account core don't have to state them. public record UserAccountSnapshot( int Id, string? Phone, @@ -9,4 +11,7 @@ public record UserAccountSnapshot( string? LastName, string? Gender, bool IsActive, - IReadOnlyList Roles); \ No newline at end of file + IReadOnlyList Roles, + bool HasCustomerProfile = false, + bool HasNurseProfile = false, + string NurseVerificationStatus = "not_started"); \ No newline at end of file diff --git a/server/src/Core/Baya.Domain/Entities/Identity/NurseProfile.cs b/server/src/Core/Baya.Domain/Entities/Identity/NurseProfile.cs index 4da3b09..b72fc38 100644 --- a/server/src/Core/Baya.Domain/Entities/Identity/NurseProfile.cs +++ b/server/src/Core/Baya.Domain/Entities/Identity/NurseProfile.cs @@ -64,4 +64,10 @@ public class NurseProfile : BaseEntity AverageRating = averageRating; TotalReviews = totalReviews; } + + /// The single sanctioned write path for the completed-bookings aggregate — recomputed from + /// source (completed bookings rows), never accepted from a request. Mirrors + /// ; consumed by the search projection and the public profile. + public void SetCompletedBookings(int totalCompletedBookings) + => TotalCompletedBookings = totalCompletedBookings; } diff --git a/server/src/Infrastructure/Baya.Infrastructure.Persistence/Repositories/UserAccountRepository.cs b/server/src/Infrastructure/Baya.Infrastructure.Persistence/Repositories/UserAccountRepository.cs index 66730df..911e748 100644 --- a/server/src/Infrastructure/Baya.Infrastructure.Persistence/Repositories/UserAccountRepository.cs +++ b/server/src/Infrastructure/Baya.Infrastructure.Persistence/Repositories/UserAccountRepository.cs @@ -1,6 +1,8 @@ using Baya.Application.Contracts.Persistence; using Baya.Application.Models.Identity; +using Baya.Domain.Entities.Identity; using Baya.Domain.Entities.User; +using Baya.Domain.Entities.Verification; using Baya.Infrastructure.Persistence.Repositories.Common; using Microsoft.EntityFrameworkCore; @@ -12,20 +14,48 @@ internal class UserAccountRepository : BaseAsyncRepository, IUserAccountRe { } - public Task GetAccountSnapshotAsync(int userId, CancellationToken cancellationToken) + public async Task GetAccountSnapshotAsync(int userId, CancellationToken cancellationToken) { // UserRoles carries a RevokedAt-is-null global filter, so revoked grants never surface here. - return TableNoTracking + // The profile flags/verification status are correlated subqueries (soft-delete filters apply), and + // the enum→code mapping happens after materialization — ToCode() is not SQL-translatable. + var row = await TableNoTracking .Where(u => u.Id == userId) - .Select(u => new UserAccountSnapshot( + .Select(u => new + { u.Id, u.PhoneNumber, u.Name, u.FamilyName, u.Gender, u.IsActive, - u.UserRoles.Select(ur => ur.Role.Name).ToList())) + Roles = u.UserRoles.Select(ur => ur.Role.Name).ToList(), + HasCustomerProfile = DbContext.Set().Any(p => p.UserId == u.Id), + HasNurseProfile = DbContext.Set().Any(p => p.UserId == u.Id), + VerificationStatus = DbContext.Set() + .Where(v => v.Nurse.UserId == u.Id) + .OrderByDescending(v => v.Id) + .Select(v => (VerificationStatus?)v.Status) + .FirstOrDefault() + }) .FirstOrDefaultAsync(cancellationToken); + + if (row is null) + return null; + + return new UserAccountSnapshot( + row.Id, + row.PhoneNumber, + row.Name, + row.FamilyName, + row.Gender, + row.IsActive, + row.Roles, + HasCustomerProfile: row.HasCustomerProfile, + HasNurseProfile: row.HasNurseProfile, + NurseVerificationStatus: row.VerificationStatus is { } status + ? status.ToCode() + : MeResult.VerificationNotStarted); } public Task GetTrackedByIdAsync(int userId, CancellationToken cancellationToken) diff --git a/server/src/Infrastructure/Baya.Infrastructure.Persistence/ServiceConfiguration/ServiceCollectionExtensions.cs b/server/src/Infrastructure/Baya.Infrastructure.Persistence/ServiceConfiguration/ServiceCollectionExtensions.cs index e186123..d6ac101 100644 --- a/server/src/Infrastructure/Baya.Infrastructure.Persistence/ServiceConfiguration/ServiceCollectionExtensions.cs +++ b/server/src/Infrastructure/Baya.Infrastructure.Persistence/ServiceConfiguration/ServiceCollectionExtensions.cs @@ -88,9 +88,10 @@ public static class ServiceCollectionExtensions throw new NotSupportedException( $"Search backend '{searchBackend}' is not available — only 'sql' is implemented (Elasticsearch is deferred)."); - // Development-only demo marketplace seeder. Registered always (cheap), but invoked from Program.cs + // Development-only demo seeders. Registered always (cheap), but invoked from Program.cs // only under IsDevelopment() — never against a production/staging DB. services.AddScoped(); + services.AddScoped(); return services; } @@ -165,4 +166,18 @@ public static class ServiceCollectionExtensions var seeder = scope.ServiceProvider.GetRequiredService(); await seeder.SeedAsync(CancellationToken.None); } + + /// + /// Seeds the Development-only lifecycle demo world (booking requests in every status, bookings in + /// every reachable state with their balanced ledger, refunds/payouts/reviews/tickets/notifications, a + /// partner center, a mid-pipeline verification case) on top of 's + /// personas. Idempotent per scenario. Must run after the demo world + payment-gateway seeds; the + /// same IsDevelopment() gating rule applies. + /// + public static async Task SeedDemoLifecycleAsync(this WebApplication app) + { + await using var scope = app.Services.CreateAsyncScope(); + var seeder = scope.ServiceProvider.GetRequiredService(); + await seeder.SeedAsync(CancellationToken.None); + } } \ No newline at end of file diff --git a/server/src/Infrastructure/Baya.Infrastructure.Persistence/Services/Seeding/DemoLifecycleDefinitions.cs b/server/src/Infrastructure/Baya.Infrastructure.Persistence/Services/Seeding/DemoLifecycleDefinitions.cs new file mode 100644 index 0000000..08cd3b4 --- /dev/null +++ b/server/src/Infrastructure/Baya.Infrastructure.Persistence/Services/Seeding/DemoLifecycleDefinitions.cs @@ -0,0 +1,103 @@ +#nullable enable +namespace Baya.Infrastructure.Persistence.Services.Seeding; + +/// +/// The static, deterministic description of the Development lifecycle demo world the +/// materialises on top of 's personas: +/// which booking scenario exists in which state, the fixed ticket reference codes, and the one extra +/// partner-center persona. Kept as plain data so the exact scenario table reads at a glance and stays the +/// single source of truth for the runbook / testing plan. +/// +/// All timestamps are expressed as day/hour offsets from seed time (negative = past) because the +/// scenario meanings are relative ("completed inside the 72h dispute window"), not absolute dates. +/// +/// +internal static class DemoLifecycleDefinitions +{ + /// The partner-center dashboard owner (no admin/nurse role — the portal keys off the center's + /// admin_user_id; the customer role only gives the login a sane landing). + public const string PartnerAdminPhone = "09120000030"; + public const string PartnerAdminUserName = "demo_partner_rastegar"; + public const string PartnerAdminName = "بهنام"; + public const string PartnerAdminFamilyName = "رستگار"; + + public const string PartnerCenterName = "مرکز پرستاری آرامش"; + public const string PartnerCenterPermitNo = "MOH-C-1001"; // the natural idempotency key + public const string PartnerCenterEnamad = "ENAMAD-DEMO-771"; + + /// The extra 5-session package variant seeded for the multi-session booking scenario + /// (PostSurgery × Night so its option-set hash can never collide with the base seeder's variants). + public const string PackageVariantDisplayName = "پکیج ۵ جلسه‌ای مراقبت پس از جراحی"; + public const long PackageVariantPricePerSession = 900_000; + public const int PackageVariantSessionCount = 5; + + // Fixed, human-greppable ticket reference codes — UNIQUE-indexed, so they double as idempotency guards. + public const string RefundTicketCard = "TKT-DEMORF01"; + public const string RefundTicketBnpl = "TKT-DEMORF02"; + public const string RefundTicketClawback = "TKT-DEMORF03"; + public const string SupportTicketOpen = "TKT-DEMOSUP1"; + public const string SupportTicketClosed = "TKT-DEMOSUP2"; + public const string EmergencyTicket = "TKT-DEMOEMG1"; + + /// Prefix for the fake Shaparak reference codes (filtered-UNIQUE column — each txn appends its + /// scenario key). + public const string GatewayRefPrefix = "demo-shaparak-"; + + /// + /// The booking scenario table. One row per engagement, keyed by (stable, greppable). + /// Offsets are in days relative to seed time unless noted. A null means the + /// booking never completed. The request behind every booking is converted; the request-only + /// scenarios (pending/accepted/rejected/expired/cancelled) are seeded separately in the seeder. + /// + public static readonly BookingScenario[] Bookings = + [ + // B1 — paid, upcoming, care instructions written; the "what does a fresh confirmed booking look like" case. + new("upcoming", Customer: 0, Nurse: 0, VariantIndex: 0, ScheduledInDays: 3, + ConfirmedDaysAgo: 1, CompletedDaysAgo: null, Cancelled: false, WithCareInstructions: true), + + // B2 — the multi-session package, mid-engagement today: 2 sessions done, session 3 checked-in now. + new("in_progress", Customer: 0, Nurse: 0, VariantIndex: -1 /* the seeded package variant */, ScheduledInDays: 0, + ConfirmedDaysAgo: 4, CompletedDaysAgo: null, Cancelled: false, WithCareInstructions: true), + + // B3 — completed yesterday: dispute window still open, review still pending moderation. + new("completed_in_window", Customer: 0, Nurse: 0, VariantIndex: 2, ScheduledInDays: -1, + ConfirmedDaysAgo: 3, CompletedDaysAgo: 1, Cancelled: false, WithCareInstructions: false), + + // B4 — completed long ago, paid out, carries the published 5★ review. + new("completed_paid", Customer: 0, Nurse: 0, VariantIndex: 0, ScheduledInDays: -10, + ConfirmedDaysAgo: 12, CompletedDaysAgo: 10, Cancelled: false, WithCareInstructions: false), + + // B5 — completed, window closed, waiting in the draft batch; carries the hidden 1★ review + the + // out-of-range EVV check-in that feeds the admin EVV queue. + new("completed_eligible", Customer: 1, Nurse: 1, VariantIndex: 0, ScheduledInDays: -5, + ConfirmedDaysAgo: 7, CompletedDaysAgo: 5, Cancelled: false, WithCareInstructions: false), + + // B6 — paid via BNPL (settled net-of-fee), then disputed: a processing bnpl_revert refund excludes it + // from every payout batch. + new("bnpl_settled", Customer: 1, Nurse: 1, VariantIndex: 1, ScheduledInDays: -6, + ConfirmedDaysAgo: 8, CompletedDaysAgo: 6, Cancelled: false, WithCareInstructions: false), + + // B7 — cancelled ≥24h ahead (standard_24h, 100%): the succeeded card refund. + new("cancelled_refunded", Customer: 0, Nurse: 0, VariantIndex: 2, ScheduledInDays: 2, + ConfirmedDaysAgo: 3, CompletedDaysAgo: null, Cancelled: true, WithCareInstructions: false), + + // C8 — completed + paid out, then refunded: the post-payout clawback case. + new("clawback", Customer: 0, Nurse: 0, VariantIndex: 1, ScheduledInDays: -11, + ConfirmedDaysAgo: 13, CompletedDaysAgo: 11, Cancelled: false, WithCareInstructions: false), + ]; +} + +/// One booking scenario row. / index into +/// /; +/// indexes the nurse's variants in creation order (−1 = the seeded 5-session +/// package variant). +internal sealed record BookingScenario( + string Key, + int Customer, + int Nurse, + int VariantIndex, + int ScheduledInDays, + int ConfirmedDaysAgo, + int? CompletedDaysAgo, + bool Cancelled, + bool WithCareInstructions); diff --git a/server/src/Infrastructure/Baya.Infrastructure.Persistence/Services/Seeding/DemoLifecycleSeeder.Money.cs b/server/src/Infrastructure/Baya.Infrastructure.Persistence/Services/Seeding/DemoLifecycleSeeder.Money.cs new file mode 100644 index 0000000..cb97fc1 --- /dev/null +++ b/server/src/Infrastructure/Baya.Infrastructure.Persistence/Services/Seeding/DemoLifecycleSeeder.Money.cs @@ -0,0 +1,372 @@ +#nullable enable +using Baya.Application.Features.Invoices.Commands.IssueInvoice; +using Baya.Application.Features.Payouts.Commands.ExecutePayoutBatch; +using Baya.Application.Features.Payouts.Commands.GeneratePayoutBatch; +using Baya.Domain.Entities.Bnpl; +using Baya.Domain.Entities.Booking; +using Baya.Domain.Entities.Messaging; +using Baya.Domain.Entities.PartnerCenters; +using Baya.Domain.Entities.Payments; +using Baya.Domain.Entities.Payouts; +using Baya.Domain.Entities.Refunds; +using Baya.Domain.Entities.User; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; + +namespace Baya.Infrastructure.Persistence.Services.Seeding; + +internal sealed partial class DemoLifecycleSeeder +{ + // --------------------------------------------------------------------------------------------------- + // BNPL — the settled provider-financed order behind the "bnpl_settled" booking (net-of-fee model). + // --------------------------------------------------------------------------------------------------- + + private async Task EnsureBnplAsync(BookingWorld bookings, DateTime now, CancellationToken cancellationToken) + { + if (!bookings.ByKey.TryGetValue("bnpl_settled", out var booking)) + return; + + var txn = bookings.TxnByKey["bnpl_settled"]; + if (await db.Set().AnyAsync(b => b.PaymentTransactionId == txn.Id, cancellationToken)) + return; + + var commissionRate = await platformConfig.GetConfig("bnpl_provider_commission_rate", cancellationToken); + var fee = (long)Math.Round(booking.GrossPriceIrr * commissionRate, MidpointRounding.AwayFromZero); + var settledAt = booking.ConfirmedAt ?? now; + + var bnpl = new BnplTransaction + { + PaymentTransactionId = txn.Id, + ProviderCode = BnplProviderCodes.SnappPay, + MerchantOfRecord = "platform", + EligibilityStatus = "approved", + OrderAmountIrr = booking.GrossPriceIrr, + InstallmentCount = 4 + }; + bnpl.MarkTokenIssued("demo-bnpl-token-1", "demo-bnpl-order-1"); + bnpl.MarkVerified("demo-bnpl-order-1", "{\"source\":\"demo-lifecycle-seed\",\"step\":\"verify\"}"); + bnpl.MarkSettled( + settledAmountIrr: booking.GrossPriceIrr - fee, + commissionIrr: fee, + settledAt: settledAt.AddDays(1), + callbackPayloadJson: "{\"source\":\"demo-lifecycle-seed\",\"step\":\"settle\"}"); + db.Set().Add(bnpl); + await db.SaveChangesAsync(cancellationToken); // assigns bnpl.Id for the ledger source ref + + db.Set().AddRange(LedgerPosting.BnplSettle( + booking.Id, booking.NurseId, booking.GrossPriceIrr, booking.BalinyaarCommissionIrr, + booking.NursePayoutAmount, bnplCommissionIrr: fee, bnplTransactionId: bnpl.Id, createdAt: settledAt.AddDays(1))); + await db.SaveChangesAsync(cancellationToken); + } + + // --------------------------------------------------------------------------------------------------- + // Payout batches — dispatched through the REAL commands so eligibility, the first-payout IBAN gate, + // clawback netting, and the payout ledger all come from production code, not a reimplementation. + // --------------------------------------------------------------------------------------------------- + + private async Task EnsurePaidPayoutBatchAsync(BookingWorld bookings, DateTime now, CancellationToken cancellationToken) + { + if (!bookings.ByKey.TryGetValue("completed_paid", out var paidBooking)) + return; + if (await db.Set().AnyAsync(l => l.BookingId == paidBooking.Id, cancellationToken)) + return; + + // periodEnd T0−4d keeps the still-in-draft-window bookings (dispute end T0−2d/−3d) out of this batch. + var generate = await sender.Send( + new GeneratePayoutBatchCommand(Today(now, -21), Today(now, -4)) { SystemInitiated = true }, + cancellationToken); + if (!generate.IsSuccess) + { + logger.LogWarning("Demo lifecycle: paid payout batch generation failed — skipping the paid-batch scenario."); + return; + } + + // The seeder is the only writer at boot, so the newest batch is the one just generated. + var batchId = await db.Set() + .OrderByDescending(b => b.Id) + .Select(b => b.Id) + .FirstAsync(cancellationToken); + + var execute = await sender.Send(new ExecutePayoutBatchCommand(batchId), cancellationToken); + if (!execute.IsSuccess) + logger.LogWarning("Demo lifecycle: executing payout batch {BatchId} failed — it stays unprocessed.", batchId); + } + + private async Task EnsureDraftPayoutBatchAsync(BookingWorld bookings, DateTime now, CancellationToken cancellationToken) + { + if (!bookings.ByKey.TryGetValue("completed_eligible", out var eligibleBooking)) + return; + if (await db.Set().AnyAsync(l => l.BookingId == eligibleBooking.Id, cancellationToken)) + return; + + // Runs AFTER the refunds: the BNPL-refunded booking is genuinely excluded by the real eligibility + // query, and this batch deliberately stays draft so the admin "process" action is demoable. + var generate = await sender.Send( + new GeneratePayoutBatchCommand(Today(now, -3), Today(now, -1)) { SystemInitiated = true }, + cancellationToken); + if (!generate.IsSuccess) + logger.LogWarning("Demo lifecycle: draft payout batch generation failed — skipping the draft-batch scenario."); + } + + // --------------------------------------------------------------------------------------------------- + // Refunds — one per channel/fork: succeeded card, processing BNPL revert, post-payout clawback. + // Every refund is ticket-linked (b15: refunds.ticket_id is always non-null on the real path). + // --------------------------------------------------------------------------------------------------- + + private async Task EnsureRefundsAsync( + PersonaWorld world, BookingWorld bookings, DateTime now, CancellationToken cancellationToken) + { + var admin = world.AdminUserId; + + // 1) Cancelled booking → full (100%) card refund, already succeeded. + if (bookings.ByKey.TryGetValue("cancelled_refunded", out var cancelled) + && !await db.Set().AnyAsync(r => r.BookingId == cancelled.Id, cancellationToken)) + { + var customer = world.Customers[0]; + var ticket = await EnsureRefundTicketAsync( + DemoLifecycleDefinitions.RefundTicketCard, cancelled.Id, customer.UserId, admin, + "استرداد وجه رزرو لغوشده", now.AddDays(-1), cancellationToken); + + var refund = new Refund + { + PaymentTransactionId = bookings.TxnByKey["cancelled_refunded"].Id, + BookingId = cancelled.Id, + RequestedByCustomerId = customer.ProfileId, + TicketId = ticket.Id, + Amount = cancelled.GrossPriceIrr, + PlatformFeeRefundedIrr = cancelled.BalinyaarCommissionIrr, + NursePayoutRefundedIrr = cancelled.NursePayoutAmount, + RefundPercentage = 1.0m, + RefundChannel = RefundChannel.PspCard, + ReasonCategory = "customer_cancelled", + CancellationPolicyCode = cancelled.CancellationPolicyCode, + RefundPercentageApplied = cancelled.CancellationRefundPercentage, + ApprovedByAdminId = admin + }; + refund.MarkSucceededCard("demo-psp-ref-1", now.AddDays(-1)); + db.Set().Add(refund); + await db.SaveChangesAsync(cancellationToken); + + ticket.RefundId = refund.Id; + db.Set().AddRange(LedgerPosting.RefundReversalPrePayout( + cancelled.Id, cancelled.NurseId, refund.PlatformFeeRefundedIrr, refund.NursePayoutRefundedIrr, + refund.Id, now.AddDays(-1))); + db.Set().AddRange(LedgerPosting.RefundPayableClearing( + cancelled.Id, refund.Amount, refund.Id, now.AddDays(-1))); + await db.SaveChangesAsync(cancellationToken); + } + + // 2) Completed BNPL booking disputed → 50% refund via bnpl_revert, still processing (the + // admin confirm_settlement action stays demoable; the ~10-business-day ETA is surfaced). + if (bookings.ByKey.TryGetValue("bnpl_settled", out var bnplBooking) + && !await db.Set().AnyAsync(r => r.BookingId == bnplBooking.Id, cancellationToken)) + { + var customer = world.Customers[1]; + var ticket = await EnsureRefundTicketAsync( + DemoLifecycleDefinitions.RefundTicketBnpl, bnplBooking.Id, customer.UserId, admin, + "اعتراض به کیفیت خدمت و درخواست استرداد", now.AddDays(-1), cancellationToken); + + var amount = bnplBooking.GrossPriceIrr / 2; + var feeLeg = (long)Math.Round(bnplBooking.BalinyaarCommissionIrr * 0.5m, MidpointRounding.AwayFromZero); + var etaBusinessDays = await platformConfig.GetConfig("bnpl_refund_eta_business_days", cancellationToken); + + var refund = new Refund + { + PaymentTransactionId = bookings.TxnByKey["bnpl_settled"].Id, + BookingId = bnplBooking.Id, + RequestedByCustomerId = customer.ProfileId, + TicketId = ticket.Id, + Amount = amount, + PlatformFeeRefundedIrr = feeLeg, + NursePayoutRefundedIrr = amount - feeLeg, + RefundPercentage = 0.5m, + RefundChannel = RefundChannel.BnplRevert, + ReasonCategory = "service_quality", + ApprovedByAdminId = admin + }; + refund.MarkProcessing("demo-revert-1", Today(now, etaBusinessDays + 4)); + db.Set().Add(refund); + await db.SaveChangesAsync(cancellationToken); + + ticket.RefundId = refund.Id; + db.Set().AddRange(LedgerPosting.RefundReversalPrePayout( + bnplBooking.Id, bnplBooking.NurseId, refund.PlatformFeeRefundedIrr, refund.NursePayoutRefundedIrr, + refund.Id, now.AddDays(-1))); + // No clearing leg yet — that posts when the admin confirms the settlement (the demoable action). + + var bnpl = await db.Set() + .FirstOrDefaultAsync(b => b.PaymentTransactionId == refund.PaymentTransactionId, cancellationToken); + bnpl?.MarkReverted("demo-revert-txn-1", amount, providerCommissionReversedAmount: null, + revertedAt: now.AddDays(-1), callbackPayloadJson: "{\"source\":\"demo-lifecycle-seed\",\"step\":\"revert\"}"); + await db.SaveChangesAsync(cancellationToken); + } + + // 3) Paid-out booking refunded afterwards → the post-payout clawback fork (IBAN transfers are + // irreversible, so the nurse's already-paid share becomes a pending receivable). + if (bookings.ByKey.TryGetValue("clawback", out var clawedBooking) + && !await db.Set().AnyAsync(r => r.BookingId == clawedBooking.Id, cancellationToken)) + { + var customer = world.Customers[0]; + var ticket = await EnsureRefundTicketAsync( + DemoLifecycleDefinitions.RefundTicketClawback, clawedBooking.Id, customer.UserId, admin, + "شکایت پس از پرداخت و درخواست استرداد", now.AddHours(-20), cancellationToken); + + var refund = new Refund + { + PaymentTransactionId = bookings.TxnByKey["clawback"].Id, + BookingId = clawedBooking.Id, + RequestedByCustomerId = customer.ProfileId, + TicketId = ticket.Id, + Amount = clawedBooking.GrossPriceIrr, + PlatformFeeRefundedIrr = clawedBooking.BalinyaarCommissionIrr, + NursePayoutRefundedIrr = clawedBooking.NursePayoutAmount, + RefundPercentage = 1.0m, + RefundChannel = RefundChannel.PspCard, + ReasonCategory = "service_quality", + ApprovedByAdminId = admin + }; + refund.MarkSucceededCard("demo-psp-ref-2", now.AddHours(-20)); + db.Set().Add(refund); + await db.SaveChangesAsync(cancellationToken); + + ticket.RefundId = refund.Id; + db.Set().AddRange(LedgerPosting.ClawbackReversalPostPayout( + clawedBooking.Id, clawedBooking.NurseId, refund.PlatformFeeRefundedIrr, refund.NursePayoutRefundedIrr, + refund.Id, now.AddHours(-20))); + db.Set().AddRange(LedgerPosting.RefundPayableClearing( + clawedBooking.Id, refund.Amount, refund.Id, now.AddHours(-20))); + + var originalPayoutId = await db.Set() + .Where(l => l.BookingId == clawedBooking.Id) + .Select(l => (long?)l.PayoutId) + .FirstOrDefaultAsync(cancellationToken); + + db.Set().Add(new NurseClawback + { + NurseId = clawedBooking.NurseId, + BookingId = clawedBooking.Id, + RefundId = refund.Id, + OriginalPayoutId = originalPayoutId, + AmountIrr = refund.NursePayoutRefundedIrr + }); + await db.SaveChangesAsync(cancellationToken); + } + } + + private async Task EnsureRefundTicketAsync( + string referenceCode, long bookingId, int customerUserId, int adminUserId, + string subject, DateTime openedAt, CancellationToken cancellationToken) + { + var existing = await db.Set() + .FirstOrDefaultAsync(t => t.ReferenceCode == referenceCode, cancellationToken); + if (existing is not null) + return existing; + + var ticket = new Ticket + { + ReferenceCode = referenceCode, + Subject = subject, + Category = TicketCategory.Refund, + BookingId = bookingId, + OpenedById = customerUserId, + Participants = + [ + new TicketParticipant { UserId = customerUserId, RoleOnTicket = TicketParticipantRole.Customer }, + new TicketParticipant { UserId = adminUserId, RoleOnTicket = TicketParticipantRole.Admin, AddedById = adminUserId } + ], + Messages = + [ + new TicketMessage + { + SenderId = customerUserId, + Body = "سلام، لطفاً وضعیت استرداد وجه این رزرو را بررسی کنید.", + SentAt = openedAt + }, + new TicketMessage + { + SenderId = adminUserId, + Body = "درخواست شما ثبت شد و در حال بررسی است. نتیجه از همین گفتگو اطلاع‌رسانی می‌شود.", + SentAt = openedAt.AddMinutes(45) + } + ] + }; + db.Set().Add(ticket); + await db.SaveChangesAsync(cancellationToken); + return ticket; + } + + // --------------------------------------------------------------------------------------------------- + // Partner center — the licensed merchant-of-record sponsor, linked to the second nurse so the MoR + // invoice resolution and the partner portal have a real subject. + // --------------------------------------------------------------------------------------------------- + + private async Task EnsurePartnerCenterAsync(PersonaWorld world, CancellationToken cancellationToken) + { + var existing = await db.Set() + .FirstOrDefaultAsync(c => c.MohEstablishmentPermitNo == DemoLifecycleDefinitions.PartnerCenterPermitNo, cancellationToken); + if (existing is not null) + return existing.Id; + + var portalUser = await userManager.GetUserByPhoneNumber(DemoLifecycleDefinitions.PartnerAdminPhone); + if (portalUser is null) + { + portalUser = new User + { + UserName = DemoLifecycleDefinitions.PartnerAdminUserName, + PhoneNumber = DemoLifecycleDefinitions.PartnerAdminPhone, + PhoneNumberConfirmed = true, + PhoneVerifiedAt = clock.UtcNow, + Name = DemoLifecycleDefinitions.PartnerAdminName, + FamilyName = DemoLifecycleDefinitions.PartnerAdminFamilyName, + Gender = "male", + IsActive = true + }; + + var createResult = await userManager.CreateUser(portalUser); + if (!createResult.Succeeded) + throw new InvalidOperationException( + $"Demo lifecycle seed failed to create the partner portal user: {string.Join("; ", createResult.Errors.Select(e => e.Description))}"); + + // The portal keys off the center's admin_user_id, not a role; the customer role only gives the + // login a sane landing screen (there is deliberately no partner role in the vocabulary). + var role = await db.Set().FirstAsync(r => r.Name == RoleNames.Customer, cancellationToken); + await userManager.AddUserToRoleAsync(portalUser, role); + } + + var center = new PartnerCenter + { + Name = DemoLifecycleDefinitions.PartnerCenterName, + LegalEntityType = "private_center", + MohEstablishmentPermitNo = DemoLifecycleDefinitions.PartnerCenterPermitNo, + EnamadCode = DemoLifecycleDefinitions.PartnerCenterEnamad, + SettlementIban = "IR120170000000555566667777", // encrypted at rest by the EF converter + IsMerchantOfRecord = true, + CommissionRate = 0.05m, + AdminUserId = portalUser.Id + }; + center.Verify(clock.UtcNow.AddDays(-30)); + db.Set().Add(center); + await db.SaveChangesAsync(cancellationToken); + + // Karimi becomes the center's sponsored nurse — his bookings' invoices resolve to the center as MoR. + world.Nurses[1].Profile.PartnerCenterId = center.Id; + await db.SaveChangesAsync(cancellationToken); + + return center.Id; + } + + // --------------------------------------------------------------------------------------------------- + // Invoices — dispatched through the real IssueInvoice (sequential number, VAT-on-commission, + // merchant-of-record resolution). Idempotent per booking on the real path. + // --------------------------------------------------------------------------------------------------- + + private async Task EnsureInvoicesAsync(BookingWorld bookings, CancellationToken cancellationToken) + { + foreach (var (key, booking) in bookings.ByKey) + { + var result = await sender.Send(new IssueInvoiceCommand(booking.Id), cancellationToken); + if (!result.IsSuccess) + logger.LogDebug("Demo lifecycle: invoice for booking scenario '{Key}' not issued (already issued or ineligible).", key); + } + } +} diff --git a/server/src/Infrastructure/Baya.Infrastructure.Persistence/Services/Seeding/DemoLifecycleSeeder.Social.cs b/server/src/Infrastructure/Baya.Infrastructure.Persistence/Services/Seeding/DemoLifecycleSeeder.Social.cs new file mode 100644 index 0000000..2c1fe0f --- /dev/null +++ b/server/src/Infrastructure/Baya.Infrastructure.Persistence/Services/Seeding/DemoLifecycleSeeder.Social.cs @@ -0,0 +1,485 @@ +#nullable enable +using Baya.Application.Features.Messaging.Commands.AutoCreateCoordinationTicket; +using Baya.Domain.Entities.Booking; +using Baya.Domain.Entities.Messaging; +using Baya.Domain.Entities.Reviews; +using Baya.Domain.Entities.SupportAlerts; +using Baya.Domain.Entities.Verification; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using OpsNotification = Baya.Domain.Entities.Notifications.Notification; + +namespace Baya.Infrastructure.Persistence.Services.Seeding; + +internal sealed partial class DemoLifecycleSeeder +{ + // --------------------------------------------------------------------------------------------------- + // Reviews — one per moderation state, plus the recomputed-from-source nurse aggregates. + // --------------------------------------------------------------------------------------------------- + + private async Task EnsureReviewsAsync( + PersonaWorld world, BookingWorld bookings, DateTime now, CancellationToken cancellationToken) + { + var mohammadi = world.Customers[0]; + var hosseini = world.Customers[1]; + var azizi = world.Nurses[0]; + var karimi = world.Nurses[1]; + var seededAny = false; + + // Published 5★ with tags — the public social proof on the paid-out booking. + if (bookings.ByKey.TryGetValue("completed_paid", out var paid) + && !await db.Set().AnyAsync(r => r.BookingId == paid.Id, cancellationToken)) + { + var review = new Review + { + BookingId = paid.Id, + CustomerProfileId = mohammadi.ProfileId, + NurseProfileId = azizi.Profile.Id, + Rating = 5, + Body = "بسیار دلسوز و حرفه‌ای. سر وقت رسید و همه‌چیز را با حوصله توضیح داد." + }; + review.Moderate(ReviewModerationStatus.Published, null, world.AdminUserId, now.AddDays(-6)); + db.Set().Add(review); + await db.SaveChangesAsync(cancellationToken); // assigns review.Id for the tag links + + var tagIds = await db.Set() + .Where(t => t.Code == ReviewTagCodes.Punctual || t.Code == ReviewTagCodes.Professional) + .Select(t => t.Id) + .ToListAsync(cancellationToken); + foreach (var tagId in tagIds) + db.Set().Add(new ReviewTagLink { ReviewId = review.Id, ReviewTagMasterId = tagId }); + seededAny = true; + } + + // Pending moderation — populates the admin moderation queue; never publicly visible. + if (bookings.ByKey.TryGetValue("completed_in_window", out var inWindow) + && !await db.Set().AnyAsync(r => r.BookingId == inWindow.Id, cancellationToken)) + { + db.Set().Add(new Review + { + BookingId = inWindow.Id, + CustomerProfileId = mohammadi.ProfileId, + NurseProfileId = azizi.Profile.Id, + Rating = 4, + Body = "مراقبت خوب بود، فقط کمی دیر رسیدند." + }); + seededAny = true; + } + + // Hidden 1★ — moderated away; excluded from the public list and the aggregate, feeds the + // low-rating support alert. + if (bookings.ByKey.TryGetValue("completed_eligible", out var eligible) + && !await db.Set().AnyAsync(r => r.BookingId == eligible.Id, cancellationToken)) + { + var review = new Review + { + BookingId = eligible.Id, + CustomerProfileId = hosseini.ProfileId, + NurseProfileId = karimi.Profile.Id, + Rating = 1, + Body = "اصلاً راضی نبودم." + }; + review.Moderate(ReviewModerationStatus.Hidden, "irrelevant_content", world.AdminUserId, now.AddDays(-4)); + db.Set().Add(review); + seededAny = true; + } + + if (seededAny) + await db.SaveChangesAsync(cancellationToken); + + // Aggregates recomputed from source, mirroring RecomputeNurseRating's published-only rule and the + // completed-bookings count — never free-entered numbers. + foreach (var nurse in new[] { azizi, karimi }) + { + var published = await db.Set() + .Where(r => r.NurseProfileId == nurse.Profile.Id && r.ModerationStatus == ReviewModerationStatus.Published) + .GroupBy(_ => 1) + .Select(g => new { Count = g.Count(), Sum = g.Sum(r => r.Rating) }) + .FirstOrDefaultAsync(cancellationToken); + nurse.Profile.SetReviewAggregates( + published is null ? 0m : Math.Round((decimal)published.Sum / published.Count, 2, MidpointRounding.AwayFromZero), + published?.Count ?? 0); + + var completed = await db.Set() + .CountAsync(b => b.NurseId == nurse.Profile.Id && b.Status == BookingStatus.Completed, cancellationToken); + nurse.Profile.SetCompletedBookings(completed); + } + await db.SaveChangesAsync(cancellationToken); + + await EnsureSupportAlertsAsync(bookings, cancellationToken); + } + + /// The staff worklist rows real usage would have raised: the low rating, the out-of-tolerance + /// EVV check-in, the clawback receivable, and the logged emergency. + private async Task EnsureSupportAlertsAsync(BookingWorld bookings, CancellationToken cancellationToken) + { + var seededAny = false; + + async Task EnsureAlertAsync(string type, string severity, string entityType, long entityId, long? bookingId, long? reviewId) + { + if (await db.Set().AnyAsync(a => a.Type == type && a.BookingId == bookingId, cancellationToken)) + return; + db.Set().Add(new SupportAlert + { + Type = type, + Severity = severity, + EntityType = entityType, + EntityId = entityId.ToString(), + BookingId = bookingId, + ReviewId = reviewId + }); + seededAny = true; + } + + if (bookings.ByKey.TryGetValue("completed_eligible", out var eligible)) + { + var review = await db.Set() + .Where(r => r.BookingId == eligible.Id) + .Select(r => (long?)r.Id) + .FirstOrDefaultAsync(cancellationToken); + if (review is { } reviewId) + await EnsureAlertAsync(SupportAlertType.LowRating, SupportAlertSeverity.Medium, "review", reviewId, eligible.Id, reviewId); + await EnsureAlertAsync(SupportAlertType.EvvLocationMismatch, SupportAlertSeverity.Medium, "booking", eligible.Id, eligible.Id, null); + } + + if (bookings.ByKey.TryGetValue("clawback", out var clawed)) + await EnsureAlertAsync(SupportAlertType.NurseClawback, SupportAlertSeverity.High, "booking", clawed.Id, clawed.Id, null); + + if (bookings.ByKey.TryGetValue("in_progress", out var inProgress)) + await EnsureAlertAsync(SupportAlertType.Emergency, SupportAlertSeverity.High, "booking", inProgress.Id, inProgress.Id, null); + + if (seededAny) + await db.SaveChangesAsync(cancellationToken); + } + + // --------------------------------------------------------------------------------------------------- + // Tickets — coordination via the real command; support/emergency threads hand-built (fixed reference + // codes double as the idempotency guards). The internal admin note proves the is_internal boundary. + // --------------------------------------------------------------------------------------------------- + + private async Task EnsureTicketsAsync( + PersonaWorld world, BookingWorld bookings, DateTime now, CancellationToken cancellationToken) + { + foreach (var (key, booking) in bookings.ByKey) + { + var result = await sender.Send(new AutoCreateCoordinationTicketCommand(booking.Id), cancellationToken); + if (!result.IsSuccess) + logger.LogDebug("Demo lifecycle: coordination ticket for '{Key}' not created.", key); + } + + var mohammadi = world.Customers[0]; + var hosseini = world.Customers[1]; + var admin = world.AdminUserId; + + // Open support thread with an is_internal admin note the user views must never surface. + if (!await db.Set().AnyAsync(t => t.ReferenceCode == DemoLifecycleDefinitions.SupportTicketOpen, cancellationToken)) + { + var openedAt = clock.UtcNow.AddDays(-2); + db.Set().Add(new Ticket + { + ReferenceCode = DemoLifecycleDefinitions.SupportTicketOpen, + Subject = "فاکتور رزرو نمایش داده نمی‌شود", + Category = TicketCategory.Support, + OpenedById = mohammadi.UserId, + Participants = + [ + new TicketParticipant { UserId = mohammadi.UserId, RoleOnTicket = TicketParticipantRole.Customer }, + new TicketParticipant { UserId = admin, RoleOnTicket = TicketParticipantRole.Admin, AddedById = admin } + ], + Messages = + [ + new TicketMessage + { + SenderId = mohammadi.UserId, + Body = "سلام، فاکتور رزرو اخیرم در بخش کیف پول باز نمی‌شود.", + SentAt = openedAt + }, + new TicketMessage + { + SenderId = admin, + IsInternal = true, + Body = "یادداشت داخلی: مشکل از سمت صدور فاکتور بود؛ صف مودیان بررسی شود.", + SentAt = openedAt.AddHours(1) + }, + new TicketMessage + { + SenderId = admin, + Body = "سلام! مشکل بررسی شد و فاکتور شما اکنون قابل مشاهده است. ممنون از صبوری‌تان.", + SentAt = openedAt.AddHours(2) + }, + new TicketMessage + { + SenderId = mohammadi.UserId, + Body = "ممنون، حل شد. 🌸", + SentAt = openedAt.AddDays(1) + } + ] + }); + await db.SaveChangesAsync(cancellationToken); + } + + // Closed support thread — the inbox's closed filter and the admin close/reopen actions. + if (!await db.Set().AnyAsync(t => t.ReferenceCode == DemoLifecycleDefinitions.SupportTicketClosed, cancellationToken)) + { + var openedAt = clock.UtcNow.AddDays(-5); + var ticket = new Ticket + { + ReferenceCode = DemoLifecycleDefinitions.SupportTicketClosed, + Subject = "سوال درباره نحوه تغییر شماره تماس", + Category = TicketCategory.Support, + OpenedById = hosseini.UserId, + Participants = + [ + new TicketParticipant { UserId = hosseini.UserId, RoleOnTicket = TicketParticipantRole.Customer }, + new TicketParticipant { UserId = admin, RoleOnTicket = TicketParticipantRole.Admin, AddedById = admin } + ], + Messages = + [ + new TicketMessage + { + SenderId = hosseini.UserId, + Body = "چطور می‌توانم شماره موبایل حسابم را عوض کنم؟", + SentAt = openedAt + }, + new TicketMessage + { + SenderId = admin, + Body = "در حال حاضر تغییر شماره از طریق پشتیبانی انجام می‌شود؛ مدارک هویتی لازم است.", + SentAt = openedAt.AddHours(3) + } + ] + }; + ticket.Close(admin, clock.UtcNow.AddDays(-3)); + db.Set().Add(ticket); + await db.SaveChangesAsync(cancellationToken); + } + + // Emergency aftermath thread (logged by the nurse mid-visit) — the admin queue's red row. + if (bookings.ByKey.TryGetValue("in_progress", out var inProgress) + && !await db.Set().AnyAsync(t => t.ReferenceCode == DemoLifecycleDefinitions.EmergencyTicket, cancellationToken)) + { + var azizi = world.Nurses[0]; + db.Set().Add(new Ticket + { + ReferenceCode = DemoLifecycleDefinitions.EmergencyTicket, + Subject = "گزارش تماس اضطراری حین ویزیت", + Category = TicketCategory.Emergency, + BookingId = inProgress.Id, + OpenedById = azizi.UserId, + Participants = + [ + new TicketParticipant { UserId = azizi.UserId, RoleOnTicket = TicketParticipantRole.Nurse }, + new TicketParticipant { UserId = admin, RoleOnTicket = TicketParticipantRole.Admin, AddedById = admin } + ], + Messages = + [ + new TicketMessage + { + SenderId = azizi.UserId, + Body = "حین ویزیت افت فشار ناگهانی داشتیم؛ با اورژانس تماس گرفتم و وضعیت پایدار شد. خانواده در جریان است.", + SentAt = clock.UtcNow.AddHours(-1) + } + ] + }); + await db.SaveChangesAsync(cancellationToken); + } + } + + // --------------------------------------------------------------------------------------------------- + // Patient care records — the encrypted, patient-scoped longitudinal history (handler-side encryption + // by design: no EF converter on body_encrypted). + // --------------------------------------------------------------------------------------------------- + + private async Task EnsureCareRecordsAsync( + PersonaWorld world, BookingWorld bookings, DateTime now, CancellationToken cancellationToken) + { + var seededAny = false; + + async Task EnsureRecordAsync(long patientId, long? bookingId, long nurseProfileId, string body, string? tasksJson, DateTime recordedAt) + { + if (await db.Set().AnyAsync( + r => r.PatientId == patientId && r.BookingId == bookingId, cancellationToken)) + return; + db.Set().Add(new PatientCareRecord + { + PatientId = patientId, + BookingId = bookingId, + NurseProfileId = nurseProfileId, + BodyEncrypted = encryptor.Encrypt(body), + TaskResultsJson = tasksJson, + RecordedAt = recordedAt + }); + seededAny = true; + } + + var aziziProfileId = world.Nurses[0].Profile.Id; + var karimiProfileId = world.Nurses[1].Profile.Id; + var patientHasan = world.Customers[0].PatientIds[0]; + var patientAmirali = world.Customers[1].PatientIds[0]; + + if (bookings.ByKey.TryGetValue("completed_paid", out var paid)) + await EnsureRecordAsync( + patientHasan, paid.Id, aziziProfileId, + "علائم حیاتی پایدار. قند خون ناشتا ۱۱۰. داروها طبق برنامه مصرف شد؛ اشتها خوب بود.", + "[{\"label\":\"کنترل قند خون\",\"done\":true},{\"label\":\"دادن داروهای صبح\",\"done\":true}]", + now.AddDays(-10).AddHours(4)); + + if (bookings.ByKey.TryGetValue("completed_in_window", out var inWindow)) + await EnsureRecordAsync( + patientHasan, inWindow.Id, aziziProfileId, + "فشار خون ۱۴ روی ۹. کمی بی‌قراری عصر داشتند که با پیاده‌روی کوتاه بهتر شد. زخم پا رو به بهبود است.", + "[{\"label\":\"پانسمان زخم پا\",\"done\":true},{\"label\":\"کنترل فشار خون\",\"done\":true},{\"label\":\"پیاده‌روی عصر\",\"done\":false}]", + now.AddDays(-1).AddHours(4)); + + if (bookings.ByKey.TryGetValue("bnpl_settled", out var bnplBooking)) + await EnsureRecordAsync( + patientAmirali, bnplBooking.Id, karimiProfileId, + "وضعیت عمومی نوزاد خوب. تغذیه منظم انجام شد و دمای بدن طبیعی بود.", + "[{\"label\":\"پایش دمای بدن\",\"done\":true}]", + now.AddDays(-6).AddHours(3)); + + if (seededAny) + await db.SaveChangesAsync(cancellationToken); + } + + // --------------------------------------------------------------------------------------------------- + // Mid-pipeline verification for the unverified nurse — feeds the nurse journey (B3–B6) and the admin + // verification queue. is_verified is deliberately never touched (status != approved). + // --------------------------------------------------------------------------------------------------- + + private async Task EnsureVerificationPipelineAsync(PersonaWorld world, DateTime now, CancellationToken cancellationToken) + { + var ahmadi = world.Nurses[2]; + var verification = await db.Set() + .FirstOrDefaultAsync(v => v.NurseId == ahmadi.Profile.Id, cancellationToken); + if (verification is null) + return; + if (await db.Set().AnyAsync(s => s.NurseVerificationId == verification.Id, cancellationToken)) + return; + + verification.Status = VerificationStatus.InReview; + verification.SubmittedAt = clock.UtcNow.AddDays(-3); + + var stepTypes = await db.Set() + .Where(t => t.IsActive) + .ToDictionaryAsync(t => t.Code, cancellationToken); + + VerificationStep AddStep(string code, VerificationStepStatus status, bool automated, string? responseJson) + { + var step = new VerificationStep + { + NurseVerificationId = verification.Id, + StepTypeId = stepTypes[code].Id, + Status = status, + IsAutomated = automated, + ExternalResponseJson = responseJson, + StartedAt = clock.UtcNow.AddDays(-3), + CompletedAt = status is VerificationStepStatus.Passed ? clock.UtcNow.AddDays(-3).AddMinutes(5) : null + }; + db.Set().Add(step); + return step; + } + + AddStep(VerificationStepTypeCodes.IdentityKyc, VerificationStepStatus.Passed, automated: true, + "{\"source\":\"demo-lifecycle-seed\",\"match\":true,\"confidence\":0.97}"); + AddStep(VerificationStepTypeCodes.ShahkarMatch, VerificationStepStatus.Passed, automated: true, + "{\"source\":\"demo-lifecycle-seed\",\"simOwnerMatch\":true}"); + var licenseStep = AddStep(VerificationStepTypeCodes.MohCompetencyLicense, VerificationStepStatus.InReview, automated: false, null); + AddStep(VerificationStepTypeCodes.CriminalRecord, VerificationStepStatus.Pending, automated: false, null); + await db.SaveChangesAsync(cancellationToken); // assigns step ids for the document FK + + // The uploaded evidence file's metadata. The object-storage bytes deliberately don't exist — the + // admin viewer's signed-URL fetch will 404, which is acceptable for a dev DB (never fake bytes). + db.Set().Add(new VerificationDocument + { + StepId = licenseStep.Id, + ObjectStorageKey = "verification/demo/ahmadi-moh-license.jpg", + IntegrityHash = "demo-integrity-hash", + ContentType = "image/jpeg", + FileSizeBytes = 245_000, + OriginalFileName = "moh-license.jpg", + UploadedByUserId = ahmadi.UserId + }); + await db.SaveChangesAsync(cancellationToken); + } + + // --------------------------------------------------------------------------------------------------- + // Notifications — direct ops rows with backdated CreatedAt, copying the REAL handlers' type/DataJson + // contract so the front-end deep-links resolve. (The real emitters write English copy; mirrored as-is.) + // --------------------------------------------------------------------------------------------------- + + private async Task EnsureNotificationsAsync( + PersonaWorld world, BookingWorld bookings, DateTime now, CancellationToken cancellationToken) + { + var azizi = world.Nurses[0]; + var karimi = world.Nurses[1]; + var mohammadi = world.Customers[0]; + + if (await db.Set().AnyAsync( + n => n.UserId == azizi.UserId && n.Type == "booking_request_received", cancellationToken)) + return; + + var pendingRequestId = await db.Set() + .Where(r => r.Status == BookingRequestStatus.PendingNurseResponse && r.NurseId == azizi.Profile.Id) + .Select(r => (long?)r.Id) + .FirstOrDefaultAsync(cancellationToken); + var acceptedRequest = await db.Set() + .Where(r => r.Status == BookingRequestStatus.AcceptedAwaitingPayment && r.CustomerId == mohammadi.ProfileId) + .Select(r => new { r.Id, r.PaymentDeadlineAt }) + .FirstOrDefaultAsync(cancellationToken); + var expiredRequestId = await db.Set() + .Where(r => r.Status == BookingRequestStatus.ExpiredNoResponse && r.NurseId == karimi.Profile.Id) + .Select(r => (long?)r.Id) + .FirstOrDefaultAsync(cancellationToken); + var publishedReviewId = bookings.ByKey.TryGetValue("completed_paid", out var paid) + ? await db.Set().Where(r => r.BookingId == paid.Id).Select(r => (long?)r.Id).FirstOrDefaultAsync(cancellationToken) + : null; + var upcomingId = bookings.ByKey.TryGetValue("upcoming", out var upcoming) ? upcoming.Id : (long?)null; + + void Add(int userId, string type, string title, string body, string dataJson, DateTime createdAt, bool read) + => db.Set().Add(new OpsNotification + { + UserId = userId, + Type = type, + Title = title, + Body = body, + DataJson = dataJson, + IsRead = read, + ReadAt = read ? new DateTimeOffset(createdAt.AddMinutes(30), TimeSpan.Zero) : null, + CreatedAt = new DateTimeOffset(createdAt, TimeSpan.Zero) + }); + + if (pendingRequestId is { } pendingId) + Add(azizi.UserId, "booking_request_received", "New booking request", + "You have a new booking request awaiting your response.", + $"{{\"booking_request_id\":{pendingId}}}", now.AddHours(-2), read: false); + + if (upcomingId is { } bookingId) + { + Add(mohammadi.UserId, "booking_confirmed", "Booking confirmed", + "Your payment was captured and your booking is confirmed.", + $"{{\"booking_id\":{bookingId}}}", now.AddDays(-1), read: true); + Add(azizi.UserId, "booking_confirmed_nurse", "New confirmed booking", + "A booking has been confirmed and paid. The care instructions and schedule are now available.", + $"{{\"booking_id\":{bookingId}}}", now.AddDays(-1), read: true); + } + + if (acceptedRequest is not null) + Add(mohammadi.UserId, "booking_request_accepted", "Booking request accepted", + "The nurse accepted your request. Pay within the payment window to confirm your booking.", + $"{{\"booking_request_id\":{acceptedRequest.Id},\"payment_deadline_at\":\"{acceptedRequest.PaymentDeadlineAt:O}\"}}", + now.AddHours(-1), read: false); + + if (publishedReviewId is { } reviewId) + Add(mohammadi.UserId, "review_moderated", "Your review was updated", + "Your review is now published.", + $"{{\"reviewId\":{reviewId},\"status\":\"published\"}}", now.AddDays(-6), read: true); + + if (expiredRequestId is { } expiredId) + Add(karimi.UserId, "booking_request_received", "New booking request", + "You have a new booking request awaiting your response.", + $"{{\"booking_request_id\":{expiredId}}}", now.AddDays(-3), read: true); + + await db.SaveChangesAsync(cancellationToken); + } +} diff --git a/server/src/Infrastructure/Baya.Infrastructure.Persistence/Services/Seeding/DemoLifecycleSeeder.cs b/server/src/Infrastructure/Baya.Infrastructure.Persistence/Services/Seeding/DemoLifecycleSeeder.cs new file mode 100644 index 0000000..c25343f --- /dev/null +++ b/server/src/Infrastructure/Baya.Infrastructure.Persistence/Services/Seeding/DemoLifecycleSeeder.cs @@ -0,0 +1,661 @@ +#nullable enable +using Baya.Application.Common; +using Baya.Application.Contracts.Common; +using Baya.Application.Contracts.Configuration; +using Baya.Application.Contracts.Identity; +using Baya.Application.Contracts.Search; +using Baya.Application.Features.Bookings; +using Baya.Application.Models.Booking; +using Baya.Application.Models.Catalog; +using Baya.Domain.Entities.Booking; +using Baya.Domain.Entities.Catalog; +using Baya.Domain.Entities.Geography; +using Baya.Domain.Entities.Identity; +using Baya.Domain.Entities.Payments; +using Mediator; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using BookingEntity = Baya.Domain.Entities.Booking.Booking; + +namespace Baya.Infrastructure.Persistence.Services.Seeding; + +/// +/// Development-only seeder that layers a full lifecycle demo world on top of the +/// personas: booking requests in every status, bookings in every reachable +/// state (upcoming, mid-engagement with EVV, completed inside/past the dispute window, BNPL-settled, +/// cancelled-with-refund, clawed-back), the balanced payment ledger behind each, refunds on every channel, +/// a paid and a draft payout batch, moderated reviews, tickets (including an admin-internal note), +/// notifications, patient care records, a partner center, and a mid-pipeline verification case. +/// +/// Every state is reached through the entities' guarded transition methods and the real money +/// helpers (, ), never by raw status assignment, so +/// the seeded world satisfies the same invariants real usage produces. Payout batches and coordination +/// tickets are produced by dispatching the real Application commands. Timestamps that carry business +/// meaning are backdated explicitly (they are method arguments/settable by design); CreatedAt audit +/// stamps stay at seed time, which no flow depends on. +/// +/// +/// Idempotent per scenario: each aggregate is guarded on a natural key (the request's +/// customer/nurse/variant/date tuple, a ticket's fixed reference code, the partner permit number…), so +/// re-running on an already-seeded DB is a no-op. Callers must gate this on IsDevelopment() and run +/// it after and the payment-gateway seed. +/// +/// +internal sealed partial class DemoLifecycleSeeder( + ApplicationDbContext db, + IAppUserManager userManager, + ISender sender, + IPlatformConfig platformConfig, + IVariantSnapshotSerializer variantSerializer, + ISearchIndexMaintainer searchIndex, + IFieldEncryptor encryptor, + IDateTimeProvider clock, + ILogger logger) +{ + public async Task SeedAsync(CancellationToken cancellationToken) + { + var world = await LoadWorldAsync(cancellationToken); + if (world is null) + { + logger.LogWarning("Demo lifecycle seed skipped — the base demo world (personas/variants) is not present."); + return; + } + + var gateway = await db.Set() + .FirstOrDefaultAsync(g => g.Type == PaymentGatewayType.Standard, cancellationToken); + if (gateway is null) + { + logger.LogWarning("Demo lifecycle seed skipped — no standard payment gateway row (run SeedPaymentGatewaysAsync first)."); + return; + } + + var now = clock.UtcNow.UtcDateTime; + + var packageVariantId = await EnsurePackageVariantAsync(world, cancellationToken); + var newRequests = await EnsureRequestScenariosAsync(world, now, cancellationToken); + var bookings = await EnsureBookingScenariosAsync(world, packageVariantId, gateway.Id, now, cancellationToken); + + var centerId = await EnsurePartnerCenterAsync(world, cancellationToken); + await EnsureBnplAsync(bookings, now, cancellationToken); + + // Order is load-bearing (the world must be *reachable*, not merely constraint-satisfying): + // the paid batch runs BEFORE the refunds exist (so the clawback booking was genuinely paid out first), + // and the draft batch runs AFTER them (so the BNPL-refunded booking is genuinely excluded). + await EnsurePaidPayoutBatchAsync(bookings, now, cancellationToken); + await EnsureRefundsAsync(world, bookings, now, cancellationToken); + await EnsureDraftPayoutBatchAsync(bookings, now, cancellationToken); + + await EnsureReviewsAsync(world, bookings, now, cancellationToken); + await EnsureInvoicesAsync(bookings, cancellationToken); + await EnsureTicketsAsync(world, bookings, now, cancellationToken); + await EnsureCareRecordsAsync(world, bookings, now, cancellationToken); + await EnsureVerificationPipelineAsync(world, now, cancellationToken); + await EnsureNotificationsAsync(world, bookings, now, cancellationToken); + + // Re-derive the search projection last so the seeded rating/completed aggregates reach the index. + var rebuild = await searchIndex.RebuildAsync(cancellationToken); + + if (newRequests == 0 && bookings.CreatedCount == 0) + logger.LogInformation( + "Demo lifecycle already seeded — no-op. Search index re-derived: {Nurses} nurses, {Rows} rows.", + rebuild.NursesProcessed, rebuild.RowsWritten); + else + logger.LogInformation( + "Demo lifecycle seeded: {Requests} request scenario(s), {Bookings} booking scenario(s), partner center #{Center}. " + + "Search index: {Nurses} nurses, {Rows} rows.", + newRequests, bookings.CreatedCount, centerId, rebuild.NursesProcessed, rebuild.RowsWritten); + } + + // --------------------------------------------------------------------------------------------------- + // World loading — resolve the base-seeder personas into ids. Null when the base world isn't there. + // --------------------------------------------------------------------------------------------------- + + internal sealed record CustomerWorld( + int UserId, long ProfileId, IReadOnlyList PatientIds, CustomerAddress PrimaryAddress); + + internal sealed record NurseWorld( + int UserId, NurseProfile Profile, IReadOnlyList Variants, string Gender); + + internal sealed record PersonaWorld( + IReadOnlyList Customers, IReadOnlyList Nurses, int AdminUserId); + + private async Task LoadWorldAsync(CancellationToken cancellationToken) + { + var customers = new List(); + foreach (var persona in DemoWorldDefinitions.Customers) + { + var user = await userManager.GetUserByPhoneNumber(persona.Phone); + if (user is null) + return null; + + var profile = await db.Set() + .FirstOrDefaultAsync(p => p.UserId == user.Id, cancellationToken); + if (profile is null) + return null; + + var patients = await db.Set() + .Where(p => p.CustomerId == profile.Id) + .OrderBy(p => p.Id) + .Select(p => p.Id) + .ToListAsync(cancellationToken); + + var address = await db.Set() + .FirstOrDefaultAsync(a => a.CustomerId == profile.Id && a.IsPrimary, cancellationToken); + if (patients.Count == 0 || address is null) + return null; + + customers.Add(new CustomerWorld(user.Id, profile.Id, patients, address)); + } + + var nurses = new List(); + foreach (var persona in DemoWorldDefinitions.Nurses) + { + var user = await userManager.GetUserByPhoneNumber(persona.Phone); + if (user is null) + return null; + + // Tracked on purpose: the reviews step mutates the aggregates through the guarded setters. + var profile = await db.Set() + .FirstOrDefaultAsync(p => p.UserId == user.Id, cancellationToken); + if (profile is null) + return null; + + var variants = await db.Set() + .Include(v => v.Options) + .Where(v => v.NurseId == profile.Id) + .OrderBy(v => v.Id) + .ToListAsync(cancellationToken); + + nurses.Add(new NurseWorld(user.Id, profile, variants, persona.Gender)); + } + + var admin = await userManager.GetUserByPhoneNumber(DemoWorldDefinitions.Admins[0].Phone); + if (admin is null) + return null; + + return new PersonaWorld(customers, nurses, admin.Id); + } + + // --------------------------------------------------------------------------------------------------- + // The 5-session package variant (the multi-session engagement source). + // --------------------------------------------------------------------------------------------------- + + private async Task EnsurePackageVariantAsync(PersonaWorld world, CancellationToken cancellationToken) + { + var azizi = world.Nurses[0]; + + var shiftGroup = await db.Set() + .Include(g => g.Values) + .FirstAsync(g => g.ServiceCategoryId == null && g.NameEn == DemoWorldDefinitions.ShiftGroupNameEn, cancellationToken); + var nightValueId = shiftGroup.Values.First(v => v.NameEn == DemoWorldDefinitions.ShiftNight).Id; + + // Guarded on the duplicate-listing UNIQUE (nurse × category × option-set hash), not the display + // name: the DbContext save hook normalizes Persian digits/ZWNJ in every stored string, so a Persian + // literal never round-trips equal to what was persisted. + var optionSetHash = OptionSetHash.Compute([(shiftGroup.Id, nightValueId)]); + var existing = await db.Set() + .Where(v => v.NurseId == azizi.Profile.Id + && v.ServiceCategoryId == DemoWorldDefinitions.PostSurgery + && v.OptionSetHash == optionSetHash) + .Select(v => v.Id) + .FirstOrDefaultAsync(cancellationToken); + if (existing != 0) + return existing; + + var variant = new NurseServiceVariant + { + NurseId = azizi.Profile.Id, + ServiceCategoryId = DemoWorldDefinitions.PostSurgery, + Price = DemoLifecycleDefinitions.PackageVariantPricePerSession, + PriceUnit = PriceUnits.PerSession, + SessionCount = DemoLifecycleDefinitions.PackageVariantSessionCount, + DisplayName = DemoLifecycleDefinitions.PackageVariantDisplayName, + OptionSetHash = optionSetHash, + IsActive = true, + Options = new List + { + new() { OptionGroupId = shiftGroup.Id, OptionValueId = nightValueId } + } + }; + + db.Set().Add(variant); + await db.SaveChangesAsync(cancellationToken); + return variant.Id; + } + + // --------------------------------------------------------------------------------------------------- + // Request-only scenarios: pending / accepted-awaiting-payment / rejected / expired / cancelled. + // --------------------------------------------------------------------------------------------------- + + private async Task EnsureRequestScenariosAsync(PersonaWorld world, DateTime now, CancellationToken cancellationToken) + { + var mohammadi = world.Customers[0]; + var hosseini = world.Customers[1]; + var azizi = world.Nurses[0]; + var karimi = world.Nurses[1]; + + var created = 0; + + // Pending: the nurse inbox's live countdown + the customer's C5 tracker. Deadline must be in the + // future or the 1-minute booking_request_expiry job sweeps it before anyone can look at it. + created += await EnsureRequestAsync( + mohammadi, azizi, azizi.Variants[1].Id, mohammadi.PatientIds[0], + requestedDate: Today(now, 5), timeStart: new TimeOnly(9, 0), timeEnd: new TimeOnly(13, 0), + notes: "پدرم به کمک برای جابه‌جایی و مصرف دارو نیاز دارد.", + deadline: now.AddHours(24), configure: null, cancellationToken); + + // Accepted, awaiting payment: the checkout entry point. The real handler computes a 30-minute + // window; the demo freezes 24h so the scenario survives longer than half an hour of testing. + created += await EnsureRequestAsync( + mohammadi, azizi, azizi.Variants[0].Id, mohammadi.PatientIds[0], + requestedDate: Today(now, 7), timeStart: new TimeOnly(8, 0), timeEnd: new TimeOnly(8, 0), + notes: "مراقبت شبانه‌روزی برای دوران نقاهت.", + deadline: now.AddHours(24), + configure: r => r.Accept(paymentDeadlineAt: now.AddHours(24)), cancellationToken); + + // Rejected with a schedule-conflict reason (the C5 re-request off-ramp keys off this wording). + created += await EnsureRequestAsync( + mohammadi, azizi, azizi.Variants[2].Id, mohammadi.PatientIds[1], + requestedDate: Today(now, 1), timeStart: new TimeOnly(10, 0), timeEnd: new TimeOnly(18, 0), + notes: "مراقبت روزانه بعد از عمل زانو.", + deadline: now.AddHours(24), + configure: r => r.Reject("زمان درخواستی با برنامه من تداخل دارد."), cancellationToken); + + // Expired: no nurse response before the (backdated) deadline. + created += await EnsureRequestAsync( + hosseini, karimi, karimi.Variants[0].Id, hosseini.PatientIds[0], + requestedDate: Today(now, 1), timeStart: new TimeOnly(9, 0), timeEnd: new TimeOnly(17, 0), + notes: "مراقبت روزانه در منزل.", + deadline: now.AddDays(-2), + configure: r => r.ExpireNoResponse(), cancellationToken); + + // Cancelled by the customer before any response. + created += await EnsureRequestAsync( + hosseini, karimi, karimi.Variants[1].Id, hosseini.PatientIds[0], + requestedDate: Today(now, 4), timeStart: new TimeOnly(8, 0), timeEnd: new TimeOnly(8, 0), + notes: "لطفاً نادیده بگیرید — برنامه تغییر کرد.", + deadline: now.AddHours(24), + configure: r => r.CancelByCustomer(), cancellationToken); + + return created; + } + + private async Task EnsureRequestAsync( + CustomerWorld customer, + NurseWorld nurse, + long variantId, + long patientId, + DateOnly requestedDate, + TimeOnly timeStart, + TimeOnly timeEnd, + string notes, + DateTime deadline, + Action? configure, + CancellationToken cancellationToken) + { + if (await RequestExistsAsync(customer.ProfileId, nurse.Profile.Id, variantId, requestedDate, cancellationToken)) + return 0; + + var request = new BookingRequest + { + CustomerId = customer.ProfileId, + NurseId = nurse.Profile.Id, + PatientId = patientId, + VariantId = variantId, + CustomerAddressId = customer.PrimaryAddress.Id, + RequiredCaregiverGender = nurse.Gender, + RequestedDate = requestedDate, + RequestedTimeStart = timeStart, + RequestedTimeEnd = timeEnd, + CustomerNotes = notes, + NurseResponseDeadlineAt = deadline + }; + configure?.Invoke(request); + + db.Set().Add(request); + await db.SaveChangesAsync(cancellationToken); + return 1; + } + + private Task RequestExistsAsync( + long customerId, long nurseId, long variantId, DateOnly requestedDate, CancellationToken cancellationToken) + => db.Set().AnyAsync( + r => r.CustomerId == customerId && r.NurseId == nurseId + && r.VariantId == variantId && r.RequestedDate == requestedDate, + cancellationToken); + + // --------------------------------------------------------------------------------------------------- + // Booking scenarios — request → (real factory) booking → sessions/EVV → payment txn → balanced ledger. + // --------------------------------------------------------------------------------------------------- + + /// The seeded (or found) bookings by scenario key, plus how many were newly created. + internal sealed class BookingWorld + { + public Dictionary ByKey { get; } = []; + public Dictionary TxnByKey { get; } = []; + public int CreatedCount { get; set; } + } + + private async Task EnsureBookingScenariosAsync( + PersonaWorld world, long packageVariantId, long gatewayId, DateTime now, CancellationToken cancellationToken) + { + var result = new BookingWorld(); + var sequence = 0; + + foreach (var scenario in DemoLifecycleDefinitions.Bookings) + { + sequence++; + var customer = world.Customers[scenario.Customer]; + var nurse = world.Nurses[scenario.Nurse]; + var variant = scenario.VariantIndex >= 0 + ? nurse.Variants[scenario.VariantIndex] + : await db.Set().Include(v => v.Options) + .FirstAsync(v => v.Id == packageVariantId, cancellationToken); + + var requestedDate = Today(now, scenario.ScheduledInDays); + + var existing = await db.Set() + .Where(r => r.CustomerId == customer.ProfileId && r.NurseId == nurse.Profile.Id + && r.VariantId == variant.Id && r.RequestedDate == requestedDate) + .Select(r => r.Id) + .FirstOrDefaultAsync(cancellationToken); + if (existing != 0) + { + var found = await db.Set().Include(b => b.Sessions) + .FirstAsync(b => b.BookingRequestId == existing, cancellationToken); + var foundTxn = await db.Set() + .FirstAsync(t => t.BookingId == found.Id && t.Status == PaymentTransactionStatus.Succeeded, cancellationToken); + result.ByKey[scenario.Key] = found; + result.TxnByKey[scenario.Key] = foundTxn; + continue; + } + + var confirmedAt = now.AddDays(-scenario.ConfirmedDaysAgo); + + var request = new BookingRequest + { + CustomerId = customer.ProfileId, + NurseId = nurse.Profile.Id, + PatientId = customer.PatientIds[0], + VariantId = variant.Id, + CustomerAddressId = customer.PrimaryAddress.Id, + RequiredCaregiverGender = nurse.Gender, + RequestedDate = requestedDate, + RequestedTimeStart = new TimeOnly(9, 0), + RequestedTimeEnd = new TimeOnly(13, 0), + CustomerNotes = "هماهنگی از طریق پیام انجام شد.", + NurseResponseDeadlineAt = confirmedAt + }; + request.Accept(paymentDeadlineAt: confirmedAt); + db.Set().Add(request); + await db.SaveChangesAsync(cancellationToken); // assigns request.Id for the 1:1 booking FK + + var booking = BookingFactory.Create( + await BuildConversionSourceAsync(request, customer, nurse, variant, cancellationToken), + rate: await GetFeeRateAsync(cancellationToken), + now: confirmedAt, + pspFeeAmount: null, + variantSerializer); + request.MarkConverted(); + + ApplyLifecycleState(booking, scenario, now); + db.Set().Add(booking); + await db.SaveChangesAsync(cancellationToken); // assigns booking/session ids for EVV + ledger refs + + SeedVisitVerifications(booking, scenario, customer.PrimaryAddress, now); + + if (scenario.WithCareInstructions) + db.Set().Add(BuildCareInstructions(booking.Id)); + + // The txn commits first so the ledger legs can reference its real id (append-only source refs). + var txn = BuildSucceededTransaction(booking, request, customer.ProfileId, gatewayId, scenario, sequence); + db.Set().Add(txn); + await db.SaveChangesAsync(cancellationToken); + + // Card bookings post the balanced capture group now; the BNPL booking posts BnplSettle in the + // money step (its group references the bnpl_transactions row, which doesn't exist yet). + if (scenario.Key != "bnpl_settled") + { + db.Set().AddRange(LedgerPosting.CardCapture( + booking.Id, booking.NurseId, booking.GrossPriceIrr, booking.BalinyaarCommissionIrr, + booking.NursePayoutAmount, txn.Id, createdAt: confirmedAt)); + await db.SaveChangesAsync(cancellationToken); + } + + result.ByKey[scenario.Key] = booking; + result.TxnByKey[scenario.Key] = txn; + result.CreatedCount++; + } + + // One deliberately-failed extra payment attempt so the wallet's payment history has a failed row. + await EnsureFailedAttemptAsync(world, gatewayId, cancellationToken); + + return result; + } + + /// Walks the booking + its sessions along the real transition edges for the scenario. + private static void ApplyLifecycleState(BookingEntity booking, BookingScenario scenario, DateTime now) + { + if (scenario.Cancelled) + { + // ≥ 24h before start → the standard_24h tier, 100% refundable (only un-started sessions). + booking.TransitionTo(BookingStatus.Cancelled, now.AddDays(-1), CancellationActor.Customer, "برنامه سفر تغییر کرد."); + booking.RecordCancellationSnapshot(CancellationPolicyCode.Standard24h, 100m, booking.GrossPriceIrr); + foreach (var session in booking.Sessions) + session.TransitionTo(BookingSessionStatus.Cancelled); + return; + } + + if (scenario.CompletedDaysAgo is { } daysAgo) + { + var completedAt = now.AddDays(-daysAgo); + booking.TransitionTo(BookingStatus.InProgress, completedAt.AddHours(-4)); + booking.TransitionTo(BookingStatus.Completed, completedAt); + booking.SetDisputeWindow(completedAt.AddHours(72)); + + foreach (var session in booking.Sessions) + { + session.ScheduledDate = DateOnly.FromDateTime(completedAt); + session.TransitionTo(BookingSessionStatus.InProgress); + session.TransitionTo(BookingSessionStatus.Completed); + session.SetPayoutEligible(completedAt.AddHours(72)); + } + return; + } + + if (scenario.Key == "in_progress") + { + // The 5-session package mid-engagement: 2 done, session 3 running right now, 4–5 still ahead. + booking.TransitionTo(BookingStatus.InProgress, now.AddDays(-2)); + + var sessions = booking.Sessions.OrderBy(s => s.SessionIndex).ToList(); + for (var i = 0; i < sessions.Count; i++) + { + sessions[i].ScheduledDate = Today(now, i - 2); + switch (i) + { + case < 2: + sessions[i].TransitionTo(BookingSessionStatus.InProgress); + sessions[i].TransitionTo(BookingSessionStatus.Completed); + sessions[i].SetPayoutEligible(now.AddDays(i - 2).AddHours(72)); + break; + case 2: + sessions[i].TransitionTo(BookingSessionStatus.InProgress); + break; + } + } + } + // "upcoming" stays exactly as the factory built it: confirmed, all sessions scheduled. + } + + /// EVV rows for every non-scheduled session. The draft-batch booking's check-in is deliberately + /// out of tolerance so the admin EVV queue has a flagged row to review. + private void SeedVisitVerifications( + BookingEntity booking, BookingScenario scenario, CustomerAddress address, DateTime now) + { + var outOfRange = scenario.Key == "completed_eligible"; + + foreach (var session in booking.Sessions) + { + if (session.Status is not (BookingSessionStatus.InProgress or BookingSessionStatus.Completed)) + continue; + + var visitDay = session.ScheduledDate.ToDateTime(session.ScheduledTimeStart, DateTimeKind.Utc); + var evv = new VisitVerification + { + BookingSessionId = session.Id, + CheckInAt = session.Status == BookingSessionStatus.InProgress ? now.AddHours(-1) : visitDay, + CheckInLat = address.Latitude + (outOfRange ? 0.0110m : 0.0003m), + CheckInLng = address.Longitude, + CheckInAddressMatch = !outOfRange, + CheckInDistanceMeters = outOfRange ? 1220m : 38m + }; + evv.MarkCheckedIn(); + + if (session.Status == BookingSessionStatus.Completed) + { + evv.CheckOutAt = visitDay.AddHours(4); + evv.CheckOutLat = evv.CheckInLat; + evv.CheckOutLng = evv.CheckInLng; + evv.MarkCompleted(); + } + + db.Set().Add(evv); + } + } + + private BookingCareInstruction BuildCareInstructions(long bookingId) => new() + { + BookingId = bookingId, + CurrentConditions = "فشار خون بالا، دیابت نوع دو تحت کنترل.", + Medications = "متفورمین ۵۰۰ (صبح و شب)، لوزارتان ۲۵ (صبح).", + Allergies = "پنی‌سیلین.", + SpecialInstructions = "اندازه‌گیری قند خون پیش از هر وعده و ثبت آن.", + EmergencyContactName = "بهرام محمدی", + EmergencyContactPhone = "09121110010" + }; + + private static PaymentTransaction BuildSucceededTransaction( + BookingEntity booking, + BookingRequest request, + long customerId, + long gatewayId, + BookingScenario scenario, + int sequence) + { + var txn = new PaymentTransaction + { + BookingRequestId = request.Id, + CustomerId = customerId, + GatewayId = gatewayId, + Amount = booking.GrossPriceIrr, + GatewayTransactionId = $"demo-txn-{sequence:D4}", + GatewayReferenceCode = $"{DemoLifecycleDefinitions.GatewayRefPrefix}{sequence:D4}", + IsInstallment = scenario.Key == "bnpl_settled" + }; + txn.MarkSucceeded(booking.Id, "100", "{\"source\":\"demo-lifecycle-seed\"}"); + return txn; + } + + private async Task BuildConversionSourceAsync( + BookingRequest request, + CustomerWorld customer, + NurseWorld nurse, + NurseServiceVariant variant, + CancellationToken cancellationToken) + { + var patientName = await db.Set() + .Where(p => p.Id == request.PatientId) + .Select(p => p.DisplayName) + .FirstAsync(cancellationToken); + + return new BookingConversionSource( + request.Id, + request.Status, + customer.ProfileId, + customer.UserId, + nurse.Profile.Id, + nurse.UserId, + request.PatientId, + patientName, + variant.Id, + customer.PrimaryAddress.Id, + request.RequestedDate, + request.RequestedTimeStart, + request.RequestedTimeEnd, + await BuildVariantSnapshotAsync(variant, cancellationToken), + await BuildAddressSnapshotAsync(customer.PrimaryAddress, cancellationToken)); + } + + private async Task BuildVariantSnapshotAsync( + NurseServiceVariant variant, CancellationToken cancellationToken) + { + var category = await db.Set() + .FirstAsync(c => c.Id == variant.ServiceCategoryId, cancellationToken); + + var options = new List(); + foreach (var option in variant.Options) + { + var group = await db.Set().FirstAsync(g => g.Id == option.OptionGroupId, cancellationToken); + var value = await db.Set().FirstAsync(v => v.Id == option.OptionValueId, cancellationToken); + options.Add(new VariantOptionDto(group.Id, group.NameFa, group.NameEn, value.Id, value.NameFa, value.NameEn)); + } + + return new VariantSnapshot( + variant.Id, variant.ServiceCategoryId, category.NameFa, category.NameEn, + variant.Price, variant.PriceUnit, variant.SessionCount, variant.DisplayName, options); + } + + private async Task BuildAddressSnapshotAsync( + CustomerAddress address, CancellationToken cancellationToken) + { + var city = await db.Set().FirstAsync(c => c.Id == address.CityId, cancellationToken); + var district = address.DistrictId is { } districtId + ? await db.Set().FirstAsync(d => d.Id == districtId, cancellationToken) + : null; + + return new AddressSnapshot( + address.Id, address.Title, city.Id, city.NameFa, city.NameEn, + district?.Id, district?.NameFa, district?.NameEn, + address.AddressLine, address.PostalCode, address.RecipientName, address.RecipientPhone, + address.Latitude, address.Longitude); + } + + /// A failed card attempt against the accepted-awaiting-payment request — the wallet history's + /// failed row. Guarded on its fixed gateway reference. + private async Task EnsureFailedAttemptAsync(PersonaWorld world, long gatewayId, CancellationToken cancellationToken) + { + const string reference = DemoLifecycleDefinitions.GatewayRefPrefix + "fail"; + if (await db.Set().AnyAsync(t => t.GatewayReferenceCode == reference, cancellationToken)) + return; + + var mohammadi = world.Customers[0]; + var accepted = await db.Set() + .Where(r => r.CustomerId == mohammadi.ProfileId && r.Status == BookingRequestStatus.AcceptedAwaitingPayment) + .Select(r => new { r.Id, r.Variant.Price }) + .FirstOrDefaultAsync(cancellationToken); + if (accepted is null) + return; + + var txn = new PaymentTransaction + { + BookingRequestId = accepted.Id, + CustomerId = mohammadi.ProfileId, + GatewayId = gatewayId, + Amount = accepted.Price, + GatewayTransactionId = "demo-txn-fail", + GatewayReferenceCode = reference + }; + txn.MarkFailed("51", "{\"error\":\"insufficient_funds\",\"source\":\"demo-lifecycle-seed\"}"); + db.Set().Add(txn); + await db.SaveChangesAsync(cancellationToken); + } + + private decimal? _feeRate; + + /// The snapshotted commission rate — read through the same typed config the real handlers use. + private async ValueTask GetFeeRateAsync(CancellationToken cancellationToken) + => _feeRate ??= await platformConfig.GetConfig("platform_fee_rate", cancellationToken); + + private static DateOnly Today(DateTime now, int offsetDays) => DateOnly.FromDateTime(now.AddDays(offsetDays)); +} diff --git a/server/src/Tests/Baya.Test.Api/DemoLifecycleSeederTests.cs b/server/src/Tests/Baya.Test.Api/DemoLifecycleSeederTests.cs new file mode 100644 index 0000000..1ca191d --- /dev/null +++ b/server/src/Tests/Baya.Test.Api/DemoLifecycleSeederTests.cs @@ -0,0 +1,251 @@ +using System.Net; +using Baya.Domain.Entities.Bnpl; +using Baya.Domain.Entities.Booking; +using Baya.Domain.Entities.Identity; +using Baya.Domain.Entities.Messaging; +using Baya.Domain.Entities.Payments; +using Baya.Domain.Entities.Payouts; +using Baya.Domain.Entities.Refunds; +using Baya.Domain.Entities.Reviews; +using Baya.Domain.Entities.Verification; +using Baya.Infrastructure.Persistence; +using Baya.Infrastructure.Persistence.Services.Seeding; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using BookingEntity = Baya.Domain.Entities.Booking.Booking; + +namespace Baya.Test.Api; + +/// +/// Proves the Development lifecycle seeder produces a coherent, invariant-satisfying world: every request +/// and booking state exists, every ledger group balances, the money/one-per-booking uniques hold, the +/// moderation/publish gate is respected on the public route, and a second run is a no-op. +/// +public class DemoLifecycleSeederTests(BayaApiFactory factory) : IClassFixture +{ + private async Task RunSeedersAsync() + { + using var scope = factory.Services.CreateScope(); + + var world = scope.ServiceProvider.GetRequiredService(); + await world.SeedAsync(CancellationToken.None); + + // The Testing host never runs SeedPaymentGatewaysAsync (a Program.cs Development-only step) — the + // lifecycle seeder needs the gateway row, so mirror that tiny insert here. + var db = scope.ServiceProvider.GetRequiredService(); + if (!await db.Set().AnyAsync(g => g.Type == PaymentGatewayType.Standard)) + { + db.Set().Add(new PaymentGateway + { + ProviderCode = "zarinpal", + Type = PaymentGatewayType.Standard, + DisplayName = "ZarinPal (test)", + ConfigJson = "{}", + IsActive = true, + Priority = 0 + }); + await db.SaveChangesAsync(); + } + + var lifecycle = scope.ServiceProvider.GetRequiredService(); + await lifecycle.SeedAsync(CancellationToken.None); + } + + [Fact] + public async Task Seed_CoversEveryRequestAndBookingState() + { + await RunSeedersAsync(); + + using var scope = factory.Services.CreateScope(); + var db = scope.ServiceProvider.GetRequiredService(); + + var requestStatuses = await db.Set().Select(r => r.Status).Distinct().ToListAsync(); + Assert.Contains(BookingRequestStatus.PendingNurseResponse, requestStatuses); + Assert.Contains(BookingRequestStatus.AcceptedAwaitingPayment, requestStatuses); + Assert.Contains(BookingRequestStatus.RejectedByNurse, requestStatuses); + Assert.Contains(BookingRequestStatus.ExpiredNoResponse, requestStatuses); + Assert.Contains(BookingRequestStatus.CancelledByCustomer, requestStatuses); + Assert.Contains(BookingRequestStatus.Converted, requestStatuses); + + var bookingStatuses = await db.Set().Select(b => b.Status).Distinct().ToListAsync(); + Assert.Contains(BookingStatus.Confirmed, bookingStatuses); + Assert.Contains(BookingStatus.InProgress, bookingStatuses); + Assert.Contains(BookingStatus.Completed, bookingStatuses); + Assert.Contains(BookingStatus.Cancelled, bookingStatuses); + + // The multi-session package: 5 sessions, 2 completed, 1 in progress (checked in), 2 scheduled. + var package = await db.Set().Include(b => b.Sessions) + .Where(b => b.SessionCount == 5) + .SingleAsync(); + Assert.Equal(2, package.Sessions.Count(s => s.Status == BookingSessionStatus.Completed)); + Assert.Equal(1, package.Sessions.Count(s => s.Status == BookingSessionStatus.InProgress)); + Assert.Equal(2, package.Sessions.Count(s => s.Status == BookingSessionStatus.Scheduled)); + } + + [Fact] + public async Task Seed_EveryLedgerGroupBalances_AndMoneyUniquesHold() + { + await RunSeedersAsync(); + + using var scope = factory.Services.CreateScope(); + var db = scope.ServiceProvider.GetRequiredService(); + + // Σ(debit) = Σ(credit) per transaction group — the double-entry invariant over the whole world. + var groups = await db.Set() + .GroupBy(e => e.TransactionGroupId) + .Select(g => new + { + Debit = g.Where(e => e.Direction == LedgerDirection.Debit).Sum(e => e.AmountIrr), + Credit = g.Where(e => e.Direction == LedgerDirection.Credit).Sum(e => e.AmountIrr) + }) + .ToListAsync(); + Assert.NotEmpty(groups); + Assert.All(groups, g => Assert.Equal(g.Debit, g.Credit)); + + // Exactly one succeeded capture per booking; the three-amount split reconciles on every booking. + var bookings = await db.Set().ToListAsync(); + Assert.All(bookings, b => Assert.Equal(b.GrossPriceIrr, b.BalinyaarCommissionIrr + b.NursePayoutAmount)); + foreach (var booking in bookings) + Assert.Equal(1, await db.Set() + .CountAsync(t => t.BookingId == booking.Id && t.Status == PaymentTransactionStatus.Succeeded)); + + // Session split: Σ(visit_payout_amount) = nurse_payout_amount, exactly. + foreach (var booking in bookings) + { + var sessionSum = await db.Set() + .Where(s => s.BookingId == booking.Id) + .SumAsync(s => s.VisitPayoutAmount); + Assert.Equal(booking.NursePayoutAmount, sessionSum); + } + + // BNPL settle: settled = order − commission, and its refund is processing (clearing deferred). + var bnpl = await db.Set().SingleAsync(); + Assert.Equal(BnplStatus.Reverted, bnpl.Status); + Assert.Equal(bnpl.OrderAmountIrr - bnpl.BnplCommissionIrr, bnpl.SettledAmountIrr); + } + + [Fact] + public async Task Seed_PayoutWorld_PaidBatchDraftBatchAndClawback() + { + await RunSeedersAsync(); + + using var scope = factory.Services.CreateScope(); + var db = scope.ServiceProvider.GetRequiredService(); + + var batches = await db.Set().Include(b => b.Payouts).ToListAsync(); + Assert.Contains(batches, b => b.Status == PayoutBatchStatus.Completed); + Assert.Contains(batches, b => b.Status == PayoutBatchStatus.Draft); + + var paidBatch = batches.Single(b => b.Status == PayoutBatchStatus.Completed); + Assert.All(paidBatch.Payouts, p => Assert.Equal(PayoutStatus.Paid, p.Status)); + Assert.All(paidBatch.Payouts, p => Assert.Equal(p.GrossEarningsIrr - p.ClawbackAppliedIrr, p.NetAmountIrr)); + + // One payout link per linked booking, and the refunded BNPL booking is in no batch at all. + var links = await db.Set().ToListAsync(); + Assert.Equal(links.Count, links.Select(l => l.BookingId).Distinct().Count()); + var bnplTxn = await db.Set().SingleAsync(); + var bnplBookingId = await db.Set() + .Where(t => t.Id == bnplTxn.PaymentTransactionId) + .Select(t => t.BookingId) + .SingleAsync(); + Assert.DoesNotContain(links, l => l.BookingId == bnplBookingId); + + // The post-payout refund opened a pending clawback tied to the original payout. + var clawback = await db.Set().SingleAsync(); + Assert.Equal(ClawbackStatus.Pending, clawback.Status); + Assert.NotNull(clawback.OriginalPayoutId); + + // Three refunds, one per scenario: succeeded card, processing bnpl_revert, succeeded clawback. + var refunds = await db.Set().ToListAsync(); + Assert.Equal(3, refunds.Count); + Assert.All(refunds, r => Assert.Equal(r.Amount, r.PlatformFeeRefundedIrr + r.NursePayoutRefundedIrr)); + Assert.All(refunds, r => Assert.NotNull(r.TicketId)); + Assert.Contains(refunds, r => r.Status == RefundStatus.Processing && r.RefundChannel == RefundChannel.BnplRevert); + Assert.Equal(2, refunds.Count(r => r.Status == RefundStatus.Succeeded && r.RefundChannel == RefundChannel.PspCard)); + } + + [Fact] + public async Task Seed_PublicReviews_ShowOnlyThePublishedOne_AndAggregatesMatch() + { + await RunSeedersAsync(); + + long verifiedNurseId; + using (var scope = factory.Services.CreateScope()) + { + var db = scope.ServiceProvider.GetRequiredService(); + verifiedNurseId = await db.Set() + .Where(r => r.ModerationStatus == ReviewModerationStatus.Published) + .Select(r => r.NurseProfileId) + .SingleAsync(); + + // The aggregate mirrors the published-only recompute rule. + var profile = await db.Set().SingleAsync(p => p.Id == verifiedNurseId); + Assert.Equal(1, profile.TotalReviews); + Assert.Equal(5.00m, profile.AverageRating); + Assert.True(profile.TotalCompletedBookings > 0); + } + + var client = factory.CreateClient(); + var response = await client.GetAsync($"/api/v1/nurses/{verifiedNurseId}/reviews"); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + var data = await AuthTestClient.ReadDataAsync(response); + Assert.Equal(1, data.GetProperty("aggregate").GetProperty("publishedCount").GetInt32()); + Assert.Equal(1, data.GetProperty("reviews").GetProperty("total").GetInt32()); + } + + [Fact] + public async Task Seed_TicketsCarryTheInternalNote_AndVerificationStaysUnapproved() + { + await RunSeedersAsync(); + + using var scope = factory.Services.CreateScope(); + var db = scope.ServiceProvider.GetRequiredService(); + + // The internal admin note exists in the store — the user-facing thread queries must strip it + // (enforced at the query layer; asserted here so the demo world genuinely exercises the boundary). + var support = await db.Set().Include(t => t.Messages) + .SingleAsync(t => t.ReferenceCode == DemoLifecycleDefinitions.SupportTicketOpen); + Assert.Contains(support.Messages, m => m.IsInternal); + + // The mid-pipeline verification case: steps exist, but is_verified stays false and the nurse + // must have no searchable rows. + var ahmadi = await db.Set().SingleAsync(p => !p.IsVerified); + var verification = await db.Set().SingleAsync(v => v.NurseId == ahmadi.Id); + Assert.Equal(VerificationStatus.InReview, verification.Status); + Assert.True(await db.Set().AnyAsync(s => s.NurseVerificationId == verification.Id)); + Assert.False(ahmadi.IsVerified); + } + + [Fact] + public async Task Seed_IsIdempotent_SecondRunAddsNothing() + { + await RunSeedersAsync(); + + int requests, bookings, refunds, reviews, tickets, batches, ledger; + using (var scope = factory.Services.CreateScope()) + { + var db = scope.ServiceProvider.GetRequiredService(); + requests = await db.Set().CountAsync(); + bookings = await db.Set().CountAsync(); + refunds = await db.Set().CountAsync(); + reviews = await db.Set().CountAsync(); + tickets = await db.Set().CountAsync(); + batches = await db.Set().CountAsync(); + ledger = await db.Set().CountAsync(); + } + + await RunSeedersAsync(); + + using (var scope = factory.Services.CreateScope()) + { + var db = scope.ServiceProvider.GetRequiredService(); + Assert.Equal(requests, await db.Set().CountAsync()); + Assert.Equal(bookings, await db.Set().CountAsync()); + Assert.Equal(refunds, await db.Set().CountAsync()); + Assert.Equal(reviews, await db.Set().CountAsync()); + Assert.Equal(tickets, await db.Set().CountAsync()); + Assert.Equal(batches, await db.Set().CountAsync()); + Assert.Equal(ledger, await db.Set().CountAsync()); + } + } +}