/

Developer Guide

Telemetry Distribution Context

Subdomain type: Core · Grounded in: User Stories TD-1 through TD-4

This page describes the design-time model of the Telemetry Distribution context. The runtime mechanics — how routing is made fast, how streams are carried to the browser — are left as decisions for whoever builds this model; the domain states only the rules those mechanics must respect.

At the domain level, this context owns two things: the metric catalog each building chooses from, and each building’s display preference (which metrics its dashboard table shows, and in what order). Readings themselves are simply routed to the building they belong to.


Ubiquitous Language

TermMeaning in this context
PreferenceThe ordered set of metrics a Building has chosen to display.
Allowed metricA single metric included in a Preference.
Metric CatalogThe combined list of metrics offered by the upstream contexts.
DistributionRouting each reading to its own Building’s live feed. It is not gated by Preference — see below.

The Building Preference Aggregate

The aggregate root is a Building’s Preference: which metrics it shows, in what order. Order is part of the model, because it is the order the display is meant to present.

classDiagram
    class BuildingPreference {
        <<Aggregate Root>>
        +buildingId
        +metric[] allowedMetrics
    }
    class Metric {
        <<Value Object>>
        +key
        +label
        +unit
        +sourceContext
    }

    BuildingPreference "1" o-- "many" Metric : selects

Value Object: Metric

An allowed metric is modelled as a value object — key, label, unit, and the context it came from — with no identity of its own: two entries describing the same metric are interchangeable. A BuildingPreference holds an ordered list of them, and a change to the preference replaces those entries rather than mutating them in place. The catalog these are drawn from is assembled separately, as described next.


The Metric Catalog

This context does not invent metrics — it assembles them. The design intent is that each upstream context describes its own metrics (see the Published Language in Telemetry Ingestion and the structural metrics owned by Building Management, and this context gathers those descriptions into one catalog the display can choose from.

graph LR
    ING["Telemetry Ingestion: metric descriptions"] --> CAT["Metric Catalog"]
    BM["Building Management: structural metrics"] --> CAT
    CAT --> UI["Display: choose which metrics to show"]

Gathering rather than defining keeps this context a Conformist consumer of each upstream Published Language: a new metric upstream becomes selectable here without a coordinated change.


Distribution as a Domain Rule

A reading belongs to exactly one Building, and the rule is simply: deliver it to that Building’s live view.

distribute(reading):
    deliver the reading to reading.building's view

This unconditional delivery is what story TD-3 asks for — live values appearing without a refresh. Preference does not gate this. It once did — distribution used to drop any metric a Building had not selected — but that coupled every live view to the dashboard’s column choices (e.g. the 3D model went stale when temperature was removed from the table). Preference is now purely a display concern: it decides which metrics a Building’s dashboard table renders, applied at the view, while the feed carries every metric the Building produces.

The model says nothing about how readings arrive or are carried onward — that this must hold at high throughput is a quality we hand to the implementation.


A note on transport

Carrying readings to the browser is, by design, not part of this context’s model. We classify real-time transport as a generic subdomain (see Strategic Design: it holds no aggregates and enforces no rules, so it is kept out of the domain model and treated as infrastructure.