Files
ITWorx-Pulse-Public/docs/architecture/DATA_MODEL.md
T
ITWorx Pulse release export bd774932d5
Public source validation / validate (push) Failing after 3m8s
Publish ITWorx Pulse source
2026-09-03 02:09:19 +02:00

15 KiB

Data model

1. Principles

  • Stable internal UUIDs; external IDs are source-scoped aliases.
  • Source facts and user overrides are stored separately.
  • Soft deletion/tombstones preserve history and reconciliation.
  • Important configuration is versioned.
  • Alert state changes are transactional.
  • Time is stored in UTC; locale/time zone applied at presentation.
  • JSONB is used for bounded extensible attributes, not as a substitute for core relational structure.

2. Identity and access

users

  • id
  • external_subject
  • display_name
  • email
  • status
  • created_at / updated_at / last_login_at

roles, user_roles

Roles: viewer, operator, editor, administrator.

sessions or external session metadata

Only if required by the chosen auth implementation. Avoid storing OIDC tokens unnecessarily.

3. Datasources

data_sources

  • id
  • type
  • name
  • enabled
  • configuration reference
  • capability document
  • health_state
  • last_success_at
  • last_error_code/message_redacted
  • freshness policy
  • created/updated

collectors

  • id
  • datasource_id
  • kind
  • version
  • heartbeat
  • capabilities
  • status

4. Inventory

entities

  • id UUID
  • entity_type
  • canonical_name
  • display_name
  • status
  • status_reasons JSONB
  • first_seen_at
  • last_seen_at
  • tombstoned_at
  • attributes JSONB

entity_aliases

  • entity_id
  • source_id
  • external_type
  • external_id
  • unique(source_id, external_type, external_id)

Container identity and recreation

Container runtime IDs are source-scoped aliases, not logical identity by themselves. A live runtime ID always matches its exact source/runtime alias. When a runtime ID changes, the same logical entity may be reused only when both the source-scoped compose project and compose service are present and uniquely identify one prior active alias. A container name, image, or digest alone is insufficient evidence and creates a new logical entity. The old runtime alias remains in history as inactive, the new alias points to the same logical entity, and recreation events keep that logical entity as events.entity_id while retaining previous/current runtime IDs in bounded attributes.

entity_facts

  • entity_id
  • field_name
  • source_id
  • value JSONB
  • observed_at
  • confidence
  • valid_until

entity_overrides

  • entity_id
  • field_name
  • value JSONB
  • user_id
  • updated_at

entity_relations

  • id
  • source_entity_id
  • relation_type
  • target_entity_id
  • source_id
  • confidence
  • confirmed
  • first_seen/last_seen/tombstoned

applications

  • logical application ID and display name
  • discovered component references
  • critical/optional component policy
  • aggregate status and bounded reason list
  • user override metadata kept separate from discovery grouping

5. Metrics catalog

metric_definitions

  • id
  • semantic_name unique
  • version
  • description
  • unit
  • value_kind
  • source_kind
  • query_template
  • label contract
  • limits
  • allowed visualizations
  • default transformations
  • status policy reference
  • enabled

metric_bindings

Maps semantic metric to datasource/exporter/capability variants.

Metric samples remain in Prometheus.

6. Dashboards

dashboards

  • id
  • slug
  • name
  • description
  • owner_user_id nullable
  • scope personal/shared/system
  • archived_at
  • current_version_id
  • revision (optimistic concurrency token)
  • created/updated

dashboard_versions

  • id
  • dashboard_id
  • version_number
  • schema_version
  • document JSONB
  • change_summary
  • created_by
  • created_at

Dashboard versions are immutable. Dashboard writes lock the current row, compare revision, and commit the new version/current pointer atomically. The API stores only bounded revision metadata in audit diffs; full dashboard documents are not copied into audit events.

A dashboard version contains variables, widget instances, behavior and layout documents. Save as one atomic version to avoid partial layout/config updates.

Optional normalized indexes may extract widget type/entity references for search/impact analysis.

7. Events

events

  • id
  • event_type
  • severity
  • entity_id nullable
  • source_id
  • occurred_at
  • received_at
  • dedup_key
  • summary
  • attributes JSONB bounded/redacted
  • correlation_id
  • unique(source_id, dedup_key, occurred_at bucket) as appropriate

8. Alerts

alert_rules

  • id
  • name
  • enabled
  • severity
  • evaluator type/config
  • scope selector
  • pending duration
  • resolve duration
  • cooldown duration for repeated firing notifications
  • hysteresis config
  • grouping labels
  • suppression/dependency policy
  • current_version_id
  • revision (optimistic concurrency token)
  • created/updated

alert_rule_versions

Immutable rule documents and audit metadata.

alert_instances

Stable entity/rule combination:

  • id
  • rule_id
  • fingerprint
  • entity_id
  • current_state
  • active_since
  • last_evaluated_at
  • last_value
  • reason
  • acknowledged_by/at
  • cooldown_until
  • silenced_until
  • version for optimistic concurrency

alert_occurrences

Immutable transitions/evaluation outcomes relevant to history.

9. Incidents

incidents

  • id
  • title
  • summary
  • severity
  • status
  • started_at
  • resolved_at
  • owner_user_id
  • correlation_method
  • confidence
  • created/updated
  • version

incident_alerts, incident_entities

Many-to-many links with rationale.

incident_notes

  • incident_id
  • author
  • body sanitized
  • created_at

10. Maintenance and notifications

maintenance_windows

  • id
  • name
  • selector
  • start/end or recurrence
  • suppress notifications/state policy
  • creator/audit

notification_channels

Encrypted secret references and non-secret config.

notification_deliveries

  • occurrence/incident
  • channel
  • status
  • attempts
  • last_error_redacted
  • timestamps
  • idempotency_key

11. Audit

audit_events

  • actor/user/service
  • action
  • resource type/id
  • result
  • occurred_at
  • correlation_id
  • source IP/session metadata where appropriate
  • before/after bounded diff with secret fields excluded

12. Operations

job_runs

  • job type/key
  • scheduled/started/completed
  • status
  • counts
  • error code
  • correlation ID
  • lease owner and lease expiry for coordinated worker execution

schema_migrations

Managed by migration tool.

system_settings

Typed/versioned settings; no plaintext secrets.

13. Concurrency

Use optimistic concurrency for:

  • dashboard save;
  • alert acknowledgement/state;
  • incident edit;
  • settings.

Return a conflict response with current version rather than silently overwriting.

14. Retention

Implement partitioning/cleanup when measurements justify it.

Baseline:

  • inventory history/tombstones: enough for reconciliation and events;
  • events: 1 year configurable;
  • alert occurrences: 2 years configurable;
  • incidents: retained until explicit policy;
  • audit: at least 1 year configurable;
  • job runs: shorter operational retention;
  • dashboard versions: at least 180 days or fixed count plus protected versions.

arrays and parity checks

An array snapshot preserves source-scoped provenance and UTC observed/received timestamps. Array members retain stable source IDs, role, state and bounded capacity/I/O counters. Parity state is separate from array state, and current/history parity checks retain progress, byte-per-second speed, error count and timestamps. Missing, disabled or emulated members are represented explicitly; stale source data maps to Unknown. Array transition events retain the array entity ID and bounded state/error attributes without exposing operational controls.

disks and capacity

Disk identity is source-scoped and stable from the provider ID. A disk retains role, state, model, privacy-aware serial display, filesystem and bounded size/used/free/inode metrics. Used values above capacity are rejected; free space and utilization are derived from validated bytes, and inode utilization is derived separately. Missing disks remain in current/history projections instead of being dropped, while raw serials are excluded from API output.

SMART facts

SMART is an optional disk capability with its own observed timestamp and freshness state. Normalization preserves generic overall result, bounded mapped attributes, critical/reason status and self-test result/age. Unavailable or stale SMART is Unknown and never Healthy; critical pending, reallocated, offline-uncorrectable, CRC or wear attributes remain visible even when the vendor overall result is passed.

disk telemetry facts

Disk performance history is bounded and timestamped for live/history consumers. Temperature observations retain source time and policy-derived status; recovery does not clear attention until the configured recovery threshold is crossed. Latency/spin capabilities explicitly report unsupported when the source cannot provide them.

pools and scrub facts

Pool identity is stable within its source and retains filesystem, usable/used/free bytes, profile/redundancy, bounded member state and filesystem error facts. Btrfs and ZFS capabilities are explicit and conditional; unsupported fields are never fabricated. Scrub current state and bounded history retain progress, bytes checked, errors and UTC timestamps. Stale source data maps pool state to Unknown while preserving provenance. Transition events identify degraded/faulted/recovered pools and scrub failures without exposing controls.

shares and growth facts

Share identity is source-scoped and retains configured allocation/cache policy, source-owned used-size timestamp/state, bounded placement by pool and chronological growth points. Growth deltas and daily rates are derived from UTC observations, including negative changes, without exposing paths or file content. ScanPlan caps due size refreshes per run and records deferred work plus cache TTL so expensive scans remain bounded and observable.

storage visualization projections

Storage map nodes are bounded projections of array members, pools and disks with entity links, kind, explicit state and detail text. Temperature heatmap points retain disk identity, UTC observed time, value and text status; visual cells never replace the accessible table alternative.

capacity forecasts

A forecast is a bounded projection over UTC usage observations. Its policy records enabled state, maximum window, minimum points and method. Median daily growth is used for linear projection; bulk-import/outlier and irregular-interval safeguards lower confidence and suppress daysToCapacity/projectedAt. Method, window, point count, confidence and reason are always retained so the UI cannot present an unexplained precise date.

capacity_samples preserves bounded historical capacity observations for shares, pools and disks without storing file contents. Agent snapshot writes and their samples commit in one PostgreSQL transaction. A six-hour UTC bucket and primary key on (entity_kind, entity_id, source_id, sampled_at) make repeated discovery runs idempotent; a delayed retry may not replace a newer observation in the same bucket. The history index (entity_kind, entity_id, sampled_at DESC) supports the actual bounded forecast query. Forecast reads use at most 512 points inside the configured window and combine persisted share usage with the current canonical pool capacity. Insufficient, stale or unavailable histories remain assessments with confidence=none; only medium/high results count as qualified forecasts.

services and probes

services, service_endpoints and probes represent reachable capabilities independently of container state. Configuration rows use revision, updated_at and archived_at; active names are unique per parent, while archived rows remain to preserve history. probe_results stores immutable timestamped outcomes, and service_certificates stores observed certificate facts. service_dependencies preserves source, confidence and confirmation state. service_permissions maps database roles to service permissions; secret references are identifiers only and never plaintext credentials.

service status projections

Service status is derived from immutable probe_results, not from container state. The bounded projection retains current state/reason, last result/success/failure timestamps, latest latency, availability sample counts and bounded history. A result older than the configured freshness policy becomes unknown; it is never silently treated as healthy. State transitions produce deterministic service events with service identity, from/to state and reason. M8-06 persistence adds alert_silences and maintenance_windows with bounded reason and name fields, JSON matcher or selector, UTC start and end timestamps, explicit active/expired/revoked status, creator and owner provenance, revocation and expiry timestamps, revision, expiry indexes, and deterministic listing indexes. These tables are additive and do not alter M1 tables or alert occurrence history.

M8-07 extends alert_occurrences with an immutable unacknowledge event type and adds an acknowledged-state index. Alert list/detail projections join rule and optional entity metadata while preserving instance revision and occurrence history.

M8-08 notification persistence

  • notification_channels stores only a bounded non-secret configuration and a reference to an external secret provider; the secret value is never part of the domain object or query result.
  • notification_outbox has a unique idempotency key, bounded event content, a lease-aware status, bounded attempts and deterministic due ordering.
  • notification_deliveries records each claimed attempt with a unique (outbox_id, attempt) key. Claim, delivery audit creation, completion and retry state changes are transactionally coordinated.
  • Channel updates use optimistic revisions. Outbox rows retain recovery events and are not deleted after successful delivery, preserving auditability.

M8-09 incident persistence

  • incidents stores a bounded correlation key, title/summary, derived severity, lifecycle status, start/resolution timestamps, rationale method, confidence, owner and optimistic revision. Only one unresolved incident may exist for a correlation key.
  • incident_alerts preserves per-alert rationale/confidence and distinguishes deterministic correlation from manual association. A manual association is never overwritten by a later correlation upsert.
  • incident_entities keeps the affected entity set with bounded rationale/confidence and restricts entity deletion while incident evidence references it.

M8-10 incident notes and ownership

incident_notes is bounded operator context attached to an incident. Bodies are normalized to plain text, stripped of tag-shaped markup and capped at 2,000 characters before persistence; notes are ordered by UTC creation time and stable ID. Notes cascade with their incident and never affect alert/entity evidence. Incident ownership is metadata updated with an optimistic revision, so stale UI writes become an explicit conflict.