platform-types 1.10.699 → 1.10.701

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/cash.d.ts CHANGED
@@ -104,13 +104,8 @@ declare global {
104
104
  * replays gross in and gross out. ⚠️ It is NOT `'refund'`, which is money
105
105
  * given BACK — a refund movement recorded on the shift, or the cash of a seña
106
106
  * refund (`POST /orders { mode: 'deposit-refund' }`, the net the seña kept).
107
- *
108
- * `'tip-payout'` is cash handed to a worker against their tip balance
109
- * (`POST /shifts/tips` `mode=payout`, `method=cash`) — an outcome, written in
110
- * the same transaction as the `TipBalance` debit. It is NOT a negative
111
- * `'tip'`, and a plain `'cash-out'` never debits a tip balance.
112
107
  */
113
- type CashEventType = 'apertura' | 'cash-in' | 'cash-out' | 'sale' | 'change' | 'refund' | 'tip' | 'tip-payout' | 'cierre' | 'reconcile';
108
+ type CashEventType = 'apertura' | 'cash-in' | 'cash-out' | 'sale' | 'change' | 'refund' | 'cierre' | 'reconcile';
114
109
  /**
115
110
  * A cashier's drawer shift — one per cashier per day. PK `STORE#{storeId}`,
116
111
  * SK `SHIFT#{shiftId}` where `shiftId = ${date}-${userId}`. State machine:
@@ -199,19 +194,6 @@ declare global {
199
194
  variance?: number;
200
195
  reconcileDecision?: 'approved' | 'rejected';
201
196
  reconcileNote?: string;
202
- /**
203
- * The net tips this shift received, per `CashEvent.recipientUserId`, in the
204
- * shift's currency: Σ income − Σ outcome over its `tip` events that name a
205
- * recipient. Stamped once, at close, and only when some recipient nets to a
206
- * non-zero amount.
207
- *
208
- * ⚠️ A summary, not a record: the tip ledger (`TipBalance`, `TipOperation`,
209
- * `TipEntry`) is the source of truth for what a worker is owed. `tip` events
210
- * with no recipient are excluded. Absent on every shift closed before the
211
- * ledger existed. It is not a compliance report: DNU 731/2024 creates no
212
- * AFIP/ARCA report for tips.
213
- */
214
- tipDistribution?: Record<string, number>;
215
197
  /**
216
198
  * The drawer's declared currency buckets, keyed by canonical currency
217
199
  * catalog id — one entry per currency the cashier declared at apertura.
@@ -219,8 +201,7 @@ declare global {
219
201
  *
220
202
  * ⚠️ THE PRIMARY-MIRROR RULE. `currency` names the primary (first-declared)
221
203
  * bucket, and the scalars `float`, `declaredCount`, `declaredDenominations`,
222
- * `expectedBalance`, `variance` and `tipDistribution` are the PRIMARY
223
- * bucket's figures. So a scalar reader keeps reading the primary bucket
204
+ * `expectedBalance` and `variance` are the PRIMARY bucket's figures. So a scalar reader keeps reading the primary bucket
224
205
  * correctly, and never a cross-currency total — no figure on this row ever
225
206
  * sums two buckets.
226
207
  *
@@ -228,8 +209,8 @@ declare global {
228
209
  * bucket through the api's responses (or its tolerant reader,
229
210
  * `shiftBuckets`), never by assuming `buckets[currency]` repeats them:
230
211
  * - A shift with ONE bucket stores `expectedBalance` and `variance` in the
231
- * scalars ONLY. Its bucket carries `float`, `declaredCount`,
232
- * `declaredDenominations` and `tipDistribution`. The blind target of a
212
+ * scalars ONLY. Its bucket carries `float`, `declaredCount` and
213
+ * `declaredDenominations`. The blind target of a
233
214
  * single-currency shift therefore has one home, the scalar every reader
234
215
  * already masks.
235
216
  * - A shift with two or more buckets stores every figure in every bucket,
@@ -277,8 +258,6 @@ declare global {
277
258
  * one-bucket shift.
278
259
  */
279
260
  variance?: number;
280
- /** Net tips per recipient over this currency's `tip` events — see `CashShift.tipDistribution`. */
281
- tipDistribution?: Record<string, number>;
282
261
  }
283
262
  /**
284
263
  * A `CashShiftBucket` as `GET /shifts` returns it — masked by the same rules
@@ -304,22 +283,6 @@ declare global {
304
283
  amount: number;
305
284
  direction?: 'income' | 'outcome';
306
285
  concept?: string;
307
- /**
308
- * On a `tip` event, the worker the tip belongs to — the caller by default,
309
- * or the active store user the movement named. Present exactly on the
310
- * ledger-backed tips: a `tip` event without it was recorded before the tip
311
- * ledger existed, stays in the drawer sum as before, and never becomes a
312
- * `TipBalance` or a `tipDistribution` entry. On a `tip-payout` event, the
313
- * worker who was paid.
314
- */
315
- recipientUserId?: string;
316
- /**
317
- * The `TipOperation.operationId` written in the same transaction as this
318
- * event. For a cash tip recorded as a drawer movement it equals `eventId`;
319
- * on a cash payout, or the compensation of a reversed cash tip or payout,
320
- * it is that act's client `operationId`.
321
- */
322
- tipOperationId?: string;
323
286
  currency: string;
324
287
  /**
325
288
  * The shift's own `CashShift.warehouseId`, copied onto every event so a
@@ -356,19 +319,14 @@ declare global {
356
319
  * `DELETE /account` of a cash movement whose mirror is a projection writes
357
320
  * one `'reversal'` with no rebook: the mirror's amount, copied, in the
358
321
  * opposite direction.
359
- *
360
- * A reversed cash tip or cash tip payout (`POST /shifts/tips`
361
- * `mode=reverse`) also writes one `'reversal'` event: a `tip` with direction
362
- * `outcome`, or a `tip-payout` with direction `income`. Its `direction` is
363
- * set explicitly — read it, never re-derive it from `type`.
364
322
  */
365
323
  compensation?: 'reversal' | 'rebook';
366
324
  }
367
325
  /**
368
326
  * `POST /shifts/{id}/movements` — a mid-shift drawer movement into the
369
327
  * caller's own OPEN drawer `{id}`. Mirrors the request side of the movement
370
- * schema in `stacks/lambdas/shifts/_postMovement.ts`; the schema strips unknown
371
- * keys, so the root `elevationToken` is read off the raw body.
328
+ * schema in `stacks/lambdas/shifts/_postMovement.ts`, which is strict: an unknown
329
+ * key is 400 VALIDATION_FAILED, and the root `elevationToken` is declared.
372
330
  *
373
331
  * From a PIN operator session, `type: 'refund'` is the `'shift.refund'`
374
332
  * elevated action and `type: 'cash-out'` is `'shift.cash-out'`; both bind the
@@ -377,19 +335,13 @@ declare global {
377
335
  * Held to its schema by `AssertShiftMovementRequestMatchesSchema`.
378
336
  */
379
337
  interface ShiftMovementRequest extends TerminalElevationAuthorization {
380
- type: 'cash-in' | 'cash-out' | 'refund' | 'tip';
338
+ type: 'cash-in' | 'cash-out' | 'refund';
381
339
  /** Above zero, at most the platform money-input cap. */
382
340
  amount: number;
383
341
  /** At most 500 characters. */
384
342
  concept?: string;
385
343
  /** A platform catalog id or ISO code the drawer declared. */
386
344
  currency?: string;
387
- /**
388
- * On a `tip` only — any other `type` carrying it is refused `400`, never
389
- * ignored. The worker the tip is owed to; defaults to the caller. Trimmed,
390
- * 1–64 characters.
391
- */
392
- recipientUserId?: string;
393
345
  }
394
346
  /**
395
347
  * A store's configurable bill/coin denomination catalog, used to validate a
@@ -513,131 +465,6 @@ declare global {
513
465
  /** Present and `true` only when the fold hit its page bound. */
514
466
  truncated?: boolean;
515
467
  }
516
- /**
517
- * What the store owes one worker in tips, in one currency. PK
518
- * `STORE#{storeId}`, SK `TIPBAL#{userId}#{currency}`.
519
- *
520
- * A tip is a LIABILITY the store holds for a named worker, never store
521
- * revenue (DNU 731/2024 art. 1 and 3). This row never enters the drawer sum:
522
- * the cash side of a tip is its `CashEvent`, and this is the worker's side.
523
- * Balances are per currency and are never converted.
524
- */
525
- interface TipBalance {
526
- storeId: string;
527
- userId: string;
528
- currency: string;
529
- /** Quantized to the currency's ledger scale. */
530
- owed: number;
531
- /**
532
- * When the balance was first credited after it was last zero (ms epoch).
533
- * DNU 731/2024 art. 7 gives the store 24 hours to make a tip available.
534
- * A debit that brings `owed` to exactly zero removes it; a partial debit
535
- * keeps the oldest credit's clock, so `overdue` errs early, never late.
536
- * The credit-back of a reversed payout is not new money: it restores the
537
- * clock to the payout's own `createdAt` unless an older clock is running.
538
- */
539
- owedSince?: number;
540
- updatedAt: number;
541
- }
542
- /**
543
- * A `TipBalance` as `GET /shifts/tips?mode=balances` answers it: `overdue` is
544
- * computed on read — true when some amount has been owed for more than 24
545
- * hours (`owedSince`). No cron and no notification stand behind it.
546
- */
547
- interface TipBalanceView extends TipBalance {
548
- overdue: boolean;
549
- }
550
- /** The acts the tip ledger records. */
551
- type TipOperationKind = 'receive' | 'allocate' | 'payout' | 'reverse';
552
- /**
553
- * One immutable tip act. PK `STORE#{storeId}`, SK `TIPOP#{operationId}`,
554
- * written under `attribute_not_exists(SK)` in the same transaction as every
555
- * balance it moves, so it is both the audit row and the idempotency anchor.
556
- */
557
- interface TipOperation {
558
- storeId: string;
559
- operationId: string;
560
- kind: TipOperationKind;
561
- /** How a `receive` arrived: through the drawer, or already in the store's account. */
562
- channel?: 'cash' | 'electronic';
563
- /** Approved provider payment backing this electronic receipt. */
564
- provider?: 'mercadopago' | 'stripe';
565
- providerPaymentId?: string;
566
- /** How a `payout` left (copied onto the `reverse` that undoes it). */
567
- method?: 'cash' | 'transfer';
568
- currency: string;
569
- amount: number;
570
- /** Who recorded the act. Provider-backed receipts may credit this same worker. */
571
- actorUserId: string;
572
- /** One signed delta per affected worker. */
573
- legs: {
574
- userId: string;
575
- delta: number;
576
- }[];
577
- /**
578
- * The drawer the act's `CashEvent` was written in — a cash `receive`, a cash
579
- * `payout`, or the compensation of a reversed cash act. Absent on a
580
- * ledger-only act.
581
- */
582
- shiftId?: string;
583
- /** The `CashEvent` the act wrote, under `shiftId`. */
584
- eventId?: string;
585
- /** An opaque client reference. Never read or written as an order. */
586
- orderId?: string;
587
- /** A `Store.paymentMethods` id, as an opaque reference. */
588
- paymentMethod?: number;
589
- note?: string;
590
- /** On a `reverse`: the `receive` or `payout` it undoes. */
591
- reversesOperationId?: string;
592
- /**
593
- * On a reversed `receive` or `payout`: the `reverse` that undid it. The ONE
594
- * attribute ever written onto a stored operation, set once under
595
- * `attribute_not_exists`, so an act is reversed at most once.
596
- */
597
- reversedBy?: string;
598
- createdAt: number;
599
- }
600
- /**
601
- * One signed movement of one worker's balance. PK `STORE#{storeId}`, SK
602
- * `TIPENTRY#{userId}#{createdAt}#{operationId}` — a worker's history reads
603
- * back in time order from one prefix.
604
- */
605
- interface TipEntry {
606
- storeId: string;
607
- userId: string;
608
- currency: string;
609
- operationId: string;
610
- kind: TipOperationKind;
611
- delta: number;
612
- createdAt: number;
613
- }
614
- /**
615
- * `POST /shifts/tips` `mode: 'payout'` — settle a worker's tip balance. Mirrors
616
- * the request side of `tipPayoutSchema` (`stacks/lambdas/shifts/_tips.ts`); the
617
- * schema strips unknown keys, so the root `elevationToken` is read off the raw
618
- * body.
619
- *
620
- * From a PIN operator session, `method: 'cash'` is the `'tip.cash-payout'`
621
- * elevated action: mint it with no `subjectId` (see
622
- * {@link TerminalElevationRequest.subjectId}) and attach the token here.
623
- * `method: 'transfer'` is ledger-only and needs no elevation.
624
- *
625
- * Held to its schema by `AssertTipPayoutRequestMatchesSchema`.
626
- */
627
- interface TipPayoutRequest extends TerminalElevationAuthorization {
628
- mode: 'payout';
629
- /** A client-minted UUID — the act's idempotency anchor (`TipOperation.operationId`). */
630
- operationId: string;
631
- /** Trimmed, 1–64 characters. Never the caller. */
632
- payeeUserId: string;
633
- /** Above zero, at most the platform money-input cap. */
634
- amount: number;
635
- /** A platform catalog id or ISO code. */
636
- currency: string;
637
- method: 'cash' | 'transfer';
638
- /** Trimmed, 1–500 characters. */
639
- note?: string;
640
- }
641
468
  }
642
469
  /**
643
470
  * Refusals from the cash-shift surface — `stacks/lambdas/shifts/*.ts`
@@ -672,32 +499,6 @@ declare global {
672
499
  */
673
500
  export declare const SHIFT_ERROR_CODES: readonly ["INVALID_SHIFT_ID", "SHIFT_NOT_FOUND", "SHIFT_ALREADY_OPEN", "SHIFT_NOT_OPEN", "SHIFT_NOT_CLOSED", "SHIFT_OWNER_MISMATCH", "CURRENCY_MISMATCH", "BUCKET_COUNTS_INVALID", "BUCKET_REVIEW_INVALID", "BUCKET_COUNT_MISSING", "SHIFT_CHANGED", "SHIFT_EVENTS_TRUNCATED", "SELF_APPROVAL_FORBIDDEN", "INVALID_DENOMINATION", "INVALID_CURSOR", "ROLE_FORBIDDEN", "VALIDATION_FAILED"];
674
501
  export type ShiftErrorCode = (typeof SHIFT_ERROR_CODES)[number];
675
- /**
676
- * Refusals from the tip ledger — `POST /shifts/{id}/movements` with `type: 'tip'`
677
- * and `/shifts/tips`.
678
- *
679
- * - `TIP_RECIPIENT_NOT_FOUND` · 404 — the named worker is missing, disabled or
680
- * removed, or is a print agent or an accountant login (neither can be paid).
681
- * - `TIP_SELF_ACTION_FORBIDDEN` · 403 — an employer act whose actor is also the
682
- * recipient or payee.
683
- * - `TIP_OPERATION_CONFLICT` · 409 — an `operationId` already used for a
684
- * different act.
685
- * - `TIP_BALANCE_CHANGED` · 409 — the tip's transaction collided with another
686
- * write on the same tip-ledger row (`TransactionConflict`), or a balance moved
687
- * between the debit's read and its write; nothing was written, retry with the
688
- * same `operationId`.
689
- * - `TIP_INSUFFICIENT_BALANCE` · 409 — a debit (`allocate`, `payout`, or the
690
- * `reverse` of a `receive`) larger than what the worker is owed.
691
- * - `TIP_ALREADY_REVERSED` · 409 — the target operation was already reversed.
692
- * - `TIP_NOT_REVERSIBLE` · 400 — only a `receive` or a `payout` can be
693
- * reversed; an `allocate` is corrected by the recipient re-allocating.
694
- * - `TIP_OPERATION_NOT_FOUND` · 404 — `targetOperationId` names no operation.
695
- *
696
- * ⚠️ Cross-cutting refusals (`CAPABILITY_REQUIRED`, `VALIDATION_FAILED`, the
697
- * drawer's own codes) are NOT repeated here.
698
- */
699
- export declare const TIP_ERROR_CODES: readonly ["TIP_INSUFFICIENT_BALANCE", "TIP_BALANCE_CHANGED", "TIP_OPERATION_CONFLICT", "TIP_RECIPIENT_NOT_FOUND", "TIP_SELF_ACTION_FORBIDDEN", "TIP_ALREADY_REVERSED", "TIP_NOT_REVERSIBLE", "TIP_OPERATION_NOT_FOUND"];
700
- export type TipErrorCode = (typeof TIP_ERROR_CODES)[number];
701
502
  /**
702
503
  * Where a {@link ShiftMethodTotal}'s `label` came from.
703
504
  *
package/dist/cash.js CHANGED
@@ -48,40 +48,6 @@ export const SHIFT_ERROR_CODES = [
48
48
  'ROLE_FORBIDDEN',
49
49
  'VALIDATION_FAILED',
50
50
  ];
51
- /**
52
- * Refusals from the tip ledger — `POST /shifts/{id}/movements` with `type: 'tip'`
53
- * and `/shifts/tips`.
54
- *
55
- * - `TIP_RECIPIENT_NOT_FOUND` · 404 — the named worker is missing, disabled or
56
- * removed, or is a print agent or an accountant login (neither can be paid).
57
- * - `TIP_SELF_ACTION_FORBIDDEN` · 403 — an employer act whose actor is also the
58
- * recipient or payee.
59
- * - `TIP_OPERATION_CONFLICT` · 409 — an `operationId` already used for a
60
- * different act.
61
- * - `TIP_BALANCE_CHANGED` · 409 — the tip's transaction collided with another
62
- * write on the same tip-ledger row (`TransactionConflict`), or a balance moved
63
- * between the debit's read and its write; nothing was written, retry with the
64
- * same `operationId`.
65
- * - `TIP_INSUFFICIENT_BALANCE` · 409 — a debit (`allocate`, `payout`, or the
66
- * `reverse` of a `receive`) larger than what the worker is owed.
67
- * - `TIP_ALREADY_REVERSED` · 409 — the target operation was already reversed.
68
- * - `TIP_NOT_REVERSIBLE` · 400 — only a `receive` or a `payout` can be
69
- * reversed; an `allocate` is corrected by the recipient re-allocating.
70
- * - `TIP_OPERATION_NOT_FOUND` · 404 — `targetOperationId` names no operation.
71
- *
72
- * ⚠️ Cross-cutting refusals (`CAPABILITY_REQUIRED`, `VALIDATION_FAILED`, the
73
- * drawer's own codes) are NOT repeated here.
74
- */
75
- export const TIP_ERROR_CODES = [
76
- 'TIP_INSUFFICIENT_BALANCE',
77
- 'TIP_BALANCE_CHANGED',
78
- 'TIP_OPERATION_CONFLICT',
79
- 'TIP_RECIPIENT_NOT_FOUND',
80
- 'TIP_SELF_ACTION_FORBIDDEN',
81
- 'TIP_ALREADY_REVERSED',
82
- 'TIP_NOT_REVERSIBLE',
83
- 'TIP_OPERATION_NOT_FOUND',
84
- ];
85
51
  /**
86
52
  * Where a {@link ShiftMethodTotal}'s `label` came from.
87
53
  *
package/dist/cjs/cash.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.METHOD_LABEL_SOURCES = exports.TIP_ERROR_CODES = exports.SHIFT_ERROR_CODES = void 0;
3
+ exports.METHOD_LABEL_SOURCES = exports.SHIFT_ERROR_CODES = void 0;
4
4
  /**
5
5
  * Refusals from the cash-shift surface — `stacks/lambdas/shifts/*.ts`
6
6
  * (`_get`, `_post`, `_patchClose`, `_postMovement`, `_patchReconcile`).
@@ -51,40 +51,6 @@ exports.SHIFT_ERROR_CODES = [
51
51
  'ROLE_FORBIDDEN',
52
52
  'VALIDATION_FAILED',
53
53
  ];
54
- /**
55
- * Refusals from the tip ledger — `POST /shifts/{id}/movements` with `type: 'tip'`
56
- * and `/shifts/tips`.
57
- *
58
- * - `TIP_RECIPIENT_NOT_FOUND` · 404 — the named worker is missing, disabled or
59
- * removed, or is a print agent or an accountant login (neither can be paid).
60
- * - `TIP_SELF_ACTION_FORBIDDEN` · 403 — an employer act whose actor is also the
61
- * recipient or payee.
62
- * - `TIP_OPERATION_CONFLICT` · 409 — an `operationId` already used for a
63
- * different act.
64
- * - `TIP_BALANCE_CHANGED` · 409 — the tip's transaction collided with another
65
- * write on the same tip-ledger row (`TransactionConflict`), or a balance moved
66
- * between the debit's read and its write; nothing was written, retry with the
67
- * same `operationId`.
68
- * - `TIP_INSUFFICIENT_BALANCE` · 409 — a debit (`allocate`, `payout`, or the
69
- * `reverse` of a `receive`) larger than what the worker is owed.
70
- * - `TIP_ALREADY_REVERSED` · 409 — the target operation was already reversed.
71
- * - `TIP_NOT_REVERSIBLE` · 400 — only a `receive` or a `payout` can be
72
- * reversed; an `allocate` is corrected by the recipient re-allocating.
73
- * - `TIP_OPERATION_NOT_FOUND` · 404 — `targetOperationId` names no operation.
74
- *
75
- * ⚠️ Cross-cutting refusals (`CAPABILITY_REQUIRED`, `VALIDATION_FAILED`, the
76
- * drawer's own codes) are NOT repeated here.
77
- */
78
- exports.TIP_ERROR_CODES = [
79
- 'TIP_INSUFFICIENT_BALANCE',
80
- 'TIP_BALANCE_CHANGED',
81
- 'TIP_OPERATION_CONFLICT',
82
- 'TIP_RECIPIENT_NOT_FOUND',
83
- 'TIP_SELF_ACTION_FORBIDDEN',
84
- 'TIP_ALREADY_REVERSED',
85
- 'TIP_NOT_REVERSIBLE',
86
- 'TIP_OPERATION_NOT_FOUND',
87
- ];
88
54
  /**
89
55
  * Where a {@link ShiftMethodTotal}'s `label` came from.
90
56
  *
@@ -18,9 +18,8 @@ exports.GATING_ERROR_CODES = void 0;
18
18
  * `message`) — its lifecycle leaving `active`, a sales channel dropped,
19
19
  * hidden from the storefront, or its price left with nothing to derive from —
20
20
  * as the product-group write does an archive or a draft of an active group,
21
- * the kit save a product it would make a kit, `POST /stripe` a payment
22
- * carrying a tip, `POST /warehouses` a depósito taken out of service or re-pointed to
23
- * another punto de venta,
21
+ * the kit save a product it would make a kit, `POST /warehouses` a depósito
22
+ * taken out of service or re-pointed to another punto de venta,
24
23
  * `POST /transfers` a dispatched transfer cancelled or closed short,
25
24
  * `PATCH /store` a change to the stock a sales channel is fed from, the
26
25
  * customer, brand, attribute and category writes a disable of a row not
@@ -1,15 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MP_REFUND_RECOVERY_ERROR_CODES = exports.MP_POINT_TIP_ERROR_CODES = exports.MP_DYNAMIC_QR_ERROR_CODES = void 0;
3
+ exports.MP_DYNAMIC_QR_ERROR_CODES = void 0;
4
4
  /**
5
5
  * Dynamic QR initiation refusals, by status:
6
- * - 400 malformed request (`VALIDATION_FAILED`, `TIP_EXCEEDS_ORDER`, `TIP_ORDER_REQUIRED`), or an
7
- * order whose paid sum cannot be converted for want of a usable rate (`FX_CONVERSION_UNAVAILABLE`);
8
- * - 403 permission, plan or support session (`CAPABILITY_REQUIRED`, `ROLE_FORBIDDEN`,
9
- * `PLAN_UPGRADE_REQUIRED`, `IMPERSONATION_READONLY`);
10
- * - 404 missing order or worker (`TIP_ORDER_NOT_FOUND`, `TIP_RECIPIENT_NOT_FOUND`; the POST never
11
- * answers `ORDER_NOT_FOUND`, only the re-sync read below does);
12
- * - 409 order state, account, attempt or allocation conflicts (every other order/tip/attempt code);
6
+ * - 400 malformed request (`VALIDATION_FAILED`, an unknown body key included);
7
+ * - 403 permission or plan (`CAPABILITY_REQUIRED`, `ROLE_FORBIDDEN`,
8
+ * `PLAN_UPGRADE_REQUIRED`);
9
+ * - 409 order state or a held order fence (`ORDER_CANCELLED`, `MP_DYN_QR_IN_PROGRESS`); the POST
10
+ * never answers `ORDER_NOT_FOUND`, only the re-sync read below does;
13
11
  * - 412 connection or configuration (`MP_NOT_CONNECTED`, `MP_TOKEN_EXPIRED`, `MP_USER_ID_MISSING`,
14
12
  * `MP_NO_STORE_ON_ACCOUNT`);
15
13
  * - 502 a definite POS or QR rejection (`MP_DYN_POS_CREATE_FAILED`, `MP_POS_INVALID`,
@@ -19,23 +17,13 @@ exports.MP_REFUND_RECOVERY_ERROR_CODES = exports.MP_POINT_TIP_ERROR_CODES = expo
19
17
  * (`GET /mercadopago/qr/dynamic?orderId=`) uses `VALIDATION_FAILED`, `PLAN_UPGRADE_REQUIRED`,
20
18
  * `CAPABILITY_REQUIRED`, `ORDER_NOT_FOUND` and `ORDER_CANCELLED` from this list.
21
19
  *
22
- * Per Idempotency-Key on the tipped path: `MP_DYN_QR_IN_PROGRESS` = in flight
23
- * (keep the key, poll); `MP_DYN_QR_REJECTED` = ended with no live charge (a
24
- * fresh key is safe); `MP_DYN_QR_EXPIRED` = its QR expired (permanent for that
25
- * key). A `contacting` attempt (MercadoPago may have been called) stays blocked
26
- * indefinitely; a `reserved` one (provably never contacted) is released once it
27
- * outlives the Lambda timeout. A fresh tipped reservation on an order already
28
- * fully paid (till tenders plus linked payments cover its total, as its
29
- * `financialStatus` derives) answers `PAYMENT_ALREADY_RECEIVED`; a part-paid
30
- * order (a split) still mints the remainder. When a till tender or linked payment
31
- * is in a currency the store holds no usable rate for, the paid sum is unknown, not
32
- * paid: it answers `400 FX_CONVERSION_UNAVAILABLE` (configure the rate in Monedas,
33
- * then retry with the same key).
34
- * `MP_DYN_QR_INVALID` is untipped-only: on the tipped path a malformed 2xx is
35
- * `MP_DYN_QR_UNCONFIRMED`. The retired `{ orderId }`-only body answers
36
- * `VALIDATION_FAILED`. `INVALID_ORDER_STATE`, `ORDER_FX_RATE_UNAVAILABLE` and
37
- * `ORDER_FX_AMOUNT_TOO_SMALL` were that body's alone and are no longer emitted;
38
- * they stay listed so an existing client switch still compiles.
20
+ * An order-bound charge holds the order's QR fence while it mints, and another charge for the
21
+ * same order meanwhile answers `MP_DYN_QR_IN_PROGRESS`. A `contacting` attempt (MercadoPago may
22
+ * have been called) stays blocked indefinitely; a `reserved` one (provably never contacted) is
23
+ * released once it outlives the Lambda timeout. A QR MercadoPago returned whose attempt could not
24
+ * be recorded answers `MP_DYN_QR_UNCONFIRMED`; a malformed 2xx answers `MP_DYN_QR_INVALID`.
25
+ * The retired `{ orderId }`-only body answers `VALIDATION_FAILED`. `INVALID_ORDER_STATE`,
26
+ * `ORDER_FX_RATE_UNAVAILABLE` and `ORDER_FX_AMOUNT_TOO_SMALL` were that body's alone.
39
27
  */
40
28
  exports.MP_DYNAMIC_QR_ERROR_CODES = [
41
29
  'VALIDATION_FAILED',
@@ -51,49 +39,11 @@ exports.MP_DYNAMIC_QR_ERROR_CODES = [
51
39
  'PLAN_UPGRADE_REQUIRED',
52
40
  'ORDER_CANCELLED',
53
41
  'INVALID_ORDER_STATE',
54
- 'PAYMENT_ALREADY_RECEIVED',
55
42
  'ORDER_NOT_FOUND',
56
43
  'ORDER_FX_RATE_UNAVAILABLE',
57
44
  'ORDER_FX_AMOUNT_TOO_SMALL',
58
45
  'CAPABILITY_REQUIRED',
59
46
  'ROLE_FORBIDDEN',
60
- 'IMPERSONATION_READONLY',
61
- 'TIP_EXCEEDS_ORDER',
62
- 'TIP_RECIPIENT_NOT_FOUND',
63
- 'TIP_ACCOUNT_UNVERIFIED',
64
- 'TIP_SHARED_ACCOUNT_FORBIDDEN',
65
- 'TIP_ORDER_REQUIRED',
66
- 'TIP_ORDER_NOT_FOUND',
67
- 'TIP_OPERATION_CONFLICT',
68
- 'TIP_PAYMENT_NOT_FOUND',
69
47
  'MP_DYN_QR_IN_PROGRESS',
70
- 'MP_DYN_QR_EXPIRED',
71
48
  'MP_DYN_QR_UNCONFIRMED',
72
- 'MP_DYN_QR_REJECTED',
73
- 'FX_CONVERSION_UNAVAILABLE',
74
- ];
75
- exports.MP_POINT_TIP_ERROR_CODES = [
76
- 'TIP_EXCEEDS_ORDER',
77
- 'VALIDATION_FAILED',
78
- 'CAPABILITY_REQUIRED',
79
- 'ROLE_FORBIDDEN',
80
- 'PLAN_UPGRADE_REQUIRED',
81
- 'TIP_RECIPIENT_NOT_FOUND',
82
- 'TIP_ACCOUNT_UNVERIFIED',
83
- 'TIP_SHARED_ACCOUNT_FORBIDDEN',
84
- 'TIP_ORDER_REQUIRED',
85
- 'TIP_ORDER_NOT_FOUND',
86
- 'TIP_OPERATION_CONFLICT',
87
- 'TIP_PAYMENT_MISMATCH',
88
- 'TIP_PAYMENT_NOT_FOUND',
89
- 'TIP_REFUND_EXCEEDS_ORDER',
90
- ];
91
- exports.MP_REFUND_RECOVERY_ERROR_CODES = [
92
- 'VALIDATION_FAILED',
93
- 'MISSING_PAYMENT_ID',
94
- 'MP_REFUND_RECOVERY_NOT_FOUND',
95
- 'MP_REFUND_RECOVERY_MISMATCH',
96
- 'MP_REFUND_IN_PROGRESS',
97
- 'MP_NOT_CONNECTED',
98
- 'MP_REFUND_PROVIDER_UNAVAILABLE',
99
49
  ];
@@ -23,9 +23,6 @@ exports.REPORT_WAREHOUSE_NONE = 'none';
23
23
  * - `change` — a `change` event: cash handed back while settling a sale.
24
24
  * - `refund` — a `refund` event: a refund movement recorded on a drawer, or the
25
25
  * cash a sales seña refund or a customer order return gives back.
26
- * - `tip` — a `tip` event, and the reversal of one.
27
- * - `tip-payout` — a `tip-payout` event (cash paid to a worker against their
28
- * tip balance), and the reversal of one.
29
26
  * - `account` — a `cash-in`/`cash-out` carrying `accountId`: the cash side of a
30
27
  * customer-account payment, and its reversal.
31
28
  * - `cash-book` — a `cash-in`/`cash-out` carrying `cashId` and no `accountId`:
@@ -48,8 +45,6 @@ exports.CASH_FLOW_SOURCES = [
48
45
  'sales',
49
46
  'change',
50
47
  'refund',
51
- 'tip',
52
- 'tip-payout',
53
48
  'account',
54
49
  'cash-book',
55
50
  'service-order-deposit',
@@ -24,3 +24,72 @@
24
24
  * enabled:false until they do.
25
25
  */
26
26
  Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.FEATURE_KEYS = exports.PLAN_TIERS = void 0;
28
+ /*
29
+ * Runtime tuples for the unions above.
30
+ *
31
+ * A union alone cannot be iterated, and any consumer that needs to enumerate
32
+ * every tier or key — zeroing a breakdown, fanning a query across tiers,
33
+ * rendering a pricing table's rows — otherwise hand-rolls its own copy that
34
+ * compiles fine while silently omitting a member. A missing member is not a
35
+ * visible break: it is a bucket that reads zero forever, or a row that never
36
+ * renders.
37
+ *
38
+ * ⚠️ `satisfies readonly PlanTier[]` alone does NOT catch that — it checks each
39
+ * element IS a tier, never that every tier is present. Hence `exhaustiveTuple`,
40
+ * whose second type parameter fails to resolve unless the tuple covers the
41
+ * union, making an omission a compile error at the tuple itself. Module-private
42
+ * on purpose: it is a type-level trick, not part of the published surface.
43
+ */
44
+ const exhaustiveTuple = () => (tuple) => tuple;
45
+ /** Every plan tier, in rank order (lowest first). */
46
+ exports.PLAN_TIERS = exhaustiveTuple()(['basico', 'emprendedor', 'profesional', 'avanzado']);
47
+ /**
48
+ * Every gated feature key.
49
+ *
50
+ * ⚠️ Adding a member here is not the whole change, and `typecheck` is what
51
+ * stops it shipping half-done. In the api, a new key needs a grant in **every
52
+ * tier** of `PLAN_FEATURES` (`stacks/services/planFeatureMatrix.ts`): that
53
+ * constant is typed total over every `PlanTier` × `FeatureKey` cell, so a tier
54
+ * missing the new key's grant, or a grant of the wrong shape for the key's
55
+ * declared `type`, fails `typecheck` at the `PLAN_FEATURES` declaration
56
+ * itself. It also widens the api's per-store override key schema, so a new key
57
+ * immediately becomes a valid override target.
58
+ *
59
+ * ⚠️ **A new member also obliges an api PLATFORM-STACK deploy.** Entitlements
60
+ * resolve inside the Lambda authorizer, built in `PlatformStack`. Deploying only
61
+ * the handler stacks leaves a STALE authorizer running the previous matrix: the
62
+ * key is absent from the resolved map, where a boolean gate refuses but a
63
+ * metered / lifetime cap PASSES THROUGH — a new cap silently unbounded.
64
+ * Checklist: `docs/PLANS_AND_ENTITLEMENTS.md` in the api repo.
65
+ */
66
+ exports.FEATURE_KEYS = [
67
+ 'afipInvoicing',
68
+ 'suppliers',
69
+ 'advancedReports',
70
+ 'cashManagement',
71
+ 'importExport',
72
+ 'domesticPayments',
73
+ 'stripePayments',
74
+ 'whatsappCommerce',
75
+ 'aiFeatures',
76
+ 'mobileApp',
77
+ 'customBranding',
78
+ 'customDomain',
79
+ 'prioritySupport',
80
+ 'advancedPricing',
81
+ 'marketplaceChannels',
82
+ 'storefront',
83
+ 'loyalty',
84
+ 'marketing',
85
+ 'mandatory2fa',
86
+ 'maxUsers',
87
+ 'maxProducts',
88
+ 'maxCustomers',
89
+ 'maxWarehouses',
90
+ 'priceListsMax',
91
+ 'webhooks',
92
+ 'maxOrdersMonth',
93
+ 'maxInvoicesMonth',
94
+ 'whatsappMessages',
95
+ ];
@@ -185,7 +185,6 @@ exports.TERMINAL_ELEVATION_ACTIONS = [
185
185
  'shift.cash-out',
186
186
  'cash.withdrawal',
187
187
  'account.cash-debit',
188
- 'tip.cash-payout',
189
188
  ];
190
189
  /**
191
190
  * Existing PIN, validation and idempotency refusals retain their current
package/dist/gating.d.ts CHANGED
@@ -15,9 +15,8 @@
15
15
  * `message`) — its lifecycle leaving `active`, a sales channel dropped,
16
16
  * hidden from the storefront, or its price left with nothing to derive from —
17
17
  * as the product-group write does an archive or a draft of an active group,
18
- * the kit save a product it would make a kit, `POST /stripe` a payment
19
- * carrying a tip, `POST /warehouses` a depósito taken out of service or re-pointed to
20
- * another punto de venta,
18
+ * the kit save a product it would make a kit, `POST /warehouses` a depósito
19
+ * taken out of service or re-pointed to another punto de venta,
21
20
  * `POST /transfers` a dispatched transfer cancelled or closed short,
22
21
  * `PATCH /store` a change to the stock a sales channel is fed from, the
23
22
  * customer, brand, attribute and category writes a disable of a row not
package/dist/gating.js CHANGED
@@ -15,9 +15,8 @@
15
15
  * `message`) — its lifecycle leaving `active`, a sales channel dropped,
16
16
  * hidden from the storefront, or its price left with nothing to derive from —
17
17
  * as the product-group write does an archive or a draft of an active group,
18
- * the kit save a product it would make a kit, `POST /stripe` a payment
19
- * carrying a tip, `POST /warehouses` a depósito taken out of service or re-pointed to
20
- * another punto de venta,
18
+ * the kit save a product it would make a kit, `POST /warehouses` a depósito
19
+ * taken out of service or re-pointed to another punto de venta,
21
20
  * `POST /transfers` a dispatched transfer cancelled or closed short,
22
21
  * `PATCH /store` a change to the stock a sales channel is fed from, the
23
22
  * customer, brand, attribute and category writes a disable of a row not