F-09: Stimulus bootstrap + main.go wiring + docker-compose demo (#12) #12

Merged
zombor merged 2 commits from bd-bookshelf-qqz.9 into main 2026-05-20 18:48:20 +00:00
Owner

Scope

This PR builds on F-09 (Stimulus bootstrap) by adding the full end-to-end server wiring and verifying the demo runs via docker compose.

Changes beyond the original F-09 commit

  1. Rebase onto main — picks up F-04 (internal/db: resilient MySQL connection + golang-migrate runner + Grimmory baseline schema, 72 tables).

  2. cmd/bookshelf/main.go — full app entrypoint

    • Parses config via internal/config.Load (flags → env → file → defaults)
    • Builds structured logger and Prometheus registry
    • Opens DB with pool via db.Open, retries ping with exponential backoff
    • Runs migrations via db.RunMigrations before serving (fail-fast if broken)
    • Computes AssetVersion from SHA256 of embedded static files
    • Builds template renderer from embedded templates
    • Registers routes: GET /healthz, GET /metrics, GET /static/, GET /
    • / serves rendered base.html+home.html with BaseData{AssetVersion, TraceID, Title}; JSON fallback for API clients
    • Middleware chain: Recoverer → MetricsRecorder → RequestLogger → TraceID → mux
    • Graceful shutdown via signal.NotifyContext + 30s shutdown timeout
  3. docker-compose.yml — corrected service wiring

    • Renamed service dbmysql to match DSN host
    • Correct env vars: BOOKSHELF_DSN, BOOKSHELF_HTTP_ADDR, BOOKSHELF_LOG_LEVEL, BOOKSHELF_LOG_FORMAT, BOOKSHELF_DATA_DIR
    • depends_on: mysql: condition: service_healthy
    • ./data:/data volume mount
  4. .gitignore — anchored /bookshelf pattern to repo root so cmd/bookshelf/ is no longer incorrectly excluded from staging.

Docker compose verify

docker compose up --build -d
curl -sf http://localhost:8080/healthz   # → "ok"
curl -sf http://localhost:8080/ | grep 'data-controller="hello"'   # → present
curl -sf http://localhost:8080/ | grep 'stimulus.js?v='            # → present
curl -sf http://localhost:8080/ | grep 'app.js?v='                 # → present
docker compose exec -T mysql mysql -uroot -proot -e \
  "SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA='bookshelf' AND TABLE_NAME='library';" bookshelf
# → COUNT(*) = 1 (migration applied)
docker compose down -v --remove-orphans

Smoke verify log output

{"time":"2026-05-20T18:40:59.916Z","level":"INFO","msg":"db connected","dsn_masked":"root:***@tcp(mysql:3306)/bookshelf?..."}
{"time":"2026-05-20T18:41:00.606Z","level":"INFO","msg":"migrations applied","duration_ms":690,"version":1,"dirty":false,"version_err":null}
{"time":"2026-05-20T18:41:00.607Z","level":"INFO","msg":"bookshelf starting","version":"dev","addr":":8080"}
{"time":"2026-05-20T18:41:03.254Z","level":"INFO","msg":"request","method":"GET","path":"/healthz","status":200,"duration_ms":0}
{"time":"2026-05-20T18:41:08.480Z","level":"INFO","msg":"request","method":"GET","path":"/","status":200,"duration_ms":0,"bytes_written":701}

All checks passed: HEALTHZ OK, STIMULUS WIRED OK, STIMULUS SCRIPT TAG OK, APP SCRIPT TAG OK, library table present.

Run locally

git checkout bd-bookshelf-qqz.9
docker compose up --build       # starts mysql + app; app waits for mysql healthcheck
# app available at http://localhost:8080
# home page shows Stimulus hello_controller wired up

Test results

  • go vet ./... — clean
  • make test — 119 specs across 9 suites, all green (includes DB integration tests via testcontainers)
  • make coverage — 100.0% on internal/ + static/

Closes bead bookshelf-qqz.9 on merge.

## Scope This PR builds on F-09 (Stimulus bootstrap) by adding the full end-to-end server wiring and verifying the demo runs via `docker compose`. ### Changes beyond the original F-09 commit 1. **Rebase onto main** — picks up F-04 (internal/db: resilient MySQL connection + golang-migrate runner + Grimmory baseline schema, 72 tables). 2. **`cmd/bookshelf/main.go` — full app entrypoint** - Parses config via `internal/config.Load` (flags → env → file → defaults) - Builds structured logger and Prometheus registry - Opens DB with pool via `db.Open`, retries ping with exponential backoff - Runs migrations via `db.RunMigrations` before serving (fail-fast if broken) - Computes `AssetVersion` from SHA256 of embedded static files - Builds template renderer from embedded templates - Registers routes: `GET /healthz`, `GET /metrics`, `GET /static/`, `GET /` - `/` serves rendered `base.html`+`home.html` with `BaseData{AssetVersion, TraceID, Title}`; JSON fallback for API clients - Middleware chain: Recoverer → MetricsRecorder → RequestLogger → TraceID → mux - Graceful shutdown via `signal.NotifyContext` + 30s shutdown timeout 3. **`docker-compose.yml` — corrected service wiring** - Renamed service `db` → `mysql` to match DSN host - Correct env vars: `BOOKSHELF_DSN`, `BOOKSHELF_HTTP_ADDR`, `BOOKSHELF_LOG_LEVEL`, `BOOKSHELF_LOG_FORMAT`, `BOOKSHELF_DATA_DIR` - `depends_on: mysql: condition: service_healthy` - `./data:/data` volume mount 4. **`.gitignore`** — anchored `/bookshelf` pattern to repo root so `cmd/bookshelf/` is no longer incorrectly excluded from staging. ## Docker compose verify ```bash docker compose up --build -d curl -sf http://localhost:8080/healthz # → "ok" curl -sf http://localhost:8080/ | grep 'data-controller="hello"' # → present curl -sf http://localhost:8080/ | grep 'stimulus.js?v=' # → present curl -sf http://localhost:8080/ | grep 'app.js?v=' # → present docker compose exec -T mysql mysql -uroot -proot -e \ "SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA='bookshelf' AND TABLE_NAME='library';" bookshelf # → COUNT(*) = 1 (migration applied) docker compose down -v --remove-orphans ``` ### Smoke verify log output ``` {"time":"2026-05-20T18:40:59.916Z","level":"INFO","msg":"db connected","dsn_masked":"root:***@tcp(mysql:3306)/bookshelf?..."} {"time":"2026-05-20T18:41:00.606Z","level":"INFO","msg":"migrations applied","duration_ms":690,"version":1,"dirty":false,"version_err":null} {"time":"2026-05-20T18:41:00.607Z","level":"INFO","msg":"bookshelf starting","version":"dev","addr":":8080"} {"time":"2026-05-20T18:41:03.254Z","level":"INFO","msg":"request","method":"GET","path":"/healthz","status":200,"duration_ms":0} {"time":"2026-05-20T18:41:08.480Z","level":"INFO","msg":"request","method":"GET","path":"/","status":200,"duration_ms":0,"bytes_written":701} ``` All checks passed: HEALTHZ OK, STIMULUS WIRED OK, STIMULUS SCRIPT TAG OK, APP SCRIPT TAG OK, library table present. ## Run locally ```bash git checkout bd-bookshelf-qqz.9 docker compose up --build # starts mysql + app; app waits for mysql healthcheck # app available at http://localhost:8080 # home page shows Stimulus hello_controller wired up ``` ## Test results - `go vet ./...` — clean - `make test` — 119 specs across 9 suites, all green (includes DB integration tests via testcontainers) - `make coverage` — 100.0% on internal/ + static/ Closes bead bookshelf-qqz.9 on merge.
F-09: Stimulus bootstrap + demo controller (bookshelf-qqz.9)
All checks were successful
/ Lint (pull_request) Successful in 1m8s
/ Test (pull_request) Successful in 1m17s
/ Coverage (pull_request) Successful in 59s
1877903719
- Vendor @hotwired/stimulus 3.2.2 UMD build at static/js/vendor/stimulus.js
  with MIT attribution comment
- Replace app.js placeholder with Stimulus Application bootstrap that
  auto-registers window.*Controller globals via safe tryRegister lookup
- Add hello_controller.js demo controller (logs on connect, exposes
  window.HelloController)
- Add three <script defer> tags to templates/layouts/base.html
- Add data-controller="hello" to home.html section wrapper

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
zombor force-pushed bd-bookshelf-qqz.9 from 1877903719
All checks were successful
/ Lint (pull_request) Successful in 1m8s
/ Test (pull_request) Successful in 1m17s
/ Coverage (pull_request) Successful in 59s
to 906f191f33
All checks were successful
/ Lint (pull_request) Successful in 1m11s
/ Test (pull_request) Successful in 1m39s
/ Coverage (pull_request) Successful in 1m21s
2026-05-20 18:41:50 +00:00
Compare
zombor changed title from F-09: Stimulus bootstrap + demo controller (bookshelf-qqz.9) to F-09: Stimulus bootstrap + main.go wiring + docker-compose demo (#12) 2026-05-20 18:42:22 +00:00
zombor merged commit 902971bd64 into main 2026-05-20 18:48:20 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
zombor/pergamum!12
No description provided.