Files
core/bible-local/architecture/data-model.md
Mikhail Chusavitin 96aefc0eb4 Hardware ingest contract v2.1: sensors, MAC addresses, device_class expansion
- Add HardwareSensors to JSON contract: fans, power, temperatures, other
- Add machine_sensor_readings table (migration 0022) with upsert in ingest service
- Add mac_addresses []string to HardwarePCIeDevice
- Expand device_class examples: VideoController, ProcessingAccelerator,
  EthernetController, FibreChannelController, StorageController
- Add distributable hardware-ingest-contract.md v2.1 with versioning,
  changelog, field tables, and canonical URL
- Add governance rule: contract doc must be updated with every parser change
- Update data-model.md to document machine_sensor_readings projection
- Update both import-example-full.json files with sensors and new PCIe entries

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 16:15:16 +03:00

4.6 KiB

Data Model And Migration Boundaries

Naming Model

  • Internal canonical naming uses Machine and Part.
  • API/UI compatibility keeps asset and component terminology where already exposed.
  • In domain aliases:
    • type Asset = Machine
    • type Component = Part

Core Persistence Areas

  • Asset registry: machines
  • Component registry: parts
  • Installations: installations
  • Observations: observations
  • Timeline: timeline_events
  • Failures: failure_events
  • Asset firmware state: machine_firmware_states
  • Asset sensor readings: machine_sensor_readings
  • Component history (canonical): component_change_events, component_state_snapshots
  • Asset history (canonical): asset_change_events, asset_state_snapshots
  • History jobs/audit: history_recompute_jobs, history_admin_audit

Sensor Readings

machine_sensor_readings is a last-known-value projection for hardware sensors per asset.

  • Primary key: (machine_id, sensor_type, sensor_name).
  • sensor_type is one of: fan, power, temperature, other.
  • value_json stores type-specific numeric readings (see JSON import contract).
  • Updated on every ingest — not history-backed (no events, no snapshots).
  • collected_at reflects the source observation time, not ingest time.

Out of active model:

  • projects is legacy and not used by runtime handlers/contracts.

Migration Policy

  • Migrations are stored in migrations/.
  • Schema migrations are applied at startup.
  • Legacy entities removed in migration 0016_remove_legacy_features remain out of active scope.
  • History architecture was introduced in migration 0017_history_core.
  • Timeline UI/filter denormalized facets were added in migration 0018_timeline_ui_facets.
  • Installation slot/location (installations.slot_name) was added in migration 0019_installation_slot_name.
  • History-first component_type projection/storage backfill was introduced in migration 0020_component_type_history_first.

Canonical State Model (History-First)

  • parts and machines are current-state projections optimized for reads.
  • component_change_events / asset_change_events are canonical state-change logs.
  • component_state_snapshots / asset_state_snapshots store full after-state snapshots for each state-changing event.
  • timeline_events, installations, failure_events, and machine_firmware_states are projections and may be rebuilt from history.
  • observations is a raw ingest trace/audit store and must not be used as source-of-truth for current component/asset state in runtime UI/API flows.
  • parts.component_type and installations.slot_name are the runtime-readable projections for component type and current slot/location (not observations.details).

History Event Storage Rules

  • History events are versioned per entity (version is monotonic per component/asset).
  • State-changing writes persist:
  1. change event
  2. after-state snapshot
  3. projection updates (parts / machines and related projections)
  4. timeline projection rows
  • History event deletion is soft-delete (is_deleted) for normal user/admin flow.
  • Hard restore is destructive for future history rows and is audited in history_admin_audit.

Timeline Projection Linkage

timeline_events includes logical linkage back to history:

  • logical_entity_type
  • logical_event_id
  • correlation_id
  • is_deleted

This linkage is required for recompute, rollback/delete propagation, and paired asset/component timeline rendering.

timeline_events also stores denormalized UI/filter facets (projection-only, rebuildable from history + registry state), including:

  • source_type
  • visual_action
  • component_serial
  • component_model (used as v1 part_number)
  • asset_serial
  • asset_name_cached
  • slot_name
  • device_name
  • changed_fields_json

These fields are not canonical state and must be treated as timeline projection helpers only.

Installation Slot (Current Components UI)

  • installations.slot_name is the canonical editable slot/location for a component attached to a server.
  • Asset page Current Components bulk actions (Add / Edit / Remove) read/write slot through history-driven component installation state (installation.slot_name in component snapshots) and synchronize projection installations.slot_name.
  • Runtime invariant (app-level validation):
    • for the same machine_id, open installations (removed_at IS NULL) must not share the same non-empty slot_name.
  • Projection-update nuance:
    • slot uniqueness validation must only block writes when slot_name is actually changing for the installation row (status-only edits must not fail because of pre-existing duplicate slot data).