Feature 01 task 3: Embed the PWA build with SPA fallback #4

4 Commits
Author SHA1 Message Date
dev_agentandClaude Opus 5.5 7ba2a37da2 Recreate the embed directory so stale dotfiles cannot be served
Independent review Approved — 0 high findings (#4)
Review finding F1: the cleanup glob internal/frontend/dist/* skipped
hidden files, which all:dist embeds. Remove and recreate the whole
directory before copying web/dist, and add a check-embed-clean target
that plants a stale hidden file and asserts the embed removes it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 22:44:33 -04:00
dev_agentandClaude Opus 5.5 8236c5e349 Add make build to embed the built PWA in the server binary
Independent review Not signed off — 0 high, 1 medium (#4)
Fixes review finding F1: nothing copied web/dist into
internal/frontend/dist, so the server always embedded the placeholder.
make build now builds the web app, replaces internal/frontend/dist with
web/dist, and builds bin/mealquest.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 22:40:46 -04:00
dev_agentandClaude Opus 5.5 efae9bed7e Keep reserved prefixes out of the SPA fallback under dot segments
Independent review Not signed off — 1 high (#4)
Address review findings F1 and F2:
- F1: check reserved prefixes against the request path before and after
  cleaning, so /auth/../quests/42 and /api%2F..%2Fquests/42 get the JSON
  404 instead of index.html. Add frontend and router tests for both.
- F2: add an unhashed asset (robots.txt) to the frontend fixture and
  assert its status, body and immutable Cache-Control.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 22:36:51 -04:00
dev_agentandClaude Opus 5.5 ee4670754a Embed the PWA build and serve it with SPA fallback
Independent review Not signed off — 0 high, 1 medium, 1 low (#4)
Add internal/frontend, which embeds internal/frontend/dist and serves it
with Cache-Control "no-cache" for index.html, sw.js and
manifest.webmanifest and "public, max-age=31536000, immutable" for every
other asset. Any other GET or HEAD falls back to index.html, except paths
under the reserved /api, /auth, /media and /health prefixes, which get
the JSON not_found error instead.

NewRouter now takes the asset fs.FS so tests use a fstest.MapFS fixture,
mounts an /api subrouter with JSON 404/405 handlers, and fails fast if
the assets lack index.html. A placeholder dist/index.html is tracked so a
fresh clone compiles; built assets remain git-ignored.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 22:29:41 -04:00