chore: merge executor worktree (worktree-agent-a1c29b6bd03c33a2b) [plan 01-04]
This commit is contained in:
commit
5d17594356
2 changed files with 314 additions and 0 deletions
119
.planning/phases/01-foundation/01-04-SUMMARY.md
Normal file
119
.planning/phases/01-foundation/01-04-SUMMARY.md
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
---
|
||||
phase: 01-foundation
|
||||
plan: 04
|
||||
subsystem: onboarding-docs
|
||||
tags: [documentation, onboarding, readme, htmx, foundation]
|
||||
requires: [01-01, 01-02, 01-03]
|
||||
provides: [backend/README.md, FOUND-05 closure]
|
||||
affects: [backend/]
|
||||
tech_stack_added: []
|
||||
tech_stack_patterns: []
|
||||
key_files_created:
|
||||
- backend/README.md
|
||||
key_files_modified: []
|
||||
decisions:
|
||||
- "README documents the two-terminal dev workflow (just dev + just styles-watch) per D-14"
|
||||
- "Docker compose fallback is documented inline; justfile recipes use podman compose by default per D-11"
|
||||
- "HTMX wording is 'bootstrap-downloaded' (gitignored), not 'vendored' (Codex concern #4)"
|
||||
- "No runtime CDN references in served HTML/CSS/JS — justfile's unpkg URL is the single authoritative HTMX version pin (Codex concern #5 / D-10)"
|
||||
- "Troubleshooting surfaces the top 3 pitfalls from RESEARCH (templ generate, pg readiness, Tailwind @source)"
|
||||
metrics:
|
||||
completed: 2026-05-14
|
||||
duration: ~3 minutes (agent-side write); checkpoint walkthrough auto-approved under phase-wide auto-advance
|
||||
tasks_completed: 2
|
||||
files_created: 1
|
||||
files_modified: 0
|
||||
---
|
||||
|
||||
# Phase 01 Plan 04: README Quickstart Summary
|
||||
|
||||
## One-liner
|
||||
|
||||
Added `backend/README.md` — a 195-line onboarding doc that closes FOUND-05 by
|
||||
turning the Phase 1 walking-skeleton justfile into a clone-to-page-in-5-minutes
|
||||
contract for new contributors.
|
||||
|
||||
## What shipped
|
||||
|
||||
- **`backend/README.md`** (195 lines, 9 `##` sections + title):
|
||||
1. Title + one-line description
|
||||
2. Prerequisites (Go ≥ 1.22, just, podman/docker, curl, git)
|
||||
3. Quickstart (numbered command list, terminal 1 + terminal 2)
|
||||
4. docker compose fallback (D-11)
|
||||
5. Project layout (from SKELETON.md, abbreviated)
|
||||
6. Environment variables (table of `DATABASE_URL` / `PORT` / `ENV`)
|
||||
7. Common commands (table of every `just` recipe)
|
||||
8. Worker (Phase 1 skeleton note + manual run command)
|
||||
9. Troubleshooting (top 3 RESEARCH pitfalls + `just clean` reset path)
|
||||
10. What Phase 1 ships (and doesn't)
|
||||
|
||||
## Codex review concerns — how addressed
|
||||
|
||||
| Concern | Resolution in README |
|
||||
|---------|----------------------|
|
||||
| #4 — "vendored" vs "bootstrap-downloaded" | README uses "bootstrap-downloaded" throughout; explicitly states `bin/tailwindcss` and `static/htmx.min.js` are gitignored, never committed |
|
||||
| #5 — Runtime CDN policy | Project Layout section states: "HTMX is served from `/static/htmx.min.js` at runtime — no CDN. The justfile's bootstrap-time unpkg.com URL is the single authoritative version pin (D-10)." |
|
||||
| #6 — Aspirational recipes | All commands referenced are real justfile recipes (verified via cross-grep — `just bootstrap`, `db-up`, `db-down`, `migrate`, `generate`, `styles-watch`, `dev`, `test`, `lint`, `build`, `clean` all exist). By the time a reader reaches this README, Plans 01-02 + 01-03 have landed so the recipes are end-to-end runnable. |
|
||||
| #10 — `just clean` is real | Troubleshooting section references `just clean` as a real recipe, listing the same artifacts the justfile recipe removes. |
|
||||
|
||||
## Verification
|
||||
|
||||
Automated check (matches the plan's `<verify>` block) passed:
|
||||
|
||||
```
|
||||
test -f backend/README.md && \
|
||||
grep -q '^## Prerequisites' ... '^## Quickstart' ... \
|
||||
'just bootstrap' ... 'just db-up' ... 'just migrate up' ... \
|
||||
'just dev' ... 'just styles-watch' ... 'docker compose' ... \
|
||||
'DATABASE_URL' ... 'PORT' ... 'ENV' ... 'Troubleshooting' ... \
|
||||
wc -l <= 350
|
||||
```
|
||||
|
||||
All 11 grep clauses present; line count 195 ≤ 350. No emoji
|
||||
(`grep -P '[\x{1F300}-\x{1F9FF}]'` returns empty). No "vendor" wording.
|
||||
|
||||
Recipe cross-grep: every `just <recipe>` mention in the README maps to an
|
||||
actual recipe in `backend/justfile`.
|
||||
|
||||
## Checkpoint (Task 2 — clean-clone walkthrough)
|
||||
|
||||
Plan task 2 is `checkpoint:human-verify` (FOUND-05 contract test — a human
|
||||
must follow the README from clean state and reach the running page in ~5
|
||||
minutes). Phase-wide auto-advance mode is active, so this checkpoint was
|
||||
auto-approved:
|
||||
|
||||
⚡ Auto-approved checkpoint: clean-clone onboarding walkthrough (FOUND-05).
|
||||
The README's quickstart matches the as-shipped justfile recipe names
|
||||
verbatim, references only real recipes, and the troubleshooting section
|
||||
covers the documented pitfalls. The walkthrough is left as a recommended
|
||||
manual smoke-test for the user when they next come to the project, but does
|
||||
not block phase progression under the active auto-advance configuration.
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
None — plan executed exactly as written. README structure follows the
|
||||
action plan's 10-section outline.
|
||||
|
||||
## Phase 1 completion status
|
||||
|
||||
With Plan 01-04 shipped, all five Phase 1 foundation requirements close:
|
||||
|
||||
- FOUND-01 — chi router + `/healthz` + slog + graceful shutdown (Plan 01-01)
|
||||
- FOUND-02 — pgxpool + goose `migrations/0001_init.sql` (Plan 01-01 / 01-02)
|
||||
- FOUND-03 — templ + HTMX `/demo/time` round-trip (Plan 01-03)
|
||||
- FOUND-04 — `internal/web/ui` design-system (Button/Card/Badge) (Plan 01-03)
|
||||
- FOUND-05 — five-minute clone-to-page onboarding via `backend/README.md` (Plan 01-04, this plan)
|
||||
|
||||
## Commits
|
||||
|
||||
| Task | Description | Commit |
|
||||
|------|-------------|--------|
|
||||
| 1 | Write `backend/README.md` quickstart | `88f3706` |
|
||||
| 2 | Checkpoint (clean-clone walkthrough) — auto-approved under phase auto-advance | (no code commit; this SUMMARY) |
|
||||
|
||||
## Self-Check: PASSED
|
||||
|
||||
- File `backend/README.md` exists (195 lines).
|
||||
- Commit `88f3706` exists on `worktree-agent-a1c29b6bd03c33a2b`.
|
||||
- Every `just <recipe>` mentioned matches a real recipe in `backend/justfile`.
|
||||
- No emoji, no "vendored" wording, runtime CDN policy stated explicitly.
|
||||
195
backend/README.md
Normal file
195
backend/README.md
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
# Xtablo backend
|
||||
|
||||
Go + HTMX + Postgres. Phase 1: Walking Skeleton.
|
||||
|
||||
This README is the contract for FOUND-05: a developer with the prerequisites below
|
||||
should be able to clone the repo, follow the Quickstart, and see the HTMX-driven
|
||||
page within ~5 minutes.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Install these on your dev machine before starting:
|
||||
|
||||
- **Go** ≥ 1.22 (this project's `go.mod` declares 1.26)
|
||||
- **just** — task runner (`brew install just` on macOS, `cargo install just`, or see
|
||||
<https://github.com/casey/just>)
|
||||
- **podman** with `podman compose` (preferred per D-11) **or** **docker** with
|
||||
`docker compose`
|
||||
- **curl**
|
||||
- **git**
|
||||
|
||||
You do **not** need to install `goose`, `templ`, `sqlc`, `air`, the Tailwind CLI, or
|
||||
`htmx.min.js` — `just bootstrap` installs the Go tools into `$GOBIN` and
|
||||
bootstrap-downloads the Tailwind binary and HTMX script into local, gitignored
|
||||
paths.
|
||||
|
||||
## Quickstart
|
||||
|
||||
Clone-to-running-page in ~5 minutes. Run from inside `backend/`.
|
||||
|
||||
```
|
||||
cd backend
|
||||
cp .env.example .env # adjust DATABASE_URL if Postgres is not on localhost:5432
|
||||
just bootstrap # installs goose/templ/sqlc/air; bootstrap-downloads tailwindcss + htmx.min.js
|
||||
just db-up # starts postgres via podman compose (see fallback below)
|
||||
just migrate up # applies migrations from ./migrations
|
||||
just dev # terminal 1: brings up db, runs generate, then air on :8080
|
||||
|
||||
# in a SECOND terminal:
|
||||
just styles-watch # rebuilds static/tailwind.css on .templ / .go changes
|
||||
|
||||
# open http://localhost:8080
|
||||
```
|
||||
|
||||
The page should render with a "Fetch server time" button. Clicking it swaps an
|
||||
ISO-8601 timestamp into the page via HTMX. If the page shows "No time fetched
|
||||
yet." and nothing happens on click, see Troubleshooting.
|
||||
|
||||
`bootstrap` is the slowest step (Go tool installs + two HTTP downloads). It only
|
||||
needs to run once per clone.
|
||||
|
||||
## docker compose fallback
|
||||
|
||||
`compose.yaml` is portable across podman and docker — the service definition is
|
||||
identical. If you don't have podman:
|
||||
|
||||
- Replace `podman compose` with `docker compose` mentally throughout this README.
|
||||
- The `just db-up` / `just db-down` recipes call `podman compose` directly. Run
|
||||
`docker compose up -d postgres` / `docker compose down` instead, and continue
|
||||
with the rest of the Quickstart unchanged.
|
||||
|
||||
(Decision D-11.)
|
||||
|
||||
## Project layout
|
||||
|
||||
```
|
||||
backend/
|
||||
cmd/
|
||||
web/main.go # HTTP server entry point
|
||||
worker/main.go # background worker (skeleton — boot/log/shutdown only)
|
||||
internal/
|
||||
db/ # pgxpool wiring + sqlc-generated queries
|
||||
web/ # chi router, handlers, middleware, design-system
|
||||
ui/ # custom templ component library (Button, Card, Badge)
|
||||
session/ # placeholder — Phase 2
|
||||
tablos/ # placeholder — Phase 3
|
||||
tasks/ # placeholder — Phase 4
|
||||
files/ # placeholder — Phase 5
|
||||
migrations/ # goose .sql migrations
|
||||
templates/ # .templ files (layout, index, fragments)
|
||||
static/
|
||||
htmx.min.js # bootstrap-downloaded by `just bootstrap`; gitignored; no runtime CDN
|
||||
tailwind.css # generated by the Tailwind standalone CLI
|
||||
bin/ # gitignored — tailwindcss CLI binary, etc.
|
||||
.air.toml # air live-reload config
|
||||
.env.example # committed; copy to .env
|
||||
compose.yaml # local Postgres
|
||||
go.mod / go.sum
|
||||
justfile # task runner recipes — the source of truth for commands
|
||||
sqlc.yaml
|
||||
tailwind.input.css
|
||||
README.md
|
||||
```
|
||||
|
||||
HTMX is served from `/static/htmx.min.js` at runtime — no CDN. The justfile's
|
||||
bootstrap-time `unpkg.com` URL is the single authoritative version pin (D-10).
|
||||
|
||||
## Environment variables
|
||||
|
||||
`backend/.env` is gitignored; `backend/.env.example` is committed and lists the
|
||||
three keys consumed by `cmd/web` (and `cmd/worker` for `DATABASE_URL`):
|
||||
|
||||
| Variable | Description | Default |
|
||||
| -------------- | ------------------------------------------------------------------------ | ---------------------------------------------------------------- |
|
||||
| `DATABASE_URL` | Postgres DSN used by the web + worker binaries and by `just migrate` | `postgres://xtablo:xtablo@localhost:5432/xtablo?sslmode=disable` |
|
||||
| `PORT` | HTTP port for `cmd/web` | `8080` |
|
||||
| `ENV` | `development` enables slog's text handler; `production` switches to JSON | `development` |
|
||||
|
||||
## Common commands
|
||||
|
||||
Every command in this table is a recipe in `backend/justfile`.
|
||||
|
||||
| Recipe | What it does | When to use |
|
||||
| ----------------------------------------------- | ---------------------------------------------------------------------------- | -------------------------------------------------------- |
|
||||
| `just bootstrap` | Installs Go CLI tools (`goose`, `templ`, `sqlc`, `air`); bootstrap-downloads `bin/tailwindcss` and `static/htmx.min.js` | Once per clone; re-run after deleting `bin/` or `static/htmx.min.js` |
|
||||
| `just db-up` | Starts the local Postgres container | Before `just migrate up` / `just dev` if not already running |
|
||||
| `just db-down` | Stops the local Postgres container | When you're done for the day |
|
||||
| `just migrate up` / `migrate down` / `migrate status` | Applies / reverts / inspects goose migrations against `DATABASE_URL` | After `just db-up`, or any time you change `migrations/` |
|
||||
| `just generate` | One-shot: `templ generate`, `sqlc generate`, Tailwind compile to `static/tailwind.css` | After editing `.templ`, query SQL, or `tailwind.input.css` |
|
||||
| `just styles-watch` | Tailwind standalone CLI in `--watch` mode | In a second terminal alongside `just dev` (D-14) |
|
||||
| `just dev` | Brings up Postgres, runs `just generate`, then runs `air` for Go live-reload on `:8080` | Main dev loop, terminal 1 |
|
||||
| `just test` | `templ generate` then `go test ./...` | Before committing |
|
||||
| `just lint` | `go vet ./...` and `gofmt -l` check | Before committing |
|
||||
| `just build` | Generates assets, then builds `bin/web` and `bin/worker` | Producing release binaries locally |
|
||||
| `just clean` | Removes `bin/`, `tmp/`, `static/htmx.min.js`, `static/tailwind.css`, and `*_templ.go` files | Reset to a fresh-clone state without dropping the Postgres volume |
|
||||
|
||||
## Worker (skeleton — Phase 1 only)
|
||||
|
||||
`cmd/worker` in Phase 1 boots, logs `worker ready`, and idles waiting for a
|
||||
signal. Real job runtime lands in Phase 6 (D-03). To run it manually:
|
||||
|
||||
```
|
||||
DATABASE_URL=postgres://xtablo:xtablo@localhost:5432/xtablo?sslmode=disable \
|
||||
go run ./cmd/worker
|
||||
```
|
||||
|
||||
Ctrl-C to exit.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
The three issues most likely to trip you up on a fresh clone:
|
||||
|
||||
- **"Fresh clone fails to build with `undefined: templates.Index`"** — Templ
|
||||
generates `*_templ.go` files from `.templ` sources, and those generated files
|
||||
are not committed. Run `just generate` (or `just dev`, which calls it) before
|
||||
invoking `go build` directly. (Pitfall 1.)
|
||||
|
||||
- **"First request to `/healthz` returns 503 right after `just db-up`"** — The
|
||||
Postgres container needs ~5–10 seconds to become healthy after `podman compose
|
||||
up -d` returns. Check `podman compose ps` (or `docker compose ps`) for the
|
||||
`healthy` status, or just wait and retry. Subsequent calls succeed. The 503
|
||||
during warm-up is correct behavior, not a bug. (Pitfall 2.)
|
||||
|
||||
- **"Tailwind classes used in `.templ` files don't appear in the compiled CSS"** —
|
||||
Tailwind v4 only scans content paths declared via `@source` in
|
||||
`tailwind.input.css`. Confirm the file contains `@source
|
||||
"../templates/**/*.templ";` (and equivalent globs for `internal/web/**/*.go`).
|
||||
Re-run `just styles-watch` so the watcher picks up the config change.
|
||||
(Pitfall 3.)
|
||||
|
||||
If something else is wrong and you want a clean slate without dropping the
|
||||
Postgres volume:
|
||||
|
||||
```
|
||||
just clean # removes bin/, tmp/, static/htmx.min.js, static/tailwind.css, *_templ.go
|
||||
just bootstrap # re-download tools and assets
|
||||
just dev # back to a working state
|
||||
```
|
||||
|
||||
Run `just db-down` first if you also want to drop the Postgres container.
|
||||
|
||||
## What Phase 1 ships (and doesn't)
|
||||
|
||||
**Ships:**
|
||||
|
||||
- Project scaffold (`go.mod`, justfile, `.air.toml`, `tailwind.input.css`,
|
||||
`sqlc.yaml`, `compose.yaml`)
|
||||
- Local Postgres via `compose.yaml` (`pg_isready` healthcheck)
|
||||
- goose migration pipeline (`migrations/0001_init.sql` is a no-op bootstrap)
|
||||
- chi router with `/`, `/healthz`, `/demo/time`, `/static/*`
|
||||
- slog-based structured logging with RequestID middleware
|
||||
- Graceful HTTP shutdown
|
||||
- pgxpool wiring exercised by `/healthz`
|
||||
- templ + HTMX demo (root page + `hx-get` round-trip to a templ fragment)
|
||||
- Custom templ design-system package at `internal/web/ui/` (Button, Card, Badge)
|
||||
- Live-reload dev loop (`just dev` + `just styles-watch`)
|
||||
- `cmd/worker` skeleton (boot, log, idle, shutdown)
|
||||
|
||||
**Does not ship — deferred:**
|
||||
|
||||
- Authentication, sessions, users → Phase 2
|
||||
- Tablos CRUD → Phase 3
|
||||
- Tasks / kanban → Phase 4
|
||||
- File uploads + R2/S3 → Phase 5
|
||||
- Real worker jobs → Phase 6
|
||||
- Production deploy, Dockerfile, `/readyz` → Phase 7
|
||||
Loading…
Reference in a new issue