Coach item — sound_card¶
Block type: sound_card · Domain: coach-content
Coach items[] discriminator 'sound_card'. Always reference-resolved (no literal form — a literal sound promo is a teaser_card with a navigate:/sounds/... action). The app resolves title/image/duration|count from the in-memory SoundCatalog at compose time. ref_kind 'track' → ref is a content.sounds.id UUID (the catalog keys tracks by id, not slug); ref_kind 'album' → ref is a content.sound_albums.slug. The static schema pins shape only; the hook enforces cross-row existence (and UUID-shape for tracks). additionalProperties:false is intentionally stricter than the app (which ignores unknown keys) — Layer 2 catches stray authored keys at save time, matching the peer session_card/teaser_card schemas.
Fields¶
| Field | Type | Required | Allowed values | Notes |
|---|---|---|---|---|
id |
string | no | minLength 1 | |
ref_kind |
enum | yes | track, album |
Discriminates how ref is resolved: 'track' → content.sounds row by id; 'album' → content.sound_albums row by slug. |
ref |
string | yes | For ref_kind 'track': a content.sounds.id UUID. For ref_kind 'album': a content.sound_albums.slug. Existence (and, for tracks, UUID shape) is enforced by the coach-content-validate hook, not this schema. — minLength 1 |