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

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 (42) hide show
  1. package/data/docs/collections/firestore-paths.md +48 -0
  2. package/data/docs/decisions/migrations.md +56 -0
  3. package/data/docs/decisions/summary.md +78 -0
  4. package/data/docs/enums/booking-status.md +26 -0
  5. package/data/docs/enums/customer-payment-status.md +26 -0
  6. package/data/docs/enums/customer-payment-target-type.md +23 -0
  7. package/data/docs/enums/delivery-type.md +23 -0
  8. package/data/docs/enums/event-status.md +30 -0
  9. package/data/docs/enums/fulfillment-status.md +32 -0
  10. package/data/docs/enums/loyalty-transaction-type.md +32 -0
  11. package/data/docs/enums/order-status.md +65 -0
  12. package/data/docs/enums/payment-method.md +36 -0
  13. package/data/docs/enums/payment-proof-status.md +23 -0
  14. package/data/docs/enums/payment-status.md +34 -0
  15. package/data/docs/enums/return-status.md +32 -0
  16. package/data/docs/enums/session-status.md +32 -0
  17. package/data/docs/enums/ticket-status.md +29 -0
  18. package/data/docs/index.md +95 -0
  19. package/data/docs/models/booking-version.md +295 -0
  20. package/data/docs/models/booking.md +1754 -0
  21. package/data/docs/models/customer-payment-allocation.md +336 -0
  22. package/data/docs/models/customer-payment.md +392 -0
  23. package/data/docs/models/customer.md +475 -0
  24. package/data/docs/models/event.md +386 -0
  25. package/data/docs/models/loyalty-config.md +317 -0
  26. package/data/docs/models/loyalty-reward.md +236 -0
  27. package/data/docs/models/loyalty-status.md +328 -0
  28. package/data/docs/models/loyalty-transaction.md +326 -0
  29. package/data/docs/models/metrics-current.md +532 -0
  30. package/data/docs/models/metrics-daily.md +548 -0
  31. package/data/docs/models/metrics-monthly.md +548 -0
  32. package/data/docs/models/order-item.md +361 -0
  33. package/data/docs/models/order.md +1637 -0
  34. package/data/docs/models/sale.md +540 -0
  35. package/data/docs/models/ticket.md +405 -0
  36. package/data/docs/triggers/event-ticket-triggers.md +204 -0
  37. package/data/docs/triggers/loyalty-automation.md +123 -0
  38. package/data/static/decisions.json +966 -0
  39. package/data/static/llms.txt +1046 -0
  40. package/data/static/openapi.yaml +3090 -0
  41. package/data/static/schemas.json +4012 -0
  42. package/package.json +1 -1
@@ -0,0 +1,123 @@
1
+ ---
2
+ title: "Loyalty Automation Triggers"
3
+ sidebar_label: "Loyalty Automation"
4
+ sidebar_position: 1
5
+ ---
6
+
7
+ # Loyalty Automation Triggers
8
+
9
+ > **Decision**: D23 (locked) — Firebase owns loyalty point automation: award, expire, and validate server-side.
10
+ > **Wave**: 3 — Server-Side Logic.
11
+ > **Status**: Specified. Not yet implemented.
12
+
13
+ These triggers run when loyalty transactions are written to Firestore. Their job is to keep `loyalty/status` counters consistent and set `pointsBalanceAfter` on each transaction.
14
+
15
+ ---
16
+
17
+ ## `onLoyaltyTransactionCreate`
18
+
19
+ Fires when a new [`LoyaltyTransaction`](/models/loyalty-transaction) document is created.
20
+
21
+ **Path**: `companies/{companyId}/customers/{customerId}/loyaltyTransactions/{transactionId}`
22
+ **Event**: `onCreate`
23
+
24
+ ### Behavior
25
+
26
+ 1. Read the new `LoyaltyTransaction` document.
27
+ 2. **Atomically** update the `loyalty/status` document at `companies/{companyId}/customers/{customerId}/loyalty/status`:
28
+
29
+ | Transaction type | `pointsBalance` | `totalPointsEarned` | `redeemedPoints` | `lastActivityDate` |
30
+ |---|---|---|---|---|
31
+ | `EARNED` | `+= pointsChange` | `+= pointsChange` | — | set to `changedAt` |
32
+ | `BONUS` | `+= pointsChange` | `+= pointsChange` | — | set to `changedAt` |
33
+ | `REDEEMED` | `-= pointsChange` (subtract abs value) | — | `+= pointsChange` | set to `changedAt` |
34
+ | `ADJUSTED` | `+= pointsChange` (can be negative) | — | — | set to `changedAt` |
35
+ | `EXPIRED` | `-= pointsChange` (subtract abs value) | — | — | set to `changedAt` |
36
+ | `REFUND` | `+= pointsChange` | — | `-= pointsChange` | set to `changedAt` |
37
+
38
+ 3. Write `pointsBalanceAfter` back to the transaction document (the running balance **after** this operation).
39
+ 4. Create or initialise the `loyalty/status` document if it does not exist.
40
+
41
+ ### Inputs
42
+
43
+ ```typescript
44
+ // onCreate event data
45
+ interface LoyaltyTransactionCreateEvent {
46
+ data: LoyaltyTransaction; // the new document
47
+ params: {
48
+ companyId: string;
49
+ customerId: string;
50
+ transactionId: string;
51
+ };
52
+ }
53
+ ```
54
+
55
+ ### Outputs
56
+
57
+ **Write 1** — Update `loyalty/status`:
58
+
59
+ ```typescript
60
+ // Partial update applied to: companies/{companyId}/customers/{customerId}/loyalty/status
61
+ {
62
+ pointsBalance: FieldValue.increment(delta), // sign depends on transaction type
63
+ totalPointsEarned: FieldValue.increment(delta), // only for EARNED and BONUS
64
+ redeemedPoints: FieldValue.increment(delta), // only for REDEEMED; decremented for REFUND
65
+ lastActivityDate: FieldValue.serverTimestamp(),
66
+ updatedAt: FieldValue.serverTimestamp(),
67
+ }
68
+ ```
69
+
70
+ **Write 2** — Patch `pointsBalanceAfter` back on the transaction:
71
+
72
+ ```typescript
73
+ // Patch applied to: companies/{companyId}/customers/{customerId}/loyaltyTransactions/{transactionId}
74
+ {
75
+ pointsBalanceAfter: <computed new balance>,
76
+ }
77
+ ```
78
+
79
+ :::warning Race condition
80
+ Both writes must be in a single **Firestore transaction** (not a batch). Using a transaction on the `loyalty/status` doc prevents two concurrent `onLoyaltyTransactionCreate` calls from producing an incorrect balance.
81
+ :::
82
+
83
+ :::note Welcome bonus
84
+ A `BONUS` transaction with `reason: "welcome_bonus"` is created by the server when a customer first enrolls. The trigger handles it identically to `EARNED`.
85
+ :::
86
+
87
+ ---
88
+
89
+ ## `onLoyaltyTransactionUpdate` (admin corrections only)
90
+
91
+ **Path**: `companies/{companyId}/customers/{customerId}/loyaltyTransactions/{transactionId}`
92
+ **Event**: `onUpdate`
93
+
94
+ ### Behavior
95
+
96
+ LoyaltyTransaction documents are marked `immutable` — clients must not update them. This trigger exists only to detect accidental or admin-tool writes and **re-heal** the `loyalty/status` balance.
97
+
98
+ 1. Compute the delta between the old and new `pointsChange` values.
99
+ 2. Apply the delta to `loyalty/status.pointsBalance`.
100
+ 3. Log the correction to `_validation_issues` (D36 log-and-heal).
101
+
102
+ :::info Scope
103
+ Only `pointsChange` corrections trigger a re-heal. Status updates or annotation changes are ignored.
104
+ :::
105
+
106
+ ---
107
+
108
+ ## Points Expiration (scheduled)
109
+
110
+ D23 also requires server-side expiration of stale points. This is a **scheduled Cloud Function** (not a Firestore trigger).
111
+
112
+ **Schedule**: Daily (configurable per company via `LoyaltyConfig.pointsExpirationDays`).
113
+
114
+ ### Behavior
115
+
116
+ For each company with `loyaltyConfig.pointsExpirationDays` set:
117
+ 1. Query `loyaltyTransactions` where `type = EARNED` and `transactionDate` is older than `pointsExpirationDays`.
118
+ 2. For each expiring transaction, create a new `LoyaltyTransaction` with `type = EXPIRED` and `pointsChange = -(originalPointsChange)`.
119
+ 3. The `onLoyaltyTransactionCreate` trigger handles the balance update automatically.
120
+
121
+ :::note
122
+ Expiration creates a new EXPIRED transaction rather than mutating the original EARNED transaction. This preserves the immutable audit trail.
123
+ :::