Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ community a harassment-free experience for everyone.
## Our Standards

Examples of behavior that contributes to a positive environment:

- Using welcoming and inclusive language
- Being respectful of differing viewpoints
- Gracefully accepting constructive criticism
Expand Down
8 changes: 4 additions & 4 deletions reports/generated/structure-audit.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"broken_links": 0,
"orphans": 0,
"hub_violations": 0,
"timestamp": "2026-01-01T03:29:23.909136"
"broken_links": 0,
"hub_violations": 0,
"orphans": 0,
"timestamp": "2026-01-01T03:29:23.909136"
}
285 changes: 247 additions & 38 deletions skills/architecture/patterns/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
name: patterns
description: Patterns standards for patterns in Architecture environments. Covers
description: "Applies architectural design patterns including microservices decomposition, event-driven architecture, hexagonal/ports-and-adapters, CQRS, and domain-driven design bounded contexts. Use when the user asks about system design, architectural patterns, service boundaries, event sourcing, CQRS, hexagonal architecture, or domain-driven design."
---

# Patterns
# Architecture Patterns

> **Quick Navigation:**
> Level 1: [Quick Start](#level-1-quick-start) (5 min) β†’ Level 2: [Implementation](#level-2-implementation) (30 min) β†’ Level 3: [Mastery](#level-3-mastery-resources) (Extended)
Expand All @@ -14,61 +14,274 @@ description: Patterns standards for patterns in Architecture environments. Cover

### Core Principles

1. **Best Practices**: Follow industry-standard patterns for architecture
2. **Security First**: Implement secure defaults and validate all inputs
3. **Maintainability**: Write clean, documented, testable code
4. **Performance**: Optimize for common use cases
1. **Separation of Concerns**: Each component owns a single responsibility
2. **Loose Coupling**: Services communicate through well-defined interfaces
3. **High Cohesion**: Related functionality lives together
4. **Dependency Inversion**: Depend on abstractions, not implementations

### Essential Checklist
### Pattern Selection Guide

- [ ] Follow established patterns for architecture
- [ ] Implement proper error handling
- [ ] Add comprehensive logging
- [ ] Write unit and integration tests
- [ ] Document public interfaces
| Pattern | Best For | Trade-off |
|---------|----------|-----------|
| Hexagonal | Testable domain logic | More initial boilerplate |
| CQRS | Read/write asymmetry | Eventual consistency complexity |
| Event-Driven | Decoupled services | Debugging distributed flows |
| Microservices | Independent deployability | Operational overhead |
| Layered | Simple CRUD apps | Tight coupling risk at scale |

### Quick Links to Level 2
### Essential Checklist

- [Core Concepts](#core-concepts)
- [Implementation Patterns](#implementation-patterns)
- [Common Pitfalls](#common-pitfalls)
- [ ] Define bounded contexts before splitting services
- [ ] Establish communication patterns (sync vs async)
- [ ] Design for failure (circuit breakers, retries, timeouts)
- [ ] Document architectural decision records (ADRs)
- [ ] Validate with fitness functions

---

## Level 2: Implementation

### Core Concepts
### Hexagonal Architecture (Ports & Adapters)

```typescript
// Domain layer β€” no framework dependencies
interface OrderRepository {
save(order: Order): Promise<void>;
findById(id: string): Promise<Order | null>;
}

interface PaymentGateway {
charge(amount: Money, method: PaymentMethod): Promise<PaymentResult>;
}

class PlaceOrderUseCase {
constructor(
private orders: OrderRepository,
private payments: PaymentGateway
) {}

async execute(cmd: PlaceOrderCommand): Promise<OrderId> {
const order = Order.create(cmd.items, cmd.customerId);
const payment = await this.payments.charge(order.total, cmd.paymentMethod);
order.confirmPayment(payment.transactionId);
await this.orders.save(order);
return order.id;
}
}

// Infrastructure adapter β€” implements the port
class PostgresOrderRepository implements OrderRepository {
constructor(private pool: Pool) {}

async save(order: Order): Promise<void> {
await this.pool.query(
"INSERT INTO orders (id, customer_id, total, status) VALUES ($1, $2, $3, $4)",
[order.id, order.customerId, order.total.amount, order.status]
);
}

async findById(id: string): Promise<Order | null> {
const result = await this.pool.query("SELECT * FROM orders WHERE id = $1", [id]);
return result.rows[0] ? Order.fromRow(result.rows[0]) : null;
}
}
```

### CQRS (Command Query Responsibility Segregation)

```typescript
// Command side β€” validates and writes
class CreateProductHandler {
constructor(
private repo: ProductRepository,
private eventBus: EventBus
) {}

async handle(cmd: CreateProduct): Promise<void> {
const product = Product.create(cmd.name, cmd.price, cmd.category);
await this.repo.save(product);
await this.eventBus.publish(new ProductCreated(product.id, product.name));
}
}

// Query side β€” optimized read model
class ProductQueryService {
constructor(private readDb: ReadDatabase) {}

async search(filters: ProductFilters): Promise<ProductListItem[]> {
return this.readDb.query(
"SELECT id, name, price, category FROM product_read_model WHERE category = $1 ORDER BY name LIMIT $2",
[filters.category, filters.limit]
);
}
}

// Event handler keeps read model in sync
class ProductReadModelUpdater {
constructor(private readDb: ReadDatabase) {}

async onProductCreated(event: ProductCreated): Promise<void> {
await this.readDb.query(
"INSERT INTO product_read_model (id, name) VALUES ($1, $2)",
[event.productId, event.productName]
);
}
}
```

### Event-Driven Architecture

This skill covers essential practices for architecture.
```typescript
// Domain event
interface DomainEvent {
type: string;
aggregateId: string;
timestamp: Date;
payload: Record<string, unknown>;
}

**Key areas include:**
// Event producer
class OrderService {
constructor(
private repo: OrderRepository,
private eventBus: EventBus
) {}

- Architecture patterns
- Implementation best practices
- Testing strategies
- Performance optimization
async cancelOrder(orderId: string, reason: string): Promise<void> {
const order = await this.repo.findById(orderId);
order.cancel(reason);
await this.repo.save(order);
await this.eventBus.publish({
type: "order.cancelled",
aggregateId: orderId,
timestamp: new Date(),
payload: { reason, customerId: order.customerId },
});
}
}

### Implementation Patterns
// Decoupled consumers react independently
class NotificationService {
@Subscribe("order.cancelled")
async onOrderCancelled(event: DomainEvent): Promise<void> {
await this.emailService.send(
event.payload.customerId,
"order-cancelled",
{ orderId: event.aggregateId, reason: event.payload.reason }
);
}
}

Apply these patterns when working with architecture:
class InventoryService {
@Subscribe("order.cancelled")
async onOrderCancelled(event: DomainEvent): Promise<void> {
await this.restoreStock(event.aggregateId);
}
}
```

1. **Pattern Selection**: Choose appropriate patterns for your use case
2. **Error Handling**: Implement comprehensive error recovery
3. **Monitoring**: Add observability hooks for production
### Circuit Breaker Pattern

### Common Pitfalls
```typescript
class CircuitBreaker {
private failures = 0;
private lastFailure: Date | null = null;
private state: "closed" | "open" | "half-open" = "closed";

Avoid these common mistakes:
constructor(
private threshold: number = 5,
private resetTimeout: number = 30000
) {}

- Skipping validation of inputs
- Ignoring edge cases
- Missing test coverage
- Poor documentation
async execute<T>(operation: () => Promise<T>): Promise<T> {
if (this.state === "open") {
if (Date.now() - this.lastFailure!.getTime() > this.resetTimeout) {
this.state = "half-open";
} else {
throw new Error("Circuit breaker is open");
}
}

try {
const result = await operation();
this.onSuccess();
return result;
} catch (error) {
this.onFailure();
throw error;
}
}

private onSuccess(): void {
this.failures = 0;
this.state = "closed";
}

private onFailure(): void {
this.failures++;
this.lastFailure = new Date();
if (this.failures >= this.threshold) {
this.state = "open";
}
}
}
```

### Integration Points

- Links to [Coding Standards](../../coding-standards/SKILL.md) for implementation patterns
- Links to [Testing Standards](../../testing/SKILL.md) for architecture testing strategies
- Links to [Security Practices](../../security-practices/SKILL.md) for secure architecture

---

## Level 3: Mastery Resources

### Architecture Decision Records (ADRs)

```markdown
# ADR-001: Use Event-Driven Architecture for Order Processing

## Status: Accepted

## Context
Order processing requires notifying multiple downstream services
(inventory, shipping, billing) without tight coupling.

## Decision
Adopt event-driven architecture with an event bus for inter-service communication.

## Consequences
- (+) Services can be deployed independently
- (+) New consumers can subscribe without modifying producers
- (-) Eventual consistency requires careful handling
- (-) Debugging distributed flows requires correlation IDs and distributed tracing
```

### Fitness Functions

```typescript
// Architectural fitness function β€” enforce dependency direction
import { Project, SyntaxKind } from "ts-morph";

function validateNoCoreToInfraImports(projectPath: string): boolean {
const project = new Project({ tsConfigFilePath: `${projectPath}/tsconfig.json` });
const coreFiles = project.getSourceFiles("src/core/**/*.ts");

for (const file of coreFiles) {
const imports = file.getImportDeclarations();
for (const imp of imports) {
const moduleSpecifier = imp.getModuleSpecifierValue();
if (moduleSpecifier.includes("/infrastructure/") || moduleSpecifier.includes("/adapters/")) {
console.error(`Violation: ${file.getFilePath()} imports from infrastructure`);
return false;
}
}
}
return true;
}
```

### Reference Materials

- [Related Standards](../../docs/standards/)
Expand All @@ -77,7 +290,3 @@ Avoid these common mistakes:
### Templates

See the `templates/` directory for starter configurations.

### External Resources

Consult official documentation and community best practices for architecture.
Loading
Loading