platform-types 1.10.811 → 1.10.813

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 CHANGED
@@ -1905,6 +1905,37 @@ export type PasskeyErrorCode = (typeof PASSKEY_ERROR_CODES)[number];
1905
1905
  */
1906
1906
  export declare const SESSION_ACTION_ERROR_CODES: readonly ["SESSION_LOOKUP_INCOMPLETE", "SESSION_UNKNOWN", "REVOKE_INCOMPLETE"];
1907
1907
  export type SessionActionErrorCode = (typeof SESSION_ACTION_ERROR_CODES)[number];
1908
+ /**
1909
+ * `body.error` codes `POST /auth/account-deletion` (staff self-deletion,
1910
+ * {@link StaffAccountDeletionInput}) refuses with. Complete for that route.
1911
+ * Nothing is anonymised on any of them.
1912
+ *
1913
+ * - `VALIDATION_FAILED` · 400 — the body failed the schema.
1914
+ * - `USER001_PROTECTED` · 403 — the founding user cannot delete the account.
1915
+ * - `USER_PLATFORM_ROLE_PROTECTED` · 403 — a SUPERVISOR or MANAGER, on any store.
1916
+ * - `USER_NOT_FOUND` · 404 — the token has no USER row (a paired PRINTER).
1917
+ * - `ACCOUNT_DISABLED` · 400 — the account is suspended.
1918
+ * - `OPEN_DRAWER_BLOCKS_DELETION` · 409 — the user holds an open cash drawer;
1919
+ * close it first.
1920
+ * - `PASSWORD_REQUIRED_FOR_DELETION` · 409 — the account has no password to
1921
+ * re-authenticate with; set one first. Counts no login failure.
1922
+ * - `ACCOUNT_LOCKED` · 403 — the shared brute-force lockout; carries
1923
+ * `retryAfterSeconds` (`AccountLockedResponse`).
1924
+ * - `WRONG_CREDENTIALS` · ⚠️ **401** here (400 on login) — wrong current
1925
+ * password; counted on the shared login counter.
1926
+ * - `REQUIRES_2FA` · 401 — 2FA is enrolled and no `code` was sent.
1927
+ * - `INVALID_2FA_CODE` · 401 — wrong or used `code`.
1928
+ * - `2FA_LOCKED` · 429 — the factor is locked; back off.
1929
+ * - `LAST_ADMIN_MUST_TRANSFER` · 409 — the caller is the store's only live
1930
+ * ADMIN; make another user ADMIN first. Also the answer when another ADMIN
1931
+ * deleted their account concurrently and left the caller the last one.
1932
+ * - `USER_CHANGED_DURING_REMOVAL` · 409 — the row (or, for an ADMIN, the store's
1933
+ * ADMIN set, twice) changed while the request ran. Retry.
1934
+ * - `USER_EMAIL_CLAIM_NOT_OWNED` · 409 — the address claim could not be
1935
+ * released; contact support before retrying.
1936
+ */
1937
+ export declare const STAFF_ACCOUNT_DELETION_ERROR_CODES: readonly ["VALIDATION_FAILED", "USER001_PROTECTED", "USER_PLATFORM_ROLE_PROTECTED", "USER_NOT_FOUND", "ACCOUNT_DISABLED", "OPEN_DRAWER_BLOCKS_DELETION", "PASSWORD_REQUIRED_FOR_DELETION", "ACCOUNT_LOCKED", "WRONG_CREDENTIALS", "REQUIRES_2FA", "INVALID_2FA_CODE", "2FA_LOCKED", "LAST_ADMIN_MUST_TRANSFER", "USER_CHANGED_DURING_REMOVAL", "USER_EMAIL_CLAIM_NOT_OWNED"];
1938
+ export type StaffAccountDeletionErrorCode = (typeof STAFF_ACCOUNT_DELETION_ERROR_CODES)[number];
1908
1939
  /**
1909
1940
  * `body.error` codes the two customer email-OTP modes (Web API `POST /auth`
1910
1941
  * `send-otp` / `verify-otp`) refuse with. Match on `body.error`.
package/dist/auth.js CHANGED
@@ -502,6 +502,52 @@ export const SESSION_ACTION_ERROR_CODES = [
502
502
  'SESSION_UNKNOWN',
503
503
  'REVOKE_INCOMPLETE',
504
504
  ];
505
+ /**
506
+ * `body.error` codes `POST /auth/account-deletion` (staff self-deletion,
507
+ * {@link StaffAccountDeletionInput}) refuses with. Complete for that route.
508
+ * Nothing is anonymised on any of them.
509
+ *
510
+ * - `VALIDATION_FAILED` · 400 — the body failed the schema.
511
+ * - `USER001_PROTECTED` · 403 — the founding user cannot delete the account.
512
+ * - `USER_PLATFORM_ROLE_PROTECTED` · 403 — a SUPERVISOR or MANAGER, on any store.
513
+ * - `USER_NOT_FOUND` · 404 — the token has no USER row (a paired PRINTER).
514
+ * - `ACCOUNT_DISABLED` · 400 — the account is suspended.
515
+ * - `OPEN_DRAWER_BLOCKS_DELETION` · 409 — the user holds an open cash drawer;
516
+ * close it first.
517
+ * - `PASSWORD_REQUIRED_FOR_DELETION` · 409 — the account has no password to
518
+ * re-authenticate with; set one first. Counts no login failure.
519
+ * - `ACCOUNT_LOCKED` · 403 — the shared brute-force lockout; carries
520
+ * `retryAfterSeconds` (`AccountLockedResponse`).
521
+ * - `WRONG_CREDENTIALS` · ⚠️ **401** here (400 on login) — wrong current
522
+ * password; counted on the shared login counter.
523
+ * - `REQUIRES_2FA` · 401 — 2FA is enrolled and no `code` was sent.
524
+ * - `INVALID_2FA_CODE` · 401 — wrong or used `code`.
525
+ * - `2FA_LOCKED` · 429 — the factor is locked; back off.
526
+ * - `LAST_ADMIN_MUST_TRANSFER` · 409 — the caller is the store's only live
527
+ * ADMIN; make another user ADMIN first. Also the answer when another ADMIN
528
+ * deleted their account concurrently and left the caller the last one.
529
+ * - `USER_CHANGED_DURING_REMOVAL` · 409 — the row (or, for an ADMIN, the store's
530
+ * ADMIN set, twice) changed while the request ran. Retry.
531
+ * - `USER_EMAIL_CLAIM_NOT_OWNED` · 409 — the address claim could not be
532
+ * released; contact support before retrying.
533
+ */
534
+ export const STAFF_ACCOUNT_DELETION_ERROR_CODES = [
535
+ 'VALIDATION_FAILED',
536
+ 'USER001_PROTECTED',
537
+ 'USER_PLATFORM_ROLE_PROTECTED',
538
+ 'USER_NOT_FOUND',
539
+ 'ACCOUNT_DISABLED',
540
+ 'OPEN_DRAWER_BLOCKS_DELETION',
541
+ 'PASSWORD_REQUIRED_FOR_DELETION',
542
+ 'ACCOUNT_LOCKED',
543
+ 'WRONG_CREDENTIALS',
544
+ 'REQUIRES_2FA',
545
+ 'INVALID_2FA_CODE',
546
+ '2FA_LOCKED',
547
+ 'LAST_ADMIN_MUST_TRANSFER',
548
+ 'USER_CHANGED_DURING_REMOVAL',
549
+ 'USER_EMAIL_CLAIM_NOT_OWNED',
550
+ ];
505
551
  /**
506
552
  * `body.error` codes the two customer email-OTP modes (Web API `POST /auth`
507
553
  * `send-otp` / `verify-otp`) refuse with. Match on `body.error`.
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.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.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
  *
@@ -505,6 +505,52 @@ exports.SESSION_ACTION_ERROR_CODES = [
505
505
  'SESSION_UNKNOWN',
506
506
  'REVOKE_INCOMPLETE',
507
507
  ];
508
+ /**
509
+ * `body.error` codes `POST /auth/account-deletion` (staff self-deletion,
510
+ * {@link StaffAccountDeletionInput}) refuses with. Complete for that route.
511
+ * Nothing is anonymised on any of them.
512
+ *
513
+ * - `VALIDATION_FAILED` · 400 — the body failed the schema.
514
+ * - `USER001_PROTECTED` · 403 — the founding user cannot delete the account.
515
+ * - `USER_PLATFORM_ROLE_PROTECTED` · 403 — a SUPERVISOR or MANAGER, on any store.
516
+ * - `USER_NOT_FOUND` · 404 — the token has no USER row (a paired PRINTER).
517
+ * - `ACCOUNT_DISABLED` · 400 — the account is suspended.
518
+ * - `OPEN_DRAWER_BLOCKS_DELETION` · 409 — the user holds an open cash drawer;
519
+ * close it first.
520
+ * - `PASSWORD_REQUIRED_FOR_DELETION` · 409 — the account has no password to
521
+ * re-authenticate with; set one first. Counts no login failure.
522
+ * - `ACCOUNT_LOCKED` · 403 — the shared brute-force lockout; carries
523
+ * `retryAfterSeconds` (`AccountLockedResponse`).
524
+ * - `WRONG_CREDENTIALS` · ⚠️ **401** here (400 on login) — wrong current
525
+ * password; counted on the shared login counter.
526
+ * - `REQUIRES_2FA` · 401 — 2FA is enrolled and no `code` was sent.
527
+ * - `INVALID_2FA_CODE` · 401 — wrong or used `code`.
528
+ * - `2FA_LOCKED` · 429 — the factor is locked; back off.
529
+ * - `LAST_ADMIN_MUST_TRANSFER` · 409 — the caller is the store's only live
530
+ * ADMIN; make another user ADMIN first. Also the answer when another ADMIN
531
+ * deleted their account concurrently and left the caller the last one.
532
+ * - `USER_CHANGED_DURING_REMOVAL` · 409 — the row (or, for an ADMIN, the store's
533
+ * ADMIN set, twice) changed while the request ran. Retry.
534
+ * - `USER_EMAIL_CLAIM_NOT_OWNED` · 409 — the address claim could not be
535
+ * released; contact support before retrying.
536
+ */
537
+ exports.STAFF_ACCOUNT_DELETION_ERROR_CODES = [
538
+ 'VALIDATION_FAILED',
539
+ 'USER001_PROTECTED',
540
+ 'USER_PLATFORM_ROLE_PROTECTED',
541
+ 'USER_NOT_FOUND',
542
+ 'ACCOUNT_DISABLED',
543
+ 'OPEN_DRAWER_BLOCKS_DELETION',
544
+ 'PASSWORD_REQUIRED_FOR_DELETION',
545
+ 'ACCOUNT_LOCKED',
546
+ 'WRONG_CREDENTIALS',
547
+ 'REQUIRES_2FA',
548
+ 'INVALID_2FA_CODE',
549
+ '2FA_LOCKED',
550
+ 'LAST_ADMIN_MUST_TRANSFER',
551
+ 'USER_CHANGED_DURING_REMOVAL',
552
+ 'USER_EMAIL_CLAIM_NOT_OWNED',
553
+ ];
508
554
  /**
509
555
  * `body.error` codes the two customer email-OTP modes (Web API `POST /auth`
510
556
  * `send-otp` / `verify-otp`) refuse with. Match on `body.error`.
@@ -7,10 +7,11 @@ exports.BASE_QUANTITY_DECIMAL_PLACES = 6;
7
7
  exports.MAX_BASE_QUANTITY = 1_000_000;
8
8
  /**
9
9
  * The `sort` values Web `GET /products?mode=discover` serves. `newest` is
10
- * descending product id; `price_asc` / `price_desc` are the caller's own price
11
- * (see `PublicProductDiscoverInput.sort`). Name sorts are not served.
10
+ * descending product id; `price_asc` / `price_desc` are the caller's own price;
11
+ * `name_asc` / `name_desc` are the product name under a Spanish collation (see
12
+ * `PublicProductDiscoverInput.sort`).
12
13
  */
13
- exports.DISCOVERY_SORTS = ['newest', 'price_asc', 'price_desc'];
14
+ exports.DISCOVERY_SORTS = ['newest', 'price_asc', 'price_desc', 'name_asc', 'name_desc'];
14
15
  /**
15
16
  * The facets Web `GET /products?mode=discover` can count (`facets=brand,tag,category`).
16
17
  * `brand` tallies `brandId`, `tag` each of `tagIds`, `category` the EXACT `categoryId`
package/dist/product.d.ts CHANGED
@@ -4,10 +4,11 @@ export declare const BASE_QUANTITY_DECIMAL_PLACES = 6;
4
4
  export declare const MAX_BASE_QUANTITY = 1000000;
5
5
  /**
6
6
  * The `sort` values Web `GET /products?mode=discover` serves. `newest` is
7
- * descending product id; `price_asc` / `price_desc` are the caller's own price
8
- * (see `PublicProductDiscoverInput.sort`). Name sorts are not served.
7
+ * descending product id; `price_asc` / `price_desc` are the caller's own price;
8
+ * `name_asc` / `name_desc` are the product name under a Spanish collation (see
9
+ * `PublicProductDiscoverInput.sort`).
9
10
  */
10
- export declare const DISCOVERY_SORTS: readonly ["newest", "price_asc", "price_desc"];
11
+ export declare const DISCOVERY_SORTS: readonly ["newest", "price_asc", "price_desc", "name_asc", "name_desc"];
11
12
  export type DiscoverySort = (typeof DISCOVERY_SORTS)[number];
12
13
  /**
13
14
  * The facets Web `GET /products?mode=discover` can count (`facets=brand,tag,category`).
@@ -298,8 +299,12 @@ declare global {
298
299
  * currency, an open offer counting as the price, no quantity break. Rows the
299
300
  * caller is shown no price for (a hidden slot, every row for a guest of a
300
301
  * store that hides prices) come LAST in both directions; equal prices and
301
- * that unpriced tail are newest first. A price sort reads the whole filtered
302
- * set on every page, so a set too large for one read is 400
302
+ * that unpriced tail are newest first. `name_asc` / `name_desc` = the
303
+ * shown product name, Spanish collation, case- and accent-insensitive,
304
+ * digits compared as numbers («HP 96» before «HP 904»); names that compare
305
+ * equal are newest first, and a row with no name comes LAST in both
306
+ * directions. A price or name sort reads the whole filtered set on every
307
+ * page, so a set too large for one read is 400
303
308
  * `DISCOVERY_SORT_UNSUPPORTED` after the reads, with `supportedSorts`
304
309
  * naming what that query can be served in, and a read the time budget cut
305
310
  * short is 503 `PRODUCT_LOOKUP_INCOMPLETE` (retryable). A price cursor is
@@ -406,12 +411,12 @@ declare global {
406
411
  }
407
412
  /** Refusals of Web `GET /products?mode=discover`. */
408
413
  type DiscoveryErrorCode = 'INVALID_DISCOVERY_QUERY' | 'INVALID_CURSOR' | 'DISCOVERY_SORT_UNSUPPORTED'
409
- /** 503: a price-sorted walk the time budget cut short; retry. */
414
+ /** 503: a price- or name-sorted walk the time budget cut short; retry. */
410
415
  | 'PRODUCT_LOOKUP_INCOMPLETE';
411
416
  /**
412
417
  * 400 body for a `sort` the api does not serve for this request; `supportedSorts` lists what
413
- * it does — every member for an unknown value, the non-price sorts when a price sort's
414
- * filtered set was too large to read whole.
418
+ * it does — every member for an unknown value, the sorts that need no whole-set read when a
419
+ * price or name sort's filtered set was too large to read whole.
415
420
  */
416
421
  interface DiscoverySortRefusal {
417
422
  message: string;
package/dist/product.js CHANGED
@@ -4,10 +4,11 @@ export const BASE_QUANTITY_DECIMAL_PLACES = 6;
4
4
  export const MAX_BASE_QUANTITY = 1_000_000;
5
5
  /**
6
6
  * The `sort` values Web `GET /products?mode=discover` serves. `newest` is
7
- * descending product id; `price_asc` / `price_desc` are the caller's own price
8
- * (see `PublicProductDiscoverInput.sort`). Name sorts are not served.
7
+ * descending product id; `price_asc` / `price_desc` are the caller's own price;
8
+ * `name_asc` / `name_desc` are the product name under a Spanish collation (see
9
+ * `PublicProductDiscoverInput.sort`).
9
10
  */
10
- export const DISCOVERY_SORTS = ['newest', 'price_asc', 'price_desc'];
11
+ export const DISCOVERY_SORTS = ['newest', 'price_asc', 'price_desc', 'name_asc', 'name_desc'];
11
12
  /**
12
13
  * The facets Web `GET /products?mode=discover` can count (`facets=brand,tag,category`).
13
14
  * `brand` tallies `brandId`, `tag` each of `tagIds`, `category` the EXACT `categoryId`
package/dist/store.d.ts CHANGED
@@ -595,6 +595,16 @@ declare global {
595
595
  * `FIELD_NOT_WRITABLE_HERE`; it moves through its own PATCH route.
596
596
  */
597
597
  palette?: StorePalette;
598
+ /**
599
+ * SERVER-ONLY — never on any app or web projection; declared so the
600
+ * ownership table covers it. A counter bumped by every staff
601
+ * self-deletion of an ADMIN (`POST /auth/account-deletion`), in the same
602
+ * transaction as the anonymise and conditioned on the value read before
603
+ * the store's live ADMINs were counted, so two ADMINs leaving at once
604
+ * cannot both commit and leave the store with none. Absent until the
605
+ * first such removal. No request body may set it.
606
+ */
607
+ adminRemovalGeneration?: number;
598
608
  storeId: string;
599
609
  createdAt: number;
600
610
  /** Unix ms — BE-stamped on every `POST`/`PATCH /store` write. Always present on written rows. */
package/dist/user.d.ts CHANGED
@@ -401,6 +401,35 @@ declare global {
401
401
  * Distinct from `LoginErrorCode`, which covers the sign-in lockout flow.
402
402
  */
403
403
  type UserWriteErrorCode = 'EMAIL_IN_USE' | 'USER_ID_COLLISION';
404
+ /**
405
+ * `POST /auth/account-deletion` — the signed-in staff user deletes their OWN
406
+ * account. The row is anonymised in place exactly as `DELETE /users/{userId}`
407
+ * would; the store, its data and its invoices are untouched.
408
+ *
409
+ * `password` is the CURRENT password; `code` is a TOTP or recovery code,
410
+ * required when the account has 2FA enrolled (without it the answer is
411
+ * `401 REQUIRES_2FA`). Refusals: {@link STAFF_ACCOUNT_DELETION_ERROR_CODES}.
412
+ */
413
+ interface StaffAccountDeletionInput {
414
+ password: string;
415
+ code?: string;
416
+ }
417
+ /**
418
+ * The `200` of `POST /auth/account-deletion`, on the first deletion and on
419
+ * every repeat (idempotent: a repeat answers the ORIGINAL `anonymizedAt`).
420
+ * `revocationComplete: false` means the row IS anonymised but some session,
421
+ * trusted device, passkey or push device may still be live; repeating the
422
+ * call re-runs those sweeps. Every session of the account is revoked, the
423
+ * caller's own included — treat the 200 as a sign-out.
424
+ */
425
+ interface StaffAccountDeletionResponse {
426
+ message: string;
427
+ data: {
428
+ /** Unix ms of the anonymisation. */
429
+ anonymizedAt: number;
430
+ revocationComplete: boolean;
431
+ };
432
+ }
404
433
  /**
405
434
  * A stored `User` plus the refresh token, where one is delivered in the body
406
435
  * at all.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "platform-types",
3
- "version": "1.10.811",
3
+ "version": "1.10.813",
4
4
  "description": "Shared wire and entity contracts for the platform.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",