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 the repository keeps its alerting in code, or a person asks for alerts outside TaskTrooper - PrometheusRule YAML, a Cloud Monitoring alert policy in Terraform, a Datadog monitor, each routed to TaskTrooper's alert ingest URL so it opens an incident here
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.