{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://ihgiz.net/api/engine/v0/documents/template-manifest.schema.json","title":"Template manifest","description":"What a template is, in data: its name and version, the engine versions it runs on, what it calls the Event and the people taking part, its event types, its own entities, and the state graphs that move them. The engine never branches on a template; it reads this (decision D1).","type":"object","required":["id","version","engine","names","roles","eventTypes","stateGraphs"],"properties":{"$schema":{"type":"string"},"id":{"description":"Stable template identifier, also its table prefix.","$ref":"state-graph.schema.json#/$defs/key"},"version":{"description":"The template's own version (Semantic Versioning 2.0.0).","type":"string","pattern":"^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(-[0-9A-Za-z.-]+)?$"},"engine":{"description":"The engine versions this template supports, as a caret range on the engine contract's major version.","type":"string","pattern":"^\\^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)$"},"domain":{"description":"The product domain this template is served on (decision D11).","type":"string","format":"hostname"},"names":{"description":"What this template calls things a person reads. The engine's own word is Event; a template may call it a reservation, an appointment or anything else.","type":"object","required":["event"],"properties":{"event":{"$ref":"#/$defs/nounLabels"},"participant":{"$ref":"#/$defs/nounLabels"}},"additionalProperties":false},"roles":{"description":"The roles a person (or a resource) can have on this template's Events. Each maps to the standard JSCalendar participant roles, so calendars and integrations understand it without knowing the template.","type":"array","minItems":1,"items":{"$ref":"#/$defs/role"}},"eventTypes":{"type":"array","minItems":1,"items":{"$ref":"#/$defs/eventType"}},"entities":{"description":"The template's own records that are not Events: tickets, memberships, cars, deals. Each attaches to an Event, a participant or a person, and may have its own stages.","type":"array","items":{"$ref":"#/$defs/entity"}},"facets":{"description":"What a viewer can hold that decides which console items they see — a role, what a business sells — and the values each takes. Read by the platform's shells, never by the engine.","type":"object","propertyNames":{"$ref":"#/$defs/navKey"},"additionalProperties":{"type":"array","minItems":1,"uniqueItems":true,"items":{"$ref":"#/$defs/navKey"}}},"consoles":{"description":"The template's consoles: a tenant's (the product's admin) and the operator's, each as groups of destinations. The platform's shells turn one into the navigation a viewer sees; the product draws it in its own look (Phase 3b.5b).","type":"object","propertyNames":{"$ref":"#/$defs/navKey"},"additionalProperties":{"$ref":"#/$defs/console"}},"scenes":{"description":"The illustrations the template registers by key, so a page block can name one.","type":"array","uniqueItems":true,"items":{"$ref":"#/$defs/navKey"}},"stateGraphs":{"type":"object","minProperties":1,"propertyNames":{"$ref":"state-graph.schema.json#/$defs/key"},"additionalProperties":{"$ref":"state-graph.schema.json"}}},"additionalProperties":false,"$defs":{"navKey":{"type":"string","pattern":"^[a-z][A-Za-z0-9]*$","maxLength":64},"console":{"type":"object","required":["audience","root","groups"],"properties":{"audience":{"enum":["tenant","operator"]},"root":{"description":"The console's home, from the product's locale root.","type":"string","pattern":"^/"},"title":{"description":"What the platform console calls an operator console.","type":"string","minLength":1},"groups":{"type":"array","minItems":1,"items":{"$ref":"#/$defs/consoleGroup"}}},"additionalProperties":false},"consoleGroup":{"type":"object","required":["key","items"],"properties":{"key":{"$ref":"#/$defs/navKey"},"heading":{"description":"False for a group shown without a heading.","type":"boolean"},"operator":{"description":"This group is the operator's own tools inside a tenant console, by the name the platform console shows.","type":"string","minLength":1},"items":{"type":"array","minItems":1,"items":{"$ref":"#/$defs/consoleItem"}}},"additionalProperties":false},"consoleItem":{"type":"object","required":["key","path","icon"],"properties":{"key":{"description":"Also the item's label key in the console's messages.","$ref":"#/$defs/navKey"},"path":{"description":"Where it goes, from the product's locale root.","type":"string","pattern":"^/[A-Za-z0-9/_-]*$"},"icon":{"description":"The glyph's name; each product draws its own.","$ref":"#/$defs/navKey"},"badge":{"description":"Which of the viewer's counts it shows.","$ref":"#/$defs/navKey"},"when":{"description":"For each facet named, the viewer must hold one of these values.","type":"object","propertyNames":{"$ref":"#/$defs/navKey"},"additionalProperties":{"type":"array","minItems":1,"uniqueItems":true,"items":{"$ref":"#/$defs/navKey"}}}},"additionalProperties":false},"nounLabels":{"description":"Singular and plural display names by BCP 47 language tag; English required.","type":"object","required":["en"],"propertyNames":{"pattern":"^[a-z]{2,3}(-[A-Za-z0-9]{2,8})*$"},"additionalProperties":{"type":"object","required":["one","other"],"properties":{"one":{"type":"string","minLength":1},"other":{"type":"string","minLength":1}},"additionalProperties":false}},"role":{"type":"object","required":["key","standard","kind","labels"],"properties":{"key":{"$ref":"state-graph.schema.json#/$defs/key"},"standard":{"description":"JSCalendar participant roles (RFC 8984 §4.4.6).","type":"array","minItems":1,"uniqueItems":true,"items":{"enum":["owner","attendee","optional","informational","chair","contact"]}},"kind":{"description":"JSCalendar participant kind: a person, a group, a place or a resource such as a car or a bay.","enum":["individual","group","location","resource"]},"labels":{"$ref":"state-graph.schema.json#/$defs/labels"},"permissions":{"description":"Capabilities this role holds on an Event it is part of.","type":"array","uniqueItems":true,"items":{"$ref":"state-graph.schema.json#/$defs/capability"}}},"additionalProperties":false},"eventType":{"type":"object","required":["key","labels","graph","roles"],"properties":{"key":{"$ref":"state-graph.schema.json#/$defs/key"},"labels":{"$ref":"state-graph.schema.json#/$defs/labels"},"graph":{"description":"The event graph for this type.","$ref":"state-graph.schema.json#/$defs/key"},"participationGraph":{"description":"The graph each participant's part follows, when it has stages beyond a plain reply.","$ref":"state-graph.schema.json#/$defs/key"},"roles":{"type":"array","minItems":1,"uniqueItems":true,"items":{"$ref":"state-graph.schema.json#/$defs/key"}},"defaultDuration":{"description":"ISO 8601 duration, JSCalendar form.","type":"string","pattern":"^P(\\d+W)?(\\d+D)?(T(\\d+H)?(\\d+M)?(\\d+S)?)?$"},"fields":{"description":"Template fields on this type's Events, as a JSON Schema for the Event's ihgiz.net:fields object.","type":"object"}},"additionalProperties":false},"entity":{"type":"object","required":["key","labels","attaches"],"properties":{"key":{"$ref":"state-graph.schema.json#/$defs/key"},"labels":{"$ref":"state-graph.schema.json#/$defs/labels"},"attaches":{"enum":["event","participant","party","tenant"]},"graph":{"$ref":"state-graph.schema.json#/$defs/key"},"fields":{"description":"The entity's attributes, as a JSON Schema.","type":"object"}},"additionalProperties":false}}}