platform-types 1.10.853 → 1.10.855

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.
@@ -6,18 +6,24 @@
6
6
  *
7
7
  * The HANDLE is 16 base62 characters (~95 bits), stored server-side and a
8
8
  * bearer credential over exactly ONE service order of one store. It authorises
9
- * the read (`GET /services/tracking?handle=`) and the current presupuesto PDF
10
- * (`GET /services/tracking?handle=&mode=quote-pdf`), and nothing else. Every
9
+ * the read (`GET /services/tracking?handle=`), the current presupuesto PDF
10
+ * (`GET /services/tracking?handle=&mode=quote-pdf`) and the online decision on
11
+ * that presupuesto, and nothing else. Every
11
12
  * earlier link of an order dies when staff revoke it. A link stops reading
12
13
  * `serviceTrackingLinkDaysAfterClose` days (platform global, default 90) after
13
14
  * the order reached a terminal status.
14
15
  *
16
+ * With the gate on, the customer may also approve (with a 6-digit code sent to
17
+ * the contact on file) or reject the current presupuesto
18
+ * (`POST /services/tracking/quote`, or signed in
19
+ * `POST /user { mode: 'service-quote-decision' }`).
20
+ *
15
21
  * The gate is `ecommerce.config.serviceTracking` AND the `workshop` module on.
16
22
  * With the gate off, staff cannot mint and the signed-in reads refuse, but a
17
23
  * link minted earlier keeps reading (STORE_MODULES rule 4).
18
24
  */
19
25
  Object.defineProperty(exports, "__esModule", { value: true });
20
- exports.SERVICE_TRACKING_HANDLE_RE = exports.SERVICE_TRACKING_PATH_PREFIX = exports.SERVICE_TRACKING_LINK_ACTIONS = exports.SERVICE_TRACKING_OPERATOR_ERROR_CODES = exports.SERVICE_TRACKING_ACCOUNT_ERROR_CODES = exports.SERVICE_TRACKING_ERROR_CODES = void 0;
26
+ exports.SERVICE_TRACKING_HANDLE_RE = exports.SERVICE_TRACKING_PATH_PREFIX = exports.SERVICE_TRACKING_LINK_ACTIONS = exports.SERVICE_TRACKING_CODE_RE = exports.SERVICE_TRACKING_CHALLENGE_HANDLE_RE = exports.SERVICE_TRACKING_QUOTE_DECISIONS = exports.SERVICE_TRACKING_CODE_VIAS = exports.SERVICE_TRACKING_DECISION_ERROR_CODES = exports.SERVICE_TRACKING_OPERATOR_ERROR_CODES = exports.SERVICE_TRACKING_ACCOUNT_ERROR_CODES = exports.SERVICE_TRACKING_ERROR_CODES = void 0;
21
27
  /**
22
28
  * The refusals the PUBLIC tracking routes answer themselves.
23
29
  *
@@ -56,6 +62,53 @@ exports.SERVICE_TRACKING_OPERATOR_ERROR_CODES = [
56
62
  'SERVICE_TRACKING_LINK_LAPSED',
57
63
  'ADMIN_REQUIRED',
58
64
  ];
65
+ /**
66
+ * The refusals of the customer's online quote decision — by link
67
+ * (`POST /services/tracking/code`, `POST /services/tracking/quote`) and signed in
68
+ * (`POST /user { mode: 'service-quote-decision' }`).
69
+ *
70
+ * - SERVICE_TRACKING_TOKEN_INVALID (401, link only): the handle cannot be
71
+ * honoured — the same one body as the read.
72
+ * - SERVICE_TRACKING_VERIFICATION_FAILED (401, link approve only): no code, a
73
+ * wrong, used, expired or burnt one, or a challenge minted for another order.
74
+ * One body for every reason.
75
+ * - SERVICE_TRACKING_DISABLED (403): the store's gate is off. The read keeps working.
76
+ * - SERVICE_ORDER_NOT_FOUND (404, signed in only): no such order, a disabled
77
+ * one, or another customer's — one body.
78
+ * - SERVICE_QUOTE_NOT_FOUND (404): no version with that `quoteId`.
79
+ * - SERVICE_QUOTE_SUPERSEDED (409): a newer version replaced it.
80
+ * - SERVICE_QUOTE_ALREADY_RESOLVED (409): it already carries the OTHER decision
81
+ * (the same decision again answers 200 with the current view and writes nothing).
82
+ * - SERVICE_QUOTE_LAPSED (409, approve only): past `expiresAt`. A rejection is
83
+ * still accepted.
84
+ * - SERVICE_ORDER_QUOTE_CHANGED (409): the order moved under the decision — retry.
85
+ * - SERVICE_ORDER_TERMINAL / SERVICE_ORDER_DISABLED (409): the ticket is closed
86
+ * or deleted.
87
+ * - SERVICE_QUOTE_HOLDS_TOO_MANY (400, approve only): the version's parts cannot
88
+ * be reserved in one write; the shop must re-quote.
89
+ */
90
+ exports.SERVICE_TRACKING_DECISION_ERROR_CODES = [
91
+ 'SERVICE_TRACKING_TOKEN_INVALID',
92
+ 'SERVICE_TRACKING_VERIFICATION_FAILED',
93
+ 'SERVICE_TRACKING_DISABLED',
94
+ 'SERVICE_ORDER_NOT_FOUND',
95
+ 'SERVICE_QUOTE_NOT_FOUND',
96
+ 'SERVICE_QUOTE_SUPERSEDED',
97
+ 'SERVICE_QUOTE_ALREADY_RESOLVED',
98
+ 'SERVICE_QUOTE_LAPSED',
99
+ 'SERVICE_ORDER_QUOTE_CHANGED',
100
+ 'SERVICE_ORDER_TERMINAL',
101
+ 'SERVICE_ORDER_DISABLED',
102
+ 'SERVICE_QUOTE_HOLDS_TOO_MANY',
103
+ ];
104
+ /** Where the 6-digit decision code is sent: the phone or the email on file. */
105
+ exports.SERVICE_TRACKING_CODE_VIAS = ['sms', 'email'];
106
+ /** The customer's two online answers to a presupuesto. */
107
+ exports.SERVICE_TRACKING_QUOTE_DECISIONS = ['approve', 'reject'];
108
+ /** A decision challenge handle: 16 random bytes, base64url (22 characters). */
109
+ exports.SERVICE_TRACKING_CHALLENGE_HANDLE_RE = /^[\w-]{22}$/;
110
+ /** The decision code: 6 digits. */
111
+ exports.SERVICE_TRACKING_CODE_RE = /^\d{6}$/;
59
112
  /** `POST /services { mode: 'trackingLink' }` actions. */
60
113
  exports.SERVICE_TRACKING_LINK_ACTIONS = ['mint', 'revoke'];
61
114
  /** The storefront path a tracking link opens: `/servicio/{handle}`. */
@@ -26,6 +26,10 @@ const storefrontDesignRegistry_ts_1 = require("./storefrontDesignRegistry.js");
26
26
  * parameters.
27
27
  */
28
28
  exports.STOREFRONT_WEB_LITERAL_KEYS = Object.freeze([
29
+ 'ADDRESSES_IS_DEFAULT',
30
+ 'ADDRESSES_LIMIT_REACHED',
31
+ 'ADDRESSES_NOT_FOUND',
32
+ 'ADDRESSES_WRITE_CONTENDED',
29
33
  'ALERT_INCLUDED_VAT',
30
34
  'APPOINTMENTS_BOOKED_DESC',
31
35
  'APPOINTMENTS_BOOKED_TITLE',
@@ -323,9 +327,11 @@ exports.STOREFRONT_WEB_LITERAL_KEYS = Object.freeze([
323
327
  'BASKET_LINE_LIMIT_REACHED',
324
328
  'BASKET_LINE_NOT_LOADED',
325
329
  'BASKET_LINE_NOT_OFFERED',
330
+ 'BASKET_LINE_NO_PRICE',
326
331
  'BASKET_LINE_OUT_OF_STOCK',
327
332
  'BASKET_LINE_STOCK_SHORT_HIDDEN',
328
333
  'BASKET_LINE_UNAVAILABLE',
334
+ 'BASKET_LINE_WITHDRAWN',
329
335
  'BASKET_LOADING',
330
336
  'BASKET_MIN_BUY_MISSING',
331
337
  'BASKET_NEXT_BUTTON',
@@ -356,8 +362,28 @@ exports.STOREFRONT_WEB_LITERAL_KEYS = Object.freeze([
356
362
  'BASKET_UNDO_ACTION',
357
363
  'BASKET_UPDATED_CONFIRMATION',
358
364
  'BASKET_VIEW_BASKET_ACTION',
365
+ 'BRANDS_DIRECTORY_EMPTY',
359
366
  'BRANDS_ERR_LOAD',
367
+ 'BRANDS_FILTER_ALL',
368
+ 'BRANDS_JUMP_LABEL',
369
+ 'BRANDS_LETTERS_LABEL',
370
+ 'BRANDS_LETTER_OTHER',
371
+ 'BRANDS_LETTER_OTHER_LABEL',
372
+ 'BRANDS_SEARCH_CLEAR',
373
+ 'BRANDS_SEARCH_LABEL',
374
+ 'BRANDS_SHOW_MORE',
360
375
  'BRANDS_TITLE',
376
+ 'BRAND_BREADCRUMB_LABEL',
377
+ 'BRAND_DESCRIPTION_MORE',
378
+ 'CATEGORY_DIRECTORY_EMPTY',
379
+ 'CATEGORY_DIRECTORY_EMPTY_ACTION',
380
+ 'CATEGORY_DIRECTORY_FAILED',
381
+ 'CATEGORY_DIRECTORY_JUMP_LABEL',
382
+ 'CATEGORY_MORE_ROOTS_TITLE',
383
+ 'CATEGORY_SHOW_LESS',
384
+ 'CATEGORY_SIBLINGS_LABEL',
385
+ 'CATEGORY_SUBCATEGORIES_LABEL',
386
+ 'CATEGORY_VIEW_ALL',
361
387
  'CHECKOUT_ACCESS_PENDING',
362
388
  'CHECKOUT_ACCESS_REJECTED',
363
389
  'CHECKOUT_ACCOUNT_DISABLED',
@@ -426,7 +452,6 @@ exports.STOREFRONT_WEB_LITERAL_KEYS = Object.freeze([
426
452
  'CHECKOUT_DNI_REQUIRED_MESSAGE',
427
453
  'CHECKOUT_DNI_REQUIRED_MESSAGE_NO_THRESHOLD',
428
454
  'CHECKOUT_EDIT_BASKET',
429
- 'CHECKOUT_EMAIL_VERIFICATION_REQUIRED',
430
455
  'CHECKOUT_EMPTY_BASKET',
431
456
  'CHECKOUT_FX_NOTICE_PAYING',
432
457
  'CHECKOUT_FX_NOTICE_PREFERRED',
@@ -541,11 +566,13 @@ exports.STOREFRONT_WEB_LITERAL_KEYS = Object.freeze([
541
566
  'DATA_RIGHTS_COLLECTION_CONTACTS',
542
567
  'DATA_RIGHTS_COLLECTION_FAVORITES',
543
568
  'DATA_RIGHTS_COLLECTION_INVOICES',
569
+ 'DATA_RIGHTS_COLLECTION_LOYALTY',
544
570
  'DATA_RIGHTS_COLLECTION_NOTES',
545
571
  'DATA_RIGHTS_COLLECTION_ORDERS',
546
572
  'DATA_RIGHTS_COLLECTION_PAYMENTS',
547
573
  'DATA_RIGHTS_COLLECTION_QUOTE_REQUESTS',
548
574
  'DATA_RIGHTS_COLLECTION_RECENT_PURCHASES',
575
+ 'DATA_RIGHTS_COLLECTION_SERVICE_ORDERS',
549
576
  'DATA_RIGHTS_COLLECTION_WHOLESALE_REQUESTS',
550
577
  'DATA_RIGHTS_DIALOG_ACK',
551
578
  'DATA_RIGHTS_DIALOG_CONFIRM',
@@ -626,6 +653,11 @@ exports.STOREFRONT_WEB_LITERAL_KEYS = Object.freeze([
626
653
  'FAVORITES_TOGGLE_ARIA',
627
654
  'FAVORITES_TOGGLE_NAME',
628
655
  'FAVORITES_UNAVAILABLE',
656
+ 'FOOTER_DEFAULT_ACCOUNT_TITLE',
657
+ 'FOOTER_DEFAULT_CONTACT',
658
+ 'FOOTER_DEFAULT_HELP_TITLE',
659
+ 'FOOTER_DEFAULT_SHOP_TITLE',
660
+ 'FOOTER_LEGAL_NAV_ARIA',
629
661
  'FOOTER_PRIVACY_POLICY',
630
662
  'FORMS_FIELD_DNI_LABEL',
631
663
  'FORMS_FIELD_PHONE_LABEL',
@@ -672,7 +704,6 @@ exports.STOREFRONT_WEB_LITERAL_KEYS = Object.freeze([
672
704
  'FORMS_ZOD_VALUE_OPTIONS',
673
705
  'FORM_FIX_ERRORS',
674
706
  'GLOBALS_APPOINTMENTS',
675
- 'GLOBALS_APP_VERSION',
676
707
  'GLOBALS_BASKET',
677
708
  'GLOBALS_BRANDS',
678
709
  'GLOBALS_CATEGORIES',
@@ -744,6 +775,9 @@ exports.STOREFRONT_WEB_LITERAL_KEYS = Object.freeze([
744
775
  'HEADER_SEARCH_INPUT',
745
776
  'HEADER_SEARCH_LABEL',
746
777
  'HEADER_SEARCH_RECENT',
778
+ 'HEADER_SEARCH_RECENT_CLEAR',
779
+ 'HEADER_SEARCH_RECENT_CLEAR_ARIA',
780
+ 'HEADER_SEARCH_RECENT_REMOVE',
747
781
  'HEADER_SEARCH_SUGGESTIONS',
748
782
  'HEADER_SEARCH_SUGGESTION_BARCODE',
749
783
  'HEADER_SEARCH_SUGGESTION_SKU',
@@ -889,7 +923,9 @@ exports.STOREFRONT_WEB_LITERAL_KEYS = Object.freeze([
889
923
  'MAINTENANCE_REDIRECT_TO_BASKET',
890
924
  'MAINTENANCE_SUPPORT_HINT_EMAIL',
891
925
  'MAINTENANCE_SURVEY_DISABLED',
926
+ 'MAINTENANCE_WHATSAPP_OPT_IN_DISABLED',
892
927
  'MAINTENANCE_WHOLESALE_REQUEST_DISABLED',
928
+ 'MAINTENANCE_WITHDRAWAL_DISABLED',
893
929
  'MARKETING_ACTIVATE_ALL',
894
930
  'MARKETING_ACTIVE_COUNT',
895
931
  'MARKETING_CHANNEL_ADS',
@@ -898,12 +934,6 @@ exports.STOREFRONT_WEB_LITERAL_KEYS = Object.freeze([
898
934
  'MARKETING_CHANNEL_EMAIL',
899
935
  'MARKETING_CHANNEL_EMAIL_DESC',
900
936
  'MARKETING_CHANNEL_EMAIL_EXAMPLE',
901
- 'MARKETING_CHANNEL_SMS',
902
- 'MARKETING_CHANNEL_SMS_DESC',
903
- 'MARKETING_CHANNEL_SMS_EXAMPLE',
904
- 'MARKETING_CHANNEL_WHATSAPP',
905
- 'MARKETING_CHANNEL_WHATSAPP_DESC',
906
- 'MARKETING_CHANNEL_WHATSAPP_EXAMPLE',
907
937
  'MARKETING_DEACTIVATE_ALL',
908
938
  'MARKETING_ERROR_MESSAGE',
909
939
  'MARKETING_EXAMPLE_PREFIX',
@@ -923,6 +953,7 @@ exports.STOREFRONT_WEB_LITERAL_KEYS = Object.freeze([
923
953
  'MOBILE_BUTTONS_BASKET',
924
954
  'MOBILE_BUTTONS_FAVORITES',
925
955
  'MOBILE_BUTTONS_INVOICES',
956
+ 'MOBILE_BUTTONS_NAV_ARIA',
926
957
  'MOBILE_BUTTONS_ORDERS',
927
958
  'NETWORK_OFFLINE',
928
959
  'NETWORK_REQUEST_FAILED',
@@ -951,6 +982,10 @@ exports.STOREFRONT_WEB_LITERAL_KEYS = Object.freeze([
951
982
  'NOTIFICATION_PREFS_SUBTITLE',
952
983
  'NOTIFICATION_PREFS_TITLE',
953
984
  'NOTIFICATION_PREFS_UNAVAILABLE_RETRY',
985
+ 'NOTIFICATION_PREFS_WHATSAPP_ARIA',
986
+ 'NOTIFICATION_PREFS_WHATSAPP_DESCRIPTION',
987
+ 'NOTIFICATION_PREFS_WHATSAPP_LABEL',
988
+ 'NOTIFICATION_PREFS_WHATSAPP_NOT_SAVED',
954
989
  'NOT_FOUND_BACK_HOME',
955
990
  'NOT_FOUND_PAGE_BODY',
956
991
  'NOT_FOUND_PAGE_TITLE',
@@ -1179,6 +1214,7 @@ exports.STOREFRONT_WEB_LITERAL_KEYS = Object.freeze([
1179
1214
  'PREVIEW_UNAVAILABLE_ACTION',
1180
1215
  'PREVIEW_VARIANTS',
1181
1216
  'PREVIEW_WAITING',
1217
+ 'PRICING_NET_PLUS_IVA',
1182
1218
  'PRICING_TIER_CHIP',
1183
1219
  'PRICING_TIER_FROM',
1184
1220
  'PRICING_TIER_UNITS',
@@ -1189,10 +1225,14 @@ exports.STOREFRONT_WEB_LITERAL_KEYS = Object.freeze([
1189
1225
  'PRODUCTS_CLEAR_FILTERS',
1190
1226
  'PRODUCTS_FILTERS_LABEL',
1191
1227
  'PRODUCTS_FILTER_ALL_BRANDS',
1228
+ 'PRODUCTS_FILTER_ALL_CATEGORIES',
1192
1229
  'PRODUCTS_FILTER_ALL_PRODUCTS',
1193
1230
  'PRODUCTS_FILTER_ALL_TAGS',
1194
1231
  'PRODUCTS_FILTER_AVAILABILITY',
1195
1232
  'PRODUCTS_FILTER_BRAND',
1233
+ 'PRODUCTS_FILTER_BRAND_UNAVAILABLE',
1234
+ 'PRODUCTS_FILTER_CATEGORY',
1235
+ 'PRODUCTS_FILTER_CATEGORY_UNAVAILABLE',
1196
1236
  'PRODUCTS_FILTER_IN_OFFER',
1197
1237
  'PRODUCTS_FILTER_IN_STOCK',
1198
1238
  'PRODUCTS_FILTER_TAG',
@@ -1203,10 +1243,14 @@ exports.STOREFRONT_WEB_LITERAL_KEYS = Object.freeze([
1203
1243
  'PRODUCTS_NO_INCOMES',
1204
1244
  'PRODUCTS_NO_MATCHES',
1205
1245
  'PRODUCTS_NO_RESULTS',
1246
+ 'PRODUCTS_PICK_SUBCATEGORY',
1206
1247
  'PRODUCTS_SEARCH_TITLE',
1207
- 'PRODUCTS_SELECT_CATEGORY',
1208
1248
  'PRODUCTS_SORT_LABEL',
1249
+ 'PRODUCTS_SORT_NAME_ASC',
1250
+ 'PRODUCTS_SORT_NAME_DESC',
1209
1251
  'PRODUCTS_SORT_NEWEST',
1252
+ 'PRODUCTS_SORT_PRICE_ASC',
1253
+ 'PRODUCTS_SORT_PRICE_DESC',
1210
1254
  'PRODUCTS_SORT_RELEVANCE',
1211
1255
  'PRODUCTS_TAG_NOT_FOUND',
1212
1256
  'PRODUCTS_TAG_TITLE',
@@ -1250,6 +1294,8 @@ exports.STOREFRONT_WEB_LITERAL_KEYS = Object.freeze([
1250
1294
  'PRODUCT_INFO_TITLE',
1251
1295
  'PRODUCT_LOAD_FAILED',
1252
1296
  'PRODUCT_PAGE_TITLE',
1297
+ 'PRODUCT_PRICE_ON_REQUEST',
1298
+ 'PRODUCT_PRICE_ON_REQUEST_HINT',
1253
1299
  'PRODUCT_PRICE_PER_UNIT',
1254
1300
  'PRODUCT_PROMOTIONS_HINT',
1255
1301
  'PRODUCT_PROMOTIONS_TITLE',
@@ -1401,6 +1447,7 @@ exports.STOREFRONT_WEB_LITERAL_KEYS = Object.freeze([
1401
1447
  'QUOTE_REQUEST_SIGNED_IN_HINT',
1402
1448
  'QUOTE_REQUEST_SUBMIT',
1403
1449
  'QUOTE_REQUEST_SUCCESS',
1450
+ 'REORDER_SHELF_TITLE',
1404
1451
  'SALE_BADGE_OFFER',
1405
1452
  'SALE_CHIP_ALL',
1406
1453
  'SALE_DISCOUNT_PERCENT',
@@ -1489,6 +1536,14 @@ exports.STOREFRONT_WEB_LITERAL_KEYS = Object.freeze([
1489
1536
  'SURVEY_TITLE',
1490
1537
  'SYNC_ALERT_ERROR_MESSAGE',
1491
1538
  'SYNC_ALERT_OFFLINE_MESSAGE',
1539
+ 'WHATSAPP_OPT_IN_ERROR',
1540
+ 'WHATSAPP_OPT_IN_HELP_GUEST',
1541
+ 'WHATSAPP_OPT_IN_HELP_SIGNED_IN',
1542
+ 'WHATSAPP_OPT_IN_OFFER_ACTION',
1543
+ 'WHATSAPP_OPT_IN_OFFER_TEXT',
1544
+ 'WHATSAPP_OPT_IN_PROFILE_LINK',
1545
+ 'WHATSAPP_OPT_IN_SUCCESS',
1546
+ 'WHATSAPP_OPT_IN_UNAVAILABLE',
1492
1547
  'WHOLESALE_REQUEST_ACTIVITY_LABEL',
1493
1548
  'WHOLESALE_REQUEST_ALREADY_PENDING',
1494
1549
  'WHOLESALE_REQUEST_APPROVED',
@@ -731,6 +731,13 @@ declare global {
731
731
  * `balance` deltas. Those are arithmetic (`ADD balance :add`) precisely so
732
732
  * concurrent writers compose; replacing this array wholesale loses updates
733
733
  * the arithmetic next to it would have kept.
734
+ *
735
+ * ⚠️ **No wire carries it.** Every boundary that spreads a raw CUSTOMER row
736
+ * (the session responses, the operator point read, the write echo) strips
737
+ * it with `openDebitsOverflow`; only the server's own report reads it. A
738
+ * client showing a customer's open debits derives them from the ledger with
739
+ * `allocateAccountLedger` — this summary ignores order stamps and is capped,
740
+ * so the two can disagree.
734
741
  */
735
742
  openDebits?: OpenDebit[];
736
743
  /**
@@ -740,6 +747,7 @@ declare global {
740
747
  * ⚠️ Absence means "not overflowed", never "unknown" — but a reader must
741
748
  * still not treat a present-and-`false` value as proof the array is
742
749
  * complete on a row written before this field existed. Forward-only.
750
+ * Stripped from every wire with `openDebits`.
743
751
  */
744
752
  openDebitsOverflow?: boolean;
745
753
  /**
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './account.ts';
2
+ export * from './accountAllocation.ts';
2
3
  export * from './afip.ts';
3
4
  export * from './ai.ts';
4
5
  export * from './api.ts';
package/dist/index.js CHANGED
@@ -7,6 +7,7 @@
7
7
  // the published ESM build keeps the extension Node's resolver demands — bare
8
8
  // `export * from "./account"` would throw ERR_MODULE_NOT_FOUND at import time.
9
9
  export * from "./account.js";
10
+ export * from "./accountAllocation.js";
10
11
  export * from "./afip.js";
11
12
  export * from "./ai.js";
12
13
  export * from "./api.js";
@@ -214,6 +214,24 @@ export declare enum NotificationTypeEnum {
214
214
  * socket).
215
215
  */
216
216
  STOREFRONT_QUOTE_REQUEST = "STOREFRONT_QUOTE_REQUEST",
217
+ /**
218
+ * A customer approved or rejected a presupuesto online — by the tracking link
219
+ * (`POST /services/tracking/quote`) or signed in
220
+ * (`POST /user { mode: 'service-quote-decision' }`). The decision does not
221
+ * move the ticket's stage; the bell is the shop's cue to do it. Names the
222
+ * ticket number and the decision only — never the customer.
223
+ *
224
+ * ⚠️ ADMIN-ONLY, and its own preference key. The producer fans out to every
225
+ * non-disabled ADMIN of the store (`listActiveAdmins`), the same recipients
226
+ * as `STOREFRONT_QUOTE_REQUEST`. No legacy opt-in scan: the consumer enforces
227
+ * explicit type/channel preferences
228
+ * (`notificationPreferences.SERVICE_QUOTE_DECIDED`), default-on when absent.
229
+ * Additive — no backfill or consumer migration owed.
230
+ *
231
+ * ⚠️ Carries `serviceOrderRef` and NEVER a top-level `customerId` (an
232
+ * audience — the bell would reach the customer's own storefront socket).
233
+ */
234
+ SERVICE_QUOTE_DECIDED = "SERVICE_QUOTE_DECIDED",
217
235
  /**
218
236
  * A refund obligation went overdue: its due date passed and the hourly
219
237
  * sweep, after reconciling the payment, still found the money owed
@@ -383,6 +401,11 @@ declare global {
383
401
  * an audience — see {@link QuoteRequestRef}. Operator surfaces only.
384
402
  */
385
403
  quoteRequestRef?: QuoteRequestRef;
404
+ /**
405
+ * `SERVICE_QUOTE_DECIDED` only: which service order to open. A POINTER, not
406
+ * an audience — see {@link ServiceOrderRef}. Operator surfaces only.
407
+ */
408
+ serviceOrderRef?: ServiceOrderRef;
386
409
  /** `MENTION` only: the colleague who wrote the mention (a snapshot). */
387
410
  actor?: NotificationActor;
388
411
  userId?: string;
@@ -446,7 +469,7 @@ declare global {
446
469
  * customer socket carry — the stored row minus the operator-only pointers.
447
470
  * A union keyed on `type`; `ORDER` is its only member today.
448
471
  */
449
- type CustomerNotification = Omit<NotificationInterface, 'cartRef' | 'pendingCustomerRef' | 'wholesaleRequestRef' | 'quoteRequestRef' | 'TableName' | 'type' | 'orderId'> & {
472
+ type CustomerNotification = Omit<NotificationInterface, 'cartRef' | 'pendingCustomerRef' | 'wholesaleRequestRef' | 'quoteRequestRef' | 'serviceOrderRef' | 'TableName' | 'type' | 'orderId'> & {
450
473
  type: NotificationTypeEnum.ORDER;
451
474
  /** Set on every customer row: the order the bell is about. */
452
475
  orderId: string;
@@ -4,6 +4,7 @@
4
4
  // Addressed ERROR / ML_FACTURADOR_COLLISION / ML_SELLER_SWITCHED /
5
5
  // ML_CONNECTION_BROKEN / MENTION / CUSTOMER_PENDING_APPROVAL /
6
6
  // PAYMENT_ATTEMPT_RESOLUTION / CUSTOMER_WHOLESALE_REQUEST / STOREFRONT_QUOTE_REQUEST /
7
+ // SERVICE_QUOTE_DECIDED /
7
8
  // REFUND_OBLIGATION_OVERDUE / MESSAGE_CREDITS_LOW / MESSAGE_SKIPPED_NO_CREDITS do not select a
8
9
  // producer subscriber audience;
9
10
  // the consumer still reads the live USER row for each delivery channel.
@@ -234,6 +235,24 @@ export var NotificationTypeEnum;
234
235
  * socket).
235
236
  */
236
237
  NotificationTypeEnum["STOREFRONT_QUOTE_REQUEST"] = "STOREFRONT_QUOTE_REQUEST";
238
+ /**
239
+ * A customer approved or rejected a presupuesto online — by the tracking link
240
+ * (`POST /services/tracking/quote`) or signed in
241
+ * (`POST /user { mode: 'service-quote-decision' }`). The decision does not
242
+ * move the ticket's stage; the bell is the shop's cue to do it. Names the
243
+ * ticket number and the decision only — never the customer.
244
+ *
245
+ * ⚠️ ADMIN-ONLY, and its own preference key. The producer fans out to every
246
+ * non-disabled ADMIN of the store (`listActiveAdmins`), the same recipients
247
+ * as `STOREFRONT_QUOTE_REQUEST`. No legacy opt-in scan: the consumer enforces
248
+ * explicit type/channel preferences
249
+ * (`notificationPreferences.SERVICE_QUOTE_DECIDED`), default-on when absent.
250
+ * Additive — no backfill or consumer migration owed.
251
+ *
252
+ * ⚠️ Carries `serviceOrderRef` and NEVER a top-level `customerId` (an
253
+ * audience — the bell would reach the customer's own storefront socket).
254
+ */
255
+ NotificationTypeEnum["SERVICE_QUOTE_DECIDED"] = "SERVICE_QUOTE_DECIDED";
237
256
  /**
238
257
  * A refund obligation went overdue: its due date passed and the hourly
239
258
  * sweep, after reconciling the payment, still found the money owed
package/dist/payment.d.ts CHANGED
@@ -199,5 +199,77 @@ declare global {
199
199
  customers: CustomerCandidate[];
200
200
  orders: OrderCandidate[];
201
201
  }
202
+ /**
203
+ * `POST /payments/{source}/{paymentId}/link` with `mode: 'reverse-credit'` — ADMIN tier only
204
+ * (`ADMIN`, `SUPERVISOR`, `MANAGER`; anyone else `403 ADMIN_REQUIRED` — an `ACCOUNTANT` token never reaches
205
+ * the route: the API's accountant gate answers it `403 ROLE_FORBIDDEN` first), refused under impersonation
206
+ * (`payment.creditReverse`). Writes an `ACCOUNT#` row reversing the ledger credit the payment's link
207
+ * booked — on any day, whoever linked it (an operator, the MercadoLibre auto-link) — and moves the
208
+ * customer's balance back in the same transaction. The amount is the stored credit's (and its FX
209
+ * sibling's), never the caller's: the body carries no amount, account or customer. The link itself
210
+ * (customer, order, `Order.linkedPayments`) stays as it is.
211
+ */
212
+ interface PaymentCreditReversalRequest {
213
+ mode: 'reverse-credit';
214
+ /**
215
+ * Required: 10–500 characters after trimming, refused when it carries an email, phone, DNI, CUIT/CUIL,
216
+ * CBU, card number or token in a recognisable shape (`400 VALIDATION_FAILED`). Stored on the payment's
217
+ * per-source row and projected onto no wire (not the response, not `GET /payments/received`); not stored
218
+ * at all when the customer was erased. The audit row records its presence only.
219
+ */
220
+ reason: string;
221
+ }
222
+ /** One committed reversal: what was reversed, on whose balance, by how much. */
223
+ interface PaymentCreditReversal {
224
+ source: PaymentReceivedSource;
225
+ paymentId: string;
226
+ /** The link credit's `accountId`, and the reversal row's (`LINKREV#{creditAccountId}`). */
227
+ creditAccountId: string;
228
+ reversalAccountId: string;
229
+ /** Present when the link also booked an FX adjustment: that row, and the row reversing it. */
230
+ fxAdjustmentAccountId?: string;
231
+ fxReversalAccountId?: string;
232
+ /** Whose balance moved — the survivor, when the payment's customer was merged into another since. */
233
+ customerId: string;
234
+ /** What the customer's balance rose by, in the ledger `currency` (the credit plus its FX sibling's delta). */
235
+ amount: number;
236
+ currency: string;
237
+ reversedAt: number;
238
+ }
239
+ /** `data` of a successful credit reversal. */
240
+ interface PaymentCreditReversalResponse {
241
+ reversal: PaymentCreditReversal;
242
+ }
243
+ /** Every `error` the credit reversal answers itself — see {@link PAYMENT_CREDIT_REVERSAL_ERROR_CODES}. */
244
+ type PaymentCreditReversalErrorCode = (typeof PAYMENT_CREDIT_REVERSAL_ERROR_CODES)[number];
245
+ /** Every `reason` of the credit reversal's `409 LINK_LOCKED` — see {@link PAYMENT_CREDIT_REVERSAL_LOCK_REASONS}. */
246
+ type PaymentCreditReversalLockReason = (typeof PAYMENT_CREDIT_REVERSAL_LOCK_REASONS)[number];
202
247
  }
203
- export {};
248
+ /**
249
+ * The credit reversal's refusals (`PaymentCreditReversalRequest`). Each writes nothing.
250
+ *
251
+ * - `ADMIN_REQUIRED` · 403 — the token is below the ADMIN tier (an `ACCOUNTANT` is `403 ROLE_FORBIDDEN`, earlier).
252
+ * - `INVALID_INPUT` · 400 — the path's `source` is not `mp`, `stripe` or `mp_movement`.
253
+ * - `VALIDATION_FAILED` · 400 — the body is not `{ mode, reason }` or the reason is refused.
254
+ * - `PAYMENT_NOT_FOUND` · 404 — the store has no such payment.
255
+ * - `LINK_LOCKED` · 409 — `reason` is one of {@link PAYMENT_CREDIT_REVERSAL_LOCK_REASONS}.
256
+ * - `CUSTOMER_MERGED` · 409 — the credit's owner is mid-merge (or the payment carries a historical
257
+ * merged-refund flag); `data.mergedInto` names the survivor.
258
+ * - `CUSTOMER_ANONYMIZED` · 409 — a legacy credit naming no customer, on an erased customer.
259
+ * - `CUSTOMER_NOT_FOUND` · 404 — the customer whose balance the credit moved is gone.
260
+ */
261
+ export declare const PAYMENT_CREDIT_REVERSAL_ERROR_CODES: readonly ["ADMIN_REQUIRED", "INVALID_INPUT", "VALIDATION_FAILED", "PAYMENT_NOT_FOUND", "LINK_LOCKED", "CUSTOMER_MERGED", "CUSTOMER_ANONYMIZED", "CUSTOMER_NOT_FOUND"];
262
+ /**
263
+ * Every `reason` of the credit reversal's `409 LINK_LOCKED`:
264
+ *
265
+ * - `credit-reversed` — this credit was already reversed (`reversalAccountId` names the row): a second
266
+ * reversal of the same credit, a replay included.
267
+ * - `not-credited` — the payment's `accountId` names no credit of its own (never credited, or a pointer to
268
+ * a row this payment did not write), or the payment names no customer (un-linked by hand).
269
+ * - `refund-obligation` — a refund obligation already debited part of this credit as in transit
270
+ * (`refundObligationId`); reversing it all would debit that share twice.
271
+ * - `edited-ledger-pointer` — the payment's `fxAdjustmentAccountId` names a row that is not its own FX
272
+ * adjustment for the credit's customer, so the delta to reverse cannot be named.
273
+ * - `concurrent-link` — the payment or its ledger rows kept changing while the reversal ran; retry.
274
+ */
275
+ export declare const PAYMENT_CREDIT_REVERSAL_LOCK_REASONS: readonly ["credit-reversed", "not-credited", "refund-obligation", "edited-ledger-pointer", "concurrent-link"];
package/dist/payment.js CHANGED
@@ -1 +1,43 @@
1
- export {};
1
+ /**
2
+ * The credit reversal's refusals (`PaymentCreditReversalRequest`). Each writes nothing.
3
+ *
4
+ * - `ADMIN_REQUIRED` · 403 — the token is below the ADMIN tier (an `ACCOUNTANT` is `403 ROLE_FORBIDDEN`, earlier).
5
+ * - `INVALID_INPUT` · 400 — the path's `source` is not `mp`, `stripe` or `mp_movement`.
6
+ * - `VALIDATION_FAILED` · 400 — the body is not `{ mode, reason }` or the reason is refused.
7
+ * - `PAYMENT_NOT_FOUND` · 404 — the store has no such payment.
8
+ * - `LINK_LOCKED` · 409 — `reason` is one of {@link PAYMENT_CREDIT_REVERSAL_LOCK_REASONS}.
9
+ * - `CUSTOMER_MERGED` · 409 — the credit's owner is mid-merge (or the payment carries a historical
10
+ * merged-refund flag); `data.mergedInto` names the survivor.
11
+ * - `CUSTOMER_ANONYMIZED` · 409 — a legacy credit naming no customer, on an erased customer.
12
+ * - `CUSTOMER_NOT_FOUND` · 404 — the customer whose balance the credit moved is gone.
13
+ */
14
+ export const PAYMENT_CREDIT_REVERSAL_ERROR_CODES = [
15
+ 'ADMIN_REQUIRED',
16
+ 'INVALID_INPUT',
17
+ 'VALIDATION_FAILED',
18
+ 'PAYMENT_NOT_FOUND',
19
+ 'LINK_LOCKED',
20
+ 'CUSTOMER_MERGED',
21
+ 'CUSTOMER_ANONYMIZED',
22
+ 'CUSTOMER_NOT_FOUND',
23
+ ];
24
+ /**
25
+ * Every `reason` of the credit reversal's `409 LINK_LOCKED`:
26
+ *
27
+ * - `credit-reversed` — this credit was already reversed (`reversalAccountId` names the row): a second
28
+ * reversal of the same credit, a replay included.
29
+ * - `not-credited` — the payment's `accountId` names no credit of its own (never credited, or a pointer to
30
+ * a row this payment did not write), or the payment names no customer (un-linked by hand).
31
+ * - `refund-obligation` — a refund obligation already debited part of this credit as in transit
32
+ * (`refundObligationId`); reversing it all would debit that share twice.
33
+ * - `edited-ledger-pointer` — the payment's `fxAdjustmentAccountId` names a row that is not its own FX
34
+ * adjustment for the credit's customer, so the delta to reverse cannot be named.
35
+ * - `concurrent-link` — the payment or its ledger rows kept changing while the reversal ran; retry.
36
+ */
37
+ export const PAYMENT_CREDIT_REVERSAL_LOCK_REASONS = [
38
+ 'credit-reversed',
39
+ 'not-credited',
40
+ 'refund-obligation',
41
+ 'edited-ledger-pointer',
42
+ 'concurrent-link',
43
+ ];
package/dist/print.d.ts CHANGED
@@ -565,6 +565,12 @@ declare global {
565
565
  /** ms epoch of the LATEST transition. Plain assignment, moves every write — the recency value to display. */
566
566
  lastTransitionAt: number;
567
567
  useCase?: PrintUseCase;
568
+ /**
569
+ * The automatic-print event (`Store.config.autoPrint`) that minted this job — stamped once, on the
570
+ * job's first `queued` write by the automatic-print consumer, and never cleared. ABSENT means a
571
+ * manual print (or a job written before this field existed — forward-only, never backfilled).
572
+ */
573
+ autoPrintEvent?: keyof StoreAutoPrintConfig;
568
574
  agentId?: string;
569
575
  printerId?: string;
570
576
  orderId?: string;
package/dist/product.d.ts CHANGED
@@ -59,6 +59,13 @@ declare global {
59
59
  * `netOfNationalTaxes` when the product is rated.
60
60
  */
61
61
  prices?: PublicPriceSlot[];
62
+ /**
63
+ * The product's GTIN, derived from its barcodes (never sent): the first one
64
+ * typed `EAN8`, `UPC`, `EAN13` or `GTIN14` that passes the GS1 check digit and
65
+ * is not restricted circulation (02/20–29, store-generated). Absent when none
66
+ * qualifies, and on a partial frame that did not carry the barcodes.
67
+ */
68
+ gtin?: string;
62
69
  };
63
70
  /** Anonymous Web GET /products lookup; the tenant comes from the public store context. */
64
71
  interface PublicProductsByIdsInput {