platform-types 1.10.841 → 1.10.842

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/cjs/index.js CHANGED
@@ -75,6 +75,7 @@ __exportStar(require("./maintenance.js"), exports);
75
75
  __exportStar(require("./marketing.js"), exports);
76
76
  __exportStar(require("./mercadolibre.js"), exports);
77
77
  __exportStar(require("./mercadopago.js"), exports);
78
+ __exportStar(require("./messaging.js"), exports);
78
79
  __exportStar(require("./notification.js"), exports);
79
80
  __exportStar(require("./order.js"), exports);
80
81
  __exportStar(require("./orderCollectionAttempt.js"), exports);
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright © 2026 BACKSPACE S.A. All rights reserved.
4
+ *
5
+ * SPDX-License-Identifier: PROPRIETARY
6
+ *
7
+ * This file is proprietary and confidential. Unauthorized copying,
8
+ * modification, or distribution is strictly prohibited.
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.MESSAGE_DELIVERY_STAMPS = exports.MESSAGE_LEDGER_KINDS = exports.MESSAGE_CREDITS_PER_CHANNEL = exports.MESSAGE_ALLOWANCE_UNLIMITED = exports.SMS_FALLBACK_CREDITS = exports.WHATSAPP_MESSAGE_CREDITS = exports.MESSAGE_LEDGER_OPERATOR_ONLY_FIELDS = void 0;
12
+ /**
13
+ * Fields a store's own ledger read drops from an `adjustment` entry: it is a
14
+ * platform operator act, and its `actor`, `reason` and `refId` (the
15
+ * operator's own `adjustmentId`) stay on operator surfaces — the store sees
16
+ * the entry, its credits and its balance. Other kinds cross whole.
17
+ */
18
+ exports.MESSAGE_LEDGER_OPERATOR_ONLY_FIELDS = [
19
+ 'actor',
20
+ 'reason',
21
+ 'refId',
22
+ ];
23
+ /** Credits one WhatsApp message costs. */
24
+ exports.WHATSAPP_MESSAGE_CREDITS = 1;
25
+ /** Credits one SMS fallback costs. */
26
+ exports.SMS_FALLBACK_CREDITS = 3;
27
+ /**
28
+ * `MessageBalanceView.allowanceLimit` for a plan or override whose `monthlyMessageAllowance` grant is
29
+ * `limit: -1` (the repo-wide spelling of unlimited). `allowanceLeft` and `available` then read `-1` too, and
30
+ * every message is taken from the allowance — never from the bought balance.
31
+ */
32
+ exports.MESSAGE_ALLOWANCE_UNLIMITED = -1;
33
+ /** Credits per message, by channel. */
34
+ exports.MESSAGE_CREDITS_PER_CHANNEL = {
35
+ whatsapp: exports.WHATSAPP_MESSAGE_CREDITS,
36
+ sms: exports.SMS_FALLBACK_CREDITS,
37
+ };
38
+ exports.MESSAGE_LEDGER_KINDS = [
39
+ 'debit',
40
+ 'refund',
41
+ 'allowance-grant',
42
+ 'purchase',
43
+ 'adjustment',
44
+ ];
45
+ exports.MESSAGE_DELIVERY_STAMPS = [
46
+ 'delivered',
47
+ 'read',
48
+ 'failed',
49
+ ];
@@ -7,7 +7,7 @@ exports.WEB_NOTIFICATIONS_MAX_LIMIT = exports.CUSTOMER_NOTIFICATION_TYPES = expo
7
7
  // Addressed ERROR / ML_FACTURADOR_COLLISION / ML_SELLER_SWITCHED /
8
8
  // ML_CONNECTION_BROKEN / MENTION / CUSTOMER_PENDING_APPROVAL /
9
9
  // PAYMENT_ATTEMPT_RESOLUTION / CUSTOMER_WHOLESALE_REQUEST / STOREFRONT_QUOTE_REQUEST /
10
- // REFUND_OBLIGATION_OVERDUE do not select a
10
+ // REFUND_OBLIGATION_OVERDUE / MESSAGE_CREDITS_LOW / MESSAGE_SKIPPED_NO_CREDITS do not select a
11
11
  // producer subscriber audience;
12
12
  // the consumer still reads the live USER row for each delivery channel.
13
13
  // AFIP_CERT_EXPIRY is seeded on the founding user and uses the subscriber index.
@@ -257,6 +257,33 @@ var NotificationTypeEnum;
257
257
  * `REFUND_OVERDUE` ERROR row and rings nothing. Never a `customerId`.
258
258
  */
259
259
  NotificationTypeEnum["REFUND_OBLIGATION_OVERDUE"] = "REFUND_OBLIGATION_OVERDUE";
260
+ /**
261
+ * The store's message credits (allowance left + bought balance) fell below
262
+ * the `messagingLowBalanceThreshold` platform global: a reserved message
263
+ * took them from at or above it to below it. Names the credits left in the
264
+ * description; the app opens the message-credits screen from the type.
265
+ *
266
+ * ⚠️ ADMIN-ONLY, and its own preference key. The producer fans out to every
267
+ * non-disabled ADMIN of the store (`listActiveAdmins`), with no legacy
268
+ * opt-in scan; the consumer enforces explicit type/channel preferences
269
+ * (`notificationPreferences.MESSAGE_CREDITS_LOW`), default-on when absent.
270
+ * Additive — no backfill or consumer migration owed.
271
+ *
272
+ * Once per crossing: a claim keyed on the reservation that crossed makes a
273
+ * redelivered or replayed reservation ring nothing more. Carries no
274
+ * customer, phone or message content.
275
+ */
276
+ NotificationTypeEnum["MESSAGE_CREDITS_LOW"] = "MESSAGE_CREDITS_LOW";
277
+ /**
278
+ * A customer message was NOT sent because the store had no credits left
279
+ * for it (allowance and bought balance both short). At most one per store
280
+ * per Buenos Aires day, whatever the number of skipped messages.
281
+ *
282
+ * ⚠️ ADMIN-ONLY, and its own preference key — the same audience and
283
+ * preference rules as `MESSAGE_CREDITS_LOW`. Carries no customer, phone,
284
+ * order or message content: NOTIF# rows outlive an erasure.
285
+ */
286
+ NotificationTypeEnum["MESSAGE_SKIPPED_NO_CREDITS"] = "MESSAGE_SKIPPED_NO_CREDITS";
260
287
  })(NotificationTypeEnum || (exports.NotificationTypeEnum = NotificationTypeEnum = {}));
261
288
  /**
262
289
  * The notification types a CUSTOMER bell can carry today; each links through
package/dist/index.d.ts CHANGED
@@ -51,6 +51,7 @@ export * from './maintenance.ts';
51
51
  export * from './marketing.ts';
52
52
  export * from './mercadolibre.ts';
53
53
  export * from './mercadopago.ts';
54
+ export * from './messaging.ts';
54
55
  export * from './notification.ts';
55
56
  export * from './order.ts';
56
57
  export * from './orderCollectionAttempt.ts';
package/dist/index.js CHANGED
@@ -59,6 +59,7 @@ export * from "./maintenance.js";
59
59
  export * from "./marketing.js";
60
60
  export * from "./mercadolibre.js";
61
61
  export * from "./mercadopago.js";
62
+ export * from "./messaging.js";
62
63
  export * from "./notification.js";
63
64
  export * from "./order.js";
64
65
  export * from "./orderCollectionAttempt.js";
@@ -0,0 +1,180 @@
1
+ declare global {
2
+ /** How a store-paid customer message went out. */
3
+ type MessageCreditChannel = 'whatsapp' | 'sms';
4
+ /**
5
+ * What a ledger entry records:
6
+ * - `debit` — a reserved message (`credits` < 0).
7
+ * - `refund` — that reservation given back (`credits` ≥ 0). An allowance part
8
+ * reserved in an earlier period is NOT given back (the allowance never rolls
9
+ * over), so a refund can be smaller than its debit, down to `0`.
10
+ * - `allowance-grant` — a period's allowance starting (`credits` = the limit,
11
+ * into the allowance bucket). Written with the period's first debit, so a
12
+ * period with no message has none.
13
+ * - `purchase` — bought credits (`credits` > 0).
14
+ * - `adjustment` — a MANAGER/SUPERVISOR correction of the bought balance,
15
+ * either sign, with `actor` and `reason` — operator-only, with its `refId`:
16
+ * the store's own ledger read drops them (`MESSAGE_LEDGER_OPERATOR_ONLY_FIELDS`).
17
+ */
18
+ type MessageLedgerKind = 'debit' | 'refund' | 'allowance-grant' | 'purchase' | 'adjustment';
19
+ /**
20
+ * How a debited message ended, stamped on its `debit` entry by the sending
21
+ * pipeline — the ONE field written after the entry lands. Absent means
22
+ * unknown (not yet reported, or never), never "not delivered".
23
+ */
24
+ type MessageDeliveryStamp = 'delivered' | 'read' | 'failed';
25
+ /** Who made an `adjustment` (or a staff `purchase`). */
26
+ interface MessageLedgerActor {
27
+ userId: string;
28
+ /** Empty, never absent, when the user row carried none. */
29
+ fullName: string;
30
+ }
31
+ /**
32
+ * One ledger entry as it crosses the wire. Entries are never edited, except
33
+ * a `debit`'s `delivery`/`deliveryAt`.
34
+ *
35
+ * `entryId` is opaque (newest entries sort first by it); address an entry by
36
+ * it, never read a date out of it — `createdAt` is the time.
37
+ */
38
+ interface MessageLedgerEntry {
39
+ entryId: string;
40
+ kind: MessageLedgerKind;
41
+ /** Signed total: the sum of `fromAllowance` and `fromBalance`. */
42
+ credits: number;
43
+ /** Signed move of the allowance bucket: negative on a debit, positive on a grant or refund. */
44
+ fromAllowance: number;
45
+ /** Signed move of the bought balance. */
46
+ fromBalance: number;
47
+ /** The bought balance after this entry. */
48
+ balanceAfter: number;
49
+ /** Allowance credits used in `period` after this entry. */
50
+ allowanceUsedAfter: number;
51
+ /** The allowance period (`YYYY-MM`, Buenos Aires) the entry was written in. */
52
+ period: string;
53
+ createdAt: number;
54
+ /** The reservation a `debit`/`refund` belongs to, the purchase id, or the adjustment id. */
55
+ refId?: string;
56
+ /** `debit` and `refund` only. */
57
+ noticeType?: StoreMessageNotice;
58
+ /** `debit` and `refund` only. */
59
+ channel?: MessageCreditChannel;
60
+ /** `refund` only: the period its reservation was debited in. */
61
+ reservationPeriod?: string;
62
+ /** `allowance-grant` only: the plan's monthly limit that period started with. */
63
+ allowanceLimit?: number;
64
+ /** `adjustment` (and a staff `purchase`). */
65
+ actor?: MessageLedgerActor;
66
+ /** `adjustment`: why, as the operator wrote it. */
67
+ reason?: string;
68
+ /** `debit` only — see `MessageDeliveryStamp`. */
69
+ delivery?: MessageDeliveryStamp;
70
+ deliveryAt?: number;
71
+ }
72
+ /** The store's credits right now, the period already rolled forward when it has ended. */
73
+ interface MessageBalanceView {
74
+ /** Bought credits, never below zero. */
75
+ balance: number;
76
+ /** The current allowance period (`YYYY-MM`, Buenos Aires). */
77
+ period: string;
78
+ /** The plan's monthly allowance; `0` when the plan includes none, `-1` (`MESSAGE_ALLOWANCE_UNLIMITED`) when unlimited. */
79
+ allowanceLimit: number;
80
+ allowanceUsed: number;
81
+ /** `max(0, allowanceLimit - allowanceUsed)`; `-1` when unlimited. */
82
+ allowanceLeft: number;
83
+ /** `allowanceLeft + balance` — what the next messages can spend; `-1` when unlimited. */
84
+ available: number;
85
+ }
86
+ /** One page of the ledger, newest first. `cursor` present only when more may follow. */
87
+ interface MessageLedgerPage {
88
+ items: MessageLedgerEntry[];
89
+ cursor?: string;
90
+ }
91
+ /** Per-notice slice of `MessageUsageReport`, refunded messages excluded. */
92
+ interface MessageUsageNoticeTotals {
93
+ messages: number;
94
+ sms: number;
95
+ credits: number;
96
+ }
97
+ /**
98
+ * One period's usage, computed from the ledger alone. A message counts once
99
+ * per `debit` not refunded; a refund written up to the end of the FOLLOWING
100
+ * period still nets its debit out.
101
+ *
102
+ * Rates are over the messages carrying a `delivery` stamp (`stamped`), never
103
+ * over all of them, and `null` when none is stamped: an unstamped message is
104
+ * unknown, not failed. `read` counts as delivered too.
105
+ *
106
+ * `truncated: true` — the ledger read stopped at its row cap, so every figure
107
+ * is a lower bound.
108
+ */
109
+ interface MessageUsageReport {
110
+ period: string;
111
+ truncated: boolean;
112
+ messages: number;
113
+ whatsapp: number;
114
+ sms: number;
115
+ /** `sms / messages`; `null` with no message. */
116
+ smsFallbackShare: number | null;
117
+ creditsSpent: number;
118
+ creditsFromAllowance: number;
119
+ creditsFromBalance: number;
120
+ delivery: {
121
+ stamped: number;
122
+ delivered: number;
123
+ read: number;
124
+ failed: number;
125
+ deliveredRate: number | null;
126
+ readRate: number | null;
127
+ };
128
+ byNotice: Partial<Record<StoreMessageNotice, MessageUsageNoticeTotals>>;
129
+ }
130
+ /**
131
+ * `POST /platform/stores/{storeId}/message-credits` — a MANAGER/SUPERVISOR
132
+ * correction of the store's BOUGHT balance (never the allowance).
133
+ */
134
+ interface MessageCreditAdjustmentRequest {
135
+ /** Signed, whole, non-zero. A negative one that would take the balance below zero is refused. */
136
+ credits: number;
137
+ /** 10–500 characters, no personal data. Internal: the store's own reads never show it. */
138
+ reason: string;
139
+ /** The target `storeId`, echoed (type-to-confirm). */
140
+ confirm: string;
141
+ /**
142
+ * The caller's idempotency id (`[A-Za-z0-9][\w.:~-]{0,127}`): a repeat with
143
+ * it answers the first outcome and moves nothing.
144
+ */
145
+ adjustmentId: string;
146
+ }
147
+ interface MessageCreditAdjustmentResult {
148
+ storeId: string;
149
+ /** The `adjustment` ledger entry. */
150
+ entryId: string;
151
+ /** The bought balance after the adjustment. */
152
+ balanceAfter: number;
153
+ /** `true` when `adjustmentId` had already been applied — nothing moved this time. */
154
+ replayed: boolean;
155
+ }
156
+ }
157
+ /**
158
+ * Fields a store's own ledger read drops from an `adjustment` entry: it is a
159
+ * platform operator act, and its `actor`, `reason` and `refId` (the
160
+ * operator's own `adjustmentId`) stay on operator surfaces — the store sees
161
+ * the entry, its credits and its balance. Other kinds cross whole.
162
+ */
163
+ export declare const MESSAGE_LEDGER_OPERATOR_ONLY_FIELDS: readonly ["actor", "reason", "refId"];
164
+ /** Credits one WhatsApp message costs. */
165
+ export declare const WHATSAPP_MESSAGE_CREDITS = 1;
166
+ /** Credits one SMS fallback costs. */
167
+ export declare const SMS_FALLBACK_CREDITS = 3;
168
+ /**
169
+ * `MessageBalanceView.allowanceLimit` for a plan or override whose `monthlyMessageAllowance` grant is
170
+ * `limit: -1` (the repo-wide spelling of unlimited). `allowanceLeft` and `available` then read `-1` too, and
171
+ * every message is taken from the allowance — never from the bought balance.
172
+ */
173
+ export declare const MESSAGE_ALLOWANCE_UNLIMITED = -1;
174
+ /** Credits per message, by channel. */
175
+ export declare const MESSAGE_CREDITS_PER_CHANNEL: {
176
+ readonly whatsapp: 1;
177
+ readonly sms: 3;
178
+ };
179
+ export declare const MESSAGE_LEDGER_KINDS: readonly ["debit", "refund", "allowance-grant", "purchase", "adjustment"];
180
+ export declare const MESSAGE_DELIVERY_STAMPS: readonly ["delivered", "read", "failed"];
@@ -0,0 +1,46 @@
1
+ /*
2
+ * Copyright © 2026 BACKSPACE S.A. All rights reserved.
3
+ *
4
+ * SPDX-License-Identifier: PROPRIETARY
5
+ *
6
+ * This file is proprietary and confidential. Unauthorized copying,
7
+ * modification, or distribution is strictly prohibited.
8
+ */
9
+ /**
10
+ * Fields a store's own ledger read drops from an `adjustment` entry: it is a
11
+ * platform operator act, and its `actor`, `reason` and `refId` (the
12
+ * operator's own `adjustmentId`) stay on operator surfaces — the store sees
13
+ * the entry, its credits and its balance. Other kinds cross whole.
14
+ */
15
+ export const MESSAGE_LEDGER_OPERATOR_ONLY_FIELDS = [
16
+ 'actor',
17
+ 'reason',
18
+ 'refId',
19
+ ];
20
+ /** Credits one WhatsApp message costs. */
21
+ export const WHATSAPP_MESSAGE_CREDITS = 1;
22
+ /** Credits one SMS fallback costs. */
23
+ export const SMS_FALLBACK_CREDITS = 3;
24
+ /**
25
+ * `MessageBalanceView.allowanceLimit` for a plan or override whose `monthlyMessageAllowance` grant is
26
+ * `limit: -1` (the repo-wide spelling of unlimited). `allowanceLeft` and `available` then read `-1` too, and
27
+ * every message is taken from the allowance — never from the bought balance.
28
+ */
29
+ export const MESSAGE_ALLOWANCE_UNLIMITED = -1;
30
+ /** Credits per message, by channel. */
31
+ export const MESSAGE_CREDITS_PER_CHANNEL = {
32
+ whatsapp: WHATSAPP_MESSAGE_CREDITS,
33
+ sms: SMS_FALLBACK_CREDITS,
34
+ };
35
+ export const MESSAGE_LEDGER_KINDS = [
36
+ 'debit',
37
+ 'refund',
38
+ 'allowance-grant',
39
+ 'purchase',
40
+ 'adjustment',
41
+ ];
42
+ export const MESSAGE_DELIVERY_STAMPS = [
43
+ 'delivered',
44
+ 'read',
45
+ 'failed',
46
+ ];
@@ -233,7 +233,34 @@ export declare enum NotificationTypeEnum {
233
233
  * daily repeat of an obligation already `overdue` writes the
234
234
  * `REFUND_OVERDUE` ERROR row and rings nothing. Never a `customerId`.
235
235
  */
236
- REFUND_OBLIGATION_OVERDUE = "REFUND_OBLIGATION_OVERDUE"
236
+ REFUND_OBLIGATION_OVERDUE = "REFUND_OBLIGATION_OVERDUE",
237
+ /**
238
+ * The store's message credits (allowance left + bought balance) fell below
239
+ * the `messagingLowBalanceThreshold` platform global: a reserved message
240
+ * took them from at or above it to below it. Names the credits left in the
241
+ * description; the app opens the message-credits screen from the type.
242
+ *
243
+ * ⚠️ ADMIN-ONLY, and its own preference key. The producer fans out to every
244
+ * non-disabled ADMIN of the store (`listActiveAdmins`), with no legacy
245
+ * opt-in scan; the consumer enforces explicit type/channel preferences
246
+ * (`notificationPreferences.MESSAGE_CREDITS_LOW`), default-on when absent.
247
+ * Additive — no backfill or consumer migration owed.
248
+ *
249
+ * Once per crossing: a claim keyed on the reservation that crossed makes a
250
+ * redelivered or replayed reservation ring nothing more. Carries no
251
+ * customer, phone or message content.
252
+ */
253
+ MESSAGE_CREDITS_LOW = "MESSAGE_CREDITS_LOW",
254
+ /**
255
+ * A customer message was NOT sent because the store had no credits left
256
+ * for it (allowance and bought balance both short). At most one per store
257
+ * per Buenos Aires day, whatever the number of skipped messages.
258
+ *
259
+ * ⚠️ ADMIN-ONLY, and its own preference key — the same audience and
260
+ * preference rules as `MESSAGE_CREDITS_LOW`. Carries no customer, phone,
261
+ * order or message content: NOTIF# rows outlive an erasure.
262
+ */
263
+ MESSAGE_SKIPPED_NO_CREDITS = "MESSAGE_SKIPPED_NO_CREDITS"
237
264
  }
238
265
  /**
239
266
  * The notification types a CUSTOMER bell can carry today; each links through
@@ -4,7 +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
- // REFUND_OBLIGATION_OVERDUE do not select a
7
+ // REFUND_OBLIGATION_OVERDUE / MESSAGE_CREDITS_LOW / MESSAGE_SKIPPED_NO_CREDITS do not select a
8
8
  // producer subscriber audience;
9
9
  // the consumer still reads the live USER row for each delivery channel.
10
10
  // AFIP_CERT_EXPIRY is seeded on the founding user and uses the subscriber index.
@@ -254,6 +254,33 @@ export var NotificationTypeEnum;
254
254
  * `REFUND_OVERDUE` ERROR row and rings nothing. Never a `customerId`.
255
255
  */
256
256
  NotificationTypeEnum["REFUND_OBLIGATION_OVERDUE"] = "REFUND_OBLIGATION_OVERDUE";
257
+ /**
258
+ * The store's message credits (allowance left + bought balance) fell below
259
+ * the `messagingLowBalanceThreshold` platform global: a reserved message
260
+ * took them from at or above it to below it. Names the credits left in the
261
+ * description; the app opens the message-credits screen from the type.
262
+ *
263
+ * ⚠️ ADMIN-ONLY, and its own preference key. The producer fans out to every
264
+ * non-disabled ADMIN of the store (`listActiveAdmins`), with no legacy
265
+ * opt-in scan; the consumer enforces explicit type/channel preferences
266
+ * (`notificationPreferences.MESSAGE_CREDITS_LOW`), default-on when absent.
267
+ * Additive — no backfill or consumer migration owed.
268
+ *
269
+ * Once per crossing: a claim keyed on the reservation that crossed makes a
270
+ * redelivered or replayed reservation ring nothing more. Carries no
271
+ * customer, phone or message content.
272
+ */
273
+ NotificationTypeEnum["MESSAGE_CREDITS_LOW"] = "MESSAGE_CREDITS_LOW";
274
+ /**
275
+ * A customer message was NOT sent because the store had no credits left
276
+ * for it (allowance and bought balance both short). At most one per store
277
+ * per Buenos Aires day, whatever the number of skipped messages.
278
+ *
279
+ * ⚠️ ADMIN-ONLY, and its own preference key — the same audience and
280
+ * preference rules as `MESSAGE_CREDITS_LOW`. Carries no customer, phone,
281
+ * order or message content: NOTIF# rows outlive an erasure.
282
+ */
283
+ NotificationTypeEnum["MESSAGE_SKIPPED_NO_CREDITS"] = "MESSAGE_SKIPPED_NO_CREDITS";
257
284
  })(NotificationTypeEnum || (NotificationTypeEnum = {}));
258
285
  /**
259
286
  * The notification types a CUSTOMER bell can carry today; each links through
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "platform-types",
3
- "version": "1.10.841",
3
+ "version": "1.10.842",
4
4
  "description": "Shared wire and entity contracts for the platform.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",