fix(13-02): auto-resolve phantom playlist tracks after library scan

- Add phantom_file_path column to playlist_tracks (migration 7)
- Store original file_path during RemoveLibrary phantom metadata population
- After each successful scan, UPDATE phantom tracks whose phantom_file_path
  now matches an audio_files row, re-linking them and clearing phantom metadata
- Update schema file, sqlc generated code, and database test for new column
This commit is contained in:
2026-03-16 12:29:06 -04:00
parent f05d2bb603
commit 93262b9ae0
7 changed files with 116 additions and 6 deletions
+48
View File
@@ -312,6 +312,16 @@ func runMigrations(
}
}
// Migration 7: add phantom_file_path to playlist_tracks
// for automatic phantom resolution after library re-scans.
if version < 7 {
if err := migration7PhantomFilePath(
ctx, db, logger,
); err != nil {
return err
}
}
return nil
}
@@ -1030,6 +1040,44 @@ func migration6MultiLibrary(
return nil
}
// migration7PhantomFilePath adds the phantom_file_path column to
// playlist_tracks so that phantom entries can be automatically
// re-linked to audio_files after a library scan.
func migration7PhantomFilePath(
ctx context.Context,
db *sql.DB,
logger *slog.Logger,
) error {
logger.Info(
"applying migration 7: phantom_file_path column",
)
// SAFETY: ALTER TABLE ADD COLUMN for new nullable column.
if _, err := db.ExecContext(ctx,
`ALTER TABLE playlist_tracks
ADD COLUMN phantom_file_path TEXT`,
); err != nil {
if !isDuplicateColumnErr(err) {
return fmt.Errorf(
"migration 7: could not add column: %w",
err,
)
}
}
if _, err := db.ExecContext(
ctx, "PRAGMA user_version = 7",
); err != nil {
return fmt.Errorf(
"could not set user_version to 7: %w", err,
)
}
logger.Info("migration 7 complete")
return nil
}
// readLibraryDirFromTOML reads the TOML config file and returns
// the Library.DirectoryPath value, or "" if not configured.
func readLibraryDirFromTOML(logger *slog.Logger) string {