Backend Engineering Skill
Activate this skill when creating or updating API endpoints, database models, background jobs, caching layers, or backend services.
Operational Directive: Design resilient, validated, and performant backend services with strict data integrity.
1. API Contract Design & HTTP Standards
Check .ai/API.md for project-specific conventions (REST, GraphQL, tRPC). Adhere to standard HTTP semantics:
Status Code Standards
200 OK: Successful retrieval or synchronous update.201 Created: Resource successfully created (includeLocationheader or created object).204 No Content: Successful mutation with no response body (e.g. deletion).400 Bad Request: Malformed syntax, invalid JSON, or failed input schema validation.401 Unauthorized: Missing or invalid authentication token.403 Forbidden: Authenticated user lacks permission to access this resource.404 Not Found: Resource does not exist.409 Conflict: Unique constraint violation or state transition conflict.422 Unprocessable Entity: Semantically invalid payload (business rule failure).500 Internal Server Error: Unhandled server error (never leak internal stack traces to client).
Standard Error Response Envelope
{
"error": {
"code": "INVALID_PAYLOAD",
"message": "The provided email address is already in use.",
"details": [
{ "field": "email", "issue": "Unique constraint violation" }
],
"requestId": "req_01h7x..."
}
}2. Input Validation & Schema Guardrails
- Always parse and validate incoming request payloads at the boundary using schema validators (
Zod,Pydantic,Joi,Validator.js) before calling business logic. - Strip unvalidated fields to prevent Mass Assignment vulnerabilities.
3. Database Integrity, Queries & Transactions
- Transactional Boundaries: Always wrap multi-table write operations inside atomic database transactions (
tx.run(),db.transaction()). - Prevent N+1 Query Anti-Patterns: Use ORM joins (
include,select_related,prefetch_related) or DataLoader rather than executing queries inside loops. - Pagination Standards:
- For small, static sets: Offset-based pagination (
limit,offset). - For high-volume, real-time data: Keyset / Cursor-based pagination (
cursor,take).
- For small, static sets: Offset-based pagination (
- Connection Pooling: Reuse connection pools; never instantiate new database connection clients per HTTP request.
4. Mandatory Backend Execution Checklist
Follow this sequence for every backend route, handler, or service mutation:
- Pre-Flight Reuse Check: Inspect
src/services/orsrc/controllers/to reuse existing database clients, validators, and error classes. - Boundary Validation: Parse headers, query parameters, and JSON bodies with schema validation (
zod,pydantic). Reject invalid input with400or422. - Atomic Transactions: If modifying more than one entity or table, enclose all operations within an atomic database transaction.
- Error Handling: Catch expected domain errors and map them to standard HTTP status codes. Never swallow errors silently or leak internal stack traces.
- Targeted Verification: Run the targeted test for the modified handler or endpoint (e.g.,
npm test -- user.test.ts).
5. Contrast Matrix: Anti-Patterns vs Required Standards
Anti-Pattern 1: Silent Error Swallowing
// ❌ WRONG: Swallows error silently, leaving system in inconsistent state
try {
await db.user.create({ data });
} catch (err) {
// Silent fail or meaningless console.log
}// ✅ CORRECT: Log internal error and return structured error response
try {
await db.user.create({ data });
} catch (err: unknown) {
logger.error('Failed to create user', { error: err, requestId });
throw new DomainError('USER_CREATION_FAILED', 'Unable to register user account.', 409);
}Anti-Pattern 2: Missing Boundary Validation (Mass Assignment)
// ❌ WRONG: Blindly trust user-supplied request body
app.post('/api/profile', async (req, res) => {
await db.user.update({ where: { id: req.user.id }, data: req.body }); // Can overwrite isAdmin!
});// ✅ CORRECT: Strict schema parsing stripping unvetted fields
const ProfileUpdateSchema = z.object({
displayName: z.string().min(2).max(50),
bio: z.string().max(280).optional(),
});
app.post('/api/profile', async (req, res) => {
const validated = ProfileUpdateSchema.parse(req.body);
await db.user.update({ where: { id: req.user.id }, data: validated });
});Anti-Pattern 3: Hardcoded Environment Secrets & Endpoints
// ❌ WRONG: Hardcoded URL or port
const DB_URL = "postgres://postgres:password@localhost:5432/production";// ✅ CORRECT: Validated environment variables
const DB_URL = process.env.DATABASE_URL;
if (!DB_URL) throw new Error("CRITICAL: DATABASE_URL environment variable is missing.");