m09-domain

CRITICAL: Use for domain modeling. Triggers: domain model, DDD, domain-driven design, entity, value object, aggregate, repository pattern, business rules,…

INSTALLATION
npx skills add https://github.com/actionbook/rust-skills --skill m09-domain
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

Domain Modeling

Layer 2: Design Choices

Core Question

What is this concept's role in the domain?

Before modeling in code, understand:

  • Is it an Entity (identity matters) or Value Object (interchangeable)?
  • What invariants must be maintained?
  • Where are the aggregate boundaries?

Domain Concept → Rust Pattern

Domain ConceptRust PatternOwnership Implication
Entitystruct + IdOwned, unique identity
Value Objectstruct + Clone/CopyShareable, immutable
Aggregate Rootstruct owns childrenClear ownership tree
RepositorytraitAbstracts persistence
Domain EventenumCaptures state changes
Serviceimpl block / free fnStateless operations

Thinking Prompt

Before creating a domain type:

-

What's the concept's identity?

  • Needs unique identity → Entity (Id field)
  • Interchangeable by value → Value Object (Clone/Copy)

-

What invariants must hold?

  • Always valid → private fields + validated constructor
  • Transition rules → type state pattern

-

Who owns this data?

  • Single owner (parent) → owned field
  • Shared reference → Arc/Rc
  • Weak reference → Weak

Trace Up ↑

To domain constraints (Layer 3):

"How should I model a Transaction?"

    ↑ Ask: What domain rules govern transactions?

    ↑ Check: domain-fintech (audit, precision requirements)

    ↑ Check: Business stakeholders (what invariants?)
Design QuestionTrace ToAsk
Entity vs Value Objectdomain-*What makes two instances "the same"?
Aggregate boundariesdomain-*What must be consistent together?
Validation rulesdomain-*What business rules apply?

Trace Down ↓

To implementation (Layer 1):

"Model as Entity"

    ↓ m01-ownership: Owned, unique

    ↓ m05-type-driven: Newtype for Id

"Model as Value Object"

    ↓ m01-ownership: Clone/Copy OK

    ↓ m05-type-driven: Validate at construction

"Model as Aggregate"

    ↓ m01-ownership: Parent owns children

    ↓ m02-resource: Consider Rc for shared within aggregate

Quick Reference

DDD ConceptRust PatternExample
Value ObjectNewtypestruct Email(String);
EntityStruct + IDstruct User { id: UserId, ... }
AggregateModule boundarymod order { ... }
RepositoryTraittrait UserRepo { fn find(...) }
Domain EventEnumenum OrderEvent { Created, ... }

Pattern Templates

Value Object

struct Email(String);

impl Email {

    pub fn new(s: &str) -> Result<Self, ValidationError> {

        validate_email(s)?;

        Ok(Self(s.to_string()))

    }

}

Entity

struct UserId(Uuid);

struct User {

    id: UserId,

    email: Email,

    // ... other fields

}

impl PartialEq for User {

    fn eq(&self, other: &Self) -> bool {

        self.id == other.id  // Identity equality

    }

}

Aggregate

mod order {

    pub struct Order {

        id: OrderId,

        items: Vec<OrderItem>,  // Owned children

        // ...

    }

    impl Order {

        pub fn add_item(&mut self, item: OrderItem) {

            // Enforce aggregate invariants

        }

    }

}

Common Mistakes

MistakeWhy WrongBetter
Primitive obsessionNo type safetyNewtype wrappers
Public fields with invariantsInvariants violatedPrivate + accessor
Leaked aggregate internalsBroken encapsulationMethods on root
String for semantic typesNo validationValidated newtype

Related Skills

WhenSee
Type-driven implementationm05-type-driven
Ownership for aggregatesm01-ownership
Domain error handlingm13-domain-error
Specific domain rulesdomain-*
BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card