The /seed-lots route group has no API-level tests — the exact gap the journal routes shipped through #83

Closed
opened 2026-07-21 22:09:39 +00:00 by steve · 0 comments
Owner

CLAUDE.md, written after the journal incident:

Anything addressed by its own id needs an API-level test through the router. Service tests can't see a route that was never registered — PATCH/DELETE /journal/:id once shipped fully implemented, fully unit-tested, and completely unreachable.

/seed-lots is currently in that state. Five routes (internal/api/api.go:181-186), five handlers (internal/api/seed_lots.go:84,102,116,129,156), and no internal/api/seed_lots_test.go — the only handler file without a sibling test.

Service coverage is good (internal/service/seed_lots_test.go, 519 lines), which is exactly what made journal feel covered too. Service tests cannot see an unregistered route, a wrong :param name, or a missing middleware.

This matters more than average for seed lots because they carry two invariants a broken route would silently violate:

  • remaining is derived, never stored (DESIGN.md) — a mis-wired route could return stale or wrong counts
  • lots are private to their owner and deliberately never shared along with a garden — a missing ACL check leaks purchases

Two smaller siblings in the same category

  • GET /gardens/:id/years (api.go:95) — no API test. Drives the season picker.
  • GET /capabilities (api.go:59,204) — no API test. It gates whether the Assistant tab renders at all (GardenEditorPage.tsx:393), and its documented purpose is the subtle distinction "report whether the runner BUILT, not whether it was configured". That distinction is untested, and #79 is about to make this endpoint dynamic — worth having a test before that lands, not after.

Shape

internal/api/journal_test.go is the model to copy — it walks the full lifecycle through the router, which is what caught the original bug.

CLAUDE.md, written after the journal incident: > **Anything addressed by its own id needs an API-level test through the router.** Service tests can't see a route that was never registered — PATCH/DELETE `/journal/:id` once shipped fully implemented, fully unit-tested, and completely unreachable. `/seed-lots` is currently in that state. Five routes (`internal/api/api.go:181-186`), five handlers (`internal/api/seed_lots.go:84,102,116,129,156`), and **no `internal/api/seed_lots_test.go`** — the only handler file without a sibling test. Service coverage is good (`internal/service/seed_lots_test.go`, 519 lines), which is exactly what made journal feel covered too. Service tests cannot see an unregistered route, a wrong `:param` name, or a missing middleware. This matters more than average for seed lots because they carry two invariants a broken route would silently violate: - `remaining` is **derived**, never stored (DESIGN.md) — a mis-wired route could return stale or wrong counts - lots are **private to their owner** and deliberately never shared along with a garden — a missing ACL check leaks purchases ## Two smaller siblings in the same category - **`GET /gardens/:id/years`** (`api.go:95`) — no API test. Drives the season picker. - **`GET /capabilities`** (`api.go:59,204`) — no API test. It gates whether the Assistant tab renders at all (`GardenEditorPage.tsx:393`), and its documented purpose is the subtle distinction "report whether the runner BUILT, not whether it was configured". That distinction is untested, and #79 is about to make this endpoint dynamic — worth having a test before that lands, not after. ## Shape `internal/api/journal_test.go` is the model to copy — it walks the full lifecycle through the router, which is what caught the original bug.
steve closed this issue 2026-07-22 02:53:13 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: steve/pansy#83