workspace "Metrics Platform" "CQRS/Event-Sourcing metrics platform with ingestion workers, projections, and dashboard delivery" { model { developer = person "Developer" "Consumes predefined development dashboards" analyst = person "BI Analyst" "Builds custom analyses on top of metrics projections" sourceA = softwareSystem "Source A" "External metrics source" sourceB = softwareSystem "Source B" "External metrics source" sourceC = softwareSystem "Source C" "External metrics source" sourceD = softwareSystem "Source D" "External metrics source" metricsPlatform = softwareSystem "Metrics Platform" "Collects raw metrics, records domain events, builds projections, and serves dashboards" { jobScheduler = container "Job Scheduler" "Triggers ingestion cycles" "Scheduler" ingestionWorker = container "Ingestion Worker" "Fetches from adapters, normalizes into domain model, stores raw data and emits domain events" ".NET Service" adapterA = container "Adapter A" "Connector for Source A" ".NET Library" adapterB = container "Adapter B" "Connector for Source B" ".NET Library" adapterC = container "Adapter C" "Connector for Source C" ".NET Library" adapterD = container "Adapter D" "Connector for Source D" ".NET Library" projectionWorker = container "Projection Worker" "Consumes domain events and rebuilds dashboard projections" ".NET Service" metricsApi = container "Metrics API" "Serves projections and configuration to dashboard clients" ".NET API" front1Web = container "Front 1 Web" "Predefined product dashboards" ".NET + React" front2Bi = container "Front 2 BI" "Advanced/custom BI views" "Power BI / BI client" domainCore = container "Domain Core Model" "Canonical domain model for metrics, events, and projection rules" ".NET Library" rawDataStore = container "Raw Data Store" "Persisted raw source payloads for traceability/reprocessing" "Data Store" { tags "Database" } domainEventStore = container "Domain Event Store" "Event stream following the domain core model" "Event Store" { tags "Database" } projectionStore = container "Projection Store" "Read model with precomputed dashboard values" "Read Model Store" { tags "Database" } configurationStore = container "Configuration DB" "Projection and dashboard configuration" "Database" { tags "Database" } jobScheduler -> ingestionWorker "Triggers ingestion run" "Scheduled job" ingestionWorker -> domainCore "Uses domain contracts" ingestionWorker -> adapterA "Uses" ingestionWorker -> adapterB "Uses" ingestionWorker -> adapterC "Uses" ingestionWorker -> adapterD "Uses" ingestionWorker -> rawDataStore "Stores raw payloads" ingestionWorker -> domainEventStore "Stores domain events" adapterA -> sourceA "Consumes" adapterB -> sourceB "Consumes" adapterC -> sourceC "Consumes" adapterD -> sourceD "Consumes" projectionWorker -> domainCore "Uses domain contracts" projectionWorker -> domainEventStore "Consumes event stream" projectionWorker -> projectionStore "Builds/saves projections" projectionWorker -> configurationStore "Reads dashboard configuration" metricsApi -> domainCore "Uses projection contracts" metricsApi -> projectionStore "Reads projections" metricsApi -> configurationStore "Reads dashboard configuration" front1Web -> metricsApi "Reads predefined dashboards" "HTTPS/JSON" front2Bi -> metricsApi "Reads/adapts metrics views" "HTTPS/JSON" developer -> front1Web "Uses" analyst -> front2Bi "Uses" } } views { systemContext metricsPlatform "context" { include developer include analyst include sourceA include sourceB include sourceC include sourceD include metricsPlatform autolayout lr title "System Context - Metrics Platform" } container metricsPlatform "containers" { include * autolayout lr title "Container - Metrics Platform" } dynamic metricsPlatform "ingestion-flow" { title "Dynamic - Ingestion and Event Recording" jobScheduler -> ingestionWorker "1. Trigger ingestion cycle" ingestionWorker -> adapterA "2. Pull data" ingestionWorker -> adapterB "2. Pull data" ingestionWorker -> adapterC "2. Pull data" ingestionWorker -> adapterD "2. Pull data" ingestionWorker -> rawDataStore "3. Persist raw payloads" ingestionWorker -> domainCore "4. Map to canonical model" ingestionWorker -> domainEventStore "5. Persist domain events" } dynamic metricsPlatform "projection-and-serving-flow" { title "Dynamic - Projection Rebuild and Dashboard Serving" projectionWorker -> domainEventStore "1. Read events" projectionWorker -> configurationStore "2. read projection definitions" projectionWorker -> domainCore "3. Apply projection configuration using domain models" projectionWorker -> projectionStore "4. Write refreshed projections" front1Web -> metricsApi "5. Request predefined dashboards" metricsApi -> projectionStore "6. Read projected metrics" front2Bi -> metricsApi "7. Request custom views on normalized data" metricsApi -> projectionStore "8. Read projected metrics" } styles { element "Person" { shape Person background #240d60 color #ffffff } element "Software System" { background #7fa06e color #000000 } element "Container" { background #f71414 color #ffffff } element "Database" { shape Cylinder background #b4cd37 color #000000 } } } }