feat: web UI scaffold with embedded SPA and multi-stage Docker build #16

Merged
bvandeusen merged 262 commits from dev into main 2026-04-22 14:23:02 -04:00
bvandeusen commented 2026-04-22 13:44:01 -04:00 (Migrated from git.fabledsword.com)

Summary

  • Scaffold SvelteKit 2 + Svelte 5 + Tailwind SPA at web/ with Vitest smoke test
  • Embed the SvelteKit build output in the Go binary via //go:embed all:build, with SPA fallback for deep links and a prefix carve-out so /api/* and /rest/* never return HTML
  • Rewrite Dockerfile as a three-stage build (node → golang → debian:slim) and update Forgejo CI to install Node, build the SPA, and run Vitest before Go steps
  • Document the two-process dev workflow (Vite on :5173 proxying to Go on :4533) in the README

Test Plan

  • go test -short -race ./... passes
  • golangci-lint run ./... clean
  • cd web && npm test && npm run build passes
  • docker build -t minstrel:scaffold-final . succeeds; binary is -x in the final image
  • docker compose up -d end-to-end:
    • GET / → 200 text/html (SPA)
    • GET /artists/<uuid> → 200 text/html (SPA deep-link fallback)
    • GET /healthz → 200 application/json
    • GET /api/nonexistent → 404 application/json (no HTML leaked)
    • GET /rest/nonexistent → 200 application/json (subsonic error shape, still JSON)
  • Forgejo CI green on this PR
## Summary - Scaffold SvelteKit 2 + Svelte 5 + Tailwind SPA at `web/` with Vitest smoke test - Embed the SvelteKit build output in the Go binary via `//go:embed all:build`, with SPA fallback for deep links and a prefix carve-out so `/api/*` and `/rest/*` never return HTML - Rewrite `Dockerfile` as a three-stage build (node → golang → debian:slim) and update Forgejo CI to install Node, build the SPA, and run Vitest before Go steps - Document the two-process dev workflow (Vite on `:5173` proxying to Go on `:4533`) in the README ## Test Plan - [x] `go test -short -race ./...` passes - [x] `golangci-lint run ./...` clean - [x] `cd web && npm test && npm run build` passes - [x] `docker build -t minstrel:scaffold-final .` succeeds; binary is `-x` in the final image - [x] `docker compose up -d` end-to-end: - `GET /` → 200 `text/html` (SPA) - `GET /artists/<uuid>` → 200 `text/html` (SPA deep-link fallback) - `GET /healthz` → 200 `application/json` - `GET /api/nonexistent` → 404 `application/json` (no HTML leaked) - `GET /rest/nonexistent` → 200 `application/json` (subsonic error shape, still JSON) - [ ] Forgejo CI green on this PR
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: bvandeusen/minstrel#16