3.8 KiB
Phase 15 — Turn off developer/debug mode on the live site
Blocker: blockers.md §B.2. Do this deliberately, on its own, right before any real stranger is let near the site — it touches deploy config and secrets handling, not app logic, and has real prerequisites. Depends on: nothing code-wise, but bundle with credential rotation (blockers.md §B.1) when you do it — currently deferred per your own call, revisit before real users arrive.
Root cause. The exposure (GET api/v1/dev/last_otp/{phone},
unauthenticated by design, guarded only by environment.IsDevelopment()) is correctly implemented in code
— the entire gap is that the deployed docker-compose.yml sets ASPNETCORE_ENVIRONMENT: Development,
deliberately and already documented (a comment in the compose file and a full section in DEPLOY.md
spell out why and what depends on it).
This is not a one-line flip — five real prerequisites, already documented in DEPLOY.md, need to land
together:
- Create
server/src/API/Baya.Web.Api/appsettings.Production.jsonwith real (non-not-for-productionsentinel)IdentitySettings:SecretKey/Encryptkey—StartupSecretsGuardrejects the sentinel outside Development, so a bare env-var flip with the current file would refuse to boot.Seams:FieldEncryption:Key/:HashKeymust be copied byte-identical from the current Development value — never regenerated (rootCLAUDE.mdrule 6 — this key decrypts all existing PII). - Set
ASPNETCORE_ENVIRONMENT: Productionindocker-compose.yml. - Switch migrations from boot-time auto-apply (Development-only branch) to the documented one-shot
(
... migrate) deploy step — and confirm the demo/lifecycle seed data the shared DB currently relies on survives the transition, since those seeders stop running automatically post-flip. - Swap
Seams:Sms:Providerfromtelegram(a broadcast-to-a-fixed-chat-list relay, fine for trusted internal testers, not for strangers) tokavenegarwith a real API key — flipping only the environment variable closes the/dev/last_otpleak but leaves OTPs going out over the Telegram relay instead of to the real phone. - Bundle with credential rotation (blockers.md §B.1) when you do it — the same config file carries the DB password alongside the encryption keys.
Flag: whether to keep the Telegram relay live in parallel with kavenegar for internal/test accounts
post-launch, or retire it entirely, is a product/ops call, not answered by the code.
Not phases — noted here so they aren't lost, but no code to write
- §B.1 (rotate committed credentials) — per your call, skipped for now (private repo, single developer). Revisit before any real user touches the deployed site; bundle with step 5 above when you do.
- §B.3 (legal review of Terms/Privacy) — not a code task; needs an actual legal review.
- §B.4 (مودیان e-invoicing) — per your call, not built now. When you pick it up: the invoice data and tax math are already correct; the only missing piece is the actual government-facing registration call, and it needs a chosen provider/gateway before any adapter code makes sense. Add a note to forgotten-features.md saying exactly that, rather than building a speculative seam with nothing real to point it at.
- §B.5 (e-namad certification) — a business/paperwork step, not a code change; also gates the real ZarinPal card-payment path (07-card-payment-redirect.md) from ever going fully live, independent of any code fix.
- §B.6 (real bank-transfer payout rail) — per your call, stays mocked. Resolved by 11-nurse-payouts.md — the seam already exists server-side; only the client UI in front of it was missing.