Skip to content
architecture class

Domain Model

Class diagram showing the DDD domain model with aggregates, entities, and value objects

Domain Model

This diagram illustrates the Domain-Driven Design (DDD) model in BlueRobin, showing aggregates, entities, value objects, and their relationships.

Aggregate Structure

classDiagram
    direction TB

    class AggregateRoot {
        <>
        +BlueRobinId Id
        -List~IDomainEvent~ _domainEvents
        +RaiseDomainEvent(event)
        +ClearDomainEvents()
    }

    class Entity {
        <>
        +BlueRobinId Id
    }

    class Archive {
        <>
        +BlueRobinId Id
        +string Name
        +BlueRobinId CreatedBy
        +DateTime CreatedOn
        +Create(name, createdBy)$ Archive
    }

    class Document {
        <>
        +BlueRobinId Id
        +BlueRobinId ArchiveId
        +BlueRobinId CreatedBy
        +DocumentStatus Status
        +DocumentMetadata Metadata
        +DocumentAnalysis Analysis
        +DocumentClassification Classification
        +ProcessingMetrics Metrics
        +DateTime CreatedOnUtc
        +Create(archiveId, createdBy, fingerPrint, fileName, fileSize, contentType)$ Document
        +UpdateStatus(status)
        +RecordOcrTime(ms)
        +RecordAnalysisTime(ms)
        +UpdateAnalysis(summary, keywords, friendlyName)
    }

    class ApplicationUser {
        <>
        +BlueRobinId Id
        +string ExternalId
        +string Email
        +string DisplayName
        +bool IsActive
        +DateTime CreatedAt
        +DateTime? LastLoginAt
    }

    class CanonicalEntity {
        <>
        +BlueRobinId Id
        +string Name
        +string Type
        +BlueRobinId OwnerUserId
        +string? NormalizedName
        +Create(name, type, ownerId)$ CanonicalEntity
    }

    class EntityRelationship {
        <>
        +BlueRobinId Id
        +BlueRobinId SourceEntityId
        +BlueRobinId TargetEntityId
        +BlueRobinId RelationshipTypeId
        +BlueRobinId DocumentId
    }

    AggregateRoot <|-- Archive
    AggregateRoot <|-- Document
    AggregateRoot <|-- ApplicationUser
    AggregateRoot <|-- CanonicalEntity
    AggregateRoot <|-- EntityRelationship
    Entity <|-- AggregateRoot

Value Objects

classDiagram
    direction LR

    class BlueRobinId {
        <>
        +string Value
        +New()$ BlueRobinId
        +From(string)$ BlueRobinId
        -GenerateId()$ string
        Note: 10-char alphanumeric
    }

    class FingerPrint {
        <>
        +string Hash
        +FromContent(bytes)$ FingerPrint
        +FromStream(stream)$ FingerPrint
        Note: SHA256 hash
    }

    class DocumentMetadata {
        <>
        +string FileName
        +string ContentType
        +long FileSize
        +string ObjectName
        +FingerPrint FingerPrint
        +int PageCount
        +CreateWithGeneratedObjectName(...)$ DocumentMetadata
    }

    class DocumentAnalysis {
        <>
        +string? Summary
        +string? Keywords
        +string? FriendlyName
        +int ChunkCount
        +Empty()$ DocumentAnalysis
        +WithSummary(summary)
        +WithKeywords(keywords)
        +WithFriendlyName(name)
    }

    class DocumentClassification {
        <>
        +string Category
        +float Confidence
        +DateTime? ClassifiedAt
        +Unclassified()$ DocumentClassification
        +Create(category, confidence)$ DocumentClassification
    }

    class ProcessingMetrics {
        <>
        +long? OcrTimeMs
        +long? AnalysisTimeMs
        +long? EmbeddingTimeMs
        +long? TotalTimeMs
        +Empty()$ ProcessingMetrics
        +WithOcrTime(ms)
        +WithAnalysisTime(ms)
    }

    class ObjectReference {
        <>
        +string Bucket
        +string Key
        +Create(bucket, key)$ ObjectReference
    }

    class SearchFilters {
        <>
        +string? Query
        +DateRange? DateRange
        +string[]? Categories
        +string[]? Keywords
    }

Document Aggregate Detail

classDiagram
    direction TB

    class Document {
        <>
        +BlueRobinId Id
        +BlueRobinId ArchiveId
        +BlueRobinId CreatedBy
        +DocumentStatus Status
        +DocumentMetadata Metadata
        +DocumentAnalysis Analysis
        +DocumentClassification Classification
        +ProcessingMetrics Metrics
    }

    class DocumentMetadata {
        <>
        +string FileName
        +string ContentType
        +long FileSize
        +string ObjectName
        +FingerPrint FingerPrint
        +int PageCount
    }

    class DocumentAnalysis {
        <>
        +string? Summary
        +string? Keywords
        +string? FriendlyName
        +int ChunkCount
    }

    class DocumentClassification {
        <>
        +string Category
        +float Confidence
        +DateTime? ClassifiedAt
    }

    class ProcessingMetrics {
        <>
        +long? OcrTimeMs
        +long? AnalysisTimeMs
        +long? EmbeddingTimeMs
    }

    class DocumentStatus {
        <>
        Pending
        Processing
        Completed
        Failed
    }

    class FingerPrint {
        <>
        +string Hash
    }

    Document *-- DocumentMetadata : contains
    Document *-- DocumentAnalysis : contains
    Document *-- DocumentClassification : contains
    Document *-- ProcessingMetrics : contains
    Document --> DocumentStatus : has
    DocumentMetadata *-- FingerPrint : contains

Domain Events

classDiagram
    direction TB

    class IDomainEvent {
        <>
        +DateTime OccurredAt
    }

    class DocumentAddedEvent {
        +BlueRobinId DocumentId
        +BlueRobinId ArchiveId
        +BlueRobinId CreatedBy
        +string FileName
        +string ContentType
        +long FileSize
        +string ObjectName
    }

    class DocumentStatusChangedEvent {
        +BlueRobinId DocumentId
        +DocumentStatus OldStatus
        +DocumentStatus NewStatus
    }

    class DocumentAnalysisUpdatedEvent {
        +BlueRobinId DocumentId
        +string Summary
        +string Keywords
        +string FriendlyName
    }

    IDomainEvent <|.. DocumentAddedEvent
    IDomainEvent <|.. DocumentStatusChangedEvent
    IDomainEvent <|.. DocumentAnalysisUpdatedEvent

Repository Interfaces

classDiagram
    direction TB

    class IRepository~T~ {
        <>
        +GetByIdAsync(id) Task~T?~
        +AddAsync(entity) Task
        +UpdateAsync(entity) Task
        +DeleteAsync(entity) Task
    }

    class IDocumentsRepository {
        <>
        +GetByArchiveIdAsync(archiveId) Task~List~Document~~
        +GetByFingerprintAsync(fingerprint) Task~Document?~
        +GetByUserIdAsync(userId, filters) Task~PagedResult~Document~~
    }

    class IArchivesRepository {
        <>
        +GetByOwnerIdAsync(ownerId) Task~Archive?~
        +ExistsAsync(id) Task~bool~
    }

    class IUsersRepository {
        <>
        +GetByExternalIdAsync(externalId) Task~ApplicationUser?~
        +GetByEmailAsync(email) Task~ApplicationUser?~
    }

    IRepository <|-- IDocumentsRepository
    IRepository <|-- IArchivesRepository
    IRepository <|-- IUsersRepository

Key DDD Patterns Used

Pattern Implementation Example
Aggregate Root AggregateRoot base class Document, Archive
Value Object Immutable records BlueRobinId, FingerPrint
Domain Event Event sourcing DocumentAddedEvent
Factory Method Static Create() methods Document.Create(...)
Repository Interface per aggregate IDocumentsRepository
Specification Search filters SearchFilters