# 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 path `wherewoof/frontend`, stdlib `net/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.sql`** at repo root = canonical schema (users, tags, scans). Applied via a small embedded Go migrator (`make db-up`) — no psql dependency. Ad-hoc SQL via `make psql` → `ssh sam@192.168.20.13 docker exec -i wherewoof-db psql ...`.
- **Auth**: gorilla/sessions cookie store (HttpOnly, SameSite=Lax, `SESSION_SECRET` env), bcrypt passwords, `RequireAuth` middleware, `currentUser` for 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/seed` inserts `TEST000001..TEST000010` tag codes.
- **Postgres (dev + prod, on .13)**: dedicated `wherewoof-db` Postgres 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 user `wherewoof`). 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.go`
- `frontend/internal/db/db.go`, `queries.sql` (+ generated code)
- `frontend/internal/auth/session.go`, `passwords.go`
- `frontend/internal/handlers/auth.go`, `tags.go`, `tag_page.go`
- `frontend/templates/base.html`, `index.html`, `register.html`, `login.html`, `account.html`, `tag-edit.html`, `tag-public.html`, `not-found.html`
- `frontend/static/style.css`
- `frontend/cmd/seed/main.go`
- `db/schema.sql`
- `Makefile`, `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

- [x] 1. Provision Postgres on .13: `wherewoof-db` container (port 5433, volume), create `wherewoof` DB + app user (via SSH + docker exec)
- [x] 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`)
- [x] 3. sqlc.yaml + `queries.sql` for users/tags CRUD; generate
- [x] 4. Config + `main.go` wiring (pool, router, templates, static)
- [x] 5. Auth: register (bcrypt, unique email, auto-login), login/logout, RequireAuth, currentUser
- [x] 6. Tag management: bind by code (reject owned, 20-limit), My Tags list, edit → active, remove → unset
- [x] 7. Public tag page: lookup, not-found page, unset prompt / active details / suspended, owner edit affordance
- [x] 8. Base layout + Tailwind; home page
- [x] 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.
