Commit Graph

74 Commits

Author SHA1 Message Date
4d93218132 feat: complete Task 4 - verify and document live/remix filtering implementation 2026-08-05 17:23:17 +03:00
0dcc86015d feat: complete Task 3 - update web UI and handlers for Live/Remix filtering 2026-08-05 17:19:31 +03:00
a3b8aa8a74 feat: complete Task 2 - update filtering core logic for live/remix filtering 2026-08-05 17:08:31 +03:00
75326cda3a feat: complete Task 1 - update database schema and model for live/remix filtering 2026-08-05 17:03:40 +03:00
f49ad40002 move completed plan: 2026-07-27-verify-scanner-wiring.md 2026-07-30 20:19:55 +03:00
c2f3258186 feat: document and enhance scanner wiring verification - added filter flow documentation and code comments 2026-07-30 19:36:11 +03:00
827b5405e5 feat: verify wiring of ignore_singles/ignore_compilations toggles - completed Task 1 2026-07-30 18:33:10 +03:00
35b1f466ec feat: write unit tests for filtering logic 2026-07-27 23:21:50 +03:00
348d0648ba move completed plan: 2026-07-26-fix-scanner-wiring.md 2026-07-27 10:33:35 +03:00
e95f581c80 move completed plan: 2026-07-21-fix-review-findings.md 2026-07-26 13:06:04 +03:00
6e49f436c3 feat: update documentation to note filter centralization pattern completion 2026-07-26 13:05:14 +03:00
aec9d89435 feat: complete filter centralization pattern and document in CLAUDE.md 2026-07-26 13:03:37 +03:00
f697ebf2f5 feat: fix NotifyOnce map key to use composite ArtistID+RGID 2026-07-26 12:37:57 +03:00
395a7f9b07 feat: handle ErrArtistNotFound in ScanArtist gracefully by using empty TypeFilter 2026-07-26 11:36:32 +03:00
4b4e852fd1 feat: complete task 6 - fix stale notification pruning to avoid SQLite parameter limit 2026-07-26 11:24:40 +03:00
355a12c6a6 feat: complete task 4 - fix scanner diff.go TypeFilter.suppressed to use centralized filter 2026-07-25 23:12:09 +03:00
41e5e079d4 feat: complete task 3 - fix sync.go cache-hit path to use centralized filter 2026-07-25 23:06:56 +03:00
9e4d2385ff feat: complete task 2 - update FilterReleaseGroups to use centralized filter helper 2026-07-25 23:01:54 +03:00
aee0241bb7 fix: address code review findings
- Start Web UI before the blocking initial sync so the dashboard is
  reachable during the (rate-limited, potentially multi-minute) first
  sync; fold the immediate sync into startPeriodicSync's overlap guard
  so it can never race a concurrent tick over the shared DB / MB client.
- Make MarkNotificationSent idempotent: INSERT OR IGNORE for same-second
  PK collisions, and explicitly swallow FK violations when a release was
  pruned by a concurrent re-sync. Prevents a single vanished/duplicate
  release from aborting the digest mark-sent loop and re-sending.
- Do not abort NotifyOnce's mark-sent loop on a single failure; log and
  continue so every release in the batch is marked.
- NULL-safe reads: COALESCE(type,''), COALESCE(release_date,'') in the
  external_releases and unnotified readers to match the cache reader.
- Update/extend tests for the new idempotency and startup contracts.
2026-07-20 06:27:42 +03:00
a8aa445d94 fix: address code review findings
- Honor ignore_singles/ignore_compilations at scanner read time so toggles
  take effect immediately on the dashboard, artist page, and digest instead
  of waiting for the MusicBrainz cache to expire and prune rows.
- Run notifier notify synchronously in the scheduler loop to avoid overlapping
  read-send-mark runs double-sending the digest.
- Show artist name (with ID fallback) on the archive page instead of raw IDs.
- Select last_synced in GetAllArtistSettings for contract consistency.
- Fix stale startPeriodicSync comment and remove redundant error var.
- Remove dead ignored-branch from the artist template (never rendered).
- Add tests: CSRF sameOrigin, ArtistCacheFresh, secondary_types round-trip,
  and scanner type-toggle filtering.
- Update Specification.md schema/config to reflect mbid, last_synced,
  secondary_types, sync.interval, and server.public_url.
2026-07-20 06:18:21 +03:00
f5b0034b4d fix: link dashboard artist names to detail pages
Task 8's ignore/restore/ignore-singles actions live on the artist detail
page, but the dashboard rendered artist names as plain text with no link,
making those actions unreachable through normal UI navigation. Wrap the
name in an anchor to /artist/{id} and assert the link in the dashboard test.
2026-07-20 00:10:20 +03:00
e0211343e0 fix: address code review findings 2026-07-20 00:05:22 +03:00
ce1c39e14b fix: address code review findings
- Preserve MBID and last_synced across periodic artist syncs (INSERT OR
  REPLACE was wiping them, forcing MusicBrainz re-resolution every cycle)
- Exclude unmonitored artists from unnotified-release digest query
- Require telegram.cron_schedule when telegram.enabled is true
- Add same-origin CSRF defense to state-changing web POST routes
- Skip WAL/busy_timeout pragmas for :memory: databases (no-op there)
- Scan mbid as sql.NullString in GetAllArtistSettings to tolerate NULLs
2026-07-19 23:51:15 +03:00
7cdb473d9c fix: address code review findings
- notifier: show artist display names (not internal IDs) in digest; resolve
  names from artist_settings and fall back to ID when unavailable
- notifier: skip sending an empty digest to avoid daily spam
- config: require telegram token/chat_id when enabled
- web: warn loudly when auth is disabled on a non-loopback bind; add HTTP
  server timeouts
- web: treat SetReleaseIgnored "release not found" as benign redirect (0 rows)
- musicbrainz: reject low-score/name-mismatched MBID resolutions instead of
  silently caching the wrong artist
- database: remove dead duplicate err check; harden DSN param appending
- musicbrainz: check rows.Err() after iterating existing releases
2026-07-19 23:46:09 +03:00
389d177d85 fix: address code review findings
- Fix duplicate Telegram notifications: SyncArtistDiscography no longer wipes
  notifications_sent for the whole artist on every cache-miss re-sync; only
  markers for releases that disappear are pruned (FK-safe via INSERT OR REPLACE
  + rgid NOT IN (...)).
- Cache empty MusicBrainz discographies via a new artist_settings.last_synced
  column (migration 009) so zero-release artists honor the TTL instead of being
  re-fetched every cycle.
- Wire the Web UI server and Telegram notifier scheduler into main.run/NewApp.
- Guard startPeriodicSync against overlapping syncs with a done-channel slot.
- Add server.public_url config; NewServerWithConfig derives reachable links
  and no longer advertises the 0.0.0.0 bind address.
- Web handlers: use scanner.ScanArtist per artist, drop always-false
  releaseIgnored lookup and dead endsWith, thread configured threshold.
- Limit :memory: DB pool to one connection so migrations and queries share the
  same in-memory store.
2026-07-19 23:38:33 +03:00
e493a4d228 feat: document wired sync pipeline, notifier, and web UI in README 2026-07-19 22:50:39 +03:00
1a644dede7 feat: verify acceptance criteria and document sync config
Add a scan->notify->web end-to-end smoke test against a seeded :memory: DB,
fix .gitignore so the cmd/naviwatcher source dir is not excluded by the
root binary rule, and document the new sync.interval field in config.yaml.example.
2026-07-19 22:48:31 +03:00
44f3b0a2a7 feat: add Web UI artist detail, archive, and ignore actions
Implements Task 8: artist detail page (local albums + found-missing
with ignore buttons), ignored-releases archive with restore, and POST
handlers toggling ignore flags and ignore_singles. Adds ErrArtistNotFound
sentinel so callers can distinguish missing artists, and wires routes via
the enhanced ServeMux path wildcard.
2026-07-19 22:43:47 +03:00
cea20957e7 feat: add Web UI server with basic-auth and artist dashboard 2026-07-19 22:35:28 +03:00
11f838ace9 feat: add notifier scheduler and NotifyOnce sent-tracking 2026-07-19 22:32:57 +03:00
3af33bd728 feat: add notifier Sender interface and digest formatter 2026-07-19 22:28:41 +03:00
0635ca8a87 feat: wire main loop with periodic sync+scan and sync_interval config
Replace compute-only run() with an immediate sync+scan followed by a
ticker-driven periodic loop, add the sync.interval config field (default
6h) with defaults and validation, and add tests for the scheduling logic.
2026-07-19 22:27:06 +03:00
dc4bdcdab0 feat: add SyncAll periodic sync pipeline and wire Navidrome client into App 2026-07-19 22:22:46 +03:00
40c4240693 feat: add MusicBrainz artist-ID resolver
Add ResolveArtistMBID to query the MB artist search endpoint and return the
first matching artist ID, with httptest-backed tests for match, no-match,
HTTP error, and invalid-JSON paths.
2026-07-19 22:16:43 +03:00
85c42ec858 feat: add mbid column to artist_settings
Additive migration 008 adds an mbid column to artist_settings, extend the
ArtistSettings struct and persistence functions (SaveArtistSettings,
GetArtistSettings, GetAllArtistSettings, UpdateArtistSettings) to carry the
MusicBrainz ID, and add round-trip tests covering empty and set MBID values.
2026-07-19 22:13:57 +03:00
35d6a5234f move completed plan: 2026-07-19-scanner-engine-fuzzy-diff.md 2026-07-19 21:59:59 +03:00
79a376a127 fix: address code review findings
- Strip standalone reissue keywords (remaster/remastered/remix/deluxe/
  expanded/edition/reissue/anniversary/bonus) regardless of brackets so
  non-parenthesized remasters still match the plain local title above the
  0.85 threshold (was falsely reported missing).
- Fix TestAppRun_ScanLogsMissingReleases to verify run() performs the
  scan itself (capture its log output) instead of re-running ScanAll
  independently, which passed even if run() were a no-op.
- Fix TestSimilarity misleading cases that downgraded to a <0.85 range
  check with dead want/epsilon fields; assert actual computed scores.
2026-07-19 21:33:52 +03:00
e2de91c5d3 fix: address code review findings
- Fix pagination to not trust MusicBrainz count for cutoff (prevents
  silent discography truncation / hidden missing releases)
- Add idx_external_releases_artist_id index for hot per-artist queries
- Dedupe cached_at layout constant in external_releases.go
2026-07-19 21:13:24 +03:00
ab2af62cb0 fix: guard against whitespace-only type attribute panic in ParseReleaseGroups 2026-07-19 21:08:57 +03:00
2468859435 fix: address code review findings 2026-07-19 20:53:06 +03:00
da8b8aa944 fix: address code review findings (consolidate slice helpers, correct bootleg comment) 2026-07-19 20:10:06 +03:00
4da5ee5f8c fix: address code review findings 2026-07-19 20:06:41 +03:00
b21bf07208 fix: address code review findings
- Store cached_at in canonical UTC layout so the cache TTL cutoff comparison is a valid time ordering (previously go-sqlite3 serialized time.Time as RFC3339, making the space-separated cutoff match only by ASCII accident; same-day expired entries were falsely served as fresh).

- Remove stale no-op scanner config keys (ignore_bootlegs, include_compilations) from config.yaml.example and docs; these fields were removed from ScannerConfig but left in configs, silently doing nothing.
2026-07-19 20:01:26 +03:00
0bee9b9b27 fix: address code review findings 2026-07-19 19:52:27 +03:00
a7803615cd fix: address code review findings 2026-07-19 19:45:08 +03:00
beef81d598 fix: address code review findings 2026-07-19 19:28:51 +03:00
401c1218b6 fix: address code review findings 2026-07-19 19:22:18 +03:00
f1839ad9e7 fix: address code review findings 2026-07-19 19:11:22 +03:00
c70f46af27 fix: address code review findings 2026-07-19 19:07:20 +03:00
a4c426f640 fix: address code review findings 2026-07-19 18:59:38 +03:00