Skip to content

Latest commit

 

History

History
270 lines (228 loc) · 10.2 KB

File metadata and controls

270 lines (228 loc) · 10.2 KB

Evolith Tracker: DDD Model - Discovery Module

Bilingual Navigation: English (this document) · Versión en Español

This document defines the tactical and strategic design for the Discovery Bounded Context based on Domain-Driven Design (DDD) principles. Its central purpose is to govern the "Idea-to-Backlog" flow, ensuring that all built code is justified by a formal business requirement.

1. Ubiquitous Language

Strict terminology shared between business and technical code within this context:

  • InitiativeStatus: Enum that governs the lifecycle of an Initiative: DRAFT, SUBMITTED, UNDER_REVIEW, APPROVED, PHASE_TRACKING, REJECTED, BACKLOG_GENERATED.

  • UserStoryStatus: Enum for User Story lifecycle: DRAFT, IN_REFINEMENT, SPLIT, READY, IN_PROGRESS, DONE.

  • Initiative: The highest-level transactional root. A business and technical container that consolidates an idea before splitting it into epics for construction.

  • Business Case: Commercial or value justification (ROI, OPEX, CAPEX, Strategic Alignment).

  • Technical Justification: Initial assessment of technological feasibility, critical dependencies, and tech debt.

  • Approval Gate: An explicit "Go/No-Go" validation checkpoint confirming the Initiative meets minimum tenant criteria.

  • Backlog: The prioritized inventory of generated artifacts (Epics and User Stories) stemming from an approved Initiative.

  • Requirement Checklist: Dynamically generated list of steps (mandatory or optional) dictating the tenant's exact workflow rules.

2. Conceptual Maps and Aggregates (Mermaid)

To improve readability and font sizing, the model has been split into multiple architectural views.

2.0. Visual Legends and Glossary

Symbol/Stereotype Meaning
<<Aggregate Root>> Transactional root entity. Governs the persistence and consistency of its internal entities.
<<Entity>> Domain object with a unique identity, dependent on its Aggregate Root.
<<Value Object>> Immutable object without intrinsic identity. Represents a structural property.
<<Shared Kernel Shell>> Cross-cutting module external to the domain, injected by the application/infrastructure layer.
*-- (Solid line) Composition. The child element cannot exist without the parent.
..> (Dotted line) Dependency. The element interacts with or delegates to another component.

Tip

Viewing Options: If the diagrams appear small in your current Markdown viewer, consider using an IDE extension (e.g., Markdown Preview Mermaid Support) or copy the code block into the Mermaid Live Editor to enable zooming, infinite panning, and high-res SVG exporting.

2.1. View 1: Business Core (Aggregates and Entities)

Displays the main Aggregate Roots and how they are hierarchically composed.

classDiagram
    class Initiative {
        <<Aggregate Root>>
        +UUID id
        +String tenantId
        +String title
        +String description
        +InitiativeStatus status
        +String strategicTheme
        +String targetQuarter
        +UUID sponsorId_umsUserId
        +List~UUID~ authorizedUmsGroupIds
        +List~ExternalReference~ externalRefs
        +String modoDeBacklog
        +String modoDeSeguimiento
        +submitForApproval()
        +approve(ApprovalGate, UUID umsUserId)
        +reject(String reason, UUID umsUserId)
        +generateBacklog()
        +advanceToNextPhaseGate()
        +updateMetadata(UUID umsUserId)
    }

    class BusinessCase {
        <<Entity>>
        +Money budget
        +ROI estimatedRoi
        +String strategicAlignment
    }

    class TechnicalJustification {
        <<Entity>>
        +String architectureNotes
        +List~String~ criticalDependencies
    }

    class Backlog {
        <<Aggregate Root>>
        +UUID id
        +UUID initiativeId
        +List~UUID~ orderedStoryIds
        +reorder(UUID storyId, Int newPosition, UUID umsUserId)
    }

    class Epic {
        <<Aggregate Root>>
        +UUID id
        +UUID backlogId
        +String title
        +String description
        +Priority priority
        +UUID assigneeId_umsUserId
        +UUID reporterId_umsUserId
        +List~ExternalReference~ externalRefs
        +updateDetails(UUID umsUserId)
        +assignTo(UUID umsUserId)
        +syncWithExternal(ExternalReference)
    }

    class UserStory {
        <<Aggregate Root>>
        +UUID id
        +UUID epicId
        +String description
        +String acceptanceCriteria
        +UserStoryStatus status
        +Priority priority
        +Int storyPoints
        +UUID assigneeId_umsUserId
        +UUID reporterId_umsUserId
        +List~String~ tags
        +Date dueDate
        +List~ExternalReference~ externalRefs
        +updateDetails(UUID umsUserId)
        +assignTo(UUID umsUserId)
        +estimate(Int points)
        +splitInto(List~String~ childTitles, UUID umsUserId)
        +syncWithExternal(ExternalReference)
    }

    class ExternalReference {
        <<Value Object>>
        +ExternalSystem system
        +String externalId
        +String url
        +ReferenceType type
        +String label
        +Date linkedAt
        +Map metadata
    }

    Initiative "1" *-- "1" BusinessCase : contains
    Initiative "1" *-- "1" TechnicalJustification : contains
    Initiative "1" --> "1..*" UserStory : originates
    Initiative "1" *-- "0..*" ExternalReference : mapped to
    Epic "1" *-- "0..*" ExternalReference : mapped to
    UserStory "1" *-- "0..*" ExternalReference : mapped to
    Backlog "1" --> "0..*" Epic : references epics
    Backlog "1" --> "0..*" UserStory : orders stories
    Epic "1" --> "0..*" UserStory : groups stories
Loading

2.2. View 2: Workflow and Audit Components

Zooms in on the Value Objects used by the Aggregates to maintain history, security, and transactional progress.

classDiagram
    class RequirementChecklist {
        <<Value Object>>
        +List~RequirementItem~ items
        +isReadyForApproval() Boolean
        +markItemCompleted(String code)
    }

    class RequirementItem {
        <<Value Object>>
        +String code
        +Boolean isMandatory
        +RequirementStatus status
    }

    class AuditControl {
        <<Value Object>>
        +String createdBy
        +Date createdAt
        +String modifiedBy
        +Date modifiedAt
    }

    class StateTransition {
        <<Value Object>>
        +InitiativeStatus fromState
        +InitiativeStatus toState
        +Date transitionDate
        +String triggeredBy
        +String reason
    }

    class ApprovalGate {
        <<Value Object>>
        +String approverId
        +GateDecision decision
        +String justification
        +Date decidedAt
    }

    class Initiative {
        <<Aggregate Root>>
    }
    
    class Backlog {
        <<Aggregate Root>>
    }

    Initiative "1" *-- "1" RequirementChecklist : validates against
    RequirementChecklist "1" *-- "1..*" RequirementItem : contains
    Initiative "1" *-- "0..1" ApprovalGate : governed by
    Initiative "1" *-- "1" AuditControl : tracked by
    Initiative "1" *-- "0..*" StateTransition : workflow history
    Backlog "1" *-- "1" AuditControl : tracked by
Loading

2.3. View 3: Cross-Cutting Infrastructure (Shells)

Describes the interaction between the pure domain and the Shared Kernels of the Evolith architecture.

classDiagram
    class WorkflowEngine {
        <<Shared Kernel Shell>>
        +validateTransition()
        +evaluateApprovalGate()
    }

    class TenantConfigShell {
        <<Shared Kernel Shell>>
        +getTenantWorkflowRules()
    }

    class IntegrationFabric {
        <<Shared Kernel Shell>>
        +ingestFromWebhook()
        +exportToExternalSystem()
    }

    class UMS_SDK {
        <<Cross-Cutting>>
        +RequiresDomainAccess()
    }

    class Initiative {
        <<Aggregate Root>>
    }
    
    class Backlog {
        <<Aggregate Root>>
    }

    %% Infrastructure Dependencies
    Initiative ..> TenantConfigShell : reads dynamic rules (isMandatory)
    Initiative ..> WorkflowEngine : delegates state machine
    Initiative ..> UMS_SDK : secured via
    Backlog ..> IntegrationFabric : exported via (Standalone)
Loading

3. Tactical Design

3.1. Aggregate Roots (Small Aggregates)

To ensure transactional scalability in a collaborative environment, the Discovery phase employs the Small Aggregates pattern.

  1. Initiative: Encapsulates the global conceptual container. The transactional orchestrator that validates policies before authorizing the split.
  2. Backlog: Does not hold physical UserStory collections, managing an efficient List<UUID> orderedStoryIds instead, allowing O(1) reprioritization.
  3. Epic and UserStory: Independent Aggregate Roots to prevent deadlocks during concurrent AI/Human editing.

3.2. Value Objects

  • RequirementChecklist / RequirementItem: Injected by the WorkflowEngine and TenantConfigShell to track mandatory/optional steps. Acts as a Guard Clause blocking transitions if pending.
  • AuditControl: Standard Evolith tracking object (createdBy, createdAt).
  • StateTransition: Immutable record of a status change.
  • ApprovalGate: Encapsulates the gate decision and approver ID.

3.3. UMS Integration and Authorization (Multi-Tenant)

  1. Application Layer & SDK: The UMS SDK is strictly utilized at the Use Case layer or API Gateway.
  2. Anti-Corruption Layer (ACL): Translates UMS identity data into explicit, primitive domain concepts.
  3. Pure Domain Execution: Aggregate Roots do not depend on the UMS SDK or its types.

3.4. Data Ingestion & Artifact Exportation

  • Data Ingestion (Import): External webhooks or CSV/YAML bulk uploads are handled by the IntegrationFabric.
  • Exportation (Standalone Mode): Handled via Integration Events. Infrastructure adapters in the IntegrationFabric translate our canonical Backlog into external API calls.

4. Context Mapping (Boundary Integration)

  • Downstream (Towards Design Module): The Design module reacts to the BacklogGeneratedEvent to automatically trigger the generation of technical contracts. In initiative-only mode, the Design module reacts to the InitiativePhaseAdvancedEvent instead, triggered when the initiative advances without internal decomposition.