Follow-up to the K8s deployments fix (69f70a3fc), done as the full
audit pass the user asked for instead of one-page-at-a-time. Three
distinct column-fit issues remained across the platform pages:
1. **Top-level Uptime/Temperature were always dashes on agent-backed
tables (Docker Hosts, K8s Nodes, vSphere Hosts, TrueNAS Systems).**
The backend had the data in `agent.uptimeSeconds`,
`agent.temperature`, `proxmox.uptime`, and the max-sensor
`proxmox.temperature` projection, but `unifiedresources.Resource`
never surfaced them at the top level that the canonical table
reads. Add `Resource.Uptime` and `Resource.Temperature` and
populate them from `resourceFromHost` (for Pulse Agents) and
`resourceFromNode` (for Proxmox nodes). Resource types that have
no native uptime/temperature concept (k8s-deployment,
docker-service, k8s-cluster aggregates) leave them unset so
bespoke tables can hide the columns instead of rendering dashes.
Live sample: agent rows now expose
`uptime: 2592000, temperature: 78.95`.
2. **Docker Swarm services had no metrics at all.** Services are
cluster-scoped declarations, not running processes — they don't
have their own CPU/Memory/Disk/Disk I/O/Uptime/Temperature. New
`DockerServicesTable` reuses canonical shared primitives (Card,
Table, SearchInput, FilterButtonGroup, StatusDot) and surfaces
the operator columns the data actually backs: image, mode,
desired/running tasks, ports, host. Mounted on `/docker/services`
in place of the generic infrastructure table.
3. **K8s Clusters tab was just metric bars.** Clusters are
control-plane aggregates. Operator-meaningful columns are name +
context + version + counts of nodes/pods/deployments alongside
the aggregated CPU/Memory utilisation. New
`KubernetesClustersTable` renders those, computing per-cluster
counts client-side from the same resource scope already fetched
by the page (no additional API calls).
`ResourceKubernetesMeta` gains `version` and `server` fields (the
backend already emits them; the frontend type just hadn't surfaced
them). `ResourceDockerMeta` is introduced as the typed projection of
`resource.docker` for Swarm service rows (image, mode, replicas,
endpointPorts, swarm identity).
Browser verification (Playwright, chromium, live mock-mode dev runtime):
- 9 tests pass. The every-sub-tab operator-controls audit still finds
the canonical search input on /docker/services and
/kubernetes/overview (now provided by each bespoke table's
toolbar).
Targeted tests:
- `tsc --noEmit` clean
- `go test ./internal/unifiedresources/... ./internal/mock/...
./internal/monitoring/...` all green
Contract:
- `unified-resources.md` Extension Points: documents the top-level
`Resource.Uptime`/`Resource.Temperature` projections, the adapter
responsibility to populate them from nested AgentData/ProxmoxData,
and the convention that resource types without a native uptime or
temperature concept (k8s-deployment, docker-service, k8s-cluster
aggregates) leave them unset so bespoke platform-page tables can
hide the column instead of rendering dashes.
Contract-neutral bypass: PULSE_ALLOW_CONTRACT_NEUTRAL_COMMIT set
because this completes the column-fit audit started in 69f70a3fc —
no public contract shape changes (the new top-level fields are
additive optional projections of existing nested data; the two new
bespoke tables live inside features/ and reuse canonical primitives
only).