@ingenx-io/valets-schema-mcp-server 0.2.6 → 0.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/data/docs/collections/firestore-paths.md +20 -0
  2. package/data/docs/enums/app-status.md +1 -1
  3. package/data/docs/enums/attention-status.md +1 -1
  4. package/data/docs/enums/booking-status.md +1 -1
  5. package/data/docs/enums/contract-status.md +1 -1
  6. package/data/docs/enums/customer-payment-status.md +1 -1
  7. package/data/docs/enums/customer-payment-target-type.md +1 -1
  8. package/data/docs/enums/delivery-type.md +1 -1
  9. package/data/docs/enums/deployment-link-type.md +1 -1
  10. package/data/docs/enums/event-status.md +1 -1
  11. package/data/docs/enums/expense-payment-status.md +24 -0
  12. package/data/docs/enums/fulfillment-status.md +2 -2
  13. package/data/docs/enums/loyalty-transaction-type.md +2 -2
  14. package/data/docs/enums/milestone-status.md +2 -2
  15. package/data/docs/enums/notification-channel.md +2 -2
  16. package/data/docs/enums/notification-entity-type.md +2 -2
  17. package/data/docs/enums/notification-status.md +2 -2
  18. package/data/docs/enums/order-status.md +2 -2
  19. package/data/docs/enums/outbound-message-format.md +2 -2
  20. package/data/docs/enums/outbound-message-purpose.md +2 -2
  21. package/data/docs/enums/outbound-message-status.md +2 -2
  22. package/data/docs/enums/payment-method.md +4 -3
  23. package/data/docs/enums/payment-proof-status.md +2 -2
  24. package/data/docs/enums/payment-status.md +2 -2
  25. package/data/docs/enums/pending-issue.md +2 -2
  26. package/data/docs/enums/return-status.md +2 -2
  27. package/data/docs/enums/session-status.md +2 -2
  28. package/data/docs/enums/site-status.md +2 -2
  29. package/data/docs/enums/stocktake-frequency.md +2 -2
  30. package/data/docs/enums/stocktake-item-status.md +2 -2
  31. package/data/docs/enums/stocktake-status.md +2 -2
  32. package/data/docs/enums/ticket-status.md +2 -2
  33. package/data/docs/enums/waba-label.md +2 -2
  34. package/data/docs/enums/whatsapp-button-sub-type.md +2 -2
  35. package/data/docs/enums/whatsapp-template-component.md +2 -2
  36. package/data/docs/enums/whatsapp-template-status.md +2 -2
  37. package/data/docs/index.md +8 -5
  38. package/data/docs/models/allowed-user.md +1 -1
  39. package/data/docs/models/analytics-backfill.md +1 -1
  40. package/data/docs/models/analytics-daily.md +1 -1
  41. package/data/docs/models/analytics-event.md +1 -1
  42. package/data/docs/models/analytics-hourly.md +1 -1
  43. package/data/docs/models/app-payment.md +1 -1
  44. package/data/docs/models/app.md +1 -1
  45. package/data/docs/models/booking-version.md +1 -1
  46. package/data/docs/models/booking.md +1 -1
  47. package/data/docs/models/contract.md +1 -1
  48. package/data/docs/models/customer-payment-allocation.md +1 -1
  49. package/data/docs/models/customer-payment.md +22 -21
  50. package/data/docs/models/customer.md +1 -1
  51. package/data/docs/models/event.md +1 -1
  52. package/data/docs/models/expense.md +434 -0
  53. package/data/docs/models/loyalty-config.md +2 -2
  54. package/data/docs/models/loyalty-reward.md +2 -2
  55. package/data/docs/models/loyalty-status.md +2 -2
  56. package/data/docs/models/loyalty-transaction.md +2 -2
  57. package/data/docs/models/magic-link-request.md +2 -2
  58. package/data/docs/models/metrics-current.md +22 -2
  59. package/data/docs/models/metrics-daily.md +92 -41
  60. package/data/docs/models/metrics-monthly.md +22 -2
  61. package/data/docs/models/notification-record.md +68 -35
  62. package/data/docs/models/order-item.md +2 -2
  63. package/data/docs/models/order.md +56 -55
  64. package/data/docs/models/outbound-payment-allocation.md +2 -2
  65. package/data/docs/models/outbound-payment.md +3 -2
  66. package/data/docs/models/payment-webhook-delivery.md +321 -0
  67. package/data/docs/models/payment-webhook-endpoint.md +2 -2
  68. package/data/docs/models/sale.md +2 -2
  69. package/data/docs/models/site-payment.md +2 -2
  70. package/data/docs/models/site.md +2 -2
  71. package/data/docs/models/stocktake-item.md +2 -2
  72. package/data/docs/models/stocktake.md +2 -2
  73. package/data/docs/models/ticket.md +2 -2
  74. package/data/docs/models/user.md +2 -2
  75. package/data/docs/models/whatsapp-inbound-message.md +42 -18
  76. package/data/docs/models/whatsapp-outbound-lifecycle-event.md +2 -2
  77. package/data/docs/models/whatsapp-outbound-message.md +56 -32
  78. package/data/docs/models/whatsapp-template.md +2 -2
  79. package/data/static/llms.txt +110 -11
  80. package/data/static/openapi.yaml +444 -15
  81. package/data/static/schemas.json +394 -13
  82. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: "WhatsappOutboundMessage"
3
3
  sidebar_label: "WhatsappOutboundMessage"
4
- sidebar_position: 38
4
+ sidebar_position: 40
5
5
  ---
6
6
 
7
7
  # WhatsappOutboundMessage
@@ -24,6 +24,7 @@ sidebar_position: 38
24
24
  "uid": "user_u8x92kqm"
25
25
  },
26
26
  "createdAt": "createdAt",
27
+ "contactE164": null,
27
28
  "status": "status",
28
29
  "wamid": null,
29
30
  "error": null,
@@ -58,21 +59,22 @@ sidebar_position: 38
58
59
  - [11. Property `createdAt`](#createdAt)
59
60
  - [11.1. Property `_seconds`](#createdAt__seconds)
60
61
  - [11.2. Property `_nanoseconds`](#createdAt__nanoseconds)
61
- - [12. Property `status`](#status)
62
- - [13. Property `wamid`](#wamid)
63
- - [14. Property `error`](#error)
64
- - [15. Property `sentAt`](#sentAt)
65
- - [15.1. Property `firestore-timestamp`](#sentAt_anyOf_i0)
66
- - [15.2. Property `item 1`](#sentAt_anyOf_i1)
67
- - [16. Property `deliveredAt`](#deliveredAt)
68
- - [16.1. Property `firestore-timestamp`](#deliveredAt_anyOf_i0)
69
- - [16.2. Property `item 1`](#deliveredAt_anyOf_i1)
70
- - [17. Property `readAt`](#readAt)
71
- - [17.1. Property `firestore-timestamp`](#readAt_anyOf_i0)
72
- - [17.2. Property `item 1`](#readAt_anyOf_i1)
73
- - [18. Property `failedAt`](#failedAt)
74
- - [18.1. Property `firestore-timestamp`](#failedAt_anyOf_i0)
75
- - [18.2. Property `item 1`](#failedAt_anyOf_i1)
62
+ - [12. Property `contactE164`](#contactE164)
63
+ - [13. Property `status`](#status)
64
+ - [14. Property `wamid`](#wamid)
65
+ - [15. Property `error`](#error)
66
+ - [16. Property `sentAt`](#sentAt)
67
+ - [16.1. Property `firestore-timestamp`](#sentAt_anyOf_i0)
68
+ - [16.2. Property `item 1`](#sentAt_anyOf_i1)
69
+ - [17. Property `deliveredAt`](#deliveredAt)
70
+ - [17.1. Property `firestore-timestamp`](#deliveredAt_anyOf_i0)
71
+ - [17.2. Property `item 1`](#deliveredAt_anyOf_i1)
72
+ - [18. Property `readAt`](#readAt)
73
+ - [18.1. Property `firestore-timestamp`](#readAt_anyOf_i0)
74
+ - [18.2. Property `item 1`](#readAt_anyOf_i1)
75
+ - [19. Property `failedAt`](#failedAt)
76
+ - [19.1. Property `firestore-timestamp`](#failedAt_anyOf_i0)
77
+ - [19.2. Property `item 1`](#failedAt_anyOf_i1)
76
78
 
77
79
  | | |
78
80
  | ------------------------- | --------------------------------------- |
@@ -96,6 +98,7 @@ sidebar_position: 38
96
98
  | - [orderUuid](#orderUuid ) | No | string or null | No | - | Order reference. Present on review_request messages. |
97
99
  | + [sentBy](#sentBy ) | No | object | No | - | (Immutable) Dashboard actor who enqueued the message. |
98
100
  | + [createdAt](#createdAt ) | No | object | No | In #/definitions/firestore-timestamp | (Immutable) Enqueue timestamp, set by the dashboard at create. |
101
+ | - [contactE164](#contactE164 ) | No | string or null | No | - | (Read-only) E.164-normalized recipient phone (e.g. +2250777471485). Canonical join key (#56). Populated by the backend; absent on pre-migration docs. |
99
102
  | + [status](#status ) | No | enum (of string) | No | In #/definitions/outbound-message-status | Delivery status. Created as \`queued\` by the dashboard; updated in place by the backend. |
100
103
  | - [wamid](#wamid ) | No | string or null | No | - | (Read-only) WhatsApp message ID returned by Meta once the backend sends. Absent while queued or on failure. |
101
104
  | - [error](#error ) | No | string or null | No | - | (Read-only) Human-readable failure reason. Present on status=failed. Raw Meta error detail lives in the lifecycle_events subcollection. |
@@ -402,7 +405,28 @@ Set at creation only. This field cannot be modified after the document is create
402
405
  Set at creation only. This field cannot be modified after the document is created. Include it in CREATE payloads; omit it (or leave unchanged) in UPDATE payloads.
403
406
  :::
404
407
 
405
- ## <a name="status"></a>12. Property `status`
408
+ ## <a name="contactE164"></a>12. Property `contactE164`
409
+
410
+ | | |
411
+ | ------------ | ---------------- |
412
+ | **Type** | `string or null` |
413
+ | **Required** | No |
414
+
415
+ **Description:** (Read-only) E.164-normalized recipient phone (e.g. +2250777471485). Canonical join key (#56). Populated by the backend; absent on pre-migration docs.
416
+
417
+ :::warning Server-set
418
+ Do not include in write requests. This field is set exclusively by the server (Firestore trigger or Admin SDK). Clients that send it will have the value silently ignored or may receive a validation error.
419
+ :::
420
+
421
+ :::note
422
+ E.164-normalized form of `to` (wa_id). Canonical join key across WhatsappOutboundMessage, WhatsappInboundMessage, and NotificationRecord. Use this for conversation threading, search, and cross-collection joins — not the raw `to` wa_id (#56).
423
+ :::
424
+
425
+ :::tip When to set
426
+ Populated by whatsapp-server on every new outbound doc. Absent on pre-#56 docs until the backfill migration runs. CI normalization: wa_id 22577471485 → +2250777471485 (insert trunk 0 after country code for 8-digit numbers in the 07/05/01 series that predate the 2014 10-digit migration).
427
+ :::
428
+
429
+ ## <a name="status"></a>13. Property `status`
406
430
 
407
431
  | | |
408
432
  | -------------- | ------------------------------------- |
@@ -423,7 +447,7 @@ Must be one of:
423
447
  Dashboard must create with `queued`. The backend owns every transition after (sent → delivered → read, or failed).
424
448
  :::
425
449
 
426
- ## <a name="wamid"></a>13. Property `wamid`
450
+ ## <a name="wamid"></a>14. Property `wamid`
427
451
 
428
452
  | | |
429
453
  | ------------ | ---------------- |
@@ -440,7 +464,7 @@ Do not include in write requests. This field is set exclusively by the server (F
440
464
  Useful for audit and dedup. Does NOT enable reply-threading for template messages — Meta silently ignores context.message_id on templates. Threading only works for kind=text within the 24-hour service window (#50).
441
465
  :::
442
466
 
443
- ## <a name="error"></a>14. Property `error`
467
+ ## <a name="error"></a>15. Property `error`
444
468
 
445
469
  | | |
446
470
  | ------------ | ---------------- |
@@ -453,7 +477,7 @@ Useful for audit and dedup. Does NOT enable reply-threading for template message
453
477
  Do not include in write requests. This field is set exclusively by the server (Firestore trigger or Admin SDK). Clients that send it will have the value silently ignored or may receive a validation error.
454
478
  :::
455
479
 
456
- ## <a name="sentAt"></a>15. Property `sentAt`
480
+ ## <a name="sentAt"></a>16. Property `sentAt`
457
481
 
458
482
  | | |
459
483
  | ------------------------- | ---------------- |
@@ -468,7 +492,7 @@ Do not include in write requests. This field is set exclusively by the server (F
468
492
  | [firestore-timestamp](#sentAt_anyOf_i0) |
469
493
  | [item 1](#sentAt_anyOf_i1) |
470
494
 
471
- ### <a name="sentAt_anyOf_i0"></a>15.1. Property `firestore-timestamp`
495
+ ### <a name="sentAt_anyOf_i0"></a>16.1. Property `firestore-timestamp`
472
496
 
473
497
  | | |
474
498
  | ------------------------- | ----------------------- |
@@ -479,7 +503,7 @@ Do not include in write requests. This field is set exclusively by the server (F
479
503
 
480
504
  **Description:** Firestore Timestamp — Admin SDK form: \{ _seconds, _nanoseconds \}. See types/firestore.ts for REST API v1 and client SDK serialization notes (#10).
481
505
 
482
- ### <a name="sentAt_anyOf_i1"></a>15.2. Property `item 1`
506
+ ### <a name="sentAt_anyOf_i1"></a>16.2. Property `item 1`
483
507
 
484
508
  | | |
485
509
  | ------------ | ------ |
@@ -490,7 +514,7 @@ Do not include in write requests. This field is set exclusively by the server (F
490
514
  Do not include in write requests. This field is set exclusively by the server (Firestore trigger or Admin SDK). Clients that send it will have the value silently ignored or may receive a validation error.
491
515
  :::
492
516
 
493
- ## <a name="deliveredAt"></a>16. Property `deliveredAt`
517
+ ## <a name="deliveredAt"></a>17. Property `deliveredAt`
494
518
 
495
519
  | | |
496
520
  | ------------------------- | ---------------- |
@@ -505,7 +529,7 @@ Do not include in write requests. This field is set exclusively by the server (F
505
529
  | [firestore-timestamp](#deliveredAt_anyOf_i0) |
506
530
  | [item 1](#deliveredAt_anyOf_i1) |
507
531
 
508
- ### <a name="deliveredAt_anyOf_i0"></a>16.1. Property `firestore-timestamp`
532
+ ### <a name="deliveredAt_anyOf_i0"></a>17.1. Property `firestore-timestamp`
509
533
 
510
534
  | | |
511
535
  | ------------------------- | ----------------------- |
@@ -516,7 +540,7 @@ Do not include in write requests. This field is set exclusively by the server (F
516
540
 
517
541
  **Description:** Firestore Timestamp — Admin SDK form: \{ _seconds, _nanoseconds \}. See types/firestore.ts for REST API v1 and client SDK serialization notes (#10).
518
542
 
519
- ### <a name="deliveredAt_anyOf_i1"></a>16.2. Property `item 1`
543
+ ### <a name="deliveredAt_anyOf_i1"></a>17.2. Property `item 1`
520
544
 
521
545
  | | |
522
546
  | ------------ | ------ |
@@ -527,7 +551,7 @@ Do not include in write requests. This field is set exclusively by the server (F
527
551
  Do not include in write requests. This field is set exclusively by the server (Firestore trigger or Admin SDK). Clients that send it will have the value silently ignored or may receive a validation error.
528
552
  :::
529
553
 
530
- ## <a name="readAt"></a>17. Property `readAt`
554
+ ## <a name="readAt"></a>18. Property `readAt`
531
555
 
532
556
  | | |
533
557
  | ------------------------- | ---------------- |
@@ -542,7 +566,7 @@ Do not include in write requests. This field is set exclusively by the server (F
542
566
  | [firestore-timestamp](#readAt_anyOf_i0) |
543
567
  | [item 1](#readAt_anyOf_i1) |
544
568
 
545
- ### <a name="readAt_anyOf_i0"></a>17.1. Property `firestore-timestamp`
569
+ ### <a name="readAt_anyOf_i0"></a>18.1. Property `firestore-timestamp`
546
570
 
547
571
  | | |
548
572
  | ------------------------- | ----------------------- |
@@ -553,7 +577,7 @@ Do not include in write requests. This field is set exclusively by the server (F
553
577
 
554
578
  **Description:** Firestore Timestamp — Admin SDK form: \{ _seconds, _nanoseconds \}. See types/firestore.ts for REST API v1 and client SDK serialization notes (#10).
555
579
 
556
- ### <a name="readAt_anyOf_i1"></a>17.2. Property `item 1`
580
+ ### <a name="readAt_anyOf_i1"></a>18.2. Property `item 1`
557
581
 
558
582
  | | |
559
583
  | ------------ | ------ |
@@ -564,7 +588,7 @@ Do not include in write requests. This field is set exclusively by the server (F
564
588
  Do not include in write requests. This field is set exclusively by the server (Firestore trigger or Admin SDK). Clients that send it will have the value silently ignored or may receive a validation error.
565
589
  :::
566
590
 
567
- ## <a name="failedAt"></a>18. Property `failedAt`
591
+ ## <a name="failedAt"></a>19. Property `failedAt`
568
592
 
569
593
  | | |
570
594
  | ------------------------- | ---------------- |
@@ -579,7 +603,7 @@ Do not include in write requests. This field is set exclusively by the server (F
579
603
  | [firestore-timestamp](#failedAt_anyOf_i0) |
580
604
  | [item 1](#failedAt_anyOf_i1) |
581
605
 
582
- ### <a name="failedAt_anyOf_i0"></a>18.1. Property `firestore-timestamp`
606
+ ### <a name="failedAt_anyOf_i0"></a>19.1. Property `firestore-timestamp`
583
607
 
584
608
  | | |
585
609
  | ------------------------- | ----------------------- |
@@ -590,7 +614,7 @@ Do not include in write requests. This field is set exclusively by the server (F
590
614
 
591
615
  **Description:** Firestore Timestamp — Admin SDK form: \{ _seconds, _nanoseconds \}. See types/firestore.ts for REST API v1 and client SDK serialization notes (#10).
592
616
 
593
- ### <a name="failedAt_anyOf_i1"></a>18.2. Property `item 1`
617
+ ### <a name="failedAt_anyOf_i1"></a>19.2. Property `item 1`
594
618
 
595
619
  | | |
596
620
  | ------------ | ------ |
@@ -598,7 +622,7 @@ Do not include in write requests. This field is set exclusively by the server (F
598
622
  | **Required** | No |
599
623
 
600
624
  ----------------------------------------------------------------------------------------------------------------------------
601
- Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-05-30 at 13:38:45 +0000
625
+ Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-05-30 at 14:38:11 +0000
602
626
 
603
627
  :::warning Server-set
604
628
  Do not include in write requests. This field is set exclusively by the server (Firestore trigger or Admin SDK). Clients that send it will have the value silently ignored or may receive a validation error.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: "WhatsappTemplate"
3
3
  sidebar_label: "WhatsappTemplate"
4
- sidebar_position: 39
4
+ sidebar_position: 41
5
5
  ---
6
6
 
7
7
  # WhatsappTemplate
@@ -291,7 +291,7 @@ Do not include in write requests. This field is set exclusively by the server (F
291
291
  **Description:** (Read-only) Rendered preview text for display in the dashboard picker.
292
292
 
293
293
  ----------------------------------------------------------------------------------------------------------------------------
294
- Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-05-30 at 13:38:45 +0000
294
+ Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-05-30 at 14:38:11 +0000
295
295
 
296
296
  :::warning Server-set
297
297
  Do not include in write requests. This field is set exclusively by the server (Firestore trigger or Admin SDK). Clients that send it will have the value silently ignored or may receive a validation error.
@@ -46,6 +46,10 @@ Values: web, mobile, pwa, app-store, play-store, other
46
46
  Ticketed event lifecycle (D32). Mobile-only today; Dashboard in Wave 4.
47
47
  Values: DRAFT, ACTIVE, CANCELLED, COMPLETED
48
48
 
49
+ ### ExpensePaymentStatus
50
+ Payment status of an Expense. Stored enum — OVERDUE is not stored, it is derived at read time from dueDate (#13).
51
+ Values: PENDING, PARTIALLY_PAID, PAID, FAILED
52
+
49
53
  ### FulfillmentStatus
50
54
  Delivery/fulfillment lifecycle (D34). Optional — null for in-person orders.
51
55
  Values: PREPARING, PARTIALLY_SHIPPED, SHIPPED, IN_TRANSIT, DELIVERED, PICKED_UP
@@ -87,8 +91,8 @@ Outbound WhatsApp message delivery status. Lifecycle: queued → sent → delive
87
91
  Values: queued, sent, delivered, read, failed
88
92
 
89
93
  ### PaymentMethod
90
- Unified payment method set with African + global methods (D02).
91
- Values: CASH, CREDIT_CARD, ORANGE_MONEY, WAVE, MTN_MONEY, MOOV_MONEY, BANK_TRANSFER, PAYPAL, STRIPE, OTHER
94
+ Unified payment method set with African + global methods (D02). Note: the metrics writer historically emits "OM" instead of "ORANGE_MONEY" as a paymentsByMethod map key — treat OM as deprecated; canonical value is ORANGE_MONEY (#21).
95
+ Values: CASH, CREDIT_CARD, ORANGE_MONEY, WAVE, MTN_MONEY, MOOV_MONEY, BANK_TRANSFER, PAYPAL, STRIPE, OTHER, OM
92
96
 
93
97
  ### PaymentProofStatus
94
98
  Payment proof review status. Used by Order and Booking payment proof workflows.
@@ -750,7 +754,7 @@ Fields: 17 (12 required)
750
754
  | amount | number | yes | |
751
755
  | currency | string | yes | Currency code. Locked to XOF (West African CFA franc) for now. |
752
756
  | paymentDate | FirestoreTimestamp | yes | Firestore Timestamp — Admin SDK form: { _seconds, _nanoseconds }. See types/firestore.ts for REST API v1 and client SDK serialization notes (#10). |
753
- | paymentMethod | PaymentMethod | yes | Unified payment method set with African + global methods (D02). |
757
+ | paymentMethod | PaymentMethod | yes | Unified payment method set with African + global methods (D02). Note: the metrics writer historically emits "OM" instead of "ORANGE_MONEY" as a paymentsByMethod map key — treat OM as deprecated; canonical value is ORANGE_MONEY (#21). |
754
758
  | referenceNumber | string | yes | Unique payment reference (receipt number, transaction ID, etc.). |
755
759
  | allocatedAmount | number | yes | (Read-only) Total amount allocated to bookings/orders/purchases via allocations. Server-calculated. |
756
760
  | unappliedAmount | number | yes | (Read-only) Remaining unallocated amount (amount - allocatedAmount). Server-calculated. |
@@ -866,6 +870,52 @@ Example:
866
870
  }
867
871
  ```
868
872
 
873
+ ### Expense
874
+ Fields: 17 (6 required)
875
+
876
+ | Field | Type | Required | Description |
877
+ |-------|------|----------|-------------|
878
+ | id | ['string', 'null'] | no | (Read-only) Firestore document ID, auto-generated. |
879
+ | companyId | string | yes | (Immutable) FK → Company document ID. |
880
+ | title | string | yes | Human-readable expense title (e.g. "Loyer mars 2026", "Facture EAU"). |
881
+ | description | ['string', 'null'] | no | Optional longer description or notes. |
882
+ | amount | number | yes | Total expense amount (XOF). |
883
+ | currency | string | yes | Currency code. Locked to XOF. |
884
+ | dueDate | any | no | When the expense is due. Used to compute OVERDUE state at read time (not stored in paymentStatus). |
885
+ | paymentStatus | ExpensePaymentStatus | yes | Current payment status. OVERDUE is never stored — derive from dueDate at read time (#13). |
886
+ | amountDue | ['number', 'null'] | no | Amount still owed. Authoritative when no OutboundPaymentAllocation records exist for this expense. |
887
+ | amountPaid | ['number', 'null'] | no | Amount paid to date (simple tracking, no allocations). |
888
+ | allocatedAmount | ['number', 'null'] | no | (Read-only) Total amount allocated via OutboundPaymentAllocation records. Authoritative when allocations exist. |
889
+ | balance | ['number', 'null'] | no | (Read-only) Remaining balance: amount minus allocatedAmount. Authoritative when OutboundPaymentAllocation records exist. |
890
+ | paidDate | any | no | When the expense was fully settled (paymentStatus = PAID). Null otherwise. |
891
+ | paymentReference | ['string', 'null'] | no | Most recent payment transaction reference. Overwritten on each payment; not a full history. |
892
+ | createdBy | string | yes | (Immutable) FK → User/staff UID who created this expense record. |
893
+ | createdAt | any | no | (Read-only) Server-generated creation timestamp. |
894
+ | updatedAt | any | no | (Read-only) Server-generated last-update timestamp. |
895
+
896
+ Example:
897
+ ```json
898
+ {
899
+ "id": null,
900
+ "companyId": "comp_xyz789",
901
+ "title": "title",
902
+ "description": null,
903
+ "amount": 45000,
904
+ "currency": "XOF",
905
+ "dueDate": "dueDate",
906
+ "paymentStatus": "paymentStatus",
907
+ "amountDue": null,
908
+ "amountPaid": null,
909
+ "allocatedAmount": null,
910
+ "balance": null,
911
+ "paidDate": "pai_ref123",
912
+ "paymentReference": null,
913
+ "createdBy": "staff_k0f1",
914
+ "createdAt": "createdAt",
915
+ "updatedAt": "updatedAt"
916
+ }
917
+ ```
918
+
869
919
  ### LoyaltyConfig
870
920
  Fields: 11 (2 required)
871
921
 
@@ -1154,7 +1204,7 @@ Fields: 31 (26 required)
1154
1204
  | staleOrdersCount | ['integer', 'null'] | no | (Read-only, Optional) Orders that have been in an incomplete status beyond the stale threshold. |
1155
1205
  | staleBookingsCount | ['integer', 'null'] | no | (Read-only, Optional) Bookings that have been in an incomplete status beyond the stale threshold. |
1156
1206
  | onHoldOrdersCount | ['integer', 'null'] | no | (Read-only, Optional) Orders currently in an on-hold state. |
1157
- | paymentsByMethod | ['object', 'null'] | no | (Read-only, Optional) Map of PaymentMethod total amount for the current day. Empty map {} until first payment. |
1207
+ | paymentsByMethod | ['object', 'null'] | no | (Read-only, Optional) Payment breakdown by method for the day. Keys are PaymentMethod values (or legacy short code OM). Value is { total: XOF amount, count: number of payments }. |
1158
1208
  | computedForDay | string | yes | (Read-only) YYYY-MM-DD string indicating which day these metrics reflect. Used to detect day boundaries and trigger midnight resets. |
1159
1209
  | generatedAt | FirestoreTimestamp | yes | (Read-only) Server timestamp of the last metrics write. |
1160
1210
  | date | string | yes | (Read-only) YYYY-MM-DD document ID repeated as a field. Identifies the day this snapshot covers. |
@@ -1282,17 +1332,20 @@ Fields: 12 (6 required)
1282
1332
  | recipients | object | yes | (Read-only) Recipients of the notification. |
1283
1333
  | recipients.to | array<object> | yes | Primary recipients. |
1284
1334
  | recipients.to[].email | string | no | Recipient email address. Present for email notifications. |
1285
- | recipients.to[].phone | string | no | Recipient phone number (E.164). Present for whatsapp/sms notifications. |
1335
+ | recipients.to[].phone | string | no | Recipient phone number as passed by the sender (may be raw wa_id or E.164). Present for whatsapp/sms notifications. |
1336
+ | recipients.to[].contactE164 | string | no | (Read-only) E.164-normalized phone (e.g. +2250777471485). Canonical join key across WhatsApp and notification collections (#56). |
1286
1337
  | recipients.to[].name | string | no | Recipient display name. |
1287
1338
  | recipients.to[].role | string | no | Recipient role (e.g. organizer, customer). |
1288
1339
  | recipients.cc | array<object> | no | CC recipients (email). |
1289
1340
  | recipients.cc[].email | string | no | Recipient email address. Present for email notifications. |
1290
- | recipients.cc[].phone | string | no | Recipient phone number (E.164). Present for whatsapp/sms notifications. |
1341
+ | recipients.cc[].phone | string | no | Recipient phone number as passed by the sender (may be raw wa_id or E.164). Present for whatsapp/sms notifications. |
1342
+ | recipients.cc[].contactE164 | string | no | (Read-only) E.164-normalized phone (e.g. +2250777471485). Canonical join key across WhatsApp and notification collections (#56). |
1291
1343
  | recipients.cc[].name | string | no | Recipient display name. |
1292
1344
  | recipients.cc[].role | string | no | Recipient role (e.g. organizer, customer). |
1293
1345
  | recipients.bcc | array<object> | no | BCC recipients (email). |
1294
1346
  | recipients.bcc[].email | string | no | Recipient email address. Present for email notifications. |
1295
- | recipients.bcc[].phone | string | no | Recipient phone number (E.164). Present for whatsapp/sms notifications. |
1347
+ | recipients.bcc[].phone | string | no | Recipient phone number as passed by the sender (may be raw wa_id or E.164). Present for whatsapp/sms notifications. |
1348
+ | recipients.bcc[].contactE164 | string | no | (Read-only) E.164-normalized phone (e.g. +2250777471485). Canonical join key across WhatsApp and notification collections (#56). |
1296
1349
  | recipients.bcc[].name | string | no | Recipient display name. |
1297
1350
  | recipients.bcc[].role | string | no | Recipient role (e.g. organizer, customer). |
1298
1351
  | relatedEntity | object | yes | (Read-only) Entity that triggered the notification. type=order triggers the dual-write to the order subcollection. |
@@ -1346,7 +1399,7 @@ Fields: 49 (8 required)
1346
1399
  | fulfillmentStatus | any | no | Delivery/fulfillment lifecycle (D34). |
1347
1400
  | returnStatus | any | no | Return/exchange lifecycle (D34). Null until a return or exchange is initiated. |
1348
1401
  | deliveryType | any | no | Fulfillment channel for this order (ON_SITE, PICK_UP, DELIVERY). |
1349
- | paymentMethod | any | no | Unified payment method set with African + global methods (D02). |
1402
+ | paymentMethod | any | no | Unified payment method set with African + global methods (D02). Note: the metrics writer historically emits "OM" instead of "ORANGE_MONEY" as a paymentsByMethod map key — treat OM as deprecated; canonical value is ORANGE_MONEY (#21). |
1350
1403
  | invoiceId | ['string', 'null'] | no | FK → Invoice document ID. |
1351
1404
  | customerId | ['string', 'null'] | no | FK → Customer.id (Firestore doc ID). Used to resolve customer details. |
1352
1405
  | customerName | ['string', 'null'] | no | (Denormalized) From Customer.name at write time. |
@@ -1540,6 +1593,48 @@ Example:
1540
1593
  }
1541
1594
  ```
1542
1595
 
1596
+ ### PaymentWebhookDelivery
1597
+ Fields: 15 (13 required)
1598
+
1599
+ | Field | Type | Required | Description |
1600
+ |-------|------|----------|-------------|
1601
+ | id | ['string', 'null'] | no | (Read-only) Firestore document ID, auto-generated. |
1602
+ | company | string | yes | (Immutable) Company document ID (e.g. "gerko_studios"). Resolved from the matched endpoint at delivery time. |
1603
+ | provider | string | yes | Payment provider that sent this webhook (e.g. "jeko", "wave"). |
1604
+ | eventType | string | yes | Provider-defined event type. Observed: "transaction.payment". Full set per provider TBD (#42). |
1605
+ | status | string | yes | Processing outcome. Observed values: "success" | "error". |
1606
+ | verified | string | yes | Signature verification result. Observed: "verified". Other values (e.g. "unverified", "error") may exist but are unconfirmed. |
1607
+ | endpointStatus | string | yes | Endpoint resolution result. Observed: "matched". Other values unconfirmed (#42). |
1608
+ | processed | boolean | yes | Whether this delivery has been reconciled to the AppPayment ledger. |
1609
+ | reference | string | yes | Provider transaction ID (= payload.id). Canonical dedup key. |
1610
+ | amount | number | yes | Payment amount, denormalized from payload.amount.amount (XOF). |
1611
+ | currency | string | yes | Currency code, denormalized from payload.amount.currency (e.g. "XOF"). |
1612
+ | payload | object | yes | Full parsed provider payload. Shape varies by provider. Contains PII (customer phone). See x-note for retention policy status. |
1613
+ | rawBody | string | yes | Verbatim raw request body — used for HMAC-SHA256 verification. Contains PII. |
1614
+ | headers | ['object', 'null'] | no | Incoming HTTP headers. Includes provider signature header and Sentry trace. Sensitive. |
1615
+ | receivedAt | FirestoreTimestamp | yes | When the webhook delivery was received by the backend. |
1616
+
1617
+ Example:
1618
+ ```json
1619
+ {
1620
+ "id": null,
1621
+ "company": "company",
1622
+ "provider": "pro_ref123",
1623
+ "eventType": "eventType",
1624
+ "status": "status",
1625
+ "verified": "verified",
1626
+ "endpointStatus": "endpointStatus",
1627
+ "processed": true,
1628
+ "reference": "reference",
1629
+ "amount": 45000,
1630
+ "currency": "XOF",
1631
+ "payload": {},
1632
+ "rawBody": "rawBody",
1633
+ "headers": null,
1634
+ "receivedAt": "receivedAt"
1635
+ }
1636
+ ```
1637
+
1543
1638
  ### PaymentWebhookEndpoint
1544
1639
  Fields: 6 (5 required)
1545
1640
 
@@ -1855,7 +1950,7 @@ Example:
1855
1950
  ```
1856
1951
 
1857
1952
  ### WhatsappInboundMessage
1858
- Fields: 13 (7 required)
1953
+ Fields: 14 (7 required)
1859
1954
 
1860
1955
  | Field | Type | Required | Description |
1861
1956
  |-------|------|----------|-------------|
@@ -1872,6 +1967,7 @@ Fields: 13 (7 required)
1872
1967
  | caption | ['string', 'null'] | no | Media caption text. Present when the sender included a caption. |
1873
1968
  | storageUrl | ['string', 'null'] | no | Durable Cloud Storage URL for the downloaded media binary. Present after the media has been fetched and stored server-side. |
1874
1969
  | context | ['object', 'null'] | no | Reply/forward context. Present on replies and forwarded messages. |
1970
+ | contactE164 | ['string', 'null'] | no | (Read-only) E.164-normalized sender phone (e.g. +2250777471485). Canonical join key (#56). Populated by the backend; absent on pre-migration docs. |
1875
1971
 
1876
1972
  Example:
1877
1973
  ```json
@@ -1888,7 +1984,8 @@ Example:
1888
1984
  "mediaId": null,
1889
1985
  "caption": null,
1890
1986
  "storageUrl": null,
1891
- "context": null
1987
+ "context": null,
1988
+ "contactE164": null
1892
1989
  }
1893
1990
  ```
1894
1991
 
@@ -1927,7 +2024,7 @@ Example:
1927
2024
  ```
1928
2025
 
1929
2026
  ### WhatsappOutboundMessage
1930
- Fields: 18 (7 required)
2027
+ Fields: 19 (7 required)
1931
2028
 
1932
2029
  | Field | Type | Required | Description |
1933
2030
  |-------|------|----------|-------------|
@@ -1944,6 +2041,7 @@ Fields: 18 (7 required)
1944
2041
  | sentBy.uid | string | yes | Firebase Auth UID of the dashboard user who enqueued the message. |
1945
2042
  | sentBy.email | string | no | Email of the sender, if available. |
1946
2043
  | createdAt | FirestoreTimestamp | yes | (Immutable) Enqueue timestamp, set by the dashboard at create. |
2044
+ | contactE164 | ['string', 'null'] | no | (Read-only) E.164-normalized recipient phone (e.g. +2250777471485). Canonical join key (#56). Populated by the backend; absent on pre-migration docs. |
1947
2045
  | status | OutboundMessageStatus | yes | Delivery status. Created as `queued` by the dashboard; updated in place by the backend. |
1948
2046
  | wamid | ['string', 'null'] | no | (Read-only) WhatsApp message ID returned by Meta once the backend sends. Absent while queued or on failure. |
1949
2047
  | error | ['string', 'null'] | no | (Read-only) Human-readable failure reason. Present on status=failed. Raw Meta error detail lives in the lifecycle_events subcollection. |
@@ -1968,6 +2066,7 @@ Example:
1968
2066
  "uid": "user_u8x92kqm"
1969
2067
  },
1970
2068
  "createdAt": "createdAt",
2069
+ "contactE164": null,
1971
2070
  "status": "status",
1972
2071
  "wamid": null,
1973
2072
  "error": null,