## ADDED Requirements ### Requirement: Hybrid storage layout The system SHALL store media files under the app Documents `library/` directory and SHALL store catalog, session, and album metadata in SwiftData (not Core Data, and not JSON as the runtime source of truth). #### Scenario: Imported file on disk and in catalog - **WHEN** a media file is successfully imported - **THEN** the file exists under Documents/`library/` at a stable relative path AND a SwiftData `CatalogEntry` records that relative path, kind, name, and import time #### Scenario: No Core Data dependency - **WHEN** the app persists metadata - **THEN** persistence MUST use SwiftData APIs and MUST NOT require a Core Data stack ### Requirement: Directory listing and library mutations The system SHALL list directories under `library/`, and SHALL support create folder, rename, move, and delete for library entries while keeping SwiftData catalog consistent. #### Scenario: List subdirectory - **WHEN** the user opens a relative directory in Explorer - **THEN** the system returns folders and files in that directory, attaching catalog metadata for known media files #### Scenario: Delete file removes catalog entry - **WHEN** the user deletes a media file from the library - **THEN** the file is removed from disk AND its `CatalogEntry` is removed or marked unavailable so it no longer appears as a playable resource #### Scenario: Path escape rejected - **WHEN** a mutation or import provides a relative path that would escape `library/` - **THEN** the system MUST reject the operation ### Requirement: Resource kind from extension The system SHALL classify imported files as `video`, `audio`, `pdf`, or `other` using extension rules aligned with the desktop StudyDeck classifier. #### Scenario: Common media extensions - **WHEN** files with extensions such as `mp4`, `mp3`, or `pdf` are imported - **THEN** their catalog kind is `video`, `audio`, or `pdf` respectively ### Requirement: Session and album persistence The system SHALL persist sessions (including progress fields and optional album linkage) and albums in SwiftData, including which session is active. #### Scenario: Active session survives relaunch - **WHEN** the user has an active session and force-quits then relaunches the app - **THEN** the active session identity and last saved progress fields are available for resume