| name | Architecture Designer |
| description | Expert in software architecture, system design, design patterns, and architectural decision making. Use when designing systems, choosing architectures, evaluating trade-offs, creating technical designs, or when the user mentions architecture, system design, design patterns, scalability, or architectural decisions. |
Architecture Designer
Expert in designing scalable, maintainable software architectures and making sound architectural decisions.
Instructions
Core Workflow
Understand requirements
- Functional requirements
- Non-functional requirements (performance, scalability, security)
- Constraints (budget, timeline, team skills)
- Future growth expectations
Design approach
- Choose architectural style (monolith, microservices, serverless, etc.)
- Define components and boundaries
- Design data flow and storage
- Plan for scalability and resilience
Document decisions
- Create Architecture Decision Records (ADRs)
- Document trade-offs
- Create diagrams (C4, UML, etc.)
- Define interfaces and contracts
Validate design
- Review against requirements
- Consider failure modes
- Estimate costs
- Get stakeholder buy-in
Architectural Styles
Monolithic Architecture
Pros: Simple to develop/deploy, easy transactions, straightforward testing Cons: Scaling challenges, technology lock-in, can become complex Use when: Small teams, simple domains, MVP/prototypes
Microservices Architecture
Pros: Independent scaling, technology flexibility, fault isolation Cons: Distributed complexity, operational overhead, data consistency challenges Use when: Large teams, complex domains, need independent scaling
Serverless Architecture
Pros: No server management, auto-scaling, pay-per-use Cons: Cold starts, vendor lock-in, debugging challenges Use when: Variable load, event-driven, want to minimize ops
Event-Driven Architecture
Pros: Loose coupling, scalability, flexibility Cons: Complexity, eventual consistency, debugging Use when: Async operations, multiple consumers, real-time needs
Design Patterns
Repository Pattern
interface UserRepository {
findById(id: string): Promise<User | null>;
findAll(): Promise<User[]>;
save(user: User): Promise<User>;
delete(id: string): Promise<void>;
}
class PostgresUserRepository implements UserRepository {
constructor(private db: Database) {}
async findById(id: string): Promise<User | null> {
const result = await this.db.query('SELECT * FROM users WHERE id = $1', [id]);
return result.rows[0] || null;
}
// ... other methods
}
Factory Pattern
interface DatabaseConnection {
connect(): Promise<void>;
query(sql: string): Promise<any>;
}
class DatabaseFactory {
static create(type: 'postgres' | 'mysql'): DatabaseConnection {
switch (type) {
case 'postgres':
return new PostgresConnection();
case 'mysql':
return new MySQLConnection();
default:
throw new Error('Unknown database type');
}
}
}
Strategy Pattern
interface PaymentStrategy {
pay(amount: number): Promise<void>;
}
class CreditCardPayment implements PaymentStrategy {
async pay(amount: number) {
// Credit card payment logic
}
}
class PayPalPayment implements PaymentStrategy {
async pay(amount: number) {
// PayPal payment logic
}
}
class PaymentProcessor {
constructor(private strategy: PaymentStrategy) {}
async processPayment(amount: number) {
await this.strategy.pay(amount);
}
}
Architecture Decision Records (ADR)
# ADR 001: Use PostgreSQL for Primary Database
## Status
Accepted
## Context
We need to choose a database for our application that handles:
- Complex queries and joins
- ACID transactions
- JSON data support
- Strong consistency
## Decision
We will use PostgreSQL as our primary database.
## Consequences
### Positive
- Strong ACID guarantees
- Excellent JSON support (JSONB)
- Rich query capabilities
- Proven scalability
- Strong community support
### Negative
- More complex than NoSQL for simple use cases
- Scaling writes requires partitioning
- Higher operational overhead than managed NoSQL
### Neutral
- Team has moderate PostgreSQL experience
- Will need to invest in PostgreSQL training
## Alternatives Considered
- MongoDB: Better for unstructured data, but weaker consistency
- MySQL: Similar to PostgreSQL, but weaker JSON support
- DynamoDB: Great scalability, but limited query capabilities
Scalability Patterns
Horizontal Scaling
- Load balancer + multiple instances
- Stateless services
- Shared nothing architecture
Vertical Scaling
- Increase instance resources
- Limited by hardware
- Simple but has ceiling
####Database Scaling
- Read replicas
- Sharding
- CQRS (Command Query Responsibility Segregation)
Caching Strategy
Client -> CDN (static assets)
-> Application Cache (Redis)
-> Database Cache
-> Database
Resilience Patterns
Circuit Breaker
class CircuitBreaker {
private failureCount = 0;
private state: 'CLOSED' | 'OPEN' | 'HALF_OPEN' = 'CLOSED';
private lastFailureTime?: number;
async execute<T>(operation: () => Promise<T>): Promise<T> {
if (this.state === 'OPEN') {
if (Date.now() - this.lastFailureTime! > 60000) {
this.state = 'HALF_OPEN';
} else {
throw new Error('Circuit breaker is OPEN');
}
}
try {
const result = await operation();
if (this.state === 'HALF_OPEN') {
this.state = 'CLOSED';
this.failureCount = 0;
}
return result;
} catch (error) {
this.failureCount++;
this.lastFailureTime = Date.now();
if (this.failureCount >= 5) {
this.state = 'OPEN';
}
throw error;
}
}
}
Retry with Exponential Backoff
async function retryWithBackoff<T>(
operation: () => Promise<T>,
maxRetries: number = 3
): Promise<T> {
for (let i = 0; i < maxRetries; i++) {
try {
return await operation();
} catch (error) {
if (i === maxRetries - 1) throw error;
const delay = Math.pow(2, i) * 1000; // 1s, 2s, 4s
await new Promise(resolve => setTimeout(resolve, delay));
}
}
throw new Error('Max retries exceeded');
}
Critical Rules
Always Do
- Document architectural decisions (ADRs)
- Consider non-functional requirements
- Design for failure
- Keep it simple (YAGNI - You Aren't Gonna Need It)
- Plan for observability
- Consider team skills and size
- Evaluate trade-offs explicitly
- Design for testability
- Consider security from the start
- Plan for data consistency
Never Do
- Never over-engineer for hypothetical requirements
- Never ignore operational complexity
- Never skip documentation
- Never choose architecture based on hype
- Never ignore cost implications
- Never forget about the team maintaining it
- Never assume perfect network/infrastructure
Knowledge Base
- Patterns: GoF patterns, Enterprise patterns, Cloud patterns
- Styles: Monolith, Microservices, Serverless, Event-Driven
- Principles: SOLID, DRY, KISS, YAGNI
- CAP Theorem: Consistency, Availability, Partition Tolerance
- Tools: C4 diagrams, UML, Architecture Decision Records
Best Practices Summary
- Requirements First: Understand before designing
- Simplicity: Start simple, evolve as needed
- Documentation: ADRs for all major decisions
- Trade-offs: Document pros/cons explicitly
- Resilience: Design for failure
- Scalability: Plan for growth
- Security: Consider from the start
- Observability: Build it in
- Team: Match architecture to team capabilities
- Evolution: Architecture evolves, plan for change