Files
3yearplan/schemas/docs/consumer-integration.md
Joseph Doherty 5953685ffb Seed the canonical OT schemas content under 3yearplan/schemas/ as a temporary location until a dedicated schemas repo is created (Gitea push-to-create is disabled, the dedicated repo needs a manual UI step). Initial seed contributed by the OtOpcUa team to unblock the EquipmentClassRef integration timeline (lmxopcua decision #112) and to provide the future cross-team owner with a concrete starting point rather than a blank slate. Marked DRAFT throughout with prominent "ownership TBD" framing in README and CONTRIBUTING — the future owner team should treat this seed as a starting point and revise format / structure / naming as the open questions in README "Open Questions" get resolved.
Includes: README explaining purpose / scope / temporary-location framing / format decision, CONTRIBUTING.md with proposed workflow + per-class semver versioning policy + validation commands, format/equipment-class.schema.json defining the shape of a class template (classId, version, displayName, applicability, signals, alarms, optional stateModel), format/tag-definition.schema.json defining the shape of a single canonical signal (name, dataType, category, unit, isArray, accessLevel, writeIdempotent, isHistorized, scaling), format/uns-subtree.schema.json defining the shape of a per-site UNS subtree (enterprise + site + areas + lines), classes/fanuc-cnc.json as the worked pilot class with 16 signals + 3 alarms + suggested state-derivation notes (per OtOpcUa corrections doc D1), uns/example-warsaw-west.json as a worked UNS subtree example, docs/overview.md (what / why / lifecycle / what's NOT in this repo), docs/format-decisions.md (8 numbered decisions covering JSON Schema choice per corrections D2, per-class semver, additive-only minor bumps, _default placeholder reservation, signal-name vs UNS-segment regex distinction, stateModel-as-informational, no per-equipment overrides at this layer, applicability.drivers as OtOpcUa driver enumeration), docs/consumer-integration.md (how OtOpcUa / Redpanda / dbt each integrate). $id URLs in the JSON schemas resolve at the actual current path so validators don't 404.

Top-level README adds a row to the Component Detail Files table pointing to schemas/. Corrections doc B2 (schemas-repo dependencies) marked partially RESOLVED with the seed location and a list of what still needs the plan team or cross-team owner to decide (owner team naming, dedicated repo migration, format-decision ratification, FANUC CNC pilot confirmation, CI gate setup, Redpanda + dbt consumer integration plumbing).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 12:35:27 -04:00

3.2 KiB

Consumer Integration

How each of the three canonical-model consumers integrates with this repo.

OtOpcUa equipment namespace

Reference: lmxopcua/docs/v2/plan.md decisions #112, #115; lmxopcua/docs/v2/config-db-schema.md Equipment table.

What it pulls: equipment-class templates from classes/ keyed by Equipment.EquipmentClassRef in the central config DB.

Integration points:

  • At Admin UI draft-publish time: sp_ValidateDraft checks that every Equipment row's tag set satisfies the referenced class's required-signal list. Missing required signals = draft validation error.
  • At cluster runtime: each OtOpcUa node fetches the relevant class templates at startup (cached locally per the LiteDB cache pattern) and uses them to validate the applied generation.

Versioning: each EquipmentClassRef value carries a classId@version form (e.g. fanuc-cnc@0.1.0). Pinning to a specific version protects against breaking changes in the schemas repo.

Status (2026-04-17): Equipment.EquipmentClassRef ships as a nullable hook column in OtOpcUa Phase 1 with no validation enforcement. Enforcement lands when the schemas repo is publishable and the OtOpcUa team wires the validator into sp_ValidateDraft.

Redpanda topics + Protobuf schemas

What it pulls: equipment-class templates derive Protobuf message definitions for canonical equipment events (equipment.state.transitioned, equipment.signal.changed, etc.).

Integration points:

  • A code-generation step in the Redpanda team's CI reads classes/*.json and emits .proto files for each class.
  • The generated .proto files publish to a Schema Registry (or equivalent) for runtime consumers.
  • Versioning: Protobuf schema versions track this repo's tag versions one-for-one.

Status (2026-04-17): not wired. Redpanda team to design the codegen step when the schemas repo has a stable initial class set.

dbt curated layer in Snowflake

What it pulls: equipment-class templates derive column definitions for the curated equipment-state and equipment-signal models in dbt.

Integration points:

  • A dbt macro reads classes/*.json and generates per-class staging models with the canonical signal columns.
  • UNS subtree definitions (uns/*.json) drive the dim_site / dim_area / dim_line dimension tables.
  • Versioning: dbt project pins to a specific schemas-repo tag; updates require an explicit dbt deploy.

Status (2026-04-17): not wired. dbt team to design the macro when the schemas repo has a stable initial class set.

Cross-consumer compatibility

A breaking change in a class template (major version bump per CONTRIBUTING.md) requires:

  1. Schemas repo PR with the change + rationale
  2. Each consumer team confirms the impact on their integration
  3. All three consumers either upgrade simultaneously OR pin to the prior major version until they can upgrade
  4. OtOpcUa specifically: a breaking change to a class with existing equipment in production requires a config-generation publish that updates the equipment's EquipmentClassRef to the new version + reconciles tag changes

Breaking changes should be rare. Preferred pattern: add new optional signals (minor bump) + deprecate old ones across multiple minor releases before removing in a major.