platform-types 1.10.738 → 1.10.740

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/auth.d.ts CHANGED
@@ -153,18 +153,23 @@ declare global {
153
153
  * (`storeContactFooter`), and `phone` also on the emisor block of every
154
154
  * invoice PDF.
155
155
  *
156
- * ⚠️ A STORE `email` is also a live DESTINATION from the first day, so the
157
- * client must confirm it is a MONITORED business address, not just a
158
- * public one:
159
- * - it is the `Reply-To` of every store-branded mail to the store's
160
- * customers sent under the platform envelope, so a customer's answer goes
161
- * there;
162
- * - it receives the storefront's survey responses (suppressed for a demo
163
- * store);
164
- * - it is the one recipient of the scheduled sales digest, once the store
165
- * opts in and is entitled to it;
166
- * - it is the last-resort recipient of an integration re-authorisation mail,
167
- * used when the request names no address and the founding admin has none.
156
+ * ⚠️ A STORE `email` becomes a DESTINATION once its inbox confirms it, so
157
+ * the client must confirm it is a MONITORED business address, not just a
158
+ * public one. Registering with it mails a single-use confirmation link
159
+ * there (platform-branded, valid 48 h), and until that link is followed:
160
+ * - customer-facing store-branded mail sent under the platform envelope
161
+ * carries NO `Reply-To`; once confirmed, the address is that `Reply-To`,
162
+ * so a customer's answer goes there. Customer mail never falls back to
163
+ * the founder's address;
164
+ * - the storefront's survey responses (suppressed for a demo store) and
165
+ * the scheduled sales digest (once the store opts in and is entitled
166
+ * to it) go to the founding admin's verified login email instead, and
167
+ * to no one when that account is disabled or its email unverified;
168
+ * once confirmed, they go to this address. Without a store `email`
169
+ * neither is sent at all;
170
+ * - an integration re-authorisation mail that names no address goes to
171
+ * the founding admin's verified login email, and to this address only
172
+ * when that one is unusable AND this one is confirmed.
168
173
  *
169
174
  * STRICT, like `acquisition`: an unknown key refuses the WHOLE
170
175
  * registration, and so does an empty object — send at least one key or
@@ -28,6 +28,23 @@ exports.DEFAULT_PURCHASE_MATCH_TOLERANCE = Object.freeze({ pct: 1 });
28
28
  * store's, or a receipt is not under it.
29
29
  * - `PURCHASE_ORDER_NOT_RECEIVABLE` · 409 — the purchase order is `draft` or
30
30
  * `cancelled`.
31
+ * - `RECEIPT_ALREADY_BILLED` · 409 — a receipt the bill names is already
32
+ * covered by another bill (`PurchaseReceipt.billedBy`); `data.receiptIds`
33
+ * lists them. Nothing is written.
34
+ * - `SUPPLIER_INVOICE_EDIT_CONFLICT` · 409 — an edit of a bill that stores or
35
+ * writes `receiptIds` (an empty list included) lost to another edit of the
36
+ * same bill that landed first and moved only the row version (when the
37
+ * `fce` block, the PDF or the payments moved too, that guard's own code
38
+ * answers); or a receipt the edit stops naming changed hands since the read;
39
+ * or the save met another transaction on the bill or one of its receipts
40
+ * in flight, and again on its one retry. Nothing is written; re-read the
41
+ * bill and retry.
42
+ * - `BILL_RECEIPT_CHANGE_TOO_LARGE` · 400 — the receipts the save would mark
43
+ * and unmark, plus the bill row, exceed one DynamoDB transaction (100
44
+ * items). Nothing is written; save the receipts in smaller steps.
45
+ * - `PURCHASE_RECEIPTS_READ_TRUNCATED` · 503 — the purchase order's receipt
46
+ * read was cut short, so the receipts to mark and the verdict cannot be
47
+ * decided. Nothing is written.
31
48
  * - `PURCHASE_ORDER_SUPPLIER_MISMATCH` · 400 — the bill's supplier is not the
32
49
  * purchase order's.
33
50
  * - `ADMIN_REQUIRED` · 403 — only ADMIN or MANAGER may override.
@@ -40,11 +57,15 @@ exports.DEFAULT_PURCHASE_MATCH_TOLERANCE = Object.freeze({ pct: 1 });
40
57
  * purchase-order line the bill's order does not have, one whose `productId`
41
58
  * differs, one another bill line already names, or names one with no
42
59
  * purchase order on the bill.
43
- * - `VALIDATION_FAILED` · 400
60
+ * - `VALIDATION_FAILED` · 400 — includes `receiptIds` naming one receipt twice.
44
61
  */
45
62
  exports.SUPPLIER_INVOICE_MATCH_ERROR_CODES = [
46
63
  'RECEIPT_NOT_ON_PURCHASE_ORDER',
47
64
  'PURCHASE_ORDER_NOT_RECEIVABLE',
65
+ 'RECEIPT_ALREADY_BILLED',
66
+ 'SUPPLIER_INVOICE_EDIT_CONFLICT',
67
+ 'BILL_RECEIPT_CHANGE_TOO_LARGE',
68
+ 'PURCHASE_RECEIPTS_READ_TRUNCATED',
48
69
  'PURCHASE_ORDER_SUPPLIER_MISMATCH',
49
70
  'ADMIN_REQUIRED',
50
71
  'SUPPLIER_INVOICE_NOT_FOUND',
@@ -100,6 +100,15 @@ declare global {
100
100
  warehouseId?: string;
101
101
  /** Operator note. ⚠️ Never personal data — this row is not scrubbed and has no TTL. */
102
102
  notes?: string;
103
+ /**
104
+ * SERVER-OWNED. The `invoiceId` of the vendor bill that covers this receipt.
105
+ * Set and cleared only by the vendor-bill writer (`POST /suppliers
106
+ * { mode: 'invoice' }`), in the same transaction as that bill's row and
107
+ * under a condition that refuses a second bill (`409 RECEIPT_ALREADY_BILLED`);
108
+ * never read from a request body. Absent on a receipt no bill covers, and on
109
+ * receipts billed before the marker existed.
110
+ */
111
+ billedBy?: string;
103
112
  items: PurchaseReceiptItem[];
104
113
  }
105
114
  /** The fields every receipt line carries, whichever quantity and cost it names. */
package/dist/store.d.ts CHANGED
@@ -409,6 +409,34 @@ declare global {
409
409
  /** Unix ms — the registration's own `createdAt`, the instant the STORE item is stamped with. */
410
410
  capturedAt: number;
411
411
  }
412
+ /**
413
+ * The ownership check on the STORE row's `email`: whether whoever reads that
414
+ * inbox has confirmed it, by following a single-use link the api mailed to it.
415
+ *
416
+ * ⚠️ Server-owned: no request body may set it. Every write that puts a NEW
417
+ * `email` on the row stamps it `pending` for that exact address; the
418
+ * confirmation link flips it to `verified` only while the row still holds
419
+ * that address. Clearing `email` KEEPS the record: it names the address it
420
+ * is about, so it can only vouch for a later `email` that really is that
421
+ * verified address.
422
+ *
423
+ * ABSENT means verified (rows that predate it are grandfathered); a PRESENT
424
+ * record that is `null` or malformed counts as unverified. The one reader of
425
+ * "verified" is `isStoreEmailVerified` (`stacks/helpers/storeEmailVerified.ts`).
426
+ */
427
+ interface StoreEmailVerification {
428
+ /** `pending` until the link mailed to `address` is followed, then `verified`. */
429
+ status: 'pending' | 'verified';
430
+ /**
431
+ * The normalised address the record is about. A record whose `address` is
432
+ * not the row's current `email` says nothing about that email.
433
+ */
434
+ address: string;
435
+ /** Unix ms — when the api stamped it `pending`. */
436
+ requestedAt: number;
437
+ /** Unix ms — when the link was followed. Present only once `verified`. */
438
+ verifiedAt?: number;
439
+ }
412
440
  /**
413
441
  * The shop's public address, as every link minter and every client reads it.
414
442
  * Computed by the api from server-owned row fields that never reach a client
@@ -529,6 +557,16 @@ declare global {
529
557
  * and every operator-created tenant.
530
558
  */
531
559
  registrationPrefill?: StoreRegistrationPrefill;
560
+ /**
561
+ * Whether `email` has been confirmed by its inbox. Admin-only; written only
562
+ * by the server.
563
+ *
564
+ * ⚠️ **Absent means verified.** A row whose `email` predates verification
565
+ * carries no record, and that address is grandfathered as verified — it is
566
+ * never backfilled. Only a record that is `pending`, or `verified` for an
567
+ * address other than the current `email`, makes the email unverified.
568
+ */
569
+ emailVerification?: StoreEmailVerification;
532
570
  /**
533
571
  * Response-time join, not a persisted Store attribute — and TWO different
534
572
  * shapes depending on the endpoint: `GET /tenants` (SUPERVISOR) attaches the
@@ -215,7 +215,10 @@ declare global {
215
215
  /**
216
216
  * The receipts this bill covers, each under `purchaseOrderId`. When a write
217
217
  * names a purchase order and no receipts, the server stores every receipt
218
- * that order had at that moment.
218
+ * that order had at that moment and no other bill covers. At most one
219
+ * bill covers a receipt: each one named is marked with this bill's id
220
+ * (`PurchaseReceipt.billedBy`), and one another bill already covers is
221
+ * `409 RECEIPT_ALREADY_BILLED`.
219
222
  */
220
223
  receiptIds?: string[];
221
224
  /**
@@ -584,6 +587,23 @@ export declare const DEFAULT_PURCHASE_MATCH_TOLERANCE: Readonly<PurchaseMatchTol
584
587
  * store's, or a receipt is not under it.
585
588
  * - `PURCHASE_ORDER_NOT_RECEIVABLE` · 409 — the purchase order is `draft` or
586
589
  * `cancelled`.
590
+ * - `RECEIPT_ALREADY_BILLED` · 409 — a receipt the bill names is already
591
+ * covered by another bill (`PurchaseReceipt.billedBy`); `data.receiptIds`
592
+ * lists them. Nothing is written.
593
+ * - `SUPPLIER_INVOICE_EDIT_CONFLICT` · 409 — an edit of a bill that stores or
594
+ * writes `receiptIds` (an empty list included) lost to another edit of the
595
+ * same bill that landed first and moved only the row version (when the
596
+ * `fce` block, the PDF or the payments moved too, that guard's own code
597
+ * answers); or a receipt the edit stops naming changed hands since the read;
598
+ * or the save met another transaction on the bill or one of its receipts
599
+ * in flight, and again on its one retry. Nothing is written; re-read the
600
+ * bill and retry.
601
+ * - `BILL_RECEIPT_CHANGE_TOO_LARGE` · 400 — the receipts the save would mark
602
+ * and unmark, plus the bill row, exceed one DynamoDB transaction (100
603
+ * items). Nothing is written; save the receipts in smaller steps.
604
+ * - `PURCHASE_RECEIPTS_READ_TRUNCATED` · 503 — the purchase order's receipt
605
+ * read was cut short, so the receipts to mark and the verdict cannot be
606
+ * decided. Nothing is written.
587
607
  * - `PURCHASE_ORDER_SUPPLIER_MISMATCH` · 400 — the bill's supplier is not the
588
608
  * purchase order's.
589
609
  * - `ADMIN_REQUIRED` · 403 — only ADMIN or MANAGER may override.
@@ -596,9 +616,9 @@ export declare const DEFAULT_PURCHASE_MATCH_TOLERANCE: Readonly<PurchaseMatchTol
596
616
  * purchase-order line the bill's order does not have, one whose `productId`
597
617
  * differs, one another bill line already names, or names one with no
598
618
  * purchase order on the bill.
599
- * - `VALIDATION_FAILED` · 400
619
+ * - `VALIDATION_FAILED` · 400 — includes `receiptIds` naming one receipt twice.
600
620
  */
601
- export declare const SUPPLIER_INVOICE_MATCH_ERROR_CODES: readonly ["RECEIPT_NOT_ON_PURCHASE_ORDER", "PURCHASE_ORDER_NOT_RECEIVABLE", "PURCHASE_ORDER_SUPPLIER_MISMATCH", "ADMIN_REQUIRED", "SUPPLIER_INVOICE_NOT_FOUND", "SUPPLIER_INVOICE_MATCH_NOT_EXCEPTION", "INVOICE_LINES_TOTAL_MISMATCH", "INVOICE_LINE_NOT_ON_PURCHASE_ORDER", "VALIDATION_FAILED"];
621
+ export declare const SUPPLIER_INVOICE_MATCH_ERROR_CODES: readonly ["RECEIPT_NOT_ON_PURCHASE_ORDER", "PURCHASE_ORDER_NOT_RECEIVABLE", "RECEIPT_ALREADY_BILLED", "SUPPLIER_INVOICE_EDIT_CONFLICT", "BILL_RECEIPT_CHANGE_TOO_LARGE", "PURCHASE_RECEIPTS_READ_TRUNCATED", "PURCHASE_ORDER_SUPPLIER_MISMATCH", "ADMIN_REQUIRED", "SUPPLIER_INVOICE_NOT_FOUND", "SUPPLIER_INVOICE_MATCH_NOT_EXCEPTION", "INVOICE_LINES_TOTAL_MISMATCH", "INVOICE_LINE_NOT_ON_PURCHASE_ORDER", "VALIDATION_FAILED"];
602
622
  export type SupplierInvoiceMatchErrorCode = (typeof SUPPLIER_INVOICE_MATCH_ERROR_CODES)[number];
603
623
  /** Every `SupplierInvoicePaymentStatus`, as a runtime value. */
604
624
  export declare const SUPPLIER_INVOICE_PAYMENT_STATUSES: readonly ["open", "partial", "paid"];
package/dist/supplier.js CHANGED
@@ -25,6 +25,23 @@ export const DEFAULT_PURCHASE_MATCH_TOLERANCE = Object.freeze({ pct: 1 });
25
25
  * store's, or a receipt is not under it.
26
26
  * - `PURCHASE_ORDER_NOT_RECEIVABLE` · 409 — the purchase order is `draft` or
27
27
  * `cancelled`.
28
+ * - `RECEIPT_ALREADY_BILLED` · 409 — a receipt the bill names is already
29
+ * covered by another bill (`PurchaseReceipt.billedBy`); `data.receiptIds`
30
+ * lists them. Nothing is written.
31
+ * - `SUPPLIER_INVOICE_EDIT_CONFLICT` · 409 — an edit of a bill that stores or
32
+ * writes `receiptIds` (an empty list included) lost to another edit of the
33
+ * same bill that landed first and moved only the row version (when the
34
+ * `fce` block, the PDF or the payments moved too, that guard's own code
35
+ * answers); or a receipt the edit stops naming changed hands since the read;
36
+ * or the save met another transaction on the bill or one of its receipts
37
+ * in flight, and again on its one retry. Nothing is written; re-read the
38
+ * bill and retry.
39
+ * - `BILL_RECEIPT_CHANGE_TOO_LARGE` · 400 — the receipts the save would mark
40
+ * and unmark, plus the bill row, exceed one DynamoDB transaction (100
41
+ * items). Nothing is written; save the receipts in smaller steps.
42
+ * - `PURCHASE_RECEIPTS_READ_TRUNCATED` · 503 — the purchase order's receipt
43
+ * read was cut short, so the receipts to mark and the verdict cannot be
44
+ * decided. Nothing is written.
28
45
  * - `PURCHASE_ORDER_SUPPLIER_MISMATCH` · 400 — the bill's supplier is not the
29
46
  * purchase order's.
30
47
  * - `ADMIN_REQUIRED` · 403 — only ADMIN or MANAGER may override.
@@ -37,11 +54,15 @@ export const DEFAULT_PURCHASE_MATCH_TOLERANCE = Object.freeze({ pct: 1 });
37
54
  * purchase-order line the bill's order does not have, one whose `productId`
38
55
  * differs, one another bill line already names, or names one with no
39
56
  * purchase order on the bill.
40
- * - `VALIDATION_FAILED` · 400
57
+ * - `VALIDATION_FAILED` · 400 — includes `receiptIds` naming one receipt twice.
41
58
  */
42
59
  export const SUPPLIER_INVOICE_MATCH_ERROR_CODES = [
43
60
  'RECEIPT_NOT_ON_PURCHASE_ORDER',
44
61
  'PURCHASE_ORDER_NOT_RECEIVABLE',
62
+ 'RECEIPT_ALREADY_BILLED',
63
+ 'SUPPLIER_INVOICE_EDIT_CONFLICT',
64
+ 'BILL_RECEIPT_CHANGE_TOO_LARGE',
65
+ 'PURCHASE_RECEIPTS_READ_TRUNCATED',
45
66
  'PURCHASE_ORDER_SUPPLIER_MISMATCH',
46
67
  'ADMIN_REQUIRED',
47
68
  'SUPPLIER_INVOICE_NOT_FOUND',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "platform-types",
3
- "version": "1.10.738",
3
+ "version": "1.10.740",
4
4
  "description": "Shared wire and entity contracts for the platform.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",