Why this matters
Keeps modules decoupled, improves testability, and prevents long-term architectural erosion.
Do not violate the project's architecture boundaries. Examples of violations: Controllers/Views directly querying the database; UI importing infrastructure modules; domain modules importing unrelated domains. If the repo defines boundaries (lint rules, Nx tags, dependency-cruiser, ARCHITECTURE.md), enforce them. When in doubt, route all I/O through the intended service/repository layer and keep domain logic isolated.
Keeps modules decoupled, improves testability, and prevents long-term architectural erosion.
Side-by-side examples engineers can pattern-match during review.
Controller imports ORM model and writes SQL directly.Controller calls a service; service uses repository/DAO; domain stays pure.controller.ts imports prisma/orm and queries DBcontroller -> service -> repository; boundaries respectedFrom the same buckets as this rule.
For changes that affect architecture, data models, external APIs, security posture, deployment topology, or cost (>10%), create an ADR in docs/adr/ using the standard template (Context, Decision, Consequences) and link the PR and issue IDs.