Files
felhom.eu/REPORT.md
T
admin 30380a59f4 hub v0.15.0: Phase 2 managed updates — per-customer controller-version floor
Operator sets a minimum controller version (FLOOR), per-customer defaulting to a
global floor; the report ACK returns the effective floor + latest_version so the
controller auto-updates to the floor when below it (latest stays the opt-in button).

- store: min_controller_version column + hub_settings global floor + Effective/
  Get/SetGlobal/SetMin resolution + config/env DEFAULT_MIN_CONTROLLER_VERSION
- handler: report ACK {min_controller_version, latest_version}; LatestVersionProvider
- web: global floor editor + per-customer override form + Floor column (English)
- tests: floor resolution + ACK + render; override-precedence red-proof verified

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FSZmmSFVzGwEzhYmxbkgBK
2026-06-27 11:59:30 +02:00

47 lines
3.0 KiB
Markdown

# felhom.eu — task reports
> **Overwrite** this file with a summary of the most recent task only (uniform with the other repos; not cumulative). The cumulative hub history lives in [hub/CHANGELOG.md](hub/CHANGELOG.md).
## hub v0.15.0 — Phase 2 managed updates: per-customer controller-version floor (2026-06-27)
**Why.** Phase 1 gave enthusiasts an opt-in "update to latest" button. Phase 2 adds the managed
default: the operator sets a per-customer **minimum controller version** (defaulting to a global floor),
and any box below it **auto-updates** on its next report — so the household that never clicks stays
current and patched. Floor = the operator's enforced minimum and the auto-target; latest stays the
customer's manual opt-in.
### Files changed
- `internal/store/store.go``customer_configs.min_controller_version` column; `hub_settings` KV table;
`defaultMinControllerVersion` + `SetDefaultMinControllerVersion`; `Get/SetGlobalMinControllerVersion`,
`SetMinControllerVersion`, `EffectiveMinControllerVersion`.
- `internal/api/handler.go``LatestVersionProvider` interface + `SetLatestVersionProvider`; report ACK
returns `{min_controller_version, latest_version}` (both omitted when empty).
- `internal/web/configs.go`, `server.go`, `templates/configs.html`, `templates/customer_unified.html`
operator UI: global floor editor + per-customer override form + Floor column / below-floor markers;
routes `POST /configs/global-floor`, `POST /customers/{id}/floor`.
- `cmd/hub/main.go``Config.ControllerUpdates.DefaultMinVersion` (yaml `default_min_version`, env
`DEFAULT_MIN_CONTROLLER_VERSION`); seeds the store default; wires the version checker as latest provider.
### Design
- Effective floor = per-customer override if non-empty, else global (hub_settings → config/env default),
else "" (Phase 2 inert for that customer).
- Rides the **existing report cycle** — no new floor-polling endpoint. The actual swap is the
controller's Phase 1 flow (in-guest pull → agent `POST /controller/swap` → rollback); the hub only
advertises the floor. **No agent change.**
### Tests (`go test ./...` green)
- `internal/store/floor_test.go` — empty-when-unset; global-default fallback; DB-overrides-default;
**override-beats-global (companion red-proof)**; set-and-preserve-across-save.
- `internal/api/floor_ack_test.go` — ACK carries effective floor (override beats global) + latest; omits
both when unset.
- `internal/web/render_test.go` — template render smoke (catches `template.Must` panics + floor fields).
- **Companion red-proof (verified):** making `EffectiveMinControllerVersion` ignore the override →
`TestEffectiveFloor_OverrideBeatsGlobal` AND `TestReportACK_FloorAndLatest` FAIL → restored → green.
### Green gate
`go build ./... && go vet ./... && go test ./...` → all pass.
### Deploy
Built + pushed `gitea.dooplex.hu/admin/felhom-hub:0.15.0`, manifest bumped + synced (see hub/CHANGELOG
and the live-test summary in felhom-controller/REPORT.md for the end-to-end floor auto-update result).