* test(web): use safe auth placeholders * feat(settings): sync navigation and card customization * fix(settings): address customization review feedback * fix(settings): address customization review feedback * fix(settings): harden customization capability handling
87 lines
3.0 KiB
JSON
87 lines
3.0 KiB
JSON
{
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"$id": "https://silo-server.dev/contracts/settings/v1/schemas/primary-menu.json",
|
|
"title": "Primary navigation menu",
|
|
"description": "Ordered visible destinations for one client family. Search and profile controls are fixed client utilities and are intentionally absent.",
|
|
"$comment": "Contract validation also rejects repeated semantic destination identities even when labels differ: builtin(destination), library(library_id), section(library_id, section_id), collection(optional library_id, collection_id).",
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["items"],
|
|
"properties": {
|
|
"items": {
|
|
"description": "Ordered destinations. Each semantic destination identity may appear at most once; changing its label does not create a distinct destination.",
|
|
"type": "array",
|
|
"minItems": 1,
|
|
"maxItems": 64,
|
|
"uniqueItems": true,
|
|
"contains": {
|
|
"type": "object",
|
|
"required": ["type", "destination"],
|
|
"properties": {
|
|
"type": { "const": "builtin" },
|
|
"destination": { "const": "home" }
|
|
}
|
|
},
|
|
"minContains": 1,
|
|
"maxContains": 1,
|
|
"items": {
|
|
"oneOf": [
|
|
{ "$ref": "#/$defs/builtin" },
|
|
{ "$ref": "#/$defs/library" },
|
|
{ "$ref": "#/$defs/section" },
|
|
{ "$ref": "#/$defs/collection" }
|
|
]
|
|
}
|
|
}
|
|
},
|
|
"$defs": {
|
|
"label": { "type": "string", "minLength": 1, "maxLength": 256, "pattern": "\\S" },
|
|
"libraryId": { "type": "integer", "minimum": 1 },
|
|
"targetId": { "type": "string", "minLength": 1, "maxLength": 128, "pattern": "\\S" },
|
|
"builtin": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["type", "destination"],
|
|
"properties": {
|
|
"type": { "const": "builtin" },
|
|
"destination": {
|
|
"type": "string",
|
|
"enum": ["home", "movies", "series", "music", "audiobooks", "for_you", "calendar"]
|
|
}
|
|
}
|
|
},
|
|
"library": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["type", "library_id", "label"],
|
|
"properties": {
|
|
"type": { "const": "library" },
|
|
"library_id": { "$ref": "#/$defs/libraryId" },
|
|
"label": { "$ref": "#/$defs/label" }
|
|
}
|
|
},
|
|
"section": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["type", "library_id", "section_id", "label"],
|
|
"properties": {
|
|
"type": { "const": "section" },
|
|
"library_id": { "$ref": "#/$defs/libraryId" },
|
|
"section_id": { "$ref": "#/$defs/targetId" },
|
|
"label": { "$ref": "#/$defs/label" }
|
|
}
|
|
},
|
|
"collection": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["type", "collection_id", "label"],
|
|
"properties": {
|
|
"type": { "const": "collection" },
|
|
"collection_id": { "$ref": "#/$defs/targetId" },
|
|
"library_id": { "$ref": "#/$defs/libraryId" },
|
|
"label": { "$ref": "#/$defs/label" }
|
|
}
|
|
}
|
|
}
|
|
}
|