sinfactura-types 1.10.261 → 1.10.262
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/dist/customer.d.ts +50 -0
- package/dist/order.d.ts +50 -0
- package/package.json +1 -1
package/dist/customer.d.ts
CHANGED
|
@@ -191,6 +191,56 @@ declare global {
|
|
|
191
191
|
lastReminderAt?: number;
|
|
192
192
|
marketing?: CustomerMarketing;
|
|
193
193
|
minBuy?: number;
|
|
194
|
+
/**
|
|
195
|
+
* How many appointments this customer has been marked `NO_SHOW` for, so a
|
|
196
|
+
* booking-time policy can be evaluated SERVER-SIDE against a durable number
|
|
197
|
+
* instead of against whatever date window a browser happened to read. Two
|
|
198
|
+
* operators with different date filters derive different counts for the same
|
|
199
|
+
* customer; this field is the one both of them share.
|
|
200
|
+
*
|
|
201
|
+
* ⚠️ **NOT A HISTORICAL TOTAL — it counts from the day it shipped.** This
|
|
202
|
+
* repo is forward-only and never backfills, so a customer with years of
|
|
203
|
+
* prior no-shows starts ABSENT and reads exactly like one who has never
|
|
204
|
+
* missed an appointment. A policy that auto-flags at 4+ will treat a
|
|
205
|
+
* long-standing offender as clean until they accumulate four MORE. That is a
|
|
206
|
+
* known consequence, not an oversight: what to do about it (a grace window,
|
|
207
|
+
* an operator override, showing the client-derived range count beside this
|
|
208
|
+
* one) is the app's decision — but it must not be a surprise.
|
|
209
|
+
*
|
|
210
|
+
* ⚠️ **Absence means "nothing recorded since this shipped"**, never "never
|
|
211
|
+
* no-showed". Coerce with `noShowCount ?? 0` for arithmetic, but do not
|
|
212
|
+
* render that fallback as a measured zero.
|
|
213
|
+
*
|
|
214
|
+
* ⚠️ **A LOWER BOUND.** The bump is issued after the appointment's own
|
|
215
|
+
* status write has already committed, and is deliberately best-effort: an
|
|
216
|
+
* appointment must still be markable `NO_SHOW` when the customer row has
|
|
217
|
+
* since been deleted. A lost bump undercounts by one and can never
|
|
218
|
+
* overcount — so a threshold that has been crossed was really crossed.
|
|
219
|
+
*
|
|
220
|
+
* ⚠️ **MONOTONIC, because `NO_SHOW` is TERMINAL — there is no decrement
|
|
221
|
+
* path.** `stacks/services/appointments.ts`'s transition table gives
|
|
222
|
+
* `NO_SHOW` an empty successor list, and the two writers that could move a
|
|
223
|
+
* terminal row (`cancelAppointment`, `rescheduleAppointment`) both condition
|
|
224
|
+
* on the status still being one of the four non-terminal ones. A booking
|
|
225
|
+
* marked `NO_SHOW` in error is corrected by creating a new appointment, not
|
|
226
|
+
* by reverting the old one. If a revert is ever added it owes a
|
|
227
|
+
* floor-guarded decrement in the SAME change, and the app must stop
|
|
228
|
+
* treating this as monotonic on the same day.
|
|
229
|
+
*
|
|
230
|
+
* ⚠️ **Written by an atomic `ADD noShowCount :one`**, like the `ADD balance`
|
|
231
|
+
* deltas on this same row. Never read-modify-write it: two operators
|
|
232
|
+
* clearing the same morning's board would both read the same value and one
|
|
233
|
+
* of the two events would vanish silently.
|
|
234
|
+
*
|
|
235
|
+
* ⚠️ Deliberately absent from `CUSTOMER_LIST_DISPLAY_FIELDS`, and therefore
|
|
236
|
+
* from `CUSTOMER_OPERATOR_BROADCAST_FIELDS`, which is DEFINED as that list
|
|
237
|
+
* plus frame mechanics. Behavioural data about a named person (Ley 25.326)
|
|
238
|
+
* does not belong on a store-wide list served to every staff-tier token, and
|
|
239
|
+
* a customer must not receive their own tally on a socket. It is served by
|
|
240
|
+
* the capability-gated `?customerId=` point read — the surface a booking
|
|
241
|
+
* screen already uses.
|
|
242
|
+
*/
|
|
243
|
+
noShowCount?: number;
|
|
194
244
|
/**
|
|
195
245
|
* Unsettled debits denormalised onto this row so the accounts report can
|
|
196
246
|
* bucket them by age without a per-customer query — the same
|
package/dist/order.d.ts
CHANGED
|
@@ -97,8 +97,58 @@ declare global {
|
|
|
97
97
|
* drift. The APPOINTMENT is authoritative: it is the row the scheduler
|
|
98
98
|
* writes under a conditional update, and a stale pointer here must be
|
|
99
99
|
* treated as absent rather than followed.
|
|
100
|
+
*
|
|
101
|
+
* ⚠️ **This field, {@link Order.appointmentDate} and
|
|
102
|
+
* {@link Order.appointmentTime} are ONE stamp.** Every writer sets all
|
|
103
|
+
* three in a single `UpdateExpression` on this row (`SET` when a booking
|
|
104
|
+
* is made or moved, `REMOVE` when it is cancelled), so they cannot drift
|
|
105
|
+
* apart from ONE ANOTHER: all three present, or all three absent — the
|
|
106
|
+
* one exception being a row written before the date/time existed, which
|
|
107
|
+
* carries this pointer alone and is never backfilled. What can still lag
|
|
108
|
+
* is the stamp AS A WHOLE, because the write follows an already-committed
|
|
109
|
+
* appointment and is best-effort; that is the drift the paragraph above
|
|
110
|
+
* is about, and it is why the appointment stays authoritative.
|
|
100
111
|
*/
|
|
101
112
|
appointmentId?: string;
|
|
113
|
+
/**
|
|
114
|
+
* The booked slot's LOCAL date, `YYYYMMDD` in the store's (Buenos Aires)
|
|
115
|
+
* time — a copy of `Appointment.date`, denormalised so a page of orders
|
|
116
|
+
* can render, sort and filter a «Turno» column without reading the
|
|
117
|
+
* appointments table at all. The three alternatives it replaces are each
|
|
118
|
+
* wrong in a different way: a range read over appointments misses any
|
|
119
|
+
* booking outside the window, and renders "sin turno" on exactly the
|
|
120
|
+
* orders an operator is hunting for; a per-row lookup is N+1 with no
|
|
121
|
+
* `orderId` filter to collapse it; and neither can sort a grid by a key
|
|
122
|
+
* that is not on the row.
|
|
123
|
+
*
|
|
124
|
+
* ⚠️ **NOT a Unix timestamp.** `20260315` is the fifteenth of March, not
|
|
125
|
+
* an instant. It copies the AUTHORITATIVE local pair the appointment row
|
|
126
|
+
* is keyed by (`${date}#${startTime}#${appointmentId}`) rather than the
|
|
127
|
+
* derived `Appointment.startTimestamp`, so this row and that key can
|
|
128
|
+
* never denote different slots.
|
|
129
|
+
*
|
|
130
|
+
* ⚠️ **Absent means "nothing to render", and that includes an order
|
|
131
|
+
* written before this field existed.** The platform is forward-only and
|
|
132
|
+
* nothing backfills, so a row may carry {@link Order.appointmentId} with
|
|
133
|
+
* no date or time: render no turno rather than inventing one, and follow
|
|
134
|
+
* the pointer only from a detail view that can afford the read. The next
|
|
135
|
+
* booking or reschedule on such an order stamps all three.
|
|
136
|
+
*
|
|
137
|
+
* ⚠️ A COPY, for display and ordering. The APPOINTMENT stays
|
|
138
|
+
* authoritative for whether the slot is still live — a cancel clears the
|
|
139
|
+
* stamp, but a clear that failed leaves it stale, so nothing that charges
|
|
140
|
+
* money or promises a customer a time may read this without the
|
|
141
|
+
* appointment.
|
|
142
|
+
*/
|
|
143
|
+
appointmentDate?: number;
|
|
144
|
+
/**
|
|
145
|
+
* The booked slot's LOCAL start time, `HHmm` — a copy of
|
|
146
|
+
* `Appointment.startTime`, written and cleared by the same single update
|
|
147
|
+
* as {@link Order.appointmentDate} and under exactly the same rules:
|
|
148
|
+
* absent means nothing to render, and the appointment remains
|
|
149
|
+
* authoritative for whether the booking still stands.
|
|
150
|
+
*/
|
|
151
|
+
appointmentTime?: string;
|
|
102
152
|
/**
|
|
103
153
|
* OPTIONAL. The eleven readers that forced this to be required have all
|
|
104
154
|
* been closed, and the widening was gated on a measured zero-error
|