ADR-0010 Device-Type Field Contract and Storage Sinks
Status
Section titled “Status”Accepted and implemented on 2026-08-06.
Context
Section titled “Context”V1 visual Flows encoded measurement and Device-attribute persistence in normal blocks. The Device Type did not authoritatively define all values a Flow could store, current values used a separate attribute history model, and a Flow could be assigned independently after creation. This hid persistence semantics and allowed contracts to drift.
Decision
Section titled “Decision”Introduce a tenant-scoped device_field_definitions catalog and bind every Flow
to exactly one Device Type. Each Device Type owns at most one Flow. Replace
persistence blocks with non-deletable Current-Value and Timeseries system sinks
in flow-graph.v2.
Store the bounded latest snapshot in device_current_values and long-term
points in measurements. V2 Measurements reference the Device Type and field
definition while retaining key, unit, and measurement type snapshots. Commit
both targets, Action jobs, outbox rows, and execution success atomically. Use
only normalized Netmore time as observedAt.
Released versions pin their field contract. Fields use deprecation and additive target evolution rather than deletion or incompatible mutation. V2 templates carry UUID-free field requirements and bind them when copied.
Consequences
Section titled “Consequences”The Flow editor makes storage behavior visible and statically typed. Current reads are bounded and organization-scoped. Out-of-order points remain available in Timeseries without rolling the current snapshot backward.
The migration intentionally removes development Flow runtime data and makes old Flow binaries incompatible after activation. Raw data remains the replay source. V1 template versions remain only as deprecated read-only history. Rollback is a database restore; normal recovery is a forward-fix.