本文へ移動
cccskills
無料GitHub で公開

domain-analysis

[Architecture] Use when you need to analyze business domain: bounded contexts, aggregates, entities, ERD, domain events, and cross-context integration.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md57.9 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

<!-- PROMPT-ENHANCE:STEP-TASK-ANCHOR:START -->

[BLOCKING] Execute skill steps in declared order. NEVER skip, reorder, or merge steps without explicit user approval. [BLOCKING] Before each step or sub-skill call, update task tracking: set in_progress when step starts, set completed when step ends. [BLOCKING] Every completed/skipped step MUST include brief evidence or explicit skip reason. [BLOCKING] If Task tools are unavailable, create and maintain an equivalent step-by-step plan tracker with the same status transitions.

<!-- PROMPT-ENHANCE:STEP-TASK-ANCHOR:END -->

Quick Summary

Goal: Analyze business domain (bounded contexts, aggregates, entities, VOs, domain events, cross-context relationships) and generate a domain model report + ERD — producing a user-validated DDD domain model with correct bounded contexts, aggregate boundaries, and event flows so downstream implementation builds on the right invariants and avoids costly boundary rework after consumers depend on them.

Summary:

  • Purpose: turn business artifacts into a user-validated DDD domain model (bounded contexts, aggregates, entities, VOs, domain events, ERD) so downstream code builds on correct invariants — never re-cut boundaries after consumers depend on them.
  • Ten ordered steps (do all, none skippable): 0 locate active plan + domain-entities-reference.md → 1 load business context (nouns→entities, verbs→events) → 2 identify bounded contexts → 3 model entities & aggregates → 4 map relationships → 5 domain events → 6 generate Mermaid ERD → 7 user-validation interview → 8 entity-change assessment vs reference doc → 9 update plan.md ## Domain Model.
  • Drive the model from business artifacts, not guesses: load plan/PBI/business-eval inputs and domain-entities-reference.md, then extract nouns→entities, verbs→events, roles, and processes before classifying anything.
  • Every concept passes the Entity-vs-VO matrix and aggregate boundary rules (≤5 entities, one transaction, reference-by-ID only, root is the sole mutation entry) — flag primitive obsession and anemic models as you go.
  • User validation is non-skippable: present bounded contexts and the Mermaid ERD, then run the 5-8 question AskUserQuestion interview to confirm boundaries, aggregate roots, and event flows before marking the model confirmed.
  • Close the loop on persistence: reconcile findings against domain-entities-reference.md (new/modified/deprecated), update the ## Domain Model section of plan.md, and keep cross-context communication event-driven with {AggregateNoun}{PastTenseVerb} naming and no cross-service FKs.

Workflow:

  1. Locate Active Plan & Domain Reference — Glob plans/*/plan.md, read plan + prior research + domain-entities-reference.md; set {plan-dir}
  2. Load Business Context — Read idea, business evaluation, refined PBI artifacts; extract nouns→entities, verbs→events, roles, processes
  3. Identify Bounded Contexts — Group related concepts, define context boundaries (validate grouping with user)
  4. Model Entities & Aggregates — Define aggregates, entities, value objects per context
  5. Map Relationships — Entity relationships, cross-context integration points (context map)
  6. Domain Events — Identify events crossing context boundaries, {AggregateNoun}{PastTenseVerb}
  7. Generate ERD — Mermaid ER diagram with all entities and relationships
  8. User Validation — Present model, ask 5-8 questions, confirm decisions → status: confirmed
  9. Domain Entity Change Assessment — Compare against domain-entities-reference.md, update/create if needed
  10. Update Main Plan — Append/update ## Domain Model section of {plan-dir}/plan.md

Key Rules:

  • MANDATORY IMPORTANT MUST ATTENTION validate every bounded context boundary with user
  • MANDATORY IMPORTANT MUST ATTENTION include Mermaid ERD diagram in report
  • MANDATORY IMPORTANT MUST ATTENTION run user validation interview at end (NEVER skip)
  • Every entity belongs to exactly one bounded context
  • Cross-context communication via domain events only — NEVER direct references

Be skeptical. Every claim needs traced proof, confidence percentages >80% to act.


DDD Reference: Strategic Design

Bounded Context Rules

SignalAction
Same term, different meaning across teamsSeparate bounded contexts
Different data lifecycles for same conceptSeparate contexts
Different invariants on same entitySeparate contexts
Team ownership conflict (Conway's Law)Separate contexts
Shared DB table touched by two servicesExtract shared kernel or introduce ACL

Ubiquitous Language Rules:

  • Every noun in codebase matches domain expert vocabulary exactly (not "User" when the domain says "Customer")
  • Class/method/variable names reflect ubiquitous language — zero translation layers inside bounded context
  • Developers say "we call it X but domain means Y" → model is wrong, fix it

Context Map Pattern Decision Table

SituationPattern
Two teams, joint success/failure, equal powerPartnership
Small shared code nucleus, joint governance acceptableShared Kernel
Downstream can influence upstream roadmapCustomer-Supplier
Downstream has no influence on upstreamConformist
External/legacy system with hostile or polluting modelAnti-Corruption Layer (ACL)
One upstream, many downstream consumersOpen Host Service + Published Language
Integration cost exceeds integration valueSeparate Ways

ACL — when to use: Upstream is external/legacy/third-party (Salesforce, SAP, Workday). Upstream types NEVER cross ACL into domain model.

Shared Kernel — when NOT to use: Teams cannot coordinate on every change → use Customer-Supplier + Published Language instead.


DDD Reference: Entity vs Value Object

Decision Matrix

QuestionEntityValue Object
Has identity beyond its attributes?YESno
Can two instances with same data be distinct?YESno
Has a lifecycle (created, modified, deleted)?YESno
Identified by an ID in any downstream system?YESno
Measured or described (quantity, address, money)?noYES
Replaced rather than modified on change?noYES
Must be found independently of parent?YESno

Fast heuristics:

  • Replace with equal-valued copy → breaks nothing? → Value Object
  • Must be tracked across time or fetched by ID? → Entity
  • Always retrieved as part of another object? → likely Value Object
  • Two instances with same data are interchangeable? → Value Object

Canonical Value Objects

VOAttributesKey Invariants
Moneyamount: Decimal, currency: Currencyamount ≥ 0, valid ISO currency; Add/Subtract require same currency
Emailvalue: stringRFC 5322 format, normalized to lowercase
Addressstreet, city, country, postalCodeAll fields non-empty; composed of Country + PostalCode VOs
DateRangestart: DateOnly, end: DateOnlystart ≤ end; operations: Contains, Overlaps, Duration
PhoneNumbercountryCode, numberE.164 format
Percentagevalue: int0 ≤ value ≤ 100

Primitive Obsession → Value Object Mapping

Primitive UsageReplace With
string orderIdOrderId typed wrapper
decimal amount, string currencyMoney { amount, currency }
string street, string city, string zipAddress { ... }
DateTime start, DateTime endDateRange { start, end }
string emailEmail { value }
int percentagePercentage { value }
string phoneNumberPhoneNumber { countryCode, number }

Rule: Primitive with validation rules, formatting, or always passed grouped with other primitives → missing Value Object.

Value Object Construction Pattern

A VO is self-validating: invariants enforced at construction via a factory (no public constructor that can produce an invalid instance), immutable, and equality-by-value. The base class and factory names below are one illustrative instantiation — translate to your language's equivalents.

Example (illustrative — adapt to your language):

// Self-validating VO — never an invalid instance in memory
public sealed class Email : ValueObject<Email>
{
    private Email(string value) { Value = value; }
    public string Value { get; }

    public static Email Of(string raw)
    {
        var normalized = raw?.Trim().ToLowerInvariant();
        if (string.IsNullOrWhiteSpace(normalized) || !IsValidFormat(normalized))
            throw new DomainException($"Invalid email: {raw}");
        return new Email(normalized);
    }
}

Rules:

  • No public constructor without validation — factory method (Of() / Create()) enforces invariants
  • VOs can reference other VOs; VOs NEVER reference entities (lifecycle coupling)
  • Mutation means replacement: email = Email.Of(newValue), NEVER email.Value = newValue

VO Persistence Strategies

StrategyWhen to UseTrade-offs
Owned types (EF Core)VO maps to same table as owning entitySimple, no FK, nullable columns possible
Embedded document storeVO stored as subdocumentNatural fit, no joins
JSON columnComplex VO, low query frequency on VO fieldsFlexible, not queryable by parts
Serialized stringSimple VOs (Email, PostalCode)Compact, unqueryable by parts

Rule: VOs NEVER have own table with primary key — that makes them entities by infrastructure.


DDD Reference: Entity Design

Identity Strategies

StrategyWhen to UseTrade-offs
ULID (default)New entities in distributed systemSortable, URL-safe, monotonic, 128-bit
UUID v4True randomness / security-sensitive IDsNot sortable, fragmented indexes
UUID v7Sortable UUID neededTime-ordered, good index locality
Natural keyDomain guarantees permanent uniqueness (SSN, EAN)Unstable — domain can change
Surrogate intLegacy/single-DB sequencesNo distributed generation
Composite keyRelationship/join tableHarder to reference from other aggregates

Rules:

  • Prefer ULID for new entities — sortable, no coordination overhead
  • NEVER use email/username as PK — users change them
  • Cross-service references use same ID type as the owning service

Rich vs Anemic Domain Model

Anemic (Anti-Pattern)Rich (Correct)
Entity is data bag, logic in servicesEntity contains behavior + invariants
public set on all propertiesPrivate setters, mutation via named methods
OrderService.Confirm(order)order.Confirm()
Service checks rules then mutates entityEntity refuses invalid state transitions
Logic duplicated across servicesSingle authoritative location in entity

Tell Don't Ask Principle:

  • BAD: if (order.Status == Confirmed) { order.Status = OnHold; } (external ask + mutate)
  • GOOD: order.Hold(reason) (entity enforces its own invariants)

Entity Invariant Enforcement

A rich entity guards its own state: a private constructor reserved for ORM/persistence hydration, named factory methods for valid creation, and intent-named mutation methods that reject invalid transitions and emit domain events. The base class, guard helper, and ID generator below are one illustrative instantiation — substitute your language's equivalents.

Example (illustrative — adapt to your language):

public class Order : AuditedAggregateRoot<Order, string>
{
    private Order() { }  // ORM hydration only

    public static Order Create(string name, Email email, WarehouseId warehouseId)
    {
        Guard.NotNullOrWhitespace(name, nameof(name));
        Guard.NotNull(email, nameof(email));
        return new Order
        {
            Id = Ulid.NewUlid().ToString(),
            Name = name,
            Email = email,
            WarehouseId = warehouseId,
            Status = OrderStatus.Confirmed
        };
    }

    public void Cancel(string reason, DateOnly cancellationDate)
    {
        if (Status == OrderStatus.Cancelled)
            throw new DomainException("Order already cancelled");
        if (cancellationDate < DateOnly.FromDateTime(DateTime.UtcNow))
            throw new DomainException("Cancellation date cannot be in the past");

        Status = OrderStatus.Cancelled;
        CancellationReason = reason;
        CancellationDate = cancellationDate;
        AddDomainEvent(new OrderCancelledDomainEvent(Id, cancellationDate));
    }
}

Entity Lifecycle State Machines

Document ALL transitions explicitly. Unmodeled transitions throw DomainException.

Draft → Submitted (Submit())
Submitted → Approved (Approve(approverId))
Submitted → Rejected (Reject(reason))
Approved → Active (Activate())
Active → Suspended (Suspend(reason))
Suspended → Active (Reinstate())
Active → Archived (Archive())
PatternWhen to Use
Status enum + transition methodsSimple linear/branching lifecycles (most cases)
State pattern (class per state)Complex per-state behavior, many states
Event sourcingFull audit trail + point-in-time reconstruction required

Domain Validation Layers

LayerWhat It ValidatesFailure Signal (per stack)
Value ObjectSingle-value format/range invariantsConstruction failure (raised error or result type)
Entity methodAggregate consistency rules, state transitionsDomain rule violation (e.g. DomainException)
Application serviceCross-aggregate rules, authorization, existenceStructured validation result (e.g. ValidationResult / problem-details payload)
InfrastructureDB constraints (last resort, NEVER first line)Persistence-layer error (last-resort constraint)

Decision rule:

  • Rule requires loading another aggregate? → Application service
  • Rule needs only data within aggregate? → Entity method
  • Rule concerns single value's format? → Value Object constructor

Factory Methods on Entities

Use when: construction requires domain logic, multiple paths, raises domain events, or object graph initialization.

Naming:

  • Order.Create(...) — primary creation
  • Order.Place(...) — semantically loaded creation (domain language)
  • Private constructor — ORM hydration only, NEVER called directly

Temporal (Bi-Temporal) Entities

Two time axes: valid time (fact true in real world) + transaction time (recorded in system).

ProductPrice {
    validFrom: DateOnly     // valid time: price effective from
    validTo: DateOnly       // valid time: price effective until
    recordedAt: DateTime    // transaction time: when entered into system
}

Use when: regulatory compliance, retroactive corrections, "as-of" queries.


DDD Reference: Aggregate Design

Aggregate Boundary Rules

  1. Invariant scope — boundary = objects needed to enforce invariants atomically
  2. Transaction boundary — exactly one database transaction per aggregate operation
  3. Consistency scope — must be consistent atomically? same aggregate. Eventual consistency acceptable? separate aggregates
  4. Small aggregates preferred — fewer members = fewer transaction conflicts = better scalability

Aggregate Size Heuristics

HeuristicGuideline
DefaultStart with single-entity aggregate unless invariant demands more
Add memberOnly when invariant requires atomic consistency across root + member
Max size> 5 entities → redesign; likely missing sub-aggregates
Concurrent writes conflictReduce aggregate size

Aggregate Root Responsibilities

  1. Maintain all invariants across all members
  2. All mutation paths go through root (child entities NEVER directly accessible from outside)
  3. Emit domain events for significant state changes
  4. Control creation of child entities (factory methods on root)
  5. Assign IDs to child entities

Rule: Outside code NEVER holds direct reference to non-root entity within aggregate.

Cross-Aggregate References

RuleDetail
Reference by ID onlyNEVER order.Customer.Name — load separately
No FK object navigationCustomerId field, NEVER Customer Customer navigation property
Cross-aggregate transactions are eventualNeed them in same transaction → boundaries are wrong
Deletion cascadeDomain event → handler → compensating action in other aggregate

Aggregate Invariant Enforcement

All mutation flows through the aggregate root, which checks every invariant before applying a change and recomputes derived state so no member can be left inconsistent. The throw-on-violation idiom below is one illustrative instantiation — your language may surface invariant breaches differently (exceptions, result types).

Example (illustrative — adapt to your language):

public void AddLineItem(ProductId productId, int quantity, Money unitPrice)
{
    if (Status != OrderStatus.Draft)
        throw new DomainException("Cannot modify confirmed order");
    if (LineItems.Count >= 50)
        throw new DomainException("Order cannot exceed 50 line items");

    var item = OrderLineItem.Create(productId, quantity, unitPrice);
    _lineItems.Add(item);
    RecalculateTotal();  // invariant: Total == sum(lineItems)
}

Aggregate Design Patterns

PatternWhen to Use
Single-entity aggregateDefault — most entities are their own aggregate
Nested aggregateInvariant requires atomic consistency across root + children
Aggregate with VOsRoot + embedded value objects (no IDs, no own table)

When to Break Aggregate Rules (Pragmatic DDD)

SituationAcceptable Pragmatism
ORM limitation (EF owned entities)Allow private owned collections even if not strictly necessary
Performance — 1-query loadEmbed child data as VO/owned type rather than separate aggregate
Legacy schema migrationAccept cross-aggregate FK temporarily, document as debt

Rule: Breaking aggregate rules acceptable ONLY when explicitly documented as technical debt with mitigation plan.


DDD Reference: ERD Design

Cardinality Types

CardinalityMermaidWhen to Use
1:1|o--o|Same-table extension, optional sub-type, shared lifecycle
1:N|o--{Parent-child, one entity owns many dependent records
M:N}o--o{Peer relationship; ALWAYS use explicit join/association entity

M:N rule: Relationship has attributes (date joined, role) → make join table explicit named entity.

1:1 decision: Same concept with optional attributes → same table. Different concepts with independent lifecycles → separate tables with FK.

Normalization Targets

Normal FormRuleUse For
1NFAtomic values, no repeating groupsAlways — baseline
2NFNo partial dependency on composite keyComposite PKs only
3NFNo transitive dependenciesOLTP — standard target
BCNFEvery determinant is a candidate keyWhen 3NF still has anomalies
DenormalizedIntentional redundancyRead models, projections, OLAP

Rule: 3NF for OLTP write models; denormalize only in read models/projections with documented justification.

Identifying vs Non-Identifying Relationships

TypeFK in Child PK?Child Existence
IdentifyingYES (FK is part of PK)Child cannot exist without parent (line item without order)
Non-identifyingNO (FK is separate column)Child can exist independently (order without warehouse)

Mapping to DDD: Identifying relationship → child entity inside parent aggregate. Non-identifying FK → likely separate aggregates.

ERD for Microservices

  • Each bounded context has its OWN ERD — NEVER cross-service entity arrows
  • Cross-service references shown as ExternalEntityId (string/ULID) — ID only, no relationship line
  • Shared data shown as replicated/synced data note, NEVER shared table
  • Event-sourced aggregates: ERD shows current state projection, not event stream

ERD Anti-Patterns

Anti-PatternProblemFix
God table (50+ columns)Every feature adds more columnsExtract sub-entities, decompose by bounded context
Cross-service FKDirect FK across microservice schemasReplicate needed data, use events to sync
Polymorphic associationentityType + entityId columnsSeparate tables per concrete type or JSON column
EAV (Entity-Attribute-Value)Key-value rows replacing typed columnsJSON column or explicit schema with migration
Implicit M:N (two FK cols, no PK)Hard to add relationship attributesExplicit join table with surrogate PK
Nullable FK everywhereUnclear cardinalitySeparate optional relationship into explicit table

ERD to Aggregate Mapping

ERD PatternDDD Mapping
Parent-child with identifying relationshipChild entity inside parent aggregate
Parent-child with non-identifying FKLikely separate aggregates (independent lifecycle)
M:N join table with no extra attributesBoth sides separate aggregates, IDs in domain events
M:N join table with attributesAssociation entity as separate aggregate
Strong entity + many weak dependentsRoot entity + owned collection aggregate

DDD Reference: Domain Events

Event Naming Conventions

Format: {AggregateNoun}{PastTenseVerb} — what happened, not what to do.

GoodBad
OrderCancelledCancelOrder (command naming)
OrderConfirmedOrderStatusChanged (too generic)
PaymentProcessedPaymentComplete (not past tense)
SalaryBandUpdatedSalaryChanged (vague)

Event Payload Design Rules

DecisionRule
Minimal vs fatMinimal (default): AggregateId + what changed. Consumer queries for rest if needed
Fat eventAccept when: round-trip cost high AND consumers known AND staleness acceptable
Required fields alwaysAggregateId, OccurredOn (UTC timestamp), Version, CorrelationId
No mutable referencesPayload contains value copies, not object references

Domain Events vs Integration Events

DimensionDomain EventIntegration Event
ScopeWithin one bounded contextAcross bounded contexts
DeliveryIn-process, post-commitVia configured message bus or event stream
Schema ownershipDomain owns, internalPublished Language contract
VersioningInternal refactor freelyVersioned, backward-compatible
Failure handlingTransaction rollbackAt-least-once delivery, idempotent consumer

Rule: Domain event raised → in-process handlers fire → if cross-service needed, handler publishes integration event to message bus.

Event Versioning Strategies

StrategyMechanismTrade-offs
Additive onlyNEVER remove/rename fields, only addSimple, payload bloats over time
Multiple versionsOrderConfirmedV1, OrderConfirmedV2Clear versioning, consumers handle both
UpcastingTransform old events to new on deserializationTransparent to consumers, complex infra

Backward compatibility rules:

  • Adding optional field → backward compatible
  • Removing or renaming field → breaking
  • Changing field type → breaking

DDD Reference: Repository Pattern

Interface Design Principles

  1. One repository per aggregate root — NEVER one for child entities
  2. Domain language in methods — GetConfirmedOrdersInWarehouse() not FindAll(e => e.Status == Active)
  3. Return domain objects — repositories return entities, not DTOs
  4. No infrastructure concerns — no leaked query/ORM types or connection strings in the interface.
  5. Async-first — methods return the configured runtime's async primitive.

Repository vs DAO

RepositoryDAO
Domain-oriented interfaceData-oriented interface
Returns entities/VOsReturns DTOs or raw data
Used in application/domain layerUsed in infrastructure layer
Hides persistence mechanismOften tied to persistence mechanism

Query Objects — When to Use Specification

Use when: rule used in multiple places, warrants naming + testing, needs composition.

A specification names a query predicate as a reusable, composable, testable unit owned by the domain. The expression-tree form below is one illustrative instantiation — your language may model it as a predicate function, query builder, or specification object.

Example (illustrative — adapt to your language):

// Static expression on entity — composable, testable
public static Expression<Func<Order, bool>> ByWarehouseExpression(string warehouseId)
    => o => o.WarehouseId == warehouseId && o.Status == OrderStatus.Confirmed;

When NOT to use Specification: Simple single-use predicate → inline lambda. Rule only used once → repository method directly.


DDD Reference: Anti-Patterns Quick Reference

Anti-PatternDetection SignalFix
Anemic domain modelServices have entity-specific logic; entity has all public settersMove logic to entity
God aggregateAggregate > 5 entities or 100+ ms load timeExtract sub-aggregates
Leaky aggregateExternal code mutates child entities directlyPrivate setters + root mutation methods
Primitive obsession3+ primitives always travel together as groupIntroduce Value Object
Implicit conceptDomain expert names it, code doesn't model itExplicit class
Feature envyMethod uses more of B's data than A'sMove method to B
Getter/setter entityAll mutation via property assignment, no intent-named methodsReplace with Cancel(), Approve(), etc.
Cross-aggregate loadingFull aggregate loaded just to read one fieldPass scalar; resolve in app service
Side effects in handlerCommand handler calls multiple services after saveDomain event + separate handlers
Cross-service FKDatabase FK across microservice schemasID reference + event-driven sync
Shared Kernel overuseTwo teams, one shared model, constant coordination overheadSplit to Customer-Supplier
Missing ACLExternal model types bleed into domain classesACL at integration boundary

Skill Workflow

Step 0: Locate Active Plan & Domain Reference (MANDATORY)

  1. Glob plans/*/plan.md sorted by modification time — find active plan directory
  2. Read plan.md — project scope, goals, prior decisions
  3. Read all {plan-dir}/research/*.md — avoid duplicating prior work
  4. Read docs/project-reference/domain-entities-reference.md (if exists) — project's single source of truth for domain entities
  5. Set {plan-dir} variable — all outputs write to this directory

If no plan directory, create using naming convention from session context.

MUST ATTENTION update {plan-dir}/plan.md with domain model summary section after completing analysis.

Step 1: Load Business Context

Read artifacts from prior workflow steps (search plans/ + team-artifacts/):

  • Active plan ({plan-dir}/plan.md) — scope, goals, constraints
  • Business evaluation report — value proposition, customer segments
  • Refined PBI — acceptance criteria, user stories, features
  • Discovery interview notes — problem statement, user roles

Extract and list:

  • Nouns — Candidate entities (user, order, product, etc.)
  • Verbs — Candidate domain events (created, approved, assigned, etc.)
  • Roles — User types with different permissions/views
  • Processes — Business workflows (application flow, review cycle, etc.)

Step 2: Identify Bounded Contexts

Group related entities using DDD principles. Apply context boundary signals from reference table above.

### Bounded Context: {Name}

**Purpose:** {What this context owns — one sentence}
**Classification:** Core domain / Supporting / Generic
**Key Responsibility:** {primary business capability}
**Team ownership:** {suggested team or role}
**Ubiquitous language:** {key terms and their meaning in this context}

Context boundary tests:

  • Same term used by two teams with different meanings? → separate contexts
  • Two entities with same name but different invariants? → separate contexts
  • Can this context be worked on without understanding the other? → good separation

MANDATORY IMPORTANT MUST ATTENTION present identified contexts to user via AskUserQuestion:

  • "I identified {N} bounded contexts: {list}. Does this grouping make sense?"
  • Options: Agree (Recommended) | Merge {X} and {Y} | Split {Z} | Add missing context

Step 3: Model Entities & Aggregates

Per bounded context: classify each concept using Entity vs VO matrix above, then apply aggregate boundary rules.

### {Context Name}

**Aggregate Root:** {EntityName}
**Identity:** {ULID / UUID / Natural key — justify}
**Lifecycle states:** {Draft → Active → Archived, etc.}

- **Child Entities:** {list — share aggregate boundary, identifying FK}
- **Value Objects:** {list — immutable, no identity, embedded}
- **Invariants:** {business rules this aggregate enforces atomically}
- **Factory method:** {Order.Create(...) / Order.Place(...)}

**Other Aggregates in this Context:**

- {Entity} — {purpose, identity strategy, lifecycle}

Entity Detail Template

EntityClassificationIdentityKey FieldsLifecycle StatesInvariants
{Name}Aggregate Root / Entity / Value ObjectULID / UUID / Composite{fields}{states}{business rules}

VO Composition — MUST ATTENTION verify:

  • 3+ primitives always travel together? → extract VO
  • String field has format rules? → extract VO (Email, PhoneNumber)
  • Numeric field has range rules? → extract VO (Percentage, Money)
  • Concept named by domain experts but not modeled? → make explicit class

Aggregate Boundary — MUST ATTENTION verify:

  • All entities in aggregate enforced in one transaction?
  • Cross-aggregate references use ID only (no navigation properties)?
  • Aggregate root is sole entry point for ALL mutations?
  • Aggregate ≤ 5 entities? If not — justify or decompose

Step 4: Map Relationships

Intra-Context Relationships

| From  | To      | Type | Cardinality   | Relationship Kind       | Description             |
| ----- | ------- | ---- | ------------- | ----------------------- | ----------------------- |
| Order | Product | M:N  | via OrderLine | Non-identifying (assoc) | Orders contain products |

Apply identifying vs non-identifying rule:

  • Identifying relationship (child FK is part of PK) → child entity inside parent aggregate
  • Non-identifying FK → likely separate aggregates

Cross-Context Integration (Context Map)

| Upstream Context | Downstream Context | Pattern | Integration Point  | Sync Mechanism |
| ---------------- | ------------------ | ------- | ------------------ | -------------- |
| Sales            | Order              | ACL     | Cart becomes Order | Domain event   |

Integration patterns to apply (see context map reference table above):

  • Anti-Corruption Layer — external/hostile upstream model
  • Customer-Supplier — downstream can negotiate with upstream
  • Open Host Service — one upstream, many consumers
  • Conformist — no negotiating power with upstream

Step 5: Domain Events

Identify events crossing bounded context boundaries. Apply naming: {AggregateNoun}{PastTenseVerb}.

EventSource ContextTarget Context(s)Payload (minimal)Trigger
OrderPlacedSalesOrder, FulfillmentcartId, productId, placedDateCheckout completed

Event design — MUST ATTENTION verify:

  • Name is past tense + includes aggregate noun?
  • Payload includes AggregateId, OccurredOn (UTC), Version?
  • Payload minimal — just what changed + correlation IDs?
  • Version field included for schema evolution?
  • Domain event vs integration event clearly classified?

Step 6: Generate ERD

Produce Mermaid ER diagram. Apply ERD-to-Aggregate mapping + anti-patterns from reference above.

```mermaid
erDiagram
 %% Bounded Context: {Name}
 ENTITY_A ||--o{ ENTITY_B: "has many"
 ENTITY_A {
 string id PK
 string name
 string status
 datetime createdAt
 }
 ENTITY_B {
 string id PK
 string entityAId FK
 string externalServiceId "ID only - no FK across services"
 string type
 }
```

ERD requirements:

  • Group entities by bounded context (use Mermaid comments %% Context: ...)
  • Show PK/FK fields and key business fields (not all fields)
  • Show cardinality (1:1, 1:N, M:N) using Crow's Foot notation
  • Cross-service references: string/ULID field with comment, no relationship line
  • Identify association entities for M:N relationships

ERD — MUST ATTENTION verify before finalizing:

  • No God tables (>20 columns — consider decomposing)?
  • No cross-service FK arrows?
  • All M:N through explicit named join entity?
  • No nullable FK everywhere (clarify optional relationships)?

Step 7: User Validation Interview

MANDATORY IMPORTANT MUST ATTENTION present domain model and ask 5-8 questions via AskUserQuestion:

Required Questions

  1. Context boundaries — "Are these {N} bounded contexts correct? Any missing or misplaced?"
    • Options: Correct (Recommended) | Need changes | Not sure, explain more
  2. Aggregate roots — "Is {Entity} the right aggregate root for {Context}? It controls {child entities}."
  3. Entity vs VO — "I modeled {concept} as a Value Object because it has no independent identity. Does that match the business model?"
  4. Relationship verification — "The {Entity A} to {Entity B} relationship is {type/cardinality}. Is that correct?"
  5. Missing entities — "Are there business concepts — workflows, roles, rules — I haven't captured as explicit domain objects?"
  6. Event verification — "When {event} happens, should {contexts} be notified? What data do they need?"

Deep-Dive Questions (pick 2-3 based on complexity)

  • "Should {Entity} be a separate aggregate or part of {Aggregate}? [separating = eventual consistency between them]"
  • "Is {field} really a Value Object or does it need its own identity and lifecycle?"
  • "How does {process} work step-by-step? What state transitions are involved?"
  • "What happens when {edge case}? Which invariant prevents the bad state?"
  • "Which entities change most frequently under concurrent load? (impacts aggregate design)"
  • "Any concepts domain experts name that I haven't modeled explicitly?"

After user confirms, update report with final decisions and mark as status: confirmed.

Step 8: Domain Entity Change Assessment (MANDATORY)

MANDATORY IMPORTANT MUST ATTENTION compare domain analysis results against docs/project-reference/domain-entities-reference.md (if exists):

  1. Identify new entities — in analysis but not in reference doc
  2. Identify modified entities — changed fields, relationships, or bounded context assignment
  3. Identify deprecated entities — in reference doc but no longer needed by feature
  4. Present changes to user via AskUserQuestion:
    • "Domain entity changes detected: {N} new, {N} modified, {N} deprecated. Proceed with updating domain-entities-reference.md?"
    • Options: Approve all (Recommended) | Review each change | Skip update

If docs/project-reference/domain-entities-reference.md does NOT exist, ask user:

  • "No domain-entities-reference.md found. Create it with all entities from this analysis?"
  • Options: Yes, create it (Recommended) | No, skip

After user confirms: update/create docs/project-reference/domain-entities-reference.md following existing format. Append new entities to appropriate bounded context section. Update field lists + relationships for modified entities.

Step 9: Update Main Plan (MANDATORY)

Read {plan-dir}/plan.md, append/update ## Domain Model section:

## Domain Model

- **Bounded Contexts:** {N} — {list names with context map patterns between them}
- **Total Entities:** {N} ({N} aggregates, {N} child entities, {N} value objects)
- **Domain Events:** {N} cross-context events
- **Key Aggregates:** {list with invariant summaries}
- **Key Relationships:** {summary of critical relationships}
- **ERD:** See `phase-01-domain-model.md`
- **Full Analysis:** See `research/domain-analysis.md`

Output

{plan-dir}/research/domain-analysis.md          # Full domain analysis report
{plan-dir}/phase-01-domain-model.md             # Confirmed domain model with ERD
{plan-dir}/plan.md                              # Updated with domain model summary
docs/project-reference/domain-entities-reference.md  # Updated/created with new/modified entities

Report structure:

  1. Executive summary (bounded contexts + entity count + key decisions)
  2. Context map (bounded contexts with integration patterns)
  3. Per-context entity/aggregate detail with identity strategy and invariants
  4. Relationship tables (intra + cross-context, identifying vs non-identifying)
  5. Value Objects catalog (VO type, attributes, invariants)
  6. Domain events catalog (with payload design)
  7. Mermaid ERD diagram
  8. Anti-pattern warnings (any detected issues in model)
  9. Unresolved questions

Report must be ≤250 lines. Use tables over prose.


MANDATORY IMPORTANT MUST ATTENTION break work into small todo tasks using TaskCreate BEFORE starting. MANDATORY IMPORTANT MUST ATTENTION validate EVERY bounded context and key relationship with user via AskUserQuestion. MANDATORY IMPORTANT MUST ATTENTION include Mermaid ERD and confidence % for all architectural decisions. MANDATORY IMPORTANT MUST ATTENTION add a final review todo task to verify work quality.


Next Steps

MANDATORY IMPORTANT MUST ATTENTION — NO EXCEPTIONS after completing this skill, use AskUserQuestion to present these options:

  • "/domain-entities-review (Recommended)" — Review DDD quality of entities modeled/modified in this analysis (anemic model, VO classification, invariant enforcement, aggregate boundaries)
  • "/tech-stack-research" — Research tech stack based on domain model
  • "/plan" — If tech stack already decided and entity quality already reviewed
  • "Skip, continue manually" — user decides

Council escalation (always-offer, second prompt)

After the existing ## Next Steps prompt above resolves, present a second, independent AskUserQuestion call (do NOT merge into the first):

  • "Skip council — proceed with model (Recommended)" — Continue with the bounded contexts / aggregate boundaries as drawn. Recommended default.
  • "Escalate to /llm-council" — Run 11 sub-agent council (5 advisors + 5 reviewers + chairman). Best applied when bounded-context splits or aggregate boundaries are contested (multiple defensible cuts), the model touches >=3 services, or invariants span aggregates. DDD boundary decisions are hard to reverse once consumers depend on them. Cheaper alternatives: /why-review, /plan-validate (run these first if you haven't).

MANDATORY IMPORTANT MUST ATTENTION use TaskCreate to break ALL work into small tasks BEFORE starting. MANDATORY IMPORTANT MUST ATTENTION use AskUserQuestion at EVERY decision point — validate every bounded context and entity relationship with user. MANDATORY IMPORTANT MUST ATTENTION produce ERD diagram (Mermaid) and domain model report with confidence %.

External Memory: For complex or lengthy work (research, analysis, scan, review), write intermediate findings and final results to a report file in plans/reports/ — prevents context loss and serves as deliverable.

Evidence Gate: MANDATORY IMPORTANT MUST ATTENTION — every claim, finding, and recommendation requires file:line proof or traced evidence with confidence percentage (>80% to act, <80% must verify first).


<!-- SYNC:ai-mistake-prevention -->

AI Mistake Prevention — Failure modes to avoid on every task:

Re-read files after context changes. Context compaction, resume, or long-running work can make memory stale; verify current files before acting. Verify generated content against source evidence. AI hallucinates APIs, names, claims, and document facts. Check the relevant source before documenting or referencing. Check downstream references before deleting or renaming. Removing an artifact can stale docs, generated mirrors, configs, and callers; map references first. Trace the full impact chain after edits. Changing a definition can miss derived outputs and consumers. Follow the affected chain before declaring done. Verify ALL affected outputs, not just the first. One green check is not all green checks; validate every output surface the change can affect. Assume existing values are intentional — ask WHY before changing OR flagging one as a defect. Before changing or reporting a constant, limit, flag, cutoff, wording, or pattern, read nearby context and history, the CALLER's ordering, and 2+ sibling call sites of the same convention. A doc stating WHAT without WHY is missing rationale, not proof of a missing guard. Surface ambiguity before acting — don't pick silently. Multiple valid interpretations require an explicit question or stated assumption with risk. Assert the outcome your system owns, not the intermediate state your infrastructure owns. When verifying async work, assert the final business state — never the delivery/retry bookkeeping held in shared infrastructure that any co-running process can write. Such a check passes when run alone and flakes the moment anything else shares that infrastructure. Keep shared guidance role-relevant. Universal guidance must help every receiving skill or agent; code-specific obligations belong only in code-specific protocols.

<!-- /SYNC:ai-mistake-prevention --> <!-- SYNC:critical-thinking-mindset -->

Critical Thinking Mindset — Apply critical thinking, sequential thinking. Every claim needs traced proof, confidence >80% to act. Anti-hallucination: Never present guess as fact — cite sources for every claim, admit uncertainty freely, self-check output for errors, cross-reference independently, stay skeptical of own confidence — certainty without evidence root of all hallucination.

<!-- /SYNC:critical-thinking-mindset --> <!-- SYNC:critical-thinking-mindset:reminder -->

MUST ATTENTION apply critical + sequential thinking — every claim needs appropriate traced evidence (file:line for repo/code claims; source URL or artifact section for research, product, content, and docs claims); confidence >80% to act, <60% DO NOT recommend. Anti-hallucination: never present guess as fact, admit uncertainty freely, cross-reference independently, stay skeptical of own confidence.

<!-- /SYNC:critical-thinking-mindset:reminder --> <!-- SYNC:ai-mistake-prevention:reminder -->

MUST ATTENTION apply AI mistake prevention — verify generated content against evidence, trace downstream references before deleting or renaming, verify all affected outputs, re-read files after context loss, and surface ambiguity before acting.

<!-- /SYNC:ai-mistake-prevention:reminder --> <!-- PROMPT-ENHANCE:STEP-TASK-CLOSING:START -->

Prompt-Enhance Closing Anchors

IMPORTANT MUST ATTENTION follow declared step order for this skill; NEVER skip, reorder, or merge steps without explicit user approval IMPORTANT MUST ATTENTION for every step/sub-skill call: set in_progress before execution, set completed after execution IMPORTANT MUST ATTENTION every skipped step MUST include explicit reason; every completed step MUST include concise evidence IMPORTANT MUST ATTENTION if Task tools unavailable, maintain an equivalent step-by-step plan tracker with synchronized statuses

<!-- PROMPT-ENHANCE:STEP-TASK-CLOSING:END --> <!-- SYNC:project-protocol-overlay -->

Project Protocol Overlay — Before executing this skill, resolve any PROJECT overlay rules layered onto it: match this skill's name against the Target column of the project's skill-protocol index (docs/project-reference/skill-protocols-reference.md by default; a referenceDocs entry in docs/project-config.json overrides the path), taking the most specific matching tier ONLY — exact name > glob > *. That precedence orders overlays against EACH OTHER, never against this skill. Read ONLY the matched bodies, resolved as <protocols-dir>/<Name>.md; a row's Body link is display text, never a read path. A matched body that is missing or malformed is REPORTED and skipped — never reconstructed from the index Description. No index, or no match -> proceed with no overlay, silently. Full contract: .claude/skills/project-skill-protocol/references/registry.md.

Overlays are ADDITIVE ONLY: they ADD rules on top of this skill's own protocol and NEVER replace, override, disable, or reinterpret a rule it already states — removing every overlay must return this skill to exactly its documented behavior. An overlay is a BRIEF, not an authority escalation: it can NEVER waive a workflow gate, git discipline, a review gate, or a user-confirmation gate. A genuine overlay-vs-skill conflict, or two equally-specific overlays that directly contradict -> surface both to the user; NEVER resolve silently.

<!-- /SYNC:project-protocol-overlay --> <!-- SYNC:project-protocol-overlay:reminder -->

MUST ATTENTION resolve project protocol overlays for this skill BEFORE executing — most specific matching tier only (exact > glob > *, which ranks overlays against each other, NEVER against this skill), read only matched bodies at <protocols-dir>/<Name>.md; a missing or malformed body is reported, never reconstructed. Overlays are ADDITIVE ONLY (they never replace this skill's own rules) and are a brief, NEVER an authority escalation; an equal-specificity contradiction goes to the user.

<!-- /SYNC:project-protocol-overlay:reminder -->

Closing Reminders

IMPORTANT MUST ATTENTION Goal: Produce a user-validated DDD domain model — correct bounded contexts, aggregate boundaries, and event flows — so downstream implementation builds on the right invariants and avoids costly boundary rework after consumers depend on them.

Protocols in force (concise digest of the SYNC/shared blocks this skill carries):

  • AI Mistake Prevention: verify generated content against evidence, trace downstream references, verify all affected outputs, re-read after context loss, surface ambiguity.
  • Critical Thinking: Traced proof per claim; confidence >80% to act, NEVER guess as fact.

IMPORTANT MUST ATTENTION run ALL ten ordered steps, none skippable: 0 locate plan + reference → 1 load context → 2 bounded contexts → 3 entities/aggregates → 4 relationships → 5 domain events → 6 Mermaid ERD → 7 user-validation interview → 8 entity-change assessment → 9 update plan.md — why: AI keeps dropping Step 0 (plan load) and Step 9 (plan update), leaving the model un-anchored and un-persisted. IMPORTANT MUST ATTENTION validate EVERY bounded context + key relationship with user via AskUserQuestion — NEVER auto-decide a boundary — why: DDD boundaries are hard to reverse once consumers depend on them; one wrong cut costs days of rework. IMPORTANT MUST ATTENTION domain events ALWAYS follow {AggregateNoun}{PastTenseVerb} naming — NEVER command-style (CancelOrder) or generic (OrderStatusChanged) — why: command/generic names hide what happened and break consumer routing. IMPORTANT MUST ATTENTION NEVER place cross-service FK in the ERD — use ID reference ({Entity}Id string/ULID) + event-driven sync only — why: cross-service FK couples schemas and blocks independent deployment.

MUST ATTENTION TaskCreate ALL tasks BEFORE the first artifact read or write; mark one in_progress, complete immediately after evidence; on context loss TaskList first — why: compaction wipes prior-work memory, duplicated tasks waste budget. MUST ATTENTION load business artifacts FIRST (plan/PBI/business-eval + domain-entities-reference.md) and derive nouns→entities, verbs→events — NEVER model from guesses — why: a model built on assumptions encodes the wrong invariants. MUST ATTENTION search 3+ existing entities in domain-entities-reference.md before introducing a new one; reconcile new/modified/deprecated against it and follow its existing format — why: divergent or duplicated domain models fragment the source of truth. MUST ATTENTION evaluate fit before reusing a nearby aggregate/VO pattern — verify the new concept shares the same identity, lifecycle, and transaction scope — why: closest example ≠ matching preconditions. MUST ATTENTION entity vs VO classification — replace with equal-valued copy breaks nothing? → Value Object. Tracked across time or fetched by ID? → Entity. Flag primitive obsession (3+ primitives travel together) and anemic models as you go. MUST ATTENTION every aggregate passes boundary rules — ≤5 entities, one transaction, reference-by-ID only, root is the sole mutation entry; >5 entities → decompose or justify as documented debt. MUST ATTENTION include the Mermaid ERD and a confidence % (>80% to act, <80% verify first) for EVERY architectural decision; cite file:line / artifact evidence — NEVER present a boundary or classification as fact without traced proof. MUST ATTENTION persist intermediate findings to plans/reports/ incrementally and add a final review task to verify work quality — why: long analysis hits context cutoffs; batched writes lose findings.

Anti-Rationalization:

EvasionRebuttal
"Boundaries are obvious, skip user validation"User validation is non-skippable — run the 5-8 question AskUserQuestion interview.
"Already know the entities, skip reference doc"Show file:line from domain-entities-reference.md. No proof = not checked.
"This concept is clearly an entity"Run the Entity-vs-VO matrix anyway — state confidence %. Pattern-matching skips context.
"Small model, skip task tracking"Still TaskCreate first. Skip depth, never skip tracking.
"Cross-service link is just one FK"Never — ID reference + event-driven sync. One FK couples two schemas permanently.

[TASK-PLANNING] Before acting, analyze task scope and systematically break it into small todo tasks and sub-tasks using TaskCreate.

IMPORTANT MUST ATTENTION validate EVERY bounded context with the user, name domain events {AggregateNoun}{PastTenseVerb}, and keep cross-service links as ID-reference + events — these three are the most-skipped, highest-blast-radius rules of this skill.

[IMPORTANT] Analyze how big the task is and break it into many small todo tasks systematically before starting — this is very important.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

[Architecture] Use when designing solution architecture across backend, frontend, data & consistency, integration & APIs, deployment, monitoring, testing, and code quality. Architecture laws, style-selection triggers, coupling taxonomy, trade-off tables and the anti-pattern catalog live in `.claude/docs/architecture-knowledge.md`.

日本語の概要は準備中です。原文の説明を表示しています。

duc01226/EasyPlatform112026年8月21日 更新

[Code Quality] Use when reviewing architecture compliance for layers, messaging, service boundaries, CQRS, repos, entity events, and data/consistency/tenancy boundaries. Universal architecture laws, coupling taxonomy and the anti-pattern catalog live in `.claude/docs/architecture-knowledge.md` (project docs always outrank it).

日本語の概要は準備中です。原文の説明を表示しています。

duc01226/EasyPlatform112026年8月21日 更新

[Architecture] Use when auditing the ENTIRE project architecture and production readiness in one pass — bundles architecture-review + architecture-scalability-review + production-readiness-review at project or diff scope, then synthesizes one consolidated Architecture Health Report.

日本語の概要は準備中です。原文の説明を表示しています。

duc01226/EasyPlatform112026年8月21日 更新

[Architecture] Use when grading project architecture and scalability quality for greenfield init or brownfield audit: build/CI scalability, distributed-monolith risk, module isolation, dependency discipline, loose coupling, horizontal scaling, DRY, abstraction, clean architecture, observability, and delivery.

日本語の概要は準備中です。原文の説明を表示しています。

duc01226/EasyPlatform112026年8月21日 更新

[Code Quality] Use when you need to review artifact quality (PBI, user story, test spec, design spec) before handoff. Supports --type={pbi|story|spec-tests|design}.

日本語の概要は準備中です。原文の説明を表示しています。

duc01226/EasyPlatform112026年8月21日 更新

ask

無料

[Utilities] Use when you need to answer technical and architectural questions.

日本語の概要は準備中です。原文の説明を表示しています。

duc01226/EasyPlatform112026年8月21日 更新

duc01226 のスキルをすべて見る

このスキルの問題を報告する