# Implement

> 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.

- Skill: `nexadevapp/implement` (Agent Skill)
- Install (CLI): `npx skillmds@latest add nexadevapp/implement`
- Raw SKILL.md: https://api.skillmd.com/api/skills/nexadevapp/implement/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: nexadevapp (https://skillmd.com/u/nexadevapp)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/nexadevapp/implement

---


# 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

1. 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/`
2. Read the entity model from `docs/entity_model.md` (if applicable)
3. 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.
4. 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.
5. 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
6. **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.
7. 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`
8. 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
9. 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
10. 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
11. 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`
12. 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.
13. 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
14. Run the `/code-quality` skill
15. Verify the implementation builds with `go tool templ generate && sqlc generate && go build ./... && go vet ./...`
16. 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

