ca-architecture-boundaries

star 266

Use when designing system architecture, drawing boundaries between business logic and infrastructure, or when changes touch many unrelated files. Triggers on: architecture design, dependency direction, separating business rules from database/UI/frameworks.

ryanthedev By ryanthedev schedule Updated 3/24/2026

name: ca-architecture-boundaries description: "Applies Clean Architecture's dependency-direction and SRP-by-actor rules to system-level boundary design: separates business logic from infrastructure, identifies actor-coupling risks, and enforces inward-pointing dependency arrows." disable-model-invocation: true

Architecture Boundaries (Clean Architecture)

Operates at SYSTEM level (layers, boundaries, components). For MODULE level (interface depth, information hiding), use aposd-designing-deep-modules.


SRP Is About Actors, Not "Doing One Thing"

"A module should be responsible to one, and only one, actor."

An actor is a group of users/stakeholders who request changes. If two actors share a class, a change for one can break the other.

// BEFORE: One class serves three actors
class Employee {
    Money calculatePay() { }      // CFO's accounting team
    String reportHours() { }      // COO's HR team
    void save() { }               // CTO's DBA team
}

// AFTER: Separate class per actor
class EmployeeData { /* just data */ }

class PayCalculator {
    Money calculatePay(EmployeeData e) { /* CFO */ }
}
class HourReporter {
    String reportHours(EmployeeData e) { /* COO */ }
}
class EmployeeSaver {
    void saveEmployee(EmployeeData e) { /* CTO */ }
}

// Optional: Facade for convenience
class EmployeeFacade {
    // Delegates to actor-specific classes
}

Test: For each class, ask "who requests changes to this?" If the answer is more than one actor, split.


DRY Within Actor Boundaries Only

Duplication across actor boundaries is safer than coupling.

If CFO's calculatePay and COO's reportHours both use the same regularHours helper, they appear duplicated — but they change for different reasons. Merging them couples two actors. When CFO's accounting rules change, COO's reports break.

Rule: DRY applies within a single actor's code. Across actors, prefer duplication over coupling.


Dependency Rule

Dependencies point inward: Frameworks → Adapters → Use Cases → Entities.

Nothing in an inner circle can know anything about an outer circle. Business rules never import database, UI, or framework code. If business logic needs to call infrastructure, define an interface in the business layer and implement it in the infrastructure layer (dependency inversion).


Separate Business Rules from Infrastructure

Pattern: interface defined in the business layer (where it's used), implemented in the infrastructure layer (dependency inversion).

// Business layer — interface lives here, no infrastructure imports
public interface OrderRepository { Order findById(String id); void save(Order order); }

// Infrastructure layer — concrete class implements the business interface
public class SqlOrderRepository implements OrderRepository { /* SQL */ }

The Use Case depends on OrderRepository (abstraction). The infrastructure layer depends on OrderRepository too — arrows point inward.


Integration Checklist

When applying to an existing system:

Phase 1: Identify

  • Map actors (who requests changes?) → list per-actor responsibilities
  • Identify Critical Business Rules (what makes/saves money?) → Entities
  • List application workflows → Use Cases
  • Find technical dependencies (DB, UI, frameworks) → Details to isolate

Phase 2: Draw Boundaries

  • Dependencies all point toward business rules?
  • Can business logic run without infrastructure?
  • Are changes proportional to scope, not shape?

Phase 3: Verify

  • SRP: Each class is responsible to exactly one actor?
  • OCP: Simple extensions do NOT require modifying existing code?
  • DIP: Business logic imports only abstractions (no concrete infrastructure)?

Boundary Violation Detection

Adapt paths to your project's directory structure.

# Framework coupling in business logic
grep -r "import.*servlet\|import.*spring.*web\|import.*express" src/domain/
grep -r "import.*sql\|import.*mongoose\|import.*prisma" src/entities/

# ORM annotations in domain
grep -r "@Entity\|@Table\|@Column" src/domain/

# Type checking instead of polymorphism (scope to domain dirs, not all of src/)
grep -r "instanceof\|getType()\|typeof.*===" src/domain/ src/entities/

Chain

After Next
Boundaries drawn aposd-designing-deep-modules (module-level design)
SOLID violations found cc-refactoring-guidance (safe restructuring)
Install via CLI
npx skills add https://github.com/ryanthedev/code-foundations --skill ca-architecture-boundaries
Repository Details
star Stars 266
call_split Forks 23
navigation Branch main
article Path SKILL.md
More from Creator