Pansy ships as one static binary: the Vite production build is embedded into the Go binary with embed.FS and served with an SPA fallback. This issue wires that up plus the Makefile that makes dev and release builds one command each.
Scope
internal/webdist/dist.go: //go:embed all:dist exposing the built frontend. Commit a minimal placeholder dist/index.html so go build works before/without a web build (the Makefile overwrites it).
internal/api/spa.go: serve embedded static files; any non-/api path with no matching file falls back to index.html (client-side routing deep links must work). Correct content types; sensible cache headers (hashed assets long-lived, index.html no-cache).
Makefile:
make web — cd web && npm ci && npm run build, then sync web/dist → internal/webdist/dist.
make build — make web + CGO_ENABLED=0 go build -o pansy ./cmd/pansy.
make dev — run the Go API server and vite dev together (or document running them in two terminals).
make test — go test ./... and cd web && npx vitest run (if tests exist yet).
README: quickstart section — build, run, env vars table.
Out of scope
Dockerfile / release automation (later if wanted).
make build produces a single binary with no cgo (file pansy / build with CGO_ENABLED=0).
Running the binary and opening http://localhost:8080/gardens directly (deep link) loads the React shell via the SPA fallback; /api/v1/healthz still returns JSON.
make dev gives a working iteration loop with the Vite proxy.
Part of epic #20 · Design: [DESIGN.md](https://gitea.stevedudenhoeffer.com/steve/pansy/src/branch/main/DESIGN.md)
## Context
Pansy ships as one static binary: the Vite production build is embedded into the Go binary with `embed.FS` and served with an SPA fallback. This issue wires that up plus the Makefile that makes dev and release builds one command each.
## Scope
- [ ] `internal/webdist/dist.go`: `//go:embed all:dist` exposing the built frontend. Commit a minimal placeholder `dist/index.html` so `go build` works before/without a web build (the Makefile overwrites it).
- [ ] `internal/api/spa.go`: serve embedded static files; any non-`/api` path with no matching file falls back to `index.html` (client-side routing deep links must work). Correct content types; sensible cache headers (hashed assets long-lived, `index.html` no-cache).
- [ ] `Makefile`:
- `make web` — `cd web && npm ci && npm run build`, then sync `web/dist` → `internal/webdist/dist`.
- `make build` — `make web` + `CGO_ENABLED=0 go build -o pansy ./cmd/pansy`.
- `make dev` — run the Go API server and `vite dev` together (or document running them in two terminals).
- `make test` — `go test ./...` and `cd web && npx vitest run` (if tests exist yet).
- [ ] README: quickstart section — build, run, env vars table.
## Out of scope
- Dockerfile / release automation (later if wanted).
- Any application features.
## Key files & patterns
- Embed + build flow summary: `DESIGN.md` § Backend layout.
## Dependencies
Blocked by #1 (Go server) and #2 (web app).
## Acceptance criteria
- `make build` produces a single binary with no cgo (`file pansy` / build with `CGO_ENABLED=0`).
- Running the binary and opening `http://localhost:8080/gardens` directly (deep link) loads the React shell via the SPA fallback; `/api/v1/healthz` still returns JSON.
- `make dev` gives a working iteration loop with the Vite proxy.
steve
added the infra label 2026-07-18 18:15:07 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Part of epic #20 · Design: DESIGN.md
Context
Pansy ships as one static binary: the Vite production build is embedded into the Go binary with
embed.FSand served with an SPA fallback. This issue wires that up plus the Makefile that makes dev and release builds one command each.Scope
internal/webdist/dist.go://go:embed all:distexposing the built frontend. Commit a minimal placeholderdist/index.htmlsogo buildworks before/without a web build (the Makefile overwrites it).internal/api/spa.go: serve embedded static files; any non-/apipath with no matching file falls back toindex.html(client-side routing deep links must work). Correct content types; sensible cache headers (hashed assets long-lived,index.htmlno-cache).Makefile:make web—cd web && npm ci && npm run build, then syncweb/dist→internal/webdist/dist.make build—make web+CGO_ENABLED=0 go build -o pansy ./cmd/pansy.make dev— run the Go API server andvite devtogether (or document running them in two terminals).make test—go test ./...andcd web && npx vitest run(if tests exist yet).Out of scope
Key files & patterns
DESIGN.md§ Backend layout.Dependencies
Blocked by #1 (Go server) and #2 (web app).
Acceptance criteria
make buildproduces a single binary with no cgo (file pansy/ build withCGO_ENABLED=0).http://localhost:8080/gardensdirectly (deep link) loads the React shell via the SPA fallback;/api/v1/healthzstill returns JSON.make devgives a working iteration loop with the Vite proxy.