aggregate-patterns

Aggregate Design Patterns

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "aggregate-patterns" with this command: npx skills add yonatangross/orchestkit/yonatangross-orchestkit-aggregate-patterns

Aggregate Design Patterns

Design aggregates with clear boundaries, invariants, and consistency guarantees.

Overview

  • Defining transactional consistency boundaries

  • Enforcing business invariants across related entities

  • Designing aggregate roots and their children

  • Handling references between aggregates

  • Optimizing aggregate size for performance

Core Concepts

┌─────────────────────────────────────────────────────────┐ │ ORDER AGGREGATE │ │ ┌─────────────────────────────────────────────────┐ │ │ │ Order (Aggregate Root) │ │ │ │ • id: UUID (UUIDv7) │ │ │ │ • customer_id: UUID (reference by ID!) │ │ │ │ • status: OrderStatus │ │ │ └─────────────────────────────────────────────────┘ │ │ │ │ │ │ ┌────────────────┐ ┌────────────────┐ │ │ │ OrderItem │ │ OrderItem │ │ │ │ (child) │ │ (child) │ │ │ └────────────────┘ └────────────────┘ │ │ │ │ INVARIANTS enforced by root: │ │ • Total = sum of items │ │ • Max 100 items per order │ │ • Cannot modify after shipped │ └─────────────────────────────────────────────────────────┘

Four Rules

  • Root controls access - External code only references aggregate root

  • Transactional boundary - One aggregate per transaction

  • Reference by ID - Never hold references to other aggregates

  • Invariants enforced - Root ensures all business rules

Quick Reference

from dataclasses import dataclass, field from uuid import UUID from uuid_utils import uuid7

@dataclass class OrderAggregate: """Aggregate root with invariant enforcement."""

id: UUID = field(default_factory=uuid7)
customer_id: UUID  # Reference by ID, not Customer object!
_items: list["OrderItem"] = field(default_factory=list)
status: str = "draft"

MAX_ITEMS = 100

def add_item(self, product_id: UUID, quantity: int, price: Money) -> None:
    """Add item with invariant checks."""
    self._ensure_modifiable()
    if len(self._items) >= self.MAX_ITEMS:
        raise DomainError("Max items exceeded")
    self._items.append(OrderItem(product_id, quantity, price))

def _ensure_modifiable(self) -> None:
    if self.status != "draft":
        raise DomainError(f"Cannot modify {self.status} order")

See aggregate-root-template.py for complete implementation.

Key Decisions

Decision Recommendation

Aggregate size Small (< 20 children), split if larger

Cross-aggregate refs Always by ID, never by object

Consistency Immediate within, eventual across

Events Collect in root, publish after persist

See aggregate-sizing.md for sizing guidelines.

Anti-Patterns (FORBIDDEN)

NEVER reference aggregates by object

customer: Customer # WRONG → customer_id: UUID

NEVER modify multiple aggregates in one transaction

order.submit() inventory.reserve(items) # WRONG - use domain events

NEVER expose mutable collections

def items(self) -> list: return self._items # WRONG → return tuple(self._items)

NEVER have unbounded collections

orders: list[Order] # WRONG - grows unbounded

Related Skills

  • domain-driven-design

  • DDD building blocks (entities, VOs)

  • distributed-locks

  • Cross-aggregate coordination

  • idempotency-patterns

  • Safe retries

References

  • Aggregate Sizing - When to split

  • Invariant Enforcement - Business rules

  • Eventual Consistency - Cross-aggregate

Capability Details

aggregate-root

Keywords: aggregate root, consistency boundary, transactional Solves: Design aggregate roots, control child access, enforce boundaries

invariants

Keywords: invariant, business rule, validation, specification Solves: Enforce business rules, validate state, specification pattern

aggregate-sizing

Keywords: aggregate size, small aggregate, performance Solves: Right-size aggregates, when to split, performance trade-offs

cross-aggregate

Keywords: reference by ID, eventual consistency, domain events Solves: Reference other aggregates, coordinate changes, eventual consistency

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

responsive-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
General

domain-driven-design

No summary provided by upstream source.

Repository SourceNeeds Review
General

dashboard-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
General

rag-retrieval

No summary provided by upstream source.

Repository SourceNeeds Review