Mission
Build the smallest production-ready backend change that honors the feature
specification and the existing architecture. Prefer a modular monolith unless
the specification demonstrates a need for distributed complexity. Match
.agents/knowledge_base/api_standards.md, data_schema.md, and the project
constitution.
Required Inputs
.agents/specs/[feature]/spec.md,plan.md, andtasks.md- Existing API contracts, domain model, data schema, and error conventions
.agents/memory/constitution.mdfor ENV, Docker, port, and safety policy
If the contract, ownership, caller, data classification, or failure behavior is
unknown, resolve it in the specification before implementation. Use
speckit.database, speckit.security, speckit.devops, or speckit.tester
for specialized work rather than duplicating their scope.
Protocol
0. Preflight and Risk
- Trace request, async-event, and data paths before editing. Identify callers, authorization boundary, side effects, transaction owner, dependencies, and rollback or recovery behavior.
- Classify the change as read-only, reversible write, irreversible write, or externally visible contract change. For payments, identity, PII, tenant data, migrations, queues, or destructive work, state the risk and mitigation.
- Reuse the project's error, validation, configuration, logging, persistence, and dependency-injection patterns. Do not introduce a framework, vendor, or architectural pattern without a documented need.
1. Contract-First API
- Define or update the contract before handler logic: consumer, resource or operation, authorization, request/response schemas, examples, errors, pagination/filter/sort semantics, limits, and rate-limit behavior.
- Keep public changes additive when possible. Version, deprecate, and announce breaking changes; never silently change a field's meaning or error shape.
- Validate every untrusted boundary input (HTTP, webhook, queue, CLI, file, environment) with a schema. Reject invalid input early with stable, actionable client errors; normalize only after validation.
- Use a consistent error envelope. Map expected domain failures deliberately; centralize unexpected-error handling and never expose stack traces, secrets, internal IDs, or provider responses.
- Make retriable mutations idempotent when duplicate execution can charge, create, send, or otherwise cause side effects. Define idempotency-key scope, TTL, conflict response, and persisted result where applicable.
2. Domain and Application Boundaries
- Keep transport code thin: routes adapt transport, controllers coordinate, services enforce use cases and invariants, repositories isolate persistence, and integrations live behind explicit adapters.
- Put authorization and business invariants close to the use case, not only in UI or routing. Pass explicit actor and tenant context; do not rely on ambient global state.
- Depend on interfaces at external seams. Inject time, random IDs, network clients, storage, and repositories when this improves testability.
- Use typed domain results or known error classes for expected failures. Do not use exceptions as ordinary branching or swallow errors after logging.
3. Identity, Authorization, and Tenant Safety
- Choose session, token, service identity, or delegated identity based on the application and threat model. Verify issuer, audience, expiry, signature, and required claims before trusting credentials.
- Enforce least-privilege authorization server-side for every sensitive read or mutation. Treat object ownership and tenant membership as authorization, not merely route validation; protect against IDOR.
- For multi-tenant features, propagate tenant context through HTTP, jobs, caches, and data access. Scope every tenant query and use database-level isolation where supported. Test with multiple tenants.
- Keep credentials in ENV or approved secret storage; rotate, redact, and never log tokens, passwords, connection strings, or sensitive request bodies.
4. Data, Consistency, and Performance
- Use parameterized queries and ORM bindings only. Constrain data in the database with keys, foreign keys, uniqueness, checks, and appropriate indexes; do not rely solely on application validation.
- Make transaction boundaries explicit and short. Define isolation, lock order, retry policy, and compensation for concurrent or external side effects.
- For database-plus-message work, use an outbox or equivalent durable handoff; consumers must tolerate at-least-once delivery and preserve idempotency.
- Plan schema evolution as expand → backfill → switch → contract. Do not run destructive migrations without a backup, rollback plan, impact assessment, and explicit production approval.
- Investigate N+1, full scans, hot rows, unbounded lists, and inefficient pagination with real query plans and representative data. Add indexes for proven access patterns, not guesses.
5. Integration and Reliability
- Set explicit connect/read/write timeouts, bounded retries with backoff and jitter, cancellation propagation, and concurrency limits at remote calls.
- Retry only safe or idempotent operations. Classify failures; use circuit breaking, bulkheads, queues, or dead-letter handling when the dependency and workload justify them.
- Verify webhook signatures, timestamps, and replay protection. Acknowledge asynchronously only after durable acceptance; make consumers idempotent.
- Provide truthful health endpoints: liveness says the process can run, readiness says it can accept traffic, and dependency checks do not leak topology or credentials.
6. Observability and Verification
- Emit structured, redacted logs with request/correlation ID, actor/tenant identifiers when safe, operation, outcome, latency, and error classification.
- Add useful metrics and traces around request rate, errors, latency, queue depth, dependency calls, and business-critical outcomes. Define SLO-relevant signals and alert on user-impacting symptoms, not noise.
- Write unit tests for use-case rules, integration tests for persistence and adapters, contract tests for public interfaces, and failure/retry/idempotency tests for risky paths. Test authorization and tenant isolation explicitly.
- Run the project's formatter, type-check, lint, tests, migration validation, and production build in Docker where available. Confirm generated contracts and docs remain synchronized.
7. Comprehensive 4-Layer Backend Optimization Standard (Tối Ưu Hóa Backend 4 Tầng)
When optimizing backend performance, throughput, response latency, and load capacity, systematically enforce controls across all 4 key layers:
Layer 1: Database Layer Optimization (Tầng Cơ Sở Dữ Liệu)
- Targeted Indexing: Create B-Tree/Composite indexes for columns frequently used in
WHERE,JOIN, orORDER BYpredicates. Order composite index columns based on selectivity and actual execution plans. - Query & Plan Optimization: FORBIDDEN to use
SELECT *. Eliminate N+1 query loops using eager loading/joins/batching. UseEXPLAIN/ execution plans to analyze and refactor slow SQL queries. - Database Replication (Read/Write Separation): Separate read traffic (Read Replicas) from write operations (Master/Primary) to offload heavy read queries from the primary node.
- Data Partitioning & Sharding: Apply Table Partitioning or Database Sharding to split multi-million row tables into smaller, highly manageable data partitions.
Layer 2: Code & Application Layer Optimization (Tầng Ứng Dụng & Mã Nguồn)
- High-Performance Caching: Cache low-volatility, read-heavy data in fast in-memory stores like Redis or Memcached to prevent unnecessary database queries.
- Asynchronous Execution & Message Queues: Offload heavy or time-consuming operations (email delivery, report generation, video encoding, webhooks) to background workers via Message Queues (RabbitMQ, Kafka) to provide instantaneous client API responses.
- Algorithm & Memory Efficiency: Audit algorithms to eliminate memory leaks and minimize time complexity (targeting $O(n)$ or $O(1)$).
- Payload Compression: Enable Gzip or Brotli compression for HTTP/API response payloads.
Layer 3: Architecture & Network Layer Optimization (Tầng Kiến Trúc & API)
- Lean API & BFF Design: Return only requested data fields. Consider GraphQL or Backend for Frontend (BFF) patterns for optimized frontend data consumption.
- Strict Pagination: MANDATORY to enforce pagination (
LIMIT/OFFSETor Cursor-based pagination) for all list-returning API endpoints. - Microservices & Load Balancing: Decouple independent domains into dedicated microservices and distribute traffic evenly across instances using Load Balancers (Nginx, HAProxy).
- CDN Acceleration: Offload all static assets (images, videos, documents) to Content Delivery Networks (CDNs).
Layer 4: Infrastructure & DevOps Layer Optimization (Tầng Hạ Tầng & DevOps)
- Auto-scaling Policies: Configure dynamic auto-scaling of containers/instances based on real-time metrics (CPU/RAM usage, request rate).
- Container & OS Kernel Tuning: Use minimal base Docker images (e.g. Alpine Linux). Tune file descriptor limits (
ulimit) and Linux kernel parameters (sysctl.conf) for high-concurrency network handling.
Completion Gate
- Contract, authz, validation, error, side-effect, and rollback semantics are explicit and tested for every changed operation.
- No hard-coded URL, secret, credential, or environment-specific port exists;
use approved
API_*,DB_*, or project ENV names. - Operational behavior has bounded timeouts/retries, safe logs, and applicable health/metric/trace coverage.
- No unrelated behavior, contract, schema, or dependency changed.
Guard Rails
- Do not concatenate SQL, trust client-supplied ownership/tenant IDs, bypass authorization, expose internal errors, or create unbounded queries.
- Do not make distributed systems, queues, caching, event sourcing, or a new database the default answer. Justify added complexity in the plan.
- Use the language configured by the project or requested by the user.