repzo 1.0.291 → 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.
- package/changelog.md +28 -0
- package/lib/index.d.ts +244 -2
- package/lib/index.js +541 -0
- package/lib/types/index.d.ts +4533 -1
- package/package.json +1 -1
- package/src/index.ts +1270 -0
- package/src/oas/activity-ai-object-detection-session-frame.yaml +600 -0
- package/src/oas/ai-object-detection-assigned-missions.yaml +283 -0
- package/src/oas/ai-object-detection-assignment-rule.yaml +357 -0
- package/src/oas/ai-object-detection-category.yaml +338 -0
- package/src/oas/ai-object-detection-dataset.yaml +342 -0
- package/src/oas/ai-object-detection-detection-settings.yaml +410 -0
- package/src/oas/ai-object-detection-inference.yaml +818 -0
- package/src/oas/ai-object-detection-label-group.yaml +265 -0
- package/src/oas/ai-object-detection-label-report.yaml +366 -0
- package/src/oas/ai-object-detection-label.yaml +395 -0
- package/src/oas/ai-object-detection-metric-result.yaml +734 -0
- package/src/oas/ai-object-detection-metric.yaml +559 -0
- package/src/oas/ai-object-detection-mission-results.yaml +370 -0
- package/src/oas/ai-object-detection-mission-set.yaml +250 -0
- package/src/oas/ai-object-detection-mission.yaml +349 -0
- package/src/oas/ai-object-detection-model-version-epoch.yaml +214 -0
- package/src/oas/ai-object-detection-model-version-train-agent.yaml +88 -0
- package/src/oas/ai-object-detection-model-version.yaml +567 -0
- package/src/oas/ai-object-detection-model.yaml +369 -0
- package/src/oas/ai-object-detection-segment.yaml +301 -0
- package/src/oas/ai-object-detection-session-analysis.yaml +1306 -0
- package/src/oas/ai-object-detection-session-election.yaml +193 -0
- package/src/oas/ai-object-detection-session-insight.yaml +418 -0
- package/src/oas/ai-object-detection-session.yaml +840 -0
- package/src/oas/ai-object-detection-settings.yaml +249 -0
- package/src/oas/ai-object-detection-task.yaml +1007 -0
- package/src/oas/object-detection-analytics-report.yaml +674 -0
- package/src/types/index.ts +5159 -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 }
|