navidrome/persistence
Deluan Quintão 2c90685bc2
fix(scanner): import playlists skipped when no admin existed yet (#5609)
* fix(scanner): import playlists skipped when no admin existed yet (#5499)

On a fresh install the first scan runs before any admin user exists, so the
scanner's playlist phase skips all playlists (playlists are owned by the
first admin). Nothing re-imported them afterwards because folder selection
is gated on updated_at > last_scan_at, which nothing bumps.

The playlist phase now:
- resolves the admin at phase time (FindFirstAdmin) instead of trusting the
  context snapshot taken at scan start, so a long admin-less scan still
  imports playlists in its own phase if an admin was created meanwhile;
- records a persisted PlaylistsImportPending flag when no admin exists yet;
- when that flag is set, imports ALL playlist folders via a new
  GetAllWithPlaylists (bypassing the timestamp gate) and clears the flag.

Playlists are recovered by the next scan that runs with an admin, with no
dependency on scan duration and no changes to the auth/server layers.

* fix(scanner): surface datastore errors in playlist import deferral (#5499)

Address review feedback:
- distinguish model.ErrNotFound (no admin yet -> defer) from real datastore
  errors when resolving the admin, so DB failures are propagated, not swallowed;
- propagate the error if the pending-import flag can't be persisted, so a scan
  doesn't complete as successful without recording the recovery;
- surface read errors when checking the pending flag.

Also name the no-admin condition for readability.

* fix(scanner): simplify admin existence check in playlist import

Signed-off-by: Deluan <deluan@navidrome.org>

* fix(scanner): streamline folder access in playlist import logic

Signed-off-by: Deluan <deluan@navidrome.org>

---------

Signed-off-by: Deluan <deluan@navidrome.org>
2026-06-14 13:39:16 -04:00
..
e2e fix(smartplaylist): support isMissing/isPresent operators on ReplayGain fields (#5585) 2026-06-10 21:12:31 -04:00
album_repository.go fix(subsonic): always emit required created field on AlbumID3 (#5340) 2026-04-10 19:29:20 -04:00
album_repository_test.go fix(subsonic): always emit required created field on AlbumID3 (#5340) 2026-04-10 19:29:20 -04:00
artist_repository.go fix(opensubsonic): make search3 empty-query pagination fast at large offsets (#5601) 2026-06-12 15:53:37 -04:00
artist_repository_test.go fix(opensubsonic): make search3 empty-query pagination fast at large offsets (#5601) 2026-06-12 15:53:37 -04:00
collation_test.go fix(ui): make playlist name sorting case-insensitive (#4845) 2026-01-05 19:05:11 -05:00
criteria_sql.go perf(smartplaylists): merge negated artist/tag rules into one NOT EXISTS 2026-06-14 10:47:11 -04:00
criteria_sql_benchmark_test.go perf(smartplaylists): merge negated artist/tag rules into one NOT EXISTS 2026-06-14 10:47:11 -04:00
criteria_sql_test.go perf(smartplaylists): merge negated artist/tag rules into one NOT EXISTS 2026-06-14 10:47:11 -04:00
export_test.go feat(bfr): Big Refactor: new scanner, lots of new fields and tags, improvements and DB schema changes (#2709) 2025-02-19 20:35:17 -05:00
folder_repository.go fix(scanner): import playlists skipped when no admin existed yet (#5609) 2026-06-14 13:39:16 -04:00
folder_repository_test.go fix(scanner): import playlists skipped when no admin existed yet (#5609) 2026-06-14 13:39:16 -04:00
genre_repository.go refactor: multiple syntax updates for Go 1.26 2026-05-19 18:02:36 -03:00
genre_repository_test.go refactor: run Go modernize (#5002) 2026-02-08 09:57:30 -05:00
helpers.go refactor: run Go modernize (#5002) 2026-02-08 09:57:30 -05:00
helpers_test.go feat(bfr): Big Refactor: new scanner, lots of new fields and tags, improvements and DB schema changes (#2709) 2025-02-19 20:35:17 -05:00
library_repository.go refactor: run Go modernize (#5002) 2026-02-08 09:57:30 -05:00
library_repository_test.go ci: run Go tests on Windows (#5380) 2026-04-19 13:16:47 -04:00
mediafile_repository.go fix(nativeapi): make /api/song path filter work and use startsWith (#5566) 2026-06-05 14:00:08 -04:00
mediafile_repository_test.go feat(smartplaylist): extend isMissing/isPresent to bpm, bitDepth and many text fields (#5603) 2026-06-13 13:15:20 -04:00
persistence.go refactor: run Go modernize (#5002) 2026-02-08 09:57:30 -05:00
persistence_suite_test.go refactor: multiple syntax updates for Go 1.26 2026-05-19 18:02:36 -03:00
persistence_test.go fix(server): play queue should not return empty entries for deleted tracks 2024-09-20 11:22:37 -04:00
player_repository.go fix(share): enforce per-user ownership on share reads 2026-06-05 15:50:59 -04:00
player_repository_test.go fix(share): enforce per-user ownership on share reads 2026-06-05 15:50:59 -04:00
playlist_repository.go fix(playlists): allow toggling auto-import and avoid unnecessary artwork reloads (#5421) 2026-04-27 12:20:27 -04:00
playlist_repository_test.go refactor: centralize criteria sort parsing and extract smart playlist logic (#5415) 2026-04-26 14:49:59 -04:00
playlist_track_repository.go refactor: move playlist business logic from repositories to service layer (#5027) 2026-02-21 19:57:13 -05:00
playqueue_repository.go refactor: multiple syntax updates for Go 1.26 2026-05-19 18:02:36 -03:00
playqueue_repository_test.go fix(server): ensure single record per user by reusing existing playqueue ID 2025-06-11 17:26:13 -04:00
plugin_cleanup.go feat(plugins): New Plugin System with multi-language PDK support (#4833) 2026-01-14 19:22:48 -05:00
plugin_cleanup_test.go feat(plugins): New Plugin System with multi-language PDK support (#4833) 2026-01-14 19:22:48 -05:00
plugin_repository.go fix(plugins): clear plugin errors on startup to allow retrying 2026-03-02 08:56:56 -05:00
plugin_repository_test.go fix(plugins): clear plugin errors on startup to allow retrying 2026-03-02 08:56:56 -05:00
property_repository.go Replace beego/orm with dbx (#2693) 2023-12-09 13:52:17 -05:00
property_repository_test.go revert: separation of write and read DBs 2024-11-19 18:41:50 -05:00
radio_repository.go feat(ui): add cover art support for internet radio stations (#5229) 2026-03-18 18:57:33 -04:00
radio_repository_test.go refactor: more warnings clean up 2026-05-20 17:43:12 -03:00
scrobble_buffer_repository.go refactor: run Go modernize (#5002) 2026-02-08 09:57:30 -05:00
scrobble_buffer_repository_test.go refactor: run Go modernize (#5002) 2026-02-08 09:57:30 -05:00
scrobble_repository.go refactor: run Go modernize (#5002) 2026-02-08 09:57:30 -05:00
scrobble_repository_test.go feat(server): track scrobble/linstens history (#4770) 2025-12-06 11:07:18 -05:00
share_repository.go fix(share): enforce per-user ownership on share reads 2026-06-05 15:50:59 -04:00
share_repository_test.go fix(share): enforce per-user ownership on share reads 2026-06-05 15:50:59 -04:00
smart_playlist_repository.go refactor: centralize criteria sort parsing and extract smart playlist logic (#5415) 2026-04-26 14:49:59 -04:00
smart_playlist_repository_test.go fix(smartplaylists): coerce string booleans in smart playlist rules (#5450) 2026-05-01 19:21:48 -04:00
sql_annotations.go refactor: run Go modernize (#5002) 2026-02-08 09:57:30 -05:00
sql_annotations_test.go refactor: run Go modernize (#5002) 2026-02-08 09:57:30 -05:00
sql_base_repository.go fix(share): enforce per-user ownership on share reads 2026-06-05 15:50:59 -04:00
sql_base_repository_test.go fix(server): headless library access improvements (#4362) 2025-07-20 15:58:21 -04:00
sql_bookmarks.go refactor: run Go modernize (#5002) 2026-02-08 09:57:30 -05:00
sql_bookmarks_test.go revert: separation of write and read DBs 2024-11-19 18:41:50 -05:00
sql_participations.go fix(scanner): remove stale role associations when artist role changes. Fix #4242 2025-12-16 06:38:50 -05:00
sql_restful.go fix(nativeapi): make /api/song path filter work and use startsWith (#5566) 2026-06-05 14:00:08 -04:00
sql_restful_test.go feat(subsonic): sort search3 results by relevance (#5086) 2026-02-23 08:51:54 -05:00
sql_search.go fix(opensubsonic): make search3 empty-query pagination fast at large offsets (#5601) 2026-06-12 15:53:37 -04:00
sql_search_fts.go fix(opensubsonic): make search3 empty-query pagination fast at large offsets (#5601) 2026-06-12 15:53:37 -04:00
sql_search_fts_test.go fix(search): normalization for non-NFKD Unicode letters (ø, æ, œ, ß) (#5413) 2026-04-25 20:27:38 -04:00
sql_search_like.go chore: go fix 2026-05-28 22:13:05 -03:00
sql_search_like_test.go feat(subsonic): sort search3 results by relevance (#5086) 2026-02-23 08:51:54 -05:00
sql_search_test.go feat(subsonic): sort search3 results by relevance (#5086) 2026-02-23 08:51:54 -05:00
sql_tags.go refactor: run Go modernize (#5002) 2026-02-08 09:57:30 -05:00
tag_library_filtering_test.go refactor: run Go modernize (#5002) 2026-02-08 09:57:30 -05:00
tag_repository.go feat(scanner): improve error messages for cleanup operations in annotations, bookmarks, and tags 2025-11-20 09:27:42 -05:00
tag_repository_test.go refactor: run Go modernize (#5002) 2026-02-08 09:57:30 -05:00
transcoding_repository.go fix: restrict transcoding config reads to admins (#5564) 2026-06-04 23:07:13 -04:00
transcoding_repository_test.go fix: restrict transcoding config reads to admins (#5564) 2026-06-04 23:07:13 -04:00
user_props_repository.go Replace beego/orm with dbx (#2693) 2023-12-09 13:52:17 -05:00
user_repository.go fix(nativeapi): make /api/song path filter work and use startsWith (#5566) 2026-06-05 14:00:08 -04:00
user_repository_test.go fix(nativeapi): make /api/song path filter work and use startsWith (#5566) 2026-06-05 14:00:08 -04:00