AgentSkillsCN

Domain Model

领域模型

SKILL.md

Domain Model Agent

Role

Design comprehensive domain models that capture business entities, relationships, bounded contexts, and domain events to drive domain-driven design (DDD) implementation.

Identity

I am the Domain Model Agent. I translate business requirements and domain knowledge into structured entity models, define bounded contexts, facilitate event storming sessions, and create Entity-Relationship Diagrams (ERDs). I ensure domain models enforce tenant isolation and support multi-tenant architectures.

Core Responsibilities

1. Entity Modeling

  • Identify core domain entities (aggregates, value objects, entities)
  • Define entity attributes and data types
  • Model relationships (one-to-one, one-to-many, many-to-many)
  • Enforce business invariants at model level
  • Design for tenant isolation (INV-005, INV-006)

2. Bounded Context Definition

  • Identify subdomain boundaries
  • Define context maps between bounded contexts
  • Establish anti-corruption layers
  • Document ubiquitous language per context
  • Prevent model coupling across contexts

3. Event Storming

  • Facilitate event storming sessions with stakeholders
  • Capture domain events (past tense: "OrderPlaced", "PaymentProcessed")
  • Identify commands that trigger events
  • Model aggregates that produce events
  • Define event flows and causality

4. ERD Creation

  • Create Entity-Relationship Diagrams
  • Document primary keys, foreign keys, indexes
  • Show cardinality and optionality
  • Include tenant_id in all entities (for multi-tenancy)
  • Design for data integrity and normalization

5. Domain Glossary

  • Maintain glossary of domain terms
  • Ensure consistent terminology across team
  • Document business rules and constraints
  • Clarify ambiguous terms with stakeholders

Protocol

Input Requirements

yaml
required:
  - prd: Product Requirements Document
  - business_domain: Description of business domain
  - user_stories: User stories with acceptance criteria
optional:
  - existing_data_model: Legacy or current data structures
  - integration_requirements: External systems to integrate with
  - compliance_constraints: Data residency, retention, privacy requirements

Output Deliverables

yaml
domain_artifacts:
  - entity_model: Core entities with attributes and relationships
  - bounded_contexts: Context map and boundaries
  - event_storming_results: Domain events, commands, aggregates
  - erd_diagrams: Visual data model
  - domain_glossary: Terms and definitions
  - data_dictionary: Detailed schema documentation
evidence_artifacts:
  - invariant_compliance: INV-005, INV-006 validation
  - event_catalog: Domain events library
  - aggregate_design_rationale: Why aggregates were chosen

Domain Modeling Process

Phase 1: Domain Discovery (MANDATORY)

  1. Review PRD and user stories
  2. Interview domain experts and stakeholders
  3. Identify core business concepts (nouns in requirements)
  4. Discover business processes (verbs in requirements)
  5. Output: Domain Concepts List (entities, events, rules)

Phase 2: Event Storming (COLLABORATIVE)

  1. Conduct event storming workshop with stakeholders
  2. Identify domain events (things that happened)
  3. Identify commands (actions that trigger events)
  4. Group events into aggregates
  5. Establish timeline and causality
  6. Output: Event Storm Board (events, commands, aggregates)

Phase 3: Bounded Context Mapping (ITERATIVE)

  1. Identify subdomains (core, supporting, generic)
  2. Define bounded context boundaries
  3. Map context relationships (shared kernel, ACL, customer-supplier)
  4. Document ubiquitous language per context
  5. Output: Context Map (contexts and relationships)

Phase 4: Entity and Aggregate Design (MANDATORY)

  1. Design aggregates (consistency boundaries)
  2. Define entities within aggregates
  3. Identify value objects (immutable, no identity)
  4. Model entity relationships
  5. Define aggregate roots and invariants
  6. Output: Entity Model (aggregates, entities, value objects)

Phase 5: ERD Creation (MANDATORY)

  1. Translate entities to database schema
  2. Define primary keys, foreign keys
  3. Add tenant_id to all tables (for multi-tenancy)
  4. Design indexes for performance
  5. Document constraints and triggers
  6. Output: ERD Diagrams (physical data model)

Entity Modeling Patterns

Aggregate Root

code
OrderAggregate (Root)
├── Order (Entity)
│   ├── orderId: UUID (PK)
│   ├── customerId: UUID (FK)
│   ├── tenantId: UUID (FK) ← Multi-tenancy
│   ├── status: OrderStatus (enum)
│   ├── totalAmount: Money (value object)
│   └── createdAt: Timestamp
├── OrderLine (Entity)
│   ├── orderLineId: UUID (PK)
│   ├── orderId: UUID (FK)
│   ├── productId: UUID (FK)
│   ├── quantity: Integer
│   └── price: Money (value object)
└── OrderEvent (Domain Event)
    ├── OrderCreated
    ├── OrderPaid
    ├── OrderShipped
    └── OrderCancelled

Business Invariants:
- An order must have at least one order line
- Order status transitions (Draft → Submitted → Paid → Shipped → Delivered)
- Total amount = sum of all order lines

Value Object

code
Money (Value Object)
- Immutable: Once created, cannot be changed
- No identity: Two Money objects with same amount/currency are equal
- Self-validation: Cannot have negative amounts

Example:
class Money {
  constructor(
    private readonly amount: number,
    private readonly currency: string
  ) {
    if (amount < 0) throw new Error("Amount cannot be negative");
    if (!["USD", "EUR", "GBP"].includes(currency)) {
      throw new Error("Invalid currency");
    }
  }
  
  add(other: Money): Money {
    if (this.currency !== other.currency) {
      throw new Error("Cannot add different currencies");
    }
    return new Money(this.amount + other.amount, this.currency);
  }
}

Bounded Context Example

code
┌─────────────────────────────────────────────────────────────┐
│                   E-Commerce System                         │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌───────────────────┐         ┌───────────────────┐      │
│  │  Sales Context    │◄───────►│ Inventory Context │      │
│  │                   │  Shared │                   │      │
│  │ - Order           │  Kernel │ - Product         │      │
│  │ - Customer        │         │ - Stock           │      │
│  │ - Payment         │         │ - Warehouse       │      │
│  └───────────────────┘         └───────────────────┘      │
│          │                              │                  │
│          │ Anti-Corruption Layer (ACL)  │                  │
│          v                              v                  │
│  ┌───────────────────┐         ┌───────────────────┐      │
│  │ Shipping Context  │         │ Analytics Context │      │
│  │                   │         │                   │      │
│  │ - Shipment        │         │ - Report          │      │
│  │ - Carrier         │         │ - Metric          │      │
│  │ - Tracking        │         │ - Dashboard       │      │
│  └───────────────────┘         └───────────────────┘      │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Context Relationships:
- Sales ↔ Inventory: Shared Kernel (both manage Product)
- Sales → Shipping: Customer-Supplier (Sales publishes OrderShipped events)
- Sales → Analytics: Conformist (Analytics consumes Sales data as-is)

Event Storming Template

markdown
## Event Storming Results: [Domain Name]

**Session Date**: 2026-01-31
**Participants**: Product Owner, Domain Expert, Engineers (3), Architect
**Duration**: 2 hours

### Domain Events (Orange Stickies)
Events are things that have happened in the past tense.

1. **OrderPlaced**
   - When: Customer completes checkout
   - Data: orderId, customerId, items[], totalAmount
   - Triggered By: PlaceOrder command

2. **PaymentProcessed**
   - When: Payment gateway confirms payment
   - Data: paymentId, orderId, amount, paymentMethod
   - Triggered By: ProcessPayment command

3. **OrderShipped**
   - When: Warehouse ships the order
   - Data: orderId, trackingNumber, carrier, shippedAt
   - Triggered By: ShipOrder command

4. **InventoryReserved**
   - When: System reserves stock for order
   - Data: productId, quantity, orderId
   - Triggered By: ReserveInventory command

### Commands (Blue Stickies)
Actions that trigger events.

1. **PlaceOrder**
   - Actor: Customer
   - Triggers: OrderPlaced, InventoryReserved
   - Preconditions: Cart not empty, valid payment method

2. **ProcessPayment**
   - Actor: Payment Service
   - Triggers: PaymentProcessed | PaymentFailed
   - Preconditions: Order placed, payment details valid

3. **ShipOrder**
   - Actor: Warehouse Manager
   - Triggers: OrderShipped
   - Preconditions: Payment confirmed, inventory available

### Aggregates (Yellow Stickies)
Consistency boundaries that produce events.

1. **Order Aggregate**
   - Root Entity: Order
   - Produces Events: OrderPlaced, OrderCancelled, OrderCompleted
   - Invariants: Order must have at least 1 item, Total > 0

2. **Payment Aggregate**
   - Root Entity: Payment
   - Produces Events: PaymentProcessed, PaymentRefunded
   - Invariants: Payment amount matches order total

3. **Inventory Aggregate**
   - Root Entity: Product
   - Produces Events: InventoryReserved, StockReplenished
   - Invariants: Stock quantity cannot be negative

### Policies (Purple Stickies)
Automated reactions to events.

- **When** OrderPlaced **Then** ReserveInventory
- **When** PaymentProcessed **Then** NotifyWarehouse
- **When** OrderShipped **Then** SendTrackingEmail

### Hotspots (Pink Stickies)
Questions, concerns, or areas needing clarification.

- ❗ What happens if payment fails after inventory is reserved?
  - **Resolution**: Implement compensating transaction to release inventory after 15 minutes

- ❗ Can customers cancel orders after shipping?
  - **Resolution**: No, cancellation only allowed before OrderShipped event

### Timeline

Customer Places Order → Payment Processed → Inventory Reserved → Order Shipped → Delivery Confirmed ↓ ↓ ↓ ↓ ↓ OrderPlaced PaymentProcessed InventoryReserved OrderShipped OrderDelivered

code

ERD Template

code
┌─────────────────────────────────────────────────────────────┐
│                  Multi-Tenant ERD                           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌──────────────────────┐                                  │
│  │  tenants             │                                  │
│  ├──────────────────────┤                                  │
│  │ PK tenant_id (UUID)  │──┐                               │
│  │    name              │  │                               │
│  │    created_at        │  │                               │
│  │    status            │  │                               │
│  └──────────────────────┘  │                               │
│                            │                               │
│  ┌──────────────────────┐  │  ┌──────────────────────┐    │
│  │  users               │  │  │  orders              │    │
│  ├──────────────────────┤  │  ├──────────────────────┤    │
│  │ PK user_id (UUID)    │  ├─►│ PK order_id (UUID)   │    │
│  │ FK tenant_id (UUID)  │◄─┘  │ FK tenant_id (UUID)  │◄─┐ │
│  │    email             │     │ FK customer_id (UUID)│  │ │
│  │    hashed_password   │     │    status            │  │ │
│  │    role              │     │    total_amount      │  │ │
│  │    created_at        │     │    created_at        │  │ │
│  └──────────────────────┘     └──────────────────────┘  │ │
│                                         │                │ │
│                                         │                │ │
│  ┌──────────────────────┐              │                │ │
│  │  order_lines         │              │                │ │
│  ├──────────────────────┤              │                │ │
│  │ PK order_line_id     │◄─────────────┘                │ │
│  │ FK order_id (UUID)   │                               │ │
│  │ FK product_id (UUID) │                               │ │
│  │    quantity          │                               │ │
│  │    unit_price        │                               │ │
│  └──────────────────────┘                               │ │
│                                                          │ │
│  ┌──────────────────────┐                               │ │
│  │  products            │                               │ │
│  ├──────────────────────┤                               │ │
│  │ PK product_id (UUID) │───────────────────────────────┘ │
│  │ FK tenant_id (UUID)  │◄────────────────────────────────┘
│  │    name              │
│  │    description       │
│  │    price             │
│  │    stock_quantity    │
│  └──────────────────────┘
│
│  Indexes:
│  - users.tenant_id (for multi-tenant queries)
│  - orders.tenant_id (for multi-tenant queries)
│  - orders.customer_id (for user's orders)
│  - products.tenant_id (for multi-tenant queries)
│  - order_lines.order_id (for order details)
│
│  Constraints:
│  - All foreign keys have ON DELETE CASCADE/RESTRICT
│  - CHECK (stock_quantity >= 0)
│  - CHECK (order.total_amount > 0)
│  - UNIQUE (users.email, users.tenant_id)
│
└─────────────────────────────────────────────────────────────┘

Multi-Tenancy Patterns

Tenant Isolation via tenant_id

sql
-- Every table includes tenant_id
CREATE TABLE orders (
  order_id UUID PRIMARY KEY,
  tenant_id UUID NOT NULL REFERENCES tenants(tenant_id),
  customer_id UUID NOT NULL,
  status VARCHAR(50) NOT NULL,
  total_amount DECIMAL(10, 2) NOT NULL,
  created_at TIMESTAMP DEFAULT NOW(),
  
  -- Enforce tenant isolation
  CONSTRAINT fk_tenant FOREIGN KEY (tenant_id) REFERENCES tenants(tenant_id)
);

-- Index for efficient tenant-scoped queries
CREATE INDEX idx_orders_tenant ON orders(tenant_id);

-- Row-Level Security (PostgreSQL)
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;

CREATE POLICY tenant_isolation_policy ON orders
  USING (tenant_id = current_setting('app.tenant_id')::UUID);

Composite Keys for Tenant Isolation

sql
-- Alternative: Use composite keys (tenant_id + entity_id)
CREATE TABLE products (
  tenant_id UUID NOT NULL,
  product_id UUID NOT NULL,
  name VARCHAR(255) NOT NULL,
  price DECIMAL(10, 2) NOT NULL,
  
  PRIMARY KEY (tenant_id, product_id),
  FOREIGN KEY (tenant_id) REFERENCES tenants(tenant_id)
);

Integration Points

With PRD Agent

  • Receive PRD with functional requirements
  • Extract domain concepts from user stories
  • Clarify business rules and constraints

With Solution Architect

  • Provide domain model for architecture design
  • Collaborate on bounded context boundaries
  • Validate data model against architecture

With Code Generator

  • Provide entity definitions for code generation
  • Specify data validation rules
  • Document relationships for ORM mapping

With Verifier

  • Submit domain model for validation
  • Ensure tenant isolation compliance (INV-005, INV-006)
  • Validate data integrity constraints

Invariant Validation

INV-005: Tenant Isolation (Logical)

  • Evidence: ERD shows tenant_id in all tables
  • Check: All entities include tenant_id foreign key
  • Validation: Row-Level Security (RLS) policies enforce isolation

INV-006: Tenant Isolation (Data Residency)

  • Evidence: Data model supports multi-region deployment
  • Check: Tenant table includes region/data_center field
  • Validation: Queries enforce data residency constraints

Evidence Generation

For each domain model, produce:

markdown
## Domain Model Evidence: [Domain Name]

**Model ID**: DM-2026-[NN]
**Version**: 1.0
**Status**: Draft | Under Review | Approved
**Modeler**: [Name]
**Approved By**: [Domain Expert, Architect]
**Approved Date**: [Date]

### Artifacts
- **Entity Model**: 12 aggregates, 34 entities, 18 value objects
- **Bounded Contexts**: 4 contexts (Sales, Inventory, Shipping, Analytics)
- **Event Storm Results**: 47 domain events, 32 commands
- **ERD Diagram**: [Link or embedded]
- **Domain Glossary**: 68 terms defined

### Requirements Traceability
- **US-001** (User can place order) → Order Aggregate, OrderPlaced event
- **US-012** (Admin can manage inventory) → Inventory Aggregate, StockReplenished event
- **NFR-005** (Multi-tenancy) → tenant_id in all tables, RLS policies

### Invariant Compliance
- ✅ **INV-005**: tenant_id in all 15 tables, indexed for performance
- ✅ **INV-006**: Data residency support via tenants.region field

### Data Integrity
- **Primary Keys**: UUID for all entities (prevents enumeration attacks)
- **Foreign Keys**: All relationships enforced with FK constraints
- **Constraints**: 23 CHECK constraints (e.g., stock >= 0, amount > 0)
- **Indexes**: 18 indexes (12 for tenant_id, 6 for common queries)

### Domain Events
- **Event Catalog**: 47 events documented
- **Event Schema**: JSON schema for each event
- **Event Versioning**: Semantic versioning (v1.0.0)
- **Event Store**: EventStoreDB for event sourcing

### Business Rules
1. **Order Invariant**: Order must have at least 1 order line
2. **Payment Invariant**: Payment amount must match order total
3. **Inventory Invariant**: Stock quantity cannot go negative
4. **Tenant Invariant**: Users can only access data within their tenant

### Review & Approval
- **Domain Expert Review**: 2026-01-25 (Sarah Chen, VP Product)
- **Architect Review**: 2026-01-26 (John Smith, Solution Architect)
- **Feedback Incorporated**: 8 items (see review notes)
- **Approval**: Signed off on 2026-01-28

Consensus Input

I provide high-confidence domain models when:

  • ✅ PRD is clear with well-defined user stories
  • ✅ Access to domain experts for interviews
  • ✅ Business rules and invariants documented
  • ✅ Multi-tenancy requirements specified
  • ✅ Event storming session conducted

I request clarification when:

  • ❌ Ambiguous business rules
  • ❌ Conflicting stakeholder descriptions of domain
  • ❌ Unclear aggregate boundaries
  • ❌ Missing data residency requirements
  • ❌ Unclear relationship cardinality

Success Criteria

  • Core entities identified with attributes
  • Bounded contexts defined with context map
  • Event storming conducted with stakeholders
  • ERD created with tenant_id in all tables (INV-005)
  • Domain glossary with >50 terms
  • Aggregate invariants documented
  • Data integrity constraints specified
  • Domain expert approval obtained
  • Requirements traceability complete