# configuration/principle/data/architecture.domain.data.json

> 472 lines of code and 0 definitions.

Tree: GovLab Context
Language: json
Layer: domain
Canonical: https://banes-lab.com/anatomy/context#file-context-configuration-principle-data-architecture-domain-data-json
Source text: https://banes-lab.com/source/context/configuration/principle/data/architecture.domain.data.json.txt

Listed in [configuration/principle/data](https://banes-lab.com/api/source/context/configuration/principle/data.md), after [configuration/principle/data/anti-pattern.data.json](https://banes-lab.com/source/context/configuration/principle/data/anti-pattern.data.json.md) and before [configuration/principle/data/binding.data.json](https://banes-lab.com/source/context/configuration/principle/data/binding.data.json.md).

## Contained in

- [configuration/principle/data](https://banes-lab.com/anatomy/context/folder-context-configuration-principle-data.md)

## Source

```json
{
    "category": "Domain Architecture",
    "check": {
        "population": "every domain type, business rule and context boundary in the domain layer",
        "freshness": "a verdict stands until a domain type, a rule's location or a context boundary changes",
        "refusal": "the layer rule or the domain test fails when a rule or a model leaves its context or its aggregate",
        "observation": "where each business rule and invariant is enforced, read from source and the domain tests",
        "evidence": "none: the catalog states this check as a class, so a watched run belongs to each system that adopts it",
        "authority": "the domain model, which decides the context and the aggregate every rule belongs to"
    },
    "records": [
        {
            "id": "domain-driven-design",
            "distinctFrom": [
                {
                    "id": "architecture:event-driven-architecture",
                    "reason": "Domain-driven design models software on the domain's language, while event-driven architecture connects services through published events."
                }
            ],
            "aliases": ["DDD"],
            "name": "Domain-Driven Design (DDD)",
            "definition": "A convention of modeling software on the business domain's own language, split into bounded contexts with a domain model in each.",
            "type": "style",
            "scope": [
                "domain",
                "bounded context",
                "system"
            ],
            "requires": [
                "Ubiquitous Language",
                "Bounded Context"
            ],
            "reinforces": [
                "Domain Model",
                "Semantic Consistency"
            ],
            "enables": ["Domain Alignment"],
            "conflicts_with": ["Anemic Transaction Script"],
            "tensions_with": ["Simple CRUD"],
            "violated_by": [
                "architecture:anemic-domain-model",
                "architecture:fat-controller"
            ],
            "detected_by": [
                "anemic models",
                "scattered business rules"
            ],
            "measured_by": ["domain logic locality"],
            "refactored_by": [
                "lexicon:extract-domain-model",
                "architecture:aggregate",
                "lexicon:split-bounded-context"
            ],
            "enforced_by": [
                "layer rules",
                "domain tests"
            ],
            "severity": "contextual",
            "exemplar": {
                "before": "function updateFoo(row: FooRow, name: string) {\n  row.name = name;\n  row.updated_at = Date.now();\n  return fooTable.save(row);\n}",
                "after": "class Foo {\n  private constructor(readonly id: FooId, private name: string) {}\n  rename(name: FooName) { this.name = name.value; }\n}\nfoo.rename(FooName.create(name));",
                "lang": "ts"
            }
        },
        {
            "id": "domain-model",
            "name": "Domain Model",
            "definition": "A formal definition of the business concepts, rules and invariants of one context, written as types with behavior.",
            "type": "artifact",
            "scope": [
                "domain",
                "bounded context"
            ],
            "requires": [
                "Ubiquitous Language",
                "Invariant"
            ],
            "reinforces": [
                "Correctness",
                "Semantic Contracts"
            ],
            "enables": ["Business Rule Encapsulation"],
            "conflicts_with": ["Anemic Model"],
            "tensions_with": ["Persistence Simplicity"],
            "violated_by": ["architecture:anemic-domain-model"],
            "detected_by": ["procedural domain logic in services/controllers"],
            "measured_by": [
                "rule locality",
                "invariant coverage"
            ],
            "refactored_by": [
                "lexicon:move-logic-to-the-domain",
                "architecture:value-object",
                "architecture:aggregate"
            ],
            "enforced_by": [
                "domain layer rules",
                "tests"
            ],
            "severity": "contextual",
            "exemplar": {
                "before": "type Foo = { status: string; count: number };\nfunction closeFoo(foo: Foo) { foo.status = \"closed\"; }",
                "after": "class Foo {\n  #status: \"open\" | \"closed\" = \"open\";\n  close() {\n    if (this.#status === \"closed\") throw new Error(\"Foo already closed\");\n    this.#status = \"closed\";\n  }\n}",
                "lang": "ts"
            }
        },
        {
            "id": "bounded-context",
            "distinctFrom": [
                {
                    "id": "lexicon:relationship-semantics",
                    "reason": "A bounded context fixes meaning inside one boundary, while relationship semantics fixes the meaning of each link between boundaries."
                }
            ],
            "name": "Bounded Context",
            "definition": "A rule or precondition that each domain model holds inside one explicit boundary, where its terms have one meaning.",
            "type": "constraint",
            "scope": [
                "domain",
                "service",
                "team"
            ],
            "requires": [
                "Explicit Boundaries",
                "Ubiquitous Language"
            ],
            "reinforces": [
                "Modularity",
                "Autonomy"
            ],
            "enables": [
                "Context Mapping",
                "Microservices"
            ],
            "conflicts_with": ["Shared Global Model"],
            "tensions_with": ["Cross-Context Reuse"],
            "violated_by": ["lexicon:shared-global-model"],
            "detected_by": ["shared domain entities across contexts"],
            "measured_by": ["context coupling"],
            "refactored_by": [
                "lexicon:split-bounded-context",
                "architecture:anti-corruption-layer",
                "architecture:context-mapping"
            ],
            "enforced_by": ["package/service boundaries"],
            "severity": "recommended",
            "exemplar": {
                "before": "type FooStatus = \"A\" | \"D\";\nfunction priceBar(status: FooStatus) { return status === \"A\" ? 10 : 0; }",
                "after": "type FooStatus = \"active\" | \"disabled\";\ntype BarEligibility = \"eligible\" | \"ineligible\";\nfunction toBarEligibility(status: FooStatus): BarEligibility {\n  return status === \"active\" ? \"eligible\" : \"ineligible\";\n}",
                "lang": "ts"
            }
        },
        {
            "id": "context-mapping",
            "name": "Context Mapping",
            "definition": "The activity of recording how bounded contexts relate, including which one is upstream and how their models translate.",
            "type": "activity",
            "scope": [
                "bounded contexts",
                "integration"
            ],
            "requires": [
                "Bounded Context",
                "Relationship Semantics"
            ],
            "reinforces": [
                "Explicit Boundaries",
                "Integration Clarity"
            ],
            "enables": ["Anti-Corruption Layer"],
            "conflicts_with": ["Implicit Integration"],
            "tensions_with": ["Documentation Overhead"],
            "violated_by": ["lexicon:implicit-integration"],
            "detected_by": [
                "unclear ownership",
                "ambiguous integration flows"
            ],
            "measured_by": ["undocumented dependency count"],
            "refactored_by": [],
            "enforced_by": [
                "architecture docs",
                "dependency reviews"
            ],
            "severity": "recommended",
            "exemplar": {
                "before": "fooService.writeDirectly(barDatabase, foo);\nbarService.readDirectly(fooDatabase, foo.id);",
                "after": "const contextMap = {\n  upstream: \"FooContext\",\n  downstream: \"BarContext\",\n  relationship: \"published-language\",\n} as const;\nfooEvents.publish(toBarIntegrationEvent(foo));",
                "lang": "ts"
            }
        },
        {
            "id": "anti-corruption-layer",
            "name": "Anti-Corruption Layer",
            "definition": "A design pattern that translates an external system's model into the local domain's terms at the boundary.",
            "type": "pattern",
            "scope": [
                "integration",
                "bounded context boundary"
            ],
            "requires": [
                "Explicit Boundary",
                "Translation Model"
            ],
            "reinforces": [
                "Domain Purity",
                "Low Coupling"
            ],
            "enables": ["Legacy/System Integration"],
            "conflicts_with": [
                "Shared Model Coupling",
                "Vendor Lock-In Leakage"
            ],
            "tensions_with": ["Mapping Overhead"],
            "violated_by": ["lexicon:direct-external-coupling"],
            "detected_by": ["external DTOs used in domain layer"],
            "measured_by": [
                "leakage count",
                "adapter coverage"
            ],
            "refactored_by": [
                "lexicon:extract-adapter",
                "lexicon:introduce-boundary-dto"
            ],
            "enforced_by": [
                "import rules",
                "layer tests"
            ],
            "severity": "recommended",
            "exemplar": {
                "before": "function createBar(fooResponse: FooApiResponse) {\n  return barService.create({ foo_status: fooResponse.state_code });\n}",
                "after": "type BarInput = { eligible: boolean };\nfunction fromFoo(response: FooApiResponse): BarInput {\n  return { eligible: response.state_code === \"A\" };\n}\nbarService.create(fromFoo(fooResponse));",
                "lang": "ts"
            }
        },
        {
            "id": "explicit-boundaries",
            "distinctFrom": [
                {
                    "id": "architecture:declared-jurisdiction",
                    "reason": "Explicit boundaries declare a module's interface and owner, while declared jurisdiction declares which roots and files a naming gate governs."
                },
                {
                    "id": "architecture:abstraction",
                    "reason": "Explicit boundaries fix where one module ends, while abstraction fixes how a concept is expressed without its detail."
                },
                {
                    "id": "architecture:encapsulation",
                    "reason": "Explicit boundaries govern access between modules, while encapsulation governs changes to one object's state."
                },
                {
                    "id": "architecture:governance",
                    "reason": "Explicit boundaries are the declared interfaces, while governance holds decisions to shared policy."
                },
                {
                    "id": "architecture:single-source-of-truth",
                    "reason": "Explicit boundaries give each module one public interface, while a single source of truth gives each fact one owning definition."
                },
                {
                    "id": "architecture:independence",
                    "reason": "Explicit boundaries declare the interface, while independence is testing and deploying a module without its neighbors."
                },
                {
                    "id": "architecture:modularity",
                    "reason": "Explicit boundaries declare each module's interface and owner, while modularity is the division into modules itself."
                },
                {
                    "id": "architecture:separation-of-concerns",
                    "reason": "Explicit boundaries declare interfaces, while separation of concerns decides which concerns sit on each side of them."
                },
                {
                    "id": "architecture:single-responsibility",
                    "reason": "Explicit boundaries declare interfaces, while single responsibility limits what sits behind one to one reason to change."
                }
            ],
            "name": "Explicit Boundaries",
            "definition": "A design rule that each module declares its public interface and owner, and other modules reach it only through that interface.",
            "type": "principle",
            "scope": [
                "module",
                "component",
                "service",
                "domain"
            ],
            "requires": [
                "Stable Interfaces",
                "Ownership"
            ],
            "reinforces": [
                "Modularity",
                "Encapsulation"
            ],
            "enables": [
                "Replaceability",
                "Governance"
            ],
            "conflicts_with": ["Boundary Leakage"],
            "tensions_with": ["Cross-Cutting Concerns"],
            "violated_by": [
                "architecture:boundary-leakage",
                "architecture:inappropriate-intimacy"
            ],
            "detected_by": [
                "forbidden imports",
                "cyclic dependencies"
            ],
            "measured_by": ["boundary violation count"],
            "refactored_by": [
                "lexicon:move-behavior-to-its-owner",
                "lexicon:define-contract",
                "lexicon:restrict-exports"
            ],
            "enforced_by": [
                "module rules",
                "architecture tests"
            ],
            "severity": "mandatory",
            "exemplar": {
                "before": "import { fooDatabase } from \"../../foo/infrastructure/database\";\nexport function loadBar(id: string) { return fooDatabase.query(id); }",
                "after": "export interface FooGateway { find(id: FooId): Promise<FooSnapshot>; }\nexport function loadBar(id: FooId, foos: FooGateway) { return foos.find(id); }",
                "lang": "ts"
            }
        },
        {
            "id": "aggregate",
            "name": "Aggregate",
            "definition": "A design pattern that groups entities under one root, which is the only entry point and keeps the group's invariants.",
            "type": "pattern",
            "scope": [
                "domain",
                "consistency boundary",
                "bounded context"
            ],
            "requires": ["Explicit Boundaries"],
            "reinforces": [
                "Invariant",
                "Encapsulation"
            ],
            "enables": [
                "Transactional Consistency Boundary",
                "Root-Guarded Invariants"
            ],
            "conflicts_with": ["Anemic Domain Model"],
            "tensions_with": ["Aggregate Size"],
            "violated_by": ["architecture:anemic-domain-model"],
            "detected_by": ["cross-entity invariant checks scattered in services"],
            "measured_by": ["out-of-aggregate invariant enforcement count"],
            "refactored_by": ["lexicon:add-aggregate-invariant"],
            "enforced_by": ["domain model review"],
            "severity": "contextual",
            "exemplar": {
                "before": "fooOrder.total -= item.price;\nfooOrderItems.delete(item.id);",
                "after": "class FooOrder {\n  #items: FooItem[] = [];\n  #total = 0;\n  removeItem(id: FooItemId) {\n    this.#items = this.#items.filter(item => item.id !== id);\n    this.#total = this.#items.reduce((sum, item) => sum + item.price, 0);\n  }\n}",
                "lang": "ts"
            }
        },
        {
            "id": "value-object",
            "name": "Value Object",
            "definition": "A design pattern that models a domain value as an immutable, self-validating object compared by its attributes.",
            "type": "pattern",
            "scope": [
                "domain",
                "modeling",
                "immutability"
            ],
            "requires": ["Value Equality"],
            "reinforces": [
                "Immutability",
                "Encapsulation"
            ],
            "enables": [
                "Self-Validating Values",
                "Side-Effect-Free Equality"
            ],
            "conflicts_with": [
                "Primitive Obsession",
                "Data Clumps",
                "Long Parameter List"
            ],
            "tensions_with": ["Object Count"],
            "violated_by": ["architecture:primitive-obsession"],
            "detected_by": ["repeated validation of the same primitive shape"],
            "measured_by": ["primitive-typed domain concept count"],
            "refactored_by": [],
            "enforced_by": ["domain model review"],
            "severity": "recommended",
            "exemplar": {
                "before": "function priceFoo(amount: number, currency: string) { return { amount, currency }; }",
                "after": "class Money {\n  private constructor(readonly amount: number, readonly currency: string) {}\n  static of(amount: number, currency: string): Money {\n    if (amount < 0) throw new Error(\"negative money\");\n    return new Money(amount, currency);\n  }\n  equals(other: Money) { return this.amount === other.amount && this.currency === other.currency; }\n  add(other: Money): Money { return Money.of(this.amount + other.amount, this.currency); }\n}",
                "lang": "ts"
            }
        },
        {
            "id": "entity",
            "distinctFrom": [
                {
                    "id": "architecture:value-object",
                    "reason": "An entity is known by an identity that outlives its attributes, while a value object is known only by its attributes."
                }
            ],
            "name": "Entity",
            "definition": "A design pattern that models a domain object by a stable identity, which stays the same while its attributes change.",
            "type": "pattern",
            "scope": [
                "domain",
                "identity",
                "lifecycle"
            ],
            "requires": ["Stable Identity"],
            "reinforces": [
                "Domain Model",
                "Encapsulation"
            ],
            "enables": [
                "Identity-Based Equality",
                "Lifecycle Tracking"
            ],
            "conflicts_with": ["Anemic Domain Model"],
            "tensions_with": ["Value Object"],
            "violated_by": ["lexicon:attribute-compared-identity"],
            "detected_by": ["equality by field value where identity is meant"],
            "measured_by": ["attribute-equality misuse count"],
            "refactored_by": [],
            "enforced_by": ["domain model review"],
            "severity": "contextual",
            "exemplar": {
                "before": "type Foo = { id: string; name: string; status: string };\nfoo.status = \"active\";",
                "after": "class Foo {\n  constructor(readonly id: FooId, private name: string, private status: FooStatus) {}\n  equals(other: Foo) { return this.id === other.id; }\n  activate() { this.status = \"active\"; }\n}",
                "lang": "ts"
            }
        },
        {
            "id": "domain-service",
            "distinctFrom": [
                {
                    "id": "architecture:aggregate",
                    "reason": "A domain service holds a stateless rule spanning entities, while an aggregate holds entities and their invariants under one root."
                }
            ],
            "name": "Domain Service",
            "definition": "A design pattern that places a domain rule spanning several entities in a stateless service named in the domain's language.",
            "type": "pattern",
            "scope": [
                "domain",
                "behavior",
                "coordination"
            ],
            "requires": ["Domain Model"],
            "reinforces": [
                "Single Responsibility Principle (SRP)",
                "Ubiquitous Language"
            ],
            "enables": ["Cross-Entity Domain Logic"],
            "conflicts_with": [
                "Fat Controller",
                "Transaction Script Sprawl"
            ],
            "tensions_with": ["Aggregate"],
            "violated_by": ["architecture:fat-controller"],
            "detected_by": ["domain logic in application/transport layers"],
            "measured_by": ["misplaced domain-rule count"],
            "refactored_by": [],
            "enforced_by": ["domain model review"],
            "severity": "contextual",
            "exemplar": {
                "before": "class FooAccount {\n  transferTo(other: FooAccount, amount: number) {\n    this.balance -= amount;\n    other.balance += amount;\n  }\n}",
                "after": "class FooTransferService {\n  transfer(from: FooAccount, to: FooAccount, amount: Money) {\n    from.withdraw(amount);\n    to.deposit(amount);\n  }\n}",
                "lang": "ts"
            }
        }
    ]
}
```
