diff --git a/services/ontology/schemas/calendarEvent.json b/services/ontology/schemas/calendarEvent.json index ed38616ef..f9f3b62a4 100644 --- a/services/ontology/schemas/calendarEvent.json +++ b/services/ontology/schemas/calendarEvent.json @@ -8,21 +8,52 @@ "type": "string", "description": "Event title" }, - "id": { "type": "string", "description": "Application-level event identifier" }, - "userEName": { "type": "string", "description": "eName of the user whose calendar contains the event" }, - "provider": { "type": "string", "enum": ["google", "manual"] }, - "externalEventId": { "type": "string" }, - "calendarId": { "type": "string" }, - "canonicalOwnerEName": { "type": "string" }, - "description": { "type": "string" }, - "location": { "type": "string" }, + "id": { + "type": "string", + "description": "Application-level event identifier" + }, + "userEName": { + "type": "string", + "description": "eName of the user whose calendar contains the event" + }, + "provider": { + "type": "string", + "enum": [ + "google", + "manual" + ] + }, + "externalEventId": { + "type": "string" + }, + "calendarId": { + "type": "string" + }, + "canonicalOwnerEName": { + "type": "string" + }, + "description": { + "type": "string" + }, + "location": { + "type": "string" + }, "color": { "type": "string", "description": "Event color (hex or named)" }, - "textColor": { "type": "string" }, - "providerColorId": { "type": ["string", "null"] }, - "canEdit": { "type": "boolean" }, + "textColor": { + "type": "string" + }, + "providerColorId": { + "type": [ + "string", + "null" + ] + }, + "canEdit": { + "type": "boolean" + }, "start": { "type": "string", "format": "date-time", @@ -33,16 +64,82 @@ "format": "date-time", "description": "Event end time (ISO 8601)" }, - "isAllDay": { "type": "boolean" }, - "status": { "type": "string", "enum": ["confirmed", "tentative", "cancelled"] }, - "attendees": { "type": "array", "items": { "type": "string" } }, - "isTransparent": { "type": "boolean" }, - "htmlLink": { "type": "string", "format": "uri" }, - "sourceUpdatedAt": { "type": "string", "format": "date-time" }, - "effectiveAcl": { "type": "array", "items": { "type": "string" } }, - "createdAt": { "type": "string", "format": "date-time" }, - "updatedAt": { "type": "string", "format": "date-time" } + "isAllDay": { + "type": "boolean" + }, + "status": { + "type": "string", + "enum": [ + "confirmed", + "tentative", + "cancelled" + ] + }, + "attendees": { + "type": "array", + "items": { + "type": "string" + } + }, + "isTransparent": { + "type": "boolean" + }, + "htmlLink": { + "type": "string", + "format": "uri" + }, + "sourceUpdatedAt": { + "type": "string", + "format": "date-time" + }, + "effectiveAcl": { + "type": "array", + "items": { + "type": "string" + } + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + }, + "responseOptions": { + "type": "array", + "description": "Optional RSVP-style choices a reader can respond with. A tap is recorded as a Relation (predicate 'respond', object = this event's uri, value = chosen). Poll/Vote model options natively and do not use this.", + "items": { + "type": "object", + "required": [ + "id", + "label" + ], + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "value": { + "type": "string" + }, + "kind": { + "type": "string", + "enum": [ + "choice" + ], + "default": "choice" + } + } + } + } }, - "required": ["title", "start", "end"], + "required": [ + "title", + "start", + "end" + ], "additionalProperties": false } diff --git a/services/ontology/schemas/communityActivity.json b/services/ontology/schemas/communityActivity.json new file mode 100644 index 000000000..8ac23f98d --- /dev/null +++ b/services/ontology/schemas/communityActivity.json @@ -0,0 +1,58 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "schemaId": "c0117a17-1b2c-4d3e-8f4a-5b6c7d8e9f01", + "title": "CommunityActivity", + "type": "object", + "description": "A generic, domain-level 'a platform posted something to a community that members see and may respond to'. NOT a presentation container: activityType follows W3C ActivityStreams and carries the meaning; the renderer decides the look. Prefer a more specific ontology when one fits (CalendarEvent, Poll). CommunityActivity is the general case AND the fallback a renderer uses for any envelope it doesn't specifically know but that carries summary + responseOptions. Responses are recorded as separate Relation envelopes (predicate 'respond'), authored by the responder.", + "properties": { + "id": { "type": "string" }, + "chatId": { "type": "string", "description": "The chat this activity surfaces in" }, + "activityType": { + "type": "string", + "enum": ["announce", "question", "offer", "invite", "acknowledge"], + "description": "W3C ActivityStreams verb — the semantics of the activity" + }, + "summary": { "type": "string", "description": "Human-visible headline (domain field, not 'title')" }, + "description": { "type": "string" }, + "relatedSubject": { + "type": "object", + "description": "Optional pointer to the domain object this activity is about", + "properties": { + "id": { "type": "string" }, + "ontologyId": { "type": "string" }, + "canonicalOwnerEName": { "type": "string" }, + "canonicalEnvelopeId": { "type": ["string", "null"] }, + "type": { "type": "string" } + }, + "required": ["id"] + }, + "responseOptions": { + "type": "array", + "description": "Optional choices the reader can respond with. A tap is recorded as a Relation (predicate 'respond', object = this envelope's uri, value = the chosen option value/id). Single mutually-exclusive choice only. Poll/Vote do NOT use this — they model options natively.", + "items": { + "type": "object", + "properties": { + "id": { "type": "string", "description": "Stable id; group responses by this (or value) for a tally" }, + "label": { "type": "string", "description": "Human-visible button text" }, + "value": { "type": "string", "description": "Semantic value recorded in the response (defaults to id)" }, + "kind": { "type": "string", "enum": ["choice"], "default": "choice" } + }, + "required": ["id", "label"] + } + }, + "display": { + "type": "object", + "description": "Presentation HINTS only — renderers MAY ignore. Keeps UI out of the domain fields", + "properties": { + "pinned": { "type": "boolean" }, + "removable": { "type": "boolean" }, + "category": { "type": "string" } + } + }, + "authorEName": { "type": "string", "description": "eName of the producing platform/app" }, + "createdAt": { "type": "string", "format": "date-time" }, + "isArchived": { "type": "boolean", "default": false } + }, + "required": ["id", "chatId", "activityType", "summary", "createdAt"], + "additionalProperties": true +}