repzo 1.0.292 → 1.0.293

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/changelog.md +28 -0
  2. package/lib/index.d.ts +244 -2
  3. package/lib/index.js +541 -0
  4. package/lib/types/index.d.ts +4530 -1
  5. package/package.json +1 -1
  6. package/src/index.ts +1270 -0
  7. package/src/oas/activity-ai-object-detection-session-frame.yaml +600 -0
  8. package/src/oas/ai-object-detection-assigned-missions.yaml +283 -0
  9. package/src/oas/ai-object-detection-assignment-rule.yaml +357 -0
  10. package/src/oas/ai-object-detection-category.yaml +338 -0
  11. package/src/oas/ai-object-detection-dataset.yaml +342 -0
  12. package/src/oas/ai-object-detection-detection-settings.yaml +410 -0
  13. package/src/oas/ai-object-detection-inference.yaml +818 -0
  14. package/src/oas/ai-object-detection-label-group.yaml +265 -0
  15. package/src/oas/ai-object-detection-label-report.yaml +366 -0
  16. package/src/oas/ai-object-detection-label.yaml +395 -0
  17. package/src/oas/ai-object-detection-metric-result.yaml +734 -0
  18. package/src/oas/ai-object-detection-metric.yaml +559 -0
  19. package/src/oas/ai-object-detection-mission-results.yaml +370 -0
  20. package/src/oas/ai-object-detection-mission-set.yaml +250 -0
  21. package/src/oas/ai-object-detection-mission.yaml +349 -0
  22. package/src/oas/ai-object-detection-model-version-epoch.yaml +214 -0
  23. package/src/oas/ai-object-detection-model-version-train-agent.yaml +88 -0
  24. package/src/oas/ai-object-detection-model-version.yaml +567 -0
  25. package/src/oas/ai-object-detection-model.yaml +369 -0
  26. package/src/oas/ai-object-detection-segment.yaml +301 -0
  27. package/src/oas/ai-object-detection-session-analysis.yaml +1306 -0
  28. package/src/oas/ai-object-detection-session-election.yaml +193 -0
  29. package/src/oas/ai-object-detection-session-insight.yaml +418 -0
  30. package/src/oas/ai-object-detection-session.yaml +840 -0
  31. package/src/oas/ai-object-detection-settings.yaml +249 -0
  32. package/src/oas/ai-object-detection-task.yaml +1007 -0
  33. package/src/oas/object-detection-analytics-report.yaml +674 -0
  34. package/src/types/index.ts +5156 -1
@@ -0,0 +1,600 @@
1
+ openapi: 3.0.3
2
+ info:
3
+ title: Repzo API - Activity AI Object Detection Session Frame
4
+ version: 1.0.0
5
+ description: |
6
+ **Session Frame intake** is the write-only multipart endpoint the
7
+ mobile AR app POSTs each captured frame to during a shelf scan. It
8
+ is the ingest half of the Object Detection Sessions feature — see
9
+ `ai-object-detection-session` for the parent record. It replaces the
10
+ removed `/ai-object-detection-session-frame` endpoint, adding the
11
+ field-sales context: every frame is attributed to a **client**
12
+ (store) and optionally the capturing **rep**.
13
+
14
+ **What it does (per frame).**
15
+ 1. Parses `meta_inline` (a JSON text field carrying the AR pose,
16
+ intrinsics, tracking quality, depth stats, frame id, and the
17
+ device's `session_id`).
18
+ 2. Validates `client` — a `clients` `_id` that must exist (and not be
19
+ disabled) within the caller's namespace.
20
+ 3. Upserts the parent `ai-object-detection-session` keyed by
21
+ `(company_namespace, session_id)` — the first frame opens the
22
+ session, later frames reuse it. Every frame (re)stamps the
23
+ session's `client` and — when sent — its `rep` and field-sales
24
+ context (`visit_id` / `route` / `business_day` / `time_zone`); a
25
+ frame without them never erases what an earlier one wrote. A
26
+ session without a `business_day` gets one stamped ONCE from the
27
+ capture time under the rep's stamping context (open-day snapshot:
28
+ shift schedule, `end_of_day` cut, time zone — the way every other
29
+ activity gets its business day). The evaluator copies the visit
30
+ id, route and business day onto the mission/metric results — that
31
+ is how the assigned-missions read tells "done in THIS visit" and
32
+ counts per-day demands in business days.
33
+ 4. Resolves the frame image from `media_id` — the
34
+ `media.mediaStorages` `_id` of the **pre-uploaded** image (the
35
+ client uploads the RGB frame separately, e.g. via a presigned
36
+ URL, and passes its id here). The id is validated to exist within
37
+ the caller's namespace; the raw image bytes are **not** sent to
38
+ this endpoint. Optional `depth` / `confidence` binary blobs are
39
+ still uploaded inline as multipart files.
40
+ 5. Materializes the frame as a normal `ai-object-detection-task`
41
+ carrying `session`, `frame_meta`, `file_media` (= `media_id`),
42
+ `depth_media`, and `confidence_media` — the inference/analysis
43
+ pipeline is unchanged.
44
+ 6. Persists an activity frame document (collection
45
+ `ai.objectDetectionSessionFrames`) carrying `client`, `rep`, the
46
+ session/task refs, and the optional field-sales context
47
+ (`visit_id` / `route` / `business_day` / `time_zone` / `geo_tag` /
48
+ `time`). The image, per-frame AR meta, and
49
+ depth/confidence media are not duplicated — they live on the
50
+ referenced task.
51
+ 7. Atomically increments the session's `frames_total`,
52
+ `frames_accepted`, and `tasks_count` counters.
53
+
54
+ **Who calls it.** Reps (rep-auth via `x-rep-login` + JWT) or an API
55
+ key. The tenant key (`company_namespace`) is injected from the
56
+ caller's credential. When authenticated as a rep and `rep` is not
57
+ sent, it defaults to the rep in the token.
58
+
59
+ **Only `create` is allowed.** `find`, `get`, `update`, `patch`, and
60
+ `remove` all reject. Query / inspect frames via the
61
+ `ai-object-detection-task` service filtered by `?session=:id`.
62
+
63
+ **Content type.** `multipart/form-data` — the `media_id` + `client` +
64
+ `meta_inline` text parts, plus optional `depth` / `confidence` file
65
+ parts. An `application/json` body carrying the same text fields is
66
+ also accepted (`meta_inline` / `geo_tag` may then be objects instead of
67
+ JSON strings); binary depth/confidence parts cannot be sent that way.
68
+
69
+ **Required fields per mode.** Frame post: `client`, `media_id` (top-level
70
+ or inside `meta_inline`) and `session_id` (top-level or inside
71
+ `meta_inline`). Completion marker: `session_id` + `session_complete`.
72
+ servers:
73
+ - url: https://sv.api.repzo.me
74
+ security:
75
+ - ApiKeyAuth: []
76
+ - JwtAuth: []
77
+ paths:
78
+ /activity-ai-object-detection-session-frame:
79
+ post:
80
+ summary: Submit one AR frame (or the upload-complete marker)
81
+ description: |
82
+ Multipart frame intake. Validates the `client`, upserts the parent
83
+ session (stamping its `client` and optional `category`), references
84
+ the pre-uploaded frame image by `media_id`, uploads the optional
85
+ depth/confidence blobs, materializes a task, persists the activity
86
+ frame document, and increments the session counters. Returns the
87
+ resulting ids.
88
+
89
+ **Completion marker:** when `session_complete=true` (top-level field
90
+ or inside `meta_inline`) the post carries NO frame — only
91
+ `session_id`. The session flips `open` → `uploaded`, and when it
92
+ carries a detection `category` (and its verdict is not `rejected`)
93
+ one background analysis is fired per category `model_settings` item,
94
+ serially. Responds with `SessionCompleteResult` instead of
95
+ `FrameResult`.
96
+ operationId: createActivityAiObjectDetectionSessionFrame
97
+ requestBody:
98
+ required: true
99
+ content:
100
+ application/json:
101
+ schema:
102
+ $ref: "#/components/schemas/FrameCreateBody"
103
+ multipart/form-data:
104
+ schema:
105
+ type: object
106
+ description: |
107
+ See the service description for which fields are required in
108
+ frame mode vs completion-marker mode.
109
+ properties:
110
+ media_id:
111
+ type: string
112
+ description: |
113
+ `media.mediaStorages` `_id` of the pre-uploaded RGB frame
114
+ image. Must exist within the caller's namespace. Becomes the
115
+ task's `file_media`. May also be supplied inside `meta_inline`.
116
+ client:
117
+ type: string
118
+ description: |
119
+ `clients` `_id` the captured shelf belongs to. Must exist
120
+ (and not be disabled) within the caller's namespace. Stored
121
+ on the activity frame document and stamped onto the parent
122
+ session.
123
+ rep:
124
+ type: string
125
+ description: |
126
+ Optional `representatives` `_id` of the capturing rep.
127
+ Defaults to the rep in the token for rep-auth calls.
128
+ depth:
129
+ type: string
130
+ format: binary
131
+ description: Optional raw float32 depth blob.
132
+ confidence:
133
+ type: string
134
+ format: binary
135
+ description: Optional raw uint8 depth-confidence blob.
136
+ meta_inline:
137
+ type: string
138
+ description: |
139
+ JSON-encoded per-frame AR metadata. Must include
140
+ `session_id` unless it is sent top-level. See `MetaInline`
141
+ in Schemas for the parsed shape.
142
+ meta:
143
+ type: string
144
+ description: Alias for `meta_inline`.
145
+ session_id:
146
+ type: string
147
+ description: |
148
+ Fallback device session id if not present inside
149
+ `meta_inline`.
150
+ visit_id:
151
+ type: string
152
+ description: |
153
+ The DEVICE visit id (`visits.visit_id`) of the visit the
154
+ scan happens in — the same id every activity carries.
155
+ Visits are created offline and may not be synced yet, so it
156
+ is stored as-is on the frame and the parent session and
157
+ never resolved to a server ref. Also accepted inside
158
+ `meta_inline` (the text part wins).
159
+ route:
160
+ type: string
161
+ description: Optional `sv.routes` `_id` of the visit's route.
162
+ business_day:
163
+ type: string
164
+ description: "Optional business day of the visit, `YYYY-MM-DD` (rejected otherwise). When absent the session is stamped once from the capture time under the rep's stamping context."
165
+ time_zone:
166
+ type: string
167
+ description: Optional IANA timezone of the device at capture.
168
+ geo_tag:
169
+ type: string
170
+ description: |
171
+ Optional JSON-encoded `{lat, lng, formatted_address?}`
172
+ capture location. `lat`/`lng` must be numeric.
173
+ time:
174
+ type: number
175
+ description: Optional device epoch (ms) of the capture.
176
+ session_complete:
177
+ type: string
178
+ enum: ["true"]
179
+ description: |
180
+ Completion-marker mode — send with `session_id` (and no
181
+ frame parts) once the device's upload queue drains. Also
182
+ accepted inside `meta_inline`.
183
+ company_namespace:
184
+ type: array
185
+ items: { type: string }
186
+ description: Optional tenant namespace override for SDK callers.
187
+ responses:
188
+ "201":
189
+ description: |
190
+ Frame intake returns the created frame's session/task/frame/media
191
+ ids (`FrameResult`); a completion marker returns the session
192
+ status + auto-analysis outcome (`SessionCompleteResult`).
193
+ content:
194
+ application/json:
195
+ schema:
196
+ oneOf:
197
+ - $ref: "#/components/schemas/FrameResult"
198
+ - $ref: "#/components/schemas/SessionCompleteResult"
199
+ components:
200
+ securitySchemes:
201
+ ApiKeyAuth:
202
+ type: apiKey
203
+ in: header
204
+ name: api-key
205
+ description: |
206
+ Server-issued API key. Also accepted via the `x-api-key` header or the
207
+ `?apiKey=` query parameter as fallbacks.
208
+ JwtAuth:
209
+ type: apiKey
210
+ in: header
211
+ name: Authorization
212
+ description: |
213
+ Raw JWT in the `Authorization` header — **no `Bearer ` prefix**.
214
+ Obtained from `POST /authenticate` (admin / rep / client login).
215
+ schemas:
216
+ MetaInline:
217
+ type: object
218
+ description: |
219
+ Parsed shape of the `meta_inline` JSON text part. Fields map onto
220
+ the materialized task's `frame_meta`. The device's camelCase aliases
221
+ (`trackingScore`, `eulerYPR`, `imageStats`, `driftM`, `velocityMps`,
222
+ `imageRotationDeg`, `tracking` as a bare state string) are tolerated
223
+ and normalized; invalid values (e.g. `shutter: "—"`) are dropped.
224
+ properties:
225
+ session_id:
226
+ type: string
227
+ description: Device-generated session id (4-char).
228
+ media_id:
229
+ type: string
230
+ description: |
231
+ Fallback `media.mediaStorages` `_id` of the frame image, if not
232
+ sent as the top-level `media_id` form field.
233
+ visit_id:
234
+ type: string
235
+ description: Alias of the `visit_id` text part (the text part wins).
236
+ route:
237
+ type: string
238
+ description: Alias of the `route` text part.
239
+ business_day:
240
+ type: string
241
+ description: Alias of the `business_day` text part.
242
+ time_zone:
243
+ type: string
244
+ description: Alias of the `time_zone` text part.
245
+ frame_id:
246
+ type: number
247
+ description: Session-scoped frame counter.
248
+ ts:
249
+ type: number
250
+ description: Device epoch (ms).
251
+ pose:
252
+ type: array
253
+ items: { type: number }
254
+ description: 16-float 4x4 pose matrix, column-major.
255
+ euler_ypr:
256
+ type: array
257
+ items: { type: number }
258
+ description: 3-float yaw/pitch/roll in degrees.
259
+ intrinsics:
260
+ type: object
261
+ properties:
262
+ fx: { type: number }
263
+ fy: { type: number }
264
+ cx: { type: number }
265
+ cy: { type: number }
266
+ distortion:
267
+ type: object
268
+ properties:
269
+ k1: { type: number }
270
+ k2: { type: number }
271
+ k3: { type: number }
272
+ p1: { type: number }
273
+ p2: { type: number }
274
+ tracking:
275
+ type: object
276
+ properties:
277
+ state: { type: string, enum: [NORMAL, LIMITED, LOST] }
278
+ score: { type: number }
279
+ drift_m: { type: number }
280
+ velocity_mps: { type: number }
281
+ distance_to_shelf_m:
282
+ type: number
283
+ description: |
284
+ Shelf-distance gate (meters) captured at the frame. Also accepted
285
+ as `depth.distanceToShelfM` from the device. Stored on
286
+ `frame_meta.distance_to_shelf_m` and used by inference back-projection.
287
+ image_stats:
288
+ type: object
289
+ properties:
290
+ iso: { type: number }
291
+ shutter: { type: number }
292
+ lux: { type: number }
293
+ sharpness:
294
+ type: number
295
+ description: >-
296
+ Variance-of-Laplacian focus measure from the device (higher =
297
+ sharper, -1 = unmeasured). Persisted on
298
+ `frame_meta.image_stats.sharpness` — election-quality input.
299
+ depth:
300
+ type: object
301
+ description: >-
302
+ Depth-map summary from the device. `width`/`height` and the
303
+ confidence fractions persist on `frame_meta.depth_summary`
304
+ (election-quality input); `distanceToShelfM` persists on
305
+ `frame_meta.distance_to_shelf_m`.
306
+ properties:
307
+ width: { type: number }
308
+ height: { type: number }
309
+ minM:
310
+ type: number
311
+ description: Legacy nearest-depth sample (metres) — fallback for `min_distance_depth`.
312
+ maxM:
313
+ type: number
314
+ description: Legacy farthest-depth sample (metres) — fallback for `max_distance_depth`.
315
+ distanceToShelfM: { type: number }
316
+ confidence:
317
+ type: object
318
+ properties:
319
+ high: { type: number }
320
+ medium: { type: number }
321
+ low: { type: number }
322
+ depth_source:
323
+ type: string
324
+ enum: [lidar, estimated, none]
325
+ min_distance_depth:
326
+ type: number
327
+ description: >-
328
+ Flat capture-quality key (app >= 0.39.0): nearest depth sample in
329
+ the frame, meters. Derived from `depth.minM` for older builds.
330
+ Persisted on `frame_meta.min_distance_depth`.
331
+ max_distance_depth:
332
+ type: number
333
+ description: >-
334
+ Farthest depth sample in the frame, meters. Derived from
335
+ `depth.maxM` for older builds. Persisted on
336
+ `frame_meta.max_distance_depth`.
337
+ depth_variation:
338
+ type: number
339
+ description: >-
340
+ Depth span of the frame (max - min), meters — the device
341
+ validator's depth-variation gate input. Derived from
342
+ `depth.maxM - depth.minM` when absent. Persisted on
343
+ `frame_meta.depth_variation`.
344
+ yaw_degree:
345
+ type: number
346
+ description: >-
347
+ Camera yaw at capture, degrees. Derived from `euler_ypr[0]` for
348
+ older builds. Persisted on `frame_meta.yaw_degree`.
349
+ pitch_degree:
350
+ type: number
351
+ description: >-
352
+ Camera pitch at capture, degrees (fallback `euler_ypr[1]`).
353
+ Persisted on `frame_meta.pitch_degree`.
354
+ roll_degree:
355
+ type: number
356
+ description: >-
357
+ Camera roll at capture, degrees (fallback `euler_ypr[2]`).
358
+ Persisted on `frame_meta.roll_degree`.
359
+ frame_sharpness:
360
+ type: number
361
+ description: >-
362
+ Variance-of-Laplacian focus measure (higher = sharper). Falls back
363
+ to `image_stats.sharpness`; the unmeasured sentinel (-1) is
364
+ dropped. Persisted on `frame_meta.frame_sharpness`.
365
+ capture_tier:
366
+ type: string
367
+ enum: [good, warn, error]
368
+ description: >-
369
+ Device validator verdict for the frame at capture time, evaluated
370
+ against the polled detection-settings limits. Persisted on
371
+ `frame_meta.capture_tier`.
372
+ detection_settings_polled_at:
373
+ type: number
374
+ description: >-
375
+ Epoch ms of the app's last successful detection-settings poll
376
+ (`/ai-object-detection-detection-settings`) before this frame was
377
+ submitted — tells analysis which config governed capture.
378
+ Persisted on `frame_meta.detection_settings_polled_at`.
379
+ image_rotation_deg:
380
+ type: number
381
+ description: >-
382
+ Degrees the sensor image was rotated CW to produce the stored
383
+ image — lets inference map the detection box back into the
384
+ sensor frame exactly. Persisted on `frame_meta.image_rotation_deg`.
385
+ depth_shape:
386
+ type: array
387
+ items: { type: number }
388
+ description: "[width, height] of the depth blob."
389
+ image_shape:
390
+ type: array
391
+ items: { type: number }
392
+ description: "[width, height] of the image."
393
+ device:
394
+ type: object
395
+ description: >-
396
+ Device descriptor — applied to the session on first frame;
397
+ `app_version` is also persisted per-frame on
398
+ `frame_meta.app_version`.
399
+ properties:
400
+ platform: { type: string }
401
+ os: { type: string }
402
+ model: { type: string }
403
+ app_version: { type: string }
404
+ ar_engine: { type: string, enum: [ARKit, ARCore] }
405
+ capture_settings:
406
+ type: object
407
+ description: >-
408
+ Capture configuration in effect for the session — applied to the
409
+ session on first frame, next to `device`. The dashboard's Capture
410
+ context panel reads both.
411
+ properties:
412
+ rate_hz:
413
+ type: number
414
+ description: AR frame capture rate the app was set to (Hz).
415
+ recording_enabled: { type: boolean }
416
+ target_distance_m: { type: number }
417
+ resolution:
418
+ type: string
419
+ enum: [medium, high, max]
420
+ description: Camera format preference active during capture.
421
+ coverage_m2:
422
+ type: number
423
+ description: >-
424
+ Device-computed swept shelf area for the WHOLE session so far, m²
425
+ — includes quality-rejected capture attempts that are never
426
+ uploaded, so the server cannot recompute it. Upserted onto the
427
+ session via $max (monotonic; frames may arrive out of order).
428
+ world_alignment:
429
+ type: string
430
+ enum: [gravity]
431
+ description: >-
432
+ How the AR world's vertical relates to earth vertical. Both ARKit
433
+ (default `.gravity`) and ARCore run gravity-aligned world frames,
434
+ so world Y IS earth vertical — recorded on the session so
435
+ consumers never have to assume it.
436
+ ground:
437
+ type: object
438
+ description: >-
439
+ Floor lock measured on-device at capture entry (optional — the rep
440
+ can skip it): the floor's Y in the AR world frame plus lock
441
+ quality. With the gravity-aligned world, the height above the
442
+ floor of ANY world point is `y − ground.y_world`. The device
443
+ re-locks after every AR session restart (the world frame resets),
444
+ so the last write matches the newest frames' poses. Upserted onto
445
+ the parent session.
446
+ properties:
447
+ y_world:
448
+ type: number
449
+ description: Floor height (world Y), metres.
450
+ samples:
451
+ type: integer
452
+ description: Gated depth samples behind the median.
453
+ spread_m:
454
+ type: number
455
+ description: Interquartile spread of those samples, metres — lock quality.
456
+ camera_height_m:
457
+ type: number
458
+ description: Camera height above the floor at lock time, metres.
459
+ eye_level_m:
460
+ type: number
461
+ description: >-
462
+ Camera height above the locked floor while shooting the shelf
463
+ (median of the first stable capture frames), metres — ≈ the rep's
464
+ standing eye level. Upserted onto the parent session.
465
+ ground_skipped:
466
+ type: boolean
467
+ description: >-
468
+ True when the rep tapped Skip on the floor point — records the
469
+ deliberate choice so an absent `ground` can be told apart from a
470
+ lock that never converged. Upserted onto the parent session.
471
+ category:
472
+ type: string
473
+ description: >-
474
+ Optional `ai-object-detection-category` `_id` picked on the device
475
+ before calibration. Stamped onto the parent session with every
476
+ frame; drives the auto-analysis fired by the completion marker.
477
+ Non-fatal when the category no longer exists (frame is kept,
478
+ category not stamped).
479
+ mission:
480
+ type: string
481
+ description: >-
482
+ Optional `ai-object-detection-mission` `_id` the session was
483
+ STARTED FROM ("SCAN THIS MISSION"). Stamped onto the parent
484
+ session with every frame — the attribution anchor for mission
485
+ completions and mission-result rows. Non-fatal when the mission
486
+ no longer exists (frame is kept, mission not stamped).
487
+ session_complete:
488
+ type: boolean
489
+ description: >-
490
+ Completion-marker flag (see the endpoint description) — when true
491
+ the post is frameless and only flips the session to uploaded +
492
+ fires the category auto-analysis.
493
+ FrameCreateBody:
494
+ type: object
495
+ description: |
496
+ JSON-equivalent of the multipart intake (no binary depth/confidence
497
+ parts). Frame mode requires `client`, `media_id` and `session_id`
498
+ (the latter two top-level or inside `meta_inline`); completion-marker
499
+ mode requires `session_id` + `session_complete`.
500
+ properties:
501
+ media_id: { type: string }
502
+ session_id: { type: string }
503
+ meta_inline:
504
+ oneOf:
505
+ - type: string
506
+ description: JSON-encoded `MetaInline`.
507
+ - $ref: "#/components/schemas/MetaInline"
508
+ meta:
509
+ description: Alias for `meta_inline`.
510
+ oneOf:
511
+ - type: string
512
+ - $ref: "#/components/schemas/MetaInline"
513
+ client: { type: string }
514
+ rep: { type: string }
515
+ visit_id: { type: string }
516
+ route: { type: string }
517
+ business_day:
518
+ type: string
519
+ description: "`YYYY-MM-DD`."
520
+ time_zone: { type: string }
521
+ geo_tag:
522
+ oneOf:
523
+ - type: string
524
+ description: JSON-encoded `{ lat, lng, formatted_address? }`.
525
+ - type: object
526
+ properties:
527
+ lat: { type: number }
528
+ lng: { type: number }
529
+ formatted_address: { type: string }
530
+ time:
531
+ oneOf:
532
+ - type: number
533
+ - type: string
534
+ description: Device epoch (ms) of the capture.
535
+ session_complete:
536
+ oneOf:
537
+ - type: boolean
538
+ - type: string
539
+ company_namespace:
540
+ type: array
541
+ items: { type: string }
542
+ description: Optional tenant namespace override for SDK callers.
543
+ FrameResult:
544
+ type: object
545
+ properties:
546
+ session:
547
+ type: string
548
+ description: The parent session `_id`.
549
+ session_id:
550
+ type: string
551
+ task:
552
+ type: string
553
+ description: The materialized task `_id`.
554
+ frame:
555
+ type: string
556
+ description: The activity frame document `_id`.
557
+ frame_id:
558
+ type: number
559
+ client:
560
+ type: string
561
+ description: The `clients` `_id` the frame was attributed to.
562
+ file_media:
563
+ type: string
564
+ description: Media id of the uploaded image.
565
+ depth_media:
566
+ type: string
567
+ nullable: true
568
+ description: Media id of the uploaded depth blob, if provided.
569
+ confidence_media:
570
+ type: string
571
+ nullable: true
572
+ description: Media id of the uploaded confidence blob, if provided.
573
+ SessionCompleteResult:
574
+ type: object
575
+ description: Response of a `session_complete=true` (frameless) post.
576
+ properties:
577
+ session:
578
+ type: string
579
+ description: The session `_id`.
580
+ session_id:
581
+ type: string
582
+ status:
583
+ type: string
584
+ enum: [uploaded]
585
+ auto_analysis:
586
+ type: object
587
+ description: >-
588
+ Whether the category auto-analysis was fired. When triggered,
589
+ `runs` = number of category model_settings items queued (executed
590
+ serially in the background).
591
+ properties:
592
+ triggered: { type: boolean }
593
+ reason:
594
+ type: string
595
+ description: >-
596
+ Present when not triggered — no_category,
597
+ category_has_no_model_settings, session_verdict_rejected, or
598
+ error.
599
+ category: { type: string }
600
+ runs: { type: number }