Agent Skills: Architect Skill

DDD and hexagonal architecture with functional core pattern. Use when designing features, modeling domains, breaking down tasks, or understanding component responsibilities.

UncategorizedID: martinffx/claude-code-atelier/oracle-architect

Install this agent skill to your local

pnpm dlx add-skill https://github.com/martinffx/atelier/tree/HEAD/skills/oracle-architect

Skill Files

Browse the full folder contents for oracle-architect.

Download Skill

Loading file tree…

skills/oracle-architect/SKILL.md

Skill Metadata

Name
oracle-architect
Description
DDD and hexagonal architecture with functional core pattern. Use when designing features, modeling domains, breaking down tasks, or understanding component responsibilities.

Architect Skill

Domain-Driven Design and hexagonal architecture with functional core pattern for feature design.

Architecture Model

Unified view of functional core and effectful edge:

          Effectful Edge (IO)              Functional Core (Pure)
┌─────────────────────────────────┐    ┌──────────────────────────┐
│  Router    → request parsing    │    │  Service  → orchestration│
│  Consumer  → event handling     │───▶│  Entity   → domain rules │
│  Client    → external APIs      │    │            → validation  │
│  Producer  → event publishing   │◀───│            → transforms  │
│  Repository→ data persistence   │    │                          │
└─────────────────────────────────┘    └──────────────────────────┘

Key Principle: Business logic lives in the functional core (Service + Entity). IO operations live in the effectful edge. Core defines interfaces; edge implements them (dependency inversion).

Functional Core

Pure, deterministic components containing all business logic.

Service Layer

Responsibility: Orchestrate business operations, coordinate between entities and repositories.

Characteristics:

  • Pure functions that take data and return results
  • No IO operations (database, HTTP, file system)
  • Calls repositories through interfaces (dependency injection)
  • Composes entity operations into workflows
  • Returns success/error results

Example:

class OrderService {
  async createOrder(request: CreateOrderRequest): Promise<Result<Order>> {
    // Validate with entity
    const order = Order.fromRequest(request);
    const validation = order.validate();
    if (!validation.ok) return validation;

    // Check business rules
    const inventory = await this.inventoryRepo.checkAvailability(order.items);
    if (!inventory.available) return Err('Items not available');

    // Coordinate persistence
    await this.inventoryRepo.reserve(order.items);
    const saved = await this.orderRepo.save(order.toRecord());

    return Ok(Order.fromRecord(saved));
  }
}

Entity Layer

Responsibility: Domain models, validation, business rules, data transformations.

Characteristics:

  • Pure data structures with behavior
  • All validation logic
  • Data transformations (fromRequest, toRecord, toResponse)
  • Business rules and invariants
  • No IO, no framework dependencies

Example:

class Order {
  constructor(
    public readonly id: string,
    public readonly customerId: string,
    public readonly items: OrderItem[],
    public readonly status: OrderStatus,
    public readonly total: number
  ) {}

  static fromRequest(req: CreateOrderRequest): Order {
    return new Order(
      generateId(),
      req.customerId,
      req.items.map(i => new OrderItem(i)),
      'pending',
      req.items.reduce((sum, i) => sum + i.price * i.quantity, 0)
    );
  }

  toRecord(): OrderRecord {
    return {
      id: this.id,
      customer_id: this.customerId,
      items: JSON.stringify(this.items),
      status: this.status,
      total: this.total
    };
  }

  validate(): Result<Order> {
    if (this.items.length === 0) {
      return Err('Order must have at least one item');
    }
    if (this.total < 0) {
      return Err('Order total cannot be negative');
    }
    return Ok(this);
  }

  canCancel(): boolean {
    return ['pending', 'confirmed'].includes(this.status);
  }
}

Effectful Edge

IO-performing components that interact with the outside world.

Router

Responsibility: HTTP request handling, parsing, response formatting.

Characteristics:

  • Parses HTTP requests into domain types
  • Calls service layer with parsed data
  • Formats service results into HTTP responses
  • Handles HTTP-specific concerns (status codes, headers)
  • No business logic

Example:

router.post('/orders', async (req, res) => {
  const result = await orderService.createOrder(req.body);

  if (result.ok) {
    res.status(201).json(result.value.toResponse());
  } else {
    res.status(400).json({ error: result.error });
  }
});

Repository

Responsibility: Data persistence and retrieval.

Characteristics:

  • Implements data access interface used by services
  • Converts between domain entities and database records
  • Handles database queries and transactions
  • No business logic or validation

Example:

class OrderRepository {
  async save(record: OrderRecord): Promise<OrderRecord> {
    return await db.orders.create(record);
  }

  async findById(id: string): Promise<OrderRecord | null> {
    return await db.orders.findOne({ id });
  }
}

Component Matrix

Quick reference for where things belong:

| Concern | Component | Layer | Testability | |---------|-----------|-------|-------------| | Domain model | Entity | Core | Unit test (pure) | | Validation | Entity | Core | Unit test (pure) | | Business rules | Entity | Core | Unit test (pure) | | Orchestration | Service | Core | Unit test (stub repos) | | Data transforms | Entity | Core | Unit test (pure) | | HTTP parsing | Router | Edge | Integration test | | Data access | Repository | Edge | Integration test | | External APIs | Client | Edge | Integration test | | Event handling | Consumer | Edge | Integration test | | Event publishing | Producer | Edge | Integration test |

Task Breakdown

Bottom-Up Dependency Ordering

Implementation order follows dependency chain:

1. Entity   → Domain models, validation, transforms
2. Repository → Data access interfaces and implementations
3. Service  → Business logic orchestration
4. Router   → HTTP endpoints

Rationale: Each layer depends on layers below. Can't implement service without entity, can't implement router without service.

Task Granularity

One task per layer:

  • Implement Order entity with validation
  • Implement OrderRepository with data access
  • Implement OrderService with business logic
  • Implement order API endpoints

For complex features, break down further:

  • Entity: Order, OrderItem, OrderStatus
  • Repository: OrderRepository, InventoryRepository
  • Service: OrderService, PaymentService
  • Router: Order routes, Payment routes

Architect → Testing Flow

Architectural decisions inform testing strategy:

Architect Outputs           →    Testing Inputs
────────────────────────────────────────────────
Component responsibilities  →    What to test
Layer boundaries           →    Where to test
Pure vs effectful          →    Unit vs integration
Entity transformations     →    Property-based tests
Service orchestration      →    Stub-driven tests

The testing skill uses architectural structure to determine:

  • What gets unit tested (core) vs integration tested (edge)
  • Where to place test boundaries
  • What to stub and what to test for real
  • What test cases validate business rules

Reference Materials

For detailed patterns and examples: