@ingenx-io/valets-schema-mcp-server 0.1.4 → 0.1.6
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/data/docs/collections/firestore-paths.md +42 -8
- package/data/docs/enums/attention-status.md +1 -1
- package/data/docs/enums/booking-status.md +1 -1
- package/data/docs/enums/customer-payment-status.md +1 -1
- package/data/docs/enums/customer-payment-target-type.md +1 -1
- package/data/docs/enums/delivery-type.md +1 -1
- package/data/docs/enums/deployment-link-type.md +26 -0
- package/data/docs/enums/event-status.md +2 -2
- package/data/docs/enums/fulfillment-status.md +2 -2
- package/data/docs/enums/loyalty-transaction-type.md +2 -2
- package/data/docs/enums/order-status.md +2 -2
- package/data/docs/enums/payment-method.md +2 -2
- package/data/docs/enums/payment-proof-status.md +2 -2
- package/data/docs/enums/payment-status.md +2 -2
- package/data/docs/enums/pending-issue.md +2 -2
- package/data/docs/enums/return-status.md +2 -2
- package/data/docs/enums/session-status.md +2 -2
- package/data/docs/enums/site-status.md +24 -0
- package/data/docs/enums/stocktake-frequency.md +24 -0
- package/data/docs/enums/stocktake-item-status.md +24 -0
- package/data/docs/enums/stocktake-status.md +24 -0
- package/data/docs/enums/ticket-status.md +2 -2
- package/data/docs/index.md +14 -3
- package/data/docs/models/allowed-user.md +1 -1
- package/data/docs/models/analytics-backfill.md +398 -0
- package/data/docs/models/analytics-daily.md +351 -0
- package/data/docs/models/analytics-event.md +2 -2
- package/data/docs/models/analytics-hourly.md +372 -0
- package/data/docs/models/booking-version.md +2 -2
- package/data/docs/models/booking.md +2 -2
- package/data/docs/models/customer-payment-allocation.md +2 -2
- package/data/docs/models/customer-payment.md +2 -2
- package/data/docs/models/customer.md +2 -2
- package/data/docs/models/event.md +2 -2
- package/data/docs/models/loyalty-config.md +2 -2
- package/data/docs/models/loyalty-reward.md +2 -2
- package/data/docs/models/loyalty-status.md +2 -2
- package/data/docs/models/loyalty-transaction.md +2 -2
- package/data/docs/models/magic-link-request.md +2 -2
- package/data/docs/models/metrics-current.md +2 -2
- package/data/docs/models/metrics-daily.md +2 -2
- package/data/docs/models/metrics-monthly.md +2 -2
- package/data/docs/models/order-item.md +2 -2
- package/data/docs/models/order.md +248 -220
- package/data/docs/models/sale.md +2 -2
- package/data/docs/models/site-payment.md +2 -2
- package/data/docs/models/site.md +561 -0
- package/data/docs/models/stocktake-item.md +500 -0
- package/data/docs/models/stocktake.md +649 -0
- package/data/docs/models/ticket.md +2 -2
- package/data/static/llms.txt +309 -2
- package/data/static/openapi.yaml +972 -0
- package/data/static/schemas.json +1249 -77
- package/package.json +1 -1
package/data/static/openapi.yaml
CHANGED
|
@@ -69,6 +69,17 @@ components:
|
|
|
69
69
|
comes to the business (ON_SITE), collects their order themselves (PICK_UP),
|
|
70
70
|
or receives a physical delivery (DELIVERY). Drives whether fulfillmentStatus
|
|
71
71
|
is relevant.
|
|
72
|
+
DeploymentLinkType:
|
|
73
|
+
type: string
|
|
74
|
+
enum:
|
|
75
|
+
- web
|
|
76
|
+
- mobile
|
|
77
|
+
- pwa
|
|
78
|
+
- app-store
|
|
79
|
+
- play-store
|
|
80
|
+
- other
|
|
81
|
+
description: Category of a Site deployment link (D41). Used for UI icon/labelling
|
|
82
|
+
and deep-link handling.
|
|
72
83
|
EventStatus:
|
|
73
84
|
type: string
|
|
74
85
|
enum:
|
|
@@ -184,6 +195,39 @@ components:
|
|
|
184
195
|
- CANCELLED
|
|
185
196
|
description: Per-date/per-slot booking session status (D19). Dashboard is sole
|
|
186
197
|
writer; Mobile is read-only.
|
|
198
|
+
SiteStatus:
|
|
199
|
+
type: string
|
|
200
|
+
enum:
|
|
201
|
+
- ACTIVE
|
|
202
|
+
- INACTIVE
|
|
203
|
+
- EXPIRED
|
|
204
|
+
- ARCHIVED
|
|
205
|
+
description: Lifecycle status for a Site (D41). Drives whether the site is reachable
|
|
206
|
+
and whether analytics/payments flow.
|
|
207
|
+
StocktakeFrequency:
|
|
208
|
+
type: string
|
|
209
|
+
enum:
|
|
210
|
+
- DAILY
|
|
211
|
+
- WEEKLY
|
|
212
|
+
- MONTHLY
|
|
213
|
+
- AD_HOC
|
|
214
|
+
description: Recurrence cadence of a Stocktake session (GH#29 §4).
|
|
215
|
+
StocktakeItemStatus:
|
|
216
|
+
type: string
|
|
217
|
+
enum:
|
|
218
|
+
- PENDING
|
|
219
|
+
- COUNTED
|
|
220
|
+
- VERIFIED
|
|
221
|
+
- ADJUSTED
|
|
222
|
+
description: Per-line workflow status inside a Stocktake (GH#29 §4, audit Q21).
|
|
223
|
+
StocktakeStatus:
|
|
224
|
+
type: string
|
|
225
|
+
enum:
|
|
226
|
+
- PENDING
|
|
227
|
+
- IN_PROGRESS
|
|
228
|
+
- COMPLETED
|
|
229
|
+
- CANCELLED
|
|
230
|
+
description: Lifecycle status of a Stocktake session (GH#29 §3, §4).
|
|
187
231
|
TicketStatus:
|
|
188
232
|
type: string
|
|
189
233
|
enum:
|
|
@@ -281,6 +325,260 @@ components:
|
|
|
281
325
|
description: Write payload for partial update (PATCH) of a AllowedUser document.
|
|
282
326
|
All fields optional. Fields marked `readOnly` or `x-immutable` must not be
|
|
283
327
|
sent.
|
|
328
|
+
AnalyticsBackfill:
|
|
329
|
+
type: object
|
|
330
|
+
properties:
|
|
331
|
+
id:
|
|
332
|
+
readOnly: true
|
|
333
|
+
description: (Read-only) Firestore document ID, auto-generated.
|
|
334
|
+
type:
|
|
335
|
+
- string
|
|
336
|
+
- 'null'
|
|
337
|
+
companyId:
|
|
338
|
+
type: string
|
|
339
|
+
x-immutable: true
|
|
340
|
+
description: (Immutable) FK → Company document ID.
|
|
341
|
+
siteId:
|
|
342
|
+
type: string
|
|
343
|
+
x-immutable: true
|
|
344
|
+
description: (Immutable) FK → Site document ID (D40).
|
|
345
|
+
status:
|
|
346
|
+
type: string
|
|
347
|
+
enum:
|
|
348
|
+
- pending
|
|
349
|
+
- running
|
|
350
|
+
- completed
|
|
351
|
+
- failed
|
|
352
|
+
- cancelled
|
|
353
|
+
description: Run status.
|
|
354
|
+
from:
|
|
355
|
+
type: string
|
|
356
|
+
x-immutable: true
|
|
357
|
+
description: (Immutable) Inclusive start date (`YYYY-MM-DD`, UTC).
|
|
358
|
+
to:
|
|
359
|
+
type: string
|
|
360
|
+
x-immutable: true
|
|
361
|
+
description: (Immutable) Inclusive end date (`YYYY-MM-DD`, UTC).
|
|
362
|
+
dryRun:
|
|
363
|
+
type: boolean
|
|
364
|
+
x-immutable: true
|
|
365
|
+
description: (Immutable) When true, rollup writes are skipped — only source
|
|
366
|
+
counts are returned for diffing.
|
|
367
|
+
processedDates:
|
|
368
|
+
type: array
|
|
369
|
+
items:
|
|
370
|
+
type: string
|
|
371
|
+
description: Ordered list of `YYYY-MM-DD` dates already processed by this
|
|
372
|
+
run.
|
|
373
|
+
errors:
|
|
374
|
+
type: array
|
|
375
|
+
items:
|
|
376
|
+
type: object
|
|
377
|
+
properties:
|
|
378
|
+
date:
|
|
379
|
+
type: string
|
|
380
|
+
description: '`YYYY-MM-DD` date that failed.'
|
|
381
|
+
message:
|
|
382
|
+
type: string
|
|
383
|
+
description: Error message captured at failure.
|
|
384
|
+
at:
|
|
385
|
+
$ref: '#/components/schemas/FirestoreTimestamp'
|
|
386
|
+
description: When the error occurred.
|
|
387
|
+
required:
|
|
388
|
+
- date
|
|
389
|
+
- message
|
|
390
|
+
- at
|
|
391
|
+
additionalProperties: false
|
|
392
|
+
description: Per-date errors collected during the run.
|
|
393
|
+
triggeredBy:
|
|
394
|
+
type: string
|
|
395
|
+
x-immutable: true
|
|
396
|
+
description: (Immutable) UID of the admin who triggered the backfill.
|
|
397
|
+
startedAt:
|
|
398
|
+
$ref: '#/components/schemas/FirestoreTimestamp'
|
|
399
|
+
description: (Read-only) When the run actually started.
|
|
400
|
+
readOnly: true
|
|
401
|
+
completedAt:
|
|
402
|
+
anyOf:
|
|
403
|
+
- $ref: '#/components/schemas/FirestoreTimestamp'
|
|
404
|
+
- type: 'null'
|
|
405
|
+
readOnly: true
|
|
406
|
+
description: (Read-only) When the run reached a terminal status.
|
|
407
|
+
required:
|
|
408
|
+
- companyId
|
|
409
|
+
- siteId
|
|
410
|
+
- status
|
|
411
|
+
- from
|
|
412
|
+
- to
|
|
413
|
+
- dryRun
|
|
414
|
+
- processedDates
|
|
415
|
+
- errors
|
|
416
|
+
- triggeredBy
|
|
417
|
+
- startedAt
|
|
418
|
+
additionalProperties: false
|
|
419
|
+
description: 'AnalyticsBackfill run (D42 / ING-304). Collection: companies/{companyId}/sites/{siteId}/analytics_backfills/{runId}.
|
|
420
|
+
Tracks admin-triggered rollup backfill jobs; supports dry-run.'
|
|
421
|
+
AnalyticsBackfillCreate:
|
|
422
|
+
allOf:
|
|
423
|
+
- $ref: '#/components/schemas/AnalyticsBackfill'
|
|
424
|
+
description: Write payload for creating a new AnalyticsBackfill document. Fields
|
|
425
|
+
marked `readOnly` are server-set and must not be included. Fields marked `x-immutable`
|
|
426
|
+
may be set once at creation.
|
|
427
|
+
required:
|
|
428
|
+
- companyId
|
|
429
|
+
- siteId
|
|
430
|
+
- status
|
|
431
|
+
- from
|
|
432
|
+
- to
|
|
433
|
+
- dryRun
|
|
434
|
+
- processedDates
|
|
435
|
+
- errors
|
|
436
|
+
- triggeredBy
|
|
437
|
+
AnalyticsBackfillUpdate:
|
|
438
|
+
allOf:
|
|
439
|
+
- $ref: '#/components/schemas/AnalyticsBackfill'
|
|
440
|
+
description: Write payload for partial update (PATCH) of a AnalyticsBackfill
|
|
441
|
+
document. All fields optional. Fields marked `readOnly` or `x-immutable` must
|
|
442
|
+
not be sent.
|
|
443
|
+
AnalyticsDaily:
|
|
444
|
+
type: object
|
|
445
|
+
properties:
|
|
446
|
+
totalEvents:
|
|
447
|
+
type: integer
|
|
448
|
+
minimum: -9007199254740991
|
|
449
|
+
maximum: 9007199254740991
|
|
450
|
+
description: Total event count within the bucket.
|
|
451
|
+
pageViews:
|
|
452
|
+
type: integer
|
|
453
|
+
minimum: -9007199254740991
|
|
454
|
+
maximum: 9007199254740991
|
|
455
|
+
description: Count of `page_view` + `screen_view` events.
|
|
456
|
+
sessions:
|
|
457
|
+
type: integer
|
|
458
|
+
minimum: -9007199254740991
|
|
459
|
+
maximum: 9007199254740991
|
|
460
|
+
description: Distinct session count within the bucket (by `sessionId`).
|
|
461
|
+
uniqueUsers:
|
|
462
|
+
type: integer
|
|
463
|
+
minimum: -9007199254740991
|
|
464
|
+
maximum: 9007199254740991
|
|
465
|
+
description: Distinct identified `userId` count. Anonymous sessions (userId=null)
|
|
466
|
+
are excluded.
|
|
467
|
+
anonymousSessions:
|
|
468
|
+
type: integer
|
|
469
|
+
minimum: -9007199254740991
|
|
470
|
+
maximum: 9007199254740991
|
|
471
|
+
description: Distinct session count where `userId` was null for the entire
|
|
472
|
+
session.
|
|
473
|
+
orders:
|
|
474
|
+
type: integer
|
|
475
|
+
minimum: -9007199254740991
|
|
476
|
+
maximum: 9007199254740991
|
|
477
|
+
description: Count of `order_submitted` events (or Order documents scoped
|
|
478
|
+
to this site, D43) within the bucket.
|
|
479
|
+
paymentsCompleted:
|
|
480
|
+
type: integer
|
|
481
|
+
minimum: -9007199254740991
|
|
482
|
+
maximum: 9007199254740991
|
|
483
|
+
description: Count of `payment_completed` events within the bucket.
|
|
484
|
+
paymentsFailed:
|
|
485
|
+
type: integer
|
|
486
|
+
minimum: -9007199254740991
|
|
487
|
+
maximum: 9007199254740991
|
|
488
|
+
description: Count of `payment_failed` events within the bucket.
|
|
489
|
+
errors:
|
|
490
|
+
type: integer
|
|
491
|
+
minimum: -9007199254740991
|
|
492
|
+
maximum: 9007199254740991
|
|
493
|
+
description: Count of `error_occurred` + `exception_caught` events within
|
|
494
|
+
the bucket.
|
|
495
|
+
eventCounts:
|
|
496
|
+
type: object
|
|
497
|
+
propertyNames:
|
|
498
|
+
type: string
|
|
499
|
+
additionalProperties:
|
|
500
|
+
type: integer
|
|
501
|
+
minimum: -9007199254740991
|
|
502
|
+
maximum: 9007199254740991
|
|
503
|
+
description: Per-event-name counts — key is the event name (canonical or
|
|
504
|
+
custom), value is the count within the bucket.
|
|
505
|
+
id:
|
|
506
|
+
readOnly: true
|
|
507
|
+
description: (Read-only) Firestore document ID = `YYYY-MM-DD`.
|
|
508
|
+
type:
|
|
509
|
+
- string
|
|
510
|
+
- 'null'
|
|
511
|
+
companyId:
|
|
512
|
+
type: string
|
|
513
|
+
x-immutable: true
|
|
514
|
+
description: (Immutable) FK → Company document ID.
|
|
515
|
+
siteId:
|
|
516
|
+
type: string
|
|
517
|
+
x-immutable: true
|
|
518
|
+
description: (Immutable) FK → Site document ID (D40).
|
|
519
|
+
date:
|
|
520
|
+
type: string
|
|
521
|
+
x-immutable: true
|
|
522
|
+
description: (Immutable) `YYYY-MM-DD` UTC — matches document ID.
|
|
523
|
+
computedAt:
|
|
524
|
+
$ref: '#/components/schemas/FirestoreTimestamp'
|
|
525
|
+
description: (Read-only) When this rollup was last (re)computed. Updated
|
|
526
|
+
on every set/merge.
|
|
527
|
+
readOnly: true
|
|
528
|
+
sourceEventCount:
|
|
529
|
+
readOnly: true
|
|
530
|
+
description: (Read-only, Optional) Total source events scanned when producing
|
|
531
|
+
this rollup. Useful for dry-run diffing.
|
|
532
|
+
type:
|
|
533
|
+
- integer
|
|
534
|
+
- 'null'
|
|
535
|
+
minimum: -9007199254740991
|
|
536
|
+
maximum: 9007199254740991
|
|
537
|
+
required:
|
|
538
|
+
- totalEvents
|
|
539
|
+
- pageViews
|
|
540
|
+
- sessions
|
|
541
|
+
- uniqueUsers
|
|
542
|
+
- anonymousSessions
|
|
543
|
+
- orders
|
|
544
|
+
- paymentsCompleted
|
|
545
|
+
- paymentsFailed
|
|
546
|
+
- errors
|
|
547
|
+
- eventCounts
|
|
548
|
+
- companyId
|
|
549
|
+
- siteId
|
|
550
|
+
- date
|
|
551
|
+
- computedAt
|
|
552
|
+
additionalProperties: false
|
|
553
|
+
description: 'AnalyticsDaily rollup (D42 / ING-304). Collection: companies/{companyId}/sites/{siteId}/analytics_daily/{YYYY-MM-DD}.
|
|
554
|
+
Idempotent set/merge — reruns overwrite. Fall back to raw analytics_events
|
|
555
|
+
for uncovered slices.'
|
|
556
|
+
AnalyticsDailyCreate:
|
|
557
|
+
allOf:
|
|
558
|
+
- $ref: '#/components/schemas/AnalyticsDaily'
|
|
559
|
+
description: Write payload for creating a new AnalyticsDaily document. Fields
|
|
560
|
+
marked `readOnly` are server-set and must not be included. Fields marked `x-immutable`
|
|
561
|
+
may be set once at creation.
|
|
562
|
+
required:
|
|
563
|
+
- totalEvents
|
|
564
|
+
- pageViews
|
|
565
|
+
- sessions
|
|
566
|
+
- uniqueUsers
|
|
567
|
+
- anonymousSessions
|
|
568
|
+
- orders
|
|
569
|
+
- paymentsCompleted
|
|
570
|
+
- paymentsFailed
|
|
571
|
+
- errors
|
|
572
|
+
- eventCounts
|
|
573
|
+
- companyId
|
|
574
|
+
- siteId
|
|
575
|
+
- date
|
|
576
|
+
AnalyticsDailyUpdate:
|
|
577
|
+
allOf:
|
|
578
|
+
- $ref: '#/components/schemas/AnalyticsDaily'
|
|
579
|
+
description: Write payload for partial update (PATCH) of a AnalyticsDaily document.
|
|
580
|
+
All fields optional. Fields marked `readOnly` or `x-immutable` must not be
|
|
581
|
+
sent.
|
|
284
582
|
AnalyticsEvent:
|
|
285
583
|
type: object
|
|
286
584
|
properties:
|
|
@@ -448,6 +746,151 @@ components:
|
|
|
448
746
|
description: Write payload for partial update (PATCH) of a AnalyticsEvent document.
|
|
449
747
|
All fields optional. Fields marked `readOnly` or `x-immutable` must not be
|
|
450
748
|
sent.
|
|
749
|
+
AnalyticsHourly:
|
|
750
|
+
type: object
|
|
751
|
+
properties:
|
|
752
|
+
totalEvents:
|
|
753
|
+
type: integer
|
|
754
|
+
minimum: -9007199254740991
|
|
755
|
+
maximum: 9007199254740991
|
|
756
|
+
description: Total event count within the bucket.
|
|
757
|
+
pageViews:
|
|
758
|
+
type: integer
|
|
759
|
+
minimum: -9007199254740991
|
|
760
|
+
maximum: 9007199254740991
|
|
761
|
+
description: Count of `page_view` + `screen_view` events.
|
|
762
|
+
sessions:
|
|
763
|
+
type: integer
|
|
764
|
+
minimum: -9007199254740991
|
|
765
|
+
maximum: 9007199254740991
|
|
766
|
+
description: Distinct session count within the bucket (by `sessionId`).
|
|
767
|
+
uniqueUsers:
|
|
768
|
+
type: integer
|
|
769
|
+
minimum: -9007199254740991
|
|
770
|
+
maximum: 9007199254740991
|
|
771
|
+
description: Distinct identified `userId` count. Anonymous sessions (userId=null)
|
|
772
|
+
are excluded.
|
|
773
|
+
anonymousSessions:
|
|
774
|
+
type: integer
|
|
775
|
+
minimum: -9007199254740991
|
|
776
|
+
maximum: 9007199254740991
|
|
777
|
+
description: Distinct session count where `userId` was null for the entire
|
|
778
|
+
session.
|
|
779
|
+
orders:
|
|
780
|
+
type: integer
|
|
781
|
+
minimum: -9007199254740991
|
|
782
|
+
maximum: 9007199254740991
|
|
783
|
+
description: Count of `order_submitted` events (or Order documents scoped
|
|
784
|
+
to this site, D43) within the bucket.
|
|
785
|
+
paymentsCompleted:
|
|
786
|
+
type: integer
|
|
787
|
+
minimum: -9007199254740991
|
|
788
|
+
maximum: 9007199254740991
|
|
789
|
+
description: Count of `payment_completed` events within the bucket.
|
|
790
|
+
paymentsFailed:
|
|
791
|
+
type: integer
|
|
792
|
+
minimum: -9007199254740991
|
|
793
|
+
maximum: 9007199254740991
|
|
794
|
+
description: Count of `payment_failed` events within the bucket.
|
|
795
|
+
errors:
|
|
796
|
+
type: integer
|
|
797
|
+
minimum: -9007199254740991
|
|
798
|
+
maximum: 9007199254740991
|
|
799
|
+
description: Count of `error_occurred` + `exception_caught` events within
|
|
800
|
+
the bucket.
|
|
801
|
+
eventCounts:
|
|
802
|
+
type: object
|
|
803
|
+
propertyNames:
|
|
804
|
+
type: string
|
|
805
|
+
additionalProperties:
|
|
806
|
+
type: integer
|
|
807
|
+
minimum: -9007199254740991
|
|
808
|
+
maximum: 9007199254740991
|
|
809
|
+
description: Per-event-name counts — key is the event name (canonical or
|
|
810
|
+
custom), value is the count within the bucket.
|
|
811
|
+
id:
|
|
812
|
+
readOnly: true
|
|
813
|
+
description: (Read-only) Firestore document ID = `YYYY-MM-DD-HH`.
|
|
814
|
+
type:
|
|
815
|
+
- string
|
|
816
|
+
- 'null'
|
|
817
|
+
companyId:
|
|
818
|
+
type: string
|
|
819
|
+
x-immutable: true
|
|
820
|
+
description: (Immutable) FK → Company document ID.
|
|
821
|
+
siteId:
|
|
822
|
+
type: string
|
|
823
|
+
x-immutable: true
|
|
824
|
+
description: (Immutable) FK → Site document ID (D40).
|
|
825
|
+
date:
|
|
826
|
+
type: string
|
|
827
|
+
x-immutable: true
|
|
828
|
+
description: (Immutable) `YYYY-MM-DD` UTC for the bucket day.
|
|
829
|
+
hour:
|
|
830
|
+
type: integer
|
|
831
|
+
minimum: -9007199254740991
|
|
832
|
+
maximum: 9007199254740991
|
|
833
|
+
x-immutable: true
|
|
834
|
+
description: (Immutable) UTC hour of day, 0–23.
|
|
835
|
+
computedAt:
|
|
836
|
+
$ref: '#/components/schemas/FirestoreTimestamp'
|
|
837
|
+
description: (Read-only) When this rollup was last (re)computed.
|
|
838
|
+
readOnly: true
|
|
839
|
+
sourceEventCount:
|
|
840
|
+
readOnly: true
|
|
841
|
+
description: (Read-only, Optional) Total source events scanned when producing
|
|
842
|
+
this rollup.
|
|
843
|
+
type:
|
|
844
|
+
- integer
|
|
845
|
+
- 'null'
|
|
846
|
+
minimum: -9007199254740991
|
|
847
|
+
maximum: 9007199254740991
|
|
848
|
+
required:
|
|
849
|
+
- totalEvents
|
|
850
|
+
- pageViews
|
|
851
|
+
- sessions
|
|
852
|
+
- uniqueUsers
|
|
853
|
+
- anonymousSessions
|
|
854
|
+
- orders
|
|
855
|
+
- paymentsCompleted
|
|
856
|
+
- paymentsFailed
|
|
857
|
+
- errors
|
|
858
|
+
- eventCounts
|
|
859
|
+
- companyId
|
|
860
|
+
- siteId
|
|
861
|
+
- date
|
|
862
|
+
- hour
|
|
863
|
+
- computedAt
|
|
864
|
+
additionalProperties: false
|
|
865
|
+
description: 'AnalyticsHourly rollup (D42 / ING-304). Collection: companies/{companyId}/sites/{siteId}/analytics_hourly/{YYYY-MM-DD-HH}.
|
|
866
|
+
Scheduled-CF writer; idempotent set/merge.'
|
|
867
|
+
AnalyticsHourlyCreate:
|
|
868
|
+
allOf:
|
|
869
|
+
- $ref: '#/components/schemas/AnalyticsHourly'
|
|
870
|
+
description: Write payload for creating a new AnalyticsHourly document. Fields
|
|
871
|
+
marked `readOnly` are server-set and must not be included. Fields marked `x-immutable`
|
|
872
|
+
may be set once at creation.
|
|
873
|
+
required:
|
|
874
|
+
- totalEvents
|
|
875
|
+
- pageViews
|
|
876
|
+
- sessions
|
|
877
|
+
- uniqueUsers
|
|
878
|
+
- anonymousSessions
|
|
879
|
+
- orders
|
|
880
|
+
- paymentsCompleted
|
|
881
|
+
- paymentsFailed
|
|
882
|
+
- errors
|
|
883
|
+
- eventCounts
|
|
884
|
+
- companyId
|
|
885
|
+
- siteId
|
|
886
|
+
- date
|
|
887
|
+
- hour
|
|
888
|
+
AnalyticsHourlyUpdate:
|
|
889
|
+
allOf:
|
|
890
|
+
- $ref: '#/components/schemas/AnalyticsHourly'
|
|
891
|
+
description: Write payload for partial update (PATCH) of a AnalyticsHourly document.
|
|
892
|
+
All fields optional. Fields marked `readOnly` or `x-immutable` must not be
|
|
893
|
+
sent.
|
|
451
894
|
Booking:
|
|
452
895
|
type: object
|
|
453
896
|
properties:
|
|
@@ -2579,6 +3022,23 @@ components:
|
|
|
2579
3022
|
type: string
|
|
2580
3023
|
x-immutable: true
|
|
2581
3024
|
description: (Immutable) FK → Company document ID. Scopes all queries.
|
|
3025
|
+
siteId:
|
|
3026
|
+
x-immutable: true
|
|
3027
|
+
x-note: 'D43 / ADR-003: optional site attribution. Absent/null means company-wide
|
|
3028
|
+
(legacy). When set, the order is attributed to a specific site for analytics
|
|
3029
|
+
and site-scoped dashboards. No migration — existing orders keep null.
|
|
3030
|
+
Flat path; Order continues to live at `companies/{companyId}/orders/{orderId}`.'
|
|
3031
|
+
x-see:
|
|
3032
|
+
decisions:
|
|
3033
|
+
- D43
|
|
3034
|
+
x-when: 'Set at order creation when the client knows which site the order
|
|
3035
|
+
originated from (e.g. SR Single, Lifesense). Leave null for legacy/company-wide
|
|
3036
|
+
orders. Composite index: (companyId, siteId, createdAt).'
|
|
3037
|
+
description: (Immutable, Optional) FK → Site document ID (D43 / ADR-003).
|
|
3038
|
+
null = company-wide.
|
|
3039
|
+
type:
|
|
3040
|
+
- string
|
|
3041
|
+
- 'null'
|
|
2582
3042
|
orderNumber:
|
|
2583
3043
|
type: string
|
|
2584
3044
|
readOnly: true
|
|
@@ -3201,6 +3661,187 @@ components:
|
|
|
3201
3661
|
- $ref: '#/components/schemas/Sale'
|
|
3202
3662
|
description: Write payload for partial update (PATCH) of a Sale document. All
|
|
3203
3663
|
fields optional. Fields marked `readOnly` or `x-immutable` must not be sent.
|
|
3664
|
+
Site:
|
|
3665
|
+
type: object
|
|
3666
|
+
properties:
|
|
3667
|
+
id:
|
|
3668
|
+
readOnly: true
|
|
3669
|
+
description: (Read-only) Firestore document ID, auto-generated.
|
|
3670
|
+
type:
|
|
3671
|
+
- string
|
|
3672
|
+
- 'null'
|
|
3673
|
+
companyId:
|
|
3674
|
+
type: string
|
|
3675
|
+
x-immutable: true
|
|
3676
|
+
description: (Immutable) FK → Company document ID. Scopes all site sub-collections.
|
|
3677
|
+
name:
|
|
3678
|
+
type: string
|
|
3679
|
+
description: Human-readable site name shown in dashboards.
|
|
3680
|
+
description:
|
|
3681
|
+
description: Optional freeform description.
|
|
3682
|
+
type:
|
|
3683
|
+
- string
|
|
3684
|
+
- 'null'
|
|
3685
|
+
status:
|
|
3686
|
+
$ref: '#/components/schemas/SiteStatus'
|
|
3687
|
+
description: Lifecycle status (D41). Clients filter by ACTIVE.
|
|
3688
|
+
x-note: ACTIVE = live and serving traffic. INACTIVE = intentionally disabled
|
|
3689
|
+
by operators. EXPIRED = past expiresAt (derived when isExpired is true;
|
|
3690
|
+
may also be stored explicitly). ARCHIVED = soft-deleted; retained for
|
|
3691
|
+
audit but not listed by default.
|
|
3692
|
+
x-see:
|
|
3693
|
+
decisions:
|
|
3694
|
+
- D41
|
|
3695
|
+
x-when: Written by operators via dashboard or by server triggers (expiration).
|
|
3696
|
+
Clients filter by ACTIVE.
|
|
3697
|
+
deploymentLinks:
|
|
3698
|
+
type: array
|
|
3699
|
+
items:
|
|
3700
|
+
type: object
|
|
3701
|
+
properties:
|
|
3702
|
+
label:
|
|
3703
|
+
type: string
|
|
3704
|
+
description: Human-readable label shown in dashboards (e.g. "Production",
|
|
3705
|
+
"Staging").
|
|
3706
|
+
url:
|
|
3707
|
+
type: string
|
|
3708
|
+
description: Absolute URL or store link.
|
|
3709
|
+
type:
|
|
3710
|
+
$ref: '#/components/schemas/DeploymentLinkType'
|
|
3711
|
+
description: Link category — drives icon/handler selection.
|
|
3712
|
+
x-note: Lowercase by convention — deployment link types are display-oriented
|
|
3713
|
+
labels, not lifecycle states.
|
|
3714
|
+
x-see:
|
|
3715
|
+
decisions:
|
|
3716
|
+
- D41
|
|
3717
|
+
isPrimary:
|
|
3718
|
+
description: If true, this link is used as the canonical deployment
|
|
3719
|
+
URL for the Site.
|
|
3720
|
+
type: boolean
|
|
3721
|
+
required:
|
|
3722
|
+
- label
|
|
3723
|
+
- url
|
|
3724
|
+
- type
|
|
3725
|
+
additionalProperties: false
|
|
3726
|
+
description: Deployment link entry embedded on Site.deploymentLinks[]
|
|
3727
|
+
(D41).
|
|
3728
|
+
description: Ordered list of deployment URLs (web, mobile, PWA, store links).
|
|
3729
|
+
expiresAt:
|
|
3730
|
+
anyOf:
|
|
3731
|
+
- $ref: '#/components/schemas/FirestoreTimestamp'
|
|
3732
|
+
- type: 'null'
|
|
3733
|
+
description: Optional expiration timestamp. When set and elapsed, `isExpired`
|
|
3734
|
+
flips true and status typically moves to EXPIRED.
|
|
3735
|
+
isExpired:
|
|
3736
|
+
readOnly: true
|
|
3737
|
+
description: (Read-only) Derived — true when `expiresAt` is in the past.
|
|
3738
|
+
Maintained by server trigger.
|
|
3739
|
+
type:
|
|
3740
|
+
- boolean
|
|
3741
|
+
- 'null'
|
|
3742
|
+
createdAt:
|
|
3743
|
+
anyOf:
|
|
3744
|
+
- $ref: '#/components/schemas/FirestoreTimestamp'
|
|
3745
|
+
- type: 'null'
|
|
3746
|
+
readOnly: true
|
|
3747
|
+
description: (Read-only) Server-generated creation timestamp.
|
|
3748
|
+
updatedAt:
|
|
3749
|
+
anyOf:
|
|
3750
|
+
- $ref: '#/components/schemas/FirestoreTimestamp'
|
|
3751
|
+
- type: 'null'
|
|
3752
|
+
readOnly: true
|
|
3753
|
+
description: (Read-only) Server-generated update timestamp.
|
|
3754
|
+
createdBy:
|
|
3755
|
+
type: string
|
|
3756
|
+
x-immutable: true
|
|
3757
|
+
description: (Immutable) FK → User/staff UID who created the site.
|
|
3758
|
+
analyticsEnabled:
|
|
3759
|
+
type: boolean
|
|
3760
|
+
description: Feature flag — when false, clients should not emit analytics
|
|
3761
|
+
events for this site.
|
|
3762
|
+
lastAnalyticsSync:
|
|
3763
|
+
anyOf:
|
|
3764
|
+
- $ref: '#/components/schemas/FirestoreTimestamp'
|
|
3765
|
+
- type: 'null'
|
|
3766
|
+
readOnly: true
|
|
3767
|
+
description: (Read-only) Last time the analytics rollup pipeline refreshed
|
|
3768
|
+
`cachedMetrics`.
|
|
3769
|
+
cachedMetrics:
|
|
3770
|
+
readOnly: true
|
|
3771
|
+
denormalized: true
|
|
3772
|
+
x-note: Updated by the rollup pipeline (D42). Readers should treat this
|
|
3773
|
+
as a hint; authoritative counts live in analytics_daily/analytics_hourly.
|
|
3774
|
+
x-see:
|
|
3775
|
+
decisions:
|
|
3776
|
+
- D41
|
|
3777
|
+
- D42
|
|
3778
|
+
description: (Read-only, Denormalized) Cached metrics snapshot for quick
|
|
3779
|
+
dashboard rendering.
|
|
3780
|
+
type:
|
|
3781
|
+
- object
|
|
3782
|
+
- 'null'
|
|
3783
|
+
properties:
|
|
3784
|
+
totalEvents:
|
|
3785
|
+
type: integer
|
|
3786
|
+
minimum: -9007199254740991
|
|
3787
|
+
maximum: 9007199254740991
|
|
3788
|
+
description: All-time event count cached on the Site.
|
|
3789
|
+
totalPageViews:
|
|
3790
|
+
type: integer
|
|
3791
|
+
minimum: -9007199254740991
|
|
3792
|
+
maximum: 9007199254740991
|
|
3793
|
+
description: All-time `page_view` + `screen_view` count.
|
|
3794
|
+
totalSessions:
|
|
3795
|
+
type: integer
|
|
3796
|
+
minimum: -9007199254740991
|
|
3797
|
+
maximum: 9007199254740991
|
|
3798
|
+
description: All-time distinct session count.
|
|
3799
|
+
totalOrders:
|
|
3800
|
+
type: integer
|
|
3801
|
+
minimum: -9007199254740991
|
|
3802
|
+
maximum: 9007199254740991
|
|
3803
|
+
description: All-time order count attributed to this site (via `Order.siteId`,
|
|
3804
|
+
D43).
|
|
3805
|
+
lastEventAt:
|
|
3806
|
+
$ref: '#/components/schemas/FirestoreTimestamp'
|
|
3807
|
+
description: Timestamp of the most recent analytics event seen for this
|
|
3808
|
+
site.
|
|
3809
|
+
required:
|
|
3810
|
+
- totalEvents
|
|
3811
|
+
- totalPageViews
|
|
3812
|
+
- totalSessions
|
|
3813
|
+
- totalOrders
|
|
3814
|
+
additionalProperties: false
|
|
3815
|
+
required:
|
|
3816
|
+
- companyId
|
|
3817
|
+
- name
|
|
3818
|
+
- status
|
|
3819
|
+
- deploymentLinks
|
|
3820
|
+
- createdBy
|
|
3821
|
+
- analyticsEnabled
|
|
3822
|
+
additionalProperties: false
|
|
3823
|
+
description: 'Site model (D41 / ING-304). Collection: companies/{companyId}/sites/{siteId}.
|
|
3824
|
+
Per-company product surface. Sub-collections (magic_link_requests, allowed_users,
|
|
3825
|
+
payments, analytics_events, analytics_daily, analytics_hourly, analytics_backfills)
|
|
3826
|
+
live under this document per D40/D42.'
|
|
3827
|
+
SiteCreate:
|
|
3828
|
+
allOf:
|
|
3829
|
+
- $ref: '#/components/schemas/Site'
|
|
3830
|
+
description: Write payload for creating a new Site document. Fields marked `readOnly`
|
|
3831
|
+
are server-set and must not be included. Fields marked `x-immutable` may be
|
|
3832
|
+
set once at creation.
|
|
3833
|
+
required:
|
|
3834
|
+
- companyId
|
|
3835
|
+
- name
|
|
3836
|
+
- status
|
|
3837
|
+
- deploymentLinks
|
|
3838
|
+
- createdBy
|
|
3839
|
+
- analyticsEnabled
|
|
3840
|
+
SiteUpdate:
|
|
3841
|
+
allOf:
|
|
3842
|
+
- $ref: '#/components/schemas/Site'
|
|
3843
|
+
description: Write payload for partial update (PATCH) of a Site document. All
|
|
3844
|
+
fields optional. Fields marked `readOnly` or `x-immutable` must not be sent.
|
|
3204
3845
|
SitePayment:
|
|
3205
3846
|
type: object
|
|
3206
3847
|
properties:
|
|
@@ -3278,6 +3919,337 @@ components:
|
|
|
3278
3919
|
description: Write payload for partial update (PATCH) of a SitePayment document.
|
|
3279
3920
|
All fields optional. Fields marked `readOnly` or `x-immutable` must not be
|
|
3280
3921
|
sent.
|
|
3922
|
+
Stocktake:
|
|
3923
|
+
type: object
|
|
3924
|
+
properties:
|
|
3925
|
+
id:
|
|
3926
|
+
readOnly: true
|
|
3927
|
+
description: (Read-only) Firestore document ID, auto-generated.
|
|
3928
|
+
type:
|
|
3929
|
+
- string
|
|
3930
|
+
- 'null'
|
|
3931
|
+
companyId:
|
|
3932
|
+
type: string
|
|
3933
|
+
x-immutable: true
|
|
3934
|
+
description: (Immutable) FK → Company document ID. Tenant scope.
|
|
3935
|
+
stocktakeNumber:
|
|
3936
|
+
type: string
|
|
3937
|
+
description: Human-readable session number, e.g. "STK-2026-001". Embedded
|
|
3938
|
+
as `referenceNumber` on the StockMovement rows the session emits, so the
|
|
3939
|
+
ledger remains traceable to the originating stocktake.
|
|
3940
|
+
stocktakeDate:
|
|
3941
|
+
$ref: '#/components/schemas/FirestoreTimestamp'
|
|
3942
|
+
description: Effective date of the count. Distinct from createdAt; can be
|
|
3943
|
+
backdated.
|
|
3944
|
+
x-note: The date the count is FOR. Can be backdated (stocktakeDate < createdAt)
|
|
3945
|
+
— analytics buckets by stocktakeDate for "what period was counted" and
|
|
3946
|
+
by completedAt for "when adjustments hit the ledger" (GH#29 Q24).
|
|
3947
|
+
warehouseId:
|
|
3948
|
+
description: FK → Warehouse document ID. Null = whole-company stocktake
|
|
3949
|
+
(no warehouse partition).
|
|
3950
|
+
anyOf:
|
|
3951
|
+
- type: string
|
|
3952
|
+
- type: 'null'
|
|
3953
|
+
frequency:
|
|
3954
|
+
anyOf:
|
|
3955
|
+
- $ref: '#/components/schemas/StocktakeFrequency'
|
|
3956
|
+
- type: 'null'
|
|
3957
|
+
description: Recurrence cadence. Optional — leave unset for ad-hoc sessions,
|
|
3958
|
+
or set to indicate this stocktake is part of a recurring schedule.
|
|
3959
|
+
x-note: Optional today (dashboard does not currently track recurrence).
|
|
3960
|
+
Frequency is a property of the record, not a separate type — a daily stocktake
|
|
3961
|
+
is a Stocktake with frequency=DAILY, not a distinct DailyStocktake model.
|
|
3962
|
+
If the session was emitted from a recurring schedule, set Stocktake.scheduledStocktakeId;
|
|
3963
|
+
ad-hoc sessions leave it null.
|
|
3964
|
+
x-see:
|
|
3965
|
+
issues:
|
|
3966
|
+
- gh#29
|
|
3967
|
+
scheduledStocktakeId:
|
|
3968
|
+
description: FK to a recurring stocktake schedule, if this session was emitted
|
|
3969
|
+
from one. Null for ad-hoc sessions.
|
|
3970
|
+
anyOf:
|
|
3971
|
+
- type: string
|
|
3972
|
+
- type: 'null'
|
|
3973
|
+
status:
|
|
3974
|
+
$ref: '#/components/schemas/StocktakeStatus'
|
|
3975
|
+
description: Lifecycle status. Transitions PENDING → IN_PROGRESS → COMPLETED
|
|
3976
|
+
are server-owned (GH#29 §3 / Q25).
|
|
3977
|
+
x-note: PENDING = session created, no items counted yet. IN_PROGRESS = at
|
|
3978
|
+
least one item has been counted. COMPLETED = all items counted and the
|
|
3979
|
+
session was closed; on this transition the server emits one StockMovement(type=INVENTORY)
|
|
3980
|
+
per non-zero delta. CANCELLED = session abandoned without applying adjustments.
|
|
3981
|
+
Status transitions PENDING → IN_PROGRESS → COMPLETED are server-owned
|
|
3982
|
+
(Q25) — clients PATCH item status; the server transitions session status
|
|
3983
|
+
to avoid the concurrent-edit race documented in stockService.ts:1671.
|
|
3984
|
+
x-see:
|
|
3985
|
+
issues:
|
|
3986
|
+
- gh#29
|
|
3987
|
+
x-when: Server-managed. Clients write item updates; the trigger transitions
|
|
3988
|
+
session status.
|
|
3989
|
+
adjustmentsApplied:
|
|
3990
|
+
type: boolean
|
|
3991
|
+
x-note: Records whether the COMPLETED transition actually mutated stock
|
|
3992
|
+
or was record-only. The dashboard's completeInventory(applyAdjustments)
|
|
3993
|
+
flag was not persisted; this field closes that gap (GH#29 audit Q22).
|
|
3994
|
+
description: True if completing the session actually emitted StockMovement
|
|
3995
|
+
adjustments. False for record-only counts.
|
|
3996
|
+
notes:
|
|
3997
|
+
description: Free-text session-level notes.
|
|
3998
|
+
anyOf:
|
|
3999
|
+
- type: string
|
|
4000
|
+
- type: 'null'
|
|
4001
|
+
totalItemsCount:
|
|
4002
|
+
type: integer
|
|
4003
|
+
minimum: -9007199254740991
|
|
4004
|
+
maximum: 9007199254740991
|
|
4005
|
+
readOnly: true
|
|
4006
|
+
x-note: Server-derived. Recomputed by trigger on each StocktakeItem write;
|
|
4007
|
+
not safe to write client-side under concurrent edits (GH#29 audit Q23).
|
|
4008
|
+
description: (Read-only) Total number of StocktakeItem rows under this session.
|
|
4009
|
+
totalDiscrepancies:
|
|
4010
|
+
type: integer
|
|
4011
|
+
minimum: -9007199254740991
|
|
4012
|
+
maximum: 9007199254740991
|
|
4013
|
+
readOnly: true
|
|
4014
|
+
x-note: Server-derived = sum of |item.delta| across COUNTED items. Updated
|
|
4015
|
+
by trigger.
|
|
4016
|
+
description: (Read-only) Sum of absolute deltas across counted items.
|
|
4017
|
+
totalDeltaValue:
|
|
4018
|
+
type: number
|
|
4019
|
+
readOnly: true
|
|
4020
|
+
x-note: Server-derived = sum of (item.delta × item.costPerUnit) across COUNTED
|
|
4021
|
+
items, in XOF integer minor units (D18). Updated by trigger.
|
|
4022
|
+
description: (Read-only) Net valuation impact of the count, in XOF integer
|
|
4023
|
+
minor units.
|
|
4024
|
+
startedAt:
|
|
4025
|
+
$ref: '#/components/schemas/FirestoreTimestamp'
|
|
4026
|
+
description: When the counting session physically opened. Typically equal
|
|
4027
|
+
to createdAt for ad-hoc sessions.
|
|
4028
|
+
completedAt:
|
|
4029
|
+
anyOf:
|
|
4030
|
+
- $ref: '#/components/schemas/FirestoreTimestamp'
|
|
4031
|
+
- type: 'null'
|
|
4032
|
+
readOnly: true
|
|
4033
|
+
x-note: Server-set on transition to COMPLETED. Distinct from stocktakeDate
|
|
4034
|
+
(the period counted) — analytics buckets by completedAt to answer "when
|
|
4035
|
+
did the ledger hit?".
|
|
4036
|
+
description: (Read-only) When the session transitioned to COMPLETED.
|
|
4037
|
+
createdAt:
|
|
4038
|
+
anyOf:
|
|
4039
|
+
- $ref: '#/components/schemas/FirestoreTimestamp'
|
|
4040
|
+
- type: 'null'
|
|
4041
|
+
readOnly: true
|
|
4042
|
+
description: (Read-only) Server-generated creation timestamp.
|
|
4043
|
+
createdBy:
|
|
4044
|
+
type: string
|
|
4045
|
+
x-immutable: true
|
|
4046
|
+
description: (Immutable) FK → User UID who created the session.
|
|
4047
|
+
createdByName:
|
|
4048
|
+
type: string
|
|
4049
|
+
denormalized: true
|
|
4050
|
+
x-note: Read-time hint snapshot of the creator's display name (GH#29 §3
|
|
4051
|
+
/ Q10).
|
|
4052
|
+
description: (Denormalized) Snapshot of the creator's display name at session
|
|
4053
|
+
creation.
|
|
4054
|
+
completedBy:
|
|
4055
|
+
readOnly: true
|
|
4056
|
+
description: (Read-only) FK → User UID who completed the session, set by
|
|
4057
|
+
server on COMPLETED.
|
|
4058
|
+
anyOf:
|
|
4059
|
+
- type: string
|
|
4060
|
+
- type: 'null'
|
|
4061
|
+
completedByName:
|
|
4062
|
+
denormalized: true
|
|
4063
|
+
x-note: Read-time hint snapshot of the completer's display name (GH#29 §3
|
|
4064
|
+
/ Q10).
|
|
4065
|
+
description: (Denormalized) Snapshot of the completer's display name.
|
|
4066
|
+
anyOf:
|
|
4067
|
+
- type: string
|
|
4068
|
+
- type: 'null'
|
|
4069
|
+
updatedAt:
|
|
4070
|
+
anyOf:
|
|
4071
|
+
- $ref: '#/components/schemas/FirestoreTimestamp'
|
|
4072
|
+
- type: 'null'
|
|
4073
|
+
readOnly: true
|
|
4074
|
+
description: (Read-only) Server-generated update timestamp.
|
|
4075
|
+
required:
|
|
4076
|
+
- companyId
|
|
4077
|
+
- stocktakeNumber
|
|
4078
|
+
- stocktakeDate
|
|
4079
|
+
- status
|
|
4080
|
+
- adjustmentsApplied
|
|
4081
|
+
- totalItemsCount
|
|
4082
|
+
- totalDiscrepancies
|
|
4083
|
+
- totalDeltaValue
|
|
4084
|
+
- startedAt
|
|
4085
|
+
- createdBy
|
|
4086
|
+
- createdByName
|
|
4087
|
+
additionalProperties: false
|
|
4088
|
+
description: 'Stocktake (GH#29 §4). Collection: companies/{companyId}/stocktakes/{stocktakeId}.
|
|
4089
|
+
A recorded session of physically counting all SKUs at a point in time. Replaces
|
|
4090
|
+
the dashboard''s Inventory model; items live in a sub-collection (replaces
|
|
4091
|
+
InventoryItem[] embedded array); InventoryEvolution is dropped — derivable
|
|
4092
|
+
from the sub-collection. Status transitions and aggregate fields (totalItemsCount/Discrepancies/totalDeltaValue)
|
|
4093
|
+
are server-owned per GH#29 §3.'
|
|
4094
|
+
StocktakeCreate:
|
|
4095
|
+
allOf:
|
|
4096
|
+
- $ref: '#/components/schemas/Stocktake'
|
|
4097
|
+
description: Write payload for creating a new Stocktake document. Fields marked
|
|
4098
|
+
`readOnly` are server-set and must not be included. Fields marked `x-immutable`
|
|
4099
|
+
may be set once at creation.
|
|
4100
|
+
required:
|
|
4101
|
+
- companyId
|
|
4102
|
+
- stocktakeNumber
|
|
4103
|
+
- stocktakeDate
|
|
4104
|
+
- status
|
|
4105
|
+
- adjustmentsApplied
|
|
4106
|
+
- startedAt
|
|
4107
|
+
- createdBy
|
|
4108
|
+
- createdByName
|
|
4109
|
+
StocktakeUpdate:
|
|
4110
|
+
allOf:
|
|
4111
|
+
- $ref: '#/components/schemas/Stocktake'
|
|
4112
|
+
description: Write payload for partial update (PATCH) of a Stocktake document.
|
|
4113
|
+
All fields optional. Fields marked `readOnly` or `x-immutable` must not be
|
|
4114
|
+
sent.
|
|
4115
|
+
StocktakeItem:
|
|
4116
|
+
type: object
|
|
4117
|
+
properties:
|
|
4118
|
+
stockItemId:
|
|
4119
|
+
type: string
|
|
4120
|
+
description: FK → StockItem document ID. Doubles as the item document ID.
|
|
4121
|
+
stockItemName:
|
|
4122
|
+
type: string
|
|
4123
|
+
denormalized: true
|
|
4124
|
+
x-note: Read-time hint snapshot of StockItem.name. Authoritative value lives
|
|
4125
|
+
at the StockItem record; do not refresh on rename — the historical name
|
|
4126
|
+
at session time is what the auditor wrote (GH#29 §3 / Q10).
|
|
4127
|
+
description: (Denormalized) Snapshot of StockItem.name at session time.
|
|
4128
|
+
theoreticalQuantity:
|
|
4129
|
+
type: number
|
|
4130
|
+
x-immutable: true
|
|
4131
|
+
description: (Immutable) System belief at session start, snapshotted when
|
|
4132
|
+
this item row was created.
|
|
4133
|
+
actualQuantity:
|
|
4134
|
+
description: Physical count entered by the counter. Null until counted;
|
|
4135
|
+
set when the line moves to status COUNTED.
|
|
4136
|
+
anyOf:
|
|
4137
|
+
- type: number
|
|
4138
|
+
- type: 'null'
|
|
4139
|
+
delta:
|
|
4140
|
+
type: number
|
|
4141
|
+
readOnly: true
|
|
4142
|
+
x-note: Server-derived = actualQuantity − theoreticalQuantity. Recomputed
|
|
4143
|
+
on every actualQuantity write; null/zero before counting.
|
|
4144
|
+
description: (Read-only) Signed difference between actual and theoretical.
|
|
4145
|
+
Drives the StockMovement(type=INVENTORY) emitted on session COMPLETED.
|
|
4146
|
+
unit:
|
|
4147
|
+
type: string
|
|
4148
|
+
x-immutable: true
|
|
4149
|
+
description: (Immutable) Snapshot of StockItem.unit at session start. Locks
|
|
4150
|
+
the unit against later catalog changes.
|
|
4151
|
+
costPerUnit:
|
|
4152
|
+
type: number
|
|
4153
|
+
x-immutable: true
|
|
4154
|
+
x-note: Snapshot at session time — locks valuation against future cost changes.
|
|
4155
|
+
Lock to XOF integer minor units per D18 (GH#29 Q16).
|
|
4156
|
+
description: (Immutable) Snapshot of StockItem.costPerUnit at session start,
|
|
4157
|
+
in XOF integer minor units.
|
|
4158
|
+
totalValue:
|
|
4159
|
+
type: number
|
|
4160
|
+
readOnly: true
|
|
4161
|
+
x-note: Server-derived = actualQuantity × costPerUnit. Recomputed when actualQuantity
|
|
4162
|
+
is written.
|
|
4163
|
+
description: (Read-only) Per-line valuation in XOF integer minor units.
|
|
4164
|
+
status:
|
|
4165
|
+
$ref: '#/components/schemas/StocktakeItemStatus'
|
|
4166
|
+
description: Per-line workflow status. Server transitions ADJUSTED on parent
|
|
4167
|
+
COMPLETED.
|
|
4168
|
+
x-note: PENDING = line not yet counted. COUNTED = a counter recorded actualQuantity.
|
|
4169
|
+
VERIFIED = a second pair of eyes signed off (verifiedBy fields populated;
|
|
4170
|
+
Q21 — kept nullable until tenants opt into stricter QA via policy). ADJUSTED
|
|
4171
|
+
= the resulting StockMovement was emitted (server-set on Stocktake.status
|
|
4172
|
+
→ COMPLETED).
|
|
4173
|
+
x-see:
|
|
4174
|
+
issues:
|
|
4175
|
+
- gh#29
|
|
4176
|
+
notes:
|
|
4177
|
+
description: Optional per-line note from the counter (e.g. "damaged carton,
|
|
4178
|
+
3 unsellable").
|
|
4179
|
+
anyOf:
|
|
4180
|
+
- type: string
|
|
4181
|
+
- type: 'null'
|
|
4182
|
+
countedBy:
|
|
4183
|
+
description: UID of the staff member who entered actualQuantity.
|
|
4184
|
+
anyOf:
|
|
4185
|
+
- type: string
|
|
4186
|
+
- type: 'null'
|
|
4187
|
+
countedByName:
|
|
4188
|
+
denormalized: true
|
|
4189
|
+
x-note: Read-time hint snapshot of the counter's display name (GH#29 §3
|
|
4190
|
+
/ Q10).
|
|
4191
|
+
description: (Denormalized) Snapshot of the counter's display name at count
|
|
4192
|
+
time.
|
|
4193
|
+
anyOf:
|
|
4194
|
+
- type: string
|
|
4195
|
+
- type: 'null'
|
|
4196
|
+
countedAt:
|
|
4197
|
+
anyOf:
|
|
4198
|
+
- $ref: '#/components/schemas/FirestoreTimestamp'
|
|
4199
|
+
- type: 'null'
|
|
4200
|
+
description: When the line was counted.
|
|
4201
|
+
verifiedBy:
|
|
4202
|
+
description: UID of a second staff member who verified the count. Nullable
|
|
4203
|
+
per GH#29 Q21.
|
|
4204
|
+
anyOf:
|
|
4205
|
+
- type: string
|
|
4206
|
+
- type: 'null'
|
|
4207
|
+
verifiedByName:
|
|
4208
|
+
denormalized: true
|
|
4209
|
+
x-note: Read-time hint snapshot of the verifier's display name (GH#29 §3
|
|
4210
|
+
/ Q10).
|
|
4211
|
+
description: (Denormalized) Snapshot of the verifier's display name.
|
|
4212
|
+
anyOf:
|
|
4213
|
+
- type: string
|
|
4214
|
+
- type: 'null'
|
|
4215
|
+
verifiedAt:
|
|
4216
|
+
anyOf:
|
|
4217
|
+
- $ref: '#/components/schemas/FirestoreTimestamp'
|
|
4218
|
+
- type: 'null'
|
|
4219
|
+
description: When the line was verified, if a second-eye flow was used.
|
|
4220
|
+
required:
|
|
4221
|
+
- stockItemId
|
|
4222
|
+
- stockItemName
|
|
4223
|
+
- theoreticalQuantity
|
|
4224
|
+
- delta
|
|
4225
|
+
- unit
|
|
4226
|
+
- costPerUnit
|
|
4227
|
+
- totalValue
|
|
4228
|
+
- status
|
|
4229
|
+
additionalProperties: false
|
|
4230
|
+
description: 'StocktakeItem (GH#29 §4). Sub-collection path: companies/{companyId}/stocktakes/{stocktakeId}/items/{stockItemId}.
|
|
4231
|
+
Replaces the embedded `InventoryItem[]` array on the dashboard model. Server
|
|
4232
|
+
emits one StockMovement(type=INVENTORY) per non-zero delta when the parent
|
|
4233
|
+
Stocktake transitions to COMPLETED.'
|
|
4234
|
+
StocktakeItemCreate:
|
|
4235
|
+
allOf:
|
|
4236
|
+
- $ref: '#/components/schemas/StocktakeItem'
|
|
4237
|
+
description: Write payload for creating a new StocktakeItem document. Fields
|
|
4238
|
+
marked `readOnly` are server-set and must not be included. Fields marked `x-immutable`
|
|
4239
|
+
may be set once at creation.
|
|
4240
|
+
required:
|
|
4241
|
+
- stockItemId
|
|
4242
|
+
- stockItemName
|
|
4243
|
+
- theoreticalQuantity
|
|
4244
|
+
- unit
|
|
4245
|
+
- costPerUnit
|
|
4246
|
+
- status
|
|
4247
|
+
StocktakeItemUpdate:
|
|
4248
|
+
allOf:
|
|
4249
|
+
- $ref: '#/components/schemas/StocktakeItem'
|
|
4250
|
+
description: Write payload for partial update (PATCH) of a StocktakeItem document.
|
|
4251
|
+
All fields optional. Fields marked `readOnly` or `x-immutable` must not be
|
|
4252
|
+
sent.
|
|
3281
4253
|
Ticket:
|
|
3282
4254
|
type: object
|
|
3283
4255
|
properties:
|