platform-types 1.10.834 → 1.10.835
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 +75 -0
- package/dist/auth.js +48 -0
- package/dist/cjs/auth.js +49 -1
- package/dist/cjs/marketing.js +27 -1
- package/dist/cjs/purchaseWithdrawal.js +12 -5
- package/dist/cjs/terminal.js +5 -0
- package/dist/customer.d.ts +7 -2
- package/dist/marketing.d.ts +84 -15
- package/dist/marketing.js +26 -0
- package/dist/order.d.ts +12 -0
- package/dist/purchaseWithdrawal.d.ts +13 -6
- package/dist/purchaseWithdrawal.js +12 -5
- package/dist/terminal.d.ts +5 -1
- package/dist/terminal.js +5 -0
- package/dist/userActivity.d.ts +3 -2
- package/package.json +1 -1
package/dist/auth.d.ts
CHANGED
|
@@ -186,6 +186,46 @@ declare global {
|
|
|
186
186
|
*/
|
|
187
187
|
storeContact?: TenantRegisterStoreContactInput;
|
|
188
188
|
}
|
|
189
|
+
/**
|
|
190
|
+
* `POST /auth { mode: 'register-social' }` on the OPERATOR host — register a
|
|
191
|
+
* store whose founder signs in with Google or Apple and has NO password. Field
|
|
192
|
+
* for field what `registerSocialSchema` (`stacks/lambdas/auth/_registerSocial.ts`)
|
|
193
|
+
* accepts as INPUT, beside `mode`; the tie is compile-time,
|
|
194
|
+
* `AssertTenantSocialRegisterInputMatchesSchema`.
|
|
195
|
+
*
|
|
196
|
+
* The business fields are {@link TenantRegisterInput}'s, same bounds, minus
|
|
197
|
+
* `email` and `password`: the founder's email is ALWAYS the verified token's,
|
|
198
|
+
* and an `email` or `password` in the body is stripped, never read. The 200 is
|
|
199
|
+
* the body `mode: 'register'` answers, with `emailVerified: true`, and no
|
|
200
|
+
* verification code is mailed.
|
|
201
|
+
*
|
|
202
|
+
* ⚠️ Apple Hide My Email: a relay login is allowed, but then
|
|
203
|
+
* `storeContact.email` is REQUIRED and must itself not be a relay — see
|
|
204
|
+
* {@link TENANT_SOCIAL_REGISTER_ERROR_CODES}.
|
|
205
|
+
*/
|
|
206
|
+
type TenantSocialRegisterInput = Omit<TenantRegisterInput, 'email' | 'password'> & {
|
|
207
|
+
/** A Firebase ID token from a Google or Apple sign-in, exactly as {@link Social.accessToken}. */
|
|
208
|
+
accessToken: string;
|
|
209
|
+
};
|
|
210
|
+
/**
|
|
211
|
+
* `POST /auth/verify-password` — re-authentication before a sensitive
|
|
212
|
+
* operation. EXACTLY ONE proof:
|
|
213
|
+
* - `password` — every account that has one;
|
|
214
|
+
* - `idToken` — a FRESH Firebase ID token (signed in within the last 5
|
|
215
|
+
* minutes) from a provider the account was registered with, whose verified
|
|
216
|
+
* email is the account's. Accepted ONLY on an account with no password;
|
|
217
|
+
* see {@link STAFF_REAUTH_ERROR_CODES}.
|
|
218
|
+
* `totpCode` is the second factor, when the account has one, on either proof.
|
|
219
|
+
*/
|
|
220
|
+
type StaffReauthInput = {
|
|
221
|
+
password: string;
|
|
222
|
+
idToken?: never;
|
|
223
|
+
totpCode?: string;
|
|
224
|
+
} | {
|
|
225
|
+
idToken: string;
|
|
226
|
+
password?: never;
|
|
227
|
+
totpCode?: string;
|
|
228
|
+
};
|
|
189
229
|
/** {@link TenantRegisterInput.storeContact} — at least one key. */
|
|
190
230
|
interface TenantRegisterStoreContactInput {
|
|
191
231
|
/** EXACTLY 10 characters. */
|
|
@@ -1615,6 +1655,41 @@ export type SocialBridgeErrorCode = (typeof SOCIAL_BRIDGE_ERROR_CODES)[number];
|
|
|
1615
1655
|
*/
|
|
1616
1656
|
export declare const CUSTOMER_SOCIAL_REGISTER_ERROR_CODES: readonly ["EMAIL_TAKEN_BY_ANOTHER_ACCOUNT", "CUSTOMER_ID_ALLOCATION_EXHAUSTED", "SIGN_IN_IDENTITY_UNVERIFIED", "INVALID_ID_TOKEN", "SIGN_IN_PROVIDER_UNSUPPORTED"];
|
|
1617
1657
|
export type CustomerSocialRegisterErrorCode = (typeof CUSTOMER_SOCIAL_REGISTER_ERROR_CODES)[number];
|
|
1658
|
+
/**
|
|
1659
|
+
* `body.error` codes `POST /auth { mode: 'register-social' }` on the OPERATOR
|
|
1660
|
+
* host can refuse with, beside the ordinary `400` validation refusal:
|
|
1661
|
+
*
|
|
1662
|
+
* - `INVALID_ID_TOKEN` · 401 — the token is expired or malformed; get a fresh one.
|
|
1663
|
+
* - `SIGN_IN_IDENTITY_UNVERIFIED` · 401 — the provider has not verified the
|
|
1664
|
+
* email, or the token carries none.
|
|
1665
|
+
* - `SIGN_IN_PROVIDER_UNSUPPORTED` · 400 — a provider other than Google or Apple.
|
|
1666
|
+
* - `STORE_CONTACT_EMAIL_REQUIRED` · 400 — the login is an Apple relay address
|
|
1667
|
+
* and the body carries no `storeContact.email`, or a relay one.
|
|
1668
|
+
* - `EMAIL_IN_USE` · 400 and `CUIT_SHARED` · 409 — exactly as `mode: 'register'`.
|
|
1669
|
+
*/
|
|
1670
|
+
export declare const TENANT_SOCIAL_REGISTER_ERROR_CODES: readonly ["INVALID_ID_TOKEN", "SIGN_IN_IDENTITY_UNVERIFIED", "SIGN_IN_PROVIDER_UNSUPPORTED", "STORE_CONTACT_EMAIL_REQUIRED", "EMAIL_IN_USE", "CUIT_SHARED"];
|
|
1671
|
+
export type TenantSocialRegisterErrorCode = (typeof TENANT_SOCIAL_REGISTER_ERROR_CODES)[number];
|
|
1672
|
+
/**
|
|
1673
|
+
* `body.error` codes `POST /auth/verify-password` answers for the PROOF itself
|
|
1674
|
+
* (the `password` / `idToken` choice), beside the identity, lockout and
|
|
1675
|
+
* second-factor codes it shared before:
|
|
1676
|
+
*
|
|
1677
|
+
* - `WRONG_CREDENTIALS` · 401 — the password did not match.
|
|
1678
|
+
* - `PASSWORD_NOT_SET` · 409 — a `password` was sent for an account that has
|
|
1679
|
+
* none (a founder registered with Google or Apple). The body carries
|
|
1680
|
+
* `providers`, the providers to re-authenticate with through `idToken`; or set
|
|
1681
|
+
* a password through recovery. Nothing is counted against the account.
|
|
1682
|
+
* - `PASSWORD_REQUIRED` · 400 — an `idToken` was sent for an account that HAS a
|
|
1683
|
+
* password; it must re-authenticate with the password.
|
|
1684
|
+
* - `INVALID_ID_TOKEN` · 401 / `SIGN_IN_IDENTITY_UNVERIFIED` · 401 — as on
|
|
1685
|
+
* `register-social`.
|
|
1686
|
+
* - `REAUTH_IDENTITY_MISMATCH` · 401 — the token's email is not the account's,
|
|
1687
|
+
* or its provider is not one the account was registered with.
|
|
1688
|
+
* - `REAUTH_NOT_RECENT` · 401 — the provider sign-in behind the token is older
|
|
1689
|
+
* than 5 minutes; sign in with the provider again.
|
|
1690
|
+
*/
|
|
1691
|
+
export declare const STAFF_REAUTH_ERROR_CODES: readonly ["WRONG_CREDENTIALS", "PASSWORD_NOT_SET", "PASSWORD_REQUIRED", "INVALID_ID_TOKEN", "SIGN_IN_IDENTITY_UNVERIFIED", "REAUTH_IDENTITY_MISMATCH", "REAUTH_NOT_RECENT"];
|
|
1692
|
+
export type StaffReauthErrorCode = (typeof STAFF_REAUTH_ERROR_CODES)[number];
|
|
1618
1693
|
/**
|
|
1619
1694
|
* `body.error` codes the operator refresh/session leg can refuse with —
|
|
1620
1695
|
* `POST /auth { mode: 'refresh' }` and the body-transport ingress it shares with
|
package/dist/auth.js
CHANGED
|
@@ -163,6 +163,54 @@ export const CUSTOMER_SOCIAL_REGISTER_ERROR_CODES = [
|
|
|
163
163
|
'INVALID_ID_TOKEN',
|
|
164
164
|
'SIGN_IN_PROVIDER_UNSUPPORTED',
|
|
165
165
|
];
|
|
166
|
+
/**
|
|
167
|
+
* `body.error` codes `POST /auth { mode: 'register-social' }` on the OPERATOR
|
|
168
|
+
* host can refuse with, beside the ordinary `400` validation refusal:
|
|
169
|
+
*
|
|
170
|
+
* - `INVALID_ID_TOKEN` · 401 — the token is expired or malformed; get a fresh one.
|
|
171
|
+
* - `SIGN_IN_IDENTITY_UNVERIFIED` · 401 — the provider has not verified the
|
|
172
|
+
* email, or the token carries none.
|
|
173
|
+
* - `SIGN_IN_PROVIDER_UNSUPPORTED` · 400 — a provider other than Google or Apple.
|
|
174
|
+
* - `STORE_CONTACT_EMAIL_REQUIRED` · 400 — the login is an Apple relay address
|
|
175
|
+
* and the body carries no `storeContact.email`, or a relay one.
|
|
176
|
+
* - `EMAIL_IN_USE` · 400 and `CUIT_SHARED` · 409 — exactly as `mode: 'register'`.
|
|
177
|
+
*/
|
|
178
|
+
export const TENANT_SOCIAL_REGISTER_ERROR_CODES = [
|
|
179
|
+
'INVALID_ID_TOKEN',
|
|
180
|
+
'SIGN_IN_IDENTITY_UNVERIFIED',
|
|
181
|
+
'SIGN_IN_PROVIDER_UNSUPPORTED',
|
|
182
|
+
'STORE_CONTACT_EMAIL_REQUIRED',
|
|
183
|
+
'EMAIL_IN_USE',
|
|
184
|
+
'CUIT_SHARED',
|
|
185
|
+
];
|
|
186
|
+
/**
|
|
187
|
+
* `body.error` codes `POST /auth/verify-password` answers for the PROOF itself
|
|
188
|
+
* (the `password` / `idToken` choice), beside the identity, lockout and
|
|
189
|
+
* second-factor codes it shared before:
|
|
190
|
+
*
|
|
191
|
+
* - `WRONG_CREDENTIALS` · 401 — the password did not match.
|
|
192
|
+
* - `PASSWORD_NOT_SET` · 409 — a `password` was sent for an account that has
|
|
193
|
+
* none (a founder registered with Google or Apple). The body carries
|
|
194
|
+
* `providers`, the providers to re-authenticate with through `idToken`; or set
|
|
195
|
+
* a password through recovery. Nothing is counted against the account.
|
|
196
|
+
* - `PASSWORD_REQUIRED` · 400 — an `idToken` was sent for an account that HAS a
|
|
197
|
+
* password; it must re-authenticate with the password.
|
|
198
|
+
* - `INVALID_ID_TOKEN` · 401 / `SIGN_IN_IDENTITY_UNVERIFIED` · 401 — as on
|
|
199
|
+
* `register-social`.
|
|
200
|
+
* - `REAUTH_IDENTITY_MISMATCH` · 401 — the token's email is not the account's,
|
|
201
|
+
* or its provider is not one the account was registered with.
|
|
202
|
+
* - `REAUTH_NOT_RECENT` · 401 — the provider sign-in behind the token is older
|
|
203
|
+
* than 5 minutes; sign in with the provider again.
|
|
204
|
+
*/
|
|
205
|
+
export const STAFF_REAUTH_ERROR_CODES = [
|
|
206
|
+
'WRONG_CREDENTIALS',
|
|
207
|
+
'PASSWORD_NOT_SET',
|
|
208
|
+
'PASSWORD_REQUIRED',
|
|
209
|
+
'INVALID_ID_TOKEN',
|
|
210
|
+
'SIGN_IN_IDENTITY_UNVERIFIED',
|
|
211
|
+
'REAUTH_IDENTITY_MISMATCH',
|
|
212
|
+
'REAUTH_NOT_RECENT',
|
|
213
|
+
];
|
|
166
214
|
/**
|
|
167
215
|
* `body.error` codes the operator refresh/session leg can refuse with —
|
|
168
216
|
* `POST /auth { mode: 'refresh' }` and the body-transport ingress it shares with
|
package/dist/cjs/auth.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CUSTOMER_OTP_LIMITS = exports.CUSTOMER_OTP_ERROR_CODES = exports.STAFF_ACCOUNT_DELETION_ERROR_CODES = exports.SESSION_ACTION_ERROR_CODES = exports.PASSKEY_ERROR_CODES = exports.TWO_FACTOR_MANAGEMENT_ERROR_CODES = exports.LOGIN_2FA_ERROR_CODES = exports.LOGIN_ERROR_CODES = exports.STEP_UP_ERROR_CODES = exports.REFRESH_ERROR_CODES = exports.CUSTOMER_SOCIAL_REGISTER_ERROR_CODES = exports.SOCIAL_BRIDGE_ERROR_CODES = exports.SIGN_IN_METHOD_ERROR_CODES = void 0;
|
|
3
|
+
exports.CUSTOMER_OTP_LIMITS = exports.CUSTOMER_OTP_ERROR_CODES = exports.STAFF_ACCOUNT_DELETION_ERROR_CODES = exports.SESSION_ACTION_ERROR_CODES = exports.PASSKEY_ERROR_CODES = exports.TWO_FACTOR_MANAGEMENT_ERROR_CODES = exports.LOGIN_2FA_ERROR_CODES = exports.LOGIN_ERROR_CODES = exports.STEP_UP_ERROR_CODES = exports.REFRESH_ERROR_CODES = exports.STAFF_REAUTH_ERROR_CODES = exports.TENANT_SOCIAL_REGISTER_ERROR_CODES = exports.CUSTOMER_SOCIAL_REGISTER_ERROR_CODES = exports.SOCIAL_BRIDGE_ERROR_CODES = exports.SIGN_IN_METHOD_ERROR_CODES = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* `body.error` codes the sign-in-method paths can refuse with.
|
|
6
6
|
*
|
|
@@ -166,6 +166,54 @@ exports.CUSTOMER_SOCIAL_REGISTER_ERROR_CODES = [
|
|
|
166
166
|
'INVALID_ID_TOKEN',
|
|
167
167
|
'SIGN_IN_PROVIDER_UNSUPPORTED',
|
|
168
168
|
];
|
|
169
|
+
/**
|
|
170
|
+
* `body.error` codes `POST /auth { mode: 'register-social' }` on the OPERATOR
|
|
171
|
+
* host can refuse with, beside the ordinary `400` validation refusal:
|
|
172
|
+
*
|
|
173
|
+
* - `INVALID_ID_TOKEN` · 401 — the token is expired or malformed; get a fresh one.
|
|
174
|
+
* - `SIGN_IN_IDENTITY_UNVERIFIED` · 401 — the provider has not verified the
|
|
175
|
+
* email, or the token carries none.
|
|
176
|
+
* - `SIGN_IN_PROVIDER_UNSUPPORTED` · 400 — a provider other than Google or Apple.
|
|
177
|
+
* - `STORE_CONTACT_EMAIL_REQUIRED` · 400 — the login is an Apple relay address
|
|
178
|
+
* and the body carries no `storeContact.email`, or a relay one.
|
|
179
|
+
* - `EMAIL_IN_USE` · 400 and `CUIT_SHARED` · 409 — exactly as `mode: 'register'`.
|
|
180
|
+
*/
|
|
181
|
+
exports.TENANT_SOCIAL_REGISTER_ERROR_CODES = [
|
|
182
|
+
'INVALID_ID_TOKEN',
|
|
183
|
+
'SIGN_IN_IDENTITY_UNVERIFIED',
|
|
184
|
+
'SIGN_IN_PROVIDER_UNSUPPORTED',
|
|
185
|
+
'STORE_CONTACT_EMAIL_REQUIRED',
|
|
186
|
+
'EMAIL_IN_USE',
|
|
187
|
+
'CUIT_SHARED',
|
|
188
|
+
];
|
|
189
|
+
/**
|
|
190
|
+
* `body.error` codes `POST /auth/verify-password` answers for the PROOF itself
|
|
191
|
+
* (the `password` / `idToken` choice), beside the identity, lockout and
|
|
192
|
+
* second-factor codes it shared before:
|
|
193
|
+
*
|
|
194
|
+
* - `WRONG_CREDENTIALS` · 401 — the password did not match.
|
|
195
|
+
* - `PASSWORD_NOT_SET` · 409 — a `password` was sent for an account that has
|
|
196
|
+
* none (a founder registered with Google or Apple). The body carries
|
|
197
|
+
* `providers`, the providers to re-authenticate with through `idToken`; or set
|
|
198
|
+
* a password through recovery. Nothing is counted against the account.
|
|
199
|
+
* - `PASSWORD_REQUIRED` · 400 — an `idToken` was sent for an account that HAS a
|
|
200
|
+
* password; it must re-authenticate with the password.
|
|
201
|
+
* - `INVALID_ID_TOKEN` · 401 / `SIGN_IN_IDENTITY_UNVERIFIED` · 401 — as on
|
|
202
|
+
* `register-social`.
|
|
203
|
+
* - `REAUTH_IDENTITY_MISMATCH` · 401 — the token's email is not the account's,
|
|
204
|
+
* or its provider is not one the account was registered with.
|
|
205
|
+
* - `REAUTH_NOT_RECENT` · 401 — the provider sign-in behind the token is older
|
|
206
|
+
* than 5 minutes; sign in with the provider again.
|
|
207
|
+
*/
|
|
208
|
+
exports.STAFF_REAUTH_ERROR_CODES = [
|
|
209
|
+
'WRONG_CREDENTIALS',
|
|
210
|
+
'PASSWORD_NOT_SET',
|
|
211
|
+
'PASSWORD_REQUIRED',
|
|
212
|
+
'INVALID_ID_TOKEN',
|
|
213
|
+
'SIGN_IN_IDENTITY_UNVERIFIED',
|
|
214
|
+
'REAUTH_IDENTITY_MISMATCH',
|
|
215
|
+
'REAUTH_NOT_RECENT',
|
|
216
|
+
];
|
|
169
217
|
/**
|
|
170
218
|
* `body.error` codes the operator refresh/session leg can refuse with —
|
|
171
219
|
* `POST /auth { mode: 'refresh' }` and the body-transport ingress it shares with
|
package/dist/cjs/marketing.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MARKETING_COPY_VARIANTS_MAX = exports.MARKETING_COPY_VARIANTS_MIN = exports.MARKETING_COPY_FACT_MAX_CHARS = exports.MARKETING_COPY_FACTS_MAX = exports.MARKETING_COPY_FACTS_MIN = exports.MARKETING_COPY_GOAL_MAX_CHARS = exports.ABANDONED_CART_SNAPSHOT_NAME_MAX = exports.ABANDONED_CART_SNAPSHOT_MAX_LINES = exports.CART_APPLICABLE_PROMOTION_TYPES = exports.PROMOTION_TYPES = exports.AUTOMATION_RULE_STATUSES = exports.AUTOMATION_SEND_STATUSES = exports.ATTRIBUTION_WINDOW_HOURS = exports.RFM_SEGMENT_LABELS = exports.AUTOMATION_TRIGGERS = void 0;
|
|
3
|
+
exports.MARKETING_COPY_VARIANTS_MAX = exports.MARKETING_COPY_VARIANTS_MIN = exports.MARKETING_COPY_FACT_MAX_CHARS = exports.MARKETING_COPY_FACTS_MAX = exports.MARKETING_COPY_FACTS_MIN = exports.MARKETING_COPY_GOAL_MAX_CHARS = exports.ABANDONED_CART_SNAPSHOT_NAME_MAX = exports.ABANDONED_CART_SNAPSHOT_MAX_LINES = exports.CART_APPLICABLE_PROMOTION_TYPES = exports.PROMOTION_TYPES = exports.AUTOMATION_RULE_STATUSES = exports.AUTOMATION_SEND_STATUSES = exports.ATTRIBUTION_WINDOW_HOURS = exports.RFM_SEGMENT_LABELS = exports.CAMPAIGN_ERROR_CODES = exports.CAMPAIGN_CLIENT_STATUSES = exports.AUTOMATION_TRIGGERS = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Runtime source for {@link AutomationTrigger}, the api’s Zod enum and the
|
|
6
6
|
* configuration picker. Derive them from this tuple; a separate union plus
|
|
@@ -11,6 +11,32 @@ exports.MARKETING_COPY_VARIANTS_MAX = exports.MARKETING_COPY_VARIANTS_MIN = expo
|
|
|
11
11
|
* consumers such as Record<AutomationTrigger, …>; handle it in the same change.
|
|
12
12
|
*/
|
|
13
13
|
exports.AUTOMATION_TRIGGERS = ['ABANDONED_CART', 'REORDER_DUE'];
|
|
14
|
+
/**
|
|
15
|
+
* The {@link CampaignStatus} values a client may write on `POST /campaigns`.
|
|
16
|
+
* Any other status is a 409 `CAMPAIGN_ILLEGAL_TRANSITION`; a client `sentAt` is
|
|
17
|
+
* a 400 `VALIDATION_FAILED`.
|
|
18
|
+
*/
|
|
19
|
+
exports.CAMPAIGN_CLIENT_STATUSES = [
|
|
20
|
+
'draft',
|
|
21
|
+
'scheduled',
|
|
22
|
+
'cancelled',
|
|
23
|
+
];
|
|
24
|
+
/**
|
|
25
|
+
* Refusals of the campaign status machine on `POST /campaigns`.
|
|
26
|
+
*
|
|
27
|
+
* - `CAMPAIGN_NOT_EDITABLE` · 409 — the campaign is `'sending'`, `'sent'` or
|
|
28
|
+
* `'cancelled'`, and the request changes no status.
|
|
29
|
+
* - `CAMPAIGN_ILLEGAL_TRANSITION` · 409 — the request (create or update) asks
|
|
30
|
+
* for a server-owned status (`'sending'` / `'sent'`), or asks a `'sending'`,
|
|
31
|
+
* `'sent'` or `'cancelled'` campaign for a different status.
|
|
32
|
+
* - `CAMPAIGN_STATUS_CONFLICT` · 409 — the status changed between the read and
|
|
33
|
+
* the write (usually the scheduler claiming it); re-read and retry.
|
|
34
|
+
*/
|
|
35
|
+
exports.CAMPAIGN_ERROR_CODES = [
|
|
36
|
+
'CAMPAIGN_NOT_EDITABLE',
|
|
37
|
+
'CAMPAIGN_ILLEGAL_TRANSITION',
|
|
38
|
+
'CAMPAIGN_STATUS_CONFLICT',
|
|
39
|
+
];
|
|
14
40
|
/**
|
|
15
41
|
* {@link RfmSegmentLabel} as a runtime value, so `isSegmentRuleValid`
|
|
16
42
|
* (`stacks/services/segments.ts`) and the nightly scoring pass
|
|
@@ -100,9 +100,10 @@ exports.PURCHASE_WITHDRAWAL_ACTION_MODES = ['accept', 'decline', 'relay'];
|
|
|
100
100
|
* on) on an order that already has an open shopper return request
|
|
101
101
|
* (`requested`, `authorized` or `received`); `data.rmaId` names it. One open
|
|
102
102
|
* shopper request per order.
|
|
103
|
-
* - `too-many-lines` — a
|
|
104
|
-
*
|
|
105
|
-
*
|
|
103
|
+
* - `too-many-lines` — a withdrawal naming more lines than
|
|
104
|
+
* {@link PURCHASE_WITHDRAWAL_LINES_MAX}, or a shopper return request (either
|
|
105
|
+
* flow) naming, or resolving to, more lines than one return request may hold;
|
|
106
|
+
* `data.max` is the bound.
|
|
106
107
|
*/
|
|
107
108
|
exports.PURCHASE_WITHDRAWAL_INELIGIBLE_REASONS = [
|
|
108
109
|
'order-cancelled',
|
|
@@ -131,8 +132,14 @@ exports.PURCHASE_WITHDRAWAL_INELIGIBLE_REASONS = [
|
|
|
131
132
|
exports.PURCHASE_WITHDRAWAL_FISCAL_IN_FLIGHT_CAUSES = ['in-progress', 'uncertain', 'stranded'];
|
|
132
133
|
/** The longest decline or relay `note`, in characters after trimming. */
|
|
133
134
|
exports.PURCHASE_WITHDRAWAL_NOTE_MAX = 500;
|
|
134
|
-
/**
|
|
135
|
-
|
|
135
|
+
/**
|
|
136
|
+
* The most lines one request may name. It is held to the worst case a single
|
|
137
|
+
* bound `Return` can carry: a withdrawal's hand-off RMA approves every line,
|
|
138
|
+
* and its `Return` must name exactly those lines, while the Return's
|
|
139
|
+
* transaction item budget fits 48 lines when every line restocks into a
|
|
140
|
+
* depósito as well as the store total. A larger withdrawal could never settle.
|
|
141
|
+
*/
|
|
142
|
+
exports.PURCHASE_WITHDRAWAL_LINES_MAX = 48;
|
|
136
143
|
/** Calendar days of the withdrawal window after the later of delivery and purchase. */
|
|
137
144
|
exports.PURCHASE_WITHDRAWAL_WINDOW_DAYS = 10;
|
|
138
145
|
/** The matrix row {@link PurchaseWithdrawal.windowClosesAt} is computed from. */
|
package/dist/cjs/terminal.js
CHANGED
|
@@ -90,6 +90,10 @@ exports.TERMINAL_ENROLMENT_ERROR_CODES = [
|
|
|
90
90
|
* - `INVALID_PIN_FORMAT` · 400 — `POST /terminal/pin`: not 4–6 digits.
|
|
91
91
|
* - `WRONG_CREDENTIALS` · 400 — `POST /terminal/pin`: the re-verified password
|
|
92
92
|
* did not match.
|
|
93
|
+
* - `PASSWORD_NOT_SET` · 409 — `POST /terminal/activation` and `POST
|
|
94
|
+
* /terminal/pin`: the employee (a founder registered with Google or Apple) has
|
|
95
|
+
* no password. The body carries `providers`, the recorded sign-in providers, as
|
|
96
|
+
* `POST /auth/verify-password` does. Nothing is counted against the account.
|
|
93
97
|
* - `IDEMPOTENCY_KEY_REUSE` · 422 / `IDEMPOTENCY_IN_PROGRESS` · 409 /
|
|
94
98
|
* `INVALID_IDEMPOTENCY_KEY` · 400 — the `Idempotency-Key` header's own
|
|
95
99
|
* refusals on `POST /terminal/operators`. A MISSING header is
|
|
@@ -126,6 +130,7 @@ exports.TERMINAL_SESSION_ERROR_CODES = [
|
|
|
126
130
|
'ROLE_NOT_ALLOWED',
|
|
127
131
|
'INVALID_PIN_FORMAT',
|
|
128
132
|
'WRONG_CREDENTIALS',
|
|
133
|
+
'PASSWORD_NOT_SET',
|
|
129
134
|
'IDEMPOTENCY_KEY_REUSE',
|
|
130
135
|
'IDEMPOTENCY_IN_PROGRESS',
|
|
131
136
|
'INVALID_IDEMPOTENCY_KEY',
|
package/dist/customer.d.ts
CHANGED
|
@@ -56,8 +56,13 @@ declare global {
|
|
|
56
56
|
interface ChannelConsentStamp {
|
|
57
57
|
/** ms epoch of the grant or withdrawal this stamp describes. */
|
|
58
58
|
ts: number;
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Who set the value. `'complaint'` is the SES events worker withdrawing
|
|
61
|
+
* `email` after the recipient marked a message as spam; it is only ever a
|
|
62
|
+
* withdrawal.
|
|
63
|
+
*/
|
|
64
|
+
source: 'ui' | 'import' | 'api' | 'storefront' | 'complaint';
|
|
65
|
+
/** Absent when the write had no request-level IP (a CSV import, a job, a complaint). */
|
|
61
66
|
ip?: string;
|
|
62
67
|
}
|
|
63
68
|
interface CustomerMarketing {
|
package/dist/marketing.d.ts
CHANGED
|
@@ -9,6 +9,21 @@ declare global {
|
|
|
9
9
|
* cheap, and having shipped a promise is not.
|
|
10
10
|
*/
|
|
11
11
|
type CampaignChannel = 'email';
|
|
12
|
+
/**
|
|
13
|
+
* Where a campaign is in its life. The api enforces the transitions:
|
|
14
|
+
*
|
|
15
|
+
* - `'draft'` → `'scheduled'` | `'cancelled'`
|
|
16
|
+
* - `'scheduled'` → `'draft'` | `'cancelled'`, or `'sending'` by the scheduler's claim
|
|
17
|
+
* - `'sending'` → `'sent'` once every recipient settled, or back to `'scheduled'`
|
|
18
|
+
* only on the scheduler's own fan-out retry
|
|
19
|
+
* - `'sent'` and `'cancelled'` are terminal.
|
|
20
|
+
*
|
|
21
|
+
* ⚠️ A client may write only {@link CAMPAIGN_CLIENT_STATUSES}. `'sending'`,
|
|
22
|
+
* `'sent'` and `sentAt` are server-owned, and a campaign that is `'sending'`,
|
|
23
|
+
* `'sent'` or `'cancelled'` cannot be edited at all — the refusals are
|
|
24
|
+
* {@link CAMPAIGN_ERROR_CODES}. A sent campaign is never sent again; to send
|
|
25
|
+
* the same content twice, create a new campaign.
|
|
26
|
+
*/
|
|
12
27
|
type CampaignStatus = 'draft' | 'scheduled' | 'sending' | 'sent' | 'cancelled';
|
|
13
28
|
interface Campaign {
|
|
14
29
|
storeId: string;
|
|
@@ -18,8 +33,14 @@ declare global {
|
|
|
18
33
|
status: CampaignStatus;
|
|
19
34
|
templateId?: string;
|
|
20
35
|
segmentId?: string;
|
|
36
|
+
/**
|
|
37
|
+
* ⚠️ UNUSED. Stored as the client sent it and returned on reads, but no
|
|
38
|
+
* code reads it: the send does not apply, mention or link a promotion.
|
|
39
|
+
* Do not build on it as if a campaign carried a discount.
|
|
40
|
+
*/
|
|
21
41
|
promotionId?: string;
|
|
22
42
|
scheduledAt?: number;
|
|
43
|
+
/** Unix MILLISECONDS. Server-owned: written only when the campaign reaches `'sent'`. */
|
|
23
44
|
sentAt?: number;
|
|
24
45
|
/**
|
|
25
46
|
* Aggregate send counters, maintained by an atomic DynamoDB `ADD` as the
|
|
@@ -65,6 +86,16 @@ declare global {
|
|
|
65
86
|
* bound the scheduler stops reverting and asks for an operator.
|
|
66
87
|
*/
|
|
67
88
|
sendAttempts?: number;
|
|
89
|
+
/**
|
|
90
|
+
* Server-owned. Present while recipients HELD by the email kill switch
|
|
91
|
+
* (`'failed'` / `EMAIL_SENDING_DISABLED`) await a re-enqueue: the send
|
|
92
|
+
* worker `ADD`s 1 on every hold, and the scheduler removes it once it has
|
|
93
|
+
* re-enqueued every held recipient after the switch is back on.
|
|
94
|
+
*
|
|
95
|
+
* ⚠️ A MARKER, not a recipient count: a recipient held twice counts twice.
|
|
96
|
+
* Read it as "held recipients are still owed a delivery", nothing more.
|
|
97
|
+
*/
|
|
98
|
+
sendHolds?: number;
|
|
68
99
|
createdAt: number;
|
|
69
100
|
updatedAt?: number;
|
|
70
101
|
}
|
|
@@ -73,12 +104,14 @@ declare global {
|
|
|
73
104
|
*
|
|
74
105
|
* `'queued'` — accepted for delivery, not yet handed to the transport.
|
|
75
106
|
* `'sent'` — the transport ACCEPTED it; acceptance is never proof of inbox
|
|
76
|
-
* placement. `'failed'` — the transport refused or errored
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
107
|
+
* placement. `'failed'` — the transport refused or errored, or the platform
|
|
108
|
+
* had email sending switched off (`reason: 'EMAIL_SENDING_DISABLED'`, held for
|
|
109
|
+
* a re-enqueue once sending is back on, and counted nowhere until it settles). `'skipped'` — the segment
|
|
110
|
+
* matched the recipient but the send was withheld at send time: the recipient
|
|
111
|
+
* was not eligible (no marketing consent for the channel, no address, a
|
|
112
|
+
* suppressed address, a customer that no longer exists or that the store
|
|
113
|
+
* disabled), the campaign was cancelled, or the store had its Marketing module
|
|
114
|
+
* switched off (`reason: 'MODULE_OFF'`). `CampaignRecipient.reason` carries which.
|
|
82
115
|
*
|
|
83
116
|
* ⚠️ `'skipped'` is a REFUSAL that was honoured, not a delivery problem:
|
|
84
117
|
* never retry it, and never roll it into a failure rate. A `'MODULE_OFF'`
|
|
@@ -477,12 +510,15 @@ declare global {
|
|
|
477
510
|
* a per-customer frequency cap. The configuration record for automated
|
|
478
511
|
* marketing — abandoned-cart recovery first.
|
|
479
512
|
*
|
|
480
|
-
* ⚠️ **
|
|
481
|
-
*
|
|
482
|
-
*
|
|
483
|
-
*
|
|
484
|
-
*
|
|
485
|
-
*
|
|
513
|
+
* ⚠️ **An `'active'` rule is an ARMED SENDER.** `cartSweep` (`ABANDONED_CART`)
|
|
514
|
+
* and `reorderDueCron` (`REORDER_DUE`) arm an {@link AutomationSend} for
|
|
515
|
+
* every active rule matching the trigger; the `automation-due` cron re-reads
|
|
516
|
+
* the rule, its template, the cap and consent when the delay ends, and the
|
|
517
|
+
* `automation-send` worker mails it. An archived template sends nothing.
|
|
518
|
+
* Automations are a `marketing` (Avanzado) feature: `/automation-rules` and
|
|
519
|
+
* `/templates` answer 403 `PLAN_UPGRADE_REQUIRED` without it, and both
|
|
520
|
+
* unattended lanes settle a store's due sends `'skipped'`
|
|
521
|
+
* `AUTOMATION_NOT_ENTITLED`.
|
|
486
522
|
*
|
|
487
523
|
* ⚠️ **No `channel`.** The bound `Template` already carries one, and a
|
|
488
524
|
* second copy is a second answer — the same argument
|
|
@@ -554,8 +590,12 @@ declare global {
|
|
|
554
590
|
* `'queued'` — accepted, not yet handed to a transport. `'sent'` — handed
|
|
555
591
|
* over. `'failed'` — the transport refused or errored. `'skipped'` — the rule
|
|
556
592
|
* matched but the send was withheld, by the frequency cap, by a live
|
|
557
|
-
* consent re-check,
|
|
558
|
-
* off (`reason: 'MODULE_OFF'`, a store choice rather than a customer's)
|
|
593
|
+
* consent re-check, because the store had its Marketing module switched
|
|
594
|
+
* off (`reason: 'MODULE_OFF'`, a store choice rather than a customer's),
|
|
595
|
+
* because its plan does not carry `marketing`
|
|
596
|
+
* (`reason: 'AUTOMATION_NOT_ENTITLED'`), or because the rule's template was
|
|
597
|
+
* archived (`reason: 'AUTOMATION_TEMPLATE_ARCHIVED'`). A `'skipped'` row
|
|
598
|
+
* does not count against the frequency cap.
|
|
559
599
|
*
|
|
560
600
|
* Deliberately the same four values as {@link CampaignRecipientStatus}, and
|
|
561
601
|
* deliberately a SEPARATE type rather than an alias: the two vocabularies
|
|
@@ -870,8 +910,18 @@ declare global {
|
|
|
870
910
|
due: number;
|
|
871
911
|
/** Sends handed to the transport queue. */
|
|
872
912
|
enqueued: number;
|
|
873
|
-
/**
|
|
913
|
+
/**
|
|
914
|
+
* Due rows withheld, each with its own recorded reason — including a
|
|
915
|
+
* store whose plan lacks `marketing` (`AUTOMATION_NOT_ENTITLED`).
|
|
916
|
+
*/
|
|
874
917
|
skipped: number;
|
|
918
|
+
/**
|
|
919
|
+
* Due rows whose evaluation or settle threw. Left queued, so the next run
|
|
920
|
+
* picks them up again; one deduped ERROR row per rule names them.
|
|
921
|
+
*/
|
|
922
|
+
failed: number;
|
|
923
|
+
/** Tenants whose drain threw. Isolated: the rest of the tick still ran. */
|
|
924
|
+
storesFailed: number;
|
|
875
925
|
/**
|
|
876
926
|
* The pass reached the end of its work rather than stopping on its own
|
|
877
927
|
* clock reserve. ⚠️ `false` is NORMAL under load and is not an error — it
|
|
@@ -1067,6 +1117,25 @@ declare global {
|
|
|
1067
1117
|
* consumers such as Record<AutomationTrigger, …>; handle it in the same change.
|
|
1068
1118
|
*/
|
|
1069
1119
|
export declare const AUTOMATION_TRIGGERS: readonly ["ABANDONED_CART", "REORDER_DUE"];
|
|
1120
|
+
/**
|
|
1121
|
+
* The {@link CampaignStatus} values a client may write on `POST /campaigns`.
|
|
1122
|
+
* Any other status is a 409 `CAMPAIGN_ILLEGAL_TRANSITION`; a client `sentAt` is
|
|
1123
|
+
* a 400 `VALIDATION_FAILED`.
|
|
1124
|
+
*/
|
|
1125
|
+
export declare const CAMPAIGN_CLIENT_STATUSES: readonly ["draft", "scheduled", "cancelled"];
|
|
1126
|
+
/**
|
|
1127
|
+
* Refusals of the campaign status machine on `POST /campaigns`.
|
|
1128
|
+
*
|
|
1129
|
+
* - `CAMPAIGN_NOT_EDITABLE` · 409 — the campaign is `'sending'`, `'sent'` or
|
|
1130
|
+
* `'cancelled'`, and the request changes no status.
|
|
1131
|
+
* - `CAMPAIGN_ILLEGAL_TRANSITION` · 409 — the request (create or update) asks
|
|
1132
|
+
* for a server-owned status (`'sending'` / `'sent'`), or asks a `'sending'`,
|
|
1133
|
+
* `'sent'` or `'cancelled'` campaign for a different status.
|
|
1134
|
+
* - `CAMPAIGN_STATUS_CONFLICT` · 409 — the status changed between the read and
|
|
1135
|
+
* the write (usually the scheduler claiming it); re-read and retry.
|
|
1136
|
+
*/
|
|
1137
|
+
export declare const CAMPAIGN_ERROR_CODES: readonly ["CAMPAIGN_NOT_EDITABLE", "CAMPAIGN_ILLEGAL_TRANSITION", "CAMPAIGN_STATUS_CONFLICT"];
|
|
1138
|
+
export type CampaignErrorCode = (typeof CAMPAIGN_ERROR_CODES)[number];
|
|
1070
1139
|
/**
|
|
1071
1140
|
* {@link RfmSegmentLabel} as a runtime value, so `isSegmentRuleValid`
|
|
1072
1141
|
* (`stacks/services/segments.ts`) and the nightly scoring pass
|
package/dist/marketing.js
CHANGED
|
@@ -8,6 +8,32 @@
|
|
|
8
8
|
* consumers such as Record<AutomationTrigger, …>; handle it in the same change.
|
|
9
9
|
*/
|
|
10
10
|
export const AUTOMATION_TRIGGERS = ['ABANDONED_CART', 'REORDER_DUE'];
|
|
11
|
+
/**
|
|
12
|
+
* The {@link CampaignStatus} values a client may write on `POST /campaigns`.
|
|
13
|
+
* Any other status is a 409 `CAMPAIGN_ILLEGAL_TRANSITION`; a client `sentAt` is
|
|
14
|
+
* a 400 `VALIDATION_FAILED`.
|
|
15
|
+
*/
|
|
16
|
+
export const CAMPAIGN_CLIENT_STATUSES = [
|
|
17
|
+
'draft',
|
|
18
|
+
'scheduled',
|
|
19
|
+
'cancelled',
|
|
20
|
+
];
|
|
21
|
+
/**
|
|
22
|
+
* Refusals of the campaign status machine on `POST /campaigns`.
|
|
23
|
+
*
|
|
24
|
+
* - `CAMPAIGN_NOT_EDITABLE` · 409 — the campaign is `'sending'`, `'sent'` or
|
|
25
|
+
* `'cancelled'`, and the request changes no status.
|
|
26
|
+
* - `CAMPAIGN_ILLEGAL_TRANSITION` · 409 — the request (create or update) asks
|
|
27
|
+
* for a server-owned status (`'sending'` / `'sent'`), or asks a `'sending'`,
|
|
28
|
+
* `'sent'` or `'cancelled'` campaign for a different status.
|
|
29
|
+
* - `CAMPAIGN_STATUS_CONFLICT` · 409 — the status changed between the read and
|
|
30
|
+
* the write (usually the scheduler claiming it); re-read and retry.
|
|
31
|
+
*/
|
|
32
|
+
export const CAMPAIGN_ERROR_CODES = [
|
|
33
|
+
'CAMPAIGN_NOT_EDITABLE',
|
|
34
|
+
'CAMPAIGN_ILLEGAL_TRANSITION',
|
|
35
|
+
'CAMPAIGN_STATUS_CONFLICT',
|
|
36
|
+
];
|
|
11
37
|
/**
|
|
12
38
|
* {@link RfmSegmentLabel} as a runtime value, so `isSegmentRuleValid`
|
|
13
39
|
* (`stacks/services/segments.ts`) and the nightly scoring pass
|
package/dist/order.d.ts
CHANGED
|
@@ -1236,6 +1236,18 @@ declare global {
|
|
|
1236
1236
|
printedAt?: number;
|
|
1237
1237
|
/** BE-minted pointer to the most recent print dispatch. Last-write-wins on reprint. */
|
|
1238
1238
|
printJobId?: string;
|
|
1239
|
+
/**
|
|
1240
|
+
* A snapshot of each factura issued on this order, located by `invoiceId`.
|
|
1241
|
+
* Two print fields mirror the invoice row and mean the same thing there:
|
|
1242
|
+
* - `invoicePrinted`: stamped `true` when `POST /invoices { mode: 'print' }`
|
|
1243
|
+
* dispatches a job — optimistic, not evidence the job printed;
|
|
1244
|
+
* - `printedAt`: server ms epoch, stamped when the agent's `ACK_PRINTED`
|
|
1245
|
+
* correlates to the invoice row's CURRENT `printJobId`. Removed by every
|
|
1246
|
+
* dispatch, so it is absent until that job is confirmed.
|
|
1247
|
+
* Both are written right after the invoice row's own stamp and announced on an
|
|
1248
|
+
* operator-only `orders` frame carrying `{ orderId, invoices }`. An entry for a
|
|
1249
|
+
* factura printed before the order copy was kept carries neither.
|
|
1250
|
+
*/
|
|
1239
1251
|
invoices?: Partial<Invoice>[];
|
|
1240
1252
|
/**
|
|
1241
1253
|
* Bounded, embedded projections of this order's returns, capped at 50.
|
|
@@ -82,9 +82,10 @@ export declare const PURCHASE_WITHDRAWAL_ACTION_MODES: readonly ["accept", "decl
|
|
|
82
82
|
* on) on an order that already has an open shopper return request
|
|
83
83
|
* (`requested`, `authorized` or `received`); `data.rmaId` names it. One open
|
|
84
84
|
* shopper request per order.
|
|
85
|
-
* - `too-many-lines` — a
|
|
86
|
-
*
|
|
87
|
-
*
|
|
85
|
+
* - `too-many-lines` — a withdrawal naming more lines than
|
|
86
|
+
* {@link PURCHASE_WITHDRAWAL_LINES_MAX}, or a shopper return request (either
|
|
87
|
+
* flow) naming, or resolving to, more lines than one return request may hold;
|
|
88
|
+
* `data.max` is the bound.
|
|
88
89
|
*/
|
|
89
90
|
export declare const PURCHASE_WITHDRAWAL_INELIGIBLE_REASONS: readonly ["order-cancelled", "no-customer", "partial-before-fulfilment", "line-not-on-order", "line-unavailable", "nothing-to-withdraw", "not-delivered", "return-request-open", "too-many-lines"];
|
|
90
91
|
/**
|
|
@@ -103,8 +104,14 @@ export declare const PURCHASE_WITHDRAWAL_INELIGIBLE_REASONS: readonly ["order-ca
|
|
|
103
104
|
export declare const PURCHASE_WITHDRAWAL_FISCAL_IN_FLIGHT_CAUSES: readonly ["in-progress", "uncertain", "stranded"];
|
|
104
105
|
/** The longest decline or relay `note`, in characters after trimming. */
|
|
105
106
|
export declare const PURCHASE_WITHDRAWAL_NOTE_MAX = 500;
|
|
106
|
-
/**
|
|
107
|
-
|
|
107
|
+
/**
|
|
108
|
+
* The most lines one request may name. It is held to the worst case a single
|
|
109
|
+
* bound `Return` can carry: a withdrawal's hand-off RMA approves every line,
|
|
110
|
+
* and its `Return` must name exactly those lines, while the Return's
|
|
111
|
+
* transaction item budget fits 48 lines when every line restocks into a
|
|
112
|
+
* depósito as well as the store total. A larger withdrawal could never settle.
|
|
113
|
+
*/
|
|
114
|
+
export declare const PURCHASE_WITHDRAWAL_LINES_MAX = 48;
|
|
108
115
|
/** Calendar days of the withdrawal window after the later of delivery and purchase. */
|
|
109
116
|
export declare const PURCHASE_WITHDRAWAL_WINDOW_DAYS = 10;
|
|
110
117
|
/** The matrix row {@link PurchaseWithdrawal.windowClosesAt} is computed from. */
|
|
@@ -450,7 +457,7 @@ declare global {
|
|
|
450
457
|
orderItemIndex?: number;
|
|
451
458
|
/** The open shopper return request, for `return-request-open`. */
|
|
452
459
|
rmaId?: string;
|
|
453
|
-
/** The
|
|
460
|
+
/** The bound a `too-many-lines` request exceeded: a withdrawal's, or a return request's. */
|
|
454
461
|
max?: number;
|
|
455
462
|
}
|
|
456
463
|
/** One of {@link PURCHASE_WITHDRAWAL_LIST_FILTERS}. */
|
|
@@ -97,9 +97,10 @@ export const PURCHASE_WITHDRAWAL_ACTION_MODES = ['accept', 'decline', 'relay'];
|
|
|
97
97
|
* on) on an order that already has an open shopper return request
|
|
98
98
|
* (`requested`, `authorized` or `received`); `data.rmaId` names it. One open
|
|
99
99
|
* shopper request per order.
|
|
100
|
-
* - `too-many-lines` — a
|
|
101
|
-
*
|
|
102
|
-
*
|
|
100
|
+
* - `too-many-lines` — a withdrawal naming more lines than
|
|
101
|
+
* {@link PURCHASE_WITHDRAWAL_LINES_MAX}, or a shopper return request (either
|
|
102
|
+
* flow) naming, or resolving to, more lines than one return request may hold;
|
|
103
|
+
* `data.max` is the bound.
|
|
103
104
|
*/
|
|
104
105
|
export const PURCHASE_WITHDRAWAL_INELIGIBLE_REASONS = [
|
|
105
106
|
'order-cancelled',
|
|
@@ -128,8 +129,14 @@ export const PURCHASE_WITHDRAWAL_INELIGIBLE_REASONS = [
|
|
|
128
129
|
export const PURCHASE_WITHDRAWAL_FISCAL_IN_FLIGHT_CAUSES = ['in-progress', 'uncertain', 'stranded'];
|
|
129
130
|
/** The longest decline or relay `note`, in characters after trimming. */
|
|
130
131
|
export const PURCHASE_WITHDRAWAL_NOTE_MAX = 500;
|
|
131
|
-
/**
|
|
132
|
-
|
|
132
|
+
/**
|
|
133
|
+
* The most lines one request may name. It is held to the worst case a single
|
|
134
|
+
* bound `Return` can carry: a withdrawal's hand-off RMA approves every line,
|
|
135
|
+
* and its `Return` must name exactly those lines, while the Return's
|
|
136
|
+
* transaction item budget fits 48 lines when every line restocks into a
|
|
137
|
+
* depósito as well as the store total. A larger withdrawal could never settle.
|
|
138
|
+
*/
|
|
139
|
+
export const PURCHASE_WITHDRAWAL_LINES_MAX = 48;
|
|
133
140
|
/** Calendar days of the withdrawal window after the later of delivery and purchase. */
|
|
134
141
|
export const PURCHASE_WITHDRAWAL_WINDOW_DAYS = 10;
|
|
135
142
|
/** The matrix row {@link PurchaseWithdrawal.windowClosesAt} is computed from. */
|
package/dist/terminal.d.ts
CHANGED
|
@@ -587,6 +587,10 @@ export type TerminalEnrolmentErrorCode = (typeof TERMINAL_ENROLMENT_ERROR_CODES)
|
|
|
587
587
|
* - `INVALID_PIN_FORMAT` · 400 — `POST /terminal/pin`: not 4–6 digits.
|
|
588
588
|
* - `WRONG_CREDENTIALS` · 400 — `POST /terminal/pin`: the re-verified password
|
|
589
589
|
* did not match.
|
|
590
|
+
* - `PASSWORD_NOT_SET` · 409 — `POST /terminal/activation` and `POST
|
|
591
|
+
* /terminal/pin`: the employee (a founder registered with Google or Apple) has
|
|
592
|
+
* no password. The body carries `providers`, the recorded sign-in providers, as
|
|
593
|
+
* `POST /auth/verify-password` does. Nothing is counted against the account.
|
|
590
594
|
* - `IDEMPOTENCY_KEY_REUSE` · 422 / `IDEMPOTENCY_IN_PROGRESS` · 409 /
|
|
591
595
|
* `INVALID_IDEMPOTENCY_KEY` · 400 — the `Idempotency-Key` header's own
|
|
592
596
|
* refusals on `POST /terminal/operators`. A MISSING header is
|
|
@@ -610,7 +614,7 @@ export type TerminalEnrolmentErrorCode = (typeof TERMINAL_ENROLMENT_ERROR_CODES)
|
|
|
610
614
|
* wrapper refused (`IDEMPOTENCY_KEY_REUSE` and the rest) exactly like a wrong
|
|
611
615
|
* PIN: a key reused with another PIN is not a free guess.
|
|
612
616
|
*/
|
|
613
|
-
export declare const TERMINAL_SESSION_ERROR_CODES: readonly ["TERMINAL_NOT_PAIRED", "SHIFT_NOT_OPEN", "TERMINAL_ACTIVATION_SESSION_INVALID", "TERMINAL_ACTIVATION_SESSION_MISMATCH", "TERMINAL_ACTIVATION_CLEANUP_FAILED", "TERMINAL_NOT_ACTIVATED", "INVALID_PIN", "ACCOUNT_LOCKED", "PIN_LOCKED", "ROLE_NOT_ALLOWED", "INVALID_PIN_FORMAT", "WRONG_CREDENTIALS", "IDEMPOTENCY_KEY_REUSE", "IDEMPOTENCY_IN_PROGRESS", "INVALID_IDEMPOTENCY_KEY", "IMPERSONATION_TERMINAL_FORBIDDEN", "VALIDATION_FAILED", "IDEMPOTENCY_LOCK_CONTENTION", "OPERATOR_TOKEN_FORBIDDEN", "INVALID_CURSOR", "OPERATOR_SESSION_STALE", "TERMINAL_LOCK_FORBIDDEN", "TERMINAL_LOCK_UNAVAILABLE"];
|
|
617
|
+
export declare const TERMINAL_SESSION_ERROR_CODES: readonly ["TERMINAL_NOT_PAIRED", "SHIFT_NOT_OPEN", "TERMINAL_ACTIVATION_SESSION_INVALID", "TERMINAL_ACTIVATION_SESSION_MISMATCH", "TERMINAL_ACTIVATION_CLEANUP_FAILED", "TERMINAL_NOT_ACTIVATED", "INVALID_PIN", "ACCOUNT_LOCKED", "PIN_LOCKED", "ROLE_NOT_ALLOWED", "INVALID_PIN_FORMAT", "WRONG_CREDENTIALS", "PASSWORD_NOT_SET", "IDEMPOTENCY_KEY_REUSE", "IDEMPOTENCY_IN_PROGRESS", "INVALID_IDEMPOTENCY_KEY", "IMPERSONATION_TERMINAL_FORBIDDEN", "VALIDATION_FAILED", "IDEMPOTENCY_LOCK_CONTENTION", "OPERATOR_TOKEN_FORBIDDEN", "INVALID_CURSOR", "OPERATOR_SESSION_STALE", "TERMINAL_LOCK_FORBIDDEN", "TERMINAL_LOCK_UNAVAILABLE"];
|
|
614
618
|
export type TerminalSessionErrorCode = (typeof TERMINAL_SESSION_ERROR_CODES)[number];
|
|
615
619
|
/** The device kinds a pairing code can pair (`TerminalPairingCodeRequest.kind`). */
|
|
616
620
|
export declare const TERMINAL_PAIRING_KINDS: readonly ["terminal", "print-agent"];
|
package/dist/terminal.js
CHANGED
|
@@ -87,6 +87,10 @@ export const TERMINAL_ENROLMENT_ERROR_CODES = [
|
|
|
87
87
|
* - `INVALID_PIN_FORMAT` · 400 — `POST /terminal/pin`: not 4–6 digits.
|
|
88
88
|
* - `WRONG_CREDENTIALS` · 400 — `POST /terminal/pin`: the re-verified password
|
|
89
89
|
* did not match.
|
|
90
|
+
* - `PASSWORD_NOT_SET` · 409 — `POST /terminal/activation` and `POST
|
|
91
|
+
* /terminal/pin`: the employee (a founder registered with Google or Apple) has
|
|
92
|
+
* no password. The body carries `providers`, the recorded sign-in providers, as
|
|
93
|
+
* `POST /auth/verify-password` does. Nothing is counted against the account.
|
|
90
94
|
* - `IDEMPOTENCY_KEY_REUSE` · 422 / `IDEMPOTENCY_IN_PROGRESS` · 409 /
|
|
91
95
|
* `INVALID_IDEMPOTENCY_KEY` · 400 — the `Idempotency-Key` header's own
|
|
92
96
|
* refusals on `POST /terminal/operators`. A MISSING header is
|
|
@@ -123,6 +127,7 @@ export const TERMINAL_SESSION_ERROR_CODES = [
|
|
|
123
127
|
'ROLE_NOT_ALLOWED',
|
|
124
128
|
'INVALID_PIN_FORMAT',
|
|
125
129
|
'WRONG_CREDENTIALS',
|
|
130
|
+
'PASSWORD_NOT_SET',
|
|
126
131
|
'IDEMPOTENCY_KEY_REUSE',
|
|
127
132
|
'IDEMPOTENCY_IN_PROGRESS',
|
|
128
133
|
'INVALID_IDEMPOTENCY_KEY',
|
package/dist/userActivity.d.ts
CHANGED
|
@@ -104,7 +104,8 @@ declare global {
|
|
|
104
104
|
channel: 'adds' | 'email' | 'phone' | 'sms' | 'whatsapp';
|
|
105
105
|
from: boolean | null;
|
|
106
106
|
to: boolean;
|
|
107
|
-
|
|
107
|
+
/** `'complaint'`: a spam complaint withdrew `email` (`to: false`, no `ip`). */
|
|
108
|
+
source: 'ui' | 'import' | 'api' | 'storefront' | 'complaint';
|
|
108
109
|
/**
|
|
109
110
|
* ⚠️ PII — absent when the write had no request-level IP. Stored only: every
|
|
110
111
|
* reader withholds it (both timeline reads, socket frames, the audit export
|
|
@@ -125,7 +126,7 @@ declare global {
|
|
|
125
126
|
}
|
|
126
127
|
/** Rows written for a customer's own action. Kept separate from {@link UserActivityEvent}. */
|
|
127
128
|
type CustomerActivityEvent = CustomerConsentUpdatedEvent;
|
|
128
|
-
/** A staff CSV import
|
|
129
|
+
/** A staff CSV import CLEARED consent on a customer row (an import never grants; a `true` cell is dropped). */
|
|
129
130
|
interface CustomerConsentImportedEvent extends UserActivityEventBase {
|
|
130
131
|
event: 'Customer Consent Imported';
|
|
131
132
|
customer_id: string;
|