You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit a181345
Browse filesBrowse the repository at this point in the historyBrowse files
`schemaVersion` (currently **`1`**) is a top-level integer on `catalog.json` and each `<category>.json`. It is bumped whenever the emitted JSON shape changes so the app can gate parsing of newer optional fields. The current contract is version 1 (adds `thumbnailUrl` + `specs` to each item).
55
+
54
56
Each **item**:
55
57
```jsonc
56
58
{
@@ -61,14 +63,35 @@ Each **item**:
61
63
"description":"…",
62
64
"tags": ["rock", "synchronized"],
63
65
"thumbnail":null, // string filename for wraps, else null
66
+
"thumbnailUrl":null, // root-relative URL when thumbnail set, else null
64
67
"files": [ // derived from declared meta.files ∩ disk
"specs": { // best-effort media specs, all fields nullable
71
+
"channels":0,
72
+
"sampleRate":null,
73
+
"durationSeconds":0.025
74
+
},
67
75
"meta": { /* full front matter; meta.files[] also gets downloadUrl + keeps label */ }
68
76
}
69
77
```
70
78
79
+
### `thumbnailUrl`
80
+
When front matter declares `thumbnail`, `build.ts` emits a root-relative `thumbnailUrl` of `<baseurl>/content/<category>/<slug>/<thumbnail>` — the **same convention and `/Volts` prefix as `files[].downloadUrl`**. When no `thumbnail` is declared it is `null`. The raw `thumbnail` field (bare filename or `null`) is kept as-is alongside it.
81
+
82
+
### `specs` (best-effort, nullable)
83
+
`specs` is parsed best-effort from an item's binaries. **Every field is nullable and the build never throws on a malformed/stub asset** — today's committed fixtures are tiny placeholder stubs, so expect `null` (or degenerate) values until real assets land. Shape: `{ channels, sampleRate, durationSeconds }`.
| mp3-only items (and items with no parseable binary) | — |`null`|`null`|`null`|
90
+
91
+
MP3 is intentionally **not** parsed (variable bitrate makes header-derived duration/sampleRate unreliable), so an mp3-only item yields all-`null` specs. Any parse failure (bad magic, truncated stub, missing chunk) also yields `null` for the affected field(s).
92
+
71
93
**Cross-repo invariants (do not break without updating the app):**
72
94
1. The five **category key names** are fixed. A new category is silently ignored by the app until it ships an update (`CatalogApi.kt` has a hardcoded `CATEGORY_KEYS`).
73
-
2.`downloadUrl` is **root-relative and includes the `/Volts` prefix** (driven by `_config.yml`'s `baseurl`). The app resolves it against the host only (`https://natobytes.com`). Changing `baseurl` breaks the app's URL resolution.
95
+
2.`downloadUrl`(and `thumbnailUrl`) is **root-relative and includes the `/Volts` prefix** (driven by `_config.yml`'s `baseurl`). The app resolves it against the host only (`https://natobytes.com`). Changing `baseurl` breaks the app's URL resolution.
74
96
3.`meta.files[].label` is relied on by the app for display.
97
+
4.`schemaVersion`, `thumbnailUrl`, and `specs` are **additive** (version 1). They don't displace any existing field, and `specs` values are best-effort/nullable — the app must tolerate `null` for any spec.
0 commit comments