Skip to content

feat(release): v1.65.0 - PoH rollover detection, dashboard density controls, settings fix - #629

Merged
Starosdev merged 57 commits into
masterfrom
beta
Jun 29, 2026
Merged

Starosdev merged 57 commits into
masterfrom
beta

Conversation

@Starosdev

@Starosdev Starosdev commented Jun 27, 2026 •

Copy link
Copy Markdown
Owner

Summary

Promotes the 1.65.0 beta line to master (1.64.0 -> 1.65.0). Scope below is limited to changes that are actually new versus master; features merged to master earlier (per-URL heartbeat, navigation visibility, host grouping, ATA self-test history, contextual help) are already shipped and are NOT part of this delta.

Features

Fixes

  • Preserve server-capability flags on settings save: server_version and collector_trigger_enabled were dropped from the POST /api/settings response, so the "Run collectors" button vanished after any settings change. Backend now echoes both flags (shared collectorTriggerEnabled() helper); frontend config setter preserves them with a current-value fallback. Adds handler regression tests.

Refactors (cognitive complexity)

Database / Upgrade Notes

  • One new migration vs master: m20260617000000 - inserts dashboard_columns=2 and dashboard_density=comfortable settings. Additive, idempotent, auto-runs on startup.
  • No scrutiny.yaml / collector.yaml schema changes. No API route changes (hub/spoke collectors stay compatible).
  • No manual user action required for 1.64.0 -> 1.65.0.

Test plan

  • go build ./... clean
  • go vet ./webapp/backend/... ./collector/... clean
  • Backend + collector tests pass (30 pkgs, 0 fail); web package fresh -count=1 pass
  • npm run lint all pass
  • npm run build:prod succeeds (warnings only: pre-existing scss budget + CommonJS bailouts)
  • Beta Docker + Publish Beta CI green on HEAD
  • Settings fix verified live on beta-omnibus (zeus dev)

dependabot Bot and others added 30 commits May 18, 2026 03:08
Bumps [@angular-eslint/schematics](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/schematics) from 21.3.1 to 21.4.0.
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/main/packages/schematics/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v21.4.0/packages/schematics)

---
updated-dependencies:
- dependency-name: "@angular-eslint/schematics"
  dependency-version: 21.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [ng-apexcharts](https://github.com/apexcharts/ng-apexcharts) from 2.3.0 to 2.4.0.
- [Release notes](https://github.com/apexcharts/ng-apexcharts/releases)
- [Changelog](https://github.com/apexcharts/ng-apexcharts/blob/master/CHANGELOG.md)
- [Commits](https://github.com/apexcharts/ng-apexcharts/commits/v2.4.0)

---
updated-dependencies:
- dependency-name: ng-apexcharts
  dependency-version: 2.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 4.2.5 to 5.5.5.
- [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/main/CHANGELOG.md)
- [Commits](prettier/eslint-plugin-prettier@v4.2.5...v5.5.5)

---
updated-dependencies:
- dependency-name: eslint-plugin-prettier
  dependency-version: 5.5.5
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [github.com/go-gormigrate/gormigrate/v2](https://github.com/go-gormigrate/gormigrate) from 2.1.5 to 2.1.6.
- [Release notes](https://github.com/go-gormigrate/gormigrate/releases)
- [Changelog](https://github.com/go-gormigrate/gormigrate/blob/master/CHANGELOG.md)
- [Commits](go-gormigrate/gormigrate@v2.1.5...v2.1.6)

---
updated-dependencies:
- dependency-name: github.com/go-gormigrate/gormigrate/v2
  dependency-version: 2.1.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [github.com/nicholas-fedor/shoutrrr](https://github.com/nicholas-fedor/shoutrrr) from 0.14.3 to 0.16.0.
- [Release notes](https://github.com/nicholas-fedor/shoutrrr/releases)
- [Changelog](https://github.com/nicholas-fedor/shoutrrr/blob/main/CHANGELOG.md)
- [Commits](nicholas-fedor/shoutrrr@v0.14.3...v0.16.0)

---
updated-dependencies:
- dependency-name: github.com/nicholas-fedor/shoutrrr
  dependency-version: 0.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
…3 updates

Bumps the dev-dependencies group with 3 updates in the /webapp/frontend directory: [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin), [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) and [apexcharts](https://github.com/apexcharts/apexcharts.js).


Updates `@typescript-eslint/eslint-plugin` from 8.59.2 to 8.60.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.60.1/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.59.2 to 8.60.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.60.1/packages/parser)

Updates `apexcharts` from 5.11.0 to 5.14.0
- [Release notes](https://github.com/apexcharts/apexcharts.js/releases)
- [Commits](apexcharts/apexcharts.js@v5.11.0...v5.14.0)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.60.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.60.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
- dependency-name: apexcharts
  dependency-version: 5.14.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Add heartbeatEnabled to NotifyUrlEntry interface, update NotifyUrlService
to map heartbeat_enabled from the API and send it on create/PATCH, and
surface a mat-slide-toggle in the notify-URLs table and add-URL form.
Add HelpLinkIconComponent — a standalone icon-button anchor — and wire it into
the Notification Channels expansion panel title. Also add an inline "Learn more"
link to the Consumer Drive Profiles field hint pointing to CONSUMER_DRIVE_PROFILES.md.
…orkload (#588)

Adds four boolean settings (navigation.show_zfs_pools, show_mdadm, show_btrfs,
show_workload) to hide unused nav links. Configurable via settings UI, scrutiny.yaml,
or env vars (SCRUTINY_WEB_NAVIGATION_SHOW_*). Defaults to true (all visible).
MDADM arrays and Workload devices now render in sections grouped by
host_id, matching the existing ZFS Pools and SMART dashboard pattern.

- Add host_id field to MDADM array across the full stack: collector
  model, backend DB model (migration m20260610000000), registration
  handler, summary API response, and frontend TS model
- Populate host_id from collector config host.id during array detection
- MDADM component builds hostGroups map and renders per-host card grids
  with h3 host headers; header hidden when host_id is empty
- Workload component builds per-host MatTableDataSource instances,
  wires @ViewChildren(MatSort) per group; both desktop table and mobile
  card views render host sections
…github.com/go-gormigrate/gormigrate/v2-2.1.6

chore(deps): bump github.com/go-gormigrate/gormigrate/v2 from 2.1.5 to 2.1.6
…github.com/nicholas-fedor/shoutrrr-0.16.0

chore(deps): bump github.com/nicholas-fedor/shoutrrr from 0.14.3 to 0.16.0
…/frontend/develop/angular-eslint/schematics-21.4.0

chore(deps): bump @angular-eslint/schematics from 21.3.1 to 21.4.0 in /webapp/frontend
…/frontend/develop/ng-apexcharts-2.4.0

chore(deps): bump ng-apexcharts from 2.3.0 to 2.4.0 in /webapp/frontend
…/frontend/develop/eslint-plugin-prettier-5.5.5

chore(deps): bump eslint-plugin-prettier from 4.2.5 to 5.5.5 in /webapp/frontend
…/frontend/develop/dev-dependencies-72597602f0

chore(deps): bump the dev-dependencies group across 1 directory with 3 updates
Starosdev and others added 21 commits June 17, 2026 20:35
# Conflicts:
#	webapp/backend/pkg/database/scrutiny_repository_device_self_tests.go
#	webapp/backend/pkg/database/scrutiny_repository_device_self_tests_test.go
#	webapp/backend/pkg/database/scrutiny_repository_device_smart_attributes.go
#	webapp/backend/pkg/database/scrutiny_repository_migrations.go
#	webapp/backend/pkg/models/collector/smart.go
#	webapp/backend/pkg/models/device_selftests.go
When merging master into beta/develop hits conflicts, open a sync PR for
manual resolution instead of exiting non-zero. Decouple develop sync from
beta outcome via if: always().
## Summary

Reduces SonarQube cognitive complexity (go:S3776) across all 10 flagged
functions in `webapp/backend/pkg/models/measurements/smart.go`. The
functions ranged from complexity 17 to 43; all now sit at or below the
allowed limit of 15.

## Why

The file had heavy duplication: a near-identical override-application
block (ShouldIgnore / forced status / custom thresholds) was copy-pasted
across 7 SMART processing functions. This drove up cognitive complexity
and made the logic error-prone to change in one place but not another.

## Changes

Extracted shared helpers, collapsing the repeated logic:

- `applyOverrideResult` — applies an override `Result` to an attribute's
status/reason fields, returning `(ignored, forcedFailure)`
- `isTransientAtaAttribute` — ATA transient-failure config lookup
- `newAttributeForProtocol` / `inflateInfluxAttribute` — InfluxDB
attribute grouping by protocol
- `parseInt64Field` / `coerceInt64` — typed InfluxDB scalar field
parsing
- `suppressDeltaIfUnchanged` — per-attribute delta-evaluation
suppression
- `buildFarmAttributeValues` — Seagate FARM page flattening

Net **-91 lines**. Behavior is unchanged.

## Verification

- [x] `go build ./webapp/backend/...`
- [x] `go vet ./webapp/backend/pkg/models/measurements/...`
- [x] `go test ./webapp/backend/pkg/models/measurements/...` (39 tests
pass)
- [x] `gocognit -over 15` reports zero functions over the limit
- [x] `gofmt` clean

## Notes

This is the first slice of SonarQube Group 5 (cognitive complexity).
Remaining clusters (DB migrations, notify, repository, collector
commands, detect) will follow in separate PRs.
#617)

## Summary

Reduces SonarQube cognitive complexity (go:S3776) in `main()` across all
five collector command entrypoints. They ranged from complexity 17 to
47; all functions now sit at or below the allowed limit of 15.

| Command | Before | After |
|---------|--------|-------|
| collector-performance | 47 | ≤15 |
| collector-filesystem | 45 | ≤15 |
| collector-btrfs | 45 | ≤15 |
| collector-zfs | 17 | ≤15 |
| collector-mdadm | 17 | ≤15 |

## Why

Each `main()` inlined the entire cli "run" action closure plus
config-path resolution and per-flag overrides, concentrating all
branching in one giant function.

## Changes

- **btrfs / filesystem / performance** — extract `resolveConfigPath`,
`applyRunFlags`, `logRedactedSettings`, and `runCollectorAction`
helpers, mirroring the structure zfs/mdadm already used
- **zfs / mdadm** — extract the inline action into `runCollectorAction`
(the other helpers already existed)
- collapse the empty `ConfigFileMissingError` branch (S108) in
btrfs/filesystem

Behavior unchanged. The performance collector keeps its extra `profile`
flag handling.

## Verification

- [x] `go build ./collector/cmd/...`
- [x] `go vet ./collector/cmd/...`
- [x] `go test ./collector/...` (all pass)
- [x] `gocognit -over 15` reports zero functions over the limit
- [x] `gofmt` clean

## Notes

Continuation of SonarQube Group 5 (cognitive complexity), after #616
(smart.go). Remaining clusters: notify, repository, DB migrations,
detect.
…#618)

## Summary

Reduces SonarQube cognitive complexity (go:S3776) across the notify
package. All flagged functions now sit at or below the allowed limit of
15.

| Function | File | Before | After |
|----------|------|--------|-------|
| ShouldNotify | notify.go | 58 | ≤15 |
| SendShoutrrrNotification | notify.go | 19 | ≤15 |
| SendSMTPNotification | smtp_sender.go | 30 | ≤15 |
| sendSMTPRecipient | smtp_sender.go | 16 | ≤15 |
| maskAppriseURL | mask.go | 24 | ≤15 |
| mockSMTPServer.serve | notify_test.go | 17 | ≤15 |

## Changes

Pure extraction of focused helpers; no behavior change.

- **notify.go** — `requiredNotifyStatuses`, `deviceProtocol`,
`isCriticalAttribute`, `collectFailingAttributes`,
`hasQualifyingFailure`; `appendQueryParam`, `joinSendErrors`
- **smtp_sender.go** — `buildSMTPConfig`, `negotiateSMTP`,
`resolveClientHost`, `startTLSIfSupported`, `smtpHeaders`,
`buildSMTPMessage`
- **mask.go** — `maskMailtoURL`, `maskTelegramURL`,
`maskURLPathSegments` (the discord/slack cases now share one
path-segment masker)
- **notify_test.go** — `handleSMTPData`

The `ShouldNotify` device-protocol detection was duplicated (override
lookup + critical check); it is now a single `deviceProtocol` helper.

## Verification

- [x] `go build ./webapp/backend/...`
- [x] `go vet ./webapp/backend/pkg/notify/...`
- [x] `go test ./webapp/backend/pkg/notify/...` (pass)
- [x] `gocognit -over 15` reports zero functions over the limit
- [x] `gofmt` clean

## Notes

Continuation of SonarQube Group 5 (cognitive complexity), after #616
(smart.go) and #617 (collector commands). Remaining clusters:
repository, DB migrations, detect.
## [1.65.0-beta.1](v1.64.0...v1.65.0-beta.1) (2026-06-20)

### Features

* **api:** expose and update heartbeat_enabled on notify URLs ([99bb242](99bb242))
* **heartbeat:** filter notify URLs by heartbeat_enabled ([24f359a](24f359a))
* **notify:** add heartbeat_enabled field to notify_urls ([6432a2c](6432a2c))
* **notify:** LoadHeartbeatDatabaseUrls filters by heartbeat_enabled ([51d8662](51d8662))
* **thresholds:** detect Power-On Hours 16-bit counter rollover ([#595](#595)) ([#625](#625)) ([390de8b](390de8b))
* **ui:** add contextual help links for settings docs ([#492](#492)) ([8ceb12b](8ceb12b))
* **ui:** add contextual help links pointing to docs folder ([#492](#492)) ([7b484a0](7b484a0))
* **ui:** add heartbeat toggle per notification URL ([e6bbfea](e6bbfea))
* **ui:** add navigation visibility settings for ZFS, MDADM, Btrfs, Workload ([#588](#588)) ([fca1ae3](fca1ae3))
* **ui:** group MDADM and Workload pages by host ([#579](#579)) ([3e3aa73](3e3aa73))

### Bug Fixes

* **api:** return 404 when heartbeat toggle targets non-existent notify URL ([8c375c2](8c375c2))
* **backend:** pass SmartInfo by pointer to syncDeviceSelfTests (hugeParam) ([e027c33](e027c33))
* **backend:** satisfy gocritic hugeParam and govet fieldalignment lint ([be05416](be05416))
* **db:** simplify migration func to satisfy unlambda linter ([8158a34](8158a34))
* **ui:** style learn more link in Consumer Drive Profiles hint ([#492](#492)) ([ba5b6c3](ba5b6c3))

### Refactoring

* **collector:** reduce cognitive complexity in collector commands ([#617](#617)) ([dedf386](dedf386)), closes [#616](#616)
* **collector:** reduce cognitive complexity in device detection ([#619](#619)) ([b2e5a9d](b2e5a9d))
* **database:** reduce cognitive complexity in repository ([#621](#621)) ([4990d88](4990d88))
* **database:** reduce cognitive complexity in the migration runner ([#624](#624)) ([037c82d](037c82d))
* **frontend:** reduce cognitive complexity in components ([#620](#620)) ([278cd44](278cd44))
* **measurements:** reduce cognitive complexity in smart.go ([#616](#616)) ([b82e0f5](b82e0f5))
* **models:** reduce cognitive complexity in measurement models ([#622](#622)) ([900e4c3](900e4c3))
* **notify:** reduce cognitive complexity in notification senders ([#618](#618)) ([249d836](249d836)), closes [#616](#616) [#617](#617)
* **web:** reduce cognitive complexity in middleware and monitors ([#623](#623)) ([8695dc8](8695dc8))
The POST /api/settings response only returned the saved settings, dropping
server_version and collector_trigger_enabled. The frontend config setter
overwrote those keys with undefined, so the 'Run collectors' button (gated
on collector_trigger_enabled) disappeared after any settings change.

Backend: save response now echoes server_version and collector_trigger_enabled,
matching GET. Extracted a shared collectorTriggerEnabled() helper.
Frontend: config setter preserves both flags, falling back to the current
config when a response omits them.

Adds handler tests asserting both GET and POST carry the capability flags.
@Starosdev Starosdev added the enhancement New feature or request label Jun 27, 2026
@Starosdev Starosdev changed the title feat(release): promote beta to master (v1.65.0) feat(release): v1.65.0 - PoH rollover detection, dashboard density controls, settings fix Jun 27, 2026
@Starosdev
Starosdev merged commit 2516ca1 into master Jun 29, 2026
30 of 36 checks passed
@Starosdev
Starosdev deleted the beta branch June 29, 2026 00:23
Starosdev pushed a commit that referenced this pull request Jun 29, 2026
## [1.65.0](v1.64.0...v1.65.0) (2026-06-29)

### Features

* **release:** v1.65.0 - PoH rollover detection, dashboard density controls, settings fix ([#629](#629)) ([2516ca1](2516ca1)), closes [#595](#595) [#625](#625) [#471](#471) [616-#624](https://github.com/Starosdev/616-/issues/624)
Starosdev added a commit that referenced this pull request Jun 29, 2026
## Summary

Hardens branch automation after `beta` was auto-deleted on the v1.65.0
release merge (#629), which broke the **Sync beta and develop** workflow
(`git checkout beta` -> `pathspec 'beta' did not match`, exit 1).

- **cleanup-branches**: add `beta` to `PROTECTED_BRANCHES` (`master
develop beta main`) so stale-branch cleanup never deletes the long-lived
release branch.
- **sync-develop**: when a sync target is missing on origin, recreate it
from `master` (already in sync) and exit cleanly, instead of failing the
checkout. Applies to both the beta and develop steps.
- Repo setting `delete_branch_on_merge` set to `false` via API to stop
the auto-delete recurring on release merges.

## Linked Issues

None.

## Test plan

- [x] `beta` recreated at master HEAD; beta and develop confirmed in
sync with master
- [x] YAML validated (`yaml.safe_load` both files)
- [x] `delete_branch_on_merge` confirmed `false` via API
- [ ] Next master merge auto-syncs beta + develop without failure
(verify on next release)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] Power an Hours rollover - cross check with head flying hours [FEAT] More columns

2 participants