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

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 +6 -3
  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 +2 -2
  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 +2 -2
  76. package/data/docs/models/whatsapp-outbound-lifecycle-event.md +2 -2
  77. package/data/docs/models/whatsapp-outbound-message.md +2 -2
  78. package/data/docs/models/whatsapp-template.md +2 -2
  79. package/data/static/llms.txt +97 -5
  80. package/data/static/openapi.yaml +370 -9
  81. package/data/static/schemas.json +347 -9
  82. package/package.json +1 -1
@@ -109,6 +109,15 @@ components:
109
109
  - COMPLETED
110
110
  description: Ticketed event lifecycle (D32). Mobile-only today; Dashboard in
111
111
  Wave 4.
112
+ ExpensePaymentStatus:
113
+ type: string
114
+ enum:
115
+ - PENDING
116
+ - PARTIALLY_PAID
117
+ - PAID
118
+ - FAILED
119
+ description: Payment status of an Expense. Stored enum — OVERDUE is not stored,
120
+ it is derived at read time from dueDate (#13).
112
121
  FulfillmentStatus:
113
122
  type: string
114
123
  enum:
@@ -222,7 +231,11 @@ components:
222
231
  - PAYPAL
223
232
  - STRIPE
224
233
  - OTHER
225
- description: Unified payment method set with African + global methods (D02).
234
+ - OM
235
+ description: 'Unified payment method set with African + global methods (D02).
236
+ Note: the metrics writer historically emits "OM" instead of "ORANGE_MONEY"
237
+ as a paymentsByMethod map key — treat OM as deprecated; canonical value is
238
+ ORANGE_MONEY (#21).'
226
239
  PaymentProofStatus:
227
240
  type: string
228
241
  enum:
@@ -2223,7 +2236,10 @@ components:
2223
2236
  notes (#10).'
2224
2237
  paymentMethod:
2225
2238
  $ref: '#/components/schemas/PaymentMethod'
2226
- description: Unified payment method set with African + global methods (D02).
2239
+ description: 'Unified payment method set with African + global methods (D02).
2240
+ Note: the metrics writer historically emits "OM" instead of "ORANGE_MONEY"
2241
+ as a paymentsByMethod map key — treat OM as deprecated; canonical value
2242
+ is ORANGE_MONEY (#21).'
2227
2243
  referenceNumber:
2228
2244
  type: string
2229
2245
  description: Unique payment reference (receipt number, transaction ID, etc.).
@@ -2520,6 +2536,146 @@ components:
2520
2536
  - $ref: '#/components/schemas/Event'
2521
2537
  description: Write payload for partial update (PATCH) of a Event document. All
2522
2538
  fields optional. Fields marked `readOnly` or `x-immutable` must not be sent.
2539
+ Expense:
2540
+ type: object
2541
+ properties:
2542
+ id:
2543
+ readOnly: true
2544
+ description: (Read-only) Firestore document ID, auto-generated.
2545
+ type:
2546
+ - string
2547
+ - 'null'
2548
+ companyId:
2549
+ type: string
2550
+ x-immutable: true
2551
+ description: (Immutable) FK → Company document ID.
2552
+ title:
2553
+ type: string
2554
+ description: Human-readable expense title (e.g. "Loyer mars 2026", "Facture
2555
+ EAU").
2556
+ description:
2557
+ description: Optional longer description or notes.
2558
+ type:
2559
+ - string
2560
+ - 'null'
2561
+ amount:
2562
+ type: number
2563
+ description: Total expense amount (XOF).
2564
+ currency:
2565
+ type: string
2566
+ const: XOF
2567
+ description: Currency code. Locked to XOF.
2568
+ dueDate:
2569
+ anyOf:
2570
+ - $ref: '#/components/schemas/FirestoreTimestamp'
2571
+ - type: 'null'
2572
+ description: When the expense is due. Used to compute OVERDUE state at read
2573
+ time (not stored in paymentStatus).
2574
+ paymentStatus:
2575
+ $ref: '#/components/schemas/ExpensePaymentStatus'
2576
+ x-note: 'OVERDUE is intentionally excluded — it is never stored in Firestore.
2577
+ Compute it at read time: expense.paymentStatus !== PAID && expense.dueDate
2578
+ < now() (#13). Helper: isExpenseOverdue(expense: Expense): boolean.'
2579
+ description: Current payment status. OVERDUE is never stored — derive from
2580
+ dueDate at read time (#13).
2581
+ amountDue:
2582
+ x-note: Authoritative for simple (non-allocation) expenses. Legacy field
2583
+ maintained for backward compatibility when no OutboundPaymentAllocation
2584
+ records exist (#12).
2585
+ description: Amount still owed. Authoritative when no OutboundPaymentAllocation
2586
+ records exist for this expense.
2587
+ type:
2588
+ - number
2589
+ - 'null'
2590
+ amountPaid:
2591
+ description: Amount paid to date (simple tracking, no allocations).
2592
+ type:
2593
+ - number
2594
+ - 'null'
2595
+ allocatedAmount:
2596
+ readOnly: true
2597
+ x-note: Server-set — computed from OutboundPaymentAllocation records. Clients
2598
+ must never write this field (#12).
2599
+ description: (Read-only) Total amount allocated via OutboundPaymentAllocation
2600
+ records. Authoritative when allocations exist.
2601
+ type:
2602
+ - number
2603
+ - 'null'
2604
+ balance:
2605
+ readOnly: true
2606
+ x-note: Server-set — computed as amount - allocatedAmount. Authoritative
2607
+ remaining amount when allocations exist. Prefer this over amountDue when
2608
+ OutboundPaymentAllocation records are present (#12).
2609
+ description: '(Read-only) Remaining balance: amount minus allocatedAmount.
2610
+ Authoritative when OutboundPaymentAllocation records exist.'
2611
+ type:
2612
+ - number
2613
+ - 'null'
2614
+ paidDate:
2615
+ anyOf:
2616
+ - $ref: '#/components/schemas/FirestoreTimestamp'
2617
+ - type: 'null'
2618
+ x-when: Set when paymentStatus transitions to PAID (fully settled). Null
2619
+ for partially paid or unpaid expenses. For multi-payment history, read
2620
+ OutboundPaymentAllocation records (#19).
2621
+ description: When the expense was fully settled (paymentStatus = PAID).
2622
+ Null otherwise.
2623
+ paymentReference:
2624
+ x-note: Reference for the most recent payment transaction (check number,
2625
+ wire ID, Wave ref, etc.). Overwritten on each payment. For full payment
2626
+ history read OutboundPaymentAllocation records (#19).
2627
+ description: Most recent payment transaction reference. Overwritten on each
2628
+ payment; not a full history.
2629
+ type:
2630
+ - string
2631
+ - 'null'
2632
+ createdBy:
2633
+ type: string
2634
+ x-immutable: true
2635
+ description: (Immutable) FK → User/staff UID who created this expense record.
2636
+ createdAt:
2637
+ anyOf:
2638
+ - $ref: '#/components/schemas/FirestoreTimestamp'
2639
+ - type: 'null'
2640
+ readOnly: true
2641
+ description: (Read-only) Server-generated creation timestamp.
2642
+ updatedAt:
2643
+ anyOf:
2644
+ - $ref: '#/components/schemas/FirestoreTimestamp'
2645
+ - type: 'null'
2646
+ readOnly: true
2647
+ description: (Read-only) Server-generated last-update timestamp.
2648
+ required:
2649
+ - companyId
2650
+ - title
2651
+ - amount
2652
+ - currency
2653
+ - paymentStatus
2654
+ - createdBy
2655
+ additionalProperties: false
2656
+ description: 'Expense (GH#12/#13/#19 partial). Collection: companies/{companyId}/expenses/{expenseId}.
2657
+ Dual balance tracking: amountPaid/amountDue for simple expenses; allocatedAmount/balance
2658
+ (server-set) for allocation-settled expenses. OVERDUE excluded from stored
2659
+ enum — derive at read time. Full domain (Payee FK, Contract FK) in #20.'
2660
+ ExpenseCreate:
2661
+ allOf:
2662
+ - $ref: '#/components/schemas/Expense'
2663
+ description: Write payload for creating a new Expense document. Fields marked
2664
+ `readOnly` are server-set and must not be included. Fields marked `x-immutable`
2665
+ may be set once at creation.
2666
+ required:
2667
+ - companyId
2668
+ - title
2669
+ - amount
2670
+ - currency
2671
+ - paymentStatus
2672
+ - createdBy
2673
+ ExpenseUpdate:
2674
+ allOf:
2675
+ - $ref: '#/components/schemas/Expense'
2676
+ description: Write payload for partial update (PATCH) of a Expense document.
2677
+ All fields optional. Fields marked `readOnly` or `x-immutable` must not be
2678
+ sent.
2523
2679
  LoyaltyConfig:
2524
2680
  type: object
2525
2681
  properties:
@@ -3006,6 +3162,9 @@ components:
3006
3162
  orderCompletionRate30d:
3007
3163
  type: number
3008
3164
  readOnly: true
3165
+ x-note: Firestore REST API v1 writes integerValue when the stored value
3166
+ is whole (e.g. 0), doubleValue when fractional (e.g. 82.17). Admin SDK
3167
+ smooths this to a JS number; REST clients must coerce the union (#11).
3009
3168
  description: (Read-only) Percentage of orders completed or delivered in
3010
3169
  the last 30 days. Always full recalc.
3011
3170
  todayPurchasesCount:
@@ -3022,11 +3181,16 @@ components:
3022
3181
  averagePurchaseAmount:
3023
3182
  type: number
3024
3183
  readOnly: true
3184
+ x-note: Firestore REST API v1 writes integerValue when whole (e.g. 10070),
3185
+ doubleValue when fractional (e.g. 10006.5). Admin SDK smooths this; REST
3186
+ clients must coerce (#11).
3025
3187
  description: (Read-only) Average purchase value across last 200 purchases
3026
3188
  (rolling, not time-windowed).
3027
3189
  monthlyRevenue:
3028
3190
  type: number
3029
3191
  readOnly: true
3192
+ x-note: Observed as integerValue on all sampled tenants (whole XOF amounts).
3193
+ Will be doubleValue if fractional. REST clients must coerce (#11).
3030
3194
  description: (Read-only) Total purchase value in the current calendar month
3031
3195
  (UTC).
3032
3196
  monthlyPurchasesCount:
@@ -3063,6 +3227,8 @@ components:
3063
3227
  todayCollectedAmount:
3064
3228
  type: number
3065
3229
  readOnly: true
3230
+ x-note: Observed as integerValue "0" on all sampled tenants. Will be doubleValue
3231
+ if fractional payments occur. REST clients must coerce (#11).
3066
3232
  description: (Read-only) Sum of totalAmount for bookings where PAYMENT_PAID_AT
3067
3233
  is today. Resets at midnight.
3068
3234
  todayRevenue:
@@ -3108,6 +3274,8 @@ components:
3108
3274
  averageRating:
3109
3275
  type: number
3110
3276
  readOnly: true
3277
+ x-note: Observed as integerValue "0" on all tenants (no reviews yet). Will
3278
+ be doubleValue once real ratings exist. REST clients must coerce (#11).
3111
3279
  description: (Read-only) Average rating from the last 200 reviews (rolling).
3112
3280
  Always full recalc.
3113
3281
  lowStockItemsCount:
@@ -3255,6 +3423,9 @@ components:
3255
3423
  orderCompletionRate30d:
3256
3424
  type: number
3257
3425
  readOnly: true
3426
+ x-note: Firestore REST API v1 writes integerValue when the stored value
3427
+ is whole (e.g. 0), doubleValue when fractional (e.g. 82.17). Admin SDK
3428
+ smooths this to a JS number; REST clients must coerce the union (#11).
3258
3429
  description: (Read-only) Percentage of orders completed or delivered in
3259
3430
  the last 30 days. Always full recalc.
3260
3431
  todayPurchasesCount:
@@ -3271,11 +3442,16 @@ components:
3271
3442
  averagePurchaseAmount:
3272
3443
  type: number
3273
3444
  readOnly: true
3445
+ x-note: Firestore REST API v1 writes integerValue when whole (e.g. 10070),
3446
+ doubleValue when fractional (e.g. 10006.5). Admin SDK smooths this; REST
3447
+ clients must coerce (#11).
3274
3448
  description: (Read-only) Average purchase value across last 200 purchases
3275
3449
  (rolling, not time-windowed).
3276
3450
  monthlyRevenue:
3277
3451
  type: number
3278
3452
  readOnly: true
3453
+ x-note: Observed as integerValue on all sampled tenants (whole XOF amounts).
3454
+ Will be doubleValue if fractional. REST clients must coerce (#11).
3279
3455
  description: (Read-only) Total purchase value in the current calendar month
3280
3456
  (UTC).
3281
3457
  monthlyPurchasesCount:
@@ -3312,6 +3488,8 @@ components:
3312
3488
  todayCollectedAmount:
3313
3489
  type: number
3314
3490
  readOnly: true
3491
+ x-note: Observed as integerValue "0" on all sampled tenants. Will be doubleValue
3492
+ if fractional payments occur. REST clients must coerce (#11).
3315
3493
  description: (Read-only) Sum of totalAmount for bookings where PAYMENT_PAID_AT
3316
3494
  is today. Resets at midnight.
3317
3495
  todayRevenue:
@@ -3357,6 +3535,8 @@ components:
3357
3535
  averageRating:
3358
3536
  type: number
3359
3537
  readOnly: true
3538
+ x-note: Observed as integerValue "0" on all tenants (no reviews yet). Will
3539
+ be doubleValue once real ratings exist. REST clients must coerce (#11).
3360
3540
  description: (Read-only) Average rating from the last 200 reviews (rolling).
3361
3541
  Always full recalc.
3362
3542
  lowStockItemsCount:
@@ -3423,17 +3603,34 @@ components:
3423
3603
  maximum: 9007199254740991
3424
3604
  paymentsByMethod:
3425
3605
  readOnly: true
3426
- x-note: Always {} until the first real payment is recorded. Present on all
3427
- tenants once rewritten by current aggregator (#8).
3428
- description: (Read-only, Optional) Map of PaymentMethod total amount for
3429
- the current day. Empty map {} until first payment.
3606
+ x-note: Map keys use short codes in practice (OM, CASH, WAVE) OM is a
3607
+ non-canonical alias for ORANGE_MONEY emitted by the metrics writer (#21).
3608
+ Value shape { total, count } differs from MetricsCurrent.paymentsByMethod
3609
+ (bare number).
3610
+ description: '(Read-only, Optional) Payment breakdown by method for the
3611
+ day. Keys are PaymentMethod values (or legacy short code OM). Value is
3612
+ { total: XOF amount, count: number of payments }.'
3430
3613
  type:
3431
3614
  - object
3432
3615
  - 'null'
3433
3616
  propertyNames:
3434
3617
  type: string
3435
3618
  additionalProperties:
3436
- type: number
3619
+ type: object
3620
+ properties:
3621
+ total:
3622
+ type: number
3623
+ description: Sum of payment amounts for this method on the given day
3624
+ (XOF).
3625
+ count:
3626
+ type: integer
3627
+ minimum: -9007199254740991
3628
+ maximum: 9007199254740991
3629
+ description: Number of payments using this method on the given day.
3630
+ required:
3631
+ - total
3632
+ - count
3633
+ additionalProperties: false
3437
3634
  computedForDay:
3438
3635
  type: string
3439
3636
  readOnly: true
@@ -3476,9 +3673,17 @@ components:
3476
3673
  - generatedAt
3477
3674
  - date
3478
3675
  additionalProperties: false
3676
+ x-note: 'Zero-activity behavior (#9): the computeDailyCompanyMetrics cron (02:00
3677
+ UTC) does NOT write a snapshot for days with no activity. A missing document
3678
+ means either zero activity or the cron did not run — consumers cannot distinguish
3679
+ the two from the absence alone. To detect cron gaps, compare the latest document
3680
+ date with today; a gap larger than 1 day on an otherwise active tenant indicates
3681
+ a cron failure. Observed: 3 of 4 zahoui tenants had gaps; bingerville (active)
3682
+ had a document every day.'
3479
3683
  description: 'Daily metrics snapshot. Collection: companies/{companyId}/metrics_daily/{YYYY-MM-DD}.
3480
3684
  Same fields as MetricsCurrent plus `date`. Written by computeDailyCompanyMetrics
3481
- cron (02:00 UTC) and inline after full recalcs.'
3685
+ cron (02:00 UTC) when the company had activity that day; zero-activity days
3686
+ may produce no document (#9).'
3482
3687
  MetricsDailyCreate:
3483
3688
  allOf:
3484
3689
  - $ref: '#/components/schemas/MetricsDaily'
@@ -3510,6 +3715,9 @@ components:
3510
3715
  orderCompletionRate30d:
3511
3716
  type: number
3512
3717
  readOnly: true
3718
+ x-note: Firestore REST API v1 writes integerValue when the stored value
3719
+ is whole (e.g. 0), doubleValue when fractional (e.g. 82.17). Admin SDK
3720
+ smooths this to a JS number; REST clients must coerce the union (#11).
3513
3721
  description: (Read-only) Percentage of orders completed or delivered in
3514
3722
  the last 30 days. Always full recalc.
3515
3723
  todayPurchasesCount:
@@ -3526,11 +3734,16 @@ components:
3526
3734
  averagePurchaseAmount:
3527
3735
  type: number
3528
3736
  readOnly: true
3737
+ x-note: Firestore REST API v1 writes integerValue when whole (e.g. 10070),
3738
+ doubleValue when fractional (e.g. 10006.5). Admin SDK smooths this; REST
3739
+ clients must coerce (#11).
3529
3740
  description: (Read-only) Average purchase value across last 200 purchases
3530
3741
  (rolling, not time-windowed).
3531
3742
  monthlyRevenue:
3532
3743
  type: number
3533
3744
  readOnly: true
3745
+ x-note: Observed as integerValue on all sampled tenants (whole XOF amounts).
3746
+ Will be doubleValue if fractional. REST clients must coerce (#11).
3534
3747
  description: (Read-only) Total purchase value in the current calendar month
3535
3748
  (UTC).
3536
3749
  monthlyPurchasesCount:
@@ -3567,6 +3780,8 @@ components:
3567
3780
  todayCollectedAmount:
3568
3781
  type: number
3569
3782
  readOnly: true
3783
+ x-note: Observed as integerValue "0" on all sampled tenants. Will be doubleValue
3784
+ if fractional payments occur. REST clients must coerce (#11).
3570
3785
  description: (Read-only) Sum of totalAmount for bookings where PAYMENT_PAID_AT
3571
3786
  is today. Resets at midnight.
3572
3787
  todayRevenue:
@@ -3612,6 +3827,8 @@ components:
3612
3827
  averageRating:
3613
3828
  type: number
3614
3829
  readOnly: true
3830
+ x-note: Observed as integerValue "0" on all tenants (no reviews yet). Will
3831
+ be doubleValue once real ratings exist. REST clients must coerce (#11).
3615
3832
  description: (Read-only) Average rating from the last 200 reviews (rolling).
3616
3833
  Always full recalc.
3617
3834
  lowStockItemsCount:
@@ -4061,7 +4278,10 @@ components:
4061
4278
  anyOf:
4062
4279
  - $ref: '#/components/schemas/PaymentMethod'
4063
4280
  - type: 'null'
4064
- description: Unified payment method set with African + global methods (D02).
4281
+ description: 'Unified payment method set with African + global methods (D02).
4282
+ Note: the metrics writer historically emits "OM" instead of "ORANGE_MONEY"
4283
+ as a paymentsByMethod map key — treat OM as deprecated; canonical value
4284
+ is ORANGE_MONEY (#21).'
4065
4285
  invoiceId:
4066
4286
  description: FK → Invoice document ID.
4067
4287
  type:
@@ -4659,6 +4879,147 @@ components:
4659
4879
  description: Write payload for partial update (PATCH) of a OutboundPaymentAllocation
4660
4880
  document. All fields optional. Fields marked `readOnly` or `x-immutable` must
4661
4881
  not be sent.
4882
+ PaymentWebhookDelivery:
4883
+ type: object
4884
+ properties:
4885
+ id:
4886
+ readOnly: true
4887
+ description: (Read-only) Firestore document ID, auto-generated.
4888
+ type:
4889
+ - string
4890
+ - 'null'
4891
+ company:
4892
+ type: string
4893
+ x-immutable: true
4894
+ description: (Immutable) Company document ID (e.g. "gerko_studios"). Resolved
4895
+ from the matched endpoint at delivery time.
4896
+ provider:
4897
+ type: string
4898
+ x-note: 'Observed value: "jeko". The inner payload.paymentMethod may differ
4899
+ (e.g. "wave") — provider here is the webhook sender, not the payment rail
4900
+ (#42).'
4901
+ description: Payment provider that sent this webhook (e.g. "jeko", "wave").
4902
+ eventType:
4903
+ type: string
4904
+ x-note: 'Observed value: "transaction.payment". Jeko docs say "transaction.completed"
4905
+ — full set per provider unconfirmed (#42). Use z.string() to avoid rejecting
4906
+ unseen values.'
4907
+ description: 'Provider-defined event type. Observed: "transaction.payment".
4908
+ Full set per provider TBD (#42).'
4909
+ status:
4910
+ type: string
4911
+ x-note: 'Observed values: "success", "error". Indicates whether the webhook
4912
+ was processed without errors.'
4913
+ description: 'Processing outcome. Observed values: "success" | "error".'
4914
+ verified:
4915
+ type: string
4916
+ x-note: 'Observed value: "verified". Indicates HMAC-SHA256 signature verification
4917
+ result. Full set of failure values unconfirmed (#42).'
4918
+ description: 'Signature verification result. Observed: "verified". Other
4919
+ values (e.g. "unverified", "error") may exist but are unconfirmed.'
4920
+ endpointStatus:
4921
+ type: string
4922
+ x-note: 'Observed value: "matched". Indicates whether the token resolved
4923
+ to a known PaymentWebhookEndpoint. Other values (e.g. "not_found", "inactive")
4924
+ unconfirmed (#42).'
4925
+ description: 'Endpoint resolution result. Observed: "matched". Other values
4926
+ unconfirmed (#42).'
4927
+ processed:
4928
+ type: boolean
4929
+ x-note: Set to true once the delivery has been reconciled to the AppPayment
4930
+ ledger (companies/{cid}/apps/{appId}/payments). Back-reference FK not
4931
+ stored on this doc — reconciliation is tracked on the AppPayment side.
4932
+ description: Whether this delivery has been reconciled to the AppPayment
4933
+ ledger.
4934
+ reference:
4935
+ type: string
4936
+ x-note: Equals payload.id (provider transaction ID). Used as dedup key —
4937
+ the backend checks this before processing (#42 ask 3).
4938
+ description: Provider transaction ID (= payload.id). Canonical dedup key.
4939
+ amount:
4940
+ type: number
4941
+ description: Payment amount, denormalized from payload.amount.amount (XOF).
4942
+ currency:
4943
+ type: string
4944
+ description: Currency code, denormalized from payload.amount.currency (e.g.
4945
+ "XOF").
4946
+ payload:
4947
+ type: object
4948
+ propertyNames:
4949
+ type: string
4950
+ additionalProperties: {}
4951
+ x-note: 'Parsed provider request body. Contains PII: counterpartIdentifier
4952
+ and counterpartLabel hold customer phone numbers. Retention/TTL policy
4953
+ TBD (#42 ask 5).'
4954
+ description: Full parsed provider payload. Shape varies by provider. Contains
4955
+ PII (customer phone). See x-note for retention policy status.
4956
+ rawBody:
4957
+ type: string
4958
+ x-note: Verbatim request body string used for HMAC-SHA256 signature verification.
4959
+ Contains same PII as payload. Retention/TTL policy TBD (#42 ask 5).
4960
+ description: Verbatim raw request body — used for HMAC-SHA256 verification.
4961
+ Contains PII.
4962
+ headers:
4963
+ x-note: Request headers including provider signature (e.g. "jeko-signature")
4964
+ and tracing headers. Sensitive — do not expose to clients.
4965
+ description: Incoming HTTP headers. Includes provider signature header and
4966
+ Sentry trace. Sensitive.
4967
+ type:
4968
+ - object
4969
+ - 'null'
4970
+ propertyNames:
4971
+ type: string
4972
+ additionalProperties:
4973
+ type: string
4974
+ receivedAt:
4975
+ $ref: '#/components/schemas/FirestoreTimestamp'
4976
+ description: When the webhook delivery was received by the backend.
4977
+ required:
4978
+ - company
4979
+ - provider
4980
+ - eventType
4981
+ - status
4982
+ - verified
4983
+ - endpointStatus
4984
+ - processed
4985
+ - reference
4986
+ - amount
4987
+ - currency
4988
+ - payload
4989
+ - rawBody
4990
+ - receivedAt
4991
+ additionalProperties: false
4992
+ x-internal: true
4993
+ description: 'PaymentWebhookDelivery (GH#42). Collection: payment_webhooks/{deliveryId}
4994
+ (top-level). One document per received provider callback. Contains raw payload
4995
+ + verification outcome. x-internal: written/read only by backend; dashboard
4996
+ reads via admin UI. PII in payload/rawBody — retention policy TBD.'
4997
+ PaymentWebhookDeliveryCreate:
4998
+ allOf:
4999
+ - $ref: '#/components/schemas/PaymentWebhookDelivery'
5000
+ description: Write payload for creating a new PaymentWebhookDelivery document.
5001
+ Fields marked `readOnly` are server-set and must not be included. Fields marked
5002
+ `x-immutable` may be set once at creation.
5003
+ required:
5004
+ - company
5005
+ - provider
5006
+ - eventType
5007
+ - status
5008
+ - verified
5009
+ - endpointStatus
5010
+ - processed
5011
+ - reference
5012
+ - amount
5013
+ - currency
5014
+ - payload
5015
+ - rawBody
5016
+ - receivedAt
5017
+ PaymentWebhookDeliveryUpdate:
5018
+ allOf:
5019
+ - $ref: '#/components/schemas/PaymentWebhookDelivery'
5020
+ description: Write payload for partial update (PATCH) of a PaymentWebhookDelivery
5021
+ document. All fields optional. Fields marked `readOnly` or `x-immutable` must
5022
+ not be sent.
4662
5023
  PaymentWebhookEndpoint:
4663
5024
  type: object
4664
5025
  properties: