Files
core/bible/architecture/runtime-flows.md

100 lines
3.0 KiB
Markdown

# Runtime Flows And Invariants
## Event Time Source Priority
Use component event time over ingest time whenever possible.
- `eventFallbackTime(actual, ingestedAt, collectedAt)`:
1. `actual`
2. `ingestedAt`
3. `collectedAt`
- `collectedFallbackTime(collectedAt, ingestedAt)`:
1. `collectedAt`
2. `ingestedAt`
## Status Event Time Parsing Order
`parseComponentStatusEventTime` resolves time in this order:
1. `status_changed_at`
2. Latest matching `status_history` item for current status
3. Latest parseable `status_history` item
4. `status_checked_at`
## Failure Event Rules
For critical components:
- Timeline event type: `COMPONENT_FAILED`
- `failure_events.failure_time` uses resolved failure time (not raw ingest time)
- `failure_events.external_id` includes the same failure timestamp
## First Seen Rules
`parts.first_seen_at` must be the earliest known ingest-derived component time.
Candidate sources:
1. Parseable `status_history[].changed_at`
2. `status_changed_at`
3. `status_checked_at`
4. `eventFallbackTime(nil, ingestedAt, collectedAt)`
Persistence rule:
- Keep the minimum value over time.
- If incoming is earlier than stored value, overwrite with incoming value.
## Duplicate Component Serial Rules (CSV + JSON Ingest)
If serial numbers are not unique within the same `p/n` (`model`) inside one ingest payload:
- First occurrence keeps original `vendor_serial`.
- Each next duplicate occurrence is assigned a service serial placeholder:
- Format: `NO_SN-XXXXXXXX` (8-digit zero-padded global counter).
- If `vendor_serial` is empty, a service serial placeholder is assigned as well.
- Counter is global for the whole application and stored in `id_sequences` under `entity_type = 'no_sn_placeholder'`.
## Component Health Computation In UI
Component health is derived only from the latest status event among:
- `COMPONENT_FAILED`
- `COMPONENT_WARNING`
- `COMPONENT_OK`
Non-status timeline events (`INSTALLED`, `REMOVED`, `FIRMWARE_CHANGED`, `FIRMWARE_INSTALLED`, etc.) must not change health status.
## Firmware Timeline Rules
For component firmware observations:
- First observed version -> `FIRMWARE_INSTALLED` (asset + component timeline pair)
- Later version change -> `FIRMWARE_CHANGED` (asset + component timeline pair)
Storage details:
- `FIRMWARE_INSTALLED` stores transition string in `timeline_events.firmware_version`: `- -> <installed_version>`
- `FIRMWARE_CHANGED` stores installed/new firmware value
Detection details:
- Previous observation lookup: `ORDER BY observed_at DESC, id DESC LIMIT 1 OFFSET 1`
## Timeline Color Semantics
- `REMOVED` -> yellow
- `COMPONENT_FAILED` -> red
- `COMPONENT_WARNING` and related warning semantics follow `timelineEventClass`
## Regression Guardrails
Do not reintroduce these regressions:
- Using ingest timestamp when payload provides better event/failure timestamp
- Letting `INSTALLED` mark failed components as healthy
- Missing `Previous Components` section on asset page
- Missing installation history on component page
- Missing firmware information on component page timeline