using ErsatzTV.Core.Domain; namespace ErsatzTV.Core.Interfaces.Repositories; public interface ILibraryRepository { Task Add(LibraryPath libraryPath); Task> GetLibrary(int libraryId); Task> GetLocal(int libraryId); /// /// Resolves the owning library id for a library path, without loading the full entity graph. /// Used by the local-libraries API to pre-check a path's existence/ownership before a move /// (see design #202 §C6 — the 404/lock-check for POST .../paths/{pathId}/move). /// Task> GetLibraryIdForPath(int libraryPathId); Task> GetAll(); Task UpdateLastScan(Library library); Task UpdateLastScan(LibraryPath libraryPath); Task> GetLocalPaths(int libraryId); Task CountMediaItemsByPath(int libraryPathId); Task SetEtag(LibraryPath libraryPath, Option knownFolder, string path, string etag); Task CleanEtagsForLibraryPath(LibraryPath libraryPath); Task> GetParentFolderId(LibraryPath libraryPath, string folder, CancellationToken cancellationToken); /// /// Returns the at under /// , creating it if it does not yet exist. /// /// /// The existing folder is looked up from the database by (LibraryPathId, Path). Callers do /// not need to eager-load — the remote (Jellyfin) /// sync path never does, and relying on that navigation collection here previously NRE'd every /// Jellyfin music-video scan (ersatztv#488). /// Task GetOrAddFolder(LibraryPath libraryPath, Option maybeParentFolder, string folder); Task UpdateLibraryFolderId(MediaFile mediaFile, int libraryFolderId); Task UpdatePath(LibraryPath libraryPath, string normalizedLibraryPath); }