Skip to content

feat(catalog): emit schemaVersion, thumbnailUrl, and per-item media specs - #71

Merged
tallnato merged 1 commit into
mainfrom
feat/catalog-metadata-fields
Jun 4, 2026
Merged

tallnato merged 1 commit into
mainfrom
feat/catalog-metadata-fields

Conversation

@tallnato

@tallnato tallnato commented Jun 4, 2026

Copy link
Copy Markdown
Member

What

Extends the catalog JSON contract (the feed scripts/build.ts emits and the VOLTS app consumes) so the app can show media specs and thumbnails. Touches scripts/build.ts and SCHEMA.md only.

Changes

  • schemaVersion — new top-level integer (1) on catalog.json and every <category>.json. Lets the app gate parsing of newer optional fields.
  • thumbnailUrl — per item: <baseurl>/content/<category>/<slug>/<thumbnail> (root-relative, same /Volts prefix convention as files[].downloadUrl) when front matter declares thumbnail; otherwise null. The raw thumbnail field is kept as-is.
  • specs — per item, best-effort and fully nullable { channels, sampleRate, durationSeconds }:
    • lightshows: .fseq header parse (PSEQ magic; channelCount@10, frameCount@14, stepTime@18) → channels, durationSeconds = frameCount*stepTime/1000.
    • locksounds / hornsounds / boombox / any .wav: RIFF chunk-walk for fmt (sampleRate, channels, bitsPerSample) + data (size) → sampleRate, durationSeconds = dataSize/(sampleRate*channels*bitsPerSample/8).
    • mp3-only: left null (VBR — not worth a header parse).

Robustness

Every parser is wrapped in try/catch and returns null on any failure. The committed fixtures are tiny placeholder stubs (e.g. a 36-byte .fseq) — these parse gracefully (degenerate values / nulls), never throw.

Verification

  • npm run build → exit 0; new fields present. Samples:
    • lightshow (stub .fseq): specs: { channels: 0, sampleRate: null, durationSeconds: 0.025 }
    • hornsound (real .wav): specs: { channels: 1, sampleRate: 44100, durationSeconds: 5 }
    • wrap: thumbnailUrl: "/Volts/content/wraps/cybertruck-camo/cybertruck-camo.png"
    • mp3-only: all-null specs
  • npm run validate → exit 0 (pre-existing placeholder-stub warnings only).
  • Jekyll (Ruby) not run locally — no _config.yml/_layouts/Liquid touched in this unit, so no Jekyll-side change to validate; the PR's build-check CI runs jekyll build.

SCHEMA.md documents schemaVersion, thumbnailUrl, and specs (which categories populate which fields, all best-effort/nullable) and updates the cross-repo invariants.

🤖 Generated with Claude Code

…pecs

Extend the catalog JSON contract so the app can show media specs and
thumbnails:

- Add a top-level integer `schemaVersion` (1) to catalog.json and each
  <category>.json.
- Emit a root-relative `thumbnailUrl` per item (same convention/`/Volts`
  prefix as files[].downloadUrl) when front matter declares `thumbnail`,
  else null. The raw `thumbnail` field is unchanged.
- Emit a best-effort, fully nullable `specs` object per item:
    - lightshows: parse the .fseq header (PSEQ magic; channelCount,
      frameCount, stepTime) -> channels + durationSeconds.
    - locksounds/hornsounds/boombox/any .wav: RIFF chunk-walk for `fmt `
      + `data` -> channels, sampleRate, durationSeconds.
    - mp3-only items: left null (VBR).
  Every parser is wrapped in try/catch and tolerates the tiny placeholder
  stub binaries (e.g. a 36-byte .fseq) without throwing.

Document the new fields in SCHEMA.md and keep the cross-repo invariants
accurate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added site Changes to site layouts, includes, and config ci Changes to CI/CD and scripts labels Jun 4, 2026
@tallnato
tallnato merged commit a181345 into main Jun 4, 2026
4 checks passed
@tallnato
tallnato deleted the feat/catalog-metadata-fields branch June 4, 2026 17:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci Changes to CI/CD and scripts site Changes to site layouts, includes, and config

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant