feat(content): serve the mounted content folder under /content (spec 003)
Audio with range requests, library.json, Homer books; LRC parser. Content stays out of git and the image. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9d063fcbe0
commit
27b1d2fe26
15 files changed
+527
-10
No files matched your search
@@ -0,0 +1,52 @@
|
||||
---
|
||||
status: approved
|
||||
---
|
||||
|
||||
# Real content from a mounted folder (audio, timed lyrics, Homer)
|
||||
|
||||
Status: approved by user 2026-10-30 · Date: 2026-10-30
|
||||
|
||||
## Intent
|
||||
|
||||
The user added the real content in `~/epic-the-musical-content/`: all 40 *EPIC* songs as FLAC, timed
|
||||
lyrics (`.lrc`) for 37 of them and plain-text lyrics for 3, saga cover art, and Samuel Butler's
|
||||
public-domain prose translations of the *Odyssey* and the *Iliad* (Project Gutenberg #1727, #2199).
|
||||
Mockups (starting with 17) and later the real app should use this content: real playback, line-synced
|
||||
lyrics, and the actual Odyssey passage for a song.
|
||||
|
||||
The audio, lyrics and cover art are Jorge Rivera-Herrans' copyrighted work. The user chose (2026-10-30):
|
||||
**"Mount it, never commit"** — the folder stays out of git and out of the Docker image; the server reads
|
||||
it from a path given by `CONTENT_DIR`, mounted read-only into the container.
|
||||
|
||||
## Goals
|
||||
|
||||
1. **Server serves the mounted folder** when `CONTENT_DIR` is set:
|
||||
- `GET /content/library.json` — every saga (name, year, cover URL) with its songs (track, title,
|
||||
audio URL, lyrics URL and whether they are timed), built by scanning the folder.
|
||||
- `GET /content/files/<path>` — the file at that path inside `CONTENT_DIR`, with the right content
|
||||
type and HTTP range support so audio can seek. Paths outside `CONTENT_DIR` are refused.
|
||||
- `GET /content/homer/<odyssey|iliad>/<book>.json` — one book of the Butler text: number, heading,
|
||||
summary line, paragraphs.
|
||||
- Without `CONTENT_DIR` (or with a missing folder), all `/content/*` routes answer 404 and every
|
||||
other route works as before.
|
||||
2. **Shared helpers** for clients: an LRC parser (timed lines, sorted, multi-stamp lines, metadata tags
|
||||
skipped) and the library types.
|
||||
3. **Nothing copyrighted is committed or baked into the image.** `.gitignore` and `.dockerignore`
|
||||
guard against a copy inside the repo.
|
||||
4. **Docs**: AGENTS.md lyrics rule updated (real lyrics only from the mounted folder, never in the
|
||||
repo); ARCHITECTURE, DECISIONS; the preview container run command mounts the folder.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Changing existing mockups 01–16 to use real content.
|
||||
- Transcoding FLAC (browsers play FLAC); caching or a CDN.
|
||||
- Mapping songs to Odyssey passages (that is content work for the real app).
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- `bun test` covers: library scan of a fixture folder (sagas in story order, songs by track, `.lrc`
|
||||
preferred over `.txt`), LRC parsing, Homer book splitting, the `/content/*` routes with and without `CONTENT_DIR`,
|
||||
path-traversal refusal, and a range request returning 206.
|
||||
- The preview container, run with `-v ~/epic-the-musical-content:/content:ro -e CONTENT_DIR=/content`,
|
||||
serves `/content/library.json` listing 9 sagas and 40 songs, and an audio file plays with seeking.
|
||||
- `git status` shows no content files; the Docker image contains none.
|
||||
Reference in new issue
Block a user