ddd-domain-primitives-and-always-valid

Designs domain-specific types with construction-time validation to enforce invariants in Rust, TypeScript, and Java.

Updated Jun 23, 2026
One-click install
npx skills add https://github.com/j5ik2o/marp-ai-base --skill ddd-domain-primitives-and-always-valid-j5ik2o
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: ddd-domain-primitives-and-always-valid
Source: https://github.com/j5ik2o/marp-ai-base/tree/main/.agents/skills/ddd-domain-primitives-and-always-valid
Command: npx skills add https://github.com/j5ik2o/marp-ai-base --skill ddd-domain-primitives-and-always-valid-j5ik2o

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Primitive types like String, int, and f64 let invalid values, swapped arguments, and unit mismatches slip past compilers and tests into production. This Skill guides the design of Domain Primitives and Always-Valid domain models so invalid states become compile-time errors instead of runtime bugs. ## Core Features & Use Cases - Anti-pattern Detection: Identifies primitive-typed parameters and fields that should be wrapped in domain types, including argument-swapping risks and unvalidated Strings. - Design Patterns: Provides Smart Constructor, composite value (Money), range-constrained (Age), and NonEmpty<T> patterns with code examples. - Multi-language Implementations: Shows newtype/TryFrom in Rust, Branded Types in TypeScript, and private-constructor factories in Java, applicable to Kotlin, Scala, Go, and Python. - Use Case: When reviewing a function like fn transfer(from: &str, to: &str, amount: i64), use this Skill to refactor it into typed primitives (AccountId, Money) so negative amounts and swapped arguments fail at compile time. ## Quick Start Ask the AI to review your domain model or function signatures and refactor primitive-typed parameters into validated domain primitives using Smart Constructors.

Frequently Asked Questions about ddd-domain-primitives-and-always-valid

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I create a domain primitive with validation in Rust?

Use the newtype pattern with a private field and a Smart Constructor that returns Result. Implement TryFrom for parsing, so invalid values like malformed emails or negative amounts cannot be constructed.

What is the Always-Valid domain model principle?

Always-Valid means an object's existence guarantees its validity, enforced by the type system. Validation happens once at construction, so downstream code never re-checks invariants.

How do branded types work in TypeScript for domain modeling?

Branded types intersect a primitive with a unique symbol tag, creating a nominal type like Email that plain strings cannot be assigned to. A parse function validates the string and returns the branded type.

When should I not wrap a primitive type in a domain type?

Avoid wrapping temporary local variables, private implementation details, and values at external library boundaries. Convert to primitives only at domain boundaries like JSON serialization, database persistence, and external APIs.

Why do primitive-typed function parameters cause production bugs?

Same-typed parameters can be swapped without compiler errors, and unvalidated primitives accept invalid values like negative amounts or SQL injection strings. Tests rarely cover these cases, so bugs surface only in production.