| name | backend |
| description | Activate for backend engineering work across APIs, services, data models, migrations, auth, validation, error handling, background jobs, queues, caching, rate limiting, observability, testing, performance, and safe production refactors. Use for Node.js/TypeScript, Python, Go, Java, PostgreSQL, MySQL, Redis, REST, GraphQL, serverless APIs, monoliths, and modular monoliths. |
| version | 1 |
| category | backend-code |
| outputs | code |
Backend
Purpose
Use this skill when the task touches backend behavior that must stay correct in production. It keeps API contracts stable, service boundaries clear, schema changes safe, auth checks close to sensitive actions, and risky changes observable and reversible. It works across Node.js/TypeScript, Python, Go, Java, SQL databases, Redis, REST APIs, GraphQL APIs, queues, serverless APIs, monoliths, and modular monoliths.
When to Use This Skill
- Building a new API, worker, webhook, or service flow
- Changing existing backend behavior without rewriting the system
- Adding auth, authorization, validation, pagination, caching, or rate limiting
- Designing or changing tables, indexes, constraints, or migrations
- Implementing jobs, queue consumers, retry logic, or idempotency
- Adding logs, metrics, traces, health checks, or alertable signals
- Refactoring backend code that already serves production traffic
- Hardening slow, fragile, or failure-prone backend paths
When Not to Use This Skill
- Pure frontend work with no server-side component
- Pure documentation or planning with no code change
- Infrastructure-only work such as cluster operations or Terraform
- Toy scripts that do not affect production behavior
- A narrow non-backend task that belongs to a more specific skill
Operating Principles
- Inspect the existing system before editing.
- Preserve API contracts unless the user explicitly asks for a breaking change.
- Prefer boring reliable patterns over clever abstractions.
- Keep domain logic separate from transport and controller code.
- Respect service boundaries. Do not bury security or data rules in helpers that can be called from anywhere.
- Use transactions when correctness depends on atomicity.
- Make risky changes small, reversible, and easy to observe.
- Do not introduce new layers until there is a second concrete use case.
First Read Checklist
- Find the entry point for the change: route, handler, worker, job, or CLI command
- Trace the call chain through transport, service, domain, and data access code
- Read the current schema, indexes, constraints, and recent migrations
- Check where authentication and authorization are enforced
- Inspect existing error handling and response shapes
- Review tests that already cover the path
- Note any performance-sensitive queries, external calls, or queue behavior
- Identify any rollout, feature flag, or compatibility pattern already in use
If any step reveals a contract or constraint that conflicts with the request, stop and surface it before changing code.
API Contract Rules
- Treat routes, request bodies, query params, response fields, and status codes as contracts.
- Preserve existing contracts unless the user asks for a breaking change.
- Additive changes are safe by default.
- Removing or renaming fields, changing field types, or changing meaning is breaking.
- List endpoints must paginate.
- Use cursor pagination for large or append-heavy datasets, offset pagination only for small bounded sets with an explicit maximum.
- Return semantically correct status codes. Use
400 for malformed input, 401 for unauthenticated requests, 403 for unauthorized requests, 404 for missing resources, 409 for conflicts, 422 for semantically invalid input, and 429 for rate limiting.
- Keep error responses consistent across the service. Use the project existing envelope if it already has one. If not, prefer a stable shape with
error, code, and an optional request_id.
- Never return stack traces or raw exception details to clients.
Data Modeling and Migration Rules
- Make schema changes through migrations. Do not edit schema files, ORM models, or table definitions without a matching migration.
- Keep migrations small and purposeful.
- Prefer reversible migrations. If rollback is not safe, document the irreversibility and data-loss risk in the migration or change notes.
- Use the expand, backfill, switch, contract sequence for zero-downtime changes.
- Add indexes for new foreign keys and for columns used in frequent filters, joins, sorts, or lookups.
- Avoid
SELECT *. Read only the columns the code uses.
- Use explicit constraints to protect correctness.
- Use optimistic locking or version checks when stale writes are possible.
- Keep transactions short. Do not hold locks while making slow external calls.
- Do not drop or rename populated columns until the old code path is gone.
Auth and Authorization Rules
- Authenticate before protected work begins.
- Authorize against the specific resource, not just the action type.
- Keep authorization checks close to the boundary where the request first becomes trusted.
- Do not rely on route naming, client state, or hidden UI for security.
- Verify token expiry and other session limits.
- Use secure defaults for cookies and CORS when the stack uses them.
- Never log passwords, secrets, tokens, session values, or sensitive personal data.
- Keep auth decisions out of deep domain helpers so they cannot be bypassed through another call path.
Validation and Error Handling
- Validate request bodies, query params, headers, queue payloads, and environment inputs at the boundary.
- Let domain code assume validated input.
- Return field-level validation errors when possible instead of generic failure messages.
- Wrap external errors with context before rethrowing.
- Add timeouts to database, cache, queue, and HTTP calls.
- Do not swallow errors.
- Use structured error mapping instead of ad hoc string parsing.
- Log detailed server-side context with a correlation id. Keep client responses clean and predictable.
Background Jobs, Queues, and Idempotency
- Put long-running or expensive work in a job or queue when synchronous execution would block the request path.
- Make job handlers idempotent and retry-safe.
- Use identifiers in payloads, not copied state, unless snapshotting is intentional.
- Use deduplication keys, unique constraints, processed-state checks, or outbox patterns when needed.
- Retry only when repeating the operation is safe.
- Make partial failure safe to retry.
- Log job type, resource id, attempt count, and failure context.
- Treat webhook handlers like jobs: idempotent, defensive, and safe to replay.
Caching and Rate Limiting
- Cache only when there is a real latency or cost reason.
- Include every input that affects the result in the cache key, including tenant or user scope.
- Set a TTL for every cached value unless the data is immutable.
- Invalidate explicitly when the source data changes.
- Do not cache authorization decisions beyond the life of the token or session that produced them.
- Apply rate limits before auth on public endpoints.
- Apply identity-based limits on authenticated endpoints.
- Return
429 with Retry-After when possible.
Observability
- Use structured logs with request id, trace id, level, event name, and relevant business context.
- Do not log request bodies containing secrets or personal data.
- Use metrics for latency, error rate, retries, queue depth, cache hit rate, and slow queries.
- Add traces for cross-service paths or high-latency operations.
- Expose a health or readiness check that verifies the dependencies the service actually needs.
- Do not report healthy if the service cannot do useful work.
Testing Requirements
- Add or update tests for changed behavior.
- Cover success, boundary, and failure cases.
- Test authz boundaries, retry behavior, and idempotency where relevant.
- Add contract tests for public API changes when the project already uses them.
- Keep fixtures realistic and small.
- Verify the failure path for missing dependencies when the change depends on them.
- Add a regression test for any bug fix that would have caught the original failure.
Performance Review
- Check query shape and query count.
- Avoid N+1 queries.
- Add indexes before relying on them for production traffic.
- Measure external call cost, payload size, and serialization overhead.
- Keep transactions short.
- Do not do expensive work on the request thread if a job is more appropriate.
- Review p95 and p99 impact, not just averages.
- Prefer data layout changes over code tricks when the database is the bottleneck.
Safe Refactoring and Rollout
- Preserve compatibility by default.
- Use expand, backfill, switch, contract for schema and API changes.
- Keep old and new paths running together only as long as needed.
- Use feature flags or rollout gates when a change is risky.
- Have a rollback path before shipping a migration or behavior change.
- Explain what might break, what is reversible, and what data would be hard to recover.
- If a live contract changes, call out the deprecation or migration plan.
Output Requirements
- Start with a brief plan that names the change, compatibility impact, and risks.
- Show migrations before application code when schema changes are involved.
- Include the full changed function, handler, or file section rather than a fragment.
- If the change is breaking, say so clearly before implementation details.
- Include tests for important new behavior.
- Do not use TODOs, placeholder comments, or partial code.
Quality Checklist
Common Failure Modes
- Contract drift: existing request or response shape changes without permission.
- Schema overwrite: ORM or schema files change without a migration.
- Missing transaction: multiple writes can partially succeed and leave state inconsistent.
- Auth gap: permission checks happen too late or only in a helper.
- Silent swallow: errors are logged poorly or ignored.
- Retry duplicate: a job or webhook runs twice and duplicates side effects.
- Cache leak: cached data crosses user, tenant, or permission boundaries.
- Unbounded query: a list endpoint returns everything or scans too much.
- Slow rollout: a risky change ships without a rollback or compatibility plan.
- Premature abstraction: an extra service or repository layer is added with one caller.
Response Format
State the plan first. Then make the smallest safe change that satisfies the request. If a contract might break, say so before editing. Handle schema, app code, and tests in that order when the task spans all three.