Pricing
Development

Backend Development (Next.js)

Structure Next.js backend code as route → controller → service → repository with validation, security checkpoints, and testable boundaries.

View on GitHub

Backend Development

Use this skill for backend work in a Next.js app. Favor reusable, testable server code with explicit boundaries and security review built into the workflow.

Architecture Rules

  • Keep reusable backend code under the /server root folder.
  • Treat Next.js API routes and server-action entrypoints as the thin edge. They should parse framework inputs, call controllers, and return framework responses.
  • Keep route handlers in app/api/**/route.js or app/api/**/route.ts lean; all reusable validation, orchestration, business logic, persistence, and security helpers should live under /server.
  • Put request orchestration in controllers. Controllers validate inputs, call services, map errors, and shape responses.
  • Put business logic in services. Services coordinate use cases and should not depend on Next.js request/response objects.
  • Put persistence behind repositories. Repositories own database queries, transactions, and database-specific details.
  • Keep shared backend utilities under /server by concern, such as server/security, server/validation, server/errors, or server/db.
  • Do not import server modules into client components.

Recommended shape:

app/api/<resource>/route.js
server/controllers/<resource>Controller.js
server/services/<resource>Service.js
server/repositories/<resource>Repository.js
server/db/client.js
server/db/schema.js
server/errors/
server/security/
server/validation/

Engineering Standards

  • Promote code reuse, but avoid abstractions that only hide one call site.
  • Apply DRY where duplication creates maintenance risk; keep small duplication when it preserves clarity.
  • Prefer repository, service, controller, mapper, validator, and policy patterns when they fit the problem.
  • Keep modules focused around use cases and ownership boundaries.
  • Use dependency injection by parameters or factories when it improves testability without adding ceremony.
  • Prefer explicit return objects and typed JSDoc over implicit shape coupling.
  • Prefer TypeScript file extensions when the codebase uses TypeScript; keep the same layering either way.
  • Use database constraints, transactions, and indexes for invariants that matter.

Security Standard

Security is a top priority. Pause and discuss with the user before implementing a path that creates meaningful risk or changes trust boundaries. For low-risk CRUD changes, refactors, or bug fixes that stay within existing auth and data-access patterns, proceed normally.

Push back or ask for a decision when work touches:

  • Authentication, authorization, roles, tenants, sessions, or ownership checks.
  • Secrets, environment variables, token handling, webhooks, or third-party credentials.
  • User-generated content, file uploads, exports, imports, prompts, or stored AI outputs.
  • SQL construction, dynamic filters, raw queries, migrations, or destructive database operations.
  • Rate limits, abuse prevention, audit trails, logging, privacy, or data retention.

Default expectations:

  • Validate all external input at the boundary before calling services.
  • Authorize every read and write against the acting user, resource ownership, and tenant scope.
  • Keep secrets server-only and out of logs, client bundles, and serialized responses.
  • Prefer parameterized queries over raw SQL.
  • Return safe error messages to clients; keep detailed diagnostics in server logs.
  • Treat migrations and destructive operations as review-worthy changes.

Backend Workflow

  1. Inspect existing route, controller, service, repository, schema, and validation patterns before editing.
  2. Identify the backend boundary being changed and keep files in /server unless the code is purely Next.js routing glue.
  3. Design the flow route -> controller -> service -> repository, skipping layers only when the feature is trivial and the boundary remains clear.
  4. Define validation, authorization, error handling, and transaction needs before writing persistence code.
  5. Implement the smallest reusable modules that solve the use case.
  6. Add or update focused tests when behavior, security checks, or persistence contracts change.
  7. Run relevant verification, usually npm run typecheck, npm run lint, and targeted tests/build commands when available.

Next.js Route Pattern

Keep route files boring and thin:

export async function POST(request) {
    return createThingController({ request });
}

The controller should own body parsing, validation, calling services, and response mapping. Services and repositories should remain portable server modules that can be tested without Next.js route machinery.