Files
baya-monorepo/.claude/skills/flow-testing/SKILL.md
T
2026-08-02 20:01:31 +03:30

5.3 KiB

name, description
name description
flow-testing Boot both sides of Balinyaar locally and walk a real user journey end to end — the right seeded account, the right flow doc, and knowing whether you just proved the real path or a mock answering. Use before claiming a fix or feature works, or when asked to test, verify, or demo a flow.

Balinyaar Flow Testing

Exercising a flow proves something only if you know which half of the stack actually answered. This is the procedure; the facts it points at (ports, accounts, known failure modes) live in docs/flows/testing-setup.md and are kept current there — don't copy them here, they will drift.


1. Boot it

The five-minute path, verbatim from testing-setup.md:

# API — mock SMS or request_otp 500s
cd server
Seams__Sms__Provider=mock dotnet run --project src/API/Baya.Web.Api/Baya.Web.Api.csproj

# client
cd client && npm install && npm run dev        # http://localhost:3000/fa

# read the OTP — the console does NOT print it
curl http://localhost:5002/api/v1/dev/last_otp/09120000010

No database setup: the committed dev config points at an already-seeded remote SQL Server. If anything here doesn't match reality when you run it, testing-setup.md is wrong and needs a fix in the same change — it carries a Last verified stamp for exactly this reason.


2. Check the mock-vs-real map before you conclude anything

A flow "working" through a mocked domain proves the UI, not the server. Before testing:

  1. Open docs/integration/domains/index.md — the census table names which of the 22 client services/ domains are real vs mock (currently 15 real, 7 mock: admin, bnpl, partnerCenter, patientRecords, payouts, refunds, verification).
  2. A mocked domain is a USE_<DOMAIN>_MOCK flag in client/src/services/<domain>/constants.ts — check it directly if you need certainty for the exact domain you're touching.
  3. State your finding in terms of which one you exercised: "the booking flow works end-to-end against the real server" is a different claim from "the admin console renders correctly against its mock" — never report the second as if it were the first.

3. Pick the right seeded account

Demo accounts, their roles, and what each one demonstrates are tabulated in testing-setup.md — read it there rather than assuming a phone number. One standing gap to route around: the seeded admin accounts (…020 super_admin, …021 finance) get 403 on every real admin endpoint (a DynamicPermission / role-literal mismatch). The admin backoffice is only testable against the client's mock; don't spend time trying to walk it against the real API without first checking whether that gap has been closed.


4. Walk the flow

docs/flows/index.md is the atlas — one file per user-meaningful journey, each answering exactly three questions: what it does, what's mocked for that journey specifically, and how to test it. Open the one file that matches what you're testing rather than guessing the steps; it's the one place gap numbers and REQ references for that journey are tracked.


5. Two things that will silently invalidate your test

  • The scheduler is live while you test. booking_request_expiry runs every 60 seconds (hardcoded) and flips an un-actioned request to expired_no_response / payment_deadline_expired out from under you. Act on a request promptly, or create a fresh one rather than trying to reuse an old test artifact.
  • The OTP endpoints are rate-limited together. request_otp and verify_otp share one bucket, 5 calls per 60 s per IP — a login is 2 calls, so that's two logins per minute, total. Space scripted logins ≥ 40 s apart (see testing-setup.md for a working script) or you'll 429 and misread it as a bug.

6. When the seeded world has aged out

There is no in-app reseed — both seeders guard on natural keys, so re-running never refreshes stale dates. If the scenario you need (an "upcoming" booking, an open dispute window, a pending request) no longer exists because the world was seeded days ago:

  • Fastest fix: create the scenario fresh yourself (customer → search → booking request → accept → pay) — this is the intended way to exercise booking-request and checkout-and-payment anyway.
  • Full reseed: only against a local database — docker compose down -v && docker compose up -d under server/, then boot. Never drop the shared remote database casually; it backs the live demo deployment and other people's sessions.

7. Report what you actually saw

Name the account you used, the domain's mock/real status, and the exact response (status code, error message) rather than "it worked" — the troubleshooting table in testing-setup.md exists because several failure modes here look identical to an unrelated bug (a rate limit looks like a crash; /healthz/ready failing on Windows looks like the app is down). Check it before filing something as a new defect.