Last updated: 2026-06-14. Read this first, then README.md (architecture),
REVIEW.md (remaining items), RUNBOOK.md, DATA.md.
main (solo project; deploys
on push). End commit messages with the Co-Authored-By trailer.worker.js) serving the
dynamic itinerary portal. Bindings: KV BOOKINGS (farholm-bookings), R2
BACKUPS (farholm-backups, daily snapshots), ASSETS (static site).main. The build
command is npm run verify (= npm ci && npm run check && npm test && npm run build), so a failing check/test blocks the deploy.ACCESS_TEAM_DOMAIN + ACCESS_AUD in wrangler.jsonc). Local dev uses
DEV_ADMIN_BYPASS=1 in .dev.vars (gitignored) so wrangler dev on
localhost grants admin.FH-9QXM4K7P, surname Demo.npm run check — syntax (standalone JS + inline .njk scripts).npm test — Node integration tests; test/worker.test.mjs loads the real
worker.js via a data: URL, stubbing only the admin.html and merle.html
text imports, with in-memory KV/R2. Add tests here for new worker behavior.npx wrangler dev — local worker with simulated KV/R2 (no auth needed; use
http://localhost). Good for end-to-end checks of new endpoints.r2_bucket_create works; KV key edits need the dash.The full engagement is done and deployed: original cleanup, security hardening
(Access JWT, CSP/HSTS/headers, lookup validation, rate limit, soft-delete/purge),
gold-standard infra (self-hosted fonts, fingerprinted assets, daily R2 backups +
encrypted off-Cloudflare export, health/readiness, structured logging), the whole
REVIEW.md code remediation with a 16-test suite + deploy gate, brand kit,
Points & Miles page, and the Merle & Michael rebrand landing (served by the
worker for merle(and)?michael.com + www). REVIEW.md top section tracks
what's fixed vs the remaining dashboard/larger items.
Shipped (2026-06-14). Documents (e-tickets, vouchers, confirmations) attach to a
booking, live in a separate R2 bucket farholm-attachments (binding DOCS,
already created in the account) at att/<REF>/<uuid>-<safeName>, and are served
only through the worker — never a public bucket. 10 MB cap; PDF + image types
only. DATA.md-prohibited content (passports, payment-card data, passwords,
medical) is restated in the admin panel copy.
worker.js): admin-gated POST /api/admin/attach?reference=…
(multipart), GET /api/admin/attachments, GET /api/admin/attachment (admin
fetch/preview), POST /api/admin/attach/delete; plus public, portal-host-only
POST /api/attachment { reference, lastName, key } gated like /api/lookup
(re-verifies ref+surname AND that the key belongs to that booking).
/api/admin/save carries attachments[] through unchanged; /api/admin/purge
deletes the R2 objects (record keys + att/<REF>/ prefix sweep).admin.html + js/admin.js), shown once a
booking is saved; client "Documents" downloads list (trip.njk + js/trip.js).test/worker.test.mjs (23 total green). Verified live via
wrangler dev + a browser smoke test (upload → list → client download).DATA.md inventory.See REVIEW.md → "Still open" for the current list. The only remaining dashboard
chore is an external uptime monitor on /api/health. Larger efforts: admin audit
log + RBAC, automated restore + staging, CSP nonces, Origin/CSRF checks, IaC.
Done 2026-06-14 (account/dashboard): Always Use HTTPS, account+Access MFA, the
merle domains' registration moved into the Farholm account + merle-michael-landing
Pages project deleted, www → farholm.com redirect verified, Termly consent
confirmed, Web3Forms spam protection set to strict (domain restriction is Pro-only),
and GitHub Actions SHA-pinned (ci.yml).