{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://tune.toys/schemas/platform/media-item.schema.json",
  "title": "SoundItem",
  "description": "The mutable catalog entry of one upload: what people see and edit (title, artwork, tags, declared musical fields, visibility). Bytes and rights live on its versions. Server-owned counters and the resolved view are separate shapes here.",
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "id": {
      "$ref": "common.schema.json#/$defs/EntityId"
    },
    "ownerId": {
      "$ref": "common.schema.json#/$defs/EntityId"
    },
    "currentVersion": {
      "$ref": "common.schema.json#/$defs/EntityId"
    },
    "family": {
      "$ref": "enums.schema.json#/$defs/MediaFamily"
    },
    "title": {
      "type": "string",
      "minLength": 1,
      "maxLength": 128
    },
    "artist": {
      "type": "string",
      "minLength": 0,
      "maxLength": 128
    },
    "description": {
      "type": "string",
      "minLength": 0,
      "maxLength": 4000,
      "description": "Markdown rendered through @tunetoys/markdown."
    },
    "tags": {
      "type": "array",
      "maxItems": 20,
      "uniqueItems": true,
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 40,
        "pattern": "^[a-z0-9][a-z0-9 ._+#&/-]{0,39}$"
      },
      "description": "Lower-case tags, at most 20 × 40 characters."
    },
    "soundType": {
      "anyOf": [
        {
          "$ref": "enums.schema.json#/$defs/SoundType"
        },
        {
          "type": "null"
        }
      ]
    },
    "visibility": {
      "$ref": "enums.schema.json#/$defs/Visibility"
    },
    "state": {
      "$ref": "enums.schema.json#/$defs/MediaItemState"
    },
    "artwork": {
      "anyOf": [
        {
          "$ref": "#/$defs/Artwork"
        },
        {
          "type": "null"
        }
      ]
    },
    "declared": {
      "$ref": "#/$defs/DeclaredMetadata"
    },
    "recordedAt": {
      "anyOf": [
        {
          "$ref": "common.schema.json#/$defs/Timestamp"
        },
        {
          "type": "null"
        }
      ]
    },
    "recordedLocation": {
      "anyOf": [
        {
          "$ref": "#/$defs/RecordedLocation"
        },
        {
          "type": "null"
        }
      ]
    },
    "source": {
      "anyOf": [
        {
          "$ref": "#/$defs/SoundSource"
        },
        {
          "type": "null"
        }
      ]
    },
    "publishedAt": {
      "anyOf": [
        {
          "$ref": "common.schema.json#/$defs/Timestamp"
        },
        {
          "type": "null"
        }
      ]
    },
    "version": {
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991,
      "description": "Optimistic lock; a stale PATCH returns 409."
    },
    "createdAt": {
      "$ref": "common.schema.json#/$defs/Timestamp"
    },
    "updatedAt": {
      "$ref": "common.schema.json#/$defs/Timestamp"
    }
  },
  "required": [
    "id",
    "ownerId",
    "currentVersion",
    "family",
    "title",
    "artist",
    "description",
    "tags",
    "soundType",
    "visibility",
    "state",
    "artwork",
    "declared",
    "recordedAt",
    "recordedLocation",
    "source",
    "publishedAt",
    "version",
    "createdAt",
    "updatedAt"
  ],
  "$defs": {
    "Meter": {
      "title": "Meter",
      "description": "Time signature.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "numerator": {
          "type": "integer",
          "minimum": 1,
          "maximum": 32
        },
        "denominator": {
          "type": "integer",
          "enum": [1, 2, 4, 8, 16]
        }
      },
      "required": ["numerator", "denominator"]
    },
    "Artwork": {
      "title": "Artwork",
      "description": "An image item the owner chose, or one of this item's own renditions.",
      "oneOf": [
        {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "mediaId": {
              "$ref": "common.schema.json#/$defs/EntityId"
            }
          },
          "required": ["mediaId"]
        },
        {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "rendition": {
              "$ref": "enums.schema.json#/$defs/RenditionKind"
            }
          },
          "required": ["rendition"]
        }
      ]
    },
    "DeclaredMetadata": {
      "title": "DeclaredMetadata",
      "description": "Musical fields the creator typed; every key optional, each overrides embedded and analysed values of the same field.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "tempoBpm": {
          "type": "number",
          "minimum": 20,
          "maximum": 400
        },
        "meter": {
          "$ref": "#/$defs/Meter"
        },
        "keyRoot": {
          "type": "integer",
          "minimum": 0,
          "maximum": 11,
          "description": "Pitch class of the key root: 0 = C … 11 = B."
        },
        "mode": {
          "$ref": "enums.schema.json#/$defs/MusicalMode"
        },
        "tonality": {
          "$ref": "enums.schema.json#/$defs/Tonality"
        },
        "rootMidi": {
          "type": "integer",
          "minimum": 0,
          "maximum": 127,
          "description": "MIDI note of a tuned one-shot."
        },
        "instruments": {
          "type": "array",
          "maxItems": 8,
          "uniqueItems": true,
          "items": {
            "$ref": "media-vocabulary.schema.json#/$defs/Instrument"
          }
        },
        "genres": {
          "type": "array",
          "maxItems": 4,
          "uniqueItems": true,
          "items": {
            "$ref": "media-vocabulary.schema.json#/$defs/Genre"
          }
        },
        "moods": {
          "type": "array",
          "maxItems": 3,
          "uniqueItems": true,
          "items": {
            "$ref": "media-vocabulary.schema.json#/$defs/Mood"
          }
        }
      }
    },
    "RecordedLocation": {
      "title": "RecordedLocation",
      "description": "Where a recording was made.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "name": {
          "type": "string",
          "minLength": 0,
          "maxLength": 128
        },
        "lat": {
          "type": "number",
          "minimum": -90,
          "maximum": 90
        },
        "lon": {
          "type": "number",
          "minimum": -180,
          "maximum": 180
        }
      },
      "required": ["name"]
    },
    "SoundSource": {
      "title": "SoundSource",
      "description": "The Toy a sound was recorded or exported from.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "projectId": {
          "$ref": "common.schema.json#/$defs/EntityId"
        },
        "releaseDigest": {
          "$ref": "common.schema.json#/$defs/Sha256Hex"
        },
        "takeId": {
          "$ref": "common.schema.json#/$defs/EntityId"
        }
      },
      "required": ["projectId"]
    },
    "ResolvedNumber": {
      "title": "ResolvedNumber",
      "description": "A numeric field with its provenance.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "value": {
          "type": "number"
        },
        "source": {
          "$ref": "enums.schema.json#/$defs/MetadataSource"
        },
        "confidence": {
          "type": "number",
          "minimum": 0,
          "maximum": 1,
          "description": "0 (a guess) to 1 (certain)."
        }
      },
      "required": ["value", "source"]
    },
    "ResolvedKeyRoot": {
      "title": "ResolvedKeyRoot",
      "description": "The key root with its provenance.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "value": {
          "type": "integer",
          "minimum": 0,
          "maximum": 11,
          "description": "Pitch class of the key root: 0 = C … 11 = B."
        },
        "source": {
          "$ref": "enums.schema.json#/$defs/MetadataSource"
        },
        "confidence": {
          "type": "number",
          "minimum": 0,
          "maximum": 1,
          "description": "0 (a guess) to 1 (certain)."
        }
      },
      "required": ["value", "source"]
    },
    "ResolvedMode": {
      "title": "ResolvedMode",
      "description": "The mode with its provenance.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "value": {
          "$ref": "enums.schema.json#/$defs/MusicalMode"
        },
        "source": {
          "$ref": "enums.schema.json#/$defs/MetadataSource"
        },
        "confidence": {
          "type": "number",
          "minimum": 0,
          "maximum": 1,
          "description": "0 (a guess) to 1 (certain)."
        }
      },
      "required": ["value", "source"]
    },
    "ResolvedTonality": {
      "title": "ResolvedTonality",
      "description": "The tonality with its provenance.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "value": {
          "$ref": "enums.schema.json#/$defs/Tonality"
        },
        "source": {
          "$ref": "enums.schema.json#/$defs/MetadataSource"
        },
        "confidence": {
          "type": "number",
          "minimum": 0,
          "maximum": 1,
          "description": "0 (a guess) to 1 (certain)."
        }
      },
      "required": ["value", "source"]
    },
    "ResolvedCamelot": {
      "title": "ResolvedCamelot",
      "description": "The Camelot code derived from the resolved root and tonality.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "value": {
          "type": "string",
          "pattern": "^(1[0-2]|[1-9])[AB]$",
          "description": "Camelot wheel code: 1A–12A minor, 1B–12B major."
        },
        "source": {
          "$ref": "enums.schema.json#/$defs/MetadataSource"
        },
        "confidence": {
          "type": "number",
          "minimum": 0,
          "maximum": 1,
          "description": "0 (a guess) to 1 (certain)."
        }
      },
      "required": ["value", "source"]
    },
    "ResolvedMeter": {
      "title": "ResolvedMeter",
      "description": "The meter with its provenance.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "value": {
          "$ref": "#/$defs/Meter"
        },
        "source": {
          "$ref": "enums.schema.json#/$defs/MetadataSource"
        },
        "confidence": {
          "type": "number",
          "minimum": 0,
          "maximum": 1,
          "description": "0 (a guess) to 1 (certain)."
        }
      },
      "required": ["value", "source"]
    },
    "ResolvedSoundType": {
      "title": "ResolvedSoundType",
      "description": "The sound type with its provenance.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "value": {
          "$ref": "enums.schema.json#/$defs/SoundType"
        },
        "source": {
          "$ref": "enums.schema.json#/$defs/MetadataSource"
        },
        "confidence": {
          "type": "number",
          "minimum": 0,
          "maximum": 1,
          "description": "0 (a guess) to 1 (certain)."
        }
      },
      "required": ["value", "source"]
    },
    "ResolvedInstruments": {
      "title": "ResolvedInstruments",
      "description": "Instrument tags with their provenance.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "value": {
          "type": "array",
          "maxItems": 8,
          "uniqueItems": true,
          "items": {
            "$ref": "media-vocabulary.schema.json#/$defs/Instrument"
          }
        },
        "source": {
          "$ref": "enums.schema.json#/$defs/MetadataSource"
        },
        "confidence": {
          "type": "number",
          "minimum": 0,
          "maximum": 1,
          "description": "0 (a guess) to 1 (certain)."
        }
      },
      "required": ["value", "source"]
    },
    "ResolvedGenres": {
      "title": "ResolvedGenres",
      "description": "Genre tags with their provenance.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "value": {
          "type": "array",
          "maxItems": 4,
          "uniqueItems": true,
          "items": {
            "$ref": "media-vocabulary.schema.json#/$defs/Genre"
          }
        },
        "source": {
          "$ref": "enums.schema.json#/$defs/MetadataSource"
        },
        "confidence": {
          "type": "number",
          "minimum": 0,
          "maximum": 1,
          "description": "0 (a guess) to 1 (certain)."
        }
      },
      "required": ["value", "source"]
    },
    "ResolvedMoods": {
      "title": "ResolvedMoods",
      "description": "Mood tags with their provenance.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "value": {
          "type": "array",
          "maxItems": 3,
          "uniqueItems": true,
          "items": {
            "$ref": "media-vocabulary.schema.json#/$defs/Mood"
          }
        },
        "source": {
          "$ref": "enums.schema.json#/$defs/MetadataSource"
        },
        "confidence": {
          "type": "number",
          "minimum": 0,
          "maximum": 1,
          "description": "0 (a guess) to 1 (certain)."
        }
      },
      "required": ["value", "source"]
    },
    "SoundResolvedFields": {
      "title": "SoundResolvedFields",
      "description": "The resolved musical fields of an item: declared › embedded › analysed, each keeping its source. A field absent from every layer is absent here.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "durationMs": {
          "$ref": "#/$defs/ResolvedNumber"
        },
        "tempoBpm": {
          "$ref": "#/$defs/ResolvedNumber"
        },
        "keyRoot": {
          "$ref": "#/$defs/ResolvedKeyRoot"
        },
        "mode": {
          "$ref": "#/$defs/ResolvedMode"
        },
        "tonality": {
          "$ref": "#/$defs/ResolvedTonality"
        },
        "camelot": {
          "$ref": "#/$defs/ResolvedCamelot"
        },
        "meter": {
          "$ref": "#/$defs/ResolvedMeter"
        },
        "rootMidi": {
          "$ref": "#/$defs/ResolvedNumber"
        },
        "loudnessLufs": {
          "$ref": "#/$defs/ResolvedNumber"
        },
        "soundType": {
          "$ref": "#/$defs/ResolvedSoundType"
        },
        "instruments": {
          "$ref": "#/$defs/ResolvedInstruments"
        },
        "genres": {
          "$ref": "#/$defs/ResolvedGenres"
        },
        "moods": {
          "$ref": "#/$defs/ResolvedMoods"
        }
      }
    }
  }
}
