4.6 KiB
Phase 1 — Frontend Foundation (GOAT + Postgres)
Plan for OpenSpec change frontend-foundation (proposal/design/specs/tasks in openspec/changes/frontend-foundation/).
Context
WhereWoof is a return-tag platform (not a tracker). This change builds the GOAT front-end foundation: a Go app serving owner auth, tag setup/management, and the public tag page, against a single shared Postgres. Laravel admin, scan flow (geolocation/SMS), billing, and deployment are later phases.
Current state: greenfield. frontend/ and admin/ are empty. Go 1.26.2 installed on .27. sqlc not installed (dev-only codegen — install on .27, generated code committed). psql not installed anywhere (ad-hoc SQL via docker exec on .13). .13 reachable over SSH with Docker (sam user). No long-term installs on .27 — everything runtime (DB + binary) lives on .13.
Execution style (agreed): master/worker — main pi session orchestrates; subagents do chunks (database for schema/queries, coder-pro for Go code, code-analysis for review).
Approach
frontend/Go module (module pathwherewoof/frontend, stdlibnet/http+ Go 1.22+ ServeMux, no framework).- Layout:
main.go;internal/db(pgx pool + queries);internal/auth(sessions + bcrypt);internal/handlers;templates/(html/template);static/. db/schema.sqlat repo root = canonical schema (users, tags, scans). Applied via a small embedded Go migrator (make db-up) — no psql dependency. Ad-hoc SQL viamake psql→ssh sam@192.168.20.13 docker exec -i wherewoof-db psql ....- Auth: gorilla/sessions cookie store (HttpOnly, SameSite=Lax,
SESSION_SECRETenv), bcrypt passwords,RequireAuthmiddleware,currentUserfor templates. - Routes (Phase 1 subset of
where_woof.md):/,/t/{tag_code},/register,/login,/logout,/account,/account/tags(add),/account/tags/{id}/edit,/account/tags/{id}/delete. - Templates:
base.html+ per-page; HTMX partials for account list/edit; Alpine for small behaviours; Tailwind via CDN. - Seed:
cmd/seedinsertsTEST000001..TEST000010tag codes. - Postgres (dev + prod, on .13): dedicated
wherewoof-dbPostgres 16 container on .13 (~/Docker/Containers/wherewoof-db/docker-compose.yml, port 5433→5434 (5433 = Langfuse PG, 5432 = ai-resume PG), named volume for data, app userwherewoof). Dev on .27 connects over LAN:postgres://wherewoof:<pw>@192.168.20.13:5434/wherewoof. Same DB host from day one — no .27 installs.
Files to create / modify
frontend/go.mod,frontend/main.gofrontend/internal/db/db.go,queries.sql(+ generated code)frontend/internal/auth/session.go,passwords.gofrontend/internal/handlers/auth.go,tags.go,tag_page.gofrontend/templates/base.html,index.html,register.html,login.html,account.html,tag-edit.html,tag-public.html,not-found.htmlfrontend/static/style.cssfrontend/cmd/seed/main.godb/schema.sqlMakefile,sqlc.yaml- (infra, on .13, not in repo):
~/Docker/Containers/wherewoof-db/docker-compose.yml
Reuse
openspec/changes/frontend-foundation/specs/*/spec.md— each requirement is a test checklist.where_woof.md— endpoints table, schema v2, scan-flow context (Phase 2 reference).awesome-design.md/mockups/— styling tokens for Tailwind (optional, Phase 1 minimal).
Steps
- 1. Provision Postgres on .13:
wherewoof-dbcontainer (port 5433, volume), createwherewoofDB + app user (via SSH + docker exec) - 2. Install sqlc on .27 (
go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest); scaffold Go module + dirs;db/schema.sql; Makefile (db-up,seed,run,generate,psql) - 3. sqlc.yaml +
queries.sqlfor users/tags CRUD; generate - 4. Config +
main.gowiring (pool, router, templates, static) - 5. Auth: register (bcrypt, unique email, auto-login), login/logout, RequireAuth, currentUser
- 6. Tag management: bind by code (reject owned, 20-limit), My Tags list, edit → active, remove → unset
- 7. Public tag page: lookup, not-found page, unset prompt / active details / suspended, owner edit affordance
- 8. Base layout + Tailwind; home page
- 9. Seed; end-to-end verification of every spec scenario;
openspec validate; commit
Verification
make db-up && make seed && make run(DATABASE_URL →192.168.20.13:5433) → register → add tag (TEST000001) → edit details → public page shows details; duplicate email rejected; second account can't bind owned tag; 21st tag rejected; remove → re-bind works; unknown code → not-found page; suspended tag → unavailable.- Run
openspec validate frontend-foundation; commit code + artifacts.