@ingenx-io/valets-schema-mcp-server 0.1.1 → 0.1.3
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 +49 -0
- package/data/docs/decisions/migrations.md +56 -0
- package/data/docs/decisions/summary.md +78 -0
- package/data/docs/enums/booking-status.md +26 -0
- package/data/docs/enums/customer-payment-status.md +26 -0
- package/data/docs/enums/customer-payment-target-type.md +23 -0
- package/data/docs/enums/delivery-type.md +23 -0
- package/data/docs/enums/event-status.md +30 -0
- package/data/docs/enums/fulfillment-status.md +32 -0
- package/data/docs/enums/loyalty-transaction-type.md +32 -0
- package/data/docs/enums/order-status.md +65 -0
- package/data/docs/enums/payment-method.md +36 -0
- package/data/docs/enums/payment-proof-status.md +23 -0
- package/data/docs/enums/payment-status.md +34 -0
- package/data/docs/enums/return-status.md +32 -0
- package/data/docs/enums/session-status.md +32 -0
- package/data/docs/enums/ticket-status.md +29 -0
- package/data/docs/index.md +102 -0
- package/data/docs/models/booking-version.md +295 -0
- package/data/docs/models/booking.md +1754 -0
- package/data/docs/models/customer-payment-allocation.md +336 -0
- package/data/docs/models/customer-payment.md +392 -0
- package/data/docs/models/customer.md +475 -0
- package/data/docs/models/event.md +386 -0
- package/data/docs/models/loyalty-config.md +317 -0
- package/data/docs/models/loyalty-reward.md +236 -0
- package/data/docs/models/loyalty-status.md +328 -0
- package/data/docs/models/loyalty-transaction.md +326 -0
- package/data/docs/models/metrics-current.md +532 -0
- package/data/docs/models/metrics-daily.md +548 -0
- package/data/docs/models/metrics-monthly.md +548 -0
- package/data/docs/models/order-item.md +361 -0
- package/data/docs/models/order.md +1637 -0
- package/data/docs/models/payment-summary.md +123 -0
- package/data/docs/models/sale.md +540 -0
- package/data/docs/models/ticket.md +405 -0
- package/data/docs/triggers/event-ticket-triggers.md +204 -0
- package/data/docs/triggers/loyalty-automation.md +123 -0
- package/data/static/decisions.json +966 -0
- package/data/static/llms.txt +1056 -0
- package/data/static/openapi.yaml +3090 -0
- package/data/static/schemas.json +4055 -0
- package/package.json +1 -1
|
@@ -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
|
|
@@ -0,0 +1,540 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Sale"
|
|
3
|
+
sidebar_label: "Sale"
|
|
4
|
+
sidebar_position: 16
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Sale
|
|
8
|
+
|
|
9
|
+
<details>
|
|
10
|
+
<summary>Example JSON</summary>
|
|
11
|
+
|
|
12
|
+
```json
|
|
13
|
+
{
|
|
14
|
+
"id": null,
|
|
15
|
+
"companyId": null,
|
|
16
|
+
"customerId": null,
|
|
17
|
+
"customerName": null,
|
|
18
|
+
"amount": null,
|
|
19
|
+
"items": null,
|
|
20
|
+
"imageUrl": null,
|
|
21
|
+
"notes": null,
|
|
22
|
+
"orderId": null,
|
|
23
|
+
"bookingId": null,
|
|
24
|
+
"purchaseDate": "purchaseDate",
|
|
25
|
+
"createdAt": "createdAt"
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
</details>
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
- [1. Property `id`](#id)
|
|
33
|
+
- [2. Property `companyId`](#companyId)
|
|
34
|
+
- [3. Property `customerId`](#customerId)
|
|
35
|
+
- [4. Property `customerName`](#customerName)
|
|
36
|
+
- [5. Property `amount`](#amount)
|
|
37
|
+
- [6. Property `items`](#items)
|
|
38
|
+
- [6.1. order-item](#items_items)
|
|
39
|
+
- [6.1.1. Property `name`](#items_items_name)
|
|
40
|
+
- [6.1.2. Property `quantity`](#items_items_quantity)
|
|
41
|
+
- [6.1.3. Property `price`](#items_items_price)
|
|
42
|
+
- [6.1.4. Property `productId`](#items_items_productId)
|
|
43
|
+
- [6.1.5. Property `increment`](#items_items_increment)
|
|
44
|
+
- [6.1.6. Property `variantId`](#items_items_variantId)
|
|
45
|
+
- [6.1.7. Property `supplierId`](#items_items_supplierId)
|
|
46
|
+
- [6.1.8. Property `supplierName`](#items_items_supplierName)
|
|
47
|
+
- [6.1.9. Property `sentAt`](#items_items_sentAt)
|
|
48
|
+
- [6.1.9.1. Property `_seconds`](#items_items_sentAt__seconds)
|
|
49
|
+
- [6.1.9.2. Property `_nanoseconds`](#items_items_sentAt__nanoseconds)
|
|
50
|
+
- [6.1.10. Property `startedCookingAt`](#items_items_startedCookingAt)
|
|
51
|
+
- [6.1.10.1. Property `_seconds`](#items_items_startedCookingAt__seconds)
|
|
52
|
+
- [6.1.10.2. Property `_nanoseconds`](#items_items_startedCookingAt__nanoseconds)
|
|
53
|
+
- [6.1.11. Property `readyAt`](#items_items_readyAt)
|
|
54
|
+
- [6.1.11.1. Property `_seconds`](#items_items_readyAt__seconds)
|
|
55
|
+
- [6.1.11.2. Property `_nanoseconds`](#items_items_readyAt__nanoseconds)
|
|
56
|
+
- [6.1.12. Property `servedAt`](#items_items_servedAt)
|
|
57
|
+
- [6.1.12.1. Property `_seconds`](#items_items_servedAt__seconds)
|
|
58
|
+
- [6.1.12.2. Property `_nanoseconds`](#items_items_servedAt__nanoseconds)
|
|
59
|
+
- [7. Property `imageUrl`](#imageUrl)
|
|
60
|
+
- [8. Property `notes`](#notes)
|
|
61
|
+
- [9. Property `orderId`](#orderId)
|
|
62
|
+
- [10. Property `bookingId`](#bookingId)
|
|
63
|
+
- [11. Property `purchaseDate`](#purchaseDate)
|
|
64
|
+
- [11.1. Property `_seconds`](#purchaseDate__seconds)
|
|
65
|
+
- [11.2. Property `_nanoseconds`](#purchaseDate__nanoseconds)
|
|
66
|
+
- [12. Property `createdAt`](#createdAt)
|
|
67
|
+
- [12.1. Property `firestore-timestamp`](#createdAt_anyOf_i0)
|
|
68
|
+
- [12.2. Property `item 1`](#createdAt_anyOf_i1)
|
|
69
|
+
|
|
70
|
+
| | |
|
|
71
|
+
| ------------------------- | ------------------ |
|
|
72
|
+
| **Type** | `object` |
|
|
73
|
+
| **Required** | No |
|
|
74
|
+
| **Deprecated** |
|
|
75
|
+
| **Additional properties** | Not allowed |
|
|
76
|
+
| **Defined in** | #/definitions/sale |
|
|
77
|
+
|
|
78
|
+
**Description:** Sale/Purchase model (D06). Collection: companies/\{companyId\}/purchases/\{purchaseId\}. Code alias: SalesService. [Deprecated path: customers/\{custId\}/purchases/\{purchaseId\} — migrate to company-wide path per MIG-04/IG-5]
|
|
79
|
+
|
|
80
|
+
| Property | Pattern | Type | Deprecated | Definition | Title/Description |
|
|
81
|
+
| -------------------------------- | ------- | -------------- | ---------- | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------- |
|
|
82
|
+
| - [id](#id ) | No | string or null | No | - | (Read-only) Firestore document ID. Note: optional in current schema — some legacy docs may lack this field. |
|
|
83
|
+
| - [companyId](#companyId ) | No | string or null | No | - | (Immutable) FK → Company document ID. Note: optional in current schema — should be required (see ID consistency audit). |
|
|
84
|
+
| - [customerId](#customerId ) | No | string or null | No | - | FK → Customer.id (Firestore doc ID). |
|
|
85
|
+
| - [customerName](#customerName ) | No | string or null | No | - | (Denormalized) From Customer.name at write time. |
|
|
86
|
+
| - [amount](#amount ) | No | number or null | No | - | - |
|
|
87
|
+
| - [items](#items ) | No | array or null | No | - | Line items. Reuses Order item schema. |
|
|
88
|
+
| - [imageUrl](#imageUrl ) | No | string or null | No | - | - |
|
|
89
|
+
| - [notes](#notes ) | No | string or null | No | - | - |
|
|
90
|
+
| - [orderId](#orderId ) | No | string or null | No | - | FK → Order.id. Link to associated Order document. |
|
|
91
|
+
| - [bookingId](#bookingId ) | No | string or null | No | - | FK → Booking.id. Link to associated Booking document (IG-12). |
|
|
92
|
+
| + [purchaseDate](#purchaseDate ) | No | object | No | In #/definitions/firestore-timestamp | Firestore Timestamp serialized representation |
|
|
93
|
+
| - [createdAt](#createdAt ) | No | Combination | No | - | (Read-only) Server-generated creation timestamp. |
|
|
94
|
+
|
|
95
|
+
## <a name="id"></a>1. Property `id`
|
|
96
|
+
|
|
97
|
+
| | |
|
|
98
|
+
| ------------ | ---------------- |
|
|
99
|
+
| **Type** | `string or null` |
|
|
100
|
+
| **Required** | No |
|
|
101
|
+
|
|
102
|
+
**Description:** (Read-only) Firestore document ID. Note: optional in current schema — some legacy docs may lack this field.
|
|
103
|
+
|
|
104
|
+
:::warning Server-set
|
|
105
|
+
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.
|
|
106
|
+
:::
|
|
107
|
+
|
|
108
|
+
## <a name="companyId"></a>2. Property `companyId`
|
|
109
|
+
|
|
110
|
+
| | |
|
|
111
|
+
| ------------ | ---------------- |
|
|
112
|
+
| **Type** | `string or null` |
|
|
113
|
+
| **Required** | No |
|
|
114
|
+
|
|
115
|
+
**Description:** (Immutable) FK → Company document ID. Note: optional in current schema — should be required (see ID consistency audit).
|
|
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="customerId"></a>3. Property `customerId`
|
|
122
|
+
|
|
123
|
+
| | |
|
|
124
|
+
| ------------ | ---------------- |
|
|
125
|
+
| **Type** | `string or null` |
|
|
126
|
+
| **Required** | No |
|
|
127
|
+
|
|
128
|
+
**Description:** FK → Customer.id (Firestore doc ID).
|
|
129
|
+
|
|
130
|
+
## <a name="customerName"></a>4. Property `customerName`
|
|
131
|
+
|
|
132
|
+
| | |
|
|
133
|
+
| ------------ | ---------------- |
|
|
134
|
+
| **Type** | `string or null` |
|
|
135
|
+
| **Required** | No |
|
|
136
|
+
|
|
137
|
+
**Description:** (Denormalized) From Customer.name at write time.
|
|
138
|
+
|
|
139
|
+
## <a name="amount"></a>5. Property `amount`
|
|
140
|
+
|
|
141
|
+
| | |
|
|
142
|
+
| ------------ | ---------------- |
|
|
143
|
+
| **Type** | `number or null` |
|
|
144
|
+
| **Required** | No |
|
|
145
|
+
|
|
146
|
+
## <a name="items"></a>6. Property `items`
|
|
147
|
+
|
|
148
|
+
| | |
|
|
149
|
+
| ------------ | --------------- |
|
|
150
|
+
| **Type** | `array or null` |
|
|
151
|
+
| **Required** | No |
|
|
152
|
+
|
|
153
|
+
**Description:** Line items. Reuses Order item schema.
|
|
154
|
+
|
|
155
|
+
| | Array restrictions |
|
|
156
|
+
| -------------------- | ------------------ |
|
|
157
|
+
| **Min items** | N/A |
|
|
158
|
+
| **Max items** | N/A |
|
|
159
|
+
| **Items unicity** | False |
|
|
160
|
+
| **Additional items** | False |
|
|
161
|
+
| **Tuple validation** | See below |
|
|
162
|
+
|
|
163
|
+
| Each item of this array must be | Description |
|
|
164
|
+
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
165
|
+
| [order-item](#items_items) | Line item within an Order or Sale/Purchase. Canonical fields: name, quantity, price, productId. Optional commerce fields (increment, variantId, supplierId, supplierName) and kitchen tracking fields (sentAt, startedCookingAt, readyAt, servedAt) are TBD/WIP pending cross-platform alignment. |
|
|
166
|
+
|
|
167
|
+
### <a name="items_items"></a>6.1. order-item
|
|
168
|
+
|
|
169
|
+
| | |
|
|
170
|
+
| ------------------------- | ------------------------ |
|
|
171
|
+
| **Type** | `object` |
|
|
172
|
+
| **Required** | No |
|
|
173
|
+
| **Additional properties** | Not allowed |
|
|
174
|
+
| **Defined in** | #/definitions/order-item |
|
|
175
|
+
|
|
176
|
+
**Description:** Line item within an Order or Sale/Purchase. Canonical fields: name, quantity, price, productId. Optional commerce fields (increment, variantId, supplierId, supplierName) and kitchen tracking fields (sentAt, startedCookingAt, readyAt, servedAt) are TBD/WIP pending cross-platform alignment.
|
|
177
|
+
|
|
178
|
+
| Property | Pattern | Type | Deprecated | Definition | Title/Description |
|
|
179
|
+
| ---------------------------------------------------- | ------- | ------ | ---------- | ---------- | ------------------------------------------------------------------------------------------------- |
|
|
180
|
+
| + [name](#items_items_name ) | No | string | No | - | Display name of the product or service. |
|
|
181
|
+
| + [quantity](#items_items_quantity ) | No | number | No | - | Number of units ordered. |
|
|
182
|
+
| + [price](#items_items_price ) | No | number | No | - | Unit price. Canonical name per D11. |
|
|
183
|
+
| - [productId](#items_items_productId ) | No | string | No | - | FK → Product document ID. |
|
|
184
|
+
| - [increment](#items_items_increment ) | No | number | No | - | Quantity step for bundle/bulk items (e.g. 5 for a 5-pack). Dashboard/Firebase only. |
|
|
185
|
+
| - [variantId](#items_items_variantId ) | No | string | No | - | FK → ProductVariant ID within the product. Dashboard/Firebase only. |
|
|
186
|
+
| - [supplierId](#items_items_supplierId ) | No | string | No | - | FK → Supplier document ID. B2B orders only. |
|
|
187
|
+
| - [supplierName](#items_items_supplierName ) | No | string | No | - | (Denormalized) From Supplier.name at write time. B2B orders only. |
|
|
188
|
+
| - [sentAt](#items_items_sentAt ) | No | object | No | - | (Read-only) Timestamp when the item was sent to the kitchen. TBD/WIP — archived CBL flow. |
|
|
189
|
+
| - [startedCookingAt](#items_items_startedCookingAt ) | No | object | No | - | (Read-only) Timestamp when the kitchen started preparing this item. TBD/WIP — archived CBL flow. |
|
|
190
|
+
| - [readyAt](#items_items_readyAt ) | No | object | No | - | (Read-only) Timestamp when the item was ready for pickup or service. TBD/WIP — archived CBL flow. |
|
|
191
|
+
| - [servedAt](#items_items_servedAt ) | No | object | No | - | (Read-only) Timestamp when the item was served to the customer. TBD/WIP — archived CBL flow. |
|
|
192
|
+
|
|
193
|
+
#### <a name="items_items_name"></a>6.1.1. Property `name`
|
|
194
|
+
|
|
195
|
+
| | |
|
|
196
|
+
| ------------ | -------- |
|
|
197
|
+
| **Type** | `string` |
|
|
198
|
+
| **Required** | Yes |
|
|
199
|
+
|
|
200
|
+
**Description:** Display name of the product or service.
|
|
201
|
+
|
|
202
|
+
#### <a name="items_items_quantity"></a>6.1.2. Property `quantity`
|
|
203
|
+
|
|
204
|
+
| | |
|
|
205
|
+
| ------------ | -------- |
|
|
206
|
+
| **Type** | `number` |
|
|
207
|
+
| **Required** | Yes |
|
|
208
|
+
|
|
209
|
+
**Description:** Number of units ordered.
|
|
210
|
+
|
|
211
|
+
#### <a name="items_items_price"></a>6.1.3. Property `price`
|
|
212
|
+
|
|
213
|
+
| | |
|
|
214
|
+
| ------------ | -------- |
|
|
215
|
+
| **Type** | `number` |
|
|
216
|
+
| **Required** | Yes |
|
|
217
|
+
|
|
218
|
+
**Description:** Unit price. Canonical name per D11.
|
|
219
|
+
|
|
220
|
+
#### <a name="items_items_productId"></a>6.1.4. Property `productId`
|
|
221
|
+
|
|
222
|
+
| | |
|
|
223
|
+
| ------------ | -------- |
|
|
224
|
+
| **Type** | `string` |
|
|
225
|
+
| **Required** | No |
|
|
226
|
+
|
|
227
|
+
**Description:** FK → Product document ID.
|
|
228
|
+
|
|
229
|
+
#### <a name="items_items_increment"></a>6.1.5. Property `increment`
|
|
230
|
+
|
|
231
|
+
| | |
|
|
232
|
+
| ------------ | -------- |
|
|
233
|
+
| **Type** | `number` |
|
|
234
|
+
| **Required** | No |
|
|
235
|
+
|
|
236
|
+
**Description:** Quantity step for bundle/bulk items (e.g. 5 for a 5-pack). Dashboard/Firebase only.
|
|
237
|
+
|
|
238
|
+
#### <a name="items_items_variantId"></a>6.1.6. Property `variantId`
|
|
239
|
+
|
|
240
|
+
| | |
|
|
241
|
+
| ------------ | -------- |
|
|
242
|
+
| **Type** | `string` |
|
|
243
|
+
| **Required** | No |
|
|
244
|
+
|
|
245
|
+
**Description:** FK → ProductVariant ID within the product. Dashboard/Firebase only.
|
|
246
|
+
|
|
247
|
+
#### <a name="items_items_supplierId"></a>6.1.7. Property `supplierId`
|
|
248
|
+
|
|
249
|
+
| | |
|
|
250
|
+
| ------------ | -------- |
|
|
251
|
+
| **Type** | `string` |
|
|
252
|
+
| **Required** | No |
|
|
253
|
+
|
|
254
|
+
**Description:** FK → Supplier document ID. B2B orders only.
|
|
255
|
+
|
|
256
|
+
#### <a name="items_items_supplierName"></a>6.1.8. Property `supplierName`
|
|
257
|
+
|
|
258
|
+
| | |
|
|
259
|
+
| ------------ | -------- |
|
|
260
|
+
| **Type** | `string` |
|
|
261
|
+
| **Required** | No |
|
|
262
|
+
|
|
263
|
+
**Description:** (Denormalized) From Supplier.name at write time. B2B orders only.
|
|
264
|
+
|
|
265
|
+
#### <a name="items_items_sentAt"></a>6.1.9. Property `sentAt`
|
|
266
|
+
|
|
267
|
+
| | |
|
|
268
|
+
| ------------------------- | ----------- |
|
|
269
|
+
| **Type** | `object` |
|
|
270
|
+
| **Required** | No |
|
|
271
|
+
| **Additional properties** | Not allowed |
|
|
272
|
+
|
|
273
|
+
**Description:** (Read-only) Timestamp when the item was sent to the kitchen. TBD/WIP — archived CBL flow.
|
|
274
|
+
|
|
275
|
+
| Property | Pattern | Type | Deprecated | Definition | Title/Description |
|
|
276
|
+
| --------------------------------------------------- | ------- | ------- | ---------- | ---------- | ----------------- |
|
|
277
|
+
| + [_seconds](#items_items_sentAt__seconds ) | No | integer | No | - | - |
|
|
278
|
+
| + [_nanoseconds](#items_items_sentAt__nanoseconds ) | No | integer | No | - | - |
|
|
279
|
+
|
|
280
|
+
##### <a name="items_items_sentAt__seconds"></a>6.1.9.1. Property `_seconds`
|
|
281
|
+
|
|
282
|
+
| | |
|
|
283
|
+
| ------------ | --------- |
|
|
284
|
+
| **Type** | `integer` |
|
|
285
|
+
| **Required** | Yes |
|
|
286
|
+
|
|
287
|
+
| Restrictions | |
|
|
288
|
+
| ------------ | ---------------------- |
|
|
289
|
+
| **Minimum** | ≥ -9007199254740991 |
|
|
290
|
+
| **Maximum** | ≤ 9007199254740991 |
|
|
291
|
+
|
|
292
|
+
##### <a name="items_items_sentAt__nanoseconds"></a>6.1.9.2. Property `_nanoseconds`
|
|
293
|
+
|
|
294
|
+
| | |
|
|
295
|
+
| ------------ | --------- |
|
|
296
|
+
| **Type** | `integer` |
|
|
297
|
+
| **Required** | Yes |
|
|
298
|
+
|
|
299
|
+
| Restrictions | |
|
|
300
|
+
| ------------ | ---------------------- |
|
|
301
|
+
| **Minimum** | ≥ -9007199254740991 |
|
|
302
|
+
| **Maximum** | ≤ 9007199254740991 |
|
|
303
|
+
|
|
304
|
+
#### <a name="items_items_startedCookingAt"></a>6.1.10. Property `startedCookingAt`
|
|
305
|
+
|
|
306
|
+
| | |
|
|
307
|
+
| ------------------------- | ----------- |
|
|
308
|
+
| **Type** | `object` |
|
|
309
|
+
| **Required** | No |
|
|
310
|
+
| **Additional properties** | Not allowed |
|
|
311
|
+
|
|
312
|
+
**Description:** (Read-only) Timestamp when the kitchen started preparing this item. TBD/WIP — archived CBL flow.
|
|
313
|
+
|
|
314
|
+
| Property | Pattern | Type | Deprecated | Definition | Title/Description |
|
|
315
|
+
| ------------------------------------------------------------- | ------- | ------- | ---------- | ---------- | ----------------- |
|
|
316
|
+
| + [_seconds](#items_items_startedCookingAt__seconds ) | No | integer | No | - | - |
|
|
317
|
+
| + [_nanoseconds](#items_items_startedCookingAt__nanoseconds ) | No | integer | No | - | - |
|
|
318
|
+
|
|
319
|
+
##### <a name="items_items_startedCookingAt__seconds"></a>6.1.10.1. Property `_seconds`
|
|
320
|
+
|
|
321
|
+
| | |
|
|
322
|
+
| ------------ | --------- |
|
|
323
|
+
| **Type** | `integer` |
|
|
324
|
+
| **Required** | Yes |
|
|
325
|
+
|
|
326
|
+
| Restrictions | |
|
|
327
|
+
| ------------ | ---------------------- |
|
|
328
|
+
| **Minimum** | ≥ -9007199254740991 |
|
|
329
|
+
| **Maximum** | ≤ 9007199254740991 |
|
|
330
|
+
|
|
331
|
+
##### <a name="items_items_startedCookingAt__nanoseconds"></a>6.1.10.2. Property `_nanoseconds`
|
|
332
|
+
|
|
333
|
+
| | |
|
|
334
|
+
| ------------ | --------- |
|
|
335
|
+
| **Type** | `integer` |
|
|
336
|
+
| **Required** | Yes |
|
|
337
|
+
|
|
338
|
+
| Restrictions | |
|
|
339
|
+
| ------------ | ---------------------- |
|
|
340
|
+
| **Minimum** | ≥ -9007199254740991 |
|
|
341
|
+
| **Maximum** | ≤ 9007199254740991 |
|
|
342
|
+
|
|
343
|
+
#### <a name="items_items_readyAt"></a>6.1.11. Property `readyAt`
|
|
344
|
+
|
|
345
|
+
| | |
|
|
346
|
+
| ------------------------- | ----------- |
|
|
347
|
+
| **Type** | `object` |
|
|
348
|
+
| **Required** | No |
|
|
349
|
+
| **Additional properties** | Not allowed |
|
|
350
|
+
|
|
351
|
+
**Description:** (Read-only) Timestamp when the item was ready for pickup or service. TBD/WIP — archived CBL flow.
|
|
352
|
+
|
|
353
|
+
| Property | Pattern | Type | Deprecated | Definition | Title/Description |
|
|
354
|
+
| ---------------------------------------------------- | ------- | ------- | ---------- | ---------- | ----------------- |
|
|
355
|
+
| + [_seconds](#items_items_readyAt__seconds ) | No | integer | No | - | - |
|
|
356
|
+
| + [_nanoseconds](#items_items_readyAt__nanoseconds ) | No | integer | No | - | - |
|
|
357
|
+
|
|
358
|
+
##### <a name="items_items_readyAt__seconds"></a>6.1.11.1. Property `_seconds`
|
|
359
|
+
|
|
360
|
+
| | |
|
|
361
|
+
| ------------ | --------- |
|
|
362
|
+
| **Type** | `integer` |
|
|
363
|
+
| **Required** | Yes |
|
|
364
|
+
|
|
365
|
+
| Restrictions | |
|
|
366
|
+
| ------------ | ---------------------- |
|
|
367
|
+
| **Minimum** | ≥ -9007199254740991 |
|
|
368
|
+
| **Maximum** | ≤ 9007199254740991 |
|
|
369
|
+
|
|
370
|
+
##### <a name="items_items_readyAt__nanoseconds"></a>6.1.11.2. Property `_nanoseconds`
|
|
371
|
+
|
|
372
|
+
| | |
|
|
373
|
+
| ------------ | --------- |
|
|
374
|
+
| **Type** | `integer` |
|
|
375
|
+
| **Required** | Yes |
|
|
376
|
+
|
|
377
|
+
| Restrictions | |
|
|
378
|
+
| ------------ | ---------------------- |
|
|
379
|
+
| **Minimum** | ≥ -9007199254740991 |
|
|
380
|
+
| **Maximum** | ≤ 9007199254740991 |
|
|
381
|
+
|
|
382
|
+
#### <a name="items_items_servedAt"></a>6.1.12. Property `servedAt`
|
|
383
|
+
|
|
384
|
+
| | |
|
|
385
|
+
| ------------------------- | ----------- |
|
|
386
|
+
| **Type** | `object` |
|
|
387
|
+
| **Required** | No |
|
|
388
|
+
| **Additional properties** | Not allowed |
|
|
389
|
+
|
|
390
|
+
**Description:** (Read-only) Timestamp when the item was served to the customer. TBD/WIP — archived CBL flow.
|
|
391
|
+
|
|
392
|
+
| Property | Pattern | Type | Deprecated | Definition | Title/Description |
|
|
393
|
+
| ----------------------------------------------------- | ------- | ------- | ---------- | ---------- | ----------------- |
|
|
394
|
+
| + [_seconds](#items_items_servedAt__seconds ) | No | integer | No | - | - |
|
|
395
|
+
| + [_nanoseconds](#items_items_servedAt__nanoseconds ) | No | integer | No | - | - |
|
|
396
|
+
|
|
397
|
+
##### <a name="items_items_servedAt__seconds"></a>6.1.12.1. Property `_seconds`
|
|
398
|
+
|
|
399
|
+
| | |
|
|
400
|
+
| ------------ | --------- |
|
|
401
|
+
| **Type** | `integer` |
|
|
402
|
+
| **Required** | Yes |
|
|
403
|
+
|
|
404
|
+
| Restrictions | |
|
|
405
|
+
| ------------ | ---------------------- |
|
|
406
|
+
| **Minimum** | ≥ -9007199254740991 |
|
|
407
|
+
| **Maximum** | ≤ 9007199254740991 |
|
|
408
|
+
|
|
409
|
+
##### <a name="items_items_servedAt__nanoseconds"></a>6.1.12.2. Property `_nanoseconds`
|
|
410
|
+
|
|
411
|
+
| | |
|
|
412
|
+
| ------------ | --------- |
|
|
413
|
+
| **Type** | `integer` |
|
|
414
|
+
| **Required** | Yes |
|
|
415
|
+
|
|
416
|
+
| Restrictions | |
|
|
417
|
+
| ------------ | ---------------------- |
|
|
418
|
+
| **Minimum** | ≥ -9007199254740991 |
|
|
419
|
+
| **Maximum** | ≤ 9007199254740991 |
|
|
420
|
+
|
|
421
|
+
## <a name="imageUrl"></a>7. Property `imageUrl`
|
|
422
|
+
|
|
423
|
+
| | |
|
|
424
|
+
| ------------ | ---------------- |
|
|
425
|
+
| **Type** | `string or null` |
|
|
426
|
+
| **Required** | No |
|
|
427
|
+
|
|
428
|
+
## <a name="notes"></a>8. Property `notes`
|
|
429
|
+
|
|
430
|
+
| | |
|
|
431
|
+
| ------------ | ---------------- |
|
|
432
|
+
| **Type** | `string or null` |
|
|
433
|
+
| **Required** | No |
|
|
434
|
+
|
|
435
|
+
## <a name="orderId"></a>9. Property `orderId`
|
|
436
|
+
|
|
437
|
+
| | |
|
|
438
|
+
| ------------ | ---------------- |
|
|
439
|
+
| **Type** | `string or null` |
|
|
440
|
+
| **Required** | No |
|
|
441
|
+
|
|
442
|
+
**Description:** FK → Order.id. Link to associated Order document.
|
|
443
|
+
|
|
444
|
+
## <a name="bookingId"></a>10. Property `bookingId`
|
|
445
|
+
|
|
446
|
+
| | |
|
|
447
|
+
| ------------ | ---------------- |
|
|
448
|
+
| **Type** | `string or null` |
|
|
449
|
+
| **Required** | No |
|
|
450
|
+
|
|
451
|
+
**Description:** FK → Booking.id. Link to associated Booking document (IG-12).
|
|
452
|
+
|
|
453
|
+
## <a name="purchaseDate"></a>11. Property `purchaseDate`
|
|
454
|
+
|
|
455
|
+
| | |
|
|
456
|
+
| ------------------------- | --------------------------------- |
|
|
457
|
+
| **Type** | `object` |
|
|
458
|
+
| **Required** | Yes |
|
|
459
|
+
| **Additional properties** | Not allowed |
|
|
460
|
+
| **Defined in** | #/definitions/firestore-timestamp |
|
|
461
|
+
|
|
462
|
+
**Description:** Firestore Timestamp serialized representation
|
|
463
|
+
|
|
464
|
+
| Property | Pattern | Type | Deprecated | Definition | Title/Description |
|
|
465
|
+
| --------------------------------------------- | ------- | ------- | ---------- | ---------- | ----------------- |
|
|
466
|
+
| + [_seconds](#purchaseDate__seconds ) | No | integer | No | - | - |
|
|
467
|
+
| + [_nanoseconds](#purchaseDate__nanoseconds ) | No | integer | No | - | - |
|
|
468
|
+
|
|
469
|
+
### <a name="purchaseDate__seconds"></a>11.1. Property `_seconds`
|
|
470
|
+
|
|
471
|
+
| | |
|
|
472
|
+
| ------------ | --------- |
|
|
473
|
+
| **Type** | `integer` |
|
|
474
|
+
| **Required** | Yes |
|
|
475
|
+
|
|
476
|
+
| Restrictions | |
|
|
477
|
+
| ------------ | ---------------------- |
|
|
478
|
+
| **Minimum** | ≥ -9007199254740991 |
|
|
479
|
+
| **Maximum** | ≤ 9007199254740991 |
|
|
480
|
+
|
|
481
|
+
### <a name="purchaseDate__nanoseconds"></a>11.2. Property `_nanoseconds`
|
|
482
|
+
|
|
483
|
+
| | |
|
|
484
|
+
| ------------ | --------- |
|
|
485
|
+
| **Type** | `integer` |
|
|
486
|
+
| **Required** | Yes |
|
|
487
|
+
|
|
488
|
+
| Restrictions | |
|
|
489
|
+
| ------------ | ---------------------- |
|
|
490
|
+
| **Minimum** | ≥ -9007199254740991 |
|
|
491
|
+
| **Maximum** | ≤ 9007199254740991 |
|
|
492
|
+
|
|
493
|
+
## <a name="createdAt"></a>12. Property `createdAt`
|
|
494
|
+
|
|
495
|
+
| | |
|
|
496
|
+
| ------------------------- | ---------------- |
|
|
497
|
+
| **Type** | `combining` |
|
|
498
|
+
| **Required** | No |
|
|
499
|
+
| **Additional properties** | Any type allowed |
|
|
500
|
+
|
|
501
|
+
**Description:** (Read-only) Server-generated creation timestamp.
|
|
502
|
+
|
|
503
|
+
| Any of(Option) |
|
|
504
|
+
| ------------------------------------------ |
|
|
505
|
+
| [firestore-timestamp](#createdAt_anyOf_i0) |
|
|
506
|
+
| [item 1](#createdAt_anyOf_i1) |
|
|
507
|
+
|
|
508
|
+
### <a name="createdAt_anyOf_i0"></a>12.1. Property `firestore-timestamp`
|
|
509
|
+
|
|
510
|
+
| | |
|
|
511
|
+
| ------------------------- | ----------------------------- |
|
|
512
|
+
| **Type** | `object` |
|
|
513
|
+
| **Required** | No |
|
|
514
|
+
| **Additional properties** | Not allowed |
|
|
515
|
+
| **Same definition as** | [purchaseDate](#purchaseDate) |
|
|
516
|
+
|
|
517
|
+
**Description:** Firestore Timestamp serialized representation
|
|
518
|
+
|
|
519
|
+
### <a name="createdAt_anyOf_i1"></a>12.2. Property `item 1`
|
|
520
|
+
|
|
521
|
+
| | |
|
|
522
|
+
| ------------ | ------ |
|
|
523
|
+
| **Type** | `null` |
|
|
524
|
+
| **Required** | No |
|
|
525
|
+
|
|
526
|
+
----------------------------------------------------------------------------------------------------------------------------
|
|
527
|
+
Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-04-06 at 19:27:48 +0000
|
|
528
|
+
|
|
529
|
+
:::warning Server-set
|
|
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.
|
|
531
|
+
:::
|
|
532
|
+
|
|
533
|
+
## Related Decisions
|
|
534
|
+
|
|
535
|
+
| Decision | Title |
|
|
536
|
+
|---|---|
|
|
537
|
+
| **D05** | Canonical purchase amount field |
|
|
538
|
+
| **D06** | Canonical sales collection path |
|
|
539
|
+
| **D12** | Payments canonical location model |
|
|
540
|
+
| **D15** | Should SaleMargin be server-side |
|