5.6 KiB
5.6 KiB
Data Model And Migration Boundaries
Naming Model
- Internal canonical naming uses
MachineandPart. - API/UI compatibility keeps
assetandcomponentterminology where already exposed. - In domain aliases:
type Asset = Machinetype 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 - Asset logs:
machine_event_logs - 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_typeis one of:fan,power,temperature,other.value_jsonstores type-specific numeric readings (see JSON import contract).- Updated on every ingest — not history-backed (no events, no snapshots).
collected_atreflects the source observation time, not ingest time.
Asset Event Logs
machine_event_logs is a deduplicated append/update read model for host/BMC/Redfish logs per asset.
- Scope: operational log entries shown in dedicated asset log views, not timeline/history.
- Logical identity is a normalized log fingerprint, not the raw ingest row.
- Required stored dimensions:
machine_idlog_source(host,bmc,redfish)fingerprintevent_timeseveritymessage_idmessagecomponent_refraw_payload_jsonfirst_seen_atlast_seen_atseen_count
- Upsert rule:
- new fingerprint for same asset/source -> insert new log row
- repeated fingerprint -> update
last_seen_at, incrementseen_count, refresh mutable presentation fields if needed
- Not history-backed:
- no
asset_change_events - no
component_change_events - no
timeline_events
- no
raw_payload_jsonis retained for diagnostics and vendor-specific fields.
Out of active model:
projectsis 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_featuresremain 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 migration0019_installation_slot_name. - History-first
component_typeprojection/storage backfill was introduced in migration0020_component_type_history_first.
Canonical State Model (History-First)
partsandmachinesare current-state projections optimized for reads.component_change_events/asset_change_eventsare canonical state-change logs.component_state_snapshots/asset_state_snapshotsstore full after-state snapshots for each state-changing event.timeline_events,installations,failure_events, andmachine_firmware_statesare projections and may be rebuilt from history.observationsis 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_typeandinstallations.slot_nameare the runtime-readable projections for component type and current slot/location (notobservations.details).
History Event Storage Rules
- History events are versioned per entity (
versionis monotonic per component/asset). - State-changing writes persist:
- change event
- after-state snapshot
- projection updates (
parts/machinesand related projections) - 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_typelogical_event_idcorrelation_idis_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_typevisual_actioncomponent_serialcomponent_model(used as v1part_number)asset_serialasset_name_cachedslot_namedevice_namechanged_fields_json
These fields are not canonical state and must be treated as timeline projection helpers only.
Installation Slot (Current Components UI)
installations.slot_nameis the canonical editable slot/location for a component attached to a server.- Asset page
Current Componentsbulk actions (Add / Edit / Remove) read/write slot through history-driven component installation state (installation.slot_namein component snapshots) and synchronize projectioninstallations.slot_name. - Runtime invariant (app-level validation):
- for the same
machine_id, open installations (removed_at IS NULL) must not share the same non-emptyslot_name.
- for the same
- Projection-update nuance:
- slot uniqueness validation must only block writes when
slot_nameis actually changing for the installation row (status-only edits must not fail because of pre-existing duplicate slot data).
- slot uniqueness validation must only block writes when