diff --git a/docs/launch-checklist.md b/docs/launch-checklist.md index 4f78525..8c89015 100644 --- a/docs/launch-checklist.md +++ b/docs/launch-checklist.md @@ -24,7 +24,7 @@ Status legend: `[ ]` open ยท `[x]` done ยท `[?]` needs verification ยท ๐Ÿ›‘ owne | `npm run build` | green, 21 pages, 0 errors / 0 warnings | | `npm run typecheck` | green, 28 files, 0/0/0 | | `npm run seo:lint` | green, 21 pages clean | -| `npm run test:e2e` | **42 passed / 4 failed** (stale assertions, see ยง2.1) | +| `npm run test:e2e` | **44 passed / 4 failed** (the 4 are stale assertions, see ยง2.1) | | CI root cause | **found + fixed in-repo 2026-09-22** โ€” see ยง1.2; needs a green run to confirm | | Staging URL | **https://bcs.int.7tl-homelab.com** โ€” LAN-only, valid cert (ยง2.6) | | Old WordPress site | untouched and serving โ€” must stay that way until cutover | @@ -124,12 +124,40 @@ Two notes written for developers, not visitors, were being rendered: Replaced the first with reader-facing copy and dropped the second (the deviation it described is already recorded in `docs/content-deviations.md`). Commit `4e354d2`. -### 1.4 Contact form has no endpoint ๐Ÿ›‘ -`PUBLIC_CONTACT_FORM_ENDPOINT` is `""` in `k8s/configmap.yaml`, so the form falls back to a -mailto handoff. Inbound leads will be lost or awkward on day one. -- [ ] Choose an endpoint (Formspree / webhook / ntfy / self-hosted) and set it in the ConfigMap. -- [ ] Test a real submission end-to-end and confirm `/thank-you/` is reached. -- [ ] Confirm the delivery address is monitored. +### 1.4 Contact form endpoint โ€” plumbing DONE 2026-09-23, needs your Formspree ID ๐Ÿ›‘ +**Correction to the original entry:** it said to set `PUBLIC_CONTACT_FORM_ENDPOINT` in +`k8s/configmap.yaml`. That would never have worked. +- The Deployment has **no `env`/`envFrom`** referencing that ConfigMap โ€” it is dead config. + (`PUBLIC_SITE_URL` is in the same state; it only appears to work because the default baked into + `astro.config.mjs` is already correct.) +- Even wired up it could not work: `output: "static"` means Astro **inlines** `PUBLIC_*` at image + build time, and the pod only runs nginx over pre-built HTML. There is no runtime knob. + +**Done (commit `af4cc4a`):** +- [x] `Dockerfile` takes `ARG PUBLIC_CONTACT_FORM_ENDPOINT` / `PUBLIC_SITE_URL` โ†’ `ENV` before build. +- [x] CI passes `--build-arg` from a `CONTACT_FORM_ENDPOINT` Actions secret. +- [x] ConfigMap rewritten as documentation, with a warning not to add `envFrom`. +- [x] Submit posts in the background via `fetch()` and redirects to our own `/thank-you/` instead + of navigating to the provider's page. +- [x] Failure path: stays on the page, re-enables the button, shows the phone/email fallback. +- [x] Honeypot `_gotcha` (Formspree treats it as spam), positioned off-screen rather than + `display:none` so bots that skip hidden fields still fill it. +- [x] e2e covers the real fetch path (mocked endpoint, asserts the payload) and the failure case. + +**Still needs you:** +- [ ] ๐Ÿ›‘ Create the Formspree form for **info@bluecapstrategies.com** and confirm the address. +- [ ] ๐Ÿ›‘ Add the endpoint as a Gitea repo Actions secret named **`CONTACT_FORM_ENDPOINT`** + (Settings โ†’ Actions โ†’ Secrets on `bmr_bluecap/bcs-website`), value + `https://formspree.io/f/`. +- [ ] Push any commit touching `src/**` so CI rebuilds with the secret baked in. +- [ ] Verify on the staging URL: submit a real inquiry, confirm it arrives, confirm the browser + lands on `/thank-you/`. +- [ ] Confirm the destination inbox is actually monitored. A working form delivering into an + unwatched inbox is its own kind of failure. + +**Degradation if the secret is missing:** the build still succeeds and the form falls back to +opening a `mailto:` draft. Survivable, but it fails silently for webmail users with no OS mail +client โ€” so treat a missing secret as a launch blocker, not a warning. ### 1.5 Draft insight was being published and indexed โœ… FIXED 2026-09-23 `src/pages/insights/[slug].astro` called `getCollection("insights")` unfiltered, so the