sinfactura-types 1.10.39 → 1.10.41

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.
@@ -115,7 +115,15 @@ declare global {
115
115
  total: number;
116
116
  condition: PartCondition;
117
117
  }
118
- /** A technician work session logged against a service order (manual hours at V1). */
118
+ /**
119
+ * A technician work session logged against a service order (manual hours at V1).
120
+ *
121
+ * Deliberately carries NO parts. Parts live exclusively on the top-level
122
+ * `ServiceOrder.partsUsed` signed ledger, which is what stock movement is
123
+ * derived from; a per-work-log copy would be a second source of truth for
124
+ * the same movement and the two would drift. Log the hours here, post the
125
+ * parts to the ledger.
126
+ */
119
127
  interface WorkLog {
120
128
  workLogId: string;
121
129
  technicianId: string;
@@ -124,7 +132,6 @@ declare global {
124
132
  /** Hours worked in this session. */
125
133
  hours: number;
126
134
  description: string;
127
- partsUsed?: PartUsed[];
128
135
  }
129
136
  /** One entry in a service order's status history (append-only audit trail). */
130
137
  interface ServiceStatusEntry {
@@ -146,7 +153,18 @@ declare global {
146
153
  * stages (which would corrupt duration metrics).
147
154
  */
148
155
  type ServiceQuoteStatus = 'draft' | 'sent' | 'approved' | 'rejected' | 'expired' | 'superseded';
149
- /** How the customer's decision on a quote reached the shop. */
156
+ /**
157
+ * How the customer's decision on a quote reached the shop.
158
+ *
159
+ * ⚠️ `'portal'` is RESERVED and must not be offered to an operator. The other
160
+ * four are things an operator records second-hand; `'portal'` means the
161
+ * customer approved it themselves, and no customer-facing service endpoint
162
+ * exists on any gateway yet — so an operator selecting it would be recording
163
+ * an event that did not happen. The api rejects it: it is excluded from the
164
+ * `POST /services` quote-resolve enum and returns 400. It stays in the union
165
+ * so rows already carrying it still read back, and so the value is ready the
166
+ * day a customer portal ships. Filter it out of any channel picker.
167
+ */
150
168
  type ServiceQuoteChannel = 'in_person' | 'phone' | 'whatsapp' | 'email' | 'portal';
151
169
  /**
152
170
  * A customer decision on a quote version, recorded as an event rather than a
@@ -212,9 +230,30 @@ declare global {
212
230
  currencyValueAt?: number;
213
231
  /** Unix ms the deposit was taken. */
214
232
  at: number;
215
- /** Payment-method code, same vocabulary as `Order.paymentMethod`. */
233
+ /**
234
+ * Payment-method code — a bare FK into the tenant's OWN
235
+ * `Store.paymentMethods[]`, not a platform-wide enum.
236
+ *
237
+ * It draws on the same catalog as `Order.paymentMethod`, but do not read
238
+ * that as "both ends are checked": `Order.paymentMethod` is accepted
239
+ * unvalidated and only resolved at invoice issuance, where an unknown id
240
+ * freezes onto `Invoice.paymentCondition` as `''`. A deposit proves the
241
+ * referent before it writes.
242
+ */
216
243
  method: number;
217
244
  freezesPrice: boolean;
245
+ /**
246
+ * The `userId` who accepted the money.
247
+ *
248
+ * Optional only because of the forward-only rule — deposits written before
249
+ * this field existed cannot have it, and nothing backfills them. New
250
+ * writes always stamp it: a seña is the one place in the service-order
251
+ * domain where CASH changes hands, and a drawer that does not reconcile at
252
+ * close is unattributable without it. `statusHistory` and
253
+ * `ServiceQuoteApproval` already record `by` for decisions that move no
254
+ * money at all.
255
+ */
256
+ by?: string;
218
257
  /** Set once the deposit is applied against the final invoice. */
219
258
  appliedToInvoiceId?: string;
220
259
  }
@@ -238,6 +277,12 @@ declare global {
238
277
  interface ServiceOrderPicture {
239
278
  url: string;
240
279
  base64?: string;
280
+ /**
281
+ * Which photo leads its stage's gallery — a CLIENT affordance, exactly as
282
+ * on `Product.pictures`. The server accepts, stores and returns it and
283
+ * deliberately never branches on it, so finding no server-side reader is
284
+ * the expected result and not grounds to retire the field.
285
+ */
241
286
  primary?: boolean;
242
287
  stage: ServiceOrderPictureStage;
243
288
  }
@@ -432,8 +477,23 @@ declare global {
432
477
  * Absent while the job is still open, and absent forever on a ticket that
433
478
  * ends `cancelled`, `returned_unrepaired` or `abandoned_disposed` — none of
434
479
  * those deliver anything to bill.
480
+ *
481
+ * ⚠️ Deliberately has NO reader inside the api, and that is correct — see
482
+ * `invoiceId` below. Do not retire it for want of one.
435
483
  */
436
484
  orderId?: string;
485
+ /**
486
+ * The fiscal document issued for this service order, stamped when
487
+ * `POST /invoices` actually draws the voucher — in the same transaction as
488
+ * the `Invoice` put, so the join can never commit half-formed.
489
+ *
490
+ * ⚠️ Like `orderId`, NOTHING server-side branches on this, by design. Both
491
+ * exist so the row is self-describing on `GET`: their consumer is the
492
+ * client's linked-order card, where `invoiceId` alone answers "was this
493
+ * invoiced?" with no second fetch and `orderId` is the navigation target.
494
+ * An audit that finds no reader has found the intended state, not dead
495
+ * fields — do not remove them on that basis.
496
+ */
437
497
  invoiceId?: string;
438
498
  warrantyDays?: number;
439
499
  /** Unix ms the warranty expires (stamped at delivery). */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sinfactura-types",
3
- "version": "1.10.39",
3
+ "version": "1.10.41",
4
4
  "main": "dist/index.js",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",