feat(notifications): library health reaches admins, coalesced (#5341)
release / govulncheck (push) Successful in 18s
release / web (push) Successful in 1m22s
release / go (push) Successful in 1m43s
release / integration (push) Successful in 4m56s
release / android (push) Successful in 5m16s
release / Build signed APK (releases and dev) (push) Successful in 5m27s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 15s
release / Verify release artifacts (tag releases only) (push) Skipped

- A failed scan run sends scan_failed. Each failure adds to the count and
  the notice shows the latest error. A scan cut short by shutdown says
  nothing.
- Marking tracks missing sends tracks_missing with a running count.
- A duplicate sweep that proposes a group it had not proposed before
  sends duplicates_found, counting everything awaiting review. A sweep
  that only re-finds known groups stays quiet, so a read notice isn't
  repeated every sweep (CountDuplicateGroupsDetectedSince).
- A playback-error report sends playback_errors, counting the unresolved
  errors (CountUnresolvedPlaybackErrors).

The library package gets its notifier as a package-level SetNotifier
beside SetEventBus, for the same reason the bus is package-level.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-08 07:20:33 -04:00
co-authored by Claude Opus 5.5
parent 069baeb14d
commit 1e9408c835
13 changed files with 338 additions and 0 deletions
+26
View File
@@ -14,6 +14,7 @@ import (
"github.com/jackc/pgx/v5/pgxpool"
"git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq"
"git.fabledsword.com/bvandeusen/minstrel/internal/notifications"
syncpkg "git.fabledsword.com/bvandeusen/minstrel/internal/sync"
)
@@ -101,12 +102,37 @@ func runDuplicateSweep(
}
}
if runErr == nil {
notifyNewDuplicates(finishCtx, q, sweep.StartedAt, logger)
}
logger.Info("duplicate sweep complete",
"candidates", res.Candidates, "groups", res.Groups, "proposed", res.Proposed,
"suppressed", res.Suppressed, "retired", res.Retired, "oversize", res.Oversize, "err", runErr)
return res, runErr
}
// notifyNewDuplicates tells admins when a sweep proposed a group it had not
// proposed before (M489), counting every proposal awaiting review. A sweep
// that only re-finds known groups says nothing, so reading the notice once
// is enough until something new turns up.
func notifyNewDuplicates(ctx context.Context, q *dbq.Queries, sweepStarted pgtype.Timestamptz, logger *slog.Logger) {
fresh, err := q.CountDuplicateGroupsDetectedSince(ctx, sweepStarted)
if err != nil {
logger.Warn("duplicate sweep: counting new proposals failed", "err", err)
return
}
if fresh == 0 {
return
}
pending, err := q.CountPendingDuplicateGroups(ctx)
if err != nil {
logger.Warn("duplicate sweep: counting pending proposals failed", "err", err)
return
}
notifyAdmins(ctx, notifications.KindDuplicatesFound, notifications.Payload{Count: pending})
}
func sweepDuplicates(
ctx context.Context, q *dbq.Queries, sweepID pgtype.UUID, cfg FingerprintSettings, pageSize int32,
) (DuplicateSweepResult, error) {