id: "ddd-profile"
version: "1.0.0"
name: "Domain-Driven Design"
description: "Domain Driven Design (DDD) is a software development approach that focuses on modeling complex business domains"
icon: "Cube"

# Metadata
metadata:
  tags:
    - "ddd"
    - "domain-driven-design"
    - "domain-modeling"
    - "aggregate"
    - "entity"
    - "value-object"

# Status Enumerations
statusEnumerations: []

# Element Types
elementTypes:
  - id: "ddd.aggregate"
    name: "Aggregate"
    description: "A domain aggregate that groups related entities and value objects"
    descriptionDetailed: "An Aggregate represents a cluster of domain objects (entities and value objects) that are treated as a single unit. Aggregates help identify boundaries in the domain model and define consistency boundaries. They group related commands, entities, and value objects together, with one entity designated as the aggregate root."
    baseType: "default-model-element"
    layer: "application"
    trackable: true
    style:
      icon: "DataConnected"
      accentColor: "#697077"
      defaultCanvasStyle: "card"

  - id: "ddd.entity"
    name: "Entity"
    description: "A domain entity with a unique identity"
    descriptionDetailed: "An Entity represents a domain object with a unique identity that persists over time. Entities have an identity that distinguishes them from other entities, even if their attributes change. Entities can be aggregate roots (root entities) or part of an aggregate. They can contain other entities and value objects."
    baseType: "default-model-element"
    layer: "application"
    trackable: true
    propertiesSchema:
      - "ddd-entity-properties"
    style:
      icon: "Data_1"
      accentColor: "#007d79"
      defaultCanvasStyle: "card"

  - id: "ddd.value-object"
    name: "ValueObject"
    description: "A value object without identity, defined by its attributes"
    descriptionDetailed: "A Value Object represents a domain concept that is defined entirely by its attributes and has no identity. Value objects are immutable and are compared by value rather than identity. They can contain other value objects to model complex value structures."
    baseType: "default-model-element"
    layer: "application"
    trackable: true
    style:
      icon: "Object"
      accentColor: "#198038"
      defaultCanvasStyle: "card"
    propertiesSchema:
      - "ddd-value-object-properties"

  - id: "ddd.command"
    name: "Command"
    description: "A command that triggers an action or process in the domain"
    descriptionDetailed: "A Command represents an intention to perform an action or trigger a process in the domain. Commands are typically written in imperative form (e.g., 'Place Order', 'Process Payment'). They represent user actions or system triggers that lead to domain events. Commands can be factory commands used to create instances of aggregate roots."
    baseType: "default-model-element"
    layer: "business"
    trackable: true
    propertiesSchema:
      - "ddd-command-properties"
    style:
      icon: "Function_2"
      accentColor: "#0072c3"
      defaultCanvasStyle: "card"

  - id: "ddd.domain-service"
    name: "Domain service"
    description: "A domain service that performs domain operations"
    descriptionDetailed: "A Domain Service represents a service that performs domain operations that don't naturally fit within an entity or value object. Domain services contain domain logic that operates across multiple aggregates or entities. They are stateless and represent operations that are part of the domain but don't belong to a specific entity."
    baseType: "default-model-element"
    layer: "application"
    trackable: true
    style:
      icon: "FlowModeler"
      accentColor: "#0f62fe"
      defaultCanvasStyle: "card"

  - id: "ddd.business-event"
    name: "Business event"
    description: "A business event that represents something that happened in the domain"
    descriptionDetailed: "A Business Event represents something that has happened in the domain. Business events are the result of commands and represent state changes or occurrences in the domain. They are typically written in past tense (e.g., 'Order Placed', 'Payment Processed'). Business events help identify the flow of information and business processes."
    baseType: "default-model-element"
    layer: "business"
    trackable: true
    style:
      icon: "Trigger"
      accentColor: "#8e6a00"
      defaultCanvasStyle: "card"

  - id: "ddd.business-error"
    name: "Business error"
    description: "A business error or exception in the domain"
    descriptionDetailed: "A Business Error represents an error condition or exception that can occur in the domain. Business errors represent domain-level exceptions that are meaningful to the business, such as validation failures, business rule violations, or domain-specific error conditions. They help model error handling and exception scenarios in the domain."
    baseType: "default-model-element"
    layer: "business"
    trackable: true
    style:
      icon: "IncompleteError"
      accentColor: "#da1e28"
      defaultCanvasStyle: "card"

# Relationship Types
relationshipTypes:
  - id: "ddd.extends"
    name: "extends"
    description: "Indicates that an element extends another element"
    descriptionDetailed: "An Extends relationship indicates that one element extends another element. This relationship is used to model inheritance hierarchies in domain-driven design, such as entities extending other entities."
    typeMappings:
      - sourceElementTypes: ["ddd.entity"]
        targetElementTypes: ["ddd.entity"]
      - sourceElementTypes: ["ddd.value-object"]
        targetElementTypes: ["ddd.value-object"]
      - sourceElementTypes: ["ddd.aggregate"]
        targetElementTypes: ["ddd.aggregate"]
    bidirectional: false
    relationshipType: "default"
    prefillLabel: false
    reverse:
      name: "extended by"
      description: "Entities extended by this entity"
      descriptionDetailed: "The reverse of the 'Extends' relationship. When an entity extends another entity, the extended entity is 'extended by' the extending entity. This represents the perspective from the extended entity's point of view."
    style:
      style: "line"
      startArrow: "none"
      endArrow: "arrow"
      defaultColor: "#000000"
      thickness: 1
  - id: "ddd.triggers"
    name: "triggers"
    description: "Indicates that one element triggers a business logic element (command or domain service)"
    descriptionDetailed: "A Triggers relationship indicates that one element triggers a business logic element (command or domain service)."
    typeMappings:
      - sourceElementTypes: ["ddd.*", "implementation.*"]
        targetElementTypes: ["ddd.command", "ddd.domain-service"]
    bidirectional: false
    relationshipType: "default"
    prefillLabel: false
    reverse:
      name: "triggered by"
      description: "Business logic elements triggered by this element"
      descriptionDetailed: "The reverse of the 'Triggers' relationship. When an element triggers a business logic element, the triggered element is 'triggered by' the triggering element. This represents the perspective from the triggered element's point of view."
    style:
      style: "line"
      startArrow: "none"
      endArrow: "simple_arrow"
      defaultColor: "#000000"
      thickness: 1
  - id: "ddd.publishes"
    name: "publishes"
    description: "Indicates that a business logic element (command or domain service) publishes a business event"
    descriptionDetailed: "A Publishes relationship indicates that one implementation element (command or domain service) triggers another."
    typeMappings:
      - sourceElementTypes: ["ddd.command", "ddd.domain-service"]
        targetElementTypes: ["ddd.business-event"]
    bidirectional: false
    relationshipType: "default"
    prefillLabel: false
    reverse:
      name: "published by"
      description: "Business events published by this element"
      descriptionDetailed: "The reverse of the 'Publishes' relationship. When a business logic element publishes a business event, the published event is 'published by' the publishing element. This represents the perspective from the published event's point of view."
    style:
      style: "dotted"
      startArrow: "none"
      endArrow: "simple_arrow"
      defaultColor: "#000000"
      thickness: 1
  - id: "ddd.throws"
    name: "throws"
    description: "Indicates that a business logic element (command or domain service) throws a business error"
    descriptionDetailed: "A Throws relationship indicates that a business logic element (command or domain service) throws a business error."
    typeMappings:
      - sourceElementTypes: ["ddd.command", "ddd.domain-service"]
        targetElementTypes: ["ddd.business-error"]
    bidirectional: false
    relationshipType: "default"
    prefillLabel: false
    reverse:
      name: "thrown by"
      description: "Business errors thrown by this element"
      descriptionDetailed: "The reverse of the 'Throws' relationship. When a business logic element throws a business error, the thrown error is 'thrown by' the throwing element. This represents the perspective from the thrown error's point of view."
    style:
      style: "dotted"
      startArrow: "none"
      endArrow: "simple_arrow"
      defaultColor: "#000000"
      thickness: 1
  - id: "ddd.contains"
    name: "contains"
    description: "Indicates that an element contains another element"
    descriptionDetailed: "A Contains relationship represents that one element contains another element. This relationship is used to model composition structures in domain-driven design, such as aggregates containing entities and value objects, entities containing nested entities and value objects, and value objects containing other value objects."
    typeMappings:
      - sourceElementTypes: ["ddd.aggregate"]
        targetElementTypes: ["ddd.entity", "ddd.value-object", "ddd.command"]
      - sourceElementTypes: ["ddd.entity"]
        targetElementTypes: ["ddd.entity", "ddd.value-object"]
      - sourceElementTypes: ["ddd.value-object"]
        targetElementTypes: ["ddd.value-object"]
    bidirectional: false
    relationshipType: "aggregation"
    prefillLabel: false
    reverse:
      name: "contained in"
      description: "Elements contained in this element"
      descriptionDetailed: "The reverse of the 'Contains' relationship. When an element contains another element, the contained element is 'contained in' the containing element. This represents the perspective from the contained element's point of view."
    style:
      style: "dashed"
      startArrow: "none"
      endArrow: "arrow"
      defaultColor: "#000000"
      thickness: 1

# Property Groups
propertyGroups:
  - id: "ddd-entity-properties"
    name: "Entity Properties"
    description: "Properties for domain entities"
    descriptionDetailed: "This property group contains properties specific to Entity elements, including whether the entity is a root entity or abstract."
    properties:
      - fieldName: "is-root"
        displayName: "Root Entity"
        description: "Indicates if entity is the root entity of the aggregate"
        descriptionDetailed: "Specifies whether this entity is the aggregate root. The aggregate root is the only entity that external objects are allowed to hold references to. It is the entry point for accessing the aggregate."
        type: "boolean"
        required: false
        defaultValue: false
      - fieldName: "is-abstract"
        displayName: "Abstract"
        description: "Indicates if entity is abstract or not (abstract means, no instance can be created)"
        descriptionDetailed: "Specifies whether this entity is abstract. Abstract entities cannot be instantiated directly and serve as base classes for concrete entity implementations. They are used to model inheritance hierarchies in the domain model."
        type: "boolean"
        required: false
      - fieldName: "propertiesDescription"
        displayName: "Properties"
        description: "The properties (attributes) of the entity"
        descriptionDetailed: "A list of properties that define the data structure of the entity. Each property represents a property with a name, type, and optional metadata such as whether it is required, whether it is an array, and a description."
        type: "formattedText"
        required: false
  
  - id: "ddd-value-object-properties"
    name: "Value Object Properties"
    description: "Properties for domain value objects"
    descriptionDetailed: "This property group contains properties specific to Value Object elements, mainly the properties of the value object."
    properties:
      - fieldName: "properties"
        displayName: "Properties"
        description: "The properties (attributes) of the value object"
        descriptionDetailed: "A list of properties that define the data structure of the value object. Each property represents a property with a name, type, and optional metadata such as whether it is required, whether it is an array, and a description."
        type: "formattedText"
        required: false

  - id: "ddd-command-properties"
    name: "Command Properties"
    description: "Properties for domain commands"
    descriptionDetailed: "This property group contains properties specific to Command elements, including whether the command is a factory command."
    properties:
      - fieldName: "is-factory"
        displayName: "FactoryCommand"
        description: "Indicates if command is a factory command, which would mean that it is used to create an instance of the root entity"
        descriptionDetailed: "Specifies whether this command is a factory command. Factory commands are used to create instances of aggregate roots. They represent the creation operations for aggregates and are distinct from commands that modify existing aggregates."
        type: "boolean"
        required: false

# Text Templates
textTemplates: []

# Validations
validations: []

# Guidelines
guidelines:
  - id: "entity-mongodb-repository-pattern"
    scope:
      elementTypes: ["ddd.entity"]
    policy: "When persisting entities in MongoDB, always use the repository pattern to abstract data access logic. The repository pattern provides a clean separation between domain logic and persistence concerns. Implement a repository interface in the domain layer that defines operations like save, findById, findAll, and delete. The concrete MongoDB repository implementation should be in the infrastructure layer and handle MongoDB-specific details like document mapping, collection names, and query construction. The repository should map domain entities to MongoDB documents, handling the conversion between domain objects and BSON documents. Use the repository interface in domain services and application services, never directly accessing MongoDB from domain code. This ensures the domain model remains independent of the persistence technology and makes it easier to test and potentially switch persistence mechanisms in the future."
