@ingenx-io/valets-schema-mcp-server 0.1.2 → 0.1.4

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 (44) hide show
  1. package/data/docs/collections/firestore-paths.md +22 -2
  2. package/data/docs/enums/attention-status.md +24 -0
  3. package/data/docs/enums/booking-status.md +2 -2
  4. package/data/docs/enums/customer-payment-status.md +2 -2
  5. package/data/docs/enums/customer-payment-target-type.md +2 -2
  6. package/data/docs/enums/delivery-type.md +2 -2
  7. package/data/docs/enums/event-status.md +2 -2
  8. package/data/docs/enums/fulfillment-status.md +2 -2
  9. package/data/docs/enums/loyalty-transaction-type.md +2 -2
  10. package/data/docs/enums/order-status.md +2 -2
  11. package/data/docs/enums/payment-method.md +2 -2
  12. package/data/docs/enums/payment-proof-status.md +2 -2
  13. package/data/docs/enums/payment-status.md +2 -2
  14. package/data/docs/enums/pending-issue.md +31 -0
  15. package/data/docs/enums/return-status.md +2 -2
  16. package/data/docs/enums/session-status.md +2 -2
  17. package/data/docs/enums/ticket-status.md +2 -2
  18. package/data/docs/index.md +15 -2
  19. package/data/docs/models/allowed-user.md +188 -0
  20. package/data/docs/models/analytics-event.md +533 -0
  21. package/data/docs/models/booking-version.md +2 -2
  22. package/data/docs/models/booking.md +2 -2
  23. package/data/docs/models/customer-payment-allocation.md +2 -2
  24. package/data/docs/models/customer-payment.md +2 -2
  25. package/data/docs/models/customer.md +2 -2
  26. package/data/docs/models/event.md +2 -2
  27. package/data/docs/models/loyalty-config.md +2 -2
  28. package/data/docs/models/loyalty-reward.md +2 -2
  29. package/data/docs/models/loyalty-status.md +2 -2
  30. package/data/docs/models/loyalty-transaction.md +2 -2
  31. package/data/docs/models/magic-link-request.md +285 -0
  32. package/data/docs/models/metrics-current.md +2 -2
  33. package/data/docs/models/metrics-daily.md +2 -2
  34. package/data/docs/models/metrics-monthly.md +2 -2
  35. package/data/docs/models/order-item.md +2 -2
  36. package/data/docs/models/order.md +2 -2
  37. package/data/docs/models/payment-summary.md +123 -0
  38. package/data/docs/models/sale.md +2 -2
  39. package/data/docs/models/site-payment.md +200 -0
  40. package/data/docs/models/ticket.md +2 -2
  41. package/data/static/llms.txt +174 -1
  42. package/data/static/openapi.yaml +451 -0
  43. package/data/static/schemas.json +511 -1
  44. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: "LoyaltyReward"
3
3
  sidebar_label: "LoyaltyReward"
4
- sidebar_position: 8
4
+ sidebar_position: 10
5
5
  ---
6
6
 
7
7
  # LoyaltyReward
@@ -229,7 +229,7 @@ Do not include in write requests. This field is set exclusively by the server (F
229
229
  | **Required** | No |
230
230
 
231
231
  ----------------------------------------------------------------------------------------------------------------------------
232
- Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-03-09 at 13:15:53 +0000
232
+ Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-04-18 at 21:21:09 +0000
233
233
 
234
234
  :::warning Server-set
235
235
  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: "LoyaltyStatus"
3
3
  sidebar_label: "LoyaltyStatus"
4
- sidebar_position: 9
4
+ sidebar_position: 11
5
5
  ---
6
6
 
7
7
  # LoyaltyStatus
@@ -315,7 +315,7 @@ Do not include in write requests. This field is set exclusively by the server (F
315
315
  | **Required** | No |
316
316
 
317
317
  ----------------------------------------------------------------------------------------------------------------------------
318
- Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-03-09 at 13:15:53 +0000
318
+ Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-04-18 at 21:21:09 +0000
319
319
 
320
320
  :::warning Server-set
321
321
  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: "LoyaltyTransaction"
3
3
  sidebar_label: "LoyaltyTransaction"
4
- sidebar_position: 10
4
+ sidebar_position: 12
5
5
  ---
6
6
 
7
7
  # LoyaltyTransaction
@@ -313,7 +313,7 @@ Set at creation only. This field cannot be modified after the document is create
313
313
  **Description:** (Immutable, Denormalized) From User display name at creation time.
314
314
 
315
315
  ----------------------------------------------------------------------------------------------------------------------------
316
- Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-03-09 at 13:15:53 +0000
316
+ Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-04-18 at 21:21:09 +0000
317
317
 
318
318
  :::info Immutable
319
319
  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.
@@ -0,0 +1,285 @@
1
+ ---
2
+ title: "MagicLinkRequest"
3
+ sidebar_label: "MagicLinkRequest"
4
+ sidebar_position: 13
5
+ ---
6
+
7
+ # MagicLinkRequest
8
+
9
+ <details>
10
+ <summary>Example JSON</summary>
11
+
12
+ ```json
13
+ {
14
+ "id": null,
15
+ "companyId": "comp_xyz789",
16
+ "siteId": "sit_ref123",
17
+ "email": "amadou@example.com",
18
+ "phone": "+225 07 00 11 22",
19
+ "ip": "ip",
20
+ "allowed": true,
21
+ "link": "link",
22
+ "tier": "Gold",
23
+ "authStatusReason": "Customer request",
24
+ "referredBy": "referredBy",
25
+ "requestedAt": "requestedAt",
26
+ "verifyReason": null,
27
+ "verified": null,
28
+ "verifiedAt": "verifiedAt"
29
+ }
30
+ ```
31
+
32
+ </details>
33
+
34
+
35
+ - [1. Property `id`](#id)
36
+ - [2. Property `companyId`](#companyId)
37
+ - [3. Property `siteId`](#siteId)
38
+ - [4. Property `email`](#email)
39
+ - [5. Property `phone`](#phone)
40
+ - [6. Property `ip`](#ip)
41
+ - [7. Property `allowed`](#allowed)
42
+ - [8. Property `link`](#link)
43
+ - [9. Property `tier`](#tier)
44
+ - [10. Property `authStatusReason`](#authStatusReason)
45
+ - [11. Property `referredBy`](#referredBy)
46
+ - [12. Property `requestedAt`](#requestedAt)
47
+ - [12.1. Property `_seconds`](#requestedAt__seconds)
48
+ - [12.2. Property `_nanoseconds`](#requestedAt__nanoseconds)
49
+ - [13. Property `verifyReason`](#verifyReason)
50
+ - [14. Property `verified`](#verified)
51
+ - [15. Property `verifiedAt`](#verifiedAt)
52
+ - [15.1. Property `firestore-timestamp`](#verifiedAt_anyOf_i0)
53
+ - [15.2. Property `item 1`](#verifiedAt_anyOf_i1)
54
+
55
+ | | |
56
+ | ------------------------- | -------------------------------- |
57
+ | **Type** | `object` |
58
+ | **Required** | No |
59
+ | **Additional properties** | Not allowed |
60
+ | **Defined in** | #/definitions/magic-link-request |
61
+
62
+ **Description:** MagicLinkRequest model (D40 / ING-304). Collection: companies/\{companyId\}/sites/\{siteId\}/magic_link_requests/\{requestId\}. Authentication audit log — every request is logged regardless of outcome. Two-stage write: Log() then LogVerify().
63
+
64
+ | Property | Pattern | Type | Deprecated | Definition | Title/Description |
65
+ | ---------------------------------------- | ------- | --------------- | ---------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
66
+ | - [id](#id ) | No | string or null | No | - | (Read-only) Firestore document ID. 16-byte random hex. |
67
+ | + [companyId](#companyId ) | No | string | No | - | (Immutable) FK → Company document ID. |
68
+ | + [siteId](#siteId ) | No | string | No | - | (Immutable) FK → Site document ID (D40 sub-tenant scope). |
69
+ | + [email](#email ) | No | string | No | - | Populated if identifier is email; empty string if phone. Mutually exclusive with phone per document. |
70
+ | + [phone](#phone ) | No | string | No | - | Populated if identifier is E.164 format (starts with +); empty string if email. |
71
+ | + [ip](#ip ) | No | string | No | - | Client IP from X-Forwarded-For or RemoteAddr. |
72
+ | + [allowed](#allowed ) | No | boolean | No | - | Whether the user passed the access control check. |
73
+ | + [link](#link ) | No | string | No | - | Magic-link URL — non-empty only when DEV_MODE=true; empty in production (audit integrity). |
74
+ | + [tier](#tier ) | No | string | No | - | Access tier selected by the user. Free string per site (ING-304 open question — tier values are site-specific today). |
75
+ | + [authStatusReason](#authStatusReason ) | No | string | No | - | Outcome reason code: whitelist \| allowed_users \| payment_redirect \| payment_complete \| not_allowed \| redirected_to_payment. |
76
+ | + [referredBy](#referredBy ) | No | string | No | - | Contact identifier of the referrer, resolved from submitted referral_code; empty if none. |
77
+ | + [requestedAt](#requestedAt ) | No | object | No | In #/definitions/firestore-timestamp | RFC3339Nano UTC at request time. |
78
+ | - [verifyReason](#verifyReason ) | No | string or null | No | - | Verify outcome reason: mirrors authStatusReason on success, or link_expired \| link_invalid \| not_allowed. |
79
+ | - [verified](#verified ) | No | boolean or null | No | - | Whether the verify attempt succeeded. |
80
+ | - [verifiedAt](#verifiedAt ) | No | Combination | No | - | RFC3339Nano UTC at verify time. |
81
+
82
+ ## <a name="id"></a>1. Property `id`
83
+
84
+ | | |
85
+ | ------------ | ---------------- |
86
+ | **Type** | `string or null` |
87
+ | **Required** | No |
88
+
89
+ **Description:** (Read-only) Firestore document ID. 16-byte random hex.
90
+
91
+ :::warning Server-set
92
+ 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.
93
+ :::
94
+
95
+ ## <a name="companyId"></a>2. Property `companyId`
96
+
97
+ | | |
98
+ | ------------ | -------- |
99
+ | **Type** | `string` |
100
+ | **Required** | Yes |
101
+
102
+ **Description:** (Immutable) FK → Company document ID.
103
+
104
+ :::info Immutable
105
+ 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.
106
+ :::
107
+
108
+ ## <a name="siteId"></a>3. Property `siteId`
109
+
110
+ | | |
111
+ | ------------ | -------- |
112
+ | **Type** | `string` |
113
+ | **Required** | Yes |
114
+
115
+ **Description:** (Immutable) FK → Site document ID (D40 sub-tenant scope).
116
+
117
+ :::info Immutable
118
+ 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.
119
+ :::
120
+
121
+ ## <a name="email"></a>4. Property `email`
122
+
123
+ | | |
124
+ | ------------ | -------- |
125
+ | **Type** | `string` |
126
+ | **Required** | Yes |
127
+
128
+ **Description:** Populated if identifier is email; empty string if phone. Mutually exclusive with phone per document.
129
+
130
+ ## <a name="phone"></a>5. Property `phone`
131
+
132
+ | | |
133
+ | ------------ | -------- |
134
+ | **Type** | `string` |
135
+ | **Required** | Yes |
136
+
137
+ **Description:** Populated if identifier is E.164 format (starts with +); empty string if email.
138
+
139
+ ## <a name="ip"></a>6. Property `ip`
140
+
141
+ | | |
142
+ | ------------ | -------- |
143
+ | **Type** | `string` |
144
+ | **Required** | Yes |
145
+
146
+ **Description:** Client IP from X-Forwarded-For or RemoteAddr.
147
+
148
+ ## <a name="allowed"></a>7. Property `allowed`
149
+
150
+ | | |
151
+ | ------------ | --------- |
152
+ | **Type** | `boolean` |
153
+ | **Required** | Yes |
154
+
155
+ **Description:** Whether the user passed the access control check.
156
+
157
+ ## <a name="link"></a>8. Property `link`
158
+
159
+ | | |
160
+ | ------------ | -------- |
161
+ | **Type** | `string` |
162
+ | **Required** | Yes |
163
+
164
+ **Description:** Magic-link URL — non-empty only when DEV_MODE=true; empty in production (audit integrity).
165
+
166
+ ## <a name="tier"></a>9. Property `tier`
167
+
168
+ | | |
169
+ | ------------ | -------- |
170
+ | **Type** | `string` |
171
+ | **Required** | Yes |
172
+
173
+ **Description:** Access tier selected by the user. Free string per site (ING-304 open question — tier values are site-specific today).
174
+
175
+ ## <a name="authStatusReason"></a>10. Property `authStatusReason`
176
+
177
+ | | |
178
+ | ------------ | -------- |
179
+ | **Type** | `string` |
180
+ | **Required** | Yes |
181
+
182
+ **Description:** Outcome reason code: whitelist | allowed_users | payment_redirect | payment_complete | not_allowed | redirected_to_payment.
183
+
184
+ ## <a name="referredBy"></a>11. Property `referredBy`
185
+
186
+ | | |
187
+ | ------------ | -------- |
188
+ | **Type** | `string` |
189
+ | **Required** | Yes |
190
+
191
+ **Description:** Contact identifier of the referrer, resolved from submitted referral_code; empty if none.
192
+
193
+ ## <a name="requestedAt"></a>12. Property `requestedAt`
194
+
195
+ | | |
196
+ | ------------------------- | --------------------------------- |
197
+ | **Type** | `object` |
198
+ | **Required** | Yes |
199
+ | **Additional properties** | Not allowed |
200
+ | **Defined in** | #/definitions/firestore-timestamp |
201
+
202
+ **Description:** RFC3339Nano UTC at request time.
203
+
204
+ | Property | Pattern | Type | Deprecated | Definition | Title/Description |
205
+ | -------------------------------------------- | ------- | ------- | ---------- | ---------- | ----------------- |
206
+ | + [_seconds](#requestedAt__seconds ) | No | integer | No | - | - |
207
+ | + [_nanoseconds](#requestedAt__nanoseconds ) | No | integer | No | - | - |
208
+
209
+ ### <a name="requestedAt__seconds"></a>12.1. Property `_seconds`
210
+
211
+ | | |
212
+ | ------------ | --------- |
213
+ | **Type** | `integer` |
214
+ | **Required** | Yes |
215
+
216
+ | Restrictions | |
217
+ | ------------ | ---------------------- |
218
+ | **Minimum** | &ge; -9007199254740991 |
219
+ | **Maximum** | &le; 9007199254740991 |
220
+
221
+ ### <a name="requestedAt__nanoseconds"></a>12.2. Property `_nanoseconds`
222
+
223
+ | | |
224
+ | ------------ | --------- |
225
+ | **Type** | `integer` |
226
+ | **Required** | Yes |
227
+
228
+ | Restrictions | |
229
+ | ------------ | ---------------------- |
230
+ | **Minimum** | &ge; -9007199254740991 |
231
+ | **Maximum** | &le; 9007199254740991 |
232
+
233
+ ## <a name="verifyReason"></a>13. Property `verifyReason`
234
+
235
+ | | |
236
+ | ------------ | ---------------- |
237
+ | **Type** | `string or null` |
238
+ | **Required** | No |
239
+
240
+ **Description:** Verify outcome reason: mirrors authStatusReason on success, or link_expired | link_invalid | not_allowed.
241
+
242
+ ## <a name="verified"></a>14. Property `verified`
243
+
244
+ | | |
245
+ | ------------ | ----------------- |
246
+ | **Type** | `boolean or null` |
247
+ | **Required** | No |
248
+
249
+ **Description:** Whether the verify attempt succeeded.
250
+
251
+ ## <a name="verifiedAt"></a>15. Property `verifiedAt`
252
+
253
+ | | |
254
+ | ------------------------- | ---------------- |
255
+ | **Type** | `combining` |
256
+ | **Required** | No |
257
+ | **Additional properties** | Any type allowed |
258
+
259
+ **Description:** RFC3339Nano UTC at verify time.
260
+
261
+ | Any of(Option) |
262
+ | ------------------------------------------- |
263
+ | [firestore-timestamp](#verifiedAt_anyOf_i0) |
264
+ | [item 1](#verifiedAt_anyOf_i1) |
265
+
266
+ ### <a name="verifiedAt_anyOf_i0"></a>15.1. Property `firestore-timestamp`
267
+
268
+ | | |
269
+ | ------------------------- | --------------------------- |
270
+ | **Type** | `object` |
271
+ | **Required** | No |
272
+ | **Additional properties** | Not allowed |
273
+ | **Same definition as** | [requestedAt](#requestedAt) |
274
+
275
+ **Description:** Firestore Timestamp serialized representation
276
+
277
+ ### <a name="verifiedAt_anyOf_i1"></a>15.2. Property `item 1`
278
+
279
+ | | |
280
+ | ------------ | ------ |
281
+ | **Type** | `null` |
282
+ | **Required** | No |
283
+
284
+ ----------------------------------------------------------------------------------------------------------------------------
285
+ Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-04-18 at 21:21:09 +0000
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: "MetricsCurrent"
3
3
  sidebar_label: "MetricsCurrent"
4
- sidebar_position: 11
4
+ sidebar_position: 14
5
5
  ---
6
6
 
7
7
  # MetricsCurrent
@@ -525,7 +525,7 @@ Do not include in write requests. This field is set exclusively by the server (F
525
525
  | **Maximum** | &le; 9007199254740991 |
526
526
 
527
527
  ----------------------------------------------------------------------------------------------------------------------------
528
- Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-03-09 at 13:15:53 +0000
528
+ Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-04-18 at 21:21:09 +0000
529
529
 
530
530
  :::warning Server-set
531
531
  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: "MetricsDaily"
3
3
  sidebar_label: "MetricsDaily"
4
- sidebar_position: 12
4
+ sidebar_position: 15
5
5
  ---
6
6
 
7
7
  # MetricsDaily
@@ -541,7 +541,7 @@ Do not include in write requests. This field is set exclusively by the server (F
541
541
  **Description:** (Read-only) YYYY-MM-DD document ID repeated as a field. Identifies the day this snapshot covers.
542
542
 
543
543
  ----------------------------------------------------------------------------------------------------------------------------
544
- Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-03-09 at 13:15:53 +0000
544
+ Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-04-18 at 21:21:09 +0000
545
545
 
546
546
  :::warning Server-set
547
547
  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: "MetricsMonthly"
3
3
  sidebar_label: "MetricsMonthly"
4
- sidebar_position: 13
4
+ sidebar_position: 16
5
5
  ---
6
6
 
7
7
  # MetricsMonthly
@@ -541,7 +541,7 @@ Do not include in write requests. This field is set exclusively by the server (F
541
541
  **Description:** (Read-only) YYYY-MM document ID repeated as a field. Identifies the month this rollup covers.
542
542
 
543
543
  ----------------------------------------------------------------------------------------------------------------------------
544
- Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-03-09 at 13:15:53 +0000
544
+ Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-04-18 at 21:21:09 +0000
545
545
 
546
546
  :::warning Server-set
547
547
  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: "OrderItem"
3
3
  sidebar_label: "OrderItem"
4
- sidebar_position: 15
4
+ sidebar_position: 18
5
5
  ---
6
6
 
7
7
  # OrderItem
@@ -350,7 +350,7 @@ TBD/WIP — Originally from the archived Couchbase Lite (CBL) restaurant flow. C
350
350
  | **Required** | No |
351
351
 
352
352
  ----------------------------------------------------------------------------------------------------------------------------
353
- Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-03-09 at 13:15:53 +0000
353
+ Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-04-18 at 21:21:09 +0000
354
354
 
355
355
  :::warning Server-set
356
356
  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: "Order"
3
3
  sidebar_label: "Order"
4
- sidebar_position: 14
4
+ sidebar_position: 17
5
5
  ---
6
6
 
7
7
  # Order
@@ -1624,7 +1624,7 @@ Set only by the mobile app when the user manually edits the order total. Dashboa
1624
1624
  **Description:** FK → Sale.id. Link to associated Sale document.
1625
1625
 
1626
1626
  ----------------------------------------------------------------------------------------------------------------------------
1627
- Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-03-09 at 13:15:53 +0000
1627
+ Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-04-18 at 21:21:09 +0000
1628
1628
 
1629
1629
  ## Related Decisions
1630
1630
 
@@ -0,0 +1,123 @@
1
+ ---
2
+ title: "PaymentSummary"
3
+ sidebar_label: "PaymentSummary"
4
+ sidebar_position: 99
5
+ ---
6
+
7
+ # PaymentSummary
8
+
9
+ **Collection:** `companies/{companyId}/paymentSummaries/{period}`
10
+
11
+ Aggregated payment totals broken down by payment method for a given period. This is a **server-owned, read-only** model — clients never write to it directly. It is maintained by Cloud Function triggers that fire on `Order.payments[]` and `CustomerPayment` changes.
12
+
13
+ ## Schema
14
+
15
+ <details>
16
+ <summary>Example JSON</summary>
17
+
18
+ ```json
19
+ {
20
+ "id": "2026-03-09",
21
+ "companyId": "comp_xyz789",
22
+ "period": "2026-03-09",
23
+ "periodType": "DAILY",
24
+ "paymentsByMethod": {
25
+ "CASH": { "total": 245000, "count": 12 },
26
+ "WAVE": { "total": 180000, "count": 8 },
27
+ "ORANGE_MONEY": { "total": 95000, "count": 5 }
28
+ },
29
+ "grandTotal": 520000,
30
+ "totalCount": 25,
31
+ "currency": "XOF",
32
+ "lastUpdatedAt": { "_seconds": 1741478400, "_nanoseconds": 0 },
33
+ "createdAt": { "_seconds": 1741435200, "_nanoseconds": 0 }
34
+ }
35
+ ```
36
+
37
+ </details>
38
+
39
+ ## Fields
40
+
41
+ | Field | Type | Required | Description |
42
+ |-------|------|----------|-------------|
43
+ | `id` | `string` | — | (Read-only) Document ID. Matches the period key. |
44
+ | `companyId` | `string` | + | (Immutable) FK → Company document ID. |
45
+ | `period` | `string` | + | Period key: `YYYY-MM-DD` (daily), `YYYY-Www` (weekly), `YYYY-MM` (monthly). |
46
+ | `periodType` | `enum` | + | `DAILY`, `WEEKLY`, or `MONTHLY`. |
47
+ | `paymentsByMethod` | `map` | + | Keyed by PaymentMethod enum value. Each value has `total` (number) and `count` (integer). |
48
+ | `grandTotal` | `number` | + | (Read-only) Sum of all `paymentsByMethod[*].total`. |
49
+ | `totalCount` | `integer` | + | (Read-only) Sum of all `paymentsByMethod[*].count`. |
50
+ | `currency` | `string` | + | Locked to `XOF`. |
51
+ | `lastUpdatedAt` | `Timestamp` | — | (Read-only) Last increment timestamp. |
52
+ | `createdAt` | `Timestamp` | + | (Read-only) Server-generated creation timestamp. |
53
+
54
+ :::info PaymentMethod keys
55
+ The `paymentsByMethod` map uses [PaymentMethod](/enums/payment-method) enum values as keys: `CASH`, `WAVE`, `ORANGE_MONEY`, `CREDIT_CARD`, etc. Missing keys imply zero for that method.
56
+ :::
57
+
58
+ :::warning Server-owned
59
+ This document is entirely server-set. All fields are computed by Cloud Function triggers. Clients should treat it as read-only.
60
+ :::
61
+
62
+ ## Trigger design
63
+
64
+ ### Source events
65
+
66
+ The summary is updated by **two independent triggers**:
67
+
68
+ 1. **`onOrderPaymentChange`** — fires when `Order.payments[]` array changes (new payment added or existing payment updated). Computes the delta and applies `FieldValue.increment()` to the matching `paymentsByMethod.{method}.total` and `.count`, plus `grandTotal` and `totalCount`.
69
+
70
+ 2. **`onCustomerPaymentWrite`** — fires on `CustomerPayment` create/update. Same increment logic for standalone customer payments not tied to an order.
71
+
72
+ ### Increment pattern
73
+
74
+ ```typescript
75
+ // Pseudo-code for the trigger
76
+ const summaryRef = db.doc(
77
+ `companies/${companyId}/paymentSummaries/${todayKey}`
78
+ );
79
+
80
+ await summaryRef.set({
81
+ companyId,
82
+ period: todayKey,
83
+ periodType: 'DAILY',
84
+ currency: 'XOF',
85
+ [`paymentsByMethod.${method}.total`]: FieldValue.increment(amount),
86
+ [`paymentsByMethod.${method}.count`]: FieldValue.increment(1),
87
+ grandTotal: FieldValue.increment(amount),
88
+ totalCount: FieldValue.increment(1),
89
+ lastUpdatedAt: FieldValue.serverTimestamp(),
90
+ createdAt: FieldValue.serverTimestamp(), // only sets on first write (merge)
91
+ }, { merge: true });
92
+ ```
93
+
94
+ ### Idempotency
95
+
96
+ To avoid double-counting on trigger retries, the trigger should check if the payment has already been counted (e.g., via a `_summarized` flag on the payment or by comparing `before`/`after` snapshots in the `onUpdate` trigger).
97
+
98
+ ### Rollups
99
+
100
+ A scheduled Cloud Function (daily at midnight WAT) can roll up daily summaries into weekly and monthly documents. This is optional — daily granularity alone may be sufficient for the dashboard.
101
+
102
+ ## Querying
103
+
104
+ ```typescript
105
+ // Get today's summary
106
+ const today = '2026-03-09';
107
+ const snap = await db.doc(`companies/${companyId}/paymentSummaries/${today}`).get();
108
+ const summary = snap.data(); // PaymentSummary
109
+
110
+ // Get summaries for a date range
111
+ const snaps = await db.collection(`companies/${companyId}/paymentSummaries`)
112
+ .where('periodType', '==', 'DAILY')
113
+ .where('period', '>=', '2026-03-01')
114
+ .where('period', '<=', '2026-03-09')
115
+ .get();
116
+ ```
117
+
118
+ ## Related
119
+
120
+ - [PaymentMethod](/enums/payment-method) — enum used as map keys
121
+ - [CustomerPayment](/models/customer-payment) — source event for trigger
122
+ - [Order](/models/order) — `payments[]` array is the other source event
123
+ - Decision D02 — Unified PaymentMethod enum
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: "Sale"
3
3
  sidebar_label: "Sale"
4
- sidebar_position: 16
4
+ sidebar_position: 19
5
5
  ---
6
6
 
7
7
  # Sale
@@ -524,7 +524,7 @@ Set at creation only. This field cannot be modified after the document is create
524
524
  | **Required** | No |
525
525
 
526
526
  ----------------------------------------------------------------------------------------------------------------------------
527
- Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-03-09 at 13:15:53 +0000
527
+ Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-04-18 at 21:21:09 +0000
528
528
 
529
529
  :::warning Server-set
530
530
  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.