docs(streams): document phase4 on-demand APIs and web simulator

This commit is contained in:
2026-01-19 13:20:00 +00:00
parent d897eefcde
commit f66b5ad15d
2 changed files with 203 additions and 0 deletions

View File

@@ -734,6 +734,187 @@ registry.registerPath({
},
});
registry.registerPath({
method: 'post',
path: '/streams/request',
summary: 'Client device requests an on-demand stream from a linked camera',
tags: ['Streams'],
security: [{ bearerDeviceToken: [] }],
request: {
body: {
content: {
'application/json': {
schema: z.object({
cameraDeviceId: z.string().uuid(),
reason: z.enum(['on_demand', 'motion_follow_up']).optional(),
metadata: z.record(z.string(), z.unknown()).optional(),
}),
},
},
},
},
responses: {
201: {
description: 'Stream request created',
content: {
'application/json': {
schema: z.object({
message: z.string(),
streamSession: z.object({
id: z.string().uuid(),
ownerUserId: z.string().uuid(),
cameraDeviceId: z.string().uuid(),
requesterDeviceId: z.string().uuid(),
status: z.string(),
reason: z.string(),
}),
command: DeviceCommandSchema,
}),
},
},
},
},
});
registry.registerPath({
method: 'post',
path: '/streams/{streamSessionId}/accept',
summary: 'Camera device accepts a pending on-demand stream request',
tags: ['Streams'],
security: [{ bearerDeviceToken: [] }],
request: {
params: z.object({ streamSessionId: z.string().uuid() }),
body: {
content: {
'application/json': {
schema: z.object({
streamKey: z.string().optional(),
metadata: z.record(z.string(), z.unknown()).optional(),
}),
},
},
},
},
responses: {
200: {
description: 'Stream session accepted',
content: {
'application/json': {
schema: z.object({
message: z.string(),
streamSession: z.object({
id: z.string().uuid(),
status: z.string(),
streamKey: z.string().nullable(),
startedAt: z.string().datetime().nullable(),
}),
}),
},
},
},
},
});
registry.registerPath({
method: 'post',
path: '/streams/{streamSessionId}/end',
summary: 'Requester or camera ends an active stream session',
tags: ['Streams'],
security: [{ bearerDeviceToken: [] }],
request: {
params: z.object({ streamSessionId: z.string().uuid() }),
body: {
content: {
'application/json': {
schema: z.object({
reason: z.enum(['completed', 'cancelled', 'failed']).optional(),
}),
},
},
},
},
responses: {
200: {
description: 'Stream session ended',
content: {
'application/json': {
schema: z.object({
message: z.string(),
streamSession: z.object({
id: z.string().uuid(),
status: z.string(),
endedAt: z.string().datetime().nullable(),
}),
}),
},
},
},
},
});
registry.registerPath({
method: 'get',
path: '/streams/{streamSessionId}/playback-token',
summary: 'Get short-lived playback token for active stream session',
tags: ['Streams'],
security: [{ bearerDeviceToken: [] }],
request: {
params: z.object({ streamSessionId: z.string().uuid() }),
},
responses: {
200: {
description: 'Playback token response',
content: {
'application/json': {
schema: z.object({
streamSessionId: z.string().uuid(),
streamKey: z.string(),
status: z.string(),
playbackToken: z.string(),
expiresInSeconds: z.number().int(),
}),
},
},
},
},
});
registry.registerPath({
method: 'get',
path: '/streams/me/list',
summary: 'List stream sessions for current device',
tags: ['Streams'],
security: [{ bearerDeviceToken: [] }],
request: {
query: z.object({
status: z.string().optional(),
limit: z.coerce.number().int().min(1).max(100).default(25),
}),
},
responses: {
200: {
description: 'Stream sessions list',
content: {
'application/json': {
schema: z.object({
count: z.number().int(),
streamSessions: z.array(
z.object({
id: z.string().uuid(),
cameraDeviceId: z.string().uuid(),
requesterDeviceId: z.string().uuid(),
status: z.string(),
reason: z.string(),
streamKey: z.string().nullable(),
}),
),
}),
},
},
},
},
});
export function buildOpenApiDocument() {
const generator = new OpenApiGeneratorV3(registry.definitions);
const document = generator.generateDocument({
@@ -752,6 +933,7 @@ export function buildOpenApiDocument() {
{ name: 'Device Links', description: 'Client-camera authorization links' },
{ name: 'Commands', description: 'Realtime command dispatch and status' },
{ name: 'Events', description: 'Motion event lifecycle and user event history' },
{ name: 'Streams', description: 'On-demand live stream control lifecycle' },
],
});