Skip to content

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

Example

{
  "type": "sound_card",
  "ref_kind": "track",
  "ref": "11111111-1111-4111-8111-111111111111"
}