Software Architecture Skill
Implements Clean Architecture, SOLID principles, and proven design patterns for building robust, maintainable software systems. Guides architectural decisions, layer separation, dependency management, and pattern selection.
Description
This skill guides architectural decisions using Clean Architecture, SOLID principles, and established design patterns. It helps structure codebases for maintainability, testability, and scalability with clear layer separation and dependency rules.
Instructions
When making architectural decisions, apply these frameworks:
Clean Architecture Layers
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā Frameworks & Drivers ā Express, React, PostgreSQL
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā Interface Adapters ā ā Controllers, Presenters, Gateways
ā ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā ā
ā ā ā Application Logic ā ā ā Use Cases, Application Services
ā ā ā āāāāāāāāāāāāāāāāāāāāāāāāā ā ā ā
ā ā ā ā Domain Entities ā ā ā ā Business rules, Value objects
ā ā ā āāāāāāāāāāāāāāāāāāāāāāāāā ā ā ā
ā ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
Dependency Rule: Arrows point INWARD only.
Inner layers never import from outer layers.
Project Structure
src/
domain/ # Entities, value objects, domain events
entities/
value-objects/
events/
repositories/ # Repository INTERFACES (not implementations)
application/ # Use cases, application services
use-cases/
services/
dto/ # Data transfer objects
infrastructure/ # Implementations of interfaces
database/ # Repository implementations
external-apis/
messaging/
presentation/ # Controllers, routes, serializers
http/
graphql/
websocket/
Design Pattern Selection Guide
| Problem | Pattern | When to Use |
|---|---|---|
| Multiple types need same interface | Strategy | Payment processors, validators |
| Object creation is complex | Factory | Creating entities with dependencies |
| Need to notify multiple consumers | Observer/Events | Domain events, webhooks |
| Step-by-step process | Template Method | Report generation, ETL pipelines |
| Need to add behavior without modifying | Decorator | Logging, caching, auth middleware |
| Complex object construction | Builder | API responses, query construction |
| Single instance needed | Singleton | Config, database pool, logger |
| Transform data through stages | Pipeline | Data processing, middleware chains |
Implementation Example: Repository Pattern
// Domain layer: Interface (no dependency on database) interface UserRepository { findById(id: string): Promise<User | null>; save(user: User): Promise<void>; findByEmail(email: string): Promise<User | null>; } // Infrastructure layer: Implementation class PostgresUserRepository implements UserRepository { constructor(private db: Pool) {} async findById(id: string): Promise<User | null> { const result = await this.db.query( 'SELECT * FROM users WHERE id = $1', [id] ); return result.rows[0] ? this.toDomain(result.rows[0]) : null; } async save(user: User): Promise<void> { await this.db.query( 'INSERT INTO users (id, email, name) VALUES ($1, $2, $3) ON CONFLICT (id) DO UPDATE SET email = $2, name = $3', [user.id, user.email, user.name] ); } private toDomain(row: any): User { return new User(row.id, row.email, row.name); } } // Application layer: Use case class CreateUserUseCase { constructor( private userRepo: UserRepository, // Depends on interface, not Postgres private emailService: EmailService, ) {} async execute(input: CreateUserInput): Promise<User> { const existing = await this.userRepo.findByEmail(input.email); if (existing) throw new DuplicateEmailError(input.email); const user = User.create(input); await this.userRepo.save(user); await this.emailService.sendWelcome(user); return user; } }
Rules
- Dependencies always point inward ā domain never imports from infrastructure
- Domain entities must not depend on frameworks, ORMs, or external libraries
- Use dependency injection ā never instantiate dependencies with
newinside business logic - Repository interfaces live in the domain layer; implementations live in infrastructure
- Use cases should orchestrate, not contain business rules (those belong in entities)
- Prefer composition over inheritance
- Apply YAGNI ā do not add patterns "just in case"; add them when complexity demands it
- For small projects (<10 files), this is overkill ā use simpler flat structure
- Each layer should be independently testable with mocks for outer layers
- Document architectural decisions using ADRs (Architecture Decision Records)
Examples
User: How should I structure my Express API? Action: Apply Clean Architecture layers, suggest project structure, implement repository pattern for data access
User: Which design pattern should I use for multiple payment providers? Action: Recommend Strategy pattern, show interface + implementations for each provider
User: My service file is 500 lines, how do I break it up? Action: Identify responsibilities, extract into domain entities + use cases + repository, show the refactored structure
Reviews
No reviews yet. Be the first to review this template!
Similar Templates
Full-Stack Code Reviewer
Comprehensive code review skill that checks for security vulnerabilities, performance issues, accessibility, and best practices across frontend and backend code.
Test Suite Generator
Generates comprehensive test suites with unit tests, integration tests, and edge cases. Supports Jest, Vitest, Pytest, and Go testing.
Pro Architecture Workspace
Battle-tested skill for architectural, decision, making, framework. Includes structured workflows, validation checks, and reusable patterns for development.