@wazir-dev/cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +111 -0
- package/CHANGELOG.md +14 -0
- package/CONTRIBUTING.md +101 -0
- package/LICENSE +21 -0
- package/README.md +314 -0
- package/assets/composition-engine.mmd +34 -0
- package/assets/demo-script.sh +17 -0
- package/assets/logo-dark.svg +14 -0
- package/assets/logo.svg +14 -0
- package/assets/pipeline.mmd +39 -0
- package/assets/record-demo.sh +51 -0
- package/docs/README.md +51 -0
- package/docs/adapters/context-mode.md +60 -0
- package/docs/concepts/architecture.md +87 -0
- package/docs/concepts/artifact-model.md +60 -0
- package/docs/concepts/composition-engine.md +36 -0
- package/docs/concepts/indexing-and-recall.md +160 -0
- package/docs/concepts/observability.md +41 -0
- package/docs/concepts/roles-and-workflows.md +59 -0
- package/docs/concepts/terminology-policy.md +27 -0
- package/docs/getting-started/01-installation.md +78 -0
- package/docs/getting-started/02-first-run.md +102 -0
- package/docs/getting-started/03-adding-to-project.md +15 -0
- package/docs/getting-started/04-host-setup.md +15 -0
- package/docs/guides/ci-integration.md +15 -0
- package/docs/guides/creating-skills.md +15 -0
- package/docs/guides/expertise-module-authoring.md +15 -0
- package/docs/guides/hook-development.md +15 -0
- package/docs/guides/memory-and-learnings.md +34 -0
- package/docs/guides/multi-host-export.md +15 -0
- package/docs/guides/troubleshooting.md +101 -0
- package/docs/guides/writing-custom-roles.md +15 -0
- package/docs/plans/2026-03-15-cli-pipeline-integration-design.md +592 -0
- package/docs/plans/2026-03-15-cli-pipeline-integration-plan.md +598 -0
- package/docs/plans/2026-03-15-docs-enforcement-plan.md +238 -0
- package/docs/readmes/INDEX.md +99 -0
- package/docs/readmes/features/expertise/README.md +171 -0
- package/docs/readmes/features/exports/README.md +222 -0
- package/docs/readmes/features/hooks/README.md +103 -0
- package/docs/readmes/features/hooks/loop-cap-guard.md +133 -0
- package/docs/readmes/features/hooks/post-tool-capture.md +121 -0
- package/docs/readmes/features/hooks/post-tool-lint.md +130 -0
- package/docs/readmes/features/hooks/pre-compact-summary.md +122 -0
- package/docs/readmes/features/hooks/pre-tool-capture-route.md +100 -0
- package/docs/readmes/features/hooks/protected-path-write-guard.md +128 -0
- package/docs/readmes/features/hooks/session-start.md +119 -0
- package/docs/readmes/features/hooks/stop-handoff-harvest.md +125 -0
- package/docs/readmes/features/roles/README.md +157 -0
- package/docs/readmes/features/roles/clarifier.md +152 -0
- package/docs/readmes/features/roles/content-author.md +190 -0
- package/docs/readmes/features/roles/designer.md +193 -0
- package/docs/readmes/features/roles/executor.md +184 -0
- package/docs/readmes/features/roles/learner.md +210 -0
- package/docs/readmes/features/roles/planner.md +182 -0
- package/docs/readmes/features/roles/researcher.md +164 -0
- package/docs/readmes/features/roles/reviewer.md +184 -0
- package/docs/readmes/features/roles/specifier.md +162 -0
- package/docs/readmes/features/roles/verifier.md +215 -0
- package/docs/readmes/features/schemas/README.md +178 -0
- package/docs/readmes/features/skills/README.md +63 -0
- package/docs/readmes/features/skills/brainstorming.md +96 -0
- package/docs/readmes/features/skills/debugging.md +148 -0
- package/docs/readmes/features/skills/design.md +120 -0
- package/docs/readmes/features/skills/prepare-next.md +109 -0
- package/docs/readmes/features/skills/run-audit.md +159 -0
- package/docs/readmes/features/skills/scan-project.md +109 -0
- package/docs/readmes/features/skills/self-audit.md +176 -0
- package/docs/readmes/features/skills/tdd.md +137 -0
- package/docs/readmes/features/skills/using-skills.md +92 -0
- package/docs/readmes/features/skills/verification.md +120 -0
- package/docs/readmes/features/skills/writing-plans.md +104 -0
- package/docs/readmes/features/tooling/README.md +320 -0
- package/docs/readmes/features/workflows/README.md +186 -0
- package/docs/readmes/features/workflows/author.md +181 -0
- package/docs/readmes/features/workflows/clarify.md +154 -0
- package/docs/readmes/features/workflows/design-review.md +171 -0
- package/docs/readmes/features/workflows/design.md +169 -0
- package/docs/readmes/features/workflows/discover.md +162 -0
- package/docs/readmes/features/workflows/execute.md +173 -0
- package/docs/readmes/features/workflows/learn.md +167 -0
- package/docs/readmes/features/workflows/plan-review.md +165 -0
- package/docs/readmes/features/workflows/plan.md +170 -0
- package/docs/readmes/features/workflows/prepare-next.md +167 -0
- package/docs/readmes/features/workflows/review.md +169 -0
- package/docs/readmes/features/workflows/run-audit.md +191 -0
- package/docs/readmes/features/workflows/spec-challenge.md +159 -0
- package/docs/readmes/features/workflows/specify.md +160 -0
- package/docs/readmes/features/workflows/verify.md +177 -0
- package/docs/readmes/packages/README.md +50 -0
- package/docs/readmes/packages/ajv.md +117 -0
- package/docs/readmes/packages/context-mode.md +118 -0
- package/docs/readmes/packages/gray-matter.md +116 -0
- package/docs/readmes/packages/node-test.md +137 -0
- package/docs/readmes/packages/yaml.md +112 -0
- package/docs/reference/configuration-reference.md +159 -0
- package/docs/reference/expertise-index.md +52 -0
- package/docs/reference/git-flow.md +43 -0
- package/docs/reference/hooks.md +87 -0
- package/docs/reference/host-exports.md +50 -0
- package/docs/reference/launch-checklist.md +172 -0
- package/docs/reference/marketplace-listings.md +76 -0
- package/docs/reference/release-process.md +34 -0
- package/docs/reference/roles-reference.md +77 -0
- package/docs/reference/skills.md +33 -0
- package/docs/reference/templates.md +29 -0
- package/docs/reference/tooling-cli.md +94 -0
- package/docs/truth-claims.yaml +222 -0
- package/expertise/PROGRESS.md +63 -0
- package/expertise/README.md +18 -0
- package/expertise/antipatterns/PROGRESS.md +56 -0
- package/expertise/antipatterns/backend/api-design-antipatterns.md +1271 -0
- package/expertise/antipatterns/backend/auth-antipatterns.md +1195 -0
- package/expertise/antipatterns/backend/caching-antipatterns.md +622 -0
- package/expertise/antipatterns/backend/database-antipatterns.md +1038 -0
- package/expertise/antipatterns/backend/index.md +24 -0
- package/expertise/antipatterns/backend/microservices-antipatterns.md +850 -0
- package/expertise/antipatterns/code/architecture-antipatterns.md +919 -0
- package/expertise/antipatterns/code/async-antipatterns.md +622 -0
- package/expertise/antipatterns/code/code-smells.md +1186 -0
- package/expertise/antipatterns/code/dependency-antipatterns.md +1209 -0
- package/expertise/antipatterns/code/error-handling-antipatterns.md +1360 -0
- package/expertise/antipatterns/code/index.md +27 -0
- package/expertise/antipatterns/code/naming-and-abstraction.md +1118 -0
- package/expertise/antipatterns/code/state-management-antipatterns.md +1076 -0
- package/expertise/antipatterns/code/testing-antipatterns.md +1053 -0
- package/expertise/antipatterns/design/accessibility-antipatterns.md +1136 -0
- package/expertise/antipatterns/design/dark-patterns.md +1121 -0
- package/expertise/antipatterns/design/index.md +22 -0
- package/expertise/antipatterns/design/ui-antipatterns.md +1202 -0
- package/expertise/antipatterns/design/ux-antipatterns.md +680 -0
- package/expertise/antipatterns/frontend/css-layout-antipatterns.md +691 -0
- package/expertise/antipatterns/frontend/flutter-antipatterns.md +1827 -0
- package/expertise/antipatterns/frontend/index.md +23 -0
- package/expertise/antipatterns/frontend/mobile-antipatterns.md +573 -0
- package/expertise/antipatterns/frontend/react-antipatterns.md +1128 -0
- package/expertise/antipatterns/frontend/spa-antipatterns.md +1235 -0
- package/expertise/antipatterns/index.md +31 -0
- package/expertise/antipatterns/performance/index.md +20 -0
- package/expertise/antipatterns/performance/performance-antipatterns.md +1013 -0
- package/expertise/antipatterns/performance/premature-optimization.md +623 -0
- package/expertise/antipatterns/performance/scaling-antipatterns.md +785 -0
- package/expertise/antipatterns/process/ai-coding-antipatterns.md +853 -0
- package/expertise/antipatterns/process/code-review-antipatterns.md +656 -0
- package/expertise/antipatterns/process/deployment-antipatterns.md +920 -0
- package/expertise/antipatterns/process/index.md +23 -0
- package/expertise/antipatterns/process/technical-debt-antipatterns.md +647 -0
- package/expertise/antipatterns/security/index.md +20 -0
- package/expertise/antipatterns/security/secrets-antipatterns.md +849 -0
- package/expertise/antipatterns/security/security-theater.md +843 -0
- package/expertise/antipatterns/security/vulnerability-patterns.md +801 -0
- package/expertise/architecture/PROGRESS.md +70 -0
- package/expertise/architecture/data/caching-architecture.md +671 -0
- package/expertise/architecture/data/data-consistency.md +574 -0
- package/expertise/architecture/data/data-modeling.md +536 -0
- package/expertise/architecture/data/event-streams-and-queues.md +634 -0
- package/expertise/architecture/data/index.md +25 -0
- package/expertise/architecture/data/search-architecture.md +663 -0
- package/expertise/architecture/data/sql-vs-nosql.md +708 -0
- package/expertise/architecture/decisions/architecture-decision-records.md +640 -0
- package/expertise/architecture/decisions/build-vs-buy.md +616 -0
- package/expertise/architecture/decisions/index.md +23 -0
- package/expertise/architecture/decisions/monolith-to-microservices.md +790 -0
- package/expertise/architecture/decisions/technology-selection.md +616 -0
- package/expertise/architecture/distributed/cap-theorem-and-tradeoffs.md +800 -0
- package/expertise/architecture/distributed/circuit-breaker-bulkhead.md +741 -0
- package/expertise/architecture/distributed/consensus-and-coordination.md +796 -0
- package/expertise/architecture/distributed/distributed-systems-fundamentals.md +564 -0
- package/expertise/architecture/distributed/idempotency-and-retry.md +796 -0
- package/expertise/architecture/distributed/index.md +25 -0
- package/expertise/architecture/distributed/saga-pattern.md +797 -0
- package/expertise/architecture/foundations/architectural-thinking.md +460 -0
- package/expertise/architecture/foundations/coupling-and-cohesion.md +770 -0
- package/expertise/architecture/foundations/design-principles-solid.md +649 -0
- package/expertise/architecture/foundations/domain-driven-design.md +719 -0
- package/expertise/architecture/foundations/index.md +25 -0
- package/expertise/architecture/foundations/separation-of-concerns.md +472 -0
- package/expertise/architecture/foundations/twelve-factor-app.md +797 -0
- package/expertise/architecture/index.md +34 -0
- package/expertise/architecture/integration/api-design-graphql.md +638 -0
- package/expertise/architecture/integration/api-design-grpc.md +804 -0
- package/expertise/architecture/integration/api-design-rest.md +892 -0
- package/expertise/architecture/integration/index.md +25 -0
- package/expertise/architecture/integration/third-party-integration.md +795 -0
- package/expertise/architecture/integration/webhooks-and-callbacks.md +1152 -0
- package/expertise/architecture/integration/websockets-realtime.md +791 -0
- package/expertise/architecture/mobile-architecture/index.md +22 -0
- package/expertise/architecture/mobile-architecture/mobile-app-architecture.md +780 -0
- package/expertise/architecture/mobile-architecture/mobile-backend-for-frontend.md +670 -0
- package/expertise/architecture/mobile-architecture/offline-first.md +719 -0
- package/expertise/architecture/mobile-architecture/push-and-sync.md +782 -0
- package/expertise/architecture/patterns/cqrs-event-sourcing.md +717 -0
- package/expertise/architecture/patterns/event-driven.md +797 -0
- package/expertise/architecture/patterns/hexagonal-clean-architecture.md +870 -0
- package/expertise/architecture/patterns/index.md +27 -0
- package/expertise/architecture/patterns/layered-architecture.md +736 -0
- package/expertise/architecture/patterns/microservices.md +753 -0
- package/expertise/architecture/patterns/modular-monolith.md +692 -0
- package/expertise/architecture/patterns/monolith.md +626 -0
- package/expertise/architecture/patterns/plugin-architecture.md +735 -0
- package/expertise/architecture/patterns/serverless.md +780 -0
- package/expertise/architecture/scaling/database-scaling.md +615 -0
- package/expertise/architecture/scaling/feature-flags-and-rollouts.md +757 -0
- package/expertise/architecture/scaling/horizontal-vs-vertical.md +606 -0
- package/expertise/architecture/scaling/index.md +24 -0
- package/expertise/architecture/scaling/multi-tenancy.md +800 -0
- package/expertise/architecture/scaling/stateless-design.md +787 -0
- package/expertise/backend/embedded-firmware.md +625 -0
- package/expertise/backend/go.md +853 -0
- package/expertise/backend/index.md +24 -0
- package/expertise/backend/java-spring.md +448 -0
- package/expertise/backend/node-typescript.md +625 -0
- package/expertise/backend/python-fastapi.md +724 -0
- package/expertise/backend/rust.md +458 -0
- package/expertise/backend/solidity.md +711 -0
- package/expertise/composition-map.yaml +443 -0
- package/expertise/content/foundations/content-modeling.md +395 -0
- package/expertise/content/foundations/editorial-standards.md +449 -0
- package/expertise/content/foundations/index.md +24 -0
- package/expertise/content/foundations/microcopy.md +455 -0
- package/expertise/content/foundations/terminology-governance.md +509 -0
- package/expertise/content/index.md +34 -0
- package/expertise/content/patterns/accessibility-copy.md +518 -0
- package/expertise/content/patterns/index.md +24 -0
- package/expertise/content/patterns/notification-content.md +433 -0
- package/expertise/content/patterns/sample-content.md +486 -0
- package/expertise/content/patterns/state-copy.md +439 -0
- package/expertise/design/PROGRESS.md +58 -0
- package/expertise/design/disciplines/dark-mode-theming.md +577 -0
- package/expertise/design/disciplines/design-systems.md +595 -0
- package/expertise/design/disciplines/index.md +25 -0
- package/expertise/design/disciplines/information-architecture.md +800 -0
- package/expertise/design/disciplines/interaction-design.md +788 -0
- package/expertise/design/disciplines/responsive-design.md +552 -0
- package/expertise/design/disciplines/usability-testing.md +516 -0
- package/expertise/design/disciplines/user-research.md +792 -0
- package/expertise/design/foundations/accessibility-design.md +796 -0
- package/expertise/design/foundations/color-theory.md +797 -0
- package/expertise/design/foundations/iconography.md +795 -0
- package/expertise/design/foundations/index.md +26 -0
- package/expertise/design/foundations/motion-and-animation.md +653 -0
- package/expertise/design/foundations/rtl-design.md +585 -0
- package/expertise/design/foundations/spacing-and-layout.md +607 -0
- package/expertise/design/foundations/typography.md +800 -0
- package/expertise/design/foundations/visual-hierarchy.md +761 -0
- package/expertise/design/index.md +32 -0
- package/expertise/design/patterns/authentication-flows.md +474 -0
- package/expertise/design/patterns/content-consumption.md +789 -0
- package/expertise/design/patterns/data-display.md +618 -0
- package/expertise/design/patterns/e-commerce.md +1494 -0
- package/expertise/design/patterns/feedback-and-states.md +642 -0
- package/expertise/design/patterns/forms-and-input.md +819 -0
- package/expertise/design/patterns/gamification.md +801 -0
- package/expertise/design/patterns/index.md +31 -0
- package/expertise/design/patterns/microinteractions.md +449 -0
- package/expertise/design/patterns/navigation.md +800 -0
- package/expertise/design/patterns/notifications.md +705 -0
- package/expertise/design/patterns/onboarding.md +700 -0
- package/expertise/design/patterns/search-and-filter.md +601 -0
- package/expertise/design/patterns/settings-and-preferences.md +768 -0
- package/expertise/design/patterns/social-and-community.md +748 -0
- package/expertise/design/platforms/desktop-native.md +612 -0
- package/expertise/design/platforms/index.md +25 -0
- package/expertise/design/platforms/mobile-android.md +825 -0
- package/expertise/design/platforms/mobile-cross-platform.md +983 -0
- package/expertise/design/platforms/mobile-ios.md +699 -0
- package/expertise/design/platforms/tablet.md +794 -0
- package/expertise/design/platforms/web-dashboard.md +790 -0
- package/expertise/design/platforms/web-responsive.md +550 -0
- package/expertise/design/psychology/behavioral-nudges.md +449 -0
- package/expertise/design/psychology/cognitive-load.md +1191 -0
- package/expertise/design/psychology/error-psychology.md +778 -0
- package/expertise/design/psychology/index.md +22 -0
- package/expertise/design/psychology/persuasive-design.md +736 -0
- package/expertise/design/psychology/user-mental-models.md +623 -0
- package/expertise/design/tooling/open-pencil.md +266 -0
- package/expertise/frontend/angular.md +1073 -0
- package/expertise/frontend/desktop-electron.md +546 -0
- package/expertise/frontend/flutter.md +782 -0
- package/expertise/frontend/index.md +27 -0
- package/expertise/frontend/native-android.md +409 -0
- package/expertise/frontend/native-ios.md +490 -0
- package/expertise/frontend/react-native.md +1160 -0
- package/expertise/frontend/react.md +808 -0
- package/expertise/frontend/vue.md +1089 -0
- package/expertise/humanize/domain-rules-code.md +79 -0
- package/expertise/humanize/domain-rules-content.md +67 -0
- package/expertise/humanize/domain-rules-technical-docs.md +56 -0
- package/expertise/humanize/index.md +35 -0
- package/expertise/humanize/self-audit-checklist.md +87 -0
- package/expertise/humanize/sentence-patterns.md +218 -0
- package/expertise/humanize/vocabulary-blacklist.md +105 -0
- package/expertise/i18n/PROGRESS.md +65 -0
- package/expertise/i18n/advanced/accessibility-and-i18n.md +28 -0
- package/expertise/i18n/advanced/bidirectional-text-algorithm.md +38 -0
- package/expertise/i18n/advanced/complex-scripts.md +30 -0
- package/expertise/i18n/advanced/performance-and-i18n.md +27 -0
- package/expertise/i18n/advanced/testing-i18n.md +28 -0
- package/expertise/i18n/content/content-adaptation.md +23 -0
- package/expertise/i18n/content/locale-specific-formatting.md +23 -0
- package/expertise/i18n/content/machine-translation-integration.md +28 -0
- package/expertise/i18n/content/translation-management.md +29 -0
- package/expertise/i18n/foundations/date-time-calendars.md +67 -0
- package/expertise/i18n/foundations/i18n-architecture.md +272 -0
- package/expertise/i18n/foundations/locale-and-language-tags.md +79 -0
- package/expertise/i18n/foundations/numbers-currency-units.md +61 -0
- package/expertise/i18n/foundations/pluralization-and-gender.md +109 -0
- package/expertise/i18n/foundations/string-externalization.md +236 -0
- package/expertise/i18n/foundations/text-direction-bidi.md +241 -0
- package/expertise/i18n/foundations/unicode-and-encoding.md +86 -0
- package/expertise/i18n/index.md +38 -0
- package/expertise/i18n/platform/backend-i18n.md +31 -0
- package/expertise/i18n/platform/flutter-i18n.md +148 -0
- package/expertise/i18n/platform/native-android-i18n.md +36 -0
- package/expertise/i18n/platform/native-ios-i18n.md +36 -0
- package/expertise/i18n/platform/react-i18n.md +103 -0
- package/expertise/i18n/platform/web-css-i18n.md +81 -0
- package/expertise/i18n/rtl/arabic-specific.md +175 -0
- package/expertise/i18n/rtl/hebrew-specific.md +149 -0
- package/expertise/i18n/rtl/rtl-animations-and-transitions.md +111 -0
- package/expertise/i18n/rtl/rtl-forms-and-input.md +161 -0
- package/expertise/i18n/rtl/rtl-fundamentals.md +211 -0
- package/expertise/i18n/rtl/rtl-icons-and-images.md +181 -0
- package/expertise/i18n/rtl/rtl-layout-mirroring.md +252 -0
- package/expertise/i18n/rtl/rtl-navigation-and-gestures.md +107 -0
- package/expertise/i18n/rtl/rtl-testing-and-qa.md +147 -0
- package/expertise/i18n/rtl/rtl-typography.md +160 -0
- package/expertise/index.md +113 -0
- package/expertise/index.yaml +216 -0
- package/expertise/infrastructure/cloud-aws.md +597 -0
- package/expertise/infrastructure/cloud-gcp.md +599 -0
- package/expertise/infrastructure/cybersecurity.md +816 -0
- package/expertise/infrastructure/database-mongodb.md +447 -0
- package/expertise/infrastructure/database-postgres.md +400 -0
- package/expertise/infrastructure/devops-cicd.md +787 -0
- package/expertise/infrastructure/index.md +27 -0
- package/expertise/performance/PROGRESS.md +50 -0
- package/expertise/performance/backend/api-latency.md +1204 -0
- package/expertise/performance/backend/background-jobs.md +506 -0
- package/expertise/performance/backend/connection-pooling.md +1209 -0
- package/expertise/performance/backend/database-query-optimization.md +515 -0
- package/expertise/performance/backend/index.md +23 -0
- package/expertise/performance/backend/rate-limiting-and-throttling.md +971 -0
- package/expertise/performance/foundations/algorithmic-complexity.md +954 -0
- package/expertise/performance/foundations/caching-strategies.md +489 -0
- package/expertise/performance/foundations/concurrency-and-parallelism.md +847 -0
- package/expertise/performance/foundations/index.md +24 -0
- package/expertise/performance/foundations/measuring-and-profiling.md +440 -0
- package/expertise/performance/foundations/memory-management.md +964 -0
- package/expertise/performance/foundations/performance-budgets.md +1314 -0
- package/expertise/performance/index.md +31 -0
- package/expertise/performance/infrastructure/auto-scaling.md +1059 -0
- package/expertise/performance/infrastructure/cdn-and-edge.md +1081 -0
- package/expertise/performance/infrastructure/index.md +22 -0
- package/expertise/performance/infrastructure/load-balancing.md +1081 -0
- package/expertise/performance/infrastructure/observability.md +1079 -0
- package/expertise/performance/mobile/index.md +23 -0
- package/expertise/performance/mobile/mobile-animations.md +544 -0
- package/expertise/performance/mobile/mobile-memory-battery.md +416 -0
- package/expertise/performance/mobile/mobile-network.md +452 -0
- package/expertise/performance/mobile/mobile-rendering.md +599 -0
- package/expertise/performance/mobile/mobile-startup-time.md +505 -0
- package/expertise/performance/platform-specific/flutter-performance.md +647 -0
- package/expertise/performance/platform-specific/index.md +22 -0
- package/expertise/performance/platform-specific/node-performance.md +1307 -0
- package/expertise/performance/platform-specific/postgres-performance.md +1366 -0
- package/expertise/performance/platform-specific/react-performance.md +1403 -0
- package/expertise/performance/web/bundle-optimization.md +1239 -0
- package/expertise/performance/web/image-and-media.md +636 -0
- package/expertise/performance/web/index.md +24 -0
- package/expertise/performance/web/network-optimization.md +1133 -0
- package/expertise/performance/web/rendering-performance.md +1098 -0
- package/expertise/performance/web/ssr-and-hydration.md +918 -0
- package/expertise/performance/web/web-vitals.md +1374 -0
- package/expertise/quality/accessibility.md +985 -0
- package/expertise/quality/evidence-based-verification.md +499 -0
- package/expertise/quality/index.md +24 -0
- package/expertise/quality/ml-model-audit.md +614 -0
- package/expertise/quality/performance.md +600 -0
- package/expertise/quality/testing-api.md +891 -0
- package/expertise/quality/testing-mobile.md +496 -0
- package/expertise/quality/testing-web.md +849 -0
- package/expertise/security/PROGRESS.md +54 -0
- package/expertise/security/agentic-identity.md +540 -0
- package/expertise/security/compliance-frameworks.md +601 -0
- package/expertise/security/data/data-encryption.md +364 -0
- package/expertise/security/data/data-privacy-gdpr.md +692 -0
- package/expertise/security/data/database-security.md +1171 -0
- package/expertise/security/data/index.md +22 -0
- package/expertise/security/data/pii-handling.md +531 -0
- package/expertise/security/foundations/authentication.md +1041 -0
- package/expertise/security/foundations/authorization.md +603 -0
- package/expertise/security/foundations/cryptography.md +1001 -0
- package/expertise/security/foundations/index.md +25 -0
- package/expertise/security/foundations/owasp-top-10.md +1354 -0
- package/expertise/security/foundations/secrets-management.md +1217 -0
- package/expertise/security/foundations/secure-sdlc.md +700 -0
- package/expertise/security/foundations/supply-chain-security.md +698 -0
- package/expertise/security/index.md +31 -0
- package/expertise/security/infrastructure/cloud-security-aws.md +1296 -0
- package/expertise/security/infrastructure/cloud-security-gcp.md +1376 -0
- package/expertise/security/infrastructure/container-security.md +721 -0
- package/expertise/security/infrastructure/incident-response.md +1295 -0
- package/expertise/security/infrastructure/index.md +24 -0
- package/expertise/security/infrastructure/logging-and-monitoring.md +1618 -0
- package/expertise/security/infrastructure/network-security.md +1337 -0
- package/expertise/security/mobile/index.md +23 -0
- package/expertise/security/mobile/mobile-android-security.md +1218 -0
- package/expertise/security/mobile/mobile-binary-protection.md +1229 -0
- package/expertise/security/mobile/mobile-data-storage.md +1265 -0
- package/expertise/security/mobile/mobile-ios-security.md +1401 -0
- package/expertise/security/mobile/mobile-network-security.md +1520 -0
- package/expertise/security/smart-contract-security.md +594 -0
- package/expertise/security/testing/index.md +22 -0
- package/expertise/security/testing/penetration-testing.md +1258 -0
- package/expertise/security/testing/security-code-review.md +1765 -0
- package/expertise/security/testing/threat-modeling.md +1074 -0
- package/expertise/security/testing/vulnerability-scanning.md +1062 -0
- package/expertise/security/web/api-security.md +586 -0
- package/expertise/security/web/cors-and-headers.md +433 -0
- package/expertise/security/web/csrf.md +562 -0
- package/expertise/security/web/file-upload.md +1477 -0
- package/expertise/security/web/index.md +25 -0
- package/expertise/security/web/injection.md +1375 -0
- package/expertise/security/web/session-management.md +1101 -0
- package/expertise/security/web/xss.md +1158 -0
- package/exports/README.md +17 -0
- package/exports/hosts/claude/.claude/agents/clarifier.md +42 -0
- package/exports/hosts/claude/.claude/agents/content-author.md +63 -0
- package/exports/hosts/claude/.claude/agents/designer.md +55 -0
- package/exports/hosts/claude/.claude/agents/executor.md +55 -0
- package/exports/hosts/claude/.claude/agents/learner.md +51 -0
- package/exports/hosts/claude/.claude/agents/planner.md +53 -0
- package/exports/hosts/claude/.claude/agents/researcher.md +43 -0
- package/exports/hosts/claude/.claude/agents/reviewer.md +54 -0
- package/exports/hosts/claude/.claude/agents/specifier.md +47 -0
- package/exports/hosts/claude/.claude/agents/verifier.md +71 -0
- package/exports/hosts/claude/.claude/commands/author.md +42 -0
- package/exports/hosts/claude/.claude/commands/clarify.md +38 -0
- package/exports/hosts/claude/.claude/commands/design-review.md +46 -0
- package/exports/hosts/claude/.claude/commands/design.md +44 -0
- package/exports/hosts/claude/.claude/commands/discover.md +37 -0
- package/exports/hosts/claude/.claude/commands/execute.md +48 -0
- package/exports/hosts/claude/.claude/commands/learn.md +38 -0
- package/exports/hosts/claude/.claude/commands/plan-review.md +42 -0
- package/exports/hosts/claude/.claude/commands/plan.md +39 -0
- package/exports/hosts/claude/.claude/commands/prepare-next.md +37 -0
- package/exports/hosts/claude/.claude/commands/review.md +40 -0
- package/exports/hosts/claude/.claude/commands/run-audit.md +41 -0
- package/exports/hosts/claude/.claude/commands/spec-challenge.md +41 -0
- package/exports/hosts/claude/.claude/commands/specify.md +38 -0
- package/exports/hosts/claude/.claude/commands/verify.md +37 -0
- package/exports/hosts/claude/.claude/settings.json +34 -0
- package/exports/hosts/claude/CLAUDE.md +19 -0
- package/exports/hosts/claude/export.manifest.json +38 -0
- package/exports/hosts/claude/host-package.json +67 -0
- package/exports/hosts/codex/AGENTS.md +19 -0
- package/exports/hosts/codex/export.manifest.json +38 -0
- package/exports/hosts/codex/host-package.json +41 -0
- package/exports/hosts/cursor/.cursor/hooks.json +16 -0
- package/exports/hosts/cursor/.cursor/rules/wazir-core.mdc +19 -0
- package/exports/hosts/cursor/export.manifest.json +38 -0
- package/exports/hosts/cursor/host-package.json +42 -0
- package/exports/hosts/gemini/GEMINI.md +19 -0
- package/exports/hosts/gemini/export.manifest.json +38 -0
- package/exports/hosts/gemini/host-package.json +41 -0
- package/hooks/README.md +18 -0
- package/hooks/definitions/loop_cap_guard.yaml +21 -0
- package/hooks/definitions/post_tool_capture.yaml +24 -0
- package/hooks/definitions/pre_compact_summary.yaml +19 -0
- package/hooks/definitions/pre_tool_capture_route.yaml +19 -0
- package/hooks/definitions/protected_path_write_guard.yaml +19 -0
- package/hooks/definitions/session_start.yaml +19 -0
- package/hooks/definitions/stop_handoff_harvest.yaml +20 -0
- package/hooks/loop-cap-guard +17 -0
- package/hooks/post-tool-lint +36 -0
- package/hooks/protected-path-write-guard +17 -0
- package/hooks/session-start +41 -0
- package/llms-full.txt +2355 -0
- package/llms.txt +43 -0
- package/package.json +79 -0
- package/roles/README.md +20 -0
- package/roles/clarifier.md +42 -0
- package/roles/content-author.md +63 -0
- package/roles/designer.md +55 -0
- package/roles/executor.md +55 -0
- package/roles/learner.md +51 -0
- package/roles/planner.md +53 -0
- package/roles/researcher.md +43 -0
- package/roles/reviewer.md +54 -0
- package/roles/specifier.md +47 -0
- package/roles/verifier.md +71 -0
- package/schemas/README.md +24 -0
- package/schemas/accepted-learning.schema.json +20 -0
- package/schemas/author-artifact.schema.json +156 -0
- package/schemas/clarification.schema.json +19 -0
- package/schemas/design-artifact.schema.json +80 -0
- package/schemas/docs-claim.schema.json +18 -0
- package/schemas/export-manifest.schema.json +20 -0
- package/schemas/hook.schema.json +67 -0
- package/schemas/host-export-package.schema.json +18 -0
- package/schemas/implementation-plan.schema.json +19 -0
- package/schemas/proposed-learning.schema.json +19 -0
- package/schemas/research.schema.json +18 -0
- package/schemas/review.schema.json +29 -0
- package/schemas/run-manifest.schema.json +18 -0
- package/schemas/spec-challenge.schema.json +18 -0
- package/schemas/spec.schema.json +20 -0
- package/schemas/usage.schema.json +102 -0
- package/schemas/verification-proof.schema.json +29 -0
- package/schemas/wazir-manifest.schema.json +173 -0
- package/skills/README.md +40 -0
- package/skills/brainstorming/SKILL.md +77 -0
- package/skills/debugging/SKILL.md +50 -0
- package/skills/design/SKILL.md +61 -0
- package/skills/dispatching-parallel-agents/SKILL.md +128 -0
- package/skills/executing-plans/SKILL.md +70 -0
- package/skills/finishing-a-development-branch/SKILL.md +169 -0
- package/skills/humanize/SKILL.md +123 -0
- package/skills/init-pipeline/SKILL.md +124 -0
- package/skills/prepare-next/SKILL.md +20 -0
- package/skills/receiving-code-review/SKILL.md +123 -0
- package/skills/requesting-code-review/SKILL.md +105 -0
- package/skills/requesting-code-review/code-reviewer.md +108 -0
- package/skills/run-audit/SKILL.md +197 -0
- package/skills/scan-project/SKILL.md +41 -0
- package/skills/self-audit/SKILL.md +153 -0
- package/skills/subagent-driven-development/SKILL.md +154 -0
- package/skills/subagent-driven-development/code-quality-reviewer-prompt.md +26 -0
- package/skills/subagent-driven-development/implementer-prompt.md +102 -0
- package/skills/subagent-driven-development/spec-reviewer-prompt.md +61 -0
- package/skills/tdd/SKILL.md +23 -0
- package/skills/using-git-worktrees/SKILL.md +163 -0
- package/skills/using-skills/SKILL.md +95 -0
- package/skills/verification/SKILL.md +22 -0
- package/skills/wazir/SKILL.md +463 -0
- package/skills/writing-plans/SKILL.md +30 -0
- package/skills/writing-skills/SKILL.md +157 -0
- package/skills/writing-skills/anthropic-best-practices.md +122 -0
- package/skills/writing-skills/persuasion-principles.md +50 -0
- package/templates/README.md +20 -0
- package/templates/artifacts/README.md +10 -0
- package/templates/artifacts/accepted-learning.md +19 -0
- package/templates/artifacts/accepted-learning.template.json +12 -0
- package/templates/artifacts/author.md +74 -0
- package/templates/artifacts/author.template.json +19 -0
- package/templates/artifacts/clarification.md +21 -0
- package/templates/artifacts/clarification.template.json +12 -0
- package/templates/artifacts/execute-notes.md +19 -0
- package/templates/artifacts/implementation-plan.md +21 -0
- package/templates/artifacts/implementation-plan.template.json +11 -0
- package/templates/artifacts/learning-proposal.md +19 -0
- package/templates/artifacts/next-run-handoff.md +21 -0
- package/templates/artifacts/plan-review.md +19 -0
- package/templates/artifacts/proposed-learning.template.json +12 -0
- package/templates/artifacts/research.md +21 -0
- package/templates/artifacts/research.template.json +12 -0
- package/templates/artifacts/review-findings.md +19 -0
- package/templates/artifacts/review.template.json +11 -0
- package/templates/artifacts/run-manifest.template.json +8 -0
- package/templates/artifacts/spec-challenge.md +19 -0
- package/templates/artifacts/spec-challenge.template.json +11 -0
- package/templates/artifacts/spec.md +21 -0
- package/templates/artifacts/spec.template.json +12 -0
- package/templates/artifacts/verification-proof.md +19 -0
- package/templates/artifacts/verification-proof.template.json +11 -0
- package/templates/examples/accepted-learning.example.json +14 -0
- package/templates/examples/author.example.json +152 -0
- package/templates/examples/clarification.example.json +15 -0
- package/templates/examples/docs-claim.example.json +8 -0
- package/templates/examples/export-manifest.example.json +7 -0
- package/templates/examples/host-export-package.example.json +11 -0
- package/templates/examples/implementation-plan.example.json +17 -0
- package/templates/examples/proposed-learning.example.json +13 -0
- package/templates/examples/research.example.json +15 -0
- package/templates/examples/research.example.md +6 -0
- package/templates/examples/review.example.json +17 -0
- package/templates/examples/run-manifest.example.json +9 -0
- package/templates/examples/spec-challenge.example.json +14 -0
- package/templates/examples/spec.example.json +21 -0
- package/templates/examples/verification-proof.example.json +21 -0
- package/templates/examples/wazir-manifest.example.yaml +65 -0
- package/templates/task-definition-schema.md +99 -0
- package/tooling/README.md +20 -0
- package/tooling/src/adapters/context-mode.js +50 -0
- package/tooling/src/capture/command.js +376 -0
- package/tooling/src/capture/store.js +99 -0
- package/tooling/src/capture/usage.js +270 -0
- package/tooling/src/checks/branches.js +50 -0
- package/tooling/src/checks/brand-truth.js +110 -0
- package/tooling/src/checks/changelog.js +231 -0
- package/tooling/src/checks/command-registry.js +36 -0
- package/tooling/src/checks/commits.js +102 -0
- package/tooling/src/checks/docs-drift.js +103 -0
- package/tooling/src/checks/docs-truth.js +201 -0
- package/tooling/src/checks/runtime-surface.js +156 -0
- package/tooling/src/cli.js +116 -0
- package/tooling/src/command-options.js +56 -0
- package/tooling/src/commands/validate.js +320 -0
- package/tooling/src/doctor/command.js +91 -0
- package/tooling/src/export/command.js +77 -0
- package/tooling/src/export/compiler.js +498 -0
- package/tooling/src/guards/loop-cap-guard.js +52 -0
- package/tooling/src/guards/protected-path-write-guard.js +67 -0
- package/tooling/src/index/command.js +152 -0
- package/tooling/src/index/storage.js +1061 -0
- package/tooling/src/index/summarizers.js +261 -0
- package/tooling/src/loaders.js +18 -0
- package/tooling/src/project-root.js +22 -0
- package/tooling/src/recall/command.js +225 -0
- package/tooling/src/schema-validator.js +30 -0
- package/tooling/src/state-root.js +40 -0
- package/tooling/src/status/command.js +71 -0
- package/wazir.manifest.yaml +135 -0
- package/workflows/README.md +19 -0
- package/workflows/author.md +42 -0
- package/workflows/clarify.md +38 -0
- package/workflows/design-review.md +46 -0
- package/workflows/design.md +44 -0
- package/workflows/discover.md +37 -0
- package/workflows/execute.md +48 -0
- package/workflows/learn.md +38 -0
- package/workflows/plan-review.md +42 -0
- package/workflows/plan.md +39 -0
- package/workflows/prepare-next.md +37 -0
- package/workflows/review.md +40 -0
- package/workflows/run-audit.md +41 -0
- package/workflows/spec-challenge.md +41 -0
- package/workflows/specify.md +38 -0
- package/workflows/verify.md +37 -0
|
@@ -0,0 +1,719 @@
|
|
|
1
|
+
# Domain-Driven Design (DDD) — Architecture Expertise Module
|
|
2
|
+
|
|
3
|
+
> Domain-Driven Design is a software development approach where the structure and language of code matches the business domain, with boundaries drawn around coherent subdomains to manage complexity in large, complex systems. It has two wings: strategic (organization and boundaries) and tactical (code patterns).
|
|
4
|
+
|
|
5
|
+
> **Category:** Foundation
|
|
6
|
+
> **Complexity:** Expert
|
|
7
|
+
> **Applies when:** Systems with complex domain logic, multiple teams, and long evolution timescales — where the cost of misunderstanding the domain is high
|
|
8
|
+
|
|
9
|
+
**Cross-reference:** modular-monolith, microservices, hexagonal-clean-architecture, coupling-and-cohesion, cqrs-event-sourcing, separation-of-concerns
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## What This Is (and What It Isn't)
|
|
14
|
+
|
|
15
|
+
Domain-Driven Design was introduced by Eric Evans in his 2003 book "Domain-Driven Design: Tackling Complexity in the Heart of Software." In 2024, Evans stated: "The state of the art of DDD is definitely better than it was twenty years ago" and affirmed that the core principle — focusing on deep issues of the domain users are engaged in — "will not go out of style."
|
|
16
|
+
|
|
17
|
+
DDD has two wings that are frequently confused or conflated:
|
|
18
|
+
|
|
19
|
+
**Strategic DDD** is the high-level practice of identifying domain boundaries, subdomains, team ownership, and relationships between models. It answers: *What are we building, for whom, and where do the natural seams lie?* Tools include Bounded Contexts, Context Maps, Ubiquitous Language, and Subdomain classification (Core / Supporting / Generic).
|
|
20
|
+
|
|
21
|
+
**Tactical DDD** is the low-level implementation vocabulary: Entities, Value Objects, Aggregates, Repositories, Domain Services, Domain Events, Factories, and Application Services. These are patterns for implementing a single Bounded Context richly.
|
|
22
|
+
|
|
23
|
+
### The Core Mistake Most Teams Make
|
|
24
|
+
|
|
25
|
+
Most teams skip strategic DDD entirely and go directly to tactical patterns. They start defining Aggregates and Value Objects before ever asking "what are our bounded contexts?" or "what is our core domain?" This is backwards and produces the worst outcome: all the complexity of DDD with none of the organizational benefits.
|
|
26
|
+
|
|
27
|
+
**Ubiquitous Language is the actual core of DDD**, not Aggregates. Evans intended DDD fundamentally as a collaboration methodology — a way for developers and domain experts to build a shared model that lives simultaneously in conversations, documentation, and code. Everything else is secondary.
|
|
28
|
+
|
|
29
|
+
### What DDD Is NOT
|
|
30
|
+
|
|
31
|
+
- DDD is not a folder structure or project layout convention. A project with `domain/`, `application/`, `infrastructure/` packages is not "doing DDD" — it may just be doing layered architecture.
|
|
32
|
+
- DDD is not "use Repositories and Entities everywhere." Applying tactical patterns uniformly across all subdomains is cargo-culting.
|
|
33
|
+
- DDD is not a coding pattern library you adopt independently of domain experts. Without collaboration and a shared language, you have overhead without value.
|
|
34
|
+
- DDD is not synonymous with microservices, though the two are often combined. Bounded Contexts can be implemented as modules within a monolith.
|
|
35
|
+
- "We use DDD because we have ValueObjects" is the most common misconception. Immutable data classes do not constitute domain-driven design.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## When to Use It
|
|
40
|
+
|
|
41
|
+
DDD delivers genuine value in a specific intersection of conditions. All of these should be present, or nearly so:
|
|
42
|
+
|
|
43
|
+
**Complex domain logic that domain experts can articulate.** Insurance premium calculation, logistics routing with constraints, financial instrument pricing, healthcare clinical workflows, legal compliance rules — domains where business rules are numerous, change independently, and have subtleties that only subject matter experts understand. Not domains where the logic is essentially database CRUD with a UI in front of it.
|
|
44
|
+
|
|
45
|
+
**Multiple teams that need to own subdomains independently.** When different groups (teams, departments, vendors) have different models for overlapping concepts, strategic DDD gives you the tools to draw those boundaries deliberately rather than having them emerge as coupling.
|
|
46
|
+
|
|
47
|
+
**Long-lived systems with expected evolution (5+ years).** The upfront investment in domain modeling amortizes over time. Systems expected to last less than two years rarely justify the overhead.
|
|
48
|
+
|
|
49
|
+
**Domain experts who are available and willing to collaborate.** DDD is fundamentally a collaborative methodology. If business experts won't sit in modeling workshops, the approach loses its primary source of value. Access to domain experts is a hard prerequisite, not a nice-to-have.
|
|
50
|
+
|
|
51
|
+
**When the cost of misunderstanding the domain is high.** In insurance, a wrong model for "policy holder" vs. "insured" can produce incorrect premium calculations at scale. In healthcare, a wrong model for "patient encounter" can cause data to be associated with the wrong clinical event. The potential damage from domain misalignment justifies the investment in getting it right.
|
|
52
|
+
|
|
53
|
+
### Real Cases Where DDD Applied Well
|
|
54
|
+
|
|
55
|
+
**Uber's DOMA (Domain-Oriented Microservice Architecture):** As Uber grew to approximately 2,200 critical microservices, the company applied domain-driven principles to consolidate them into 70 domains, each with a single gateway entry point. Teams could call one gateway instead of dozens of downstream services. The result: order-of-magnitude reduction in platform support costs, 25–50% decrease in new feature onboarding time, and independent team operation. Uber explicitly credits DDD principles alongside Clean Architecture and SOA.
|
|
56
|
+
|
|
57
|
+
**Netflix content delivery architecture:** Netflix identified key bounded contexts — User Management, Content Catalog, Recommendations, Playback — and mapped each to cohesive service groups. Netflix's own definition of a well-designed microservice mirrors DDD: "loosely coupled with bounded context — if you don't have bounded context, you have to know too much about what's around you." Continuous refinement of service boundaries, driven by domain understanding, was central to their scaling story.
|
|
58
|
+
|
|
59
|
+
**Banking core systems:** Major banks (e.g., systems built on Axon Framework in the Netherlands) model Account Management, Transaction Processing, Loan Processing, and Customer Service as separate bounded contexts with explicit context maps. The "Account" concept in Account Management has a different model than "Account" in Risk Management — and DDD gives teams the vocabulary to make that explicit rather than forcing an impossible universal Account model.
|
|
60
|
+
|
|
61
|
+
**Healthcare EHR systems:** Clinical workflows require separating the clinical domain (diagnoses, treatment plans, medication orders) from the administrative domain (billing codes, insurance authorizations, scheduling). A single model for "encounter" that serves both clinical and billing needs is invariably wrong for at least one of them.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## When NOT to Use It
|
|
66
|
+
|
|
67
|
+
This section is as important as the previous one. The failure modes of misapplied DDD are severe: months of upfront modeling investment, architectural complexity far exceeding what the problem requires, and teams that spend more time debating aggregate boundaries than delivering software.
|
|
68
|
+
|
|
69
|
+
### Simple CRUD Applications
|
|
70
|
+
|
|
71
|
+
If the core activity of your system is storing and retrieving records — user management, content management systems, basic inventory, most B2C consumer apps — DDD is the wrong tool. These domains have little complex behavior. The "business rules" are simple validation. There is no rich domain model to discover. Applying Aggregates and Domain Events to a to-do app or a blog platform produces a heavily over-engineered system where every feature change requires touching five layers of abstraction.
|
|
72
|
+
|
|
73
|
+
**Real example of overuse:** Startups have spent 3+ months modeling aggregates, value objects, and domain events for early-stage products with fewer than 100 users and a domain that amounts to "users post content and other users read it." The time would have been better spent shipping.
|
|
74
|
+
|
|
75
|
+
### Technical and Infrastructure Domains
|
|
76
|
+
|
|
77
|
+
Logging pipelines, authentication middleware, API gateways, deployment infrastructure — these are technical problems, not business domain problems. They have no "domain experts" in the DDD sense and no rich business concepts to model. Applying DDD here produces the vocabulary of DDD without any of the substance.
|
|
78
|
+
|
|
79
|
+
### Teams Without Domain Expert Access
|
|
80
|
+
|
|
81
|
+
Without domain experts, you have no source of ubiquitous language. Developers will invent a domain model based on their assumptions about the business, which is exactly the situation DDD was designed to prevent. If the "domain expert" is a product manager who has never spoken to an actual customer or understands the business process only superficially, the collaboration assumption of DDD is not met.
|
|
82
|
+
|
|
83
|
+
### Short-Horizon Projects (Less Than 6 Months)
|
|
84
|
+
|
|
85
|
+
The investment in strategic DDD — event storming workshops, context mapping, subdomain analysis, establishing ubiquitous language — takes time. For projects with a lifecycle shorter than 6 months or proof-of-concept work that may never reach production, this investment does not pay off. A well-structured layered architecture is usually sufficient.
|
|
86
|
+
|
|
87
|
+
### Small Teams (Fewer Than 5 Developers)
|
|
88
|
+
|
|
89
|
+
The primary benefit of strategic DDD is organizational: clear team ownership of bounded contexts, explicit contracts between contexts, and independent evolution. With a team of 2–4 developers, everyone can hold the entire model in their heads and communicate informally. The overhead of formal context maps and ACLs is pure friction with no corresponding benefit.
|
|
90
|
+
|
|
91
|
+
### When Domain Experts Cannot Describe Their Own Rules
|
|
92
|
+
|
|
93
|
+
Some domains have rules so deeply tacit that domain experts cannot articulate them — they just know when something looks right. In these cases, collaborative modeling is impossible. Machine learning approaches often handle these better than explicit domain models.
|
|
94
|
+
|
|
95
|
+
### The Cargo-Cult Warning
|
|
96
|
+
|
|
97
|
+
The most common failure mode is cargo-culting tactical DDD patterns without strategic DDD. Teams adopt Aggregates, Value Objects, and Repositories as a "best practice" layer on top of what is fundamentally a CRUD application. This adds 40–60% more code for the same functionality, makes the system harder to understand for new developers, and creates the illusion of a rich domain model where none exists. INNOQ's analysis of this pattern notes that teams often end up with all the costs of a domain model without any of the benefits — the same criticism Martin Fowler leveled at the Anemic Domain Model.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## How It Works
|
|
102
|
+
|
|
103
|
+
### Strategic DDD Patterns
|
|
104
|
+
|
|
105
|
+
#### Bounded Context
|
|
106
|
+
|
|
107
|
+
A Bounded Context is an explicit boundary within which a particular domain model is defined and applicable. Within the boundary, all terms have a specific, agreed-upon meaning. Outside the boundary, the same term may mean something different.
|
|
108
|
+
|
|
109
|
+
**How to identify boundaries:**
|
|
110
|
+
|
|
111
|
+
- *Linguistic boundaries:* Where does the same word mean different things? In an e-commerce company, "Product" in the Catalog context (description, images, specifications) is a different concept from "Product" in the Inventory context (SKU, warehouse location, stock level) and "Product" in the Pricing context (price tiers, discounts, promotions). These different meanings are a signal that three separate bounded contexts exist.
|
|
112
|
+
- *Team boundaries:* Conway's Law suggests that systems reflect the communication structure of the organizations that build them. Let team ownership drive context boundaries, or deliberately restructure teams to match desired architecture (the Inverse Conway Maneuver).
|
|
113
|
+
- *Data ownership boundaries:* Which team has the authoritative record for a given entity? That authority defines a context boundary. No two bounded contexts should both claim write authority over the same data without an explicit agreement pattern.
|
|
114
|
+
- *Rate-of-change boundaries:* Business capabilities that change at different rates for different reasons (promotions change daily; product taxonomy changes quarterly; accounting rules change annually) are candidates for separate contexts.
|
|
115
|
+
|
|
116
|
+
**Real example — electricity utility:** In one utility company, the word "meter" meant subtly different things across departments: the physical device, the connection between the grid and a location, the billing relationship between the grid and a customer. A single "meter" model was impossible; three separate bounded contexts, each with their own meter concept, was the correct answer.
|
|
117
|
+
|
|
118
|
+
#### Context Map
|
|
119
|
+
|
|
120
|
+
A Context Map documents the relationships between bounded contexts. It is not a UML diagram — it is a strategic document showing how teams interact and how models translate across boundaries. The relationship patterns:
|
|
121
|
+
|
|
122
|
+
| Pattern | Description | Use When |
|
|
123
|
+
|---------|-------------|----------|
|
|
124
|
+
| **Shared Kernel** | Two contexts share a subset of the domain model, jointly owned | Close teams with tight coupling that cannot be avoided |
|
|
125
|
+
| **Customer-Supplier** | Upstream context (supplier) publishes; downstream (customer) consumes | Clear upstream/downstream dependency with negotiated interface |
|
|
126
|
+
| **Conformist** | Downstream context simply conforms to upstream model without translation | When translation cost exceeds benefit; upstream won't negotiate |
|
|
127
|
+
| **Anticorruption Layer (ACL)** | Downstream translates upstream model into its own language | Protecting a clean model from a legacy or external system |
|
|
128
|
+
| **Open Host Service (OHS)** | Upstream publishes a formal, stable API for multiple consumers | When many downstreams consume; upstream wants to decouple |
|
|
129
|
+
| **Published Language** | A shared, documented, versioned data format for cross-context integration | Event-driven integration; public API contracts |
|
|
130
|
+
| **Separate Ways** | No integration; contexts evolve entirely independently | When integration cost exceeds the benefit of shared data |
|
|
131
|
+
|
|
132
|
+
#### Ubiquitous Language
|
|
133
|
+
|
|
134
|
+
Ubiquitous Language is the shared vocabulary co-created by developers and domain experts that is used consistently in all conversations, documentation, and — critically — in the code itself. Class names, method names, variable names, and event names all reflect the language of the domain expert, not the implementation convenience of the developer.
|
|
135
|
+
|
|
136
|
+
**How to develop it in practice:**
|
|
137
|
+
|
|
138
|
+
1. Run domain storytelling sessions or EventStorming workshops with domain experts. The language that emerges naturally is the foundation.
|
|
139
|
+
2. Document contested terms in a glossary. When developers and business people disagree on what a term means, that disagreement is a signal — it may indicate a missing subdomain boundary.
|
|
140
|
+
3. Apply the language immediately in code. If the business says "quote" and the code says `PriceEstimateRequest`, the model has already drifted.
|
|
141
|
+
4. Treat language drift as a bug. When the code's language diverges from the domain language, the model is losing fidelity. Schedule model refinement.
|
|
142
|
+
5. The language is bounded: "Customer" in Sales means something different from "Customer" in Support. The ubiquitous language belongs to a specific bounded context.
|
|
143
|
+
|
|
144
|
+
#### Subdomains
|
|
145
|
+
|
|
146
|
+
Subdomains classify parts of the business by strategic importance:
|
|
147
|
+
|
|
148
|
+
**Core Domain:** The part of the business that creates competitive advantage. This is where the organization wins or loses in the market. It deserves the most attention, the best developers, and full tactical DDD investment. In a logistics company, route optimization is core. In a bank, risk modeling is core. Core domains must not be outsourced or built from generic off-the-shelf solutions.
|
|
149
|
+
|
|
150
|
+
**Supporting Domain:** Necessary to the business but not differentiating. It supports the core domain. Can often be built simply (even as CRUD), or outsourced. In the same logistics company, a driver onboarding workflow is supporting.
|
|
151
|
+
|
|
152
|
+
**Generic Domain:** Commodity functionality that any business needs. Authentication, billing, email sending, notifications. Buy or use off-the-shelf. Building these as custom software is waste. Applying tactical DDD here is almost always wrong.
|
|
153
|
+
|
|
154
|
+
The practical implication: apply tactical DDD patterns (Aggregates, Domain Events, rich models) only in the **core domain**. Use simple CRUD or third-party services for generic domains. Use simple services for supporting domains. This is where the "DDD everywhere" failure mode is most damaging — teams apply tactical complexity uniformly across all subdomains when it only belongs in core.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
### Tactical DDD Patterns
|
|
159
|
+
|
|
160
|
+
Tactical patterns are implementation-level building blocks for modeling within a single bounded context. They are most valuable in the core domain.
|
|
161
|
+
|
|
162
|
+
#### Entity
|
|
163
|
+
|
|
164
|
+
An object defined primarily by its **identity** rather than its attributes. Two entities with the same attributes but different identities are different objects. State is mutable over time.
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
// An Order is an Entity — it has a unique identity (orderId)
|
|
168
|
+
// and its state changes over time (items added, status transitions)
|
|
169
|
+
class Order {
|
|
170
|
+
orderId: OrderId // identity
|
|
171
|
+
customerId: CustomerId // reference to another aggregate by ID
|
|
172
|
+
status: OrderStatus // mutable state
|
|
173
|
+
lineItems: LineItem[] // internal value objects
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
When to use: when an object has a life cycle, when you need to track a thing over time, when the "same" object with changed attributes is still considered the same object.
|
|
178
|
+
|
|
179
|
+
#### Value Object
|
|
180
|
+
|
|
181
|
+
An object defined entirely by its **attributes**. Two value objects with the same attributes are the same object. Immutable by definition — you don't change a value object, you replace it.
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
// Money is a Value Object — $10 USD is $10 USD regardless of which instance
|
|
185
|
+
// No identity field; equality is structural
|
|
186
|
+
class Money {
|
|
187
|
+
readonly amount: Decimal // immutable
|
|
188
|
+
readonly currency: Currency
|
|
189
|
+
|
|
190
|
+
add(other: Money): Money { ... } // returns new instance, never mutates
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Value Objects should be the default choice. Reach for Entity only when identity tracking is genuinely needed. Rich value objects encapsulate validation (a `Money` that cannot represent a negative amount), making invariants self-enforcing.
|
|
195
|
+
|
|
196
|
+
#### Aggregate
|
|
197
|
+
|
|
198
|
+
An Aggregate is a cluster of associated Entities and Value Objects treated as a single unit for data changes, with one designated **Aggregate Root** as the only entry point for external interaction.
|
|
199
|
+
|
|
200
|
+
The Aggregate enforces consistency rules (invariants) within its boundary. Any state change that must be consistent must happen within the same aggregate, within a single transaction.
|
|
201
|
+
|
|
202
|
+
#### Domain Service
|
|
203
|
+
|
|
204
|
+
Logic that represents an important domain concept but doesn't naturally fit inside a single entity or value object. Stateless. Named after domain activities.
|
|
205
|
+
|
|
206
|
+
```
|
|
207
|
+
// FundsTransferService doesn't belong inside Account because it
|
|
208
|
+
// involves two accounts and a transfer policy
|
|
209
|
+
class FundsTransferService {
|
|
210
|
+
transfer(source: Account, destination: Account, amount: Money): TransferResult
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Domain Services are often over-used. Before creating one, genuinely ask: does this behavior belong in one of the entities involved? If yes, put it there (that's the rich domain model). Only create a Domain Service when the operation genuinely doesn't fit.
|
|
215
|
+
|
|
216
|
+
#### Repository
|
|
217
|
+
|
|
218
|
+
A collection-like abstraction that hides persistence mechanics. The interface belongs to the domain layer; the implementation belongs to infrastructure.
|
|
219
|
+
|
|
220
|
+
```
|
|
221
|
+
interface OrderRepository {
|
|
222
|
+
findById(id: OrderId): Order | null
|
|
223
|
+
findByCustomer(customerId: CustomerId): Order[]
|
|
224
|
+
save(order: Order): void
|
|
225
|
+
}
|
|
226
|
+
// The domain layer only knows about this interface
|
|
227
|
+
// PostgresOrderRepository implements it in the infrastructure layer
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
One Repository per Aggregate Root. Never one per Entity.
|
|
231
|
+
|
|
232
|
+
#### Domain Event
|
|
233
|
+
|
|
234
|
+
A record of something that happened in the domain that domain experts care about. Named in past tense. Immutable. Used for cross-aggregate integration and recording audit history.
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
class OrderPlaced {
|
|
238
|
+
readonly occurredAt: Date
|
|
239
|
+
readonly orderId: OrderId
|
|
240
|
+
readonly customerId: CustomerId
|
|
241
|
+
readonly totalAmount: Money
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Domain Events are the primary mechanism for eventual consistency between aggregates and between bounded contexts (via a message bus).
|
|
246
|
+
|
|
247
|
+
#### Application Service
|
|
248
|
+
|
|
249
|
+
The orchestration layer. Coordinates domain objects to fulfill a use case. Contains no domain logic itself — it delegates entirely to the domain model. Handles transactions, authentication, and cross-cutting concerns.
|
|
250
|
+
|
|
251
|
+
```
|
|
252
|
+
class PlaceOrderApplicationService {
|
|
253
|
+
placeOrder(command: PlaceOrderCommand): OrderId {
|
|
254
|
+
// 1. Load aggregates via repositories
|
|
255
|
+
// 2. Invoke domain logic
|
|
256
|
+
// 3. Persist via repositories
|
|
257
|
+
// 4. Publish domain events
|
|
258
|
+
// No business rules here — those live in Order
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
### Aggregate Design Rules
|
|
266
|
+
|
|
267
|
+
Vaughn Vernon's four rules from "Implementing Domain-Driven Design" (the "Red Book"):
|
|
268
|
+
|
|
269
|
+
**Rule 1 — Model true invariants in consistency boundaries.** An invariant is a business rule that must always be consistent. An Aggregate defines the boundary within which all invariants must be maintained in a single transaction. The discipline: identify your invariants first, then draw the aggregate boundary to contain them — not the other way around.
|
|
270
|
+
|
|
271
|
+
**Rule 2 — Design small aggregates.** "A large-cluster Aggregate will never perform or scale well. It is more likely to become a nightmare leading only to failure." The correct size is: the Aggregate Root entity plus the minimum number of additional objects needed to enforce consistency. This is almost always smaller than teams initially design. A `User` aggregate that contains their entire order history, all their addresses, all their payment methods, and their notification preferences is a textbook large-cluster anti-pattern. Each of those is likely a separate aggregate or a separate context.
|
|
272
|
+
|
|
273
|
+
**Rule 3 — Reference other aggregates by identity only.** Aggregates refer to other aggregates by their globally unique identifier, not by holding object references. This prevents accidental loading of large object graphs, forces explicit loading decisions, and makes aggregate boundaries legible in the code. A field `customerId: CustomerId` is correct. A field `customer: Customer` (where Customer is another aggregate) is wrong.
|
|
274
|
+
|
|
275
|
+
**Rule 4 — Use eventual consistency outside the boundary.** When a business rule spans multiple aggregates, it should be satisfied eventually via Domain Events, not immediately in a single transaction. If you find yourself updating two aggregates in a single transaction, either: (a) they should be one aggregate (they share an invariant), or (b) the operation should use eventual consistency. Most cross-aggregate "consistency" requirements turn out to be eventually consistent when you discuss them with domain experts.
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
### Integration Patterns Between Bounded Contexts
|
|
280
|
+
|
|
281
|
+
**Anti-Corruption Layer (ACL):** A translation layer that sits between a downstream context and an upstream context (or external system), converting the upstream model into the downstream context's language. This prevents the upstream model from "leaking" into and corrupting the carefully crafted downstream model.
|
|
282
|
+
|
|
283
|
+
Practical ACL structure:
|
|
284
|
+
- A Translator that maps upstream DTOs/models to downstream domain objects
|
|
285
|
+
- An Adapter that wraps the upstream API
|
|
286
|
+
- The downstream domain code never imports types from the upstream context directly
|
|
287
|
+
|
|
288
|
+
**Domain Events for cross-context integration:** The most loosely coupled integration pattern. The producing context publishes events on a message bus (Kafka, RabbitMQ, SNS) using its own language. Consuming contexts subscribe, translate via an ACL if needed, and react. The producer has no knowledge of consumers. This is how large-scale systems (Netflix, Uber) integrate dozens of contexts without creating a web of synchronous dependencies.
|
|
289
|
+
|
|
290
|
+
**Published Language:** A formal, versioned, documented data format shared across context boundaries. Often implemented as JSON schemas, Protobuf definitions, or AsyncAPI specifications. Differs from Shared Kernel in that it's a read-only contract — consumers don't contribute to its definition.
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
## Trade-Offs Matrix
|
|
295
|
+
|
|
296
|
+
| You Get | You Pay |
|
|
297
|
+
|---------|---------|
|
|
298
|
+
| Explicit, enforceable domain boundaries | Significant upfront analysis and design time |
|
|
299
|
+
| Code that speaks the domain language — readable by business and technical stakeholders | Learning curve for tactical patterns (weeks for developers new to DDD) |
|
|
300
|
+
| Team autonomy — teams can evolve their contexts independently | Domain expert time — requires sustained collaboration, not a one-time meeting |
|
|
301
|
+
| Aggregates enforce invariants — business rules cannot be violated by calling code | More code per feature in the core domain: entities, value objects, events, repositories vs. simple CRUD |
|
|
302
|
+
| Clear ownership of data — no ambiguity about which system is authoritative | Slower initial velocity (first 4–8 sprints) while patterns are established |
|
|
303
|
+
| Tactical patterns provide natural seams for testing | Risk of over-designing: applying full tactical DDD in supporting/generic domains where CRUD suffices |
|
|
304
|
+
| Context Maps make team dependencies visible and manageable | Context Map maintenance overhead — boundaries discovered wrong require expensive refactoring |
|
|
305
|
+
| Domain Events create an audit trail and enable eventual consistency | Event schema evolution is complex — consumers must handle multiple versions |
|
|
306
|
+
| Subdomains allow applying the right tool per capability | Requires organizational maturity: teams must respect context boundaries consistently |
|
|
307
|
+
| Long-term maintainability — the model stays aligned with business reality | Risk of ubiquitous language drift if collaboration discipline lapses |
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## Evolution Path
|
|
312
|
+
|
|
313
|
+
### Starting from Scratch
|
|
314
|
+
|
|
315
|
+
1. **Identify the core domain first.** Ask: "What do we do that no competitor can easily replicate? Where does the business win or lose?" That answer defines your core domain — the area that deserves the deepest investment.
|
|
316
|
+
|
|
317
|
+
2. **Run an EventStorming workshop.** Gather domain experts and developers in a room (physical or virtual) with sticky notes. Map the domain as a timeline of business events. This surfaces the natural seams in the domain, the language, the commands, the aggregates, and the context boundaries — all at once. Alberto Brandolini's EventStorming is the most effective technique for discovering bounded contexts that exists.
|
|
318
|
+
|
|
319
|
+
3. **Draw a Context Map.** Before writing code, document the bounded contexts you've identified and their relationships. Which teams own which contexts? Which are Customer-Supplier? Where are the ACL boundaries?
|
|
320
|
+
|
|
321
|
+
4. **Apply tactical patterns only in the core domain.** Supporting domains use simple services. Generic domains use off-the-shelf components. Tactical DDD patterns — Aggregates, Value Objects, Domain Events — are reserved for the core.
|
|
322
|
+
|
|
323
|
+
5. **Start with Ubiquitous Language.** Before defining classes, establish the glossary with domain experts. Run every entity name and method name past a domain expert. If they don't recognize the language, iterate.
|
|
324
|
+
|
|
325
|
+
### Refactoring from an Anemic Domain Model
|
|
326
|
+
|
|
327
|
+
An Anemic Domain Model is the most common failure state: entities that are essentially data bags (getters and setters only), with all logic scattered across service classes. Martin Fowler identified this anti-pattern in 2003: "The fundamental horror of this anti-pattern is that it's so contrary to the basic idea of object-oriented design; which is to combine data and process together."
|
|
328
|
+
|
|
329
|
+
Refactoring path:
|
|
330
|
+
|
|
331
|
+
1. **Identify the services with the most domain logic.** These are the services you need to push down into the domain model first.
|
|
332
|
+
2. **Find the invariants.** What rules does the service enforce about the entity's state? These should move into the entity as methods.
|
|
333
|
+
3. **Create Value Objects for concepts.** Primitive obsession (using `String` for email, `int` for money amounts) is a signal. Replace primitives with Value Objects that enforce their own validity.
|
|
334
|
+
4. **Define Aggregate Roots.** Which entity is the consistency boundary for a cluster? Make it the Aggregate Root, put the invariants there, remove direct access to internal entities from outside.
|
|
335
|
+
5. **Introduce Domain Events.** Replace direct method calls across aggregates with event publication and subscription.
|
|
336
|
+
6. This is a months-long migration, not a sprint. Prioritize the core domain, leave supporting domains anemic if they don't need the richness.
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## Failure Modes
|
|
341
|
+
|
|
342
|
+
### God Aggregates
|
|
343
|
+
|
|
344
|
+
The single most common tactical failure. A `User` aggregate that accumulates every concept connected to a user — profile, orders, addresses, payment methods, notification preferences, subscription status — becomes a massive, slow-to-load, contention-prone object. Every feature that touches "anything about a user" modifies the same aggregate, creating locking contention in RDBMS and making independent team evolution impossible.
|
|
345
|
+
|
|
346
|
+
**Symptoms:** Aggregate classes with 30+ fields. Repositories that load massive object graphs. Every team's changes conflict because they all touch the same aggregate. Slow transaction throughput on high-write entities.
|
|
347
|
+
|
|
348
|
+
**Fix:** Apply Aggregate Rule 2 ruthlessly. The `User` aggregate should contain only what is needed to enforce the user's core invariants (perhaps identity, credentials, status). Addresses, orders, payment methods are separate aggregates referencing `UserId`.
|
|
349
|
+
|
|
350
|
+
### Anemic Domain Model
|
|
351
|
+
|
|
352
|
+
Entities are passive data bags. All logic lives in `*Service` classes. This is the result of applying DDD's structural vocabulary (entities, repositories) without its substance (rich domain objects with behavior). The code incurs all DDD overhead with none of its benefits.
|
|
353
|
+
|
|
354
|
+
**Symptoms:** Entities have only getters and setters. `UserService.activate(userId)` rather than `user.activate()`. Business rules are duplicated across multiple service classes. Services have method counts in the dozens.
|
|
355
|
+
|
|
356
|
+
### Aggregate Crossing (Transactions Spanning Multiple Aggregates)
|
|
357
|
+
|
|
358
|
+
Developers write transactions that modify two or more aggregates atomically. This defeats the aggregate boundary and signals either: (a) the aggregates should be one (they share an invariant that requires synchronous consistency), or (b) the transaction needs to be decomposed into eventual consistency via Domain Events.
|
|
359
|
+
|
|
360
|
+
**Symptoms:** `@Transactional` methods that call multiple repositories. Saga/compensation logic written to handle partial failures.
|
|
361
|
+
|
|
362
|
+
### Ubiquitous Language Drift
|
|
363
|
+
|
|
364
|
+
The code's language diverges from the domain language over time. Classes are renamed for technical convenience. New developers use technical terms rather than domain terms. Domain experts stop being consulted. After two years, the codebase is written in "developer domain" that domain experts cannot read, and the original DDD investment is largely lost.
|
|
365
|
+
|
|
366
|
+
**Symptoms:** Domain experts cannot understand class names or method names when code is read aloud. Glossaries exist as docs but aren't reflected in code. Multiple synonyms for the same concept in the codebase.
|
|
367
|
+
|
|
368
|
+
**Fix:** Treat language drift as a bug. Regular model refinement sessions. Code review that includes checking naming against the ubiquitous language.
|
|
369
|
+
|
|
370
|
+
### Wrong Context Boundaries (Discovered Too Late)
|
|
371
|
+
|
|
372
|
+
The most expensive failure. Context boundaries are drawn incorrectly early in the project — perhaps too granular (splitting a single cohesive context into three), or too coarse (merging contexts that belong to different teams). Discovering this after 12 months of development means significant refactoring.
|
|
373
|
+
|
|
374
|
+
**Symptoms:** One team regularly needs to modify code in another team's context to complete features. Or: one context has become enormous with internal coupling that rivals the pre-boundary state.
|
|
375
|
+
|
|
376
|
+
**Prevention:** EventStorming early. Expect the first context map to be wrong. Plan an explicit checkpoint at 3 months to revisit boundaries based on what you've learned.
|
|
377
|
+
|
|
378
|
+
### Applying DDD to the Wrong Subdomain
|
|
379
|
+
|
|
380
|
+
Teams spend months applying full tactical DDD to supporting or generic domains — email notification service, user authentication, report generation — while the core domain gets insufficient attention. Supporting domains have low complexity; the DDD overhead produces no value.
|
|
381
|
+
|
|
382
|
+
**Real case (composite from community reports):** A fintech startup spent their first quarter applying DDD, CQRS, and Event Sourcing to their user registration and authentication flow — a generic domain that could have been handled by Auth0 or Cognito. Their actual core domain (novel risk scoring algorithm) was implemented as a single service with procedural code and no model. Six months later, the risk scoring service was unmaintainable; the authentication service was a perfectly modeled irrelevance.
|
|
383
|
+
|
|
384
|
+
---
|
|
385
|
+
|
|
386
|
+
## Technology Landscape
|
|
387
|
+
|
|
388
|
+
### DDD Frameworks
|
|
389
|
+
|
|
390
|
+
**Axon Framework (Java/Kotlin):** The most mature DDD + CQRS + Event Sourcing framework. Provides Aggregate annotations, Command Bus, Event Bus, Saga support, and optional Axon Server for event store. Used widely in Dutch banking and insurance. Opinionated — projects that diverge from its patterns face friction.
|
|
391
|
+
|
|
392
|
+
**Eventuate Platform (Java):** Framework for building microservices with Saga pattern, CQRS, and Event Sourcing. Less opinionated than Axon. Suitable for systems that need Saga-based distributed transactions.
|
|
393
|
+
|
|
394
|
+
**NestJS CQRS Module (Node.js/TypeScript):** Lightweight CQRS and Domain Events support within the NestJS ecosystem. Does not enforce DDD structure but provides the Command/Event/Query bus infrastructure. Common starting point for TypeScript DDD implementations.
|
|
395
|
+
|
|
396
|
+
**MediatR (C# /.NET):** The dominant mediator pattern library in .NET, widely used to implement the Command/Query separation part of CQRS and Application Service orchestration in DDD.NET projects.
|
|
397
|
+
|
|
398
|
+
### Domain Modeling and Discovery Tools
|
|
399
|
+
|
|
400
|
+
**EventStorming (Alberto Brandolini):** Facilitated workshop technique using sticky notes (physical or virtual via Miro/Mural) to map domain events, commands, aggregates, and context boundaries. The most effective known technique for discovering bounded contexts and building ubiquitous language. Available in Big Picture (strategic) and Design-Level (tactical) formats.
|
|
401
|
+
|
|
402
|
+
**ContextMapper:** Open-source DSL and toolset for modeling bounded contexts, context maps, and generating PlantUML diagrams, MDSL service contracts, and PlantUML class diagrams from the model. Actively maintained; integrates with EventStorming output. Supports all DDD context relationship patterns in code.
|
|
403
|
+
|
|
404
|
+
**Domain Storytelling:** Structured workshop format where domain experts tell stories about their work using a pictographic language. Complements EventStorming for early domain discovery.
|
|
405
|
+
|
|
406
|
+
### Related Architectural Patterns
|
|
407
|
+
|
|
408
|
+
**CQRS (Command Query Responsibility Segregation):** Separates write operations (Commands, processed by the domain model) from read operations (Queries, served by optimized read models). Frequently combined with DDD — the write side implements the rich domain model; the read side uses simple projections. Not required for DDD but addresses the impedance mismatch between a rich domain model and query performance needs.
|
|
409
|
+
|
|
410
|
+
**Event Sourcing:** Instead of storing current state, stores the sequence of Domain Events that produced that state. Provides a complete audit log, enables temporal queries, and makes Domain Events first-class citizens. High operational complexity — use only when the audit/temporal requirements genuinely justify it.
|
|
411
|
+
|
|
412
|
+
**Hexagonal Architecture (Ports and Adapters):** The preferred physical structure for implementing a DDD bounded context. The domain model is at the center; infrastructure (databases, message buses, HTTP) is outside. Domain interfaces (ports) define what infrastructure must provide; concrete implementations (adapters) plug in. Prevents domain model contamination by infrastructure concerns.
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
## Decision Tree
|
|
417
|
+
|
|
418
|
+
**Start here: How complex is the domain logic?**
|
|
419
|
+
|
|
420
|
+
```
|
|
421
|
+
Is the domain primarily CRUD (store/retrieve/display data)?
|
|
422
|
+
YES → Skip DDD entirely. Use a simple layered architecture.
|
|
423
|
+
Revisit if the domain grows significantly more complex.
|
|
424
|
+
NO → Continue
|
|
425
|
+
|
|
426
|
+
Do you have access to domain experts who can articulate the rules?
|
|
427
|
+
NO → DDD's collaborative foundation is absent.
|
|
428
|
+
Consider a lightweight domain model without full DDD investment.
|
|
429
|
+
YES → Continue
|
|
430
|
+
|
|
431
|
+
Is this a system expected to evolve for 2+ years with 5+ developers?
|
|
432
|
+
NO → Consider a modular monolith with clear module boundaries.
|
|
433
|
+
Full DDD tactical investment not warranted.
|
|
434
|
+
YES → Continue
|
|
435
|
+
|
|
436
|
+
Do you have multiple teams needing to own different capabilities independently?
|
|
437
|
+
NO → Apply strategic DDD (identify subdomains and bounded contexts)
|
|
438
|
+
but apply tactical DDD patterns only in the core domain.
|
|
439
|
+
Supporting domains use simple services.
|
|
440
|
+
YES → Start with a Context Map. Run EventStorming.
|
|
441
|
+
Apply tactical DDD only in the core domain.
|
|
442
|
+
Use simpler approaches (ACL, Published Language) for integration.
|
|
443
|
+
|
|
444
|
+
Is the core domain identifiable and significantly more complex than supporting domains?
|
|
445
|
+
YES → Full strategic + tactical DDD in core domain only.
|
|
446
|
+
This is the canonical DDD use case.
|
|
447
|
+
NO → The domain may be more uniform. Consider modular architecture
|
|
448
|
+
with consistent lightweight domain models rather than
|
|
449
|
+
full tactical DDD in some areas and CRUD in others.
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
**Shortcuts:**
|
|
453
|
+
- Fewer than 3 bounded contexts AND mostly CRUD operations → skip DDD tactical entirely
|
|
454
|
+
- Complex business rules that domain experts can clearly articulate → start with ubiquitous language + strategic DDD, add tactical patterns in the core domain
|
|
455
|
+
- Multiple teams owning different subdomains → draw the context map before writing any code
|
|
456
|
+
- Core domain with complex state transitions and invariants → full tactical DDD in the core domain, using Aggregates, Value Objects, and Domain Events
|
|
457
|
+
|
|
458
|
+
---
|
|
459
|
+
|
|
460
|
+
## Implementation Sketch
|
|
461
|
+
|
|
462
|
+
### Bounded Context Folder Structure
|
|
463
|
+
|
|
464
|
+
```
|
|
465
|
+
src/
|
|
466
|
+
ordering/ ← Bounded Context: Order Management
|
|
467
|
+
domain/
|
|
468
|
+
order/
|
|
469
|
+
Order.ts ← Aggregate Root
|
|
470
|
+
OrderId.ts ← Value Object
|
|
471
|
+
OrderStatus.ts ← Value Object (enum-like)
|
|
472
|
+
LineItem.ts ← Entity within aggregate
|
|
473
|
+
Money.ts ← Value Object
|
|
474
|
+
OrderPlaced.ts ← Domain Event
|
|
475
|
+
OrderCancelled.ts ← Domain Event
|
|
476
|
+
OrderRepository.ts ← Repository Interface (domain layer)
|
|
477
|
+
shared/
|
|
478
|
+
CustomerId.ts ← Value Object (cross-context ID reference)
|
|
479
|
+
application/
|
|
480
|
+
PlaceOrderCommand.ts
|
|
481
|
+
PlaceOrderHandler.ts ← Application Service
|
|
482
|
+
CancelOrderHandler.ts
|
|
483
|
+
infrastructure/
|
|
484
|
+
PostgresOrderRepository.ts ← Repository Implementation
|
|
485
|
+
OrderEventPublisher.ts
|
|
486
|
+
acl/
|
|
487
|
+
CatalogProductTranslator.ts ← ACL: translates catalog context's model
|
|
488
|
+
|
|
489
|
+
catalog/ ← Bounded Context: Product Catalog
|
|
490
|
+
domain/
|
|
491
|
+
...
|
|
492
|
+
|
|
493
|
+
shipping/ ← Bounded Context: Shipping & Fulfillment
|
|
494
|
+
domain/
|
|
495
|
+
...
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
### Aggregate Root Example
|
|
499
|
+
|
|
500
|
+
```typescript
|
|
501
|
+
// domain/order/Order.ts
|
|
502
|
+
class Order {
|
|
503
|
+
private readonly _orderId: OrderId;
|
|
504
|
+
private _status: OrderStatus;
|
|
505
|
+
private _lineItems: LineItem[];
|
|
506
|
+
private _domainEvents: DomainEvent[] = [];
|
|
507
|
+
|
|
508
|
+
private constructor(orderId: OrderId, customerId: CustomerId) {
|
|
509
|
+
this._orderId = orderId;
|
|
510
|
+
this._customerId = customerId;
|
|
511
|
+
this._status = OrderStatus.DRAFT;
|
|
512
|
+
this._lineItems = [];
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
static place(customerId: CustomerId, items: LineItemSpec[]): Order {
|
|
516
|
+
if (items.length === 0) {
|
|
517
|
+
throw new DomainError("Order must have at least one item");
|
|
518
|
+
}
|
|
519
|
+
const order = new Order(OrderId.generate(), customerId);
|
|
520
|
+
items.forEach(spec => order.addLineItem(spec));
|
|
521
|
+
order._status = OrderStatus.PLACED;
|
|
522
|
+
order.record(new OrderPlaced(order._orderId, order._customerId, order.total()));
|
|
523
|
+
return order;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
cancel(reason: CancellationReason): void {
|
|
527
|
+
if (!this._status.isCancellable()) {
|
|
528
|
+
throw new DomainError(`Cannot cancel order in status ${this._status}`);
|
|
529
|
+
}
|
|
530
|
+
this._status = OrderStatus.CANCELLED;
|
|
531
|
+
this.record(new OrderCancelled(this._orderId, reason));
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// Invariant enforced here: no direct access to _lineItems from outside
|
|
535
|
+
private addLineItem(spec: LineItemSpec): void {
|
|
536
|
+
this._lineItems.push(LineItem.create(spec));
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
total(): Money {
|
|
540
|
+
return this._lineItems.reduce(
|
|
541
|
+
(sum, item) => sum.add(item.subtotal()), Money.ZERO
|
|
542
|
+
);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
private record(event: DomainEvent): void {
|
|
546
|
+
this._domainEvents.push(event);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
pullDomainEvents(): DomainEvent[] {
|
|
550
|
+
const events = [...this._domainEvents];
|
|
551
|
+
this._domainEvents = [];
|
|
552
|
+
return events;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
### Value Object Example
|
|
558
|
+
|
|
559
|
+
```typescript
|
|
560
|
+
// domain/order/Money.ts
|
|
561
|
+
class Money {
|
|
562
|
+
static readonly ZERO = new Money(new Decimal(0), Currency.USD);
|
|
563
|
+
|
|
564
|
+
private constructor(
|
|
565
|
+
private readonly _amount: Decimal,
|
|
566
|
+
private readonly _currency: Currency
|
|
567
|
+
) {
|
|
568
|
+
if (_amount.isNegative()) {
|
|
569
|
+
throw new DomainError("Money amount cannot be negative");
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
static of(amount: number, currency: Currency): Money {
|
|
574
|
+
return new Money(new Decimal(amount), currency);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
add(other: Money): Money {
|
|
578
|
+
if (!this._currency.equals(other._currency)) {
|
|
579
|
+
throw new DomainError("Cannot add money of different currencies");
|
|
580
|
+
}
|
|
581
|
+
return new Money(this._amount.plus(other._amount), this._currency);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
equals(other: Money): boolean {
|
|
585
|
+
return this._amount.equals(other._amount) &&
|
|
586
|
+
this._currency.equals(other._currency);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
// No setters — immutable by design
|
|
590
|
+
}
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
### Domain Event Example
|
|
594
|
+
|
|
595
|
+
```typescript
|
|
596
|
+
// domain/order/OrderPlaced.ts
|
|
597
|
+
class OrderPlaced implements DomainEvent {
|
|
598
|
+
readonly eventType = "ordering.OrderPlaced";
|
|
599
|
+
readonly occurredAt: Date;
|
|
600
|
+
readonly orderId: string;
|
|
601
|
+
readonly customerId: string;
|
|
602
|
+
readonly totalAmount: { amount: string; currency: string };
|
|
603
|
+
|
|
604
|
+
constructor(orderId: OrderId, customerId: CustomerId, total: Money) {
|
|
605
|
+
this.occurredAt = new Date();
|
|
606
|
+
this.orderId = orderId.value;
|
|
607
|
+
this.customerId = customerId.value;
|
|
608
|
+
this.totalAmount = total.serialize();
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
### Application Service Orchestrating Domain Objects
|
|
614
|
+
|
|
615
|
+
```typescript
|
|
616
|
+
// application/PlaceOrderHandler.ts
|
|
617
|
+
class PlaceOrderHandler {
|
|
618
|
+
constructor(
|
|
619
|
+
private readonly orderRepository: OrderRepository,
|
|
620
|
+
private readonly catalogAcl: CatalogACL, // ACL to catalog context
|
|
621
|
+
private readonly eventPublisher: DomainEventPublisher
|
|
622
|
+
) {}
|
|
623
|
+
|
|
624
|
+
async handle(command: PlaceOrderCommand): Promise<OrderId> {
|
|
625
|
+
// Translate incoming data through ACL
|
|
626
|
+
const lineItemSpecs = await this.catalogAcl.resolveItems(command.requestedItems);
|
|
627
|
+
|
|
628
|
+
// All domain logic inside domain objects
|
|
629
|
+
const order = Order.place(
|
|
630
|
+
CustomerId.of(command.customerId),
|
|
631
|
+
lineItemSpecs
|
|
632
|
+
);
|
|
633
|
+
|
|
634
|
+
// Persist
|
|
635
|
+
await this.orderRepository.save(order);
|
|
636
|
+
|
|
637
|
+
// Publish domain events (cross-context integration)
|
|
638
|
+
const events = order.pullDomainEvents();
|
|
639
|
+
await this.eventPublisher.publishAll(events);
|
|
640
|
+
|
|
641
|
+
return order.orderId;
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
// Note: no business rules here — all in Order.place() and Order.cancel()
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
### ACL Translating Between Contexts
|
|
648
|
+
|
|
649
|
+
```typescript
|
|
650
|
+
// acl/CatalogProductTranslator.ts
|
|
651
|
+
// The ordering context's view of a product — different from catalog context's Product
|
|
652
|
+
interface OrderableProduct {
|
|
653
|
+
productId: ProductId;
|
|
654
|
+
currentPrice: Money;
|
|
655
|
+
isAvailable: boolean;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
class CatalogACL {
|
|
659
|
+
constructor(private readonly catalogClient: CatalogServiceClient) {}
|
|
660
|
+
|
|
661
|
+
async resolveItems(requests: RequestedItem[]): Promise<LineItemSpec[]> {
|
|
662
|
+
// Catalog context returns its own model
|
|
663
|
+
const catalogProducts = await this.catalogClient.getProducts(
|
|
664
|
+
requests.map(r => r.catalogProductId)
|
|
665
|
+
);
|
|
666
|
+
|
|
667
|
+
// ACL translates catalog language into ordering language
|
|
668
|
+
return requests.map(request => {
|
|
669
|
+
const catalogProduct = catalogProducts.find(
|
|
670
|
+
p => p.id === request.catalogProductId
|
|
671
|
+
);
|
|
672
|
+
if (!catalogProduct || !catalogProduct.available) {
|
|
673
|
+
throw new DomainError(`Product ${request.catalogProductId} is not orderable`);
|
|
674
|
+
}
|
|
675
|
+
return new LineItemSpec(
|
|
676
|
+
ProductId.of(catalogProduct.id),
|
|
677
|
+
Money.of(catalogProduct.listPrice, Currency.of(catalogProduct.currency)),
|
|
678
|
+
request.quantity
|
|
679
|
+
);
|
|
680
|
+
});
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
---
|
|
686
|
+
|
|
687
|
+
## Frequently Encountered Debates
|
|
688
|
+
|
|
689
|
+
**"Should bounded contexts map 1:1 to microservices?"**
|
|
690
|
+
No. A Bounded Context is a domain concept (a coherent model with its own language). A microservice is a deployment unit. One bounded context can be deployed as multiple services; one service can contain multiple bounded contexts (though the latter should be avoided in mature architectures). Start with bounded contexts as modules in a monolith; extract to services when operational needs (independent scaling, separate deployment cadence) justify the distributed systems overhead.
|
|
691
|
+
|
|
692
|
+
**"Is CQRS required for DDD?"**
|
|
693
|
+
No. CQRS is frequently used with DDD because rich aggregate models are optimized for writes (invariant enforcement) but poor for reads (complex queries across aggregates). CQRS separates these concerns. But DDD's domain model works without CQRS; only add CQRS when query performance problems actually emerge from the rich model.
|
|
694
|
+
|
|
695
|
+
**"Should aggregates be serialized directly to the database?"**
|
|
696
|
+
Generally no. Aggregate design should be driven by domain invariants, not by the relational schema. Use a mapping layer (or an ORM that supports domain model mapping, like Hibernate with embeddables for Value Objects). Object-Relational impedance mismatch is a real problem; accepting it is better than letting database schema dictate aggregate structure.
|
|
697
|
+
|
|
698
|
+
**"Can DDD and LLMs/AI work together?"**
|
|
699
|
+
Eric Evans, at Explore DDD 2024: yes. "Some parts of complex systems never fit into structured parts of domain models and are typically handled by humans." LLMs can take over those unstructured parts. He encouraged practitioners to experiment with combining DDD's explicit model for the structured domain with LLM capabilities for the unstructured parts. The domain model provides the guardrails and interpretation layer for LLM outputs.
|
|
700
|
+
|
|
701
|
+
---
|
|
702
|
+
|
|
703
|
+
*Researched: 2026-03-08*
|
|
704
|
+
|
|
705
|
+
*Sources:*
|
|
706
|
+
- *Evans, Eric. "Domain-Driven Design: Tackling Complexity in the Heart of Software." Addison-Wesley, 2003.*
|
|
707
|
+
- *Vernon, Vaughn. "Implementing Domain-Driven Design." Addison-Wesley, 2013.*
|
|
708
|
+
- *Vernon, Vaughn. "Effective Aggregate Design" (essay series). DDD Community, 2011. https://www.dddcommunity.org/library/vernon_2011/*
|
|
709
|
+
- *Fowler, Martin. "Bounded Context." martinfowler.com. https://martinfowler.com/bliki/BoundedContext.html*
|
|
710
|
+
- *Fowler, Martin. "Anemic Domain Model." martinfowler.com. https://martinfowler.com/bliki/AnemicDomainModel.html*
|
|
711
|
+
- *Fowler, Martin. "Ubiquitous Language." martinfowler.com. https://martinfowler.com/bliki/UbiquitousLanguage.html*
|
|
712
|
+
- *InfoQ. "Eric Evans Encourages DDD Practitioners to Experiment with LLMs." March 2024. https://www.infoq.com/news/2024/03/Evans-ddd-experiment-llm/*
|
|
713
|
+
- *Uber Engineering. "Introducing Domain-Oriented Microservice Architecture." Uber Blog, 2020. https://www.uber.com/blog/microservice-architecture/*
|
|
714
|
+
- *ContextMapper. "Context Mapper — Open Source DDD Tooling." https://contextmapper.org/*
|
|
715
|
+
- *Microsoft Azure Architecture Center. "Use Domain Analysis to Model Microservices." https://learn.microsoft.com/en-us/azure/architecture/microservices/model/domain-analysis*
|
|
716
|
+
- *INNOQ. "Is Domain-Driven Design Overrated?" 2021. https://www.innoq.com/en/blog/2021/03/is-domain-driven-design-overrated/*
|
|
717
|
+
- *CodeOpinion. "STOP doing dogmatic Domain Driven Design." https://codeopinion.com/stop-doing-dogmatic-domain-driven-design/*
|
|
718
|
+
- *InfoQ. "Practical DDD: Bounded Contexts + Events => Microservices." https://www.infoq.com/presentations/microservices-ddd-bounded-contexts/*
|
|
719
|
+
- *ddd-crew. "Bounded Context Canvas." GitHub. https://github.com/ddd-crew/bounded-context-canvas*
|