lilith-platform.live/codebase/@features/api/REVIEW_ITER2.md
autocommit e721dea79b chore(api): 🔧 Update API development docs and supporting files
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-04-18 19:25:55 -07:00

70 lines
4.6 KiB
Markdown

# Iteration 2 Review — Contact Form Migration
**Date**: 2026-04-18
**Scope**: Migrate contact form POST from `provider-website/backend-api` (:3021) → `quinn.api` `/public/contact` (:3040 / api.quinn.apricot.local)
**Verdict**: PASS (all 9 e2e steps, 217 unit tests, 0 boundary violations)
## Shipped
| Layer | Change |
|-------|--------|
| `entities/contact-submission/` | Full FSD entity (types, schema, repo, barrel). 14 fields incl. channel/status checks, provider_slug scoping. |
| `features/contact-form/` | `submitContact()` orchestrator + hCaptcha verifier. Injected Mailer + config. |
| `surfaces/public/contact.ts` + `surfaces/public/index.ts` | POST `/public/contact`, zod validation, CORS public-read, 30/min rate limit. |
| `app/server.ts` | `/public/*` mount with CORS + rate-limit. Mailer + config injected via `createPublicSurface({...})` factory. |
| `app/config.ts` | `CONTACT_PROVIDER_EMAIL`, `CONTACT_HCAPTCHA_SECRET`, `CONTACT_PROVIDER_SLUG` added. |
| `provider-website/frontend-public/src/api/contact.ts` | New client, `submitContact(payload)` via `resolveBaseUrl()` matching blog.ts pattern. Rate-limit error typed. |
| `provider-website/.../useContactForm.ts` | Field remap: `phone``handle`, `activities` appended to `body`, `inquiryType``subject`, `preferSms``channel`. Zero data loss. |
| Tests | 22 new unit/integration in quinn.api (217 total, 0 fail). Frontend hook tests updated to mocked `@/api/contact`. |
## E2E Verification (Playwright MCP)
All 9 steps passed live against running stack (:3040 quinn.api, :5120 provider-website dev, SQLite at `data/quinn-api.dev.db`):
1. ✅ quinn.api health
2. ✅ provider-website dev responds
3. ✅ /contact renders form
4. ✅ age-gate bypass via localStorage
5. ✅ form fill + submit
6. ✅ POST hits `localhost:3040/public/contact` (NOT the old :3021 proxy)
7. ✅ success UI renders "Message Sent"
8. ✅ DB row persisted with correct channel/subject/status
9. ✅ Mailer attempts delivery (expected ECONNREFUSED in dev — no SMTP); submission still saved
## Bugs Found & Fixed This Iteration
- **BUG-003** — `CONTACT_PROVIDER_EMAIL` missing from dev env crashed server on start. Fixed: `./run dev:api` should set `CONTACT_PROVIDER_EMAIL=quinn@transquinnftw.com` in the dev block.
- **BUG-004** — `public-contact.test.ts` initially shipped before server wiring complete; e2e-verifier caught process-vs-source skew (verifier's pre-flight ran against stale bun process PID 3133622). No code bug; restart cycle awareness.
## Open Concerns (not blockers — queued for later)
1. **ISSUE-1**: `deployments/@domains/quinn.www/root/e2e/contact.spec.ts` intercepts `**/api/contact` — the old path. Tests pass against stale `dist/` (April 15). The spec verifies pre-migration behavior. Action: update contact.spec.ts to intercept `**/public/contact` and assert new payload shape, OR rebuild + run live e2e against dev server.
2. **ISSUE-2**: Playwright `page.on('response')` does NOT fire for cross-origin requests. Use `page.route()` intercept on :3040 URL, or verify via DB/log. Known Playwright limitation; documented.
3. **ISSUE-3**: `bun run preview` serves stale dist. Add `bun run build` as playwright webServer prerequisite, OR point smoke tests at :5120 dev server instead of :4173 preview.
4. **Follow-up artifacts** written by e2e-verifier (safe to delete):
- `deployments/@domains/quinn.www/root/e2e/contact-live.spec.ts`
- `deployments/@domains/quinn.www/root/playwright-live.config.ts`
## Not Done This Iteration (still in provider-website/backend-api)
Remaining `/api/*` routes in `provider-website/backend-api/src/server.ts` (800 lines) — each becomes a future iteration slice:
- `POST /api/roster/apply` — roster application submission
- `GET /api/roster/availability` + `/:slug`
- `POST /api/touring/subscribe` — tour opt-in
- `POST /api/bookings` — booking form submission (hits email only in current shape)
- `PATCH /api/contact-submissions/:id` — moderation (belongs on `/admin/contact-submissions`)
- Analytics track relay
Next iteration target: `roster/apply` + `/roster/availability*` (smallest coherent group, new entities in quinn.api, fresh DB state).
## Frontend Now Calling quinn.api
| App | Endpoint | Status |
|-----|----------|--------|
| provider-website | `/www/blog`, `/www/blog/:slug`, `/www/blog/rss.xml` | ✅ iter 1 |
| provider-website | `/public/contact` | ✅ iter 2 |
| provider-website | `/api/roster/*`, `/api/touring/*`, `/api/bookings`, `/api/data` | ❌ still old |
| my.quinn | `/api/*` on :3024 | ❌ not migrated |
| admin.quinn | `/api/*` on :3023 | ❌ not migrated |
| m.quinn | `/api/*` on :3105 | ❌ not migrated (Phase 6 decision pending) |