MVP Limitations and Production Gate
Status: MVP skeleton code — not production ready. This document lists every limitation the user must address before flipping the production switch.
Per user instruction (2026-08-31): authorization, payment integration, and any other live-service dependency are placeholder. They are not blockers for the MVP skeleton because the business scope and architecture are locked; they are blockers for production traffic.
1. Architecture and persistence (locked by ADR 0089)
- Runtime: Cloudflare Worker (TypeScript,
nodejs_compat). - Database: Cloudflare D1 (single regional primary + global read replicas).
- PersistenceAdapter: single seam in
app/src/persistence/adapter.ts; D1 implementation ind1-adapter.ts. Future Postgres rewrite touches only the adapter.
To deploy:
1. wrangler d1 create seraya-db → copy database_id into wrangler.toml.
2. wrangler d1 migrations apply seraya-db --remote.
3. wrangler deploy.
Migration is in app/migrations/0001_init.sql and references ADRs 0089–0095 (couple participant, capacity overlap, no-show timing, settlement uniqueness, intake schema, package cancellation).
2. Authorization (placeholder, per user instruction)
- Public routes:
/,/pulang,/about,/fuja,/faq,/safety/crisis,/privacy,/consent,/cancellation,/book/*— open to all. - Admin routes:
/admin/*are gated behindALLOW_PLACEHOLDER_ADMIN_AUTH=trueenv flag. Production must remove this flag and integrate: - Google SSO verification per ADR 0080 (
google_subjectclaim → StaffMembership lookup). - StaffMembership bootstrap with two Admin per ADR 0081.
- Role check per ADR 0079 (
admin/psychologist). - Two-Admin invariant for staff invite/revoke (TBC-STAFF-SESSION-01).
3. Payment integration (placeholder)
app/src/adapters/midtrans-snap.tsis a stub that throws on non-test calls. It exists to keep the Worker compilable and to lock the interface per ADR 0089 §7.- For real settlement, complete
TBC-PAY-01:
1. Midtrans Snap merchant onboarding (server key, client key, sandbox account).
2. Real signature verification (SHA-512 over body + server key).
3. Webhook payload mapping intoVerifiedPaymentEvent.
4. Idempotency-key naming convention.
5. Retry and dead-letter policy.
The FakePaymentAdapter for local dev/tests is not in this skeleton; add it under tests/integration/fake-adapter.ts before running integration tests.
4. Notification and email (placeholder)
- The Worker does not call any email provider in this skeleton.
NotificationandDeliveryAttempttables exist in the migration; the Worker just inserts rows. TBC-NOTIFY-01 covers provider integration.
5. Content/CMS (placeholder)
ContentEntryandContentRevisiontables exist; Admin CMS is not implemented.- Public pages render from inline views in
app/src/views/index.ts. Move content tocontent_entryrows before launch.
6. Crisis, privacy, consent, cancellation copy (placeholder wording)
- All public-facing copy for
/safety/crisis,/privacy,/consent,/cancellationis a placeholder intended to match the locked business scope. Final wording requires: - Clinical/ethics sign-off (TBC-CONSENT-01).
- Privacy review (TBC-PRIVACY-01).
- Legal review for terms of service and refund policy.
7. Couple booking (launch-deferred pending ADR 0090)
- The couple package is modeled end-to-end (
BookingParticipant,AppointmentParticipant,joint_attendees), but the public page surfaces a "coming soon" badge. - To launch couple booking: complete TBC-COUPLE-LAUNCH-01 (additional clinical/ethics sign-off on joint-session consent wording, and Admin workspace support for couple-package cancellation).
8. What is locked (do not re-open without a new ADR)
| Decision | ADR | Authority |
|---|---|---|
| Stack: Cloudflare Worker + D1 | ADR 0089 | Locked |
| Cancellation/refund handled by Admin WhatsApp only | Round 3 + ADR 0076/0077 | Locked |
Refund outcomes only full_refund / no_refund |
ADR 0077/0093 | Locked |
| Capacity grid 30 min, symmetric TransitionBuffer | ADR 0091 | Locked |
| No-show early checkpoint T+15m, correction window 7×24h | ADR 0092 | Locked |
| At-most-one settled Payment per Booking | ADR 0093 | Locked |
| Intake: Nama + Email + optional Phone + Consent | ADR 0094 | Locked |
| Couple BookingParticipant/AppointmentParticipant | ADR 0090 | Locked |
| Package cancellation matrix R1–R4 | ADR 0095 | Locked |
| Launch gate G-1..G-14 with owners | ADR 0096 | Locked |
9. What is operational (must be done before production, but not architecture changes)
- Staff bootstrap: record two Admin StaffMemberships per ADR 0081.
- Profile evidence: verify Fuja's STR/SILP and obtain publication consent.
- Real availability: replace
anytime/anyplaceplaceholder with Fuja's recurring schedule and offline venue (TBC-SCHEDULE-01). - Approved consent/privacy copy: clinical/ethics sign-off on the placeholder text in
app/src/views/index.ts. - Midtrans onboarding: production merchant + sandbox evidence + refund capability verification (TBC-PAY-01).
- Email provider: choose provider, set sender domain, and write template copy (TBC-NOTIFY-01).
- Backup/restore drill: pre-launch snapshot export via
wrangler d1 export; restore drill. - Runbook: cancellation handling, late payment reconciliation, refund failure recovery.
Each gate G-1..G-14 in ADR 0096 maps to one of the above.
10. Folder layout
seraya-psikologi-mvp/
├── package.json # Worker + Hono + Vitest + wrangler
├── wrangler.toml # CF Worker + D1 binding (PLACEHOLDER db_id)
├── tsconfig.json
├── README.md # (this file)
├── app/
│ ├── migrations/
│ │ └── 0001_init.sql # D1 schema baseline (post ADR 0089–0095)
│ ├── public/
│ │ └── (placeholder, Worker serves inline CSS)
│ └── src/
│ ├── worker/index.ts # Hono router; public + booking + admin + webhook
│ ├── modules/ # catalog, availability, booking, payment, admin
│ ├── adapters/ # MidtransSnapAdapter (placeholder)
│ ├── persistence/ # PersistenceAdapter + D1 driver
│ ├── domain/types.ts # shared vocabulary
│ └── views/index.ts # SSR HTML helpers
└── tests/
├── unit/ # (empty; place pure-policy tests here)
└── integration/ # (empty; place D1/Miniflare tests here)
11. How to run locally
- Install deps:
pnpm install(ornpm install). - Apply migrations:
pnpm migrate:local. - Start Worker:
pnpm dev. Openhttp://localhost:8787. - Admin (placeholder): set
ALLOW_PLACEHOLDER_ADMIN_AUTH=truein.dev.vars, then visit/admin.
Local DB is a fresh D1 binding. Seed data is not included; minimal seed script under scripts/seed.mjs is referenced in package.json but not implemented (TBC).
12. Verification artifacts (already produced)
docs/adr/0089–0096— eight ADRs covering all top-priority ticket closures.docs/IMPLEMENTATION-GUIDE.md,docs/DOMAIN-MODEL.md,docs/CONTEXT.md— patched and consistent with the ADRs.docs/PRD-GUIDELINE-REVIEW.md— 1,075 lines, Round 1–6 closure summary.output/seraya-psikologi-prd-review-001.zip— review bundle (125 members, 96 ADR, MVP skeleton files).