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

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 (78) hide show
  1. package/data/docs/enums/app-status.md +1 -1
  2. package/data/docs/enums/attention-status.md +1 -1
  3. package/data/docs/enums/booking-status.md +1 -1
  4. package/data/docs/enums/contract-status.md +24 -0
  5. package/data/docs/enums/customer-payment-status.md +2 -2
  6. package/data/docs/enums/customer-payment-target-type.md +2 -2
  7. package/data/docs/enums/delivery-type.md +2 -2
  8. package/data/docs/enums/deployment-link-type.md +2 -2
  9. package/data/docs/enums/event-status.md +2 -2
  10. package/data/docs/enums/fulfillment-status.md +2 -2
  11. package/data/docs/enums/loyalty-transaction-type.md +2 -2
  12. package/data/docs/enums/milestone-status.md +23 -0
  13. package/data/docs/enums/notification-channel.md +2 -2
  14. package/data/docs/enums/notification-entity-type.md +2 -2
  15. package/data/docs/enums/notification-status.md +2 -2
  16. package/data/docs/enums/order-status.md +2 -2
  17. package/data/docs/enums/outbound-message-format.md +2 -2
  18. package/data/docs/enums/outbound-message-purpose.md +2 -2
  19. package/data/docs/enums/outbound-message-status.md +2 -2
  20. package/data/docs/enums/payment-method.md +2 -2
  21. package/data/docs/enums/payment-proof-status.md +2 -2
  22. package/data/docs/enums/payment-status.md +2 -2
  23. package/data/docs/enums/pending-issue.md +2 -2
  24. package/data/docs/enums/return-status.md +2 -2
  25. package/data/docs/enums/session-status.md +2 -2
  26. package/data/docs/enums/site-status.md +2 -2
  27. package/data/docs/enums/stocktake-frequency.md +2 -2
  28. package/data/docs/enums/stocktake-item-status.md +2 -2
  29. package/data/docs/enums/stocktake-status.md +2 -2
  30. package/data/docs/enums/ticket-status.md +2 -2
  31. package/data/docs/enums/waba-label.md +3 -3
  32. package/data/docs/enums/whatsapp-button-sub-type.md +2 -2
  33. package/data/docs/enums/whatsapp-template-component.md +2 -2
  34. package/data/docs/enums/whatsapp-template-status.md +2 -2
  35. package/data/docs/index.md +11 -5
  36. package/data/docs/models/allowed-user.md +1 -1
  37. package/data/docs/models/analytics-backfill.md +1 -1
  38. package/data/docs/models/analytics-daily.md +1 -1
  39. package/data/docs/models/analytics-event.md +1 -1
  40. package/data/docs/models/analytics-hourly.md +1 -1
  41. package/data/docs/models/app-payment.md +1 -1
  42. package/data/docs/models/app.md +45 -21
  43. package/data/docs/models/booking-version.md +1 -1
  44. package/data/docs/models/booking.md +1 -1
  45. package/data/docs/models/contract.md +454 -0
  46. package/data/docs/models/customer-payment-allocation.md +2 -2
  47. package/data/docs/models/customer-payment.md +2 -2
  48. package/data/docs/models/customer.md +2 -2
  49. package/data/docs/models/event.md +2 -2
  50. package/data/docs/models/loyalty-config.md +2 -2
  51. package/data/docs/models/loyalty-reward.md +2 -2
  52. package/data/docs/models/loyalty-status.md +2 -2
  53. package/data/docs/models/loyalty-transaction.md +2 -2
  54. package/data/docs/models/magic-link-request.md +2 -2
  55. package/data/docs/models/metrics-current.md +2 -2
  56. package/data/docs/models/metrics-daily.md +2 -2
  57. package/data/docs/models/metrics-monthly.md +2 -2
  58. package/data/docs/models/notification-record.md +2 -2
  59. package/data/docs/models/order-item.md +2 -2
  60. package/data/docs/models/order.md +238 -218
  61. package/data/docs/models/outbound-payment-allocation.md +195 -0
  62. package/data/docs/models/outbound-payment.md +318 -0
  63. package/data/docs/models/payment-webhook-endpoint.md +191 -0
  64. package/data/docs/models/sale.md +2 -2
  65. package/data/docs/models/site-payment.md +2 -2
  66. package/data/docs/models/site.md +2 -2
  67. package/data/docs/models/stocktake-item.md +2 -2
  68. package/data/docs/models/stocktake.md +2 -2
  69. package/data/docs/models/ticket.md +2 -2
  70. package/data/docs/models/user.md +2 -2
  71. package/data/docs/models/whatsapp-inbound-message.md +6 -2
  72. package/data/docs/models/whatsapp-outbound-lifecycle-event.md +2 -2
  73. package/data/docs/models/whatsapp-outbound-message.md +39 -23
  74. package/data/docs/models/whatsapp-template.md +6 -2
  75. package/data/static/llms.txt +145 -5
  76. package/data/static/openapi.yaml +456 -14
  77. package/data/static/schemas.json +477 -9
  78. package/package.json +1 -1
@@ -391,7 +391,7 @@ Do not include in write requests. This field is set exclusively by the server (F
391
391
  | **Required** | No |
392
392
 
393
393
  ----------------------------------------------------------------------------------------------------------------------------
394
- Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-05-30 at 12:42:50 +0000
394
+ Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-05-30 at 13:38:44 +0000
395
395
 
396
396
  :::warning Server-set
397
397
  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.
@@ -344,7 +344,7 @@ Do not include in write requests. This field is set exclusively by the server (F
344
344
  | **Maximum** | ≤ 9007199254740991 |
345
345
 
346
346
  ----------------------------------------------------------------------------------------------------------------------------
347
- Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-05-30 at 12:42:50 +0000
347
+ Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-05-30 at 13:38:44 +0000
348
348
 
349
349
  :::warning Server-set
350
350
  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.
@@ -530,4 +530,4 @@ Must be one of:
530
530
  | **Additional properties** | Any type allowed |
531
531
 
532
532
  ----------------------------------------------------------------------------------------------------------------------------
533
- Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-05-30 at 12:42:50 +0000
533
+ Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-05-30 at 13:38:44 +0000
@@ -365,7 +365,7 @@ Do not include in write requests. This field is set exclusively by the server (F
365
365
  | **Maximum** | ≤ 9007199254740991 |
366
366
 
367
367
  ----------------------------------------------------------------------------------------------------------------------------
368
- Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-05-30 at 12:42:50 +0000
368
+ Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-05-30 at 13:38:44 +0000
369
369
 
370
370
  :::warning Server-set
371
371
  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.
@@ -197,4 +197,4 @@ Set at creation only. This field cannot be modified after the document is create
197
197
  | **Maximum** | ≤ 9007199254740991 |
198
198
 
199
199
  ----------------------------------------------------------------------------------------------------------------------------
200
- Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-05-30 at 12:42:50 +0000
200
+ Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-05-30 at 13:38:44 +0000
@@ -42,6 +42,8 @@ sidebar_position: 6
42
42
  - [3. Property `name`](#name)
43
43
  - [4. Property `description`](#description)
44
44
  - [5. Property `status`](#status)
45
+ - [5.1. Property `app-status`](#status_anyOf_i0)
46
+ - [5.2. Property `item 1`](#status_anyOf_i1)
45
47
  - [6. Property `deploymentLinks`](#deploymentLinks)
46
48
  - [6.1. deploymentLinks items](#deploymentLinks_items)
47
49
  - [6.1.1. Property `label`](#deploymentLinks_items_label)
@@ -81,22 +83,22 @@ sidebar_position: 6
81
83
 
82
84
  **Description:** App model (D41 / ING-304). Collection: companies/\{companyId\}/apps/\{appId\}. Per-company product surface. Sub-collections (magic_link_requests, allowed_users, payments, analytics_events, analytics_daily, analytics_hourly, analytics_backfills) live under this document per D40/D42.
83
85
 
84
- | Property | Pattern | Type | Deprecated | Definition | Title/Description |
85
- | ------------------------------------------ | ------- | ---------------- | ---------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------- |
86
- | - [id](#id ) | No | string or null | No | - | (Read-only) Firestore document ID, auto-generated. |
87
- | + [companyId](#companyId ) | No | string | No | - | (Immutable) FK → Company document ID. Scopes all app sub-collections. |
88
- | + [name](#name ) | No | string | No | - | Human-readable app name shown in dashboards. |
89
- | - [description](#description ) | No | string or null | No | - | Optional freeform description. |
90
- | + [status](#status ) | No | enum (of string) | No | In #/definitions/app-status | Lifecycle status (D41/D44). Clients filter by ACTIVE. |
91
- | + [deploymentLinks](#deploymentLinks ) | No | array of object | No | - | Ordered list of deployment URLs (web, mobile, PWA, store links). |
92
- | - [expiresAt](#expiresAt ) | No | Combination | No | - | Optional expiration timestamp. When set and elapsed, \`isExpired\` flips true and status typically moves to EXPIRED. |
93
- | - [isExpired](#isExpired ) | No | boolean or null | No | - | (Read-only) Derived — true when \`expiresAt\` is in the past. Maintained by server trigger. |
94
- | - [createdAt](#createdAt ) | No | Combination | No | - | (Read-only) Server-generated creation timestamp. |
95
- | - [updatedAt](#updatedAt ) | No | Combination | No | - | (Read-only) Server-generated update timestamp. |
96
- | + [createdBy](#createdBy ) | No | string | No | - | (Immutable) FK → User/staff UID who created the app. |
97
- | + [analyticsEnabled](#analyticsEnabled ) | No | boolean | No | - | Feature flag — when false, clients should not emit analytics events for this app. |
98
- | - [lastAnalyticsSync](#lastAnalyticsSync ) | No | Combination | No | - | (Read-only) Last time the analytics rollup pipeline refreshed \`cachedMetrics\`. |
99
- | - [cachedMetrics](#cachedMetrics ) | No | object or null | No | - | (Read-only, Denormalized) Cached metrics snapshot for quick dashboard rendering. |
86
+ | Property | Pattern | Type | Deprecated | Definition | Title/Description |
87
+ | ------------------------------------------ | ------- | --------------- | ---------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------- |
88
+ | - [id](#id ) | No | string or null | No | - | (Read-only) Firestore document ID, auto-generated. |
89
+ | + [companyId](#companyId ) | No | string | No | - | (Immutable) FK → Company document ID. Scopes all app sub-collections. |
90
+ | + [name](#name ) | No | string | No | - | Human-readable app name shown in dashboards. |
91
+ | - [description](#description ) | No | string or null | No | - | Optional freeform description. |
92
+ | - [status](#status ) | No | Combination | No | - | Lifecycle status (D41/D44). Optional pending backfill of pre-existing records (#26) — treat absent as ACTIVE. Clients filter by ACTIVE. |
93
+ | + [deploymentLinks](#deploymentLinks ) | No | array of object | No | - | Ordered list of deployment URLs (web, mobile, PWA, store links). |
94
+ | - [expiresAt](#expiresAt ) | No | Combination | No | - | Optional expiration timestamp. When set and elapsed, \`isExpired\` flips true and status typically moves to EXPIRED. |
95
+ | - [isExpired](#isExpired ) | No | boolean or null | No | - | (Read-only) Derived — true when \`expiresAt\` is in the past. Maintained by server trigger. |
96
+ | - [createdAt](#createdAt ) | No | Combination | No | - | (Read-only) Server-generated creation timestamp. |
97
+ | - [updatedAt](#updatedAt ) | No | Combination | No | - | (Read-only) Server-generated update timestamp. |
98
+ | + [createdBy](#createdBy ) | No | string | No | - | (Immutable) FK → User/staff UID who created the app. |
99
+ | + [analyticsEnabled](#analyticsEnabled ) | No | boolean | No | - | Feature flag — when false, clients should not emit analytics events for this app. |
100
+ | - [lastAnalyticsSync](#lastAnalyticsSync ) | No | Combination | No | - | (Read-only) Last time the analytics rollup pipeline refreshed \`cachedMetrics\`. |
101
+ | - [cachedMetrics](#cachedMetrics ) | No | object or null | No | - | (Read-only, Denormalized) Cached metrics snapshot for quick dashboard rendering. |
100
102
 
101
103
  ## <a name="id"></a>1. Property `id`
102
104
 
@@ -144,13 +146,28 @@ Set at creation only. This field cannot be modified after the document is create
144
146
 
145
147
  ## <a name="status"></a>5. Property `status`
146
148
 
149
+ | | |
150
+ | ------------------------- | ---------------- |
151
+ | **Type** | `combining` |
152
+ | **Required** | No |
153
+ | **Additional properties** | Any type allowed |
154
+
155
+ **Description:** Lifecycle status (D41/D44). Optional pending backfill of pre-existing records (#26) — treat absent as ACTIVE. Clients filter by ACTIVE.
156
+
157
+ | Any of(Option) |
158
+ | ------------------------------ |
159
+ | [app-status](#status_anyOf_i0) |
160
+ | [item 1](#status_anyOf_i1) |
161
+
162
+ ### <a name="status_anyOf_i0"></a>5.1. Property `app-status`
163
+
147
164
  | | |
148
165
  | -------------- | ------------------------ |
149
166
  | **Type** | `enum (of string)` |
150
- | **Required** | Yes |
167
+ | **Required** | No |
151
168
  | **Defined in** | #/definitions/app-status |
152
169
 
153
- **Description:** Lifecycle status (D41/D44). Clients filter by ACTIVE.
170
+ **Description:** Lifecycle status for an App (formerly Site — renamed per decision #40 / D44). Drives whether the app is reachable and whether analytics/payments flow.
154
171
 
155
172
  Must be one of:
156
173
  * "ACTIVE"
@@ -158,12 +175,19 @@ Must be one of:
158
175
  * "EXPIRED"
159
176
  * "ARCHIVED"
160
177
 
178
+ ### <a name="status_anyOf_i1"></a>5.2. Property `item 1`
179
+
180
+ | | |
181
+ | ------------ | ------ |
182
+ | **Type** | `null` |
183
+ | **Required** | No |
184
+
161
185
  :::note
162
- ACTIVE = live and serving traffic. INACTIVE = intentionally disabled by operators. EXPIRED = past expiresAt (derived when isExpired is true; may also be stored explicitly). ARCHIVED = soft-deleted; retained for audit but not listed by default.
186
+ Real Firestore documents may be missing this field on pre-backfill records (#26). Treat absent as ACTIVE. A backfill script will populate status=ACTIVE on all existing documents; once confirmed, this field will be promoted to required.
163
187
  :::
164
188
 
165
189
  :::tip When to set
166
- Written by operators via dashboard or by server triggers (expiration). Clients filter by ACTIVE.
190
+ Written by operators via dashboard or by server triggers (expiration). Clients must not use server-side `where(status == ACTIVE)` until backfill is complete — filter client-side instead, treating absent as ACTIVE.
167
191
  :::
168
192
 
169
193
  :::info See also
@@ -546,7 +570,7 @@ Do not include in write requests. This field is set exclusively by the server (F
546
570
  **Description:** Timestamp of the most recent analytics event seen for this app.
547
571
 
548
572
  ----------------------------------------------------------------------------------------------------------------------------
549
- Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-05-30 at 12:42:50 +0000
573
+ Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-05-30 at 13:38:44 +0000
550
574
 
551
575
  :::warning Server-set
552
576
  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.
@@ -270,7 +270,7 @@ Dot-notation paths for nested fields (e.g. "bookingDates.0.status"). Populated b
270
270
  | **Additional properties** | Any type allowed |
271
271
 
272
272
  ----------------------------------------------------------------------------------------------------------------------------
273
- Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-05-30 at 12:42:51 +0000
273
+ Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-05-30 at 13:38:45 +0000
274
274
 
275
275
  :::warning Server-set
276
276
  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.
@@ -1739,7 +1739,7 @@ Set at creation only. This field cannot be modified after the document is create
1739
1739
  **Description:** When true, suppresses Firebase notification triggers (D20/IG-8).
1740
1740
 
1741
1741
  ----------------------------------------------------------------------------------------------------------------------------
1742
- Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-05-30 at 12:42:51 +0000
1742
+ Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-05-30 at 13:38:45 +0000
1743
1743
 
1744
1744
  ## Related Decisions
1745
1745
 
@@ -0,0 +1,454 @@
1
+ ---
2
+ title: "Contract"
3
+ sidebar_label: "Contract"
4
+ sidebar_position: 10
5
+ ---
6
+
7
+ # Contract
8
+
9
+ <details>
10
+ <summary>Example JSON</summary>
11
+
12
+ ```json
13
+ {
14
+ "id": null,
15
+ "companyId": "comp_xyz789",
16
+ "payeeId": "pay_ref123",
17
+ "title": "title",
18
+ "description": null,
19
+ "status": "status",
20
+ "currency": "XOF",
21
+ "totalAmount": 45000,
22
+ "startDate": "2026-02-15",
23
+ "endDate": null,
24
+ "milestones": null,
25
+ "notes": null,
26
+ "createdBy": "staff_k0f1",
27
+ "createdAt": "createdAt",
28
+ "updatedAt": "updatedAt"
29
+ }
30
+ ```
31
+
32
+ </details>
33
+
34
+
35
+ - [1. Property `id`](#id)
36
+ - [2. Property `companyId`](#companyId)
37
+ - [3. Property `payeeId`](#payeeId)
38
+ - [4. Property `title`](#title)
39
+ - [5. Property `description`](#description)
40
+ - [6. Property `status`](#status)
41
+ - [7. Property `currency`](#currency)
42
+ - [8. Property `totalAmount`](#totalAmount)
43
+ - [9. Property `startDate`](#startDate)
44
+ - [10. Property `endDate`](#endDate)
45
+ - [11. Property `milestones`](#milestones)
46
+ - [11.1. milestones items](#milestones_items)
47
+ - [11.1.1. Property `id`](#milestones_items_id)
48
+ - [11.1.2. Property `title`](#milestones_items_title)
49
+ - [11.1.3. Property `amount`](#milestones_items_amount)
50
+ - [11.1.4. Property `dueDate`](#milestones_items_dueDate)
51
+ - [11.1.5. Property `status`](#milestones_items_status)
52
+ - [11.1.6. Property `invoicedAt`](#milestones_items_invoicedAt)
53
+ - [11.1.6.1. Property `_seconds`](#milestones_items_invoicedAt__seconds)
54
+ - [11.1.6.2. Property `_nanoseconds`](#milestones_items_invoicedAt__nanoseconds)
55
+ - [11.1.7. Property `paidAt`](#milestones_items_paidAt)
56
+ - [11.1.8. Property `notes`](#milestones_items_notes)
57
+ - [12. Property `notes`](#notes)
58
+ - [13. Property `createdBy`](#createdBy)
59
+ - [14. Property `createdAt`](#createdAt)
60
+ - [14.1. Property `firestore-timestamp`](#createdAt_anyOf_i0)
61
+ - [14.2. Property `item 1`](#createdAt_anyOf_i1)
62
+ - [15. Property `updatedAt`](#updatedAt)
63
+ - [15.1. Property `firestore-timestamp`](#updatedAt_anyOf_i0)
64
+ - [15.2. Property `item 1`](#updatedAt_anyOf_i1)
65
+
66
+ | | |
67
+ | ------------------------- | ---------------------- |
68
+ | **Type** | `object` |
69
+ | **Required** | No |
70
+ | **Additional properties** | Not allowed |
71
+ | **Defined in** | #/definitions/contract |
72
+
73
+ **Description:** Contract model (GH#14/#17/#18). Collection: companies/\{companyId\}/contracts/\{contractId\}. Service/supplier contract between a company and a Payee. No isActive field — query by status. Currency locked to XOF. Milestones use MilestoneStatus enum (no stored OVERDUE).
74
+
75
+ | Property | Pattern | Type | Deprecated | Definition | Title/Description |
76
+ | ------------------------------ | ------- | ----------------------- | ---------- | -------------------------------- | ----------------------------------------------------------------------------------------------------- |
77
+ | - [id](#id ) | No | string or null | No | - | (Read-only) Firestore document ID, auto-generated. |
78
+ | + [companyId](#companyId ) | No | string | No | - | (Immutable) FK → Company document ID. |
79
+ | + [payeeId](#payeeId ) | No | string | No | - | (Immutable) FK → Payee document ID. Full Payee model tracked in #20. |
80
+ | + [title](#title ) | No | string | No | - | Contract title or reference name shown in dashboards. |
81
+ | - [description](#description ) | No | string or null | No | - | Optional freeform description of the contract scope. |
82
+ | + [status](#status ) | No | enum (of string) | No | In #/definitions/contract-status | Contract lifecycle status (#14). Query by ACTIVE — do not use an isActive boolean. |
83
+ | + [currency](#currency ) | No | const | No | - | Currency code. Locked to XOF (#18). Multi-currency support requires a deliberate schema version bump. |
84
+ | + [totalAmount](#totalAmount ) | No | number | No | - | Total contract value (XOF). |
85
+ | + [startDate](#startDate ) | No | string | No | - | Contract start date (ISO 8601 YYYY-MM-DD). |
86
+ | - [endDate](#endDate ) | No | string or null | No | - | Contract end date (ISO 8601 YYYY-MM-DD). Absent for open-ended contracts. |
87
+ | - [milestones](#milestones ) | No | array of object or null | No | - | Ordered list of payment milestones. Embedded in the contract document (#17). |
88
+ | - [notes](#notes ) | No | string or null | No | - | Optional internal notes. |
89
+ | + [createdBy](#createdBy ) | No | string | No | - | (Immutable) FK → User/staff UID who created the contract. |
90
+ | - [createdAt](#createdAt ) | No | Combination | No | - | (Read-only) Server-generated creation timestamp. |
91
+ | - [updatedAt](#updatedAt ) | No | Combination | No | - | (Read-only) Server-generated update timestamp. |
92
+
93
+ ## <a name="id"></a>1. Property `id`
94
+
95
+ | | |
96
+ | ------------ | ---------------- |
97
+ | **Type** | `string or null` |
98
+ | **Required** | No |
99
+
100
+ **Description:** (Read-only) Firestore document ID, auto-generated.
101
+
102
+ :::warning Server-set
103
+ 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.
104
+ :::
105
+
106
+ ## <a name="companyId"></a>2. Property `companyId`
107
+
108
+ | | |
109
+ | ------------ | -------- |
110
+ | **Type** | `string` |
111
+ | **Required** | Yes |
112
+
113
+ **Description:** (Immutable) FK → Company document ID.
114
+
115
+ :::info Immutable
116
+ 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.
117
+ :::
118
+
119
+ ## <a name="payeeId"></a>3. Property `payeeId`
120
+
121
+ | | |
122
+ | ------------ | -------- |
123
+ | **Type** | `string` |
124
+ | **Required** | Yes |
125
+
126
+ **Description:** (Immutable) FK → Payee document ID. Full Payee model tracked in #20.
127
+
128
+ :::info Immutable
129
+ 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.
130
+ :::
131
+
132
+ ## <a name="title"></a>4. Property `title`
133
+
134
+ | | |
135
+ | ------------ | -------- |
136
+ | **Type** | `string` |
137
+ | **Required** | Yes |
138
+
139
+ **Description:** Contract title or reference name shown in dashboards.
140
+
141
+ ## <a name="description"></a>5. Property `description`
142
+
143
+ | | |
144
+ | ------------ | ---------------- |
145
+ | **Type** | `string or null` |
146
+ | **Required** | No |
147
+
148
+ **Description:** Optional freeform description of the contract scope.
149
+
150
+ ## <a name="status"></a>6. Property `status`
151
+
152
+ | | |
153
+ | -------------- | ----------------------------- |
154
+ | **Type** | `enum (of string)` |
155
+ | **Required** | Yes |
156
+ | **Defined in** | #/definitions/contract-status |
157
+
158
+ **Description:** Contract lifecycle status (#14). Query by ACTIVE — do not use an isActive boolean.
159
+
160
+ Must be one of:
161
+ * "DRAFT"
162
+ * "ACTIVE"
163
+ * "COMPLETED"
164
+ * "TERMINATED"
165
+
166
+ ## <a name="currency"></a>7. Property `currency`
167
+
168
+ | | |
169
+ | ------------ | ------- |
170
+ | **Type** | `const` |
171
+ | **Required** | Yes |
172
+
173
+ **Description:** Currency code. Locked to XOF (#18). Multi-currency support requires a deliberate schema version bump.
174
+
175
+ Specific value: `"XOF"`
176
+
177
+ ## <a name="totalAmount"></a>8. Property `totalAmount`
178
+
179
+ | | |
180
+ | ------------ | -------- |
181
+ | **Type** | `number` |
182
+ | **Required** | Yes |
183
+
184
+ **Description:** Total contract value (XOF).
185
+
186
+ ## <a name="startDate"></a>9. Property `startDate`
187
+
188
+ | | |
189
+ | ------------ | -------- |
190
+ | **Type** | `string` |
191
+ | **Required** | Yes |
192
+
193
+ **Description:** Contract start date (ISO 8601 YYYY-MM-DD).
194
+
195
+ ## <a name="endDate"></a>10. Property `endDate`
196
+
197
+ | | |
198
+ | ------------ | ---------------- |
199
+ | **Type** | `string or null` |
200
+ | **Required** | No |
201
+
202
+ **Description:** Contract end date (ISO 8601 YYYY-MM-DD). Absent for open-ended contracts.
203
+
204
+ ## <a name="milestones"></a>11. Property `milestones`
205
+
206
+ | | |
207
+ | ------------ | ------------------------- |
208
+ | **Type** | `array of object or null` |
209
+ | **Required** | No |
210
+
211
+ **Description:** Ordered list of payment milestones. Embedded in the contract document (#17).
212
+
213
+ | | Array restrictions |
214
+ | -------------------- | ------------------ |
215
+ | **Min items** | N/A |
216
+ | **Max items** | N/A |
217
+ | **Items unicity** | False |
218
+ | **Additional items** | False |
219
+ | **Tuple validation** | See below |
220
+
221
+ | Each item of this array must be | Description |
222
+ | ------------------------------------- | ------------------------------------------------------------------------------------- |
223
+ | [milestones items](#milestones_items) | ContractMilestone — embedded sub-object on Contract (#17). Not a separate collection. |
224
+
225
+ ### <a name="milestones_items"></a>11.1. milestones items
226
+
227
+ | | |
228
+ | ------------------------- | ----------- |
229
+ | **Type** | `object` |
230
+ | **Required** | No |
231
+ | **Additional properties** | Not allowed |
232
+
233
+ **Description:** ContractMilestone — embedded sub-object on Contract (#17). Not a separate collection.
234
+
235
+ | Property | Pattern | Type | Deprecated | Definition | Title/Description |
236
+ | --------------------------------------------- | ------- | ---------------- | ---------- | --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
237
+ | + [id](#milestones_items_id ) | No | string | No | - | Client-generated milestone ID (UUID or slug). Unique within the contract. |
238
+ | + [title](#milestones_items_title ) | No | string | No | - | Milestone description or deliverable name. |
239
+ | + [amount](#milestones_items_amount ) | No | number | No | - | Amount due at this milestone (XOF). |
240
+ | - [dueDate](#milestones_items_dueDate ) | No | string | No | - | ISO 8601 date string (YYYY-MM-DD) when the milestone is due. OVERDUE is derived at read time from dueDate — not stored. |
241
+ | + [status](#milestones_items_status ) | No | enum (of string) | No | In #/definitions/milestone-status | Milestone payment status (#17). OVERDUE is derived at read time from dueDate, not stored. |
242
+ | - [invoicedAt](#milestones_items_invoicedAt ) | No | object | No | In #/definitions/firestore-timestamp | When the invoice was issued for this milestone. |
243
+ | - [paidAt](#milestones_items_paidAt ) | No | object | No | Same as [invoicedAt](#milestones_items_invoicedAt ) | When payment was received for this milestone. |
244
+ | - [notes](#milestones_items_notes ) | No | string | No | - | Optional notes for this milestone. |
245
+
246
+ #### <a name="milestones_items_id"></a>11.1.1. Property `id`
247
+
248
+ | | |
249
+ | ------------ | -------- |
250
+ | **Type** | `string` |
251
+ | **Required** | Yes |
252
+
253
+ **Description:** Client-generated milestone ID (UUID or slug). Unique within the contract.
254
+
255
+ #### <a name="milestones_items_title"></a>11.1.2. Property `title`
256
+
257
+ | | |
258
+ | ------------ | -------- |
259
+ | **Type** | `string` |
260
+ | **Required** | Yes |
261
+
262
+ **Description:** Milestone description or deliverable name.
263
+
264
+ #### <a name="milestones_items_amount"></a>11.1.3. Property `amount`
265
+
266
+ | | |
267
+ | ------------ | -------- |
268
+ | **Type** | `number` |
269
+ | **Required** | Yes |
270
+
271
+ **Description:** Amount due at this milestone (XOF).
272
+
273
+ #### <a name="milestones_items_dueDate"></a>11.1.4. Property `dueDate`
274
+
275
+ | | |
276
+ | ------------ | -------- |
277
+ | **Type** | `string` |
278
+ | **Required** | No |
279
+
280
+ **Description:** ISO 8601 date string (YYYY-MM-DD) when the milestone is due. OVERDUE is derived at read time from dueDate — not stored.
281
+
282
+ #### <a name="milestones_items_status"></a>11.1.5. Property `status`
283
+
284
+ | | |
285
+ | -------------- | ------------------------------ |
286
+ | **Type** | `enum (of string)` |
287
+ | **Required** | Yes |
288
+ | **Defined in** | #/definitions/milestone-status |
289
+
290
+ **Description:** Milestone payment status (#17). OVERDUE is derived at read time from dueDate, not stored.
291
+
292
+ Must be one of:
293
+ * "PENDING"
294
+ * "INVOICED"
295
+ * "PAID"
296
+
297
+ #### <a name="milestones_items_invoicedAt"></a>11.1.6. Property `invoicedAt`
298
+
299
+ | | |
300
+ | ------------------------- | --------------------------------- |
301
+ | **Type** | `object` |
302
+ | **Required** | No |
303
+ | **Additional properties** | Not allowed |
304
+ | **Defined in** | #/definitions/firestore-timestamp |
305
+
306
+ **Description:** When the invoice was issued for this milestone.
307
+
308
+ | Property | Pattern | Type | Deprecated | Definition | Title/Description |
309
+ | ------------------------------------------------------------ | ------- | ------- | ---------- | ---------- | ----------------- |
310
+ | + [_seconds](#milestones_items_invoicedAt__seconds ) | No | integer | No | - | - |
311
+ | + [_nanoseconds](#milestones_items_invoicedAt__nanoseconds ) | No | integer | No | - | - |
312
+
313
+ ##### <a name="milestones_items_invoicedAt__seconds"></a>11.1.6.1. Property `_seconds`
314
+
315
+ | | |
316
+ | ------------ | --------- |
317
+ | **Type** | `integer` |
318
+ | **Required** | Yes |
319
+
320
+ | Restrictions | |
321
+ | ------------ | ---------------------- |
322
+ | **Minimum** | &ge; -9007199254740991 |
323
+ | **Maximum** | &le; 9007199254740991 |
324
+
325
+ ##### <a name="milestones_items_invoicedAt__nanoseconds"></a>11.1.6.2. Property `_nanoseconds`
326
+
327
+ | | |
328
+ | ------------ | --------- |
329
+ | **Type** | `integer` |
330
+ | **Required** | Yes |
331
+
332
+ | Restrictions | |
333
+ | ------------ | ---------------------- |
334
+ | **Minimum** | &ge; -9007199254740991 |
335
+ | **Maximum** | &le; 9007199254740991 |
336
+
337
+ #### <a name="milestones_items_paidAt"></a>11.1.7. Property `paidAt`
338
+
339
+ | | |
340
+ | ------------------------- | ------------------------------------------ |
341
+ | **Type** | `object` |
342
+ | **Required** | No |
343
+ | **Additional properties** | Not allowed |
344
+ | **Same definition as** | [invoicedAt](#milestones_items_invoicedAt) |
345
+
346
+ **Description:** When payment was received for this milestone.
347
+
348
+ #### <a name="milestones_items_notes"></a>11.1.8. Property `notes`
349
+
350
+ | | |
351
+ | ------------ | -------- |
352
+ | **Type** | `string` |
353
+ | **Required** | No |
354
+
355
+ **Description:** Optional notes for this milestone.
356
+
357
+ ## <a name="notes"></a>12. Property `notes`
358
+
359
+ | | |
360
+ | ------------ | ---------------- |
361
+ | **Type** | `string or null` |
362
+ | **Required** | No |
363
+
364
+ **Description:** Optional internal notes.
365
+
366
+ ## <a name="createdBy"></a>13. Property `createdBy`
367
+
368
+ | | |
369
+ | ------------ | -------- |
370
+ | **Type** | `string` |
371
+ | **Required** | Yes |
372
+
373
+ **Description:** (Immutable) FK → User/staff UID who created the contract.
374
+
375
+ :::info Immutable
376
+ 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.
377
+ :::
378
+
379
+ ## <a name="createdAt"></a>14. Property `createdAt`
380
+
381
+ | | |
382
+ | ------------------------- | ---------------- |
383
+ | **Type** | `combining` |
384
+ | **Required** | No |
385
+ | **Additional properties** | Any type allowed |
386
+
387
+ **Description:** (Read-only) Server-generated creation timestamp.
388
+
389
+ | Any of(Option) |
390
+ | ------------------------------------------ |
391
+ | [firestore-timestamp](#createdAt_anyOf_i0) |
392
+ | [item 1](#createdAt_anyOf_i1) |
393
+
394
+ ### <a name="createdAt_anyOf_i0"></a>14.1. Property `firestore-timestamp`
395
+
396
+ | | |
397
+ | ------------------------- | ------------------------------------------ |
398
+ | **Type** | `object` |
399
+ | **Required** | No |
400
+ | **Additional properties** | Not allowed |
401
+ | **Same definition as** | [invoicedAt](#milestones_items_invoicedAt) |
402
+
403
+ **Description:** Firestore Timestamp — Admin SDK form: \{ _seconds, _nanoseconds \}. See types/firestore.ts for REST API v1 and client SDK serialization notes (#10).
404
+
405
+ ### <a name="createdAt_anyOf_i1"></a>14.2. Property `item 1`
406
+
407
+ | | |
408
+ | ------------ | ------ |
409
+ | **Type** | `null` |
410
+ | **Required** | No |
411
+
412
+ :::warning Server-set
413
+ 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.
414
+ :::
415
+
416
+ ## <a name="updatedAt"></a>15. Property `updatedAt`
417
+
418
+ | | |
419
+ | ------------------------- | ---------------- |
420
+ | **Type** | `combining` |
421
+ | **Required** | No |
422
+ | **Additional properties** | Any type allowed |
423
+
424
+ **Description:** (Read-only) Server-generated update timestamp.
425
+
426
+ | Any of(Option) |
427
+ | ------------------------------------------ |
428
+ | [firestore-timestamp](#updatedAt_anyOf_i0) |
429
+ | [item 1](#updatedAt_anyOf_i1) |
430
+
431
+ ### <a name="updatedAt_anyOf_i0"></a>15.1. Property `firestore-timestamp`
432
+
433
+ | | |
434
+ | ------------------------- | ------------------------------------------ |
435
+ | **Type** | `object` |
436
+ | **Required** | No |
437
+ | **Additional properties** | Not allowed |
438
+ | **Same definition as** | [invoicedAt](#milestones_items_invoicedAt) |
439
+
440
+ **Description:** Firestore Timestamp — Admin SDK form: \{ _seconds, _nanoseconds \}. See types/firestore.ts for REST API v1 and client SDK serialization notes (#10).
441
+
442
+ ### <a name="updatedAt_anyOf_i1"></a>15.2. Property `item 1`
443
+
444
+ | | |
445
+ | ------------ | ------ |
446
+ | **Type** | `null` |
447
+ | **Required** | No |
448
+
449
+ ----------------------------------------------------------------------------------------------------------------------------
450
+ Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-05-30 at 13:38:45 +0000
451
+
452
+ :::warning Server-set
453
+ 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
+ :::