Implement Use Case
Instructions
Implement $ARGUMENTS in Go: net/http handlers, templ views with htmx, and sqlc for data
access. $ARGUMENTS can be a use case (UC-XXX), a technical task (TT-XXX), or a bug fix
(BUG-XXX). Write unit tests alongside the implementation. Integration tests (/integration-test) and
e2e tests (/playwright-test) are separate skills.
Use the context7 MCP server to look up templ, htmx, sqlc, and pgx documentation when needed.
DO NOT
- Create integration or e2e tests (use dedicated testing skills instead)
- Write SQL strings in Go code — every query lives in
db/queries/*.sql and is generated by sqlc
- Edit generated code (
internal/db/, *_templ.go) — change the source and regenerate
- Put business logic in handlers or
.templ files — handlers parse, validate, call the service, and render
- Write JavaScript beyond htmx attributes unless the design artifact requires client behaviour htmx cannot express
- Add a dependency the standard library, templ, htmx, sqlc, or pgx already covers
- Introduce an interface with a single implementation — the only accepted exception is sqlc's
db.Querier, which unit tests fake
- Make implementation decisions without documenting their provenance (EXPLICIT vs INFERRED)
- Over-engineer — implement only what the specification requires. No speculative abstractions, unnecessary indirection, premature generalisation, or features not in the spec. Three similar lines of code are better than a premature abstraction. If a simple approach satisfies the requirement, use it.
Nexa Rules Gate
Read and follow ${CLAUDE_PLUGIN_ROOT}/shared/readiness/NEXA_RULES_GATE.md.
Worktree Gate
Read and follow ${CLAUDE_PLUGIN_ROOT}/shared/readiness/WORKTREE_GATE.md.
Project Readiness Gate
Read and follow ${CLAUDE_PLUGIN_ROOT}/shared/readiness/PROJECT_READINESS.md.
This gate checks that cross-cutting infrastructure (middleware, structured logging, security headers,
environment configuration, migrations) exists before use case implementation begins. It applies to
UC-XXX items only — TT-XXX and BUG-XXX items skip this gate.
Do not proceed with implementation until all items pass or the user explicitly waives failures.
DoR Check
- For UC-XXX: Read and follow
${CLAUDE_PLUGIN_ROOT}/shared/readiness/DEFINITION_OF_READY.md.
- For TT-XXX: Read and follow
${CLAUDE_PLUGIN_ROOT}/shared/readiness/DEFINITION_OF_READY_TT.md.
- For BUG-XXX: Read and follow
${CLAUDE_PLUGIN_ROOT}/shared/readiness/DEFINITION_OF_READY_BUG.md.
Do not proceed with implementation until all items pass or the user explicitly waives failures.
Tracking
Read and follow the Before Implementation steps in ${CLAUDE_PLUGIN_ROOT}/shared/tracking/TRACKING.md.
Test Data Conventions
- Use only
example.com for test emails and accounts (e.g., user@example.com, admin@example.com). This is an IANA-reserved domain that will never route real mail.
Workflow
- Read the specification:
- For UC-XXX: Read the use case specification from
docs/use_cases/
- For TT-XXX: Read the technical task specification from
docs/technical_tasks/
- For BUG-XXX: Read the bug report from
docs/bugs/
- Read the entity model from
docs/entity_model.md (if applicable)
- Read the design artifact from
docs/designs/ (if it exists for this UC). When a design artifact exists, the implementation must match the specified screens, layout, components, states, and navigation flow.
- Read project design rules from
docs/designs/DESIGN_RULES.md (if it exists). These are project-specific constraints — e.g., shared layout elements (header, footer, sidebar), mandatory components, or navigation patterns — that every implementation must follow. Missing a shared element specified in design rules is a defect.
- Check existing code for patterns and conventions — read
internal/web/routes.go, internal/web/layout/layout.templ, and at least one existing internal/<feature>/ package before writing a new one
- i18n Detection — check the project's
CLAUDE.md for the marker <!-- NEXA_I18N_CONFIGURED -->,
then look for an existing translation setup (internal/i18n/, message catalogs,
golang.org/x/text/message, go-i18n in go.mod). If one exists, every user-facing string in
this implementation — including validation messages — MUST go through it (/setup-i18n:
i18n.T(ctx, "namespace.key") in templ and handlers), and new keys go into all locale
catalogs. If none exists, write plain strings.
- Write the queries:
- Add named queries to
db/queries/<entity>.sql (-- name: ListItems :many, :one, :exec)
- Every table and column must already exist in
db/migrations/ — if not, stop: the schema
belongs to /db-migration, which runs before delivery
- Run
go tool templ generate && sqlc generate
- Implement the service in
internal/<feature>/service.go:
- A struct holding
db.Querier; one method per use case operation
- Business rules (
BR-XXX) live here, with a comment naming the rule
- Return domain errors (
var ErrNotFound = errors.New(...)) that handlers map to status codes
- Implement the form in
internal/<feature>/form.go:
- A struct per form, parsed from
r.PostForm
func (f CreateItemForm) Validate() map[string]string returning field -> message (a message ID when i18n is active; the view translates it); empty map means valid
- Mirror each server rule with an HTML5 attribute in the view (
required, maxlength, type="email", pattern) — client-side validation is a convenience, the server check is the authority
- Implement the handler in
internal/<feature>/handler.go:
- Methods with the
http.HandlerFunc signature; read path values with r.PathValue("id")
- Mutations:
r.ParseForm() -> Validate() -> on errors re-render the form fragment with the
submitted values and field errors, status 422 -> otherwise call the service. htmx swaps
the 422 body only because the layout's htmx-config enables it (/setup-web-middleware);
if the project's layout lacks that responseHandling entry, add it
- Render a full page for normal requests and only the fragment when
r.Header.Get("HX-Request") == "true"
- After a successful htmx mutation, respond with the updated fragment or
HX-Redirect; after a plain form post, http.Redirect with 303
- Map service errors: not found ->
404, forbidden -> 403, anything else -> log with slog and 500
- Read the signed-in user with
auth.FromContext(r.Context()) — never read the cookie or the session store again
- Implement the views in
internal/<feature>/views.templ:
- Pages wrap content in the shared layout from package
internal/web/layout — never import internal/web from a feature (import cycle)
- Every htmx target is its own templ component so handlers can render it alone
- Loading state:
hx-indicator on the triggering element
- Error state: field errors next to their inputs, a summary for non-field errors
- Empty state: an explicit component when a list has no rows
- When a design artifact exists, match the specified layout, components, states, and navigation
- When project design rules exist (read in step 4), enforce every rule — e.g., include shared layout elements, follow mandatory navigation patterns, and apply required brand guidelines
- Use labelled inputs (
<label for>), semantic headings, and buttons for actions — the E2E tests select by role and label
- Run
go tool templ generate
- Register routes in
web.NewHandler (internal/web/routes.go) with method patterns (mux.HandleFunc("POST /items", h.Create)).
Every route requires a signed-in user by default. When the spec restricts a route to a role, wrap it
on the registration line: mux.Handle("POST /items", auth.RequireRole("ADMIN")(http.HandlerFunc(h.Create))).
Add a path to auth.PublicPaths only when the spec makes it reachable without signing in.
- Write unit tests (no build tag) next to the code:
form_test.go — table-driven Validate() tests: each valid input passes, each invalid input produces the expected field error
service_test.go — a fake struct implementing db.Querier (embed db.Querier and override only the methods used); assert business rules and returned errors
handler_test.go — httptest.NewRecorder + the handler wired to a service with the fake: status codes, 422 with field errors on invalid input, fragment-only body when HX-Request: true, full layout otherwise, redirect target on success
views_test.go — render the component into a bytes.Buffer with Render(context.Background(), &buf) and assert the text the design specifies (empty-state message, error messages)
- Run
go test ./... to verify they pass
- Run the
/code-quality skill
- Verify the implementation builds with
go tool templ generate && sqlc generate && go build ./... && go vet ./...
- Document implementation decisions in a
DECISIONS.md file (or in the PR description):
- For each non-trivial decision made during implementation, record:
- Decision: What was decided
- Provenance: EXPLICIT (from spec/requirements) or INFERRED (agent reasoning)
- Source/Reasoning: Quote the source document or explain the reasoning
- INFERRED decisions are candidates for stakeholder review before merge
Post-Implementation Tracking
Read and follow the After Implementation steps in ${CLAUDE_PLUGIN_ROOT}/shared/tracking/TRACKING.md.
Resources
- Use the context7 MCP server for templ, htmx, sqlc, and pgx documentation
1---2name: implement3description: Implements use cases and fixes bugs in a Go web application: sqlc queries, services, form validation, net/http handlers, templ views with htmx, and routes. Use when the user asks to "implement a use case", "fix a bug", "build the UI", "create an endpoint", "write a handler", "write a page", or mentions Go implementation, templ, htmx, sqlc, or full-stack Go implementation.4---56# Implement Use Case78## Instructions910Implement $ARGUMENTS in Go: `net/http` handlers, `templ` views with `htmx`, and `sqlc` for data11access. $ARGUMENTS can be a use case (`UC-XXX`), a technical task (`TT-XXX`), or a bug fix12(`BUG-XXX`). Write unit tests alongside the implementation. Integration tests (`/integration-test`) and13e2e tests (`/playwright-test`) are separate skills.1415Use the context7 MCP server to look up templ, htmx, sqlc, and pgx documentation when needed.1617## DO NOT1819- Create integration or e2e tests (use dedicated testing skills instead)20- Write SQL strings in Go code — every query lives in `db/queries/*.sql` and is generated by sqlc21- Edit generated code (`internal/db/`, `*_templ.go`) — change the source and regenerate22- Put business logic in handlers or `.templ` files — handlers parse, validate, call the service, and render23- Write JavaScript beyond htmx attributes unless the design artifact requires client behaviour htmx cannot express24- Add a dependency the standard library, templ, htmx, sqlc, or pgx already covers25- Introduce an interface with a single implementation — the only accepted exception is sqlc's `db.Querier`, which unit tests fake26- Make implementation decisions without documenting their provenance (EXPLICIT vs INFERRED)27- Over-engineer — implement only what the specification requires. No speculative abstractions, unnecessary indirection, premature generalisation, or features not in the spec. Three similar lines of code are better than a premature abstraction. If a simple approach satisfies the requirement, use it.2829## Nexa Rules Gate3031Read and follow `${CLAUDE_PLUGIN_ROOT}/shared/readiness/NEXA_RULES_GATE.md`.3233## Worktree Gate3435Read and follow `${CLAUDE_PLUGIN_ROOT}/shared/readiness/WORKTREE_GATE.md`.3637## Project Readiness Gate3839Read and follow `${CLAUDE_PLUGIN_ROOT}/shared/readiness/PROJECT_READINESS.md`.4041This gate checks that cross-cutting infrastructure (middleware, structured logging, security headers,42environment configuration, migrations) exists before use case implementation begins. It applies to43`UC-XXX` items only — `TT-XXX` and `BUG-XXX` items skip this gate.4445Do not proceed with implementation until all items pass or the user explicitly waives failures.4647## DoR Check4849- For **UC-XXX**: Read and follow `${CLAUDE_PLUGIN_ROOT}/shared/readiness/DEFINITION_OF_READY.md`.50- For **TT-XXX**: Read and follow `${CLAUDE_PLUGIN_ROOT}/shared/readiness/DEFINITION_OF_READY_TT.md`.51- For **BUG-XXX**: Read and follow `${CLAUDE_PLUGIN_ROOT}/shared/readiness/DEFINITION_OF_READY_BUG.md`.5253Do not proceed with implementation until all items pass or the user explicitly waives failures.5455## Tracking5657Read and follow the **Before Implementation** steps in `${CLAUDE_PLUGIN_ROOT}/shared/tracking/TRACKING.md`.5859## Test Data Conventions6061- Use only `example.com` for test emails and accounts (e.g., `user@example.com`, `admin@example.com`). This is an IANA-reserved domain that will never route real mail.6263## Workflow64651. Read the specification:66 - For **UC-XXX**: Read the use case specification from `docs/use_cases/`67 - For **TT-XXX**: Read the technical task specification from `docs/technical_tasks/`68 - For **BUG-XXX**: Read the bug report from `docs/bugs/`692. Read the entity model from `docs/entity_model.md` (if applicable)703. Read the design artifact from `docs/designs/` (if it exists for this UC). When a design artifact exists, the implementation must match the specified screens, layout, components, states, and navigation flow.714. Read project design rules from `docs/designs/DESIGN_RULES.md` (if it exists). These are project-specific constraints — e.g., shared layout elements (header, footer, sidebar), mandatory components, or navigation patterns — that every implementation must follow. Missing a shared element specified in design rules is a defect.725. Check existing code for patterns and conventions — read `internal/web/routes.go`, `internal/web/layout/layout.templ`, and at least one existing `internal/<feature>/` package before writing a new one736. **i18n Detection** — check the project's `CLAUDE.md` for the marker `<!-- NEXA_I18N_CONFIGURED -->`,74 then look for an existing translation setup (`internal/i18n/`, message catalogs,75 `golang.org/x/text/message`, `go-i18n` in `go.mod`). If one exists, every user-facing string in76 this implementation — including validation messages — MUST go through it (`/setup-i18n`:77 `i18n.T(ctx, "namespace.key")` in templ and handlers), and new keys go into **all** locale78 catalogs. If none exists, write plain strings.797. Write the queries:80 - Add named queries to `db/queries/<entity>.sql` (`-- name: ListItems :many`, `:one`, `:exec`)81 - Every table and column must already exist in `db/migrations/` — if not, stop: the schema82 belongs to `/db-migration`, which runs before delivery83 - Run `go tool templ generate && sqlc generate`848. Implement the service in `internal/<feature>/service.go`:85 - A struct holding `db.Querier`; one method per use case operation86 - Business rules (`BR-XXX`) live here, with a comment naming the rule87 - Return domain errors (`var ErrNotFound = errors.New(...)`) that handlers map to status codes889. Implement the form in `internal/<feature>/form.go`:89 - A struct per form, parsed from `r.PostForm`90 - `func (f CreateItemForm) Validate() map[string]string` returning field -> message (a message ID when i18n is active; the view translates it); empty map means valid91 - Mirror each server rule with an HTML5 attribute in the view (`required`, `maxlength`, `type="email"`, `pattern`) — client-side validation is a convenience, the server check is the authority9210. Implement the handler in `internal/<feature>/handler.go`:93 - Methods with the `http.HandlerFunc` signature; read path values with `r.PathValue("id")`94 - Mutations: `r.ParseForm()` -> `Validate()` -> on errors re-render the form fragment with the95 submitted values and field errors, status `422` -> otherwise call the service. htmx swaps96 the `422` body only because the layout's `htmx-config` enables it (`/setup-web-middleware`);97 if the project's layout lacks that `responseHandling` entry, add it98 - Render a full page for normal requests and only the fragment when `r.Header.Get("HX-Request") == "true"`99 - After a successful htmx mutation, respond with the updated fragment or `HX-Redirect`; after a plain form post, `http.Redirect` with `303`100 - Map service errors: not found -> `404`, forbidden -> `403`, anything else -> log with `slog` and `500`101 - Read the signed-in user with `auth.FromContext(r.Context())` — never read the cookie or the session store again10211. Implement the views in `internal/<feature>/views.templ`:103 - Pages wrap content in the shared layout from package `internal/web/layout` — never import `internal/web` from a feature (import cycle)104 - Every htmx target is its own templ component so handlers can render it alone105 - Loading state: `hx-indicator` on the triggering element106 - Error state: field errors next to their inputs, a summary for non-field errors107 - Empty state: an explicit component when a list has no rows108 - When a design artifact exists, match the specified layout, components, states, and navigation109 - When project design rules exist (read in step 4), enforce every rule — e.g., include shared layout elements, follow mandatory navigation patterns, and apply required brand guidelines110 - Use labelled inputs (`<label for>`), semantic headings, and buttons for actions — the E2E tests select by role and label111 - Run `go tool templ generate`11212. Register routes in `web.NewHandler` (`internal/web/routes.go`) with method patterns (`mux.HandleFunc("POST /items", h.Create)`).113 Every route requires a signed-in user by default. When the spec restricts a route to a role, wrap it114 on the registration line: `mux.Handle("POST /items", auth.RequireRole("ADMIN")(http.HandlerFunc(h.Create)))`.115 Add a path to `auth.PublicPaths` only when the spec makes it reachable without signing in.11613. Write unit tests (no build tag) next to the code:117 - `form_test.go` — table-driven `Validate()` tests: each valid input passes, each invalid input produces the expected field error118 - `service_test.go` — a fake struct implementing `db.Querier` (embed `db.Querier` and override only the methods used); assert business rules and returned errors119 - `handler_test.go` — `httptest.NewRecorder` + the handler wired to a service with the fake: status codes, `422` with field errors on invalid input, fragment-only body when `HX-Request: true`, full layout otherwise, redirect target on success120 - `views_test.go` — render the component into a `bytes.Buffer` with `Render(context.Background(), &buf)` and assert the text the design specifies (empty-state message, error messages)121 - Run `go test ./...` to verify they pass12214. Run the `/code-quality` skill12315. Verify the implementation builds with `go tool templ generate && sqlc generate && go build ./... && go vet ./...`12416. Document implementation decisions in a `DECISIONS.md` file (or in the PR description):125 - For each non-trivial decision made during implementation, record:126 - **Decision:** What was decided127 - **Provenance:** EXPLICIT (from spec/requirements) or INFERRED (agent reasoning)128 - **Source/Reasoning:** Quote the source document or explain the reasoning129 - INFERRED decisions are candidates for stakeholder review before merge130131## Post-Implementation Tracking132133Read and follow the **After Implementation** steps in `${CLAUDE_PLUGIN_ROOT}/shared/tracking/TRACKING.md`.134135## Resources136137- Use the context7 MCP server for templ, htmx, sqlc, and pgx documentation