## ADDED Requirements ### Requirement: Publish server lifecycle The desktop StudyDeck application SHALL provide a user-controlled LAN publish mode that starts and stops a read-only HTTP server exposing organized courses for download. The server MUST NOT require authentication. The UI MUST present trusted-LAN-only messaging while the server is running. #### Scenario: Start publish - **WHEN** the parent enables publish/share on desktop StudyDeck - **THEN** the app starts an HTTP listener on a default or fallback port and displays a base URL usable from an iPad on the same LAN #### Scenario: Stop publish - **WHEN** the parent disables publish or the desktop app exits - **THEN** the HTTP server stops accepting requests ### Requirement: Connection affordances While publish is running, the desktop app SHALL show at least the LAN IPv4 address, port, and a QR code encoding the base URL. #### Scenario: QR encodes base URL - **WHEN** publish is running - **THEN** the displayed QR code decodes to the same HTTP base URL shown in the UI ### Requirement: Course catalog API The publish server SHALL expose a JSON catalog of downloadable courses derived from desktop albums with mode `combo`. Each entry MUST include stable `id`, `title`, `mode`, and `updatedAt`. Unsaved Explorer drafts and study-only sessions that are not persisted as combo albums MUST NOT appear until they are saved (or promoted) as combo albums. #### Scenario: List combo courses - **WHEN** a client calls `GET /api/courses` while publish is running - **THEN** the response is a JSON array of combo courses from the desktop album store #### Scenario: Playlist excluded from MVP catalog - **WHEN** the desktop store contains playlist albums - **THEN** those playlist albums MUST NOT appear in `GET /api/courses` for MVP #### Scenario: Catalog after saving a combo from Explorer - **WHEN** the parent starts or saves a valid combo course from Explorer so that a combo album is persisted - **THEN** a subsequent `GET /api/courses` includes that course ### Requirement: Course pack download API The publish server SHALL provide `GET /api/courses/:id/pack` that returns a zip archive containing a valid course pack for that course id, or a clear client error if the course is missing or media files are incomplete. Media entries in the zip SHOULD use store (uncompressed) method so large already-compressed media does not rely on client deflate inflate. #### Scenario: Pack succeeds for complete course - **WHEN** a client requests the pack for an existing combo course whose referenced media files exist on disk - **THEN** the server responds with a zip body and a success status #### Scenario: Pack fails when media missing - **WHEN** a client requests a pack for a course whose referenced media file is missing - **THEN** the server MUST NOT return a success zip and MUST return an error status suitable for client display ### Requirement: Health endpoint The publish server SHALL expose `GET /api/health` that indicates the service is StudyDeck publish and is reachable. #### Scenario: Health ok - **WHEN** a client calls `GET /api/health` while publish is running - **THEN** the response indicates success and identifies the publish service ### Requirement: Browser fallback list The publish server SHALL serve a simple HTML course list at `GET /` that links to pack downloads for available combo courses. #### Scenario: HTML lists courses - **WHEN** a browser opens the publish base URL while courses exist - **THEN** the page lists those combo courses