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.
@@ -22,4 +22,71 @@
22
22
  * declared here even when their epics haven't shipped — the matrix can set
23
23
  * enabled:false until they do.
24
24
  */
25
- export {};
25
+ /*
26
+ * Runtime tuples for the unions above.
27
+ *
28
+ * A union alone cannot be iterated, and any consumer that needs to enumerate
29
+ * every tier or key — zeroing a breakdown, fanning a query across tiers,
30
+ * rendering a pricing table's rows — otherwise hand-rolls its own copy that
31
+ * compiles fine while silently omitting a member. A missing member is not a
32
+ * visible break: it is a bucket that reads zero forever, or a row that never
33
+ * renders.
34
+ *
35
+ * ⚠️ `satisfies readonly PlanTier[]` alone does NOT catch that — it checks each
36
+ * element IS a tier, never that every tier is present. Hence `exhaustiveTuple`,
37
+ * whose second type parameter fails to resolve unless the tuple covers the
38
+ * union, making an omission a compile error at the tuple itself. Module-private
39
+ * on purpose: it is a type-level trick, not part of the published surface.
40
+ */
41
+ const exhaustiveTuple = () => (tuple) => tuple;
42
+ /** Every plan tier, in rank order (lowest first). */
43
+ export const PLAN_TIERS = exhaustiveTuple()(['basico', 'emprendedor', 'profesional', 'avanzado']);
44
+ /**
45
+ * Every gated feature key.
46
+ *
47
+ * ⚠️ Adding a member here is not the whole change, and `typecheck` is what
48
+ * stops it shipping half-done. In the api, a new key needs a grant in **every
49
+ * tier** of `PLAN_FEATURES` (`stacks/services/planFeatureMatrix.ts`): that
50
+ * constant is typed total over every `PlanTier` × `FeatureKey` cell, so a tier
51
+ * missing the new key's grant, or a grant of the wrong shape for the key's
52
+ * declared `type`, fails `typecheck` at the `PLAN_FEATURES` declaration
53
+ * itself. It also widens the api's per-store override key schema, so a new key
54
+ * immediately becomes a valid override target.
55
+ *
56
+ * ⚠️ **A new member also obliges an api PLATFORM-STACK deploy.** Entitlements
57
+ * resolve inside the Lambda authorizer, built in `PlatformStack`. Deploying only
58
+ * the handler stacks leaves a STALE authorizer running the previous matrix: the
59
+ * key is absent from the resolved map, where a boolean gate refuses but a
60
+ * metered / lifetime cap PASSES THROUGH — a new cap silently unbounded.
61
+ * Checklist: `docs/PLANS_AND_ENTITLEMENTS.md` in the api repo.
62
+ */
63
+ export const FEATURE_KEYS = [
64
+ 'afipInvoicing',
65
+ 'suppliers',
66
+ 'advancedReports',
67
+ 'cashManagement',
68
+ 'importExport',
69
+ 'domesticPayments',
70
+ 'stripePayments',
71
+ 'whatsappCommerce',
72
+ 'aiFeatures',
73
+ 'mobileApp',
74
+ 'customBranding',
75
+ 'customDomain',
76
+ 'prioritySupport',
77
+ 'advancedPricing',
78
+ 'marketplaceChannels',
79
+ 'storefront',
80
+ 'loyalty',
81
+ 'marketing',
82
+ 'mandatory2fa',
83
+ 'maxUsers',
84
+ 'maxProducts',
85
+ 'maxCustomers',
86
+ 'maxWarehouses',
87
+ 'priceListsMax',
88
+ 'webhooks',
89
+ 'maxOrdersMonth',
90
+ 'maxInvoicesMonth',
91
+ 'whatsappMessages',
92
+ ];
@@ -452,8 +452,7 @@ declare global {
452
452
  * - `'mercadopago.refund'` — the MercadoPago `paymentId` being refunded. Required.
453
453
  * - `'shift.refund'` / `'shift.cash-out'` — the path `{id}` (the `shiftId`) of
454
454
  * `POST /shifts/{id}/movements` ({@link ShiftMovementRequest}). Required.
455
- * - `'cash.withdrawal'` ({@link CashPostRequest}), `'tip.cash-payout'`
456
- * ({@link TipPayoutRequest}) and `'account.cash-debit'`
455
+ * - `'cash.withdrawal'` ({@link CashPostRequest}) and `'account.cash-debit'`
457
456
  * ({@link AccountPostRequest}) — the drawer (`shiftId`) the write itself
458
457
  * resolves. **Omit it**: the API computes it at mint from the same `body`,
459
458
  * READ-ONLY, with the derivation the write uses — the operator's own OPEN
@@ -464,7 +463,7 @@ declare global {
464
463
  * A client never computes a drawer id.
465
464
  *
466
465
  * The four required subjects are refused by the mint's validation when
467
- * missing (`400`). For the three drawer-bound actions the mint checks, before
466
+ * missing (`400`). For the two drawer-bound actions the mint checks, before
468
467
  * any PIN work, only the body fields it reads (`400 VALIDATION_FAILED`, paths
469
468
  * under `body`): `currency`, a cash edit's `cashId`, an account debit's
470
469
  * `customerId`. A `subjectId` naming any drawer other than the computed one
@@ -495,11 +494,11 @@ declare global {
495
494
  * fingerprint of the cash, account, shift-movement and deposit-refund
496
495
  * writes, so a retry carrying a FRESH token with the same key replays the
497
496
  * committed response instead of answering `422 IDEMPOTENCY_KEY_REUSE`. A
498
- * body without a token fingerprints exactly as before. A tip payout replays
499
- * by its `operationId`. A MercadoPago refund has no stored-response replay:
500
- * its elevation is consumed before the refund claim, so a retry with the
501
- * same token answers `403 ELEVATION_INVALID`, and a retry with a fresh one
502
- * spends that approval and then meets the refund's own state (`409
497
+ * body without a token fingerprints exactly as before. A MercadoPago refund
498
+ * has no stored-response replay: its elevation is consumed before the refund
499
+ * claim, so a retry with the same token answers `403 ELEVATION_INVALID`, and
500
+ * a retry with a fresh one spends that approval and then meets the refund's
501
+ * own state (`409
503
502
  * MP_ALREADY_REFUNDED` once the payment is exhausted, `409
504
503
  * MP_REFUND_IN_PROGRESS` while another attempt holds the claim).
505
504
  */
@@ -647,7 +646,7 @@ export declare const PRINT_AGENT_SESSION_TTL_SECONDS: number;
647
646
  export declare const TERMINAL_ENROLMENT_TTL_SECONDS: number;
648
647
  export declare const TERMINAL_PAIRING_CODE_TTL_SECONDS: number;
649
648
  /** Money-out actions whose operator sessions require a different ADMIN-or-higher approver. */
650
- export declare const TERMINAL_ELEVATION_ACTIONS: readonly ["order.deposit-refund", "mercadopago.refund", "shift.refund", "shift.cash-out", "cash.withdrawal", "account.cash-debit", "tip.cash-payout"];
649
+ export declare const TERMINAL_ELEVATION_ACTIONS: readonly ["order.deposit-refund", "mercadopago.refund", "shift.refund", "shift.cash-out", "cash.withdrawal", "account.cash-debit"];
651
650
  export type TerminalElevationAction = (typeof TERMINAL_ELEVATION_ACTIONS)[number];
652
651
  /**
653
652
  * Existing PIN, validation and idempotency refusals retain their current
package/dist/terminal.js CHANGED
@@ -182,7 +182,6 @@ export const TERMINAL_ELEVATION_ACTIONS = [
182
182
  'shift.cash-out',
183
183
  'cash.withdrawal',
184
184
  'account.cash-debit',
185
- 'tip.cash-payout',
186
185
  ];
187
186
  /**
188
187
  * Existing PIN, validation and idempotency refusals retain their current
package/dist/webhook.d.ts CHANGED
@@ -281,11 +281,6 @@ export interface PaymentReceivedWebhookPayload {
281
281
  invoiceId?: string;
282
282
  /** MP/Stripe-side `external_reference`, when the provider carried one. */
283
283
  externalReference?: string;
284
- /** Goods and tip split, without worker or ledger operation identity. */
285
- paymentTip?: {
286
- orderAmount: number;
287
- tipAmount: number;
288
- };
289
284
  }
290
285
  /**
291
286
  * Payload for `product.stock_low` — a sale CROSSED `Product.minStock`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "platform-types",
3
- "version": "1.10.699",
3
+ "version": "1.10.701",
4
4
  "description": "Shared wire and entity contracts for the platform.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",