This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
# Host, container and application monitoring requirements
|
||||
|
||||
## Host
|
||||
|
||||
Metrics/state:
|
||||
- uptime and boot time;
|
||||
- CPU total/per core, load, frequency where available;
|
||||
- iowait, interrupts and context switches;
|
||||
- memory used/available/cache/swap and pressure;
|
||||
- filesystem usage/inodes;
|
||||
- network per interface, errors/drops;
|
||||
- process count and OOM events;
|
||||
- temperatures/fans/sensors where supported;
|
||||
- GPU usage/memory/temperature where supported;
|
||||
- time synchronization health.
|
||||
|
||||
Host status must distinguish:
|
||||
- high but expected load;
|
||||
- sustained saturation;
|
||||
- missing collector;
|
||||
- stale metrics;
|
||||
- thermal risk;
|
||||
- resource exhaustion.
|
||||
|
||||
## Process explorer
|
||||
|
||||
Read-only, bounded view:
|
||||
- top CPU;
|
||||
- top memory;
|
||||
- PID, name, state, runtime;
|
||||
- container association when known;
|
||||
- process tree on demand.
|
||||
|
||||
No process termination. Process command-line arguments, environment and working directory are not shown by default; process rows are bounded and read-only.
|
||||
|
||||
## Containers
|
||||
|
||||
Inventory:
|
||||
- ID/name;
|
||||
- image/tag/digest when available;
|
||||
- state and health;
|
||||
- uptime/start/stop;
|
||||
- restart count and exit code;
|
||||
- CPU/memory;
|
||||
- network;
|
||||
- block I/O;
|
||||
- ports;
|
||||
- volumes/networks;
|
||||
- stack/project and labels.
|
||||
|
||||
Behavior:
|
||||
- preserve runtime state separately from health;
|
||||
- expose intentional stop explicitly so a stopped container is not silently treated as healthy;
|
||||
- retain source freshness and provenance;
|
||||
- expose metric and lifecycle availability explicitly; absent collector fields render as Unknown rather than numeric zero;
|
||||
- bound container count and detail collections for predictable response size;
|
||||
- detect restart loops over a rolling window;
|
||||
- distinguish intentionally stopped/disabled;
|
||||
- preserve history across container recreation through stable identity mapping;
|
||||
- never infer application health solely from Docker `running`.
|
||||
|
||||
### Container identity and recreation
|
||||
|
||||
Runtime IDs are source-scoped aliases. A changed runtime ID maps to the same logical container only when the source, compose project and compose service form a unique stable key. Reusing a name without that evidence creates a new logical entity; ambiguous stable keys also refuse to merge. Historical aliases remain visible to reconciliation, and lifecycle events retain the logical entity ID while recording the prior and current runtime IDs.
|
||||
## Lifecycle events and instability
|
||||
|
||||
Container transitions are normalized into bounded lifecycle events for state, health, restart and intentional-stop changes. Duplicate source/dedup/time events are discarded. A restart loop requires the current container state to be running and at least the configured number of restarts inside the bounded window; a stopped container is not labeled as looping. Ranked resource consumers use deterministic ID/label tie-breaks, and status grids retain text reasons alongside status indicators.
|
||||
## Applications
|
||||
|
||||
Applications group containers and services into a policy-driven status. Critical component failures degrade the application; critical unknown state remains Unknown. Optional component failures are included in the reasons list and degrade the aggregate without being labeled critical. A service-down state degrades the component even when its container runtime is still running. User overrides for application names and component criticality are applied after discovery and survive repeated discovery projections.
|
||||
|
||||
Applications group one or more containers and services.
|
||||
|
||||
Fields:
|
||||
- friendly name;
|
||||
- critical/optional components;
|
||||
- dependencies;
|
||||
- public/internal URLs;
|
||||
- owner/category/tags;
|
||||
- aggregate status reasons.
|
||||
|
||||
Aggregate status is policy-driven and tested. An optional background worker may fail without making the complete application critical, while a database or main endpoint failure normally degrades it.
|
||||
|
||||
## Events
|
||||
|
||||
Generate normalized events for:
|
||||
- container start/stop/restart/die/health change;
|
||||
- image or configuration change;
|
||||
- application status change;
|
||||
- datasource loss/recovery;
|
||||
- host reboot;
|
||||
- OOM and thermal events.
|
||||
|
||||
Deduplicate noisy repeated events.
|
||||
@@ -0,0 +1,238 @@
|
||||
# ITWorx Pulse — Product requirements
|
||||
|
||||
## 1. Product statement
|
||||
|
||||
ITWorx Pulse is a self-hosted operational observability platform for a personal/professional Unraid environment. It combines infrastructure, container, storage, network and service health in a configurable dashboard that is easier to understand and operate than a collection of raw monitoring tools.
|
||||
|
||||
Pulse is not a thin Grafana theme. It owns:
|
||||
|
||||
- inventory and relationships;
|
||||
- semantic metrics;
|
||||
- dashboard composition;
|
||||
- status reasoning;
|
||||
- alert lifecycle;
|
||||
- incident grouping;
|
||||
- user experience;
|
||||
- operational documentation and audit.
|
||||
|
||||
Prometheus-compatible systems remain the primary source of time-series history in v1.
|
||||
|
||||
## 2. Primary user
|
||||
|
||||
The primary user is a technically experienced server owner/operator who:
|
||||
|
||||
- manages an Unraid host with many Docker applications;
|
||||
- wants one reliable status surface;
|
||||
- needs detailed drill-down without constant PromQL work;
|
||||
- uses desktop, mobile and a possible wallboard;
|
||||
- values safe automation and read-only monitoring;
|
||||
- may later link incidents to a separate management platform.
|
||||
|
||||
The architecture supports additional viewers/operators but v1 does not need multi-tenant SaaS behavior.
|
||||
|
||||
## 3. Goals
|
||||
|
||||
1. Determine within seconds whether the environment is healthy.
|
||||
2. Explain every degraded/critical/unknown state.
|
||||
3. Allow dashboards to be composed without code.
|
||||
4. Show smooth live behavior and useful history.
|
||||
5. Detect container, storage and service failure independently.
|
||||
6. Prevent alert storms and group related failures.
|
||||
7. Remain safe when telemetry is stale or unavailable.
|
||||
8. Deploy without disrupting existing Unraid services.
|
||||
9. Provide reproducible evidence for operation, backup and recovery.
|
||||
10. Be portfolio-quality in visual, technical and operational terms.
|
||||
|
||||
## 4. Non-goals for v1
|
||||
|
||||
- General log aggregation/search platform.
|
||||
- Kubernetes monitoring.
|
||||
- Multi-organization SaaS.
|
||||
- Automatic remediation.
|
||||
- Container lifecycle management.
|
||||
- Array/storage write operations.
|
||||
- Public unauthenticated monitoring.
|
||||
- AI-required diagnosis.
|
||||
- Unlimited third-party plugin marketplace.
|
||||
- Replacing Prometheus or Grafana without measured need.
|
||||
- Monitoring arbitrary internet targets without an allowlist.
|
||||
|
||||
## 5. Functional capabilities
|
||||
|
||||
### 5.1 Authentication and access
|
||||
|
||||
- Authentik-compatible OIDC login.
|
||||
- Viewer, Operator, Editor and Administrator roles.
|
||||
- Disabled-by-default local break-glass recovery.
|
||||
- Session expiry and logout.
|
||||
- Audit for security/configuration changes.
|
||||
- Wallboard uses a constrained read-only mode or authenticated session.
|
||||
|
||||
### 5.2 Overview
|
||||
|
||||
The default overview shows:
|
||||
|
||||
- global status and explanation;
|
||||
- active incidents/alerts;
|
||||
- uptime, CPU, memory and load;
|
||||
- array and pool status/capacity;
|
||||
- network traffic;
|
||||
- container/application health;
|
||||
- service reachability and latency;
|
||||
- UPS when available;
|
||||
- recent events;
|
||||
- freshness of each source.
|
||||
|
||||
### 5.3 Dashboards
|
||||
|
||||
Users can:
|
||||
|
||||
- create, clone, rename, archive and delete dashboards;
|
||||
- add widgets from a catalog;
|
||||
- drag, resize, lock, duplicate, hide and remove widgets;
|
||||
- configure data, visualization, thresholds and behavior;
|
||||
- preview and edit desktop/tablet/mobile/wallboard layouts;
|
||||
- use variables and cross-filtering;
|
||||
- undo/redo during editing;
|
||||
- save versioned revisions and restore previous versions;
|
||||
- import/export validated JSON;
|
||||
- use system templates;
|
||||
- open widgets fullscreen and drill into entities.
|
||||
|
||||
### 5.4 Inventory and relationships
|
||||
|
||||
Pulse discovers and maintains:
|
||||
|
||||
- host;
|
||||
- hardware and interfaces;
|
||||
- array, pools, disks, filesystems and shares;
|
||||
- containers, images, stacks, volumes and networks;
|
||||
- applications and services;
|
||||
- endpoints and certificates;
|
||||
- data sources, collectors and probes;
|
||||
- dependency relationships.
|
||||
|
||||
Every reconciled field retains source ownership and optional user override.
|
||||
|
||||
### 5.5 Metrics and charts
|
||||
|
||||
- Historical range queries.
|
||||
- Live updates with bounded memory.
|
||||
- Semantic metric catalog.
|
||||
- Units, transformations and aggregation.
|
||||
- Zoom, hover, pause, time range and compare.
|
||||
- Stale/unknown representation.
|
||||
- Query limits and authorization.
|
||||
- CSV/image export where appropriate.
|
||||
- Event annotations.
|
||||
|
||||
### 5.6 Alerts and incidents
|
||||
|
||||
- Versioned alert rules.
|
||||
- Pending, firing, acknowledged and resolved lifecycle.
|
||||
- Unknown, silenced, suppressed and maintenance states.
|
||||
- Hysteresis, cooldown, grouping and dependency suppression.
|
||||
- Notification channels with delivery audit.
|
||||
- Incident creation/grouping from related alerts.
|
||||
- Timeline, notes, ownership and status.
|
||||
- Suggested relationships labeled as uncertain unless proven.
|
||||
|
||||
### 5.7 Operations
|
||||
|
||||
- Datasource health page.
|
||||
- Self-monitoring page.
|
||||
- Backup/restore.
|
||||
- Config export.
|
||||
- Safe deployment and rollback.
|
||||
- Maintenance windows.
|
||||
- Diagnostic bundle with secret redaction.
|
||||
- Clear runbook.
|
||||
|
||||
## 6. Core user journeys
|
||||
|
||||
### Journey A — Morning health check
|
||||
|
||||
1. User opens Pulse.
|
||||
2. Global state loads within the performance budget.
|
||||
3. The page shows Operational or a specific explained deviation.
|
||||
4. User opens an affected component from the status explanation.
|
||||
5. Related graph/event context is visible without constructing a query.
|
||||
|
||||
### Journey B — Customize overview
|
||||
|
||||
1. User enters Edit mode.
|
||||
2. Adds a network chart.
|
||||
3. Resizes and positions it.
|
||||
4. Configures the interface and time range.
|
||||
5. Previews mobile layout.
|
||||
6. Saves.
|
||||
7. Reload preserves all layouts and version history.
|
||||
|
||||
### Journey C — Diagnose service failure
|
||||
|
||||
1. Application container remains running.
|
||||
2. HTTP probe returns failure.
|
||||
3. Service becomes Degraded.
|
||||
4. Alert transitions pending -> firing after its duration.
|
||||
5. Related container/network events appear.
|
||||
6. User acknowledges the incident.
|
||||
7. Recovery resolves the alert and records duration.
|
||||
|
||||
### Journey D — Storage risk
|
||||
|
||||
1. SMART/temperature or pool capacity crosses policy.
|
||||
2. Pulse explains which disk/pool and why.
|
||||
3. User sees current values and history.
|
||||
4. No destructive storage action is offered.
|
||||
5. Optional link opens an external operational workflow later.
|
||||
|
||||
### Journey E — Mobile incident view
|
||||
|
||||
1. User opens Pulse on mobile.
|
||||
2. Active incident is immediately accessible.
|
||||
3. Summary, affected entities, latest values and acknowledgement fit the mobile flow.
|
||||
4. Complex dashboard editing is not required.
|
||||
|
||||
## 7. Status model
|
||||
|
||||
Top-level and entity status:
|
||||
|
||||
- `operational`
|
||||
- `attention`
|
||||
- `degraded`
|
||||
- `critical`
|
||||
- `unknown`
|
||||
- `maintenance`
|
||||
- `disabled`
|
||||
|
||||
Rules:
|
||||
|
||||
- `unknown` outranks a false `operational` claim when required data is stale.
|
||||
- Top-level status includes a list of contributing reasons.
|
||||
- Optional/non-critical component failures do not automatically become critical.
|
||||
- Status aggregation is deterministic and tested.
|
||||
- Color is never the only representation.
|
||||
|
||||
## 8. Acceptance-level non-functional requirements
|
||||
|
||||
- Clean build/deploy from a new checkout.
|
||||
- Responsive at target scale.
|
||||
- At least 17 hours of real wallboard soak without unbounded growth; the
|
||||
product owner explicitly replaced the original 24-hour duration for M10-14
|
||||
on 2026-08-11 while retaining every other performance budget.
|
||||
- Graceful source disconnect/reconnect.
|
||||
- No unrestricted Docker socket in API/web.
|
||||
- Least privilege and non-root runtime.
|
||||
- Automated accessibility checks plus keyboard flows.
|
||||
- Backup/restore and upgrade/rollback.
|
||||
- Secrets absent from repository, logs and evidence.
|
||||
- Traceable requirement-to-test-to-evidence mapping.
|
||||
|
||||
## 9. Success metrics
|
||||
|
||||
- Time to first meaningful overview: under the defined performance budget.
|
||||
- Time to identify a simulated primary fault: less than two minutes in usability validation.
|
||||
- Zero false-green results in stale-source tests.
|
||||
- All baseline failure scenarios detected with expected status and alert behavior.
|
||||
- Dashboard configuration persists and restores across browser/server restart.
|
||||
- Production deployment survives planned restart with healthy state and preserved configuration.
|
||||
@@ -0,0 +1,44 @@
|
||||
# Requirements index
|
||||
|
||||
The machine-readable/portable traceability matrix is `planning/requirements-matrix.csv`.
|
||||
|
||||
- **PRD-001** — Global health is visible and explained — tasks: `M2-09;M5-07;M6-09;M7-09;M8-10;M9-13` — verification: E2E + final acceptance
|
||||
- **PRD-002** — Stale required telemetry is Unknown, never Healthy — tasks: `M2-07;M4-11;M5-09;M6-09;M8-03;M9-13` — verification: Unit + scenario + E2E
|
||||
- **PRD-003** — Dashboard CRUD and version history — tasks: `M3-01;M3-03;M3-11` — verification: API + integration + E2E
|
||||
- **PRD-004** — Drag, resize, lock, duplicate, hide and remove widgets — tasks: `M3-05;M3-11` — verification: Playwright + accessibility
|
||||
- **PRD-005** — Per-viewport desktop/tablet/mobile/wallboard layouts — tasks: `M3-07;M9-03;M9-04` — verification: E2E + visual
|
||||
- **PRD-006** — Undo/redo, atomic save and conflict recovery — tasks: `M3-08;M3-11` — verification: Unit + integration + E2E
|
||||
- **PRD-007** — Dashboard variables and cross-filtering — tasks: `M3-09;M3-11` — verification: E2E
|
||||
- **PRD-008** — Validated dashboard import/export/templates — tasks: `M3-10;M3-11` — verification: Schema/security/E2E
|
||||
- **PRD-009** — Semantic bounded metrics query layer — tasks: `M4-01;M4-02;M4-03;M4-04` — verification: Unit + contract + load
|
||||
- **PRD-010** — Live charts use bounded efficient subscriptions — tasks: `M4-06;M4-07;M4-08;M4-09;M4-12` — verification: Protocol + load + soak
|
||||
- **PRD-011** — Host compute/memory/network monitoring — tasks: `M5-01;M5-07;M5-09` — verification: Contract + E2E
|
||||
- **PRD-012** — Optional sensors/GPU degrade gracefully — tasks: `M5-02;M5-09` — verification: Capability tests
|
||||
- **PRD-013** — Read-only bounded process explorer — tasks: `M5-03;M5-09` — verification: Security + UI
|
||||
- **PRD-014** — Container inventory/resource/health monitoring — tasks: `M5-04;M5-05;M5-07;M5-09` — verification: Scale + E2E
|
||||
- **PRD-015** — Application grouping independent of container running — tasks: `M5-06;M5-08;M7-05` — verification: Scenario + E2E
|
||||
- **PRD-016** — Array/parity monitoring without controls — tasks: `M6-01;M6-09` — verification: Scenario + architecture test
|
||||
- **PRD-017** — Disk capacity, temperature, performance and SMART — tasks: `M6-02;M6-03;M6-04;M6-09` — verification: Fixtures + E2E
|
||||
- **PRD-018** — Pool/filesystem/scrub monitoring — tasks: `M6-05;M6-09` — verification: Fixtures + contract
|
||||
- **PRD-019** — Shares and capacity forecasting — tasks: `M6-06;M6-08;M6-10` — verification: Unit + performance + UI
|
||||
- **PRD-020** — Service probes and availability/latency — tasks: `M7-01;M7-03;M7-04;M7-05;M7-06` — verification: Security + load + E2E
|
||||
- **PRD-021** — Probe SSRF and target safety — tasks: `M7-02;M7-11;M9-07` — verification: Negative security tests
|
||||
- **PRD-022** — Dependencies and topology with confidence — tasks: `M7-07;M7-08;M7-11` — verification: Unit + UI
|
||||
- **PRD-023** — Network/DNS/gateway/TLS health are distinct — tasks: `M7-09;M7-11` — verification: Scenarios + E2E
|
||||
- **PRD-024** — Alert state lifecycle and persistence — tasks: `M8-01;M8-02;M8-03;M8-04;M8-11` — verification: State machine + restart
|
||||
- **PRD-025** — Alert grouping, suppression, silence and maintenance — tasks: `M8-05;M8-06;M8-11` — verification: Storm scenarios + E2E
|
||||
- **PRD-026** — Acknowledgement and audit — tasks: `M8-07;M8-12` — verification: RBAC + concurrency
|
||||
- **PRD-027** — Notification delivery is idempotent and audited — tasks: `M8-08;M8-11` — verification: Integration + restart
|
||||
- **PRD-028** — Incidents group related alerts with rationale/confidence — tasks: `M8-09;M8-10;M8-11` — verification: Scenario + E2E
|
||||
- **PRD-029** — Authentik OIDC and RBAC — tasks: `M1-06;M9-07;M9-12` — verification: Auth matrix + production smoke
|
||||
- **PRD-030** — Pulse v1 has no host/Docker/storage mutation path — tasks: `M0-06;M1-08;M5-09;M6-09;M9-07` — verification: Architecture/security scan
|
||||
- **PRD-031** — Backup, restore, upgrade and rollback — tasks: `M9-09;M9-10;M9-13` — verification: Clean restore + migration
|
||||
- **PRD-032** — Clean-room build and deployment — tasks: `M9-11;M9-12;M9-13` — verification: Clean checkout + production smoke
|
||||
- **PRD-033** — Dutch default UI and accessible core workflows — tasks: `M1-03;M9-02;M9-05` — verification: Localization + axe + keyboard
|
||||
- **PRD-034** — Mobile and wallboard are first-class — tasks: `M3-07;M9-03;M9-04;M9-06` — verification: E2E + 24h soak
|
||||
- **PRD-035** — Pulse self-observability and independent failure detection — tasks: `M9-08;M9-13` — verification: System status + external smoke
|
||||
- **NFR-001** — Target scale 150 containers, 40 disks, 300 probes — tasks: `M2-10;M5-09;M6-10;M7-11;M9-06` — verification: Load/scale
|
||||
- **NFR-002** — No unbounded browser/server resource growth — tasks: `M4-12;M9-06` — verification: Load + 24h soak
|
||||
- **NFR-003** — Secrets absent from repo/logs/evidence/images — tasks: `M1-05;M1-07;M9-07;M9-09` — verification: Secret scans
|
||||
- **NFR-004** — Non-root least-privilege container deployment — tasks: `M1-08;M9-07;M9-12` — verification: Compose/image inspection
|
||||
- **NFR-005** — Requirement-to-test-to-evidence traceability — tasks: `M0-08;M1-10;M2-10;M3-11;M4-12;M5-10;M6-10;M7-11;M8-12;M9-13` — verification: Evidence indexes + final matrix
|
||||
@@ -0,0 +1,83 @@
|
||||
# Service and network monitoring requirements
|
||||
|
||||
## Service model
|
||||
|
||||
A service represents a reachable capability independently of container state.
|
||||
|
||||
Types:
|
||||
- HTTP/HTTPS;
|
||||
- TCP;
|
||||
- DNS;
|
||||
- ICMP where permitted;
|
||||
- TLS certificate;
|
||||
- JSON response;
|
||||
- keyword/content assertion.
|
||||
|
||||
A service belongs to an application/entity and may declare dependencies.
|
||||
|
||||
## Probe configuration
|
||||
|
||||
- target URL/host/port;
|
||||
- interval and timeout;
|
||||
- expected status codes;
|
||||
- redirect policy;
|
||||
- TLS verification;
|
||||
- optional JSONPath/keyword assertion;
|
||||
- allowed source/agent;
|
||||
- maintenance schedule;
|
||||
- labels/category;
|
||||
- secret reference for authenticated probes.
|
||||
|
||||
Never store plaintext probe credentials in database exports or evidence.
|
||||
|
||||
## SSRF and target safety
|
||||
|
||||
The probe engine must:
|
||||
- validate scheme and port;
|
||||
- resolve and re-check DNS;
|
||||
- block link-local, metadata and unspecified addresses;
|
||||
- apply an explicit network/target allowlist;
|
||||
- prevent redirect escape to disallowed targets;
|
||||
- limit response size;
|
||||
- avoid executing returned content;
|
||||
- restrict custom headers and methods;
|
||||
- log redacted destinations.
|
||||
|
||||
LAN/private targets may be intentionally allowed through administrator configuration.
|
||||
|
||||
## Results
|
||||
|
||||
Store/derive:
|
||||
- current state;
|
||||
- response time;
|
||||
- status/error class;
|
||||
- availability windows;
|
||||
- last success/failure;
|
||||
- incident history;
|
||||
- TLS expiry/issuer/hostname validity;
|
||||
- DNS resolution timing when relevant.
|
||||
|
||||
## Network
|
||||
|
||||
Monitor:
|
||||
- interface throughput;
|
||||
- packet errors/drops;
|
||||
- gateway reachability;
|
||||
- DNS latency/failure;
|
||||
- internet reachability using configured targets;
|
||||
- internal service dependency failures;
|
||||
- certificate expiry.
|
||||
|
||||
Avoid conflating internet failure with server failure. Dependency suppression should group downstream service alerts.
|
||||
|
||||
## Topology
|
||||
|
||||
Relationships may come from:
|
||||
- container labels;
|
||||
- compose project;
|
||||
- reverse proxy connector;
|
||||
- service configuration;
|
||||
- observed dependency declarations;
|
||||
- user confirmation.
|
||||
|
||||
Source/confidence must be retained. Inferred edges are visibly different from confirmed edges.
|
||||
@@ -0,0 +1,95 @@
|
||||
# Storage monitoring requirements
|
||||
|
||||
Storage is a first-class domain with strict read-only behavior.
|
||||
|
||||
## Array
|
||||
|
||||
Display:
|
||||
- current array state;
|
||||
- parity presence/state;
|
||||
- data disk membership;
|
||||
- missing/disabled/emulated disks;
|
||||
- read/write activity;
|
||||
- parity check state, progress, speed, errors and history;
|
||||
- last/next check when available.
|
||||
|
||||
No start/stop/check/correct action is offered in v1.
|
||||
|
||||
## Disks
|
||||
|
||||
For every disk:
|
||||
- stable identity and role;
|
||||
- model/serial with privacy-aware display;
|
||||
- size and filesystem;
|
||||
- used/free/inodes;
|
||||
- temperature and trend;
|
||||
- read/write throughput, IOPS and latency when available;
|
||||
- spin state when available;
|
||||
- SMART overall and selected attributes;
|
||||
- self-test age/result;
|
||||
- reallocated, pending and offline-uncorrectable sectors;
|
||||
- CRC/interface errors;
|
||||
- SSD wear/percentage used where relevant.
|
||||
|
||||
Rules must avoid declaring a disk healthy when SMART data is unavailable/stale.
|
||||
|
||||
## Pools
|
||||
|
||||
Support cache and ZFS/Btrfs pool concepts discovered in the environment:
|
||||
|
||||
- members;
|
||||
- usable/used/free;
|
||||
- profile/redundancy;
|
||||
- degraded/faulted/offline member state;
|
||||
- scrub status/results;
|
||||
- filesystem errors;
|
||||
- write/read performance;
|
||||
- SSD wear;
|
||||
- mover-related signals when available.
|
||||
|
||||
Do not assume all pools use the same filesystem.
|
||||
|
||||
## Shares
|
||||
|
||||
- name and configured policy;
|
||||
- used size and growth;
|
||||
- participating storage;
|
||||
- cache/pool relationship;
|
||||
- recent growth;
|
||||
- forecast to thresholds;
|
||||
- unavailable/stale state.
|
||||
|
||||
Potentially expensive size calculation must be rate-limited/cached and optional.
|
||||
|
||||
## Forecasting
|
||||
|
||||
Capacity forecast:
|
||||
- uses configurable historical window;
|
||||
- reports method and confidence/uncertainty;
|
||||
- handles irregular bulk imports;
|
||||
- never presents a precise date without qualification;
|
||||
- can be disabled when insufficient history exists.
|
||||
|
||||
## Baseline alert classes
|
||||
|
||||
- array degraded/missing disk;
|
||||
- parity errors;
|
||||
- SMART critical attribute;
|
||||
- temperature sustained above policy;
|
||||
- pool degraded/faulted;
|
||||
- capacity thresholds;
|
||||
- read-only filesystem;
|
||||
- scrub/check errors;
|
||||
- stale storage data.
|
||||
|
||||
Availability, device health, capacity pressure and thermal pressure are separate
|
||||
signals. An online device can therefore be capacity-critical or thermally
|
||||
critical without being presented as offline, and a stale observation makes all
|
||||
current signal severities Unknown. Pulse uses the stable source device ID as
|
||||
the canonical physical identity. Repeated identical observations are
|
||||
idempotent; conflicting roles or facts for one physical ID fail closed instead
|
||||
of producing duplicate or contradictory topology nodes.
|
||||
|
||||
## Safety tests
|
||||
|
||||
Storage fault behavior is tested through fixtures/simulator or read-only captured data. Never trigger real SMART damage, pool degradation, disk removal or array operations.
|
||||
@@ -0,0 +1,308 @@
|
||||
# UX specification
|
||||
|
||||
## 1. Experience principles
|
||||
|
||||
- **Explain before exposing raw detail.**
|
||||
- **Dense, not cramped.**
|
||||
- **Live, not distracting.**
|
||||
- **Configurable, not chaotic.**
|
||||
- **Safe, not action-heavy.**
|
||||
- **Unknown is visible.**
|
||||
- **Desktop, mobile and wallboard are designed separately.**
|
||||
|
||||
## 2. Information architecture
|
||||
|
||||
```text
|
||||
Overview
|
||||
Dashboards
|
||||
|
||||
Infrastructure
|
||||
Host
|
||||
Hardware
|
||||
Storage
|
||||
Network
|
||||
UPS
|
||||
|
||||
Containers
|
||||
Applications
|
||||
Services
|
||||
|
||||
Alerts
|
||||
Incidents
|
||||
Events
|
||||
|
||||
Explore
|
||||
Metrics
|
||||
Compare
|
||||
History
|
||||
|
||||
Wallboards
|
||||
|
||||
Settings
|
||||
Data sources
|
||||
Discovery
|
||||
Alerting
|
||||
Notifications
|
||||
Retention
|
||||
Users & access
|
||||
Backups
|
||||
System
|
||||
```
|
||||
|
||||
Navigation may collapse responsively. Route names and labels are localized.
|
||||
|
||||
## 3. Global shell
|
||||
|
||||
### Header
|
||||
|
||||
- current server/environment;
|
||||
- global time range;
|
||||
- live/pause control;
|
||||
- refresh/freshness state;
|
||||
- active filters;
|
||||
- alert count;
|
||||
- user menu.
|
||||
|
||||
### Source freshness
|
||||
|
||||
A compact indicator exposes:
|
||||
|
||||
- healthy;
|
||||
- delayed;
|
||||
- stale;
|
||||
- unavailable.
|
||||
|
||||
Opening it lists each datasource and last successful sample.
|
||||
|
||||
### Global time control
|
||||
|
||||
Presets:
|
||||
|
||||
- Live;
|
||||
- 15 minutes;
|
||||
- 1 hour;
|
||||
- 6 hours;
|
||||
- 24 hours;
|
||||
- 7 days;
|
||||
- 30 days;
|
||||
- custom.
|
||||
|
||||
A widget may override the dashboard range, but the override is clearly indicated.
|
||||
|
||||
## 4. Overview
|
||||
|
||||
### Healthy state
|
||||
|
||||
Prioritize trends, capacity and service summary.
|
||||
|
||||
### Degraded state
|
||||
|
||||
A problem summary appears before normal cards:
|
||||
|
||||
```text
|
||||
Degraded
|
||||
Cachepool is 91% full.
|
||||
Plex restarted 4 times in 10 minutes.
|
||||
Prometheus storage metrics are 3 minutes stale.
|
||||
```
|
||||
|
||||
Each reason links to its entity and relevant timeframe.
|
||||
|
||||
### Layout
|
||||
|
||||
The system template must remain useful before any editing:
|
||||
|
||||
- status summary;
|
||||
- active incidents;
|
||||
- CPU/load;
|
||||
- memory;
|
||||
- array/pools;
|
||||
- network;
|
||||
- container/application state;
|
||||
- service matrix;
|
||||
- recent events.
|
||||
|
||||
## 5. Dashboard composer
|
||||
|
||||
### Modes
|
||||
|
||||
**View mode**
|
||||
- no drag handles;
|
||||
- widgets fixed;
|
||||
- normal chart interactions;
|
||||
- fast rendering.
|
||||
|
||||
**Edit mode**
|
||||
- visible grid and selection outlines;
|
||||
- drag/resize handles;
|
||||
- widget library;
|
||||
- undo/redo;
|
||||
- save/exit;
|
||||
- breakpoint preview.
|
||||
|
||||
Unsaved changes are clearly indicated. Navigation away prompts only when changes would be lost.
|
||||
|
||||
### Grid
|
||||
|
||||
Recommended logical columns:
|
||||
|
||||
- large desktop/wallboard: 24;
|
||||
- desktop: 18;
|
||||
- tablet: 8;
|
||||
- mobile: 1.
|
||||
|
||||
Widgets define minimum and preferred sizes. Collision handling and snapping are predictable.
|
||||
|
||||
### Widget configuration drawer
|
||||
|
||||
Tabs:
|
||||
|
||||
1. Data
|
||||
2. Visualization
|
||||
3. Thresholds
|
||||
4. Behavior
|
||||
5. Links
|
||||
6. Advanced
|
||||
|
||||
Changes preview live but persist only through the editor save transaction.
|
||||
|
||||
### Editing interactions
|
||||
|
||||
- keyboard move/resize alternative;
|
||||
- duplicate;
|
||||
- lock/unlock;
|
||||
- hide per viewport;
|
||||
- copy to another dashboard;
|
||||
- reset to template;
|
||||
- restore version;
|
||||
- inspect validation errors before save.
|
||||
|
||||
## 6. Entity pages
|
||||
|
||||
Common structure:
|
||||
|
||||
1. identity, status and reason;
|
||||
2. key values and freshness;
|
||||
3. primary charts;
|
||||
4. relationships/dependencies;
|
||||
5. events;
|
||||
6. alerts/incidents;
|
||||
7. technical metadata.
|
||||
|
||||
Deep technical payloads are collapsed by default.
|
||||
|
||||
## 7. Alerts and incidents
|
||||
|
||||
### Alert list
|
||||
|
||||
Supports filters for:
|
||||
- state;
|
||||
- severity;
|
||||
- entity;
|
||||
- source;
|
||||
- acknowledged;
|
||||
- maintenance;
|
||||
- time.
|
||||
|
||||
Each row shows:
|
||||
- concise rule name;
|
||||
- affected entity;
|
||||
- current value/reason;
|
||||
- duration;
|
||||
- state;
|
||||
- incident relationship.
|
||||
|
||||
### Incident page
|
||||
|
||||
- plain-language summary;
|
||||
- severity and lifecycle;
|
||||
- affected entities;
|
||||
- contributing alerts;
|
||||
- timeline;
|
||||
- selected charts;
|
||||
- acknowledgement/notes;
|
||||
- uncertain relationship labels;
|
||||
- external workflow link when configured.
|
||||
|
||||
## 8. Mobile
|
||||
|
||||
Primary mobile navigation:
|
||||
|
||||
- Overview;
|
||||
- Incidents;
|
||||
- Containers;
|
||||
- Storage;
|
||||
- Services;
|
||||
- More.
|
||||
|
||||
Mobile priorities:
|
||||
- global status;
|
||||
- active incident;
|
||||
- acknowledgement;
|
||||
- essential entity facts;
|
||||
- readable charts with reduced series;
|
||||
- touch-sized controls.
|
||||
|
||||
Dashboard editing on mobile:
|
||||
- reorder;
|
||||
- show/hide;
|
||||
- simple config;
|
||||
- no precision freeform grid placement.
|
||||
|
||||
## 9. Wallboard
|
||||
|
||||
- fullscreen;
|
||||
- no standard navigation;
|
||||
- large readable status;
|
||||
- page rotation;
|
||||
- reconnect indicator;
|
||||
- last update/freshness;
|
||||
- optional kiosk-safe token/session;
|
||||
- no edit controls;
|
||||
- subtle movement strategy to reduce static burn-in risk;
|
||||
- survives days without reload.
|
||||
|
||||
## 10. Loading, empty and failure states
|
||||
|
||||
Every data surface defines:
|
||||
|
||||
- initial loading;
|
||||
- incremental live update;
|
||||
- empty because no entities exist;
|
||||
- empty because filters exclude all;
|
||||
- stale;
|
||||
- unavailable;
|
||||
- unauthorized;
|
||||
- query limit exceeded;
|
||||
- partial data.
|
||||
|
||||
Skeletons must not imply exact values. Previous values may remain visible only with an explicit stale age.
|
||||
|
||||
## 11. Copy
|
||||
|
||||
Default user-facing copy is natural Dutch:
|
||||
|
||||
Good:
|
||||
- `Geen recente gegevens`
|
||||
- `Container herstart herhaaldelijk`
|
||||
- `Cachepool bijna vol`
|
||||
- `Laatst succesvol bijgewerkt om 13:42`
|
||||
|
||||
Avoid:
|
||||
- raw metric names;
|
||||
- unexplained `NaN`;
|
||||
- only `Error 500`;
|
||||
- invented root-cause certainty;
|
||||
- alarmist language for attention-level conditions.
|
||||
|
||||
## 12. Accessibility
|
||||
|
||||
- WCAG 2.2 AA target for core workflows.
|
||||
- Full keyboard navigation.
|
||||
- Visible focus.
|
||||
- Text/icon plus color for status.
|
||||
- Reduced-motion support.
|
||||
- Charts have accessible summaries/table alternatives.
|
||||
- Drag interactions have non-pointer alternatives.
|
||||
- Contrast is validated in all themes/states.
|
||||
- Live regions announce important state changes without constant noise.
|
||||
@@ -0,0 +1,179 @@
|
||||
# Widget catalog
|
||||
|
||||
Every widget implements a common contract:
|
||||
|
||||
- identity and type;
|
||||
- data query;
|
||||
- transformations;
|
||||
- visualization settings;
|
||||
- thresholds/status mapping;
|
||||
- behavior and links;
|
||||
- layout per breakpoint;
|
||||
- loading/empty/error/stale states;
|
||||
- permission requirements;
|
||||
- export capability.
|
||||
|
||||
## 1. Stat card
|
||||
|
||||
Use for one current value.
|
||||
|
||||
Features:
|
||||
- label and value;
|
||||
- unit/format;
|
||||
- state;
|
||||
- sparkline;
|
||||
- trend against prior period;
|
||||
- min/max/average tooltip;
|
||||
- freshness.
|
||||
|
||||
Examples: CPU, RAM, uptime, active containers, free capacity.
|
||||
|
||||
## 2. Time series
|
||||
|
||||
Features:
|
||||
- one or more bounded series;
|
||||
- line/area;
|
||||
- hover crosshair;
|
||||
- zoom/pan;
|
||||
- pause/live;
|
||||
- event annotations;
|
||||
- min/max/average;
|
||||
- legend and series toggles;
|
||||
- downsampling;
|
||||
- compare period;
|
||||
- export.
|
||||
|
||||
## 3. Gauge
|
||||
|
||||
Use only where a meaningful min/max and thresholds exist.
|
||||
|
||||
Examples:
|
||||
- capacity;
|
||||
- temperature;
|
||||
- UPS charge;
|
||||
- memory limit.
|
||||
|
||||
Avoid gauges for values with no stable range.
|
||||
|
||||
## 4. Ranked list
|
||||
|
||||
- top/bottom N;
|
||||
- current value;
|
||||
- mini trend;
|
||||
- click-to-filter;
|
||||
- deterministic ID/label tie handling;
|
||||
- tie handling;
|
||||
- "other" aggregation where appropriate.
|
||||
|
||||
Examples: top container CPU, disk latency, service response time.
|
||||
|
||||
## 5. Status grid
|
||||
|
||||
The status grid renders bounded text/icon states and supports keyboard click-to-filter for the selected entity.
|
||||
|
||||
Compact tiles for many entities.
|
||||
|
||||
Required:
|
||||
- status icon/text;
|
||||
- entity name;
|
||||
- optional key value;
|
||||
- age/freshness;
|
||||
- grouping and filtering;
|
||||
- accessible list alternative.
|
||||
|
||||
## 6. Table
|
||||
|
||||
- server-side pagination/filtering where large;
|
||||
- sort and column selector;
|
||||
- pinned identifying columns;
|
||||
- export;
|
||||
- row drill-down;
|
||||
- virtualized rendering;
|
||||
- explicit stale fields.
|
||||
|
||||
## 7. Heatmap
|
||||
|
||||
Examples:
|
||||
- CPU by hour/day;
|
||||
- disk temperature history;
|
||||
- service latency distribution.
|
||||
|
||||
Must provide a textual/table summary.
|
||||
|
||||
## 8. Event timeline
|
||||
|
||||
- chronological events;
|
||||
- severity/type filters;
|
||||
- entity grouping;
|
||||
- chart annotation synchronization;
|
||||
- expandable attributes;
|
||||
- no secret/raw sensitive payloads.
|
||||
|
||||
## 9. Storage map
|
||||
|
||||
Visual model of:
|
||||
- parity;
|
||||
- array disks;
|
||||
- pools;
|
||||
- members;
|
||||
- filesystems;
|
||||
- capacity;
|
||||
- temperature;
|
||||
- SMART state.
|
||||
|
||||
It must remain usable without relying on physical slot colors alone.
|
||||
|
||||
## 10. Topology
|
||||
|
||||
Nodes:
|
||||
- applications;
|
||||
- containers;
|
||||
- services;
|
||||
- endpoints;
|
||||
- dependencies;
|
||||
- reverse proxy;
|
||||
- database/storage.
|
||||
|
||||
Edges may show status, latency or traffic when reliable. Unknown relationships are visually distinct from discovered/confirmed ones.
|
||||
|
||||
## 11. Service matrix
|
||||
|
||||
For endpoints/services:
|
||||
- status;
|
||||
- latency;
|
||||
- uptime percentage;
|
||||
- last incident;
|
||||
- TLS expiry;
|
||||
- maintenance.
|
||||
|
||||
## 12. Alert/incident summary
|
||||
|
||||
- active counts by severity/state;
|
||||
- newest/highest priority;
|
||||
- acknowledgement state;
|
||||
- drill-down;
|
||||
- no hidden critical item due to pagination.
|
||||
|
||||
## 13. Text/annotation
|
||||
|
||||
Markdown subset with sanitization.
|
||||
|
||||
Use for:
|
||||
- dashboard instructions;
|
||||
- maintenance note;
|
||||
- runbook link;
|
||||
- scope explanation.
|
||||
|
||||
No arbitrary script/HTML.
|
||||
|
||||
## 14. Query inspector
|
||||
|
||||
Advanced and permission-controlled:
|
||||
- semantic query;
|
||||
- generated PromQL;
|
||||
- execution timing;
|
||||
- returned series/points;
|
||||
- limits applied;
|
||||
- copy for troubleshooting.
|
||||
|
||||
It is not enabled as an unrestricted public query console.
|
||||
Reference in New Issue
Block a user