From 5f0abd93272b6e1942031325827a874ddda6590e Mon Sep 17 00:00:00 2001 From: AI Date: Thu, 14 May 2026 13:52:38 +0000 Subject: [PATCH 1/2] docs(events): Shadow Update fields nullable + promote auto-gen schema files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two related fixes after the recent b2c-api work: 1. **events-catalog.mdx — Shadow Update nullability.** Real AWS-delivered `spk.iot.shadow@Shadow Update` events have `null` in fields the doc previously typed as `string`. The b2c-api Zod schema was relaxed today to match reality (PR #129 — SPK-API-V). Partner-facing types updated: - `desiredState`: string → string\|null (null when no desired state set; observed in ~50% of real events) - `reportedState`: string → string\|null (null for never-reported) - `metadata`: string → string\|null - `version`: number → number\|null (null on first event) - `partnerId`: already string\|null (no change) Added explicit guidance: only `thingName` and `deltaState` are guaranteed non-null; plan for null on every other field. 2. **events-webhooks.mdx — Schema & Code Generation section rewritten.** The old section pointed at `eventbridge-schemas.yaml` with a "lags the catalog" caveat. The repo now has TWO auto-generated JSON Schema files regenerated on every b2c-api deploy: - `event-schemas.json` ← `GET /schemas/events.json` - `command-schemas.json` ← `GET /schemas/commands.json` Both carry a `version` field (worker git SHA) for staleness detection. Added paste-ready recipes for Pydantic v2, TypeScript, and any-language via quicktype. Also called out that the Shadow Update envelope lives in the catalog page (separate shape from spk.api events) and that the API Reference tab covers the full OpenAPI surface. No content change to event-type lists or other partner-facing docs — those were refreshed last week and remain accurate. --- events-catalog.mdx | 18 ++++++++++-------- events-webhooks.mdx | 45 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 45 insertions(+), 18 deletions(-) diff --git a/events-catalog.mdx b/events-catalog.mdx index 2cea31d..e045875 100644 --- a/events-catalog.mdx +++ b/events-catalog.mdx @@ -349,12 +349,14 @@ This event has a **different envelope** from `spk.api` events — there is no `d | Field | Type | Description | |-------|------|-------------| | `thingName` | string | AWS IoT thing name of the device | -| `partnerId` | string\|null | Partner associated with this device | -| `version` | number | Shadow document version | -| `desiredState` | string | Target state set by the application (JSON string) | -| `reportedState` | string | State the device reported back (JSON string) | -| `deltaState` | string | Difference between desired and reported state (JSON string); non-empty when the device hasn't applied all changes | -| `metadata` | string | AWS IoT shadow metadata with timestamps per field (JSON string) | +| `partnerId` | string\|null | Partner associated with this device; `null` when the device's IoT thing has no `Org` attribute yet | +| `version` | number\|null | Shadow document version; `null` for the device's very first shadow event | +| `desiredState` | string\|null | Target state set by the application (JSON string); `null` when no desired state has ever been set — common for idle devices | +| `reportedState` | string\|null | State the device reported back (JSON string); `null` when the device has not yet reported any state | +| `deltaState` | string | Difference between desired and reported state (JSON string); always populated (`"{}"` when no delta) | +| `metadata` | string\|null | AWS IoT shadow metadata with timestamps per field (JSON string); `null` when the device hasn't produced metadata yet | + +Only `thingName` and `deltaState` are guaranteed non-null. **Plan for `null` on all other fields** when consuming Shadow Update events — roughly half of real-world events have at least one null field (typically `desiredState` for devices that never received a desired-state update). **Example payload:** @@ -366,7 +368,7 @@ This event has a **different envelope** from `spk.api` events — there is no `d "partnerId": "", "thingName": "", "reportedState": "", - "desiredState": "", + "desiredState": null, "deltaState": "{}", "metadata": "", "version": 42 @@ -374,4 +376,4 @@ This event has a **different envelope** from `spk.api` events — there is no `d } ``` -Note: `reportedState`, `desiredState`, `deltaState`, and `metadata` are **stringified JSON** embedded inside the outer JSON object. Partners must call `JSON.parse()` on each of these fields before accessing their contents. +Note: when `reportedState`, `desiredState`, `deltaState`, or `metadata` is non-null, the value is **stringified JSON** embedded inside the outer JSON object. Call `JSON.parse()` on each non-null field before accessing its contents. diff --git a/events-webhooks.mdx b/events-webhooks.mdx index 03616fc..f03537a 100644 --- a/events-webhooks.mdx +++ b/events-webhooks.mdx @@ -348,21 +348,46 @@ To narrow later, replace `events` with an explicit list of PascalCase `detail-ty ## Schema & Code Generation -Download the OpenAPI schema to scaffold your webhook handler: +Two auto-generated JSON Schema files are published in this repo and regenerated on every b2c-api deploy. They are the authoritative description of the `detail.data` payload for every `spk.api` event and the request body of every API command: -**Download:** [eventbridge-schemas.yaml](https://raw.githubusercontent.com/spk-alex/documentationai-Docs/main/eventbridge-schemas.yaml) +| File | Source endpoint | Contents | +|------|-----------------|----------| +| [event-schemas.json](https://raw.githubusercontent.com/spk-alex/documentationai-Docs/main/event-schemas.json) | `GET /schemas/events.json` on b2c-api | JSON Schema for every `spk.api` event's `detail.data` payload | +| [command-schemas.json](https://raw.githubusercontent.com/spk-alex/documentationai-Docs/main/command-schemas.json) | `GET /schemas/commands.json` on b2c-api | JSON Schema for every API command request body | -Generate a typed client: +Both files carry a `version` field (the worker's git SHA) so you can detect a stale local copy. The `events` / `commands` map keys are PascalCase identifiers matching the EventBridge `detail-type` (events) or the route path's command name (commands). + +### Generate typed models + +**Pydantic v2 (Python):** ```bash -# TypeScript -npx openapi-generator-cli generate -i eventbridge-schemas.yaml -g typescript-fetch -o ./generated +curl -s https://raw.githubusercontent.com/spk-alex/documentationai-Docs/main/event-schemas.json \ + | jq '.events' \ + | datamodel-codegen --input - --input-file-type jsonschema \ + --output-model-type pydantic_v2.BaseModel --output events.py +``` -# Python -openapi-generator-cli generate -i eventbridge-schemas.yaml -g python -o ./generated +**TypeScript:** -# Go -openapi-generator-cli generate -i eventbridge-schemas.yaml -g go -o ./generated +```bash +curl -s https://raw.githubusercontent.com/spk-alex/documentationai-Docs/main/event-schemas.json \ + | jq '.events' \ + | npx -y json-schema-to-typescript -o events.d.ts ``` -The bundled schema currently lags the full event catalog above — regeneration from the b2c-api source is tracked separately. Use the tables in this page as the authoritative list of emitted `detail-type`s in the meantime. +**Any language via quicktype:** + +```bash +curl -s https://raw.githubusercontent.com/spk-alex/documentationai-Docs/main/event-schemas.json \ + | jq '.events' \ + | npx -y quicktype --src-lang schema --lang go --out events.go +``` + +### The Shadow Update envelope + +`event-schemas.json` covers `spk.api` events only. The `spk.iot.shadow@Shadow Update` envelope (different `detail` shape — flat fields, no `detail.data` wrapper) is documented under [Event Catalog → Shadow Update](/events-catalog#shadow-update). Plan for `null` on most fields when consuming Shadow Update events; only `thingName` and `deltaState` are guaranteed non-null. + +### Full REST API + +For the full OpenAPI surface (request/response shapes of every endpoint), see the **API Reference** tab — it renders from `openapi.yaml`, regenerated by the same b2c-api CI. From 72e4cb48ecd5e3e7f2b39e86bc1bdf6fe3a7c8a4 Mon Sep 17 00:00:00 2001 From: AI Date: Tue, 19 May 2026 14:38:58 +0000 Subject: [PATCH 2/2] chore: manual publishDocs sync from b2c-api nonprod MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CI publishDocs step keeps getting cancelled by sibling test() failure (3dEye 429 rate-limit in camera-role acceptance tests). The deployed b2c-api worker (version 32d654a1, nonprod) has the correct OpenAPI including /cameras/my and /cameras/{id}/stream and updated CreateCameraRole schema — but docs repo was 5 days stale. Synced manually with the same jq sanitization + yq YAML conversion publishDocs does. Will roll back to CI-driven once acceptance flakiness is sorted. Co-Authored-By: Claude Opus 4.7 (1M context) --- command-schemas.json | 1218 +---------------------------- event-schemas.json | 1724 +----------------------------------------- openapi.yaml | 875 ++++++++++++++++++++- 3 files changed, 850 insertions(+), 2967 deletions(-) diff --git a/command-schemas.json b/command-schemas.json index a7144ad..94b0a2e 100644 --- a/command-schemas.json +++ b/command-schemas.json @@ -1,1217 +1 @@ -{ - "version": "eb194fa5", - "schemaDraft": "https://json-schema.org/draft/2020-12/schema", - "commands": { - "CreateLock": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "index": { - "type": "integer", - "exclusiveMinimum": 0, - "maximum": 9007199254740991, - "description": "Lock index number" - }, - "uuid": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$", - "description": "Lock UUID" - }, - "serialNumber": { - "description": "Serial number", - "type": "string" - }, - "vendorName": { - "description": "Vendor/manufacturer name", - "type": "string" - }, - "ownerId": { - "description": "Owner user ID", - "type": "string" - }, - "keys": { - "default": [], - "description": "Initial keys", - "type": "array", - "items": { - "type": "object", - "properties": { - "uuid": { - "type": "string" - }, - "indexNumber": { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991 - }, - "userId": { - "type": "string" - } - }, - "required": [ - "uuid" - ], - "additionalProperties": false - } - } - }, - "required": [ - "index", - "uuid", - "keys" - ], - "additionalProperties": false - }, - "AddKey": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "keyUuid": { - "type": "string", - "description": "Key identifier" - }, - "keyIndexNumber": { - "description": "Physical key index", - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991 - }, - "userId": { - "description": "User ID", - "type": "string" - } - }, - "required": [ - "keyUuid" - ], - "additionalProperties": false - }, - "RemoveKey": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "keyUuid": { - "description": "Key identifier", - "type": "string" - }, - "keyIndexNumber": { - "description": "Physical key index", - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991 - } - }, - "additionalProperties": false - }, - "WriteKey": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "keyUuid": { - "type": "string", - "minLength": 1, - "description": "Key identifier to write to device firmware" - }, - "keyIndexNumber": { - "description": "Physical key index on device", - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991 - } - }, - "required": [ - "keyUuid" - ], - "additionalProperties": false - }, - "AddResident": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "email": { - "type": "string", - "format": "email", - "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$", - "description": "Resident email — server resolves to the user UUID via D1" - }, - "name": { - "type": "string", - "minLength": 1, - "description": "Resident name" - } - }, - "required": [ - "email", - "name" - ], - "additionalProperties": false - }, - "RemoveResident": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "email": { - "type": "string", - "format": "email", - "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$", - "description": "Resident email to remove" - } - }, - "required": [ - "email" - ], - "additionalProperties": false - }, - "SetOwner": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "userId": { - "type": "string", - "description": "User ID to set as owner" - } - }, - "required": [ - "userId" - ], - "additionalProperties": false - }, - "SetOrganization": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "orgId": { - "type": "string", - "description": "Organization ID" - } - }, - "required": [ - "orgId" - ], - "additionalProperties": false - }, - "ChangeLockUuid": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "newUuid": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$", - "description": "New UUID for the lock" - } - }, - "required": [ - "newUuid" - ], - "additionalProperties": false - }, - "OpenLock": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "requestId": { - "description": "Request tracking ID", - "type": "string" - }, - "reason": { - "description": "Reason for opening", - "type": "string" - } - }, - "additionalProperties": false - }, - "BulkAddKeys": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "keys": { - "minItems": 1, - "type": "array", - "items": { - "type": "object", - "properties": { - "keyUuid": { - "type": "string", - "description": "Key identifier" - }, - "keyIndexNumber": { - "description": "Physical key index", - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991 - }, - "userId": { - "description": "User ID", - "type": "string" - } - }, - "required": [ - "keyUuid" - ], - "additionalProperties": false - }, - "description": "List of keys to add to the lock" - } - }, - "required": [ - "keys" - ], - "additionalProperties": false - }, - "create-temp-key": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "tempKeyUuid": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$" - }, - "accessMode": { - "type": "string", - "enum": [ - "public", - "user-whitelist" - ] - }, - "allowedUserIds": { - "default": [], - "type": "array", - "items": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$" - } - }, - "validFrom": { - "type": "string", - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" - }, - "validUntil": { - "type": "string", - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" - }, - "maxUses": { - "anyOf": [ - { - "type": "integer", - "exclusiveMinimum": 0, - "maximum": 9007199254740991 - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "tempKeyUuid", - "accessMode", - "allowedUserIds", - "validFrom", - "validUntil" - ], - "additionalProperties": false - }, - "delete-temp-key": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "tempKeyUuid": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$" - } - }, - "required": [ - "tempKeyUuid" - ], - "additionalProperties": false - }, - "update-temp-key": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "tempKeyUuid": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$" - }, - "validFrom": { - "type": "string", - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" - }, - "validUntil": { - "type": "string", - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$" - }, - "maxUses": { - "anyOf": [ - { - "type": "integer", - "exclusiveMinimum": 0, - "maximum": 9007199254740991 - }, - { - "type": "null" - } - ] - }, - "allowedUserIds": { - "type": "array", - "items": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$" - } - }, - "accessMode": { - "type": "string", - "enum": [ - "public", - "user-whitelist" - ] - } - }, - "required": [ - "tempKeyUuid" - ], - "additionalProperties": false - }, - "CreateUser": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "userId": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$", - "description": "User UUID" - }, - "email": { - "type": "string", - "format": "email", - "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$", - "description": "User email" - }, - "firstName": { - "description": "First name", - "type": "string" - }, - "lastName": { - "description": "Last name", - "type": "string" - }, - "phoneNumber": { - "description": "Phone number", - "type": "string" - } - }, - "required": [ - "userId", - "email" - ], - "additionalProperties": false - }, - "AddAccessibleLock": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "lockId": { - "type": "string", - "description": "Lock ID" - }, - "lockName": { - "type": "string", - "description": "Lock name" - }, - "accessLevel": { - "type": "string", - "enum": [ - "OWNER", - "ADMIN", - "USER", - "GUEST" - ], - "description": "Access level" - }, - "validFrom": { - "description": "Valid from date", - "type": "string" - }, - "validUntil": { - "description": "Valid until date", - "type": "string" - }, - "grantedBy": { - "type": "string", - "description": "User who granted access" - } - }, - "required": [ - "lockId", - "lockName", - "accessLevel", - "grantedBy" - ], - "additionalProperties": false - }, - "RemoveAccessibleLock": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "lockId": { - "type": "string", - "description": "Lock ID" - }, - "removedBy": { - "type": "string", - "description": "User who removed access" - }, - "reason": { - "type": "string", - "description": "Reason for removal" - } - }, - "required": [ - "lockId", - "removedBy", - "reason" - ], - "additionalProperties": false - }, - "AddDevice": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "deviceId": { - "type": "string", - "description": "Device UUID" - }, - "deviceType": { - "type": "string", - "enum": [ - "matter", - "camera" - ], - "description": "matter | camera" - }, - "orgId": { - "type": "string", - "description": "Organisation the device belongs to" - }, - "name": { - "description": "Friendly label", - "type": "string" - }, - "addedBy": { - "description": "Actor that performed the link", - "type": "string" - } - }, - "required": [ - "deviceId", - "deviceType", - "orgId" - ], - "additionalProperties": false - }, - "RemoveDevice": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "deviceId": { - "type": "string", - "description": "Device UUID" - }, - "removedBy": { - "type": "string", - "description": "Actor that performed the unlink" - }, - "reason": { - "type": "string", - "description": "Why the device is being unlinked" - } - }, - "required": [ - "deviceId", - "removedBy", - "reason" - ], - "additionalProperties": false - }, - "AddLicensePlate": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "plate": { - "type": "string", - "minLength": 1, - "description": "License plate number" - }, - "label": { - "default": "", - "description": "Human-readable label for the plate", - "type": "string" - } - }, - "required": [ - "plate", - "label" - ], - "additionalProperties": false - }, - "RemoveLicensePlate": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "plate": { - "type": "string", - "minLength": 1, - "description": "License plate number to remove" - } - }, - "required": [ - "plate" - ], - "additionalProperties": false - }, - "AddPhysicalKey": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "orgId": { - "type": "string", - "minLength": 1, - "description": "Issuing organisation id" - }, - "orgName": { - "description": "Issuing organisation display name", - "type": "string" - }, - "note": { - "description": "Free-text note about the key (max 500 chars)", - "type": "string", - "maxLength": 500 - } - }, - "required": [ - "orgId" - ], - "additionalProperties": false - }, - "RemovePhysicalKey": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "number": { - "type": "integer", - "exclusiveMinimum": 0, - "maximum": 9007199254740991, - "description": "Number of the physical key to remove" - }, - "_callerOrgId": { - "description": "Server-set: caller org id from API-key auth. Clients MUST NOT supply this.", - "type": "string" - } - }, - "required": [ - "number" - ], - "additionalProperties": false - }, - "AddWalletKey": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "walletType": { - "type": "string", - "enum": [ - "APPLE", - "GOOGLE" - ], - "description": "Wallet type (APPLE or GOOGLE)" - }, - "keyIndex": { - "type": "number", - "description": "Key index" - } - }, - "required": [ - "walletType", - "keyIndex" - ], - "additionalProperties": false - }, - "ProvisionHub": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "hubId": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$", - "description": "Hub ID" - }, - "serial": { - "type": "string", - "minLength": 1, - "description": "Hub serial number" - }, - "model": { - "type": "string", - "minLength": 1, - "description": "Hub model identifier" - }, - "thingName": { - "description": "AWS IoT Thing name (defaults to hubId)", - "type": "string" - }, - "vendorName": { - "description": "Vendor/manufacturer name", - "type": "string" - } - }, - "required": [ - "hubId", - "serial", - "model" - ], - "additionalProperties": false - }, - "ClaimHub": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "hubId": { - "type": "string", - "description": "Hub ID" - }, - "orgId": { - "description": "Organization ID (defaults to caller org from API key)", - "type": "string" - }, - "siteId": { - "type": "string", - "description": "Site ID" - }, - "userId": { - "type": "string", - "description": "User ID claiming the hub" - } - }, - "required": [ - "hubId", - "siteId", - "userId" - ], - "additionalProperties": false - }, - "ReClaimHub": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "hubId": { - "type": "string", - "description": "Hub ID" - }, - "newOrgId": { - "type": "string", - "description": "New Organization ID" - }, - "newSiteId": { - "type": "string", - "description": "New Site ID" - }, - "reason": { - "type": "string", - "minLength": 1, - "description": "Reason for re-claiming" - }, - "userId": { - "type": "string", - "description": "User ID performing re-claim" - } - }, - "required": [ - "hubId", - "newOrgId", - "newSiteId", - "reason", - "userId" - ], - "additionalProperties": false - }, - "SetHubRole": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "hubId": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$", - "description": "Hub ID" - }, - "isPrimary": { - "type": "boolean", - "description": "Whether hub is primary" - }, - "userId": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$", - "description": "User ID setting the role" - } - }, - "required": [ - "hubId", - "isPrimary", - "userId" - ], - "additionalProperties": false - }, - "SuspendHub": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "hubId": { - "type": "string", - "description": "Hub ID" - }, - "reason": { - "type": "string", - "minLength": 1, - "description": "Reason for suspension" - }, - "userId": { - "type": "string", - "description": "User ID suspending the hub" - } - }, - "required": [ - "hubId", - "reason", - "userId" - ], - "additionalProperties": false - }, - "CommissionDevice": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "hubId": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$", - "description": "Hub ID" - }, - "commissioningCode": { - "type": "string", - "pattern": "^(\\d{11}|\\d{22}|MT:.+)$", - "description": "Matter commissioning code (11 or 22 digits, or MT:)" - } - }, - "required": [ - "hubId", - "commissioningCode" - ], - "additionalProperties": false - }, - "SendHubCommand": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "hubId": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$", - "description": "Hub ID" - }, - "command": { - "type": "string", - "enum": [ - "get_nodes", - "server_info", - "set_wifi_credentials" - ], - "description": "Hub command type" - }, - "args": { - "description": "Command arguments", - "type": "object", - "propertyNames": { - "type": "string" - }, - "additionalProperties": {} - } - }, - "required": [ - "hubId", - "command" - ], - "additionalProperties": false - }, - "RegisterCamera": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "cameraId": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$", - "description": "Camera ID" - }, - "name": { - "type": "string", - "minLength": 1, - "description": "Camera name" - }, - "type": { - "type": "string", - "enum": [ - "generic", - "onvif", - "pnp" - ], - "description": "Camera type" - }, - "httpUrl": { - "type": "string", - "format": "uri", - "description": "HTTP access URL for the camera (http:// or https://)" - }, - "rtspUrl": { - "type": "string", - "format": "uri", - "description": "RTSP streaming URL for the camera (rtsp://)" - }, - "orgId": { - "type": "string", - "minLength": 1, - "description": "Organization ID — opaque string, conventionally but not always a UUID" - }, - "ownerId": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$", - "description": "Owner user ID" - }, - "login": { - "type": "string", - "minLength": 1, - "description": "Camera admin login name (required by 3dEye)" - }, - "password": { - "type": "string", - "minLength": 1, - "description": "Camera admin password (required by 3dEye)" - }, - "port": { - "description": "Optional RTSP port — required for ONVIF cameras (parsed from rtspUrl if omitted).", - "type": "integer", - "exclusiveMinimum": 0, - "maximum": 65535 - } - }, - "required": [ - "cameraId", - "name", - "type", - "httpUrl", - "rtspUrl", - "orgId", - "ownerId", - "login", - "password" - ], - "additionalProperties": false - }, - "UpdateCamera": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "name": { - "description": "Updated camera name", - "type": "string", - "minLength": 1 - }, - "httpUrl": { - "description": "Updated HTTP access URL", - "type": "string", - "format": "uri" - }, - "rtspUrl": { - "description": "Updated RTSP streaming URL", - "type": "string", - "format": "uri" - } - }, - "additionalProperties": false - }, - "DisableCamera": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "reason": { - "type": "string", - "minLength": 1, - "description": "Reason for disabling the camera" - }, - "disabledBy": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$", - "description": "User ID who disabled the camera" - } - }, - "required": [ - "reason", - "disabledBy" - ], - "additionalProperties": false - }, - "DeleteCamera": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "deletedBy": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$", - "description": "User ID who deleted the camera" - } - }, - "required": [ - "deletedBy" - ], - "additionalProperties": false - }, - "LinkCameraToLock": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "lockId": { - "type": "string", - "description": "Lock ID to link this camera to" - } - }, - "required": [ - "lockId" - ], - "additionalProperties": false - }, - "UnlinkCameraFromLock": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": {}, - "additionalProperties": false - }, - "CreateCameraRole": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "roleId": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$", - "description": "Camera Role ID" - }, - "name": { - "type": "string", - "minLength": 1, - "description": "Role name" - }, - "description": { - "type": "string", - "minLength": 1, - "description": "Role description" - }, - "orgId": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$", - "description": "Organization ID" - } - }, - "required": [ - "roleId", - "name", - "description", - "orgId" - ], - "additionalProperties": false - }, - "DeleteCameraRole": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "deletedBy": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$", - "description": "User ID who deleted the role" - } - }, - "required": [ - "deletedBy" - ], - "additionalProperties": false - }, - "AssignUser": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "userId": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$", - "description": "Our user UUID" - }, - "threeDeyeUserId": { - "type": "string", - "minLength": 1, - "description": "3dEye user GUID" - } - }, - "required": [ - "userId", - "threeDeyeUserId" - ], - "additionalProperties": false - }, - "RemoveUser": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "userId": { - "type": "string", - "format": "uuid", - "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$", - "description": "Our user UUID" - }, - "threeDeyeUserId": { - "type": "string", - "minLength": 1, - "description": "3dEye user GUID" - } - }, - "required": [ - "userId", - "threeDeyeUserId" - ], - "additionalProperties": false - }, - "AssignCamera": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "cameraId": { - "type": "string", - "minLength": 1, - "description": "Camera ID in 3dEye (numeric, coerced to string)" - }, - "permissions": { - "minItems": 1, - "type": "array", - "items": { - "type": "string", - "minLength": 1 - }, - "description": "Permissions (e.g. View, Share)" - } - }, - "required": [ - "cameraId", - "permissions" - ], - "additionalProperties": false - }, - "RemoveCamera": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "cameraId": { - "type": "string", - "minLength": 1, - "description": "Camera ID in 3dEye (numeric, coerced to string)" - } - }, - "required": [ - "cameraId" - ], - "additionalProperties": false - }, - "CreateMatterDevice": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "deviceId": { - "type": "string", - "description": "Matter Device ID" - }, - "thingName": { - "type": "string", - "description": "AWS IoT Thing name" - }, - "hubId": { - "type": "string", - "description": "Hub ID this device belongs to" - }, - "deviceType": { - "default": "generic", - "description": "Matter device type", - "type": "string" - } - }, - "required": [ - "deviceId", - "thingName", - "hubId", - "deviceType" - ], - "additionalProperties": false - }, - "UpdateReportedShadow": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "reported": { - "type": "object", - "propertyNames": { - "type": "string" - }, - "additionalProperties": {}, - "description": "Reported shadow state from device" - } - }, - "required": [ - "reported" - ], - "additionalProperties": false - }, - "UpdateDesiredShadow": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "desired": { - "type": "object", - "propertyNames": { - "type": "string" - }, - "additionalProperties": {}, - "description": "Desired shadow state to push to device" - } - }, - "required": [ - "desired" - ], - "additionalProperties": false - } - } -} +{"version":"32d654a1","schemaDraft":"https://json-schema.org/draft/2020-12/schema","commands":{"CreateLock":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"index":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991,"description":"Lock index number"},"uuid":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$","description":"Lock UUID"},"serialNumber":{"description":"Serial number","type":"string"},"vendorName":{"description":"Vendor/manufacturer name","type":"string"},"ownerId":{"description":"Owner user ID","type":"string"},"keys":{"default":[],"description":"Initial keys","type":"array","items":{"type":"object","properties":{"uuid":{"type":"string"},"indexNumber":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"userId":{"type":"string"}},"required":["uuid"],"additionalProperties":false}}},"required":["index","uuid","keys"],"additionalProperties":false},"AddKey":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"keyUuid":{"type":"string","description":"Key identifier"},"keyIndexNumber":{"description":"Physical key index","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"userId":{"description":"User ID","type":"string"}},"required":["keyUuid"],"additionalProperties":false},"RemoveKey":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"keyUuid":{"description":"Key identifier","type":"string"},"keyIndexNumber":{"description":"Physical key index","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"additionalProperties":false},"WriteKey":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"keyUuid":{"type":"string","minLength":1,"description":"Key identifier to write to device firmware"},"keyIndexNumber":{"description":"Physical key index on device","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["keyUuid"],"additionalProperties":false},"AddResident":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"email":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$","description":"Resident email — server resolves to the user UUID via D1"},"name":{"type":"string","minLength":1,"description":"Resident name"}},"required":["email","name"],"additionalProperties":false},"RemoveResident":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"email":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$","description":"Resident email to remove"}},"required":["email"],"additionalProperties":false},"SetOwner":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"userId":{"type":"string","description":"User ID to set as owner"}},"required":["userId"],"additionalProperties":false},"SetOrganization":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"orgId":{"type":"string","description":"Organization ID"}},"required":["orgId"],"additionalProperties":false},"ChangeLockUuid":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"newUuid":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$","description":"New UUID for the lock"}},"required":["newUuid"],"additionalProperties":false},"OpenLock":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"requestId":{"description":"Request tracking ID","type":"string"},"reason":{"description":"Reason for opening","type":"string"}},"additionalProperties":false},"BulkAddKeys":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"keys":{"minItems":1,"type":"array","items":{"type":"object","properties":{"keyUuid":{"type":"string","description":"Key identifier"},"keyIndexNumber":{"description":"Physical key index","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"userId":{"description":"User ID","type":"string"}},"required":["keyUuid"],"additionalProperties":false},"description":"List of keys to add to the lock"}},"required":["keys"],"additionalProperties":false},"create-temp-key":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"tempKeyUuid":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$"},"accessMode":{"type":"string","enum":["public","user-whitelist"]},"allowedUserIds":{"default":[],"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$"}},"validFrom":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"validUntil":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"maxUses":{"anyOf":[{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},{"type":"null"}]}},"required":["tempKeyUuid","accessMode","allowedUserIds","validFrom","validUntil"],"additionalProperties":false},"delete-temp-key":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"tempKeyUuid":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$"}},"required":["tempKeyUuid"],"additionalProperties":false},"update-temp-key":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"tempKeyUuid":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$"},"validFrom":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"validUntil":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"maxUses":{"anyOf":[{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},{"type":"null"}]},"allowedUserIds":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$"}},"accessMode":{"type":"string","enum":["public","user-whitelist"]}},"required":["tempKeyUuid"],"additionalProperties":false},"CreateUser":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"userId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$","description":"User UUID"},"email":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$","description":"User email"},"firstName":{"description":"First name","type":"string"},"lastName":{"description":"Last name","type":"string"},"phoneNumber":{"description":"Phone number","type":"string"}},"required":["userId","email"],"additionalProperties":false},"AddAccessibleLock":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"lockId":{"type":"string","description":"Lock ID"},"lockName":{"type":"string","description":"Lock name"},"accessLevel":{"type":"string","enum":["OWNER","ADMIN","USER","GUEST"],"description":"Access level"},"validFrom":{"description":"Valid from date","type":"string"},"validUntil":{"description":"Valid until date","type":"string"},"grantedBy":{"type":"string","description":"User who granted access"}},"required":["lockId","lockName","accessLevel","grantedBy"],"additionalProperties":false},"RemoveAccessibleLock":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"lockId":{"type":"string","description":"Lock ID"},"removedBy":{"type":"string","description":"User who removed access"},"reason":{"type":"string","description":"Reason for removal"}},"required":["lockId","removedBy","reason"],"additionalProperties":false},"AddDevice":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"deviceId":{"type":"string","description":"Device UUID"},"deviceType":{"type":"string","enum":["matter","camera","rtsp-camera"],"description":"matter | camera"},"orgId":{"type":"string","description":"Organisation the device belongs to"},"name":{"description":"Friendly label","type":"string"},"addedBy":{"description":"Actor that performed the link","type":"string"}},"required":["deviceId","deviceType","orgId"],"additionalProperties":false},"RemoveDevice":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"deviceId":{"type":"string","description":"Device UUID"},"removedBy":{"type":"string","description":"Actor that performed the unlink"},"reason":{"type":"string","description":"Why the device is being unlinked"}},"required":["deviceId","removedBy","reason"],"additionalProperties":false},"AddLicensePlate":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"plate":{"type":"string","minLength":1,"description":"License plate number"},"label":{"default":"","description":"Human-readable label for the plate","type":"string"}},"required":["plate","label"],"additionalProperties":false},"RemoveLicensePlate":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"plate":{"type":"string","minLength":1,"description":"License plate number to remove"}},"required":["plate"],"additionalProperties":false},"AddPhysicalKey":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"orgId":{"type":"string","minLength":1,"description":"Issuing organisation id"},"orgName":{"description":"Issuing organisation display name","type":"string"},"note":{"description":"Free-text note about the key (max 500 chars)","type":"string","maxLength":500}},"required":["orgId"],"additionalProperties":false},"RemovePhysicalKey":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"number":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991,"description":"Number of the physical key to remove"},"_callerOrgId":{"description":"Server-set: caller org id from API-key auth. Clients MUST NOT supply this.","type":"string"}},"required":["number"],"additionalProperties":false},"AddWalletKey":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"walletType":{"type":"string","enum":["APPLE","GOOGLE"],"description":"Wallet type (APPLE or GOOGLE)"},"keyIndex":{"type":"number","description":"Key index"}},"required":["walletType","keyIndex"],"additionalProperties":false},"ProvisionHub":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"hubId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$","description":"Hub ID"},"serial":{"type":"string","minLength":1,"description":"Hub serial number"},"model":{"type":"string","minLength":1,"description":"Hub model identifier"},"thingName":{"description":"AWS IoT Thing name (defaults to hubId)","type":"string"},"vendorName":{"description":"Vendor/manufacturer name","type":"string"}},"required":["hubId","serial","model"],"additionalProperties":false},"ClaimHub":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"hubId":{"type":"string","description":"Hub ID"},"orgId":{"description":"Organization ID (defaults to caller org from API key)","type":"string"},"siteId":{"type":"string","description":"Site ID"},"userId":{"type":"string","description":"User ID claiming the hub"}},"required":["hubId","siteId","userId"],"additionalProperties":false},"ReClaimHub":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"hubId":{"type":"string","description":"Hub ID"},"newOrgId":{"type":"string","description":"New Organization ID"},"newSiteId":{"type":"string","description":"New Site ID"},"reason":{"type":"string","minLength":1,"description":"Reason for re-claiming"},"userId":{"type":"string","description":"User ID performing re-claim"}},"required":["hubId","newOrgId","newSiteId","reason","userId"],"additionalProperties":false},"SetHubRole":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"hubId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$","description":"Hub ID"},"isPrimary":{"type":"boolean","description":"Whether hub is primary"},"userId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$","description":"User ID setting the role"}},"required":["hubId","isPrimary","userId"],"additionalProperties":false},"SuspendHub":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"hubId":{"type":"string","description":"Hub ID"},"reason":{"type":"string","minLength":1,"description":"Reason for suspension"},"userId":{"type":"string","description":"User ID suspending the hub"}},"required":["hubId","reason","userId"],"additionalProperties":false},"CommissionDevice":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"hubId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$","description":"Hub ID"},"commissioningCode":{"type":"string","pattern":"^(\\d{11}|\\d{22}|MT:.+)$","description":"Matter commissioning code (11 or 22 digits, or MT:)"}},"required":["hubId","commissioningCode"],"additionalProperties":false},"SendHubCommand":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"hubId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$","description":"Hub ID"},"command":{"type":"string","enum":["get_nodes","server_info","set_wifi_credentials"],"description":"Hub command type"},"args":{"description":"Command arguments","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["hubId","command"],"additionalProperties":false},"RegisterCamera":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"cameraId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$","description":"Camera ID"},"name":{"type":"string","minLength":1,"description":"Camera name"},"type":{"type":"string","enum":["generic","onvif","pnp"],"description":"Camera type"},"httpUrl":{"type":"string","format":"uri","description":"HTTP access URL for the camera (http:// or https://)"},"rtspUrl":{"type":"string","format":"uri","description":"RTSP streaming URL for the camera (rtsp://)"},"orgId":{"type":"string","minLength":1,"description":"Organization ID — opaque string, conventionally but not always a UUID"},"ownerId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$","description":"Owner user ID"},"login":{"type":"string","minLength":1,"description":"Camera admin login name (required by 3dEye)"},"password":{"type":"string","minLength":1,"description":"Camera admin password (required by 3dEye)"},"port":{"description":"Optional RTSP port — required for ONVIF cameras (parsed from rtspUrl if omitted).","type":"integer","exclusiveMinimum":0,"maximum":65535}},"required":["cameraId","name","type","httpUrl","rtspUrl","orgId","ownerId","login","password"],"additionalProperties":false},"UpdateCamera":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"description":"Updated camera name","type":"string","minLength":1},"httpUrl":{"description":"Updated HTTP access URL","type":"string","format":"uri"},"rtspUrl":{"description":"Updated RTSP streaming URL","type":"string","format":"uri"}},"additionalProperties":false},"DisableCamera":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"reason":{"type":"string","minLength":1,"description":"Reason for disabling the camera"},"disabledBy":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$","description":"User ID who disabled the camera"}},"required":["reason","disabledBy"],"additionalProperties":false},"DeleteCamera":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"deletedBy":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$","description":"User ID who deleted the camera"}},"required":["deletedBy"],"additionalProperties":false},"LinkCameraToLock":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"lockId":{"type":"string","description":"Lock ID to link this camera to"}},"required":["lockId"],"additionalProperties":false},"UnlinkCameraFromLock":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{},"additionalProperties":false},"CreateCameraRole":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"roleId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$","description":"Camera Role ID"},"name":{"type":"string","minLength":1,"description":"Role name"},"description":{"type":"string","minLength":1,"description":"Role description"},"orgId":{"type":"string","minLength":1,"description":"Organization ID — opaque string, conventionally but not always a UUID"}},"required":["roleId","name","description","orgId"],"additionalProperties":false},"DeleteCameraRole":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"deletedBy":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$","description":"User ID who deleted the role"}},"required":["deletedBy"],"additionalProperties":false},"AssignUser":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"userId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$","description":"Our user UUID"},"threeDeyeUserId":{"type":"string","minLength":1,"description":"3dEye user GUID"}},"required":["userId","threeDeyeUserId"],"additionalProperties":false},"RemoveUser":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"userId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$","description":"Our user UUID"},"threeDeyeUserId":{"type":"string","minLength":1,"description":"3dEye user GUID"}},"required":["userId","threeDeyeUserId"],"additionalProperties":false},"AssignCamera":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"cameraId":{"type":"string","minLength":1,"description":"Camera ID in 3dEye (numeric, coerced to string)"},"permissions":{"minItems":1,"type":"array","items":{"type":"string","minLength":1},"description":"Permissions (e.g. View, Share)"}},"required":["cameraId","permissions"],"additionalProperties":false},"RemoveCamera":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"cameraId":{"type":"string","minLength":1,"description":"Camera ID in 3dEye (numeric, coerced to string)"}},"required":["cameraId"],"additionalProperties":false},"CreateMatterDevice":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"deviceId":{"type":"string","description":"Matter Device ID"},"thingName":{"type":"string","description":"AWS IoT Thing name"},"hubId":{"type":"string","description":"Hub ID this device belongs to"},"deviceType":{"default":"generic","description":"Matter device type","type":"string"}},"required":["deviceId","thingName","hubId","deviceType"],"additionalProperties":false},"UpdateReportedShadow":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"reported":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"Reported shadow state from device"}},"required":["reported"],"additionalProperties":false},"UpdateDesiredShadow":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"desired":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"Desired shadow state to push to device"}},"required":["desired"],"additionalProperties":false},"RegisterRtspCamera":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"rtspCameraId":{"type":"string","description":"Camera UUID (caller-supplied or server-generated)"},"name":{"type":"string","minLength":1,"description":"Human-readable camera name"},"rtspUrl":{"type":"string","minLength":1,"description":"RTSP stream URL (e.g. rtsp://192.168.1.1:554/stream)"},"httpSnapshotUrl":{"description":"HTTP snapshot URL for still image capture","type":"string"},"username":{"description":"Camera authentication username","type":"string"},"password":{"description":"Camera authentication password","type":"string"},"ownerId":{"description":"User ID who owns this camera (B2C)","type":"string"},"orgId":{"description":"Organisation ID that owns this camera (B2B)","type":"string"}},"required":["rtspCameraId","name","rtspUrl"],"additionalProperties":false},"DeleteRtspCamera":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"deletedBy":{"description":"Actor who requested the deletion","type":"string"}},"additionalProperties":false}}} \ No newline at end of file diff --git a/event-schemas.json b/event-schemas.json index fa76354..3a80b48 100644 --- a/event-schemas.json +++ b/event-schemas.json @@ -1,1723 +1 @@ -{ - "version": "eb194fa5", - "schemaDraft": "https://json-schema.org/draft/2020-12/schema", - "events": { - "LockCreated": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "lockId": { - "type": "number" - }, - "uuid": { - "type": "string" - }, - "serialNumber": { - "type": "string" - }, - "keys": { - "type": "array", - "items": { - "type": "object", - "properties": { - "uuid": { - "type": "string" - }, - "indexNumber": { - "type": "number" - }, - "userId": { - "type": "string" - } - }, - "required": [ - "uuid" - ], - "additionalProperties": false - } - }, - "ownerId": { - "type": "string" - }, - "timestamp": { - "type": "string" - }, - "thingName": { - "type": "string" - }, - "thingArn": { - "type": "string" - } - }, - "required": [ - "lockId", - "uuid", - "timestamp" - ], - "additionalProperties": false - }, - "OwnerSet": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "lockId": { - "type": "number" - }, - "uuid": { - "type": "string" - }, - "timestamp": { - "type": "string" - }, - "userId": { - "type": "string" - } - }, - "required": [ - "lockId", - "uuid", - "timestamp", - "userId" - ], - "additionalProperties": false - }, - "OrganizationSet": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "lockId": { - "type": "number" - }, - "uuid": { - "type": "string" - }, - "timestamp": { - "type": "string" - }, - "orgId": { - "type": "string" - } - }, - "required": [ - "lockId", - "uuid", - "timestamp", - "orgId" - ], - "additionalProperties": false - }, - "KeyAdded": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "lockId": { - "type": "number" - }, - "uuid": { - "type": "string" - }, - "timestamp": { - "type": "string" - }, - "keyUuid": { - "type": "string" - }, - "keyIndexNumber": { - "type": "number" - }, - "userId": { - "type": "string" - } - }, - "required": [ - "lockId", - "uuid", - "timestamp", - "keyUuid" - ], - "additionalProperties": false - }, - "KeyRemoved": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "lockId": { - "type": "number" - }, - "uuid": { - "type": "string" - }, - "timestamp": { - "type": "string" - }, - "keyUuid": { - "type": "string" - }, - "keyIndexNumber": { - "type": "number" - } - }, - "required": [ - "lockId", - "uuid", - "timestamp", - "keyUuid" - ], - "additionalProperties": false - }, - "ResidentAdded": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "lockId": { - "type": "number" - }, - "uuid": { - "type": "string" - }, - "timestamp": { - "type": "string" - }, - "userId": { - "type": "string" - }, - "name": { - "type": "string" - }, - "email": { - "type": "string" - } - }, - "required": [ - "lockId", - "uuid", - "timestamp", - "userId", - "name" - ], - "additionalProperties": false - }, - "ResidentRemoved": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "lockId": { - "type": "number" - }, - "uuid": { - "type": "string" - }, - "timestamp": { - "type": "string" - }, - "userId": { - "type": "string" - }, - "email": { - "type": "string" - } - }, - "required": [ - "lockId", - "uuid", - "timestamp", - "userId" - ], - "additionalProperties": false - }, - "LockUuidChanged": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "lockId": { - "type": "number" - }, - "uuid": { - "type": "string" - }, - "timestamp": { - "type": "string" - }, - "newUuid": { - "type": "string" - }, - "previousUuid": { - "type": "string" - } - }, - "required": [ - "lockId", - "uuid", - "timestamp", - "newUuid", - "previousUuid" - ], - "additionalProperties": false - }, - "LockOpenRequested": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "lockId": { - "type": "number" - }, - "uuid": { - "type": "string" - }, - "timestamp": { - "type": "string" - }, - "reason": { - "type": "string" - }, - "requestId": { - "type": "string" - } - }, - "required": [ - "lockId", - "uuid", - "timestamp" - ], - "additionalProperties": false - }, - "KeyWriteRequested": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "lockId": { - "type": "number" - }, - "uuid": { - "type": "string" - }, - "timestamp": { - "type": "string" - }, - "keyUuid": { - "type": "string" - }, - "keyIndexNumber": { - "type": "number" - } - }, - "required": [ - "lockId", - "uuid", - "timestamp", - "keyUuid" - ], - "additionalProperties": false - }, - "UserCreated": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "userId": { - "type": "string" - }, - "email": { - "type": "string" - }, - "firstName": { - "type": "string" - }, - "lastName": { - "type": "string" - }, - "phoneNumber": { - "type": "string" - }, - "status": { - "type": "string", - "enum": [ - "ACTIVE", - "INACTIVE", - "SUSPENDED" - ] - } - }, - "required": [ - "userId", - "email", - "status" - ], - "additionalProperties": false - }, - "ProfileUpdated": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "userId": { - "type": "string" - }, - "changes": { - "type": "object", - "properties": { - "firstName": { - "type": "object", - "properties": { - "old": { - "type": "string" - }, - "new": { - "type": "string" - } - }, - "required": [ - "old", - "new" - ], - "additionalProperties": false - }, - "lastName": { - "type": "object", - "properties": { - "old": { - "type": "string" - }, - "new": { - "type": "string" - } - }, - "required": [ - "old", - "new" - ], - "additionalProperties": false - }, - "phoneNumber": { - "type": "object", - "properties": { - "old": { - "type": "string" - }, - "new": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - }, - "required": [ - "userId", - "changes" - ], - "additionalProperties": false - }, - "PhysicalKeyAdded": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "userId": { - "type": "string" - }, - "number": { - "type": "number" - }, - "orgId": { - "type": "string" - }, - "orgName": { - "type": "string" - }, - "note": { - "type": "string" - }, - "addedAt": { - "type": "number" - } - }, - "required": [ - "userId", - "number", - "orgId", - "addedAt" - ], - "additionalProperties": false - }, - "PhysicalKeyRemoved": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "userId": { - "type": "string" - }, - "number": { - "type": "number" - }, - "removedAt": { - "type": "number" - } - }, - "required": [ - "userId", - "number", - "removedAt" - ], - "additionalProperties": false - }, - "WalletKeyPrepared": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "userId": { - "type": "string" - }, - "keyId": { - "type": "string" - }, - "walletType": { - "type": "string", - "enum": [ - "APPLE", - "GOOGLE" - ] - }, - "keyIndex": { - "type": "number" - }, - "deviceId": { - "type": "string" - } - }, - "required": [ - "userId", - "keyId", - "walletType" - ], - "additionalProperties": false - }, - "WalletKeyCommitted": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "userId": { - "type": "string" - }, - "keyId": { - "type": "string" - }, - "keyIndex": { - "type": "number" - }, - "walletType": { - "type": "string", - "enum": [ - "APPLE", - "GOOGLE" - ] - }, - "deviceId": { - "type": "string" - }, - "passId": { - "type": "string" - }, - "passUrl": { - "type": "string" - }, - "committedAt": { - "type": "string" - } - }, - "required": [ - "userId", - "keyId", - "passId", - "passUrl", - "committedAt" - ], - "additionalProperties": false - }, - "WalletKeyRolledBack": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "userId": { - "type": "string" - }, - "preparedKeyId": { - "type": "string" - }, - "reason": { - "type": "string" - }, - "rolledBackAt": { - "type": "string" - } - }, - "required": [ - "userId", - "preparedKeyId", - "reason", - "rolledBackAt" - ], - "additionalProperties": false - }, - "WalletKeyRemoved": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "userId": { - "type": "string" - }, - "keyId": { - "type": "string" - }, - "reason": { - "type": "string" - }, - "removedAt": { - "type": "string" - } - }, - "required": [ - "userId", - "keyId", - "reason", - "removedAt" - ], - "additionalProperties": false - }, - "AccessibleLockAdded": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "userId": { - "type": "string" - }, - "lockId": { - "type": "string" - }, - "lockName": { - "type": "string" - }, - "accessLevel": { - "type": "string", - "enum": [ - "OWNER", - "ADMIN", - "USER", - "GUEST" - ] - }, - "grantedBy": { - "type": "string" - } - }, - "required": [ - "userId", - "lockId", - "lockName", - "accessLevel", - "grantedBy" - ], - "additionalProperties": false - }, - "AccessibleLockRemoved": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "userId": { - "type": "string" - }, - "lockId": { - "type": "string" - }, - "removedBy": { - "type": "string" - }, - "reason": { - "type": "string" - }, - "removedAt": { - "type": "string" - } - }, - "required": [ - "userId", - "lockId", - "removedBy", - "reason", - "removedAt" - ], - "additionalProperties": false - }, - "UserSuspended": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "userId": { - "type": "string" - }, - "reason": { - "type": "string" - }, - "suspendedBy": { - "type": "string" - }, - "suspendedAt": { - "type": "string" - } - }, - "required": [ - "userId", - "reason", - "suspendedBy", - "suspendedAt" - ], - "additionalProperties": false - }, - "UserReactivated": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "userId": { - "type": "string" - }, - "reactivatedBy": { - "type": "string" - }, - "reactivatedAt": { - "type": "string" - } - }, - "required": [ - "userId", - "reactivatedBy", - "reactivatedAt" - ], - "additionalProperties": false - }, - "WalletKeyAdded": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "userId": { - "type": "string" - }, - "walletKey": { - "type": "object", - "properties": { - "keyId": { - "type": "string" - }, - "keyIndex": { - "type": "number" - }, - "walletType": { - "type": "string", - "enum": [ - "APPLE", - "GOOGLE" - ] - }, - "deviceId": { - "type": "string" - }, - "passUrl": { - "type": "string" - }, - "serialNumber": { - "type": "string" - }, - "addedAt": { - "type": "string" - } - }, - "required": [ - "keyId", - "keyIndex", - "walletType", - "deviceId", - "addedAt" - ], - "additionalProperties": false - } - }, - "required": [ - "userId", - "walletKey" - ], - "additionalProperties": false - }, - "LicensePlateAdded": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "userId": { - "type": "string" - }, - "plate": { - "type": "string" - }, - "label": { - "type": "string" - }, - "addedAt": { - "type": "number" - } - }, - "required": [ - "userId", - "plate", - "label", - "addedAt" - ], - "additionalProperties": false - }, - "LicensePlateRemoved": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "userId": { - "type": "string" - }, - "plate": { - "type": "string" - } - }, - "required": [ - "userId", - "plate" - ], - "additionalProperties": false - }, - "DeviceAdded": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "userId": { - "type": "string" - }, - "deviceId": { - "type": "string" - }, - "deviceType": { - "type": "string", - "enum": [ - "matter", - "camera" - ] - }, - "orgId": { - "type": "string" - }, - "name": { - "type": "string" - }, - "addedBy": { - "type": "string" - }, - "addedAt": { - "type": "string" - } - }, - "required": [ - "userId", - "deviceId", - "deviceType", - "orgId", - "addedAt" - ], - "additionalProperties": false - }, - "DeviceRemoved": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "userId": { - "type": "string" - }, - "deviceId": { - "type": "string" - }, - "deviceType": { - "type": "string", - "enum": [ - "matter", - "camera" - ] - }, - "removedBy": { - "type": "string" - }, - "reason": { - "type": "string" - }, - "removedAt": { - "type": "string" - } - }, - "required": [ - "userId", - "deviceId", - "deviceType", - "removedBy", - "reason", - "removedAt" - ], - "additionalProperties": false - }, - "HubProvisioned": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "hubId": { - "type": "string" - }, - "serial": { - "type": "string" - }, - "model": { - "type": "string" - }, - "thingName": { - "type": "string" - }, - "vendorName": { - "type": "string" - }, - "provisionedAt": { - "type": "number" - } - }, - "required": [ - "hubId", - "serial", - "model", - "thingName", - "provisionedAt" - ], - "additionalProperties": false - }, - "HubClaimed": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "hubId": { - "type": "string" - }, - "orgId": { - "type": "string" - }, - "siteId": { - "type": "string" - }, - "claimedBy": { - "type": "string" - }, - "claimedAt": { - "type": "number" - } - }, - "required": [ - "hubId", - "orgId", - "siteId", - "claimedBy", - "claimedAt" - ], - "additionalProperties": false - }, - "HubReClaimed": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "hubId": { - "type": "string" - }, - "previousOrgId": { - "type": "string" - }, - "previousSiteId": { - "type": "string" - }, - "newOrgId": { - "type": "string" - }, - "newSiteId": { - "type": "string" - }, - "reclaimedBy": { - "type": "string" - }, - "reason": { - "type": "string" - }, - "reclaimedAt": { - "type": "number" - } - }, - "required": [ - "hubId", - "previousOrgId", - "previousSiteId", - "newOrgId", - "newSiteId", - "reclaimedBy", - "reason", - "reclaimedAt" - ], - "additionalProperties": false - }, - "HubRoleSet": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "hubId": { - "type": "string" - }, - "isPrimary": { - "type": "boolean" - }, - "setBy": { - "type": "string" - }, - "setAt": { - "type": "number" - } - }, - "required": [ - "hubId", - "isPrimary", - "setBy", - "setAt" - ], - "additionalProperties": false - }, - "HubSuspended": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "hubId": { - "type": "string" - }, - "reason": { - "type": "string" - }, - "suspendedBy": { - "type": "string" - }, - "suspendedAt": { - "type": "number" - } - }, - "required": [ - "hubId", - "reason", - "suspendedBy", - "suspendedAt" - ], - "additionalProperties": false - }, - "HubDecommissioned": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "hubId": { - "type": "string" - }, - "reason": { - "type": "string" - }, - "decommissionedBy": { - "type": "string" - }, - "decommissionedAt": { - "type": "number" - } - }, - "required": [ - "hubId", - "reason", - "decommissionedBy", - "decommissionedAt" - ], - "additionalProperties": false - }, - "MigrationStarted": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "migrationId": { - "type": "string" - }, - "sourceHubId": { - "type": "string" - }, - "targetHubId": { - "type": "string" - }, - "targetThingName": { - "type": "string" - }, - "deviceIds": { - "type": "array", - "items": { - "type": "string" - } - }, - "startedBy": { - "type": "string" - }, - "startedAt": { - "type": "number" - } - }, - "required": [ - "migrationId", - "sourceHubId", - "targetHubId", - "targetThingName", - "deviceIds", - "startedBy", - "startedAt" - ], - "additionalProperties": false - }, - "DeviceMigrationStatusUpdated": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "migrationId": { - "type": "string" - }, - "deviceId": { - "type": "string" - }, - "status": { - "type": "string", - "enum": [ - "Queued", - "Migrating", - "Migrated", - "Blocked", - "Failed" - ] - }, - "error": { - "type": "string" - }, - "updatedAt": { - "type": "number" - } - }, - "required": [ - "migrationId", - "deviceId", - "status", - "updatedAt" - ], - "additionalProperties": false - }, - "MigrationCompleted": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "migrationId": { - "type": "string" - }, - "status": { - "type": "string", - "enum": [ - "Completed", - "Completed with errors", - "Failed" - ] - }, - "completedAt": { - "type": "number" - } - }, - "required": [ - "migrationId", - "status", - "completedAt" - ], - "additionalProperties": false - }, - "CameraRegistered": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "cameraId": { - "type": "string" - }, - "threeDeyeCameraId": { - "type": "string" - }, - "cameraType": { - "type": "string", - "enum": [ - "generic", - "onvif", - "pnp" - ] - }, - "name": { - "type": "string" - }, - "orgId": { - "type": "string" - }, - "ownerId": { - "type": "string" - }, - "httpUrl": { - "type": "string" - }, - "rtspUrl": { - "type": "string" - }, - "registrationCode": { - "type": "string" - }, - "registeredAt": { - "type": "number" - } - }, - "required": [ - "cameraId", - "threeDeyeCameraId", - "cameraType", - "name", - "orgId", - "ownerId", - "httpUrl", - "rtspUrl", - "registeredAt" - ], - "additionalProperties": false - }, - "CameraUpdated": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "cameraId": { - "type": "string" - }, - "name": { - "type": "string" - }, - "httpUrl": { - "type": "string" - }, - "rtspUrl": { - "type": "string" - }, - "updatedAt": { - "type": "number" - } - }, - "required": [ - "cameraId", - "updatedAt" - ], - "additionalProperties": false - }, - "CameraDisabled": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "cameraId": { - "type": "string" - }, - "reason": { - "type": "string" - }, - "disabledBy": { - "type": "string" - }, - "disabledAt": { - "type": "number" - } - }, - "required": [ - "cameraId", - "reason", - "disabledBy", - "disabledAt" - ], - "additionalProperties": false - }, - "CameraDeleted": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "cameraId": { - "type": "string" - }, - "deletedBy": { - "type": "string" - }, - "deletedAt": { - "type": "number" - } - }, - "required": [ - "cameraId", - "deletedBy", - "deletedAt" - ], - "additionalProperties": false - }, - "CameraLinkedToLock": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "cameraId": { - "type": "string" - }, - "lockId": { - "type": "string" - } - }, - "required": [ - "cameraId", - "lockId" - ], - "additionalProperties": false - }, - "CameraUnlinkedFromLock": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "cameraId": { - "type": "string" - } - }, - "required": [ - "cameraId" - ], - "additionalProperties": false - }, - "CameraRoleCreated": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "roleId": { - "type": "string" - }, - "threeDeyeRoleId": { - "type": "string" - }, - "name": { - "type": "string" - }, - "description": { - "type": "string" - }, - "orgId": { - "type": "string" - }, - "createdAt": { - "type": "number" - } - }, - "required": [ - "roleId", - "threeDeyeRoleId", - "name", - "description", - "orgId", - "createdAt" - ], - "additionalProperties": false - }, - "CameraRoleDeleted": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "roleId": { - "type": "string" - }, - "deletedAt": { - "type": "number" - } - }, - "required": [ - "roleId", - "deletedAt" - ], - "additionalProperties": false - }, - "CameraRoleUserAssigned": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "roleId": { - "type": "string" - }, - "userId": { - "type": "string" - }, - "threeDeyeUserId": { - "type": "string" - }, - "assignedAt": { - "type": "number" - } - }, - "required": [ - "roleId", - "userId", - "threeDeyeUserId", - "assignedAt" - ], - "additionalProperties": false - }, - "CameraRoleUserRemoved": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "roleId": { - "type": "string" - }, - "userId": { - "type": "string" - }, - "threeDeyeUserId": { - "type": "string" - }, - "removedAt": { - "type": "number" - } - }, - "required": [ - "roleId", - "userId", - "threeDeyeUserId", - "removedAt" - ], - "additionalProperties": false - }, - "CameraRoleCameraAssigned": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "roleId": { - "type": "string" - }, - "cameraId": { - "type": "string" - }, - "permissions": { - "type": "array", - "items": { - "type": "string" - } - }, - "assignedAt": { - "type": "number" - } - }, - "required": [ - "roleId", - "cameraId", - "permissions", - "assignedAt" - ], - "additionalProperties": false - }, - "CameraRoleCameraRemoved": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "roleId": { - "type": "string" - }, - "cameraId": { - "type": "string" - }, - "removedAt": { - "type": "number" - } - }, - "required": [ - "roleId", - "cameraId", - "removedAt" - ], - "additionalProperties": false - }, - "TempKeyCreated": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "tempKeyUuid": { - "type": "string" - }, - "lockId": { - "type": "number" - }, - "lockUuid": { - "type": "string" - }, - "accessMode": { - "type": "string", - "enum": [ - "public", - "user-whitelist" - ] - }, - "allowedUserIds": { - "type": "array", - "items": { - "type": "string" - } - }, - "validFrom": { - "type": "string" - }, - "validUntil": { - "type": "string" - }, - "maxUses": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "createdBy": { - "type": "string" - }, - "timestamp": { - "type": "string" - } - }, - "required": [ - "tempKeyUuid", - "lockId", - "lockUuid", - "accessMode", - "validFrom", - "validUntil", - "createdBy", - "timestamp" - ], - "additionalProperties": false - }, - "TempKeyUsed": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "tempKeyUuid": { - "type": "string" - }, - "lockId": { - "type": "number" - }, - "lockUuid": { - "type": "string" - }, - "userId": { - "type": "string" - }, - "usedCount": { - "type": "number" - }, - "timestamp": { - "type": "string" - } - }, - "required": [ - "tempKeyUuid", - "lockId", - "lockUuid", - "usedCount", - "timestamp" - ], - "additionalProperties": false - }, - "TempKeyDeleted": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "tempKeyUuid": { - "type": "string" - }, - "lockId": { - "type": "number" - }, - "lockUuid": { - "type": "string" - }, - "deletedBy": { - "type": "string" - }, - "timestamp": { - "type": "string" - } - }, - "required": [ - "tempKeyUuid", - "lockId", - "lockUuid", - "deletedBy", - "timestamp" - ], - "additionalProperties": false - }, - "TempKeyUpdated": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "tempKeyUuid": { - "type": "string" - }, - "lockId": { - "type": "number" - }, - "lockUuid": { - "type": "string" - }, - "changes": { - "type": "object", - "properties": { - "validFrom": { - "type": "string" - }, - "validUntil": { - "type": "string" - }, - "maxUses": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "allowedUserIds": { - "type": "array", - "items": { - "type": "string" - } - }, - "accessMode": { - "type": "string", - "enum": [ - "public", - "user-whitelist" - ] - } - }, - "additionalProperties": false - }, - "updatedBy": { - "type": "string" - }, - "timestamp": { - "type": "string" - } - }, - "required": [ - "tempKeyUuid", - "lockId", - "lockUuid", - "changes", - "updatedBy", - "timestamp" - ], - "additionalProperties": false - }, - "MatterDeviceCreated": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "deviceId": { - "type": "string" - }, - "thingName": { - "type": "string" - }, - "hubId": { - "type": "string" - }, - "deviceType": { - "type": "string" - }, - "createdAt": { - "type": "number" - } - }, - "required": [ - "deviceId", - "thingName", - "hubId", - "deviceType", - "createdAt" - ], - "additionalProperties": false - }, - "ReportedShadowUpdated": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "deviceId": { - "type": "string" - }, - "thingName": { - "type": "string" - }, - "reported": { - "type": "object", - "propertyNames": { - "type": "string" - }, - "additionalProperties": {} - }, - "updatedAt": { - "type": "number" - } - }, - "required": [ - "deviceId", - "thingName", - "reported", - "updatedAt" - ], - "additionalProperties": false - }, - "DesiredShadowUpdated": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "deviceId": { - "type": "string" - }, - "thingName": { - "type": "string" - }, - "desired": { - "type": "object", - "propertyNames": { - "type": "string" - }, - "additionalProperties": {} - }, - "updatedAt": { - "type": "number" - } - }, - "required": [ - "deviceId", - "thingName", - "desired", - "updatedAt" - ], - "additionalProperties": false - } - } -} +{"version":"32d654a1","schemaDraft":"https://json-schema.org/draft/2020-12/schema","events":{"LockCreated":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"lockId":{"type":"number"},"uuid":{"type":"string"},"serialNumber":{"type":"string"},"keys":{"type":"array","items":{"type":"object","properties":{"uuid":{"type":"string"},"indexNumber":{"type":"number"},"userId":{"type":"string"}},"required":["uuid"],"additionalProperties":false}},"ownerId":{"type":"string"},"timestamp":{"type":"string"},"thingName":{"type":"string"},"thingArn":{"type":"string"}},"required":["lockId","uuid","timestamp"],"additionalProperties":false},"OwnerSet":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"lockId":{"type":"number"},"uuid":{"type":"string"},"timestamp":{"type":"string"},"userId":{"type":"string"}},"required":["lockId","uuid","timestamp","userId"],"additionalProperties":false},"OrganizationSet":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"lockId":{"type":"number"},"uuid":{"type":"string"},"timestamp":{"type":"string"},"orgId":{"type":"string"}},"required":["lockId","uuid","timestamp","orgId"],"additionalProperties":false},"KeyAdded":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"lockId":{"type":"number"},"uuid":{"type":"string"},"timestamp":{"type":"string"},"keyUuid":{"type":"string"},"keyIndexNumber":{"type":"number"},"userId":{"type":"string"}},"required":["lockId","uuid","timestamp","keyUuid"],"additionalProperties":false},"KeyRemoved":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"lockId":{"type":"number"},"uuid":{"type":"string"},"timestamp":{"type":"string"},"keyUuid":{"type":"string"},"keyIndexNumber":{"type":"number"}},"required":["lockId","uuid","timestamp","keyUuid"],"additionalProperties":false},"ResidentAdded":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"lockId":{"type":"number"},"uuid":{"type":"string"},"timestamp":{"type":"string"},"userId":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"}},"required":["lockId","uuid","timestamp","userId","name"],"additionalProperties":false},"ResidentRemoved":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"lockId":{"type":"number"},"uuid":{"type":"string"},"timestamp":{"type":"string"},"userId":{"type":"string"},"email":{"type":"string"}},"required":["lockId","uuid","timestamp","userId"],"additionalProperties":false},"LockUuidChanged":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"lockId":{"type":"number"},"uuid":{"type":"string"},"timestamp":{"type":"string"},"newUuid":{"type":"string"},"previousUuid":{"type":"string"}},"required":["lockId","uuid","timestamp","newUuid","previousUuid"],"additionalProperties":false},"LockOpenRequested":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"lockId":{"type":"number"},"uuid":{"type":"string"},"timestamp":{"type":"string"},"reason":{"type":"string"},"requestId":{"type":"string"}},"required":["lockId","uuid","timestamp"],"additionalProperties":false},"KeyWriteRequested":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"lockId":{"type":"number"},"uuid":{"type":"string"},"timestamp":{"type":"string"},"keyUuid":{"type":"string"},"keyIndexNumber":{"type":"number"}},"required":["lockId","uuid","timestamp","keyUuid"],"additionalProperties":false},"UserCreated":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"userId":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"phoneNumber":{"type":"string"},"status":{"type":"string","enum":["ACTIVE","INACTIVE","SUSPENDED"]}},"required":["userId","email","status"],"additionalProperties":false},"ProfileUpdated":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"userId":{"type":"string"},"changes":{"type":"object","properties":{"firstName":{"type":"object","properties":{"old":{"type":"string"},"new":{"type":"string"}},"required":["old","new"],"additionalProperties":false},"lastName":{"type":"object","properties":{"old":{"type":"string"},"new":{"type":"string"}},"required":["old","new"],"additionalProperties":false},"phoneNumber":{"type":"object","properties":{"old":{"type":"string"},"new":{"type":"string"}},"additionalProperties":false}},"additionalProperties":false}},"required":["userId","changes"],"additionalProperties":false},"PhysicalKeyAdded":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"userId":{"type":"string"},"number":{"type":"number"},"orgId":{"type":"string"},"orgName":{"type":"string"},"note":{"type":"string"},"addedAt":{"type":"number"}},"required":["userId","number","orgId","addedAt"],"additionalProperties":false},"PhysicalKeyRemoved":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"userId":{"type":"string"},"number":{"type":"number"},"removedAt":{"type":"number"}},"required":["userId","number","removedAt"],"additionalProperties":false},"WalletKeyPrepared":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"userId":{"type":"string"},"keyId":{"type":"string"},"walletType":{"type":"string","enum":["APPLE","GOOGLE"]},"keyIndex":{"type":"number"},"deviceId":{"type":"string"}},"required":["userId","keyId","walletType"],"additionalProperties":false},"WalletKeyCommitted":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"userId":{"type":"string"},"keyId":{"type":"string"},"keyIndex":{"type":"number"},"walletType":{"type":"string","enum":["APPLE","GOOGLE"]},"deviceId":{"type":"string"},"passId":{"type":"string"},"passUrl":{"type":"string"},"committedAt":{"type":"string"}},"required":["userId","keyId","passId","passUrl","committedAt"],"additionalProperties":false},"WalletKeyRolledBack":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"userId":{"type":"string"},"preparedKeyId":{"type":"string"},"reason":{"type":"string"},"rolledBackAt":{"type":"string"}},"required":["userId","preparedKeyId","reason","rolledBackAt"],"additionalProperties":false},"WalletKeyRemoved":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"userId":{"type":"string"},"keyId":{"type":"string"},"reason":{"type":"string"},"removedAt":{"type":"string"}},"required":["userId","keyId","reason","removedAt"],"additionalProperties":false},"AccessibleLockAdded":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"userId":{"type":"string"},"lockId":{"type":"string"},"lockName":{"type":"string"},"accessLevel":{"type":"string","enum":["OWNER","ADMIN","USER","GUEST"]},"grantedBy":{"type":"string"}},"required":["userId","lockId","lockName","accessLevel","grantedBy"],"additionalProperties":false},"AccessibleLockRemoved":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"userId":{"type":"string"},"lockId":{"type":"string"},"removedBy":{"type":"string"},"reason":{"type":"string"},"removedAt":{"type":"string"}},"required":["userId","lockId","removedBy","reason","removedAt"],"additionalProperties":false},"UserSuspended":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"userId":{"type":"string"},"reason":{"type":"string"},"suspendedBy":{"type":"string"},"suspendedAt":{"type":"string"}},"required":["userId","reason","suspendedBy","suspendedAt"],"additionalProperties":false},"UserReactivated":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"userId":{"type":"string"},"reactivatedBy":{"type":"string"},"reactivatedAt":{"type":"string"}},"required":["userId","reactivatedBy","reactivatedAt"],"additionalProperties":false},"WalletKeyAdded":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"userId":{"type":"string"},"walletKey":{"type":"object","properties":{"keyId":{"type":"string"},"keyIndex":{"type":"number"},"walletType":{"type":"string","enum":["APPLE","GOOGLE"]},"deviceId":{"type":"string"},"passUrl":{"type":"string"},"serialNumber":{"type":"string"},"addedAt":{"type":"string"}},"required":["keyId","keyIndex","walletType","deviceId","addedAt"],"additionalProperties":false}},"required":["userId","walletKey"],"additionalProperties":false},"LicensePlateAdded":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"userId":{"type":"string"},"plate":{"type":"string"},"label":{"type":"string"},"addedAt":{"type":"number"}},"required":["userId","plate","label","addedAt"],"additionalProperties":false},"LicensePlateRemoved":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"userId":{"type":"string"},"plate":{"type":"string"}},"required":["userId","plate"],"additionalProperties":false},"DeviceAdded":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"userId":{"type":"string"},"deviceId":{"type":"string"},"deviceType":{"type":"string","enum":["matter","camera","rtsp-camera"]},"orgId":{"type":"string"},"name":{"type":"string"},"addedBy":{"type":"string"},"addedAt":{"type":"string"}},"required":["userId","deviceId","deviceType","orgId","addedAt"],"additionalProperties":false},"DeviceRemoved":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"userId":{"type":"string"},"deviceId":{"type":"string"},"deviceType":{"type":"string","enum":["matter","camera","rtsp-camera"]},"removedBy":{"type":"string"},"reason":{"type":"string"},"removedAt":{"type":"string"}},"required":["userId","deviceId","deviceType","removedBy","reason","removedAt"],"additionalProperties":false},"HubProvisioned":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"hubId":{"type":"string"},"serial":{"type":"string"},"model":{"type":"string"},"thingName":{"type":"string"},"vendorName":{"type":"string"},"provisionedAt":{"type":"number"}},"required":["hubId","serial","model","thingName","provisionedAt"],"additionalProperties":false},"HubClaimed":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"hubId":{"type":"string"},"orgId":{"type":"string"},"siteId":{"type":"string"},"claimedBy":{"type":"string"},"claimedAt":{"type":"number"}},"required":["hubId","orgId","siteId","claimedBy","claimedAt"],"additionalProperties":false},"HubReClaimed":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"hubId":{"type":"string"},"previousOrgId":{"type":"string"},"previousSiteId":{"type":"string"},"newOrgId":{"type":"string"},"newSiteId":{"type":"string"},"reclaimedBy":{"type":"string"},"reason":{"type":"string"},"reclaimedAt":{"type":"number"}},"required":["hubId","previousOrgId","previousSiteId","newOrgId","newSiteId","reclaimedBy","reason","reclaimedAt"],"additionalProperties":false},"HubRoleSet":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"hubId":{"type":"string"},"isPrimary":{"type":"boolean"},"setBy":{"type":"string"},"setAt":{"type":"number"}},"required":["hubId","isPrimary","setBy","setAt"],"additionalProperties":false},"HubSuspended":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"hubId":{"type":"string"},"reason":{"type":"string"},"suspendedBy":{"type":"string"},"suspendedAt":{"type":"number"}},"required":["hubId","reason","suspendedBy","suspendedAt"],"additionalProperties":false},"HubDecommissioned":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"hubId":{"type":"string"},"reason":{"type":"string"},"decommissionedBy":{"type":"string"},"decommissionedAt":{"type":"number"}},"required":["hubId","reason","decommissionedBy","decommissionedAt"],"additionalProperties":false},"MigrationStarted":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"migrationId":{"type":"string"},"sourceHubId":{"type":"string"},"targetHubId":{"type":"string"},"targetThingName":{"type":"string"},"deviceIds":{"type":"array","items":{"type":"string"}},"startedBy":{"type":"string"},"startedAt":{"type":"number"}},"required":["migrationId","sourceHubId","targetHubId","targetThingName","deviceIds","startedBy","startedAt"],"additionalProperties":false},"DeviceMigrationStatusUpdated":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"migrationId":{"type":"string"},"deviceId":{"type":"string"},"status":{"type":"string","enum":["Queued","Migrating","Migrated","Blocked","Failed"]},"error":{"type":"string"},"updatedAt":{"type":"number"}},"required":["migrationId","deviceId","status","updatedAt"],"additionalProperties":false},"MigrationCompleted":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"migrationId":{"type":"string"},"status":{"type":"string","enum":["Completed","Completed with errors","Failed"]},"completedAt":{"type":"number"}},"required":["migrationId","status","completedAt"],"additionalProperties":false},"CameraRegistered":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"cameraId":{"type":"string"},"threeDeyeCameraId":{"type":"string"},"cameraType":{"type":"string","enum":["generic","onvif","pnp"]},"name":{"type":"string"},"orgId":{"type":"string"},"ownerId":{"type":"string"},"httpUrl":{"type":"string"},"rtspUrl":{"type":"string"},"registrationCode":{"type":"string"},"registeredAt":{"type":"number"}},"required":["cameraId","threeDeyeCameraId","cameraType","name","orgId","ownerId","httpUrl","rtspUrl","registeredAt"],"additionalProperties":false},"CameraUpdated":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"cameraId":{"type":"string"},"name":{"type":"string"},"httpUrl":{"type":"string"},"rtspUrl":{"type":"string"},"updatedAt":{"type":"number"}},"required":["cameraId","updatedAt"],"additionalProperties":false},"CameraDisabled":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"cameraId":{"type":"string"},"reason":{"type":"string"},"disabledBy":{"type":"string"},"disabledAt":{"type":"number"}},"required":["cameraId","reason","disabledBy","disabledAt"],"additionalProperties":false},"CameraDeleted":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"cameraId":{"type":"string"},"deletedBy":{"type":"string"},"deletedAt":{"type":"number"}},"required":["cameraId","deletedBy","deletedAt"],"additionalProperties":false},"CameraLinkedToLock":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"cameraId":{"type":"string"},"lockId":{"type":"string"}},"required":["cameraId","lockId"],"additionalProperties":false},"CameraUnlinkedFromLock":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"cameraId":{"type":"string"}},"required":["cameraId"],"additionalProperties":false},"CameraRoleCreated":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"roleId":{"type":"string"},"threeDeyeRoleId":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"orgId":{"type":"string"},"createdAt":{"type":"number"}},"required":["roleId","threeDeyeRoleId","name","description","orgId","createdAt"],"additionalProperties":false},"CameraRoleDeleted":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"roleId":{"type":"string"},"deletedAt":{"type":"number"}},"required":["roleId","deletedAt"],"additionalProperties":false},"CameraRoleUserAssigned":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"roleId":{"type":"string"},"userId":{"type":"string"},"threeDeyeUserId":{"type":"string"},"assignedAt":{"type":"number"}},"required":["roleId","userId","threeDeyeUserId","assignedAt"],"additionalProperties":false},"CameraRoleUserRemoved":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"roleId":{"type":"string"},"userId":{"type":"string"},"threeDeyeUserId":{"type":"string"},"removedAt":{"type":"number"}},"required":["roleId","userId","threeDeyeUserId","removedAt"],"additionalProperties":false},"CameraRoleCameraAssigned":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"roleId":{"type":"string"},"cameraId":{"type":"string"},"permissions":{"type":"array","items":{"type":"string"}},"assignedAt":{"type":"number"}},"required":["roleId","cameraId","permissions","assignedAt"],"additionalProperties":false},"CameraRoleCameraRemoved":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"roleId":{"type":"string"},"cameraId":{"type":"string"},"removedAt":{"type":"number"}},"required":["roleId","cameraId","removedAt"],"additionalProperties":false},"TempKeyCreated":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"tempKeyUuid":{"type":"string"},"lockId":{"type":"number"},"lockUuid":{"type":"string"},"accessMode":{"type":"string","enum":["public","user-whitelist"]},"allowedUserIds":{"type":"array","items":{"type":"string"}},"validFrom":{"type":"string"},"validUntil":{"type":"string"},"maxUses":{"anyOf":[{"type":"number"},{"type":"null"}]},"createdBy":{"type":"string"},"timestamp":{"type":"string"}},"required":["tempKeyUuid","lockId","lockUuid","accessMode","validFrom","validUntil","createdBy","timestamp"],"additionalProperties":false},"TempKeyUsed":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"tempKeyUuid":{"type":"string"},"lockId":{"type":"number"},"lockUuid":{"type":"string"},"userId":{"type":"string"},"usedCount":{"type":"number"},"timestamp":{"type":"string"}},"required":["tempKeyUuid","lockId","lockUuid","usedCount","timestamp"],"additionalProperties":false},"TempKeyDeleted":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"tempKeyUuid":{"type":"string"},"lockId":{"type":"number"},"lockUuid":{"type":"string"},"deletedBy":{"type":"string"},"timestamp":{"type":"string"}},"required":["tempKeyUuid","lockId","lockUuid","deletedBy","timestamp"],"additionalProperties":false},"TempKeyUpdated":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"tempKeyUuid":{"type":"string"},"lockId":{"type":"number"},"lockUuid":{"type":"string"},"changes":{"type":"object","properties":{"validFrom":{"type":"string"},"validUntil":{"type":"string"},"maxUses":{"anyOf":[{"type":"number"},{"type":"null"}]},"allowedUserIds":{"type":"array","items":{"type":"string"}},"accessMode":{"type":"string","enum":["public","user-whitelist"]}},"additionalProperties":false},"updatedBy":{"type":"string"},"timestamp":{"type":"string"}},"required":["tempKeyUuid","lockId","lockUuid","changes","updatedBy","timestamp"],"additionalProperties":false},"MatterDeviceCreated":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"deviceId":{"type":"string"},"thingName":{"type":"string"},"hubId":{"type":"string"},"deviceType":{"type":"string"},"createdAt":{"type":"number"}},"required":["deviceId","thingName","hubId","deviceType","createdAt"],"additionalProperties":false},"ReportedShadowUpdated":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"deviceId":{"type":"string"},"thingName":{"type":"string"},"reported":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"updatedAt":{"type":"number"}},"required":["deviceId","thingName","reported","updatedAt"],"additionalProperties":false},"DesiredShadowUpdated":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"deviceId":{"type":"string"},"thingName":{"type":"string"},"desired":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"updatedAt":{"type":"number"}},"required":["deviceId","thingName","desired","updatedAt"],"additionalProperties":false},"RtspCameraRegistered":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"rtspCameraId":{"type":"string"},"name":{"type":"string"},"rtspUrl":{"type":"string"},"httpSnapshotUrl":{"type":"string"},"username":{"type":"string"},"ownerId":{"type":"string"},"orgId":{"type":"string"},"createdAt":{"type":"string"}},"required":["rtspCameraId","name","rtspUrl","createdAt"],"additionalProperties":false},"RtspCameraDeleted":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"rtspCameraId":{"type":"string"},"deletedAt":{"type":"string"},"deletedBy":{"type":"string"}},"required":["rtspCameraId","deletedAt"],"additionalProperties":false}}} \ No newline at end of file diff --git a/openapi.yaml b/openapi.yaml index c9f44c8..0abb9fb 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1733,7 +1733,8 @@ }, "orgId": { "type": "string", - "description": "Organization ID" + "minLength": 1, + "description": "Organization ID — opaque string, conventionally but not always a UUID" } }, "required": [ @@ -3817,6 +3818,219 @@ } } }, + "/cameras/{id}/stream": { + "get": { + "tags": [ + "Camera", + "Query" + ], + "summary": "Get camera streaming URLs", + "description": "Fetches live streaming URLs (HLS, DASH, RTMP, thumbnail, snapshot) from 3dEye for a specific camera. Requires the authenticated user to have View permission on the camera.", + "operationId": "get_GetCameraStreamRoute", + "parameters": [ + { + "schema": { + "type": "string", + "description": "Camera ID" + }, + "required": true, + "description": "Camera ID", + "name": "id", + "in": "path" + } + ], + "responses": { + "200": { + "description": "Streaming URLs retrieved successfully", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "cameraId": { + "type": "string", + "description": "Camera ID" + }, + "threeDeyeCameraId": { + "type": "string", + "description": "3dEye camera ID" + }, + "name": { + "type": "string", + "description": "Camera display name" + }, + "videoStreamState": { + "type": "string", + "description": "Current video stream state from 3dEye" + }, + "accessUrls": { + "type": "object", + "properties": { + "http": { + "type": "string", + "description": "HTTP stream URL" + }, + "rtsp": { + "type": "string", + "description": "RTSP stream URL" + }, + "hlsStream": { + "type": "string", + "description": "HLS stream URL" + }, + "dashStream": { + "type": "string", + "description": "DASH stream URL" + }, + "rtmpStream": { + "type": "string", + "description": "RTMP stream URL" + }, + "thumbnail": { + "type": "string", + "description": "Thumbnail URL" + }, + "snapShot": { + "type": "string", + "description": "Snapshot URL" + } + }, + "required": [ + "http", + "rtsp", + "hlsStream", + "dashStream", + "rtmpStream", + "thumbnail", + "snapShot" + ], + "description": "Stream access URLs for different protocols" + } + }, + "required": [ + "cameraId", + "threeDeyeCameraId", + "name", + "videoStreamState", + "accessUrls" + ] + } + } + } + }, + "401": { + "description": "Unauthorized — JWT authentication required", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "error", + "message" + ] + } + } + } + }, + "403": { + "description": "Forbidden — user does not have View permission on this camera", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "error", + "message" + ] + } + } + } + }, + "404": { + "description": "Camera not found or not active, or not linked to 3dEye", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "error", + "message" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "error", + "message" + ] + } + } + } + }, + "503": { + "description": "3dEye integration not configured", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "error", + "message" + ] + } + } + } + } + } + } + }, "/hubs/{id}/ClaimHub": { "post": { "tags": [ @@ -9126,51 +9340,491 @@ } } }, - "/temp-keys/{uuid}/open": { + "/rtsp-cameras/{id}/DeleteRtspCamera": { "post": { "tags": [ - "TempKey", - "Web" + "RtspCamera", + "Command" ], - "summary": "Open lock via temp key", - "description": "Validates a temporary key (expiration, usage limits, authorization) and sends an OpenLock command to the LockAggregate Durable Object. On success, increments the usage counter and redirects back to the temp key page. Public keys need no auth; user-whitelist keys require a JWT with a whitelisted userId.", - "operationId": "post_OpenTempKeyRoute", + "summary": "Delete an RTSP camera", + "description": "Soft-deletes an RTSP camera aggregate (status transitions to Deleted)", + "operationId": "post_DeleteRtspCameraRoute", "parameters": [ { "schema": { "type": "string", - "format": "uuid", - "description": "Temporary key UUID" + "description": "RTSP Camera UUID" }, "required": true, - "description": "Temporary key UUID", - "name": "uuid", + "description": "RTSP Camera UUID", + "name": "id", "in": "path" } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "deletedBy": { + "type": "string", + "description": "Actor who requested the deletion" + } + } + } + } + } + }, "responses": { - "303": { - "description": "Lock opened successfully, redirecting to temp key page" - }, - "400": { - "description": "Temporary key is invalid (not yet valid, expired, or used up)", + "200": { + "description": "RTSP camera deleted successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { - "error": { + "success": { + "type": "boolean" + }, + "aggregateId": { "type": "string" + }, + "version": { + "type": "number" + }, + "event": { + "type": [ + "object", + "null" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "RtspCameraDeleted" + ] + }, + "data": { + "type": "object", + "properties": { + "rtspCameraId": { + "type": "string" + }, + "deletedAt": { + "type": "string" + }, + "deletedBy": { + "type": "string" + } + }, + "required": [ + "rtspCameraId", + "deletedAt" + ] + } + }, + "required": [ + "type", + "data" + ] } }, "required": [ - "error" + "success", + "aggregateId", + "version", + "event" ] } } } }, - "403": { + "400": { + "description": "Camera is already deleted.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "error": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "success", + "error", + "message" + ] + } + } + } + }, + "401": { + "description": "Unauthorized — missing or invalid authentication credentials.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "error": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "success", + "error", + "message" + ] + } + } + } + }, + "403": { + "description": "Forbidden — you do not own this camera.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "error": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "success", + "error", + "message" + ] + } + } + } + }, + "404": { + "description": "Not found — the camera does not exist.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + }, + "errors": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "number" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + } + }, + "required": [ + "success", + "errors" + ] + } + } + } + } + } + } + }, + "/rtsp-cameras/{id}/RegisterRtspCamera": { + "post": { + "tags": [ + "RtspCamera", + "Command" + ], + "summary": "Register a new RTSP camera", + "description": "Creates a new RTSP camera aggregate for a simple plug-and-play camera", + "operationId": "post_RegisterRtspCameraRoute", + "parameters": [ + { + "schema": { + "type": "string", + "description": "RTSP Camera UUID" + }, + "required": true, + "description": "RTSP Camera UUID", + "name": "id", + "in": "path" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "rtspCameraId": { + "type": "string", + "description": "Camera UUID (caller-supplied or server-generated)" + }, + "name": { + "type": "string", + "minLength": 1, + "description": "Human-readable camera name" + }, + "rtspUrl": { + "type": "string", + "minLength": 1, + "description": "RTSP stream URL (e.g. rtsp://192.168.1.1:554/stream)" + }, + "httpSnapshotUrl": { + "type": "string", + "description": "HTTP snapshot URL for still image capture" + }, + "username": { + "type": "string", + "description": "Camera authentication username" + }, + "password": { + "type": "string", + "description": "Camera authentication password" + }, + "ownerId": { + "type": "string", + "description": "User ID who owns this camera (B2C)" + }, + "orgId": { + "type": "string", + "description": "Organisation ID that owns this camera (B2B)" + } + }, + "required": [ + "rtspCameraId", + "name", + "rtspUrl" + ] + } + } + } + }, + "responses": { + "200": { + "description": "RTSP camera registered successfully", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + }, + "aggregateId": { + "type": "string" + }, + "version": { + "type": "number" + }, + "event": { + "type": [ + "object", + "null" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "RtspCameraRegistered" + ] + }, + "data": { + "type": "object", + "properties": { + "rtspCameraId": { + "type": "string" + }, + "name": { + "type": "string" + }, + "rtspUrl": { + "type": "string" + }, + "httpSnapshotUrl": { + "type": "string" + }, + "username": { + "type": "string" + }, + "ownerId": { + "type": "string" + }, + "orgId": { + "type": "string" + }, + "createdAt": { + "type": "string" + } + }, + "required": [ + "rtspCameraId", + "name", + "rtspUrl", + "createdAt" + ] + } + }, + "required": [ + "type", + "data" + ] + } + }, + "required": [ + "success", + "aggregateId", + "version", + "event" + ] + } + } + } + }, + "400": { + "description": "Invalid request — validation failed.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "error": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "success", + "error", + "message" + ] + } + } + } + }, + "409": { + "description": "Conflict — camera already registered.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "enum": [ + false + ] + }, + "error": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "success", + "error", + "message" + ] + } + } + } + } + } + } + }, + "/temp-keys/{uuid}/open": { + "post": { + "tags": [ + "TempKey", + "Web" + ], + "summary": "Open lock via temp key", + "description": "Validates a temporary key (expiration, usage limits, authorization) and sends an OpenLock command to the LockAggregate Durable Object. On success, increments the usage counter and redirects back to the temp key page. Public keys need no auth; user-whitelist keys require a JWT with a whitelisted userId.", + "operationId": "post_OpenTempKeyRoute", + "parameters": [ + { + "schema": { + "type": "string", + "format": "uuid", + "description": "Temporary key UUID" + }, + "required": true, + "description": "Temporary key UUID", + "name": "uuid", + "in": "path" + } + ], + "responses": { + "303": { + "description": "Lock opened successfully, redirecting to temp key page" + }, + "400": { + "description": "Temporary key is invalid (not yet valid, expired, or used up)", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string" + } + }, + "required": [ + "error" + ] + } + } + } + }, + "403": { "description": "User not authorized to use this temporary key", "content": { "application/json": { @@ -9531,7 +10185,8 @@ "type": "string", "enum": [ "matter", - "camera" + "camera", + "rtsp-camera" ], "description": "matter | camera" }, @@ -9599,7 +10254,8 @@ "type": "string", "enum": [ "matter", - "camera" + "camera", + "rtsp-camera" ] }, "orgId": { @@ -10808,7 +11464,8 @@ "type": "string", "enum": [ "matter", - "camera" + "camera", + "rtsp-camera" ], "description": "Filter by device type (matter | camera)" }, @@ -10838,7 +11495,8 @@ "type": "string", "enum": [ "matter", - "camera" + "camera", + "rtsp-camera" ] }, "orgId": { @@ -11579,7 +12237,8 @@ "type": "string", "enum": [ "matter", - "camera" + "camera", + "rtsp-camera" ] }, "removedBy": { @@ -12321,15 +12980,29 @@ "enum": [ "user", "lock", - "hub" + "hub", + "matter-device", + "camera", + "camera-role", + "rtsp-camera" ], - "description": "Limit resync to a single aggregate type (user, lock, or hub). Omit to resync all." + "description": "Limit resync to a single aggregate type. Omit to resync all supported types." }, "required": false, - "description": "Limit resync to a single aggregate type (user, lock, or hub). Omit to resync all.", + "description": "Limit resync to a single aggregate type. Omit to resync all supported types.", "name": "aggregateType", "in": "query" }, + { + "schema": { + "type": "string", + "description": "Optional single aggregate ID to resync. Requires aggregateType. When set, the R2 list step is skipped — the workflow enqueues just this one DO." + }, + "required": false, + "description": "Optional single aggregate ID to resync. Requires aggregateType. When set, the R2 list step is skipped — the workflow enqueues just this one DO.", + "name": "aggregateId", + "in": "query" + }, { "schema": { "type": "string", @@ -12394,6 +13067,18 @@ }, "hub": { "type": "number" + }, + "matter-device": { + "type": "number" + }, + "camera": { + "type": "number" + }, + "camera-role": { + "type": "number" + }, + "rtsp-camera": { + "type": "number" } } }, @@ -12500,6 +13185,142 @@ } } }, + "/cameras/my": { + "get": { + "tags": [ + "Camera", + "Query" + ], + "summary": "List cameras accessible to the authenticated user", + "description": "Returns all cameras the authenticated B2C user can access via their camera role memberships. Permissions from multiple roles for the same camera are merged into a single entry.", + "operationId": "get_GetMyCamerasRoute", + "responses": { + "200": { + "description": "Camera list retrieved successfully", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "cameras": { + "type": "array", + "items": { + "type": "object", + "properties": { + "cameraId": { + "type": "string", + "description": "Camera ID" + }, + "threeDeyeCameraId": { + "type": "string", + "description": "3dEye camera ID" + }, + "name": { + "type": "string", + "description": "Camera display name" + }, + "type": { + "type": "string", + "description": "Camera type (generic, onvif, pnp)" + }, + "status": { + "type": "string", + "description": "Camera status" + }, + "httpUrl": { + "type": "string", + "description": "HTTP access URL for the camera" + }, + "rtspUrl": { + "type": "string", + "description": "RTSP streaming URL for the camera" + }, + "orgId": { + "type": "string", + "description": "Organization ID" + }, + "permissions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Permissions granted to the user for this camera" + } + }, + "required": [ + "cameraId", + "threeDeyeCameraId", + "name", + "type", + "status", + "httpUrl", + "rtspUrl", + "orgId", + "permissions" + ] + }, + "description": "Cameras accessible to the authenticated user" + }, + "total": { + "type": "number", + "description": "Total number of cameras returned" + } + }, + "required": [ + "cameras", + "total" + ] + } + } + } + }, + "401": { + "description": "Unauthorized — JWT authentication required", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "error", + "message" + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "error", + "message" + ] + } + } + } + } + } + } + }, "/temp-keys/{uuid}": { "get": { "tags": [