@ingenx-io/valets-schema-mcp-server 0.1.3 → 0.1.5
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 +56 -3
- package/data/docs/enums/attention-status.md +24 -0
- package/data/docs/enums/booking-status.md +2 -2
- package/data/docs/enums/customer-payment-status.md +2 -2
- package/data/docs/enums/customer-payment-target-type.md +2 -2
- package/data/docs/enums/delivery-type.md +2 -2
- 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 +31 -0
- 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/ticket-status.md +2 -2
- package/data/docs/index.md +15 -3
- package/data/docs/models/allowed-user.md +188 -0
- 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 +533 -0
- 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 +285 -0
- 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 +200 -0
- package/data/docs/models/site.md +561 -0
- package/data/docs/models/ticket.md +2 -2
- package/data/static/llms.txt +362 -2
- package/data/static/openapi.yaml +1068 -0
- package/data/static/schemas.json +1229 -44
- package/package.json +1 -1
package/data/static/openapi.yaml
CHANGED
|
@@ -20,6 +20,16 @@ info:
|
|
|
20
20
|
paths: {}
|
|
21
21
|
components:
|
|
22
22
|
schemas:
|
|
23
|
+
AttentionStatus:
|
|
24
|
+
type: string
|
|
25
|
+
enum:
|
|
26
|
+
- ACTIVE
|
|
27
|
+
- STALE
|
|
28
|
+
- ON_HOLD
|
|
29
|
+
- ESCALATED
|
|
30
|
+
description: Operational attention status for Order and Booking (D39). Controls
|
|
31
|
+
home-page queue assignment. Server-owned — set via triggers or callable fn
|
|
32
|
+
only.
|
|
23
33
|
BookingStatus:
|
|
24
34
|
type: string
|
|
25
35
|
enum:
|
|
@@ -59,6 +69,17 @@ components:
|
|
|
59
69
|
comes to the business (ON_SITE), collects their order themselves (PICK_UP),
|
|
60
70
|
or receives a physical delivery (DELIVERY). Drives whether fulfillmentStatus
|
|
61
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.
|
|
62
83
|
EventStatus:
|
|
63
84
|
type: string
|
|
64
85
|
enum:
|
|
@@ -135,6 +156,23 @@ components:
|
|
|
135
156
|
- PARTIALLY_REFUNDED
|
|
136
157
|
description: Payment lifecycle status (D01 amended). Used by Order, Sale/Purchase,
|
|
137
158
|
Booking.
|
|
159
|
+
PendingIssue:
|
|
160
|
+
type: string
|
|
161
|
+
enum:
|
|
162
|
+
- PAYMENT_PROOF_PENDING
|
|
163
|
+
- PAYMENT_PROOF_REJECTED
|
|
164
|
+
- AMOUNT_DISCREPANCY
|
|
165
|
+
- RETURN_UNRESOLVED
|
|
166
|
+
- OVERDUE_DELIVERY
|
|
167
|
+
- SESSION_OVERDUE
|
|
168
|
+
- PAYMENT_INCOMPLETE
|
|
169
|
+
- CANCELLATION_REQUESTED
|
|
170
|
+
- UNREFUNDED_CANCELLATION
|
|
171
|
+
- UPCOMING_UNPAID
|
|
172
|
+
- NO_SHOW_UNRESOLVED
|
|
173
|
+
description: Specific detected conditions on an Order or Booking requiring human
|
|
174
|
+
action (D39). Stored as an array — multiple issues can be active simultaneously.
|
|
175
|
+
Server-owned.
|
|
138
176
|
ReturnStatus:
|
|
139
177
|
type: string
|
|
140
178
|
enum:
|
|
@@ -157,6 +195,15 @@ components:
|
|
|
157
195
|
- CANCELLED
|
|
158
196
|
description: Per-date/per-slot booking session status (D19). Dashboard is sole
|
|
159
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.
|
|
160
207
|
TicketStatus:
|
|
161
208
|
type: string
|
|
162
209
|
enum:
|
|
@@ -180,6 +227,646 @@ components:
|
|
|
180
227
|
- _nanoseconds
|
|
181
228
|
additionalProperties: false
|
|
182
229
|
description: Firestore Timestamp serialized representation
|
|
230
|
+
AllowedUser:
|
|
231
|
+
type: object
|
|
232
|
+
properties:
|
|
233
|
+
id:
|
|
234
|
+
readOnly: true
|
|
235
|
+
description: (Read-only) Firestore document ID = contact identifier (email
|
|
236
|
+
or E.164 phone), URL-escaped.
|
|
237
|
+
type:
|
|
238
|
+
- string
|
|
239
|
+
- 'null'
|
|
240
|
+
companyId:
|
|
241
|
+
type: string
|
|
242
|
+
x-immutable: true
|
|
243
|
+
description: (Immutable) FK → Company document ID.
|
|
244
|
+
siteId:
|
|
245
|
+
type: string
|
|
246
|
+
x-immutable: true
|
|
247
|
+
description: (Immutable) FK → Site document ID (D40 sub-tenant scope).
|
|
248
|
+
contact:
|
|
249
|
+
type: string
|
|
250
|
+
description: Email or E.164 phone number. Canonical identifier for this
|
|
251
|
+
user within the site.
|
|
252
|
+
tier:
|
|
253
|
+
type: string
|
|
254
|
+
description: Access tier. Free string per site (ING-304 open question —
|
|
255
|
+
tier values are site-specific today).
|
|
256
|
+
amount:
|
|
257
|
+
type: number
|
|
258
|
+
description: Amount paid. Generalized from amount_xof per D40 decision.
|
|
259
|
+
currency:
|
|
260
|
+
default: XOF
|
|
261
|
+
description: Currency code (ISO 4217). Defaults to XOF for legacy SR-Single
|
|
262
|
+
parity.
|
|
263
|
+
type: string
|
|
264
|
+
transactionId:
|
|
265
|
+
type: string
|
|
266
|
+
description: Payment provider transaction ID (e.g. Wave).
|
|
267
|
+
paidAt:
|
|
268
|
+
$ref: '#/components/schemas/FirestoreTimestamp'
|
|
269
|
+
description: RFC3339Nano UTC when payment was completed.
|
|
270
|
+
required:
|
|
271
|
+
- companyId
|
|
272
|
+
- siteId
|
|
273
|
+
- contact
|
|
274
|
+
- tier
|
|
275
|
+
- amount
|
|
276
|
+
- currency
|
|
277
|
+
- transactionId
|
|
278
|
+
- paidAt
|
|
279
|
+
additionalProperties: false
|
|
280
|
+
description: 'AllowedUser model (D40 / ING-304). Collection: companies/{companyId}/sites/{siteId}/allowed_users/{contactId}.
|
|
281
|
+
Authoritative paid-access allowlist. Upsert semantics — tier upgrades overwrite.
|
|
282
|
+
Source of truth for access checks and referral code resolution.'
|
|
283
|
+
AllowedUserCreate:
|
|
284
|
+
allOf:
|
|
285
|
+
- $ref: '#/components/schemas/AllowedUser'
|
|
286
|
+
description: Write payload for creating a new AllowedUser document. Fields marked
|
|
287
|
+
`readOnly` are server-set and must not be included. Fields marked `x-immutable`
|
|
288
|
+
may be set once at creation.
|
|
289
|
+
required:
|
|
290
|
+
- companyId
|
|
291
|
+
- siteId
|
|
292
|
+
- contact
|
|
293
|
+
- tier
|
|
294
|
+
- amount
|
|
295
|
+
- currency
|
|
296
|
+
- transactionId
|
|
297
|
+
- paidAt
|
|
298
|
+
AllowedUserUpdate:
|
|
299
|
+
allOf:
|
|
300
|
+
- $ref: '#/components/schemas/AllowedUser'
|
|
301
|
+
description: Write payload for partial update (PATCH) of a AllowedUser document.
|
|
302
|
+
All fields optional. Fields marked `readOnly` or `x-immutable` must not be
|
|
303
|
+
sent.
|
|
304
|
+
AnalyticsBackfill:
|
|
305
|
+
type: object
|
|
306
|
+
properties:
|
|
307
|
+
id:
|
|
308
|
+
readOnly: true
|
|
309
|
+
description: (Read-only) Firestore document ID, auto-generated.
|
|
310
|
+
type:
|
|
311
|
+
- string
|
|
312
|
+
- 'null'
|
|
313
|
+
companyId:
|
|
314
|
+
type: string
|
|
315
|
+
x-immutable: true
|
|
316
|
+
description: (Immutable) FK → Company document ID.
|
|
317
|
+
siteId:
|
|
318
|
+
type: string
|
|
319
|
+
x-immutable: true
|
|
320
|
+
description: (Immutable) FK → Site document ID (D40).
|
|
321
|
+
status:
|
|
322
|
+
type: string
|
|
323
|
+
enum:
|
|
324
|
+
- pending
|
|
325
|
+
- running
|
|
326
|
+
- completed
|
|
327
|
+
- failed
|
|
328
|
+
- cancelled
|
|
329
|
+
description: Run status.
|
|
330
|
+
from:
|
|
331
|
+
type: string
|
|
332
|
+
x-immutable: true
|
|
333
|
+
description: (Immutable) Inclusive start date (`YYYY-MM-DD`, UTC).
|
|
334
|
+
to:
|
|
335
|
+
type: string
|
|
336
|
+
x-immutable: true
|
|
337
|
+
description: (Immutable) Inclusive end date (`YYYY-MM-DD`, UTC).
|
|
338
|
+
dryRun:
|
|
339
|
+
type: boolean
|
|
340
|
+
x-immutable: true
|
|
341
|
+
description: (Immutable) When true, rollup writes are skipped — only source
|
|
342
|
+
counts are returned for diffing.
|
|
343
|
+
processedDates:
|
|
344
|
+
type: array
|
|
345
|
+
items:
|
|
346
|
+
type: string
|
|
347
|
+
description: Ordered list of `YYYY-MM-DD` dates already processed by this
|
|
348
|
+
run.
|
|
349
|
+
errors:
|
|
350
|
+
type: array
|
|
351
|
+
items:
|
|
352
|
+
type: object
|
|
353
|
+
properties:
|
|
354
|
+
date:
|
|
355
|
+
type: string
|
|
356
|
+
description: '`YYYY-MM-DD` date that failed.'
|
|
357
|
+
message:
|
|
358
|
+
type: string
|
|
359
|
+
description: Error message captured at failure.
|
|
360
|
+
at:
|
|
361
|
+
$ref: '#/components/schemas/FirestoreTimestamp'
|
|
362
|
+
description: When the error occurred.
|
|
363
|
+
required:
|
|
364
|
+
- date
|
|
365
|
+
- message
|
|
366
|
+
- at
|
|
367
|
+
additionalProperties: false
|
|
368
|
+
description: Per-date errors collected during the run.
|
|
369
|
+
triggeredBy:
|
|
370
|
+
type: string
|
|
371
|
+
x-immutable: true
|
|
372
|
+
description: (Immutable) UID of the admin who triggered the backfill.
|
|
373
|
+
startedAt:
|
|
374
|
+
$ref: '#/components/schemas/FirestoreTimestamp'
|
|
375
|
+
description: (Read-only) When the run actually started.
|
|
376
|
+
readOnly: true
|
|
377
|
+
completedAt:
|
|
378
|
+
anyOf:
|
|
379
|
+
- $ref: '#/components/schemas/FirestoreTimestamp'
|
|
380
|
+
- type: 'null'
|
|
381
|
+
readOnly: true
|
|
382
|
+
description: (Read-only) When the run reached a terminal status.
|
|
383
|
+
required:
|
|
384
|
+
- companyId
|
|
385
|
+
- siteId
|
|
386
|
+
- status
|
|
387
|
+
- from
|
|
388
|
+
- to
|
|
389
|
+
- dryRun
|
|
390
|
+
- processedDates
|
|
391
|
+
- errors
|
|
392
|
+
- triggeredBy
|
|
393
|
+
- startedAt
|
|
394
|
+
additionalProperties: false
|
|
395
|
+
description: 'AnalyticsBackfill run (D42 / ING-304). Collection: companies/{companyId}/sites/{siteId}/analytics_backfills/{runId}.
|
|
396
|
+
Tracks admin-triggered rollup backfill jobs; supports dry-run.'
|
|
397
|
+
AnalyticsBackfillCreate:
|
|
398
|
+
allOf:
|
|
399
|
+
- $ref: '#/components/schemas/AnalyticsBackfill'
|
|
400
|
+
description: Write payload for creating a new AnalyticsBackfill document. Fields
|
|
401
|
+
marked `readOnly` are server-set and must not be included. Fields marked `x-immutable`
|
|
402
|
+
may be set once at creation.
|
|
403
|
+
required:
|
|
404
|
+
- companyId
|
|
405
|
+
- siteId
|
|
406
|
+
- status
|
|
407
|
+
- from
|
|
408
|
+
- to
|
|
409
|
+
- dryRun
|
|
410
|
+
- processedDates
|
|
411
|
+
- errors
|
|
412
|
+
- triggeredBy
|
|
413
|
+
AnalyticsBackfillUpdate:
|
|
414
|
+
allOf:
|
|
415
|
+
- $ref: '#/components/schemas/AnalyticsBackfill'
|
|
416
|
+
description: Write payload for partial update (PATCH) of a AnalyticsBackfill
|
|
417
|
+
document. All fields optional. Fields marked `readOnly` or `x-immutable` must
|
|
418
|
+
not be sent.
|
|
419
|
+
AnalyticsDaily:
|
|
420
|
+
type: object
|
|
421
|
+
properties:
|
|
422
|
+
totalEvents:
|
|
423
|
+
type: integer
|
|
424
|
+
minimum: -9007199254740991
|
|
425
|
+
maximum: 9007199254740991
|
|
426
|
+
description: Total event count within the bucket.
|
|
427
|
+
pageViews:
|
|
428
|
+
type: integer
|
|
429
|
+
minimum: -9007199254740991
|
|
430
|
+
maximum: 9007199254740991
|
|
431
|
+
description: Count of `page_view` + `screen_view` events.
|
|
432
|
+
sessions:
|
|
433
|
+
type: integer
|
|
434
|
+
minimum: -9007199254740991
|
|
435
|
+
maximum: 9007199254740991
|
|
436
|
+
description: Distinct session count within the bucket (by `sessionId`).
|
|
437
|
+
uniqueUsers:
|
|
438
|
+
type: integer
|
|
439
|
+
minimum: -9007199254740991
|
|
440
|
+
maximum: 9007199254740991
|
|
441
|
+
description: Distinct identified `userId` count. Anonymous sessions (userId=null)
|
|
442
|
+
are excluded.
|
|
443
|
+
anonymousSessions:
|
|
444
|
+
type: integer
|
|
445
|
+
minimum: -9007199254740991
|
|
446
|
+
maximum: 9007199254740991
|
|
447
|
+
description: Distinct session count where `userId` was null for the entire
|
|
448
|
+
session.
|
|
449
|
+
orders:
|
|
450
|
+
type: integer
|
|
451
|
+
minimum: -9007199254740991
|
|
452
|
+
maximum: 9007199254740991
|
|
453
|
+
description: Count of `order_submitted` events (or Order documents scoped
|
|
454
|
+
to this site, D43) within the bucket.
|
|
455
|
+
paymentsCompleted:
|
|
456
|
+
type: integer
|
|
457
|
+
minimum: -9007199254740991
|
|
458
|
+
maximum: 9007199254740991
|
|
459
|
+
description: Count of `payment_completed` events within the bucket.
|
|
460
|
+
paymentsFailed:
|
|
461
|
+
type: integer
|
|
462
|
+
minimum: -9007199254740991
|
|
463
|
+
maximum: 9007199254740991
|
|
464
|
+
description: Count of `payment_failed` events within the bucket.
|
|
465
|
+
errors:
|
|
466
|
+
type: integer
|
|
467
|
+
minimum: -9007199254740991
|
|
468
|
+
maximum: 9007199254740991
|
|
469
|
+
description: Count of `error_occurred` + `exception_caught` events within
|
|
470
|
+
the bucket.
|
|
471
|
+
eventCounts:
|
|
472
|
+
type: object
|
|
473
|
+
propertyNames:
|
|
474
|
+
type: string
|
|
475
|
+
additionalProperties:
|
|
476
|
+
type: integer
|
|
477
|
+
minimum: -9007199254740991
|
|
478
|
+
maximum: 9007199254740991
|
|
479
|
+
description: Per-event-name counts — key is the event name (canonical or
|
|
480
|
+
custom), value is the count within the bucket.
|
|
481
|
+
id:
|
|
482
|
+
readOnly: true
|
|
483
|
+
description: (Read-only) Firestore document ID = `YYYY-MM-DD`.
|
|
484
|
+
type:
|
|
485
|
+
- string
|
|
486
|
+
- 'null'
|
|
487
|
+
companyId:
|
|
488
|
+
type: string
|
|
489
|
+
x-immutable: true
|
|
490
|
+
description: (Immutable) FK → Company document ID.
|
|
491
|
+
siteId:
|
|
492
|
+
type: string
|
|
493
|
+
x-immutable: true
|
|
494
|
+
description: (Immutable) FK → Site document ID (D40).
|
|
495
|
+
date:
|
|
496
|
+
type: string
|
|
497
|
+
x-immutable: true
|
|
498
|
+
description: (Immutable) `YYYY-MM-DD` UTC — matches document ID.
|
|
499
|
+
computedAt:
|
|
500
|
+
$ref: '#/components/schemas/FirestoreTimestamp'
|
|
501
|
+
description: (Read-only) When this rollup was last (re)computed. Updated
|
|
502
|
+
on every set/merge.
|
|
503
|
+
readOnly: true
|
|
504
|
+
sourceEventCount:
|
|
505
|
+
readOnly: true
|
|
506
|
+
description: (Read-only, Optional) Total source events scanned when producing
|
|
507
|
+
this rollup. Useful for dry-run diffing.
|
|
508
|
+
type:
|
|
509
|
+
- integer
|
|
510
|
+
- 'null'
|
|
511
|
+
minimum: -9007199254740991
|
|
512
|
+
maximum: 9007199254740991
|
|
513
|
+
required:
|
|
514
|
+
- totalEvents
|
|
515
|
+
- pageViews
|
|
516
|
+
- sessions
|
|
517
|
+
- uniqueUsers
|
|
518
|
+
- anonymousSessions
|
|
519
|
+
- orders
|
|
520
|
+
- paymentsCompleted
|
|
521
|
+
- paymentsFailed
|
|
522
|
+
- errors
|
|
523
|
+
- eventCounts
|
|
524
|
+
- companyId
|
|
525
|
+
- siteId
|
|
526
|
+
- date
|
|
527
|
+
- computedAt
|
|
528
|
+
additionalProperties: false
|
|
529
|
+
description: 'AnalyticsDaily rollup (D42 / ING-304). Collection: companies/{companyId}/sites/{siteId}/analytics_daily/{YYYY-MM-DD}.
|
|
530
|
+
Idempotent set/merge — reruns overwrite. Fall back to raw analytics_events
|
|
531
|
+
for uncovered slices.'
|
|
532
|
+
AnalyticsDailyCreate:
|
|
533
|
+
allOf:
|
|
534
|
+
- $ref: '#/components/schemas/AnalyticsDaily'
|
|
535
|
+
description: Write payload for creating a new AnalyticsDaily document. Fields
|
|
536
|
+
marked `readOnly` are server-set and must not be included. Fields marked `x-immutable`
|
|
537
|
+
may be set once at creation.
|
|
538
|
+
required:
|
|
539
|
+
- totalEvents
|
|
540
|
+
- pageViews
|
|
541
|
+
- sessions
|
|
542
|
+
- uniqueUsers
|
|
543
|
+
- anonymousSessions
|
|
544
|
+
- orders
|
|
545
|
+
- paymentsCompleted
|
|
546
|
+
- paymentsFailed
|
|
547
|
+
- errors
|
|
548
|
+
- eventCounts
|
|
549
|
+
- companyId
|
|
550
|
+
- siteId
|
|
551
|
+
- date
|
|
552
|
+
AnalyticsDailyUpdate:
|
|
553
|
+
allOf:
|
|
554
|
+
- $ref: '#/components/schemas/AnalyticsDaily'
|
|
555
|
+
description: Write payload for partial update (PATCH) of a AnalyticsDaily document.
|
|
556
|
+
All fields optional. Fields marked `readOnly` or `x-immutable` must not be
|
|
557
|
+
sent.
|
|
558
|
+
AnalyticsEvent:
|
|
559
|
+
type: object
|
|
560
|
+
properties:
|
|
561
|
+
id:
|
|
562
|
+
readOnly: true
|
|
563
|
+
description: (Read-only) Firestore document ID. Equal to eventId.
|
|
564
|
+
type:
|
|
565
|
+
- string
|
|
566
|
+
- 'null'
|
|
567
|
+
companyId:
|
|
568
|
+
type: string
|
|
569
|
+
x-immutable: true
|
|
570
|
+
description: (Immutable) FK → Company document ID.
|
|
571
|
+
siteId:
|
|
572
|
+
type: string
|
|
573
|
+
x-immutable: true
|
|
574
|
+
description: (Immutable) FK → Site document ID (D40 sub-tenant scope).
|
|
575
|
+
eventId:
|
|
576
|
+
type: string
|
|
577
|
+
x-immutable: true
|
|
578
|
+
description: (Immutable) Client-generated UUID. Matches document ID.
|
|
579
|
+
eventName:
|
|
580
|
+
type: string
|
|
581
|
+
description: Event name. Free string; canonical vocabulary is encouraged
|
|
582
|
+
(see CANONICAL_ANALYTICS_EVENT_NAMES).
|
|
583
|
+
timestamp:
|
|
584
|
+
type: string
|
|
585
|
+
description: Client-side ISO 8601 — "when it happened on device". Can diverge
|
|
586
|
+
from serverTimestamp for queued offline events.
|
|
587
|
+
serverTimestamp:
|
|
588
|
+
$ref: '#/components/schemas/FirestoreTimestamp'
|
|
589
|
+
description: (Read-only) Firestore serverTimestamp() — authoritative for
|
|
590
|
+
ordering.
|
|
591
|
+
readOnly: true
|
|
592
|
+
sessionId:
|
|
593
|
+
type: string
|
|
594
|
+
description: 30-minute rolling session identifier.
|
|
595
|
+
userId:
|
|
596
|
+
anyOf:
|
|
597
|
+
- type: string
|
|
598
|
+
- type: 'null'
|
|
599
|
+
description: Stable user ID if identified; explicitly null (not omitted)
|
|
600
|
+
for anonymous sessions — simplifies querying.
|
|
601
|
+
properties:
|
|
602
|
+
type: object
|
|
603
|
+
propertyNames:
|
|
604
|
+
type: string
|
|
605
|
+
additionalProperties: {}
|
|
606
|
+
description: 'Free-form event-specific payload. Contract is at the event-name
|
|
607
|
+
level. PII posture: follow-up issue pending.'
|
|
608
|
+
context:
|
|
609
|
+
type: object
|
|
610
|
+
properties:
|
|
611
|
+
url:
|
|
612
|
+
description: Full URL at event time.
|
|
613
|
+
type: string
|
|
614
|
+
origin:
|
|
615
|
+
description: Protocol + host.
|
|
616
|
+
type: string
|
|
617
|
+
hostname:
|
|
618
|
+
description: Hostname only — useful for deployment identification.
|
|
619
|
+
type: string
|
|
620
|
+
page:
|
|
621
|
+
description: Current route/pathname.
|
|
622
|
+
type: string
|
|
623
|
+
title:
|
|
624
|
+
description: Page title.
|
|
625
|
+
type: string
|
|
626
|
+
referrer:
|
|
627
|
+
description: Referrer URL.
|
|
628
|
+
type: string
|
|
629
|
+
deviceType:
|
|
630
|
+
type: string
|
|
631
|
+
enum:
|
|
632
|
+
- mobile
|
|
633
|
+
- tablet
|
|
634
|
+
- desktop
|
|
635
|
+
platform:
|
|
636
|
+
description: OS/platform string.
|
|
637
|
+
type: string
|
|
638
|
+
screenWidth:
|
|
639
|
+
description: Viewport width (flattened from screen.width).
|
|
640
|
+
type: integer
|
|
641
|
+
minimum: -9007199254740991
|
|
642
|
+
maximum: 9007199254740991
|
|
643
|
+
screenHeight:
|
|
644
|
+
description: Viewport height (flattened from screen.height).
|
|
645
|
+
type: integer
|
|
646
|
+
minimum: -9007199254740991
|
|
647
|
+
maximum: 9007199254740991
|
|
648
|
+
appVersion:
|
|
649
|
+
description: Consuming app version.
|
|
650
|
+
type: string
|
|
651
|
+
online:
|
|
652
|
+
description: Connectivity state at event time.
|
|
653
|
+
type: boolean
|
|
654
|
+
locale:
|
|
655
|
+
description: User locale.
|
|
656
|
+
type: string
|
|
657
|
+
timezone:
|
|
658
|
+
description: IANA timezone.
|
|
659
|
+
type: string
|
|
660
|
+
utm:
|
|
661
|
+
description: UTM parameters; null when not a campaign-landed session.
|
|
662
|
+
anyOf:
|
|
663
|
+
- type: object
|
|
664
|
+
properties:
|
|
665
|
+
source:
|
|
666
|
+
type: string
|
|
667
|
+
medium:
|
|
668
|
+
type: string
|
|
669
|
+
campaign:
|
|
670
|
+
type: string
|
|
671
|
+
term:
|
|
672
|
+
type: string
|
|
673
|
+
content:
|
|
674
|
+
type: string
|
|
675
|
+
additionalProperties: false
|
|
676
|
+
- type: 'null'
|
|
677
|
+
additionalProperties: false
|
|
678
|
+
description: Environment context at event time (nested per D40).
|
|
679
|
+
userTraits:
|
|
680
|
+
description: 'Optional — included only when includeUserTraits: true on the
|
|
681
|
+
write. PII posture: follow-up issue pending.'
|
|
682
|
+
type:
|
|
683
|
+
- object
|
|
684
|
+
- 'null'
|
|
685
|
+
propertyNames:
|
|
686
|
+
type: string
|
|
687
|
+
additionalProperties: {}
|
|
688
|
+
required:
|
|
689
|
+
- companyId
|
|
690
|
+
- siteId
|
|
691
|
+
- eventId
|
|
692
|
+
- eventName
|
|
693
|
+
- timestamp
|
|
694
|
+
- serverTimestamp
|
|
695
|
+
- sessionId
|
|
696
|
+
- userId
|
|
697
|
+
- properties
|
|
698
|
+
- context
|
|
699
|
+
additionalProperties: false
|
|
700
|
+
description: 'AnalyticsEvent model (D40 / ING-304). Collection: companies/{companyId}/sites/{siteId}/analytics_events/{eventId}.
|
|
701
|
+
Append-only, immutable product/behavior event stream. Event names are free
|
|
702
|
+
strings; canonical vocabulary in CANONICAL_ANALYTICS_EVENT_NAMES.'
|
|
703
|
+
AnalyticsEventCreate:
|
|
704
|
+
allOf:
|
|
705
|
+
- $ref: '#/components/schemas/AnalyticsEvent'
|
|
706
|
+
description: Write payload for creating a new AnalyticsEvent document. Fields
|
|
707
|
+
marked `readOnly` are server-set and must not be included. Fields marked `x-immutable`
|
|
708
|
+
may be set once at creation.
|
|
709
|
+
required:
|
|
710
|
+
- companyId
|
|
711
|
+
- siteId
|
|
712
|
+
- eventId
|
|
713
|
+
- eventName
|
|
714
|
+
- timestamp
|
|
715
|
+
- sessionId
|
|
716
|
+
- userId
|
|
717
|
+
- properties
|
|
718
|
+
- context
|
|
719
|
+
AnalyticsEventUpdate:
|
|
720
|
+
allOf:
|
|
721
|
+
- $ref: '#/components/schemas/AnalyticsEvent'
|
|
722
|
+
description: Write payload for partial update (PATCH) of a AnalyticsEvent document.
|
|
723
|
+
All fields optional. Fields marked `readOnly` or `x-immutable` must not be
|
|
724
|
+
sent.
|
|
725
|
+
AnalyticsHourly:
|
|
726
|
+
type: object
|
|
727
|
+
properties:
|
|
728
|
+
totalEvents:
|
|
729
|
+
type: integer
|
|
730
|
+
minimum: -9007199254740991
|
|
731
|
+
maximum: 9007199254740991
|
|
732
|
+
description: Total event count within the bucket.
|
|
733
|
+
pageViews:
|
|
734
|
+
type: integer
|
|
735
|
+
minimum: -9007199254740991
|
|
736
|
+
maximum: 9007199254740991
|
|
737
|
+
description: Count of `page_view` + `screen_view` events.
|
|
738
|
+
sessions:
|
|
739
|
+
type: integer
|
|
740
|
+
minimum: -9007199254740991
|
|
741
|
+
maximum: 9007199254740991
|
|
742
|
+
description: Distinct session count within the bucket (by `sessionId`).
|
|
743
|
+
uniqueUsers:
|
|
744
|
+
type: integer
|
|
745
|
+
minimum: -9007199254740991
|
|
746
|
+
maximum: 9007199254740991
|
|
747
|
+
description: Distinct identified `userId` count. Anonymous sessions (userId=null)
|
|
748
|
+
are excluded.
|
|
749
|
+
anonymousSessions:
|
|
750
|
+
type: integer
|
|
751
|
+
minimum: -9007199254740991
|
|
752
|
+
maximum: 9007199254740991
|
|
753
|
+
description: Distinct session count where `userId` was null for the entire
|
|
754
|
+
session.
|
|
755
|
+
orders:
|
|
756
|
+
type: integer
|
|
757
|
+
minimum: -9007199254740991
|
|
758
|
+
maximum: 9007199254740991
|
|
759
|
+
description: Count of `order_submitted` events (or Order documents scoped
|
|
760
|
+
to this site, D43) within the bucket.
|
|
761
|
+
paymentsCompleted:
|
|
762
|
+
type: integer
|
|
763
|
+
minimum: -9007199254740991
|
|
764
|
+
maximum: 9007199254740991
|
|
765
|
+
description: Count of `payment_completed` events within the bucket.
|
|
766
|
+
paymentsFailed:
|
|
767
|
+
type: integer
|
|
768
|
+
minimum: -9007199254740991
|
|
769
|
+
maximum: 9007199254740991
|
|
770
|
+
description: Count of `payment_failed` events within the bucket.
|
|
771
|
+
errors:
|
|
772
|
+
type: integer
|
|
773
|
+
minimum: -9007199254740991
|
|
774
|
+
maximum: 9007199254740991
|
|
775
|
+
description: Count of `error_occurred` + `exception_caught` events within
|
|
776
|
+
the bucket.
|
|
777
|
+
eventCounts:
|
|
778
|
+
type: object
|
|
779
|
+
propertyNames:
|
|
780
|
+
type: string
|
|
781
|
+
additionalProperties:
|
|
782
|
+
type: integer
|
|
783
|
+
minimum: -9007199254740991
|
|
784
|
+
maximum: 9007199254740991
|
|
785
|
+
description: Per-event-name counts — key is the event name (canonical or
|
|
786
|
+
custom), value is the count within the bucket.
|
|
787
|
+
id:
|
|
788
|
+
readOnly: true
|
|
789
|
+
description: (Read-only) Firestore document ID = `YYYY-MM-DD-HH`.
|
|
790
|
+
type:
|
|
791
|
+
- string
|
|
792
|
+
- 'null'
|
|
793
|
+
companyId:
|
|
794
|
+
type: string
|
|
795
|
+
x-immutable: true
|
|
796
|
+
description: (Immutable) FK → Company document ID.
|
|
797
|
+
siteId:
|
|
798
|
+
type: string
|
|
799
|
+
x-immutable: true
|
|
800
|
+
description: (Immutable) FK → Site document ID (D40).
|
|
801
|
+
date:
|
|
802
|
+
type: string
|
|
803
|
+
x-immutable: true
|
|
804
|
+
description: (Immutable) `YYYY-MM-DD` UTC for the bucket day.
|
|
805
|
+
hour:
|
|
806
|
+
type: integer
|
|
807
|
+
minimum: -9007199254740991
|
|
808
|
+
maximum: 9007199254740991
|
|
809
|
+
x-immutable: true
|
|
810
|
+
description: (Immutable) UTC hour of day, 0–23.
|
|
811
|
+
computedAt:
|
|
812
|
+
$ref: '#/components/schemas/FirestoreTimestamp'
|
|
813
|
+
description: (Read-only) When this rollup was last (re)computed.
|
|
814
|
+
readOnly: true
|
|
815
|
+
sourceEventCount:
|
|
816
|
+
readOnly: true
|
|
817
|
+
description: (Read-only, Optional) Total source events scanned when producing
|
|
818
|
+
this rollup.
|
|
819
|
+
type:
|
|
820
|
+
- integer
|
|
821
|
+
- 'null'
|
|
822
|
+
minimum: -9007199254740991
|
|
823
|
+
maximum: 9007199254740991
|
|
824
|
+
required:
|
|
825
|
+
- totalEvents
|
|
826
|
+
- pageViews
|
|
827
|
+
- sessions
|
|
828
|
+
- uniqueUsers
|
|
829
|
+
- anonymousSessions
|
|
830
|
+
- orders
|
|
831
|
+
- paymentsCompleted
|
|
832
|
+
- paymentsFailed
|
|
833
|
+
- errors
|
|
834
|
+
- eventCounts
|
|
835
|
+
- companyId
|
|
836
|
+
- siteId
|
|
837
|
+
- date
|
|
838
|
+
- hour
|
|
839
|
+
- computedAt
|
|
840
|
+
additionalProperties: false
|
|
841
|
+
description: 'AnalyticsHourly rollup (D42 / ING-304). Collection: companies/{companyId}/sites/{siteId}/analytics_hourly/{YYYY-MM-DD-HH}.
|
|
842
|
+
Scheduled-CF writer; idempotent set/merge.'
|
|
843
|
+
AnalyticsHourlyCreate:
|
|
844
|
+
allOf:
|
|
845
|
+
- $ref: '#/components/schemas/AnalyticsHourly'
|
|
846
|
+
description: Write payload for creating a new AnalyticsHourly document. Fields
|
|
847
|
+
marked `readOnly` are server-set and must not be included. Fields marked `x-immutable`
|
|
848
|
+
may be set once at creation.
|
|
849
|
+
required:
|
|
850
|
+
- totalEvents
|
|
851
|
+
- pageViews
|
|
852
|
+
- sessions
|
|
853
|
+
- uniqueUsers
|
|
854
|
+
- anonymousSessions
|
|
855
|
+
- orders
|
|
856
|
+
- paymentsCompleted
|
|
857
|
+
- paymentsFailed
|
|
858
|
+
- errors
|
|
859
|
+
- eventCounts
|
|
860
|
+
- companyId
|
|
861
|
+
- siteId
|
|
862
|
+
- date
|
|
863
|
+
- hour
|
|
864
|
+
AnalyticsHourlyUpdate:
|
|
865
|
+
allOf:
|
|
866
|
+
- $ref: '#/components/schemas/AnalyticsHourly'
|
|
867
|
+
description: Write payload for partial update (PATCH) of a AnalyticsHourly document.
|
|
868
|
+
All fields optional. Fields marked `readOnly` or `x-immutable` must not be
|
|
869
|
+
sent.
|
|
183
870
|
Booking:
|
|
184
871
|
type: object
|
|
185
872
|
properties:
|
|
@@ -1598,6 +2285,112 @@ components:
|
|
|
1598
2285
|
description: Write payload for partial update (PATCH) of a LoyaltyTransaction
|
|
1599
2286
|
document. All fields optional. Fields marked `readOnly` or `x-immutable` must
|
|
1600
2287
|
not be sent.
|
|
2288
|
+
MagicLinkRequest:
|
|
2289
|
+
type: object
|
|
2290
|
+
properties:
|
|
2291
|
+
id:
|
|
2292
|
+
readOnly: true
|
|
2293
|
+
description: (Read-only) Firestore document ID. 16-byte random hex.
|
|
2294
|
+
type:
|
|
2295
|
+
- string
|
|
2296
|
+
- 'null'
|
|
2297
|
+
companyId:
|
|
2298
|
+
type: string
|
|
2299
|
+
x-immutable: true
|
|
2300
|
+
description: (Immutable) FK → Company document ID.
|
|
2301
|
+
siteId:
|
|
2302
|
+
type: string
|
|
2303
|
+
x-immutable: true
|
|
2304
|
+
description: (Immutable) FK → Site document ID (D40 sub-tenant scope).
|
|
2305
|
+
email:
|
|
2306
|
+
type: string
|
|
2307
|
+
description: Populated if identifier is email; empty string if phone. Mutually
|
|
2308
|
+
exclusive with phone per document.
|
|
2309
|
+
phone:
|
|
2310
|
+
type: string
|
|
2311
|
+
description: Populated if identifier is E.164 format (starts with +); empty
|
|
2312
|
+
string if email.
|
|
2313
|
+
ip:
|
|
2314
|
+
type: string
|
|
2315
|
+
description: Client IP from X-Forwarded-For or RemoteAddr.
|
|
2316
|
+
allowed:
|
|
2317
|
+
type: boolean
|
|
2318
|
+
description: Whether the user passed the access control check.
|
|
2319
|
+
link:
|
|
2320
|
+
type: string
|
|
2321
|
+
description: Magic-link URL — non-empty only when DEV_MODE=true; empty in
|
|
2322
|
+
production (audit integrity).
|
|
2323
|
+
tier:
|
|
2324
|
+
type: string
|
|
2325
|
+
description: Access tier selected by the user. Free string per site (ING-304
|
|
2326
|
+
open question — tier values are site-specific today).
|
|
2327
|
+
authStatusReason:
|
|
2328
|
+
type: string
|
|
2329
|
+
description: 'Outcome reason code: whitelist | allowed_users | payment_redirect
|
|
2330
|
+
| payment_complete | not_allowed | redirected_to_payment.'
|
|
2331
|
+
referredBy:
|
|
2332
|
+
type: string
|
|
2333
|
+
description: Contact identifier of the referrer, resolved from submitted
|
|
2334
|
+
referral_code; empty if none.
|
|
2335
|
+
requestedAt:
|
|
2336
|
+
$ref: '#/components/schemas/FirestoreTimestamp'
|
|
2337
|
+
description: RFC3339Nano UTC at request time.
|
|
2338
|
+
verifyReason:
|
|
2339
|
+
description: 'Verify outcome reason: mirrors authStatusReason on success,
|
|
2340
|
+
or link_expired | link_invalid | not_allowed.'
|
|
2341
|
+
type:
|
|
2342
|
+
- string
|
|
2343
|
+
- 'null'
|
|
2344
|
+
verified:
|
|
2345
|
+
description: Whether the verify attempt succeeded.
|
|
2346
|
+
type:
|
|
2347
|
+
- boolean
|
|
2348
|
+
- 'null'
|
|
2349
|
+
verifiedAt:
|
|
2350
|
+
anyOf:
|
|
2351
|
+
- $ref: '#/components/schemas/FirestoreTimestamp'
|
|
2352
|
+
- type: 'null'
|
|
2353
|
+
description: RFC3339Nano UTC at verify time.
|
|
2354
|
+
required:
|
|
2355
|
+
- companyId
|
|
2356
|
+
- siteId
|
|
2357
|
+
- email
|
|
2358
|
+
- phone
|
|
2359
|
+
- ip
|
|
2360
|
+
- allowed
|
|
2361
|
+
- link
|
|
2362
|
+
- tier
|
|
2363
|
+
- authStatusReason
|
|
2364
|
+
- referredBy
|
|
2365
|
+
- requestedAt
|
|
2366
|
+
additionalProperties: false
|
|
2367
|
+
description: 'MagicLinkRequest model (D40 / ING-304). Collection: companies/{companyId}/sites/{siteId}/magic_link_requests/{requestId}.
|
|
2368
|
+
Authentication audit log — every request is logged regardless of outcome.
|
|
2369
|
+
Two-stage write: Log() then LogVerify().'
|
|
2370
|
+
MagicLinkRequestCreate:
|
|
2371
|
+
allOf:
|
|
2372
|
+
- $ref: '#/components/schemas/MagicLinkRequest'
|
|
2373
|
+
description: Write payload for creating a new MagicLinkRequest document. Fields
|
|
2374
|
+
marked `readOnly` are server-set and must not be included. Fields marked `x-immutable`
|
|
2375
|
+
may be set once at creation.
|
|
2376
|
+
required:
|
|
2377
|
+
- companyId
|
|
2378
|
+
- siteId
|
|
2379
|
+
- email
|
|
2380
|
+
- phone
|
|
2381
|
+
- ip
|
|
2382
|
+
- allowed
|
|
2383
|
+
- link
|
|
2384
|
+
- tier
|
|
2385
|
+
- authStatusReason
|
|
2386
|
+
- referredBy
|
|
2387
|
+
- requestedAt
|
|
2388
|
+
MagicLinkRequestUpdate:
|
|
2389
|
+
allOf:
|
|
2390
|
+
- $ref: '#/components/schemas/MagicLinkRequest'
|
|
2391
|
+
description: Write payload for partial update (PATCH) of a MagicLinkRequest
|
|
2392
|
+
document. All fields optional. Fields marked `readOnly` or `x-immutable` must
|
|
2393
|
+
not be sent.
|
|
1601
2394
|
MetricsCurrent:
|
|
1602
2395
|
type: object
|
|
1603
2396
|
properties:
|
|
@@ -2205,6 +2998,23 @@ components:
|
|
|
2205
2998
|
type: string
|
|
2206
2999
|
x-immutable: true
|
|
2207
3000
|
description: (Immutable) FK → Company document ID. Scopes all queries.
|
|
3001
|
+
siteId:
|
|
3002
|
+
x-immutable: true
|
|
3003
|
+
x-note: 'D43 / ADR-003: optional site attribution. Absent/null means company-wide
|
|
3004
|
+
(legacy). When set, the order is attributed to a specific site for analytics
|
|
3005
|
+
and site-scoped dashboards. No migration — existing orders keep null.
|
|
3006
|
+
Flat path; Order continues to live at `companies/{companyId}/orders/{orderId}`.'
|
|
3007
|
+
x-see:
|
|
3008
|
+
decisions:
|
|
3009
|
+
- D43
|
|
3010
|
+
x-when: 'Set at order creation when the client knows which site the order
|
|
3011
|
+
originated from (e.g. SR Single, Lifesense). Leave null for legacy/company-wide
|
|
3012
|
+
orders. Composite index: (companyId, siteId, createdAt).'
|
|
3013
|
+
description: (Immutable, Optional) FK → Site document ID (D43 / ADR-003).
|
|
3014
|
+
null = company-wide.
|
|
3015
|
+
type:
|
|
3016
|
+
- string
|
|
3017
|
+
- 'null'
|
|
2208
3018
|
orderNumber:
|
|
2209
3019
|
type: string
|
|
2210
3020
|
readOnly: true
|
|
@@ -2827,6 +3637,264 @@ components:
|
|
|
2827
3637
|
- $ref: '#/components/schemas/Sale'
|
|
2828
3638
|
description: Write payload for partial update (PATCH) of a Sale document. All
|
|
2829
3639
|
fields optional. Fields marked `readOnly` or `x-immutable` must not be sent.
|
|
3640
|
+
Site:
|
|
3641
|
+
type: object
|
|
3642
|
+
properties:
|
|
3643
|
+
id:
|
|
3644
|
+
readOnly: true
|
|
3645
|
+
description: (Read-only) Firestore document ID, auto-generated.
|
|
3646
|
+
type:
|
|
3647
|
+
- string
|
|
3648
|
+
- 'null'
|
|
3649
|
+
companyId:
|
|
3650
|
+
type: string
|
|
3651
|
+
x-immutable: true
|
|
3652
|
+
description: (Immutable) FK → Company document ID. Scopes all site sub-collections.
|
|
3653
|
+
name:
|
|
3654
|
+
type: string
|
|
3655
|
+
description: Human-readable site name shown in dashboards.
|
|
3656
|
+
description:
|
|
3657
|
+
description: Optional freeform description.
|
|
3658
|
+
type:
|
|
3659
|
+
- string
|
|
3660
|
+
- 'null'
|
|
3661
|
+
status:
|
|
3662
|
+
$ref: '#/components/schemas/SiteStatus'
|
|
3663
|
+
description: Lifecycle status (D41). Clients filter by ACTIVE.
|
|
3664
|
+
x-note: ACTIVE = live and serving traffic. INACTIVE = intentionally disabled
|
|
3665
|
+
by operators. EXPIRED = past expiresAt (derived when isExpired is true;
|
|
3666
|
+
may also be stored explicitly). ARCHIVED = soft-deleted; retained for
|
|
3667
|
+
audit but not listed by default.
|
|
3668
|
+
x-see:
|
|
3669
|
+
decisions:
|
|
3670
|
+
- D41
|
|
3671
|
+
x-when: Written by operators via dashboard or by server triggers (expiration).
|
|
3672
|
+
Clients filter by ACTIVE.
|
|
3673
|
+
deploymentLinks:
|
|
3674
|
+
type: array
|
|
3675
|
+
items:
|
|
3676
|
+
type: object
|
|
3677
|
+
properties:
|
|
3678
|
+
label:
|
|
3679
|
+
type: string
|
|
3680
|
+
description: Human-readable label shown in dashboards (e.g. "Production",
|
|
3681
|
+
"Staging").
|
|
3682
|
+
url:
|
|
3683
|
+
type: string
|
|
3684
|
+
description: Absolute URL or store link.
|
|
3685
|
+
type:
|
|
3686
|
+
$ref: '#/components/schemas/DeploymentLinkType'
|
|
3687
|
+
description: Link category — drives icon/handler selection.
|
|
3688
|
+
x-note: Lowercase by convention — deployment link types are display-oriented
|
|
3689
|
+
labels, not lifecycle states.
|
|
3690
|
+
x-see:
|
|
3691
|
+
decisions:
|
|
3692
|
+
- D41
|
|
3693
|
+
isPrimary:
|
|
3694
|
+
description: If true, this link is used as the canonical deployment
|
|
3695
|
+
URL for the Site.
|
|
3696
|
+
type: boolean
|
|
3697
|
+
required:
|
|
3698
|
+
- label
|
|
3699
|
+
- url
|
|
3700
|
+
- type
|
|
3701
|
+
additionalProperties: false
|
|
3702
|
+
description: Deployment link entry embedded on Site.deploymentLinks[]
|
|
3703
|
+
(D41).
|
|
3704
|
+
description: Ordered list of deployment URLs (web, mobile, PWA, store links).
|
|
3705
|
+
expiresAt:
|
|
3706
|
+
anyOf:
|
|
3707
|
+
- $ref: '#/components/schemas/FirestoreTimestamp'
|
|
3708
|
+
- type: 'null'
|
|
3709
|
+
description: Optional expiration timestamp. When set and elapsed, `isExpired`
|
|
3710
|
+
flips true and status typically moves to EXPIRED.
|
|
3711
|
+
isExpired:
|
|
3712
|
+
readOnly: true
|
|
3713
|
+
description: (Read-only) Derived — true when `expiresAt` is in the past.
|
|
3714
|
+
Maintained by server trigger.
|
|
3715
|
+
type:
|
|
3716
|
+
- boolean
|
|
3717
|
+
- 'null'
|
|
3718
|
+
createdAt:
|
|
3719
|
+
anyOf:
|
|
3720
|
+
- $ref: '#/components/schemas/FirestoreTimestamp'
|
|
3721
|
+
- type: 'null'
|
|
3722
|
+
readOnly: true
|
|
3723
|
+
description: (Read-only) Server-generated creation timestamp.
|
|
3724
|
+
updatedAt:
|
|
3725
|
+
anyOf:
|
|
3726
|
+
- $ref: '#/components/schemas/FirestoreTimestamp'
|
|
3727
|
+
- type: 'null'
|
|
3728
|
+
readOnly: true
|
|
3729
|
+
description: (Read-only) Server-generated update timestamp.
|
|
3730
|
+
createdBy:
|
|
3731
|
+
type: string
|
|
3732
|
+
x-immutable: true
|
|
3733
|
+
description: (Immutable) FK → User/staff UID who created the site.
|
|
3734
|
+
analyticsEnabled:
|
|
3735
|
+
type: boolean
|
|
3736
|
+
description: Feature flag — when false, clients should not emit analytics
|
|
3737
|
+
events for this site.
|
|
3738
|
+
lastAnalyticsSync:
|
|
3739
|
+
anyOf:
|
|
3740
|
+
- $ref: '#/components/schemas/FirestoreTimestamp'
|
|
3741
|
+
- type: 'null'
|
|
3742
|
+
readOnly: true
|
|
3743
|
+
description: (Read-only) Last time the analytics rollup pipeline refreshed
|
|
3744
|
+
`cachedMetrics`.
|
|
3745
|
+
cachedMetrics:
|
|
3746
|
+
readOnly: true
|
|
3747
|
+
denormalized: true
|
|
3748
|
+
x-note: Updated by the rollup pipeline (D42). Readers should treat this
|
|
3749
|
+
as a hint; authoritative counts live in analytics_daily/analytics_hourly.
|
|
3750
|
+
x-see:
|
|
3751
|
+
decisions:
|
|
3752
|
+
- D41
|
|
3753
|
+
- D42
|
|
3754
|
+
description: (Read-only, Denormalized) Cached metrics snapshot for quick
|
|
3755
|
+
dashboard rendering.
|
|
3756
|
+
type:
|
|
3757
|
+
- object
|
|
3758
|
+
- 'null'
|
|
3759
|
+
properties:
|
|
3760
|
+
totalEvents:
|
|
3761
|
+
type: integer
|
|
3762
|
+
minimum: -9007199254740991
|
|
3763
|
+
maximum: 9007199254740991
|
|
3764
|
+
description: All-time event count cached on the Site.
|
|
3765
|
+
totalPageViews:
|
|
3766
|
+
type: integer
|
|
3767
|
+
minimum: -9007199254740991
|
|
3768
|
+
maximum: 9007199254740991
|
|
3769
|
+
description: All-time `page_view` + `screen_view` count.
|
|
3770
|
+
totalSessions:
|
|
3771
|
+
type: integer
|
|
3772
|
+
minimum: -9007199254740991
|
|
3773
|
+
maximum: 9007199254740991
|
|
3774
|
+
description: All-time distinct session count.
|
|
3775
|
+
totalOrders:
|
|
3776
|
+
type: integer
|
|
3777
|
+
minimum: -9007199254740991
|
|
3778
|
+
maximum: 9007199254740991
|
|
3779
|
+
description: All-time order count attributed to this site (via `Order.siteId`,
|
|
3780
|
+
D43).
|
|
3781
|
+
lastEventAt:
|
|
3782
|
+
$ref: '#/components/schemas/FirestoreTimestamp'
|
|
3783
|
+
description: Timestamp of the most recent analytics event seen for this
|
|
3784
|
+
site.
|
|
3785
|
+
required:
|
|
3786
|
+
- totalEvents
|
|
3787
|
+
- totalPageViews
|
|
3788
|
+
- totalSessions
|
|
3789
|
+
- totalOrders
|
|
3790
|
+
additionalProperties: false
|
|
3791
|
+
required:
|
|
3792
|
+
- companyId
|
|
3793
|
+
- name
|
|
3794
|
+
- status
|
|
3795
|
+
- deploymentLinks
|
|
3796
|
+
- createdBy
|
|
3797
|
+
- analyticsEnabled
|
|
3798
|
+
additionalProperties: false
|
|
3799
|
+
description: 'Site model (D41 / ING-304). Collection: companies/{companyId}/sites/{siteId}.
|
|
3800
|
+
Per-company product surface. Sub-collections (magic_link_requests, allowed_users,
|
|
3801
|
+
payments, analytics_events, analytics_daily, analytics_hourly, analytics_backfills)
|
|
3802
|
+
live under this document per D40/D42.'
|
|
3803
|
+
SiteCreate:
|
|
3804
|
+
allOf:
|
|
3805
|
+
- $ref: '#/components/schemas/Site'
|
|
3806
|
+
description: Write payload for creating a new Site document. Fields marked `readOnly`
|
|
3807
|
+
are server-set and must not be included. Fields marked `x-immutable` may be
|
|
3808
|
+
set once at creation.
|
|
3809
|
+
required:
|
|
3810
|
+
- companyId
|
|
3811
|
+
- name
|
|
3812
|
+
- status
|
|
3813
|
+
- deploymentLinks
|
|
3814
|
+
- createdBy
|
|
3815
|
+
- analyticsEnabled
|
|
3816
|
+
SiteUpdate:
|
|
3817
|
+
allOf:
|
|
3818
|
+
- $ref: '#/components/schemas/Site'
|
|
3819
|
+
description: Write payload for partial update (PATCH) of a Site document. All
|
|
3820
|
+
fields optional. Fields marked `readOnly` or `x-immutable` must not be sent.
|
|
3821
|
+
SitePayment:
|
|
3822
|
+
type: object
|
|
3823
|
+
properties:
|
|
3824
|
+
id:
|
|
3825
|
+
readOnly: true
|
|
3826
|
+
description: (Read-only) Firestore document ID, auto-generated.
|
|
3827
|
+
type:
|
|
3828
|
+
- string
|
|
3829
|
+
- 'null'
|
|
3830
|
+
companyId:
|
|
3831
|
+
type: string
|
|
3832
|
+
x-immutable: true
|
|
3833
|
+
description: (Immutable) FK → Company document ID.
|
|
3834
|
+
siteId:
|
|
3835
|
+
type: string
|
|
3836
|
+
x-immutable: true
|
|
3837
|
+
description: (Immutable) FK → Site document ID (D40 sub-tenant scope).
|
|
3838
|
+
contact:
|
|
3839
|
+
type: string
|
|
3840
|
+
description: Email or E.164 phone number. Matches AllowedUser.contact.
|
|
3841
|
+
sessionId:
|
|
3842
|
+
type: string
|
|
3843
|
+
description: Payment provider checkout session ID (e.g. Wave). Usable for
|
|
3844
|
+
dedup across dual writes.
|
|
3845
|
+
transactionId:
|
|
3846
|
+
type: string
|
|
3847
|
+
description: Payment provider transaction ID.
|
|
3848
|
+
tier:
|
|
3849
|
+
type: string
|
|
3850
|
+
description: Access tier. Free string per site (ING-304 open question).
|
|
3851
|
+
amount:
|
|
3852
|
+
type: number
|
|
3853
|
+
description: Amount paid. Generalized from amount_xof per D40 decision.
|
|
3854
|
+
currency:
|
|
3855
|
+
default: XOF
|
|
3856
|
+
description: Currency code (ISO 4217). Defaults to XOF for legacy SR-Single
|
|
3857
|
+
parity.
|
|
3858
|
+
type: string
|
|
3859
|
+
paidAt:
|
|
3860
|
+
$ref: '#/components/schemas/FirestoreTimestamp'
|
|
3861
|
+
description: RFC3339Nano UTC when payment was completed.
|
|
3862
|
+
required:
|
|
3863
|
+
- companyId
|
|
3864
|
+
- siteId
|
|
3865
|
+
- contact
|
|
3866
|
+
- sessionId
|
|
3867
|
+
- transactionId
|
|
3868
|
+
- tier
|
|
3869
|
+
- amount
|
|
3870
|
+
- currency
|
|
3871
|
+
- paidAt
|
|
3872
|
+
additionalProperties: false
|
|
3873
|
+
description: 'SitePayment model (D40 / ING-304). Collection: companies/{companyId}/sites/{siteId}/payments/{paymentId}.
|
|
3874
|
+
Immutable append-only transaction ledger. Distinct from AllowedUser (access
|
|
3875
|
+
state) and CustomerPayment (D22 — customer-level billing).'
|
|
3876
|
+
SitePaymentCreate:
|
|
3877
|
+
allOf:
|
|
3878
|
+
- $ref: '#/components/schemas/SitePayment'
|
|
3879
|
+
description: Write payload for creating a new SitePayment document. Fields marked
|
|
3880
|
+
`readOnly` are server-set and must not be included. Fields marked `x-immutable`
|
|
3881
|
+
may be set once at creation.
|
|
3882
|
+
required:
|
|
3883
|
+
- companyId
|
|
3884
|
+
- siteId
|
|
3885
|
+
- contact
|
|
3886
|
+
- sessionId
|
|
3887
|
+
- transactionId
|
|
3888
|
+
- tier
|
|
3889
|
+
- amount
|
|
3890
|
+
- currency
|
|
3891
|
+
- paidAt
|
|
3892
|
+
SitePaymentUpdate:
|
|
3893
|
+
allOf:
|
|
3894
|
+
- $ref: '#/components/schemas/SitePayment'
|
|
3895
|
+
description: Write payload for partial update (PATCH) of a SitePayment document.
|
|
3896
|
+
All fields optional. Fields marked `readOnly` or `x-immutable` must not be
|
|
3897
|
+
sent.
|
|
2830
3898
|
Ticket:
|
|
2831
3899
|
type: object
|
|
2832
3900
|
properties:
|