Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
日本語の概要は準備中です。原文の説明を表示しています。
Use when you design or change an endpoint's errors, status codes, pagination, idempotency or concurrency behaviour — one error shape, the status-code table, bounded lists, safe retries
インストール方法を見るインストールする前に、エージェントに与えられる指示の中身を確認できます。
Most backend-caused QA bounces are inconsistency, not bugs: a 422 here and a 400 there, an unbounded list, a create that isn't safe to retry. This skill is the shared vocabulary so every endpoint in a service answers these the same way.
Core principle: the repository's existing choice wins (rule repo-conventions-win); these are the defaults for a new repo or an endpoint with nothing established yet.
Default for a repo with no convention yet: RFC 9457 application/problem+json — {type, title, status, detail, instance} plus an extension array for field errors, e.g. errors: [{field, message}]. Never a bare string, never a stack trace, never a raw framework exception body. Map it in ONE place (fiber-rest-api's central ErrorHandler, Spring @RestControllerAdvice + ProblemDetail/spring.mvc.problemdetails.enabled=true, Quarkus @ServerExceptionMapper) — not per handler.
| Code | When | Note |
|---|---|---|
| 200 / 201 | success / created | 201 includes Location of the new resource |
| 204 | success with no body (e.g. delete) | |
| 400 | unparseable or invalid input | or 422 if the repo already standardizes on it — don't introduce a second convention |
| 401 / 403 | unauthenticated / forbidden | |
| 404 | missing, OR present-but-not-yours (BOLA, api-security-checklist) | |
| 409 | duplicate or invalid state transition | e.g. a unique-constraint violation (pgx 23505) |
| 412 | a conditional request's precondition failed | If-Match version mismatch |
| 413 | body too large | |
| 429 | rate-limited | include Retry-After |
| 500 | genuinely unexpected only | never for validation or not-found |
The task's acceptance criteria or an existing contract always wins over this table.
Do the translation in the adapter, never in the handler:
switch {
case errors.Is(err, pgx.ErrNoRows):
return domain.ErrNotFound
case isPGCode(err, "23505"): // unique_violation
return domain.ErrConflict
case isPGCode(err, "23503"): // foreign_key_violation
return domain.ErrInvalidReference
}
ORDER BY created_at DESC, id DESC (a tiebreaker column prevents duplicate/missing rows across pages when timestamps collide).WHERE (created_at, id) < ($1, $2) ORDER BY created_at DESC, id DESC LIMIT $3+1, use the extra row to compute has_more, return an opaque next_cursor (base64 of the last row's sort key). Offset pagination (LIMIT/OFFSET) is fine for small, bounded tables only.INSERT ... ON CONFLICT (key) DO NOTHING RETURNING ..., or an Idempotency-Key request header backed by a dedupe table, following the draft semantics: same key + same payload → replay the stored response; same key + different payload → 422; a second request with the same in-flight key → 409; a required key that's missing → 400.version column (UPDATE ... SET ..., version = version + 1 WHERE id = $1 AND version = $2; zero rows affected → 409/412) or JPA @Version (java-persistence); or SELECT ... FOR UPDATE inside one transaction when the operation must serialize.Evolve additively; prefer a new optional field over renaming one in place; readers should ignore fields they don't recognise rather than failing closed (api-contract-openapi has the breaking-change procedure).
RFC 3339 timestamps in UTC; money as a decimal string or integer minor units, never a float; ids as strings even when they're numeric internally, so a client never silently loses precision.
❌ POST /tasks twice with the same client-generated request → two rows, two 201s
✅ POST /tasks with Idempotency-Key: <uuid> twice → first 201, second replays the same 201 body
❌ GET /tasks?page=50 on a 2M-row table → OFFSET 500000, a sequential scan
✅ GET /tasks?after=<cursor>&limit=50 → keyset WHERE, index-only scan
OFFSET climbing past five digits in a hot path.version/@Version field present on the entity but never checked in the update query.まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
日本語の概要は準備中です。原文の説明を表示しています。
Use when the diff adds or changes an endpoint, resolver, RPC, job or query that takes an object id, a role check, a request binding or a tenant filter - BOLA/IDOR, function-level authorization, mass assignment and tenant scoping
日本語の概要は準備中です。原文の説明を表示しています。
Use on every UI change - semantic HTML, labels for controls, keyboard-navigable dialogs/menus, visible focus, and never color as the only signal
日本語の概要は準備中です。原文の説明を表示しています。
Use when a task changes any screen, form, dialog, menu or control - Lighthouse/axe scan of the changed screens, a keyboard walk, and the thresholds that fail a task
日本語の概要は準備中です。原文の説明を表示しています。
How to work a task returned with review, QA or UAT findings. Use when a task is in need_revision or PR review comments are in your context.
日本語の概要は準備中です。原文の説明を表示しています。
Use when deciding whether a request needs an analiz task before implementation - the conditions that require the architect's analysis versus going straight to implementation
日本語の概要は準備中です。原文の説明を表示しています。