pi-kiosk-shared 2.3.3 → 2.3.5

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.
Files changed (73) hide show
  1. package/README.md +18 -9
  2. package/dist/analyticsPiiTags.d.ts +6 -0
  3. package/dist/analyticsPiiTags.d.ts.map +1 -0
  4. package/dist/api.d.ts +129 -0
  5. package/dist/api.d.ts.map +1 -0
  6. package/dist/api.js +305 -0
  7. package/dist/api.js.map +1 -0
  8. package/dist/auditEventCodes.d.ts +8 -0
  9. package/dist/auditEventCodes.d.ts.map +1 -0
  10. package/dist/auditEventCodes.js +180 -0
  11. package/dist/auditEventCodes.js.map +1 -0
  12. package/dist/auditEventDescriptions.d.ts +5 -0
  13. package/dist/auditEventDescriptions.d.ts.map +1 -0
  14. package/dist/auditEventDescriptions.js +849 -0
  15. package/dist/auditEventDescriptions.js.map +1 -0
  16. package/dist/auditEventLabels.d.ts +4 -0
  17. package/dist/auditEventLabels.d.ts.map +1 -0
  18. package/dist/auditEventLabels.js +858 -0
  19. package/dist/auditEventLabels.js.map +1 -0
  20. package/dist/auditMetadataDisplayFields.d.ts +9 -0
  21. package/dist/auditMetadataDisplayFields.d.ts.map +1 -0
  22. package/dist/auditMetadataDisplayFields.js +273 -0
  23. package/dist/auditMetadataDisplayFields.js.map +1 -0
  24. package/dist/barcode/normalizeScanPayload.d.ts +17 -0
  25. package/dist/barcode/normalizeScanPayload.d.ts.map +1 -0
  26. package/dist/barcode/normalizeScanPayload.js +100 -0
  27. package/dist/barcode/normalizeScanPayload.js.map +1 -0
  28. package/dist/checkout/sessionMetadataV3.d.ts +36 -0
  29. package/dist/checkout/sessionMetadataV3.d.ts.map +1 -0
  30. package/dist/checkout/sessionMetadataV3.js +6 -0
  31. package/dist/checkout/sessionMetadataV3.js.map +1 -0
  32. package/dist/checkout/sessionMetadataV4.d.ts +19 -0
  33. package/dist/checkout/sessionMetadataV4.d.ts.map +1 -0
  34. package/dist/checkout/sessionMetadataV4.js +33 -0
  35. package/dist/checkout/sessionMetadataV4.js.map +1 -0
  36. package/dist/checkout/sessionMetadataV5.d.ts +46 -0
  37. package/dist/checkout/sessionMetadataV5.d.ts.map +1 -0
  38. package/dist/checkout/sessionMetadataV5.js +40 -0
  39. package/dist/checkout/sessionMetadataV5.js.map +1 -0
  40. package/dist/errors/pickLocalizedApiMessage.d.ts +6 -0
  41. package/dist/errors/pickLocalizedApiMessage.d.ts.map +1 -0
  42. package/dist/errors/pickLocalizedApiMessage.js +31 -0
  43. package/dist/errors/pickLocalizedApiMessage.js.map +1 -0
  44. package/dist/hooks/scannerCameraConstraints.d.ts +57 -0
  45. package/dist/hooks/scannerCameraConstraints.d.ts.map +1 -0
  46. package/dist/hooks/scannerCameraConstraints.js +195 -0
  47. package/dist/hooks/scannerCameraConstraints.js.map +1 -0
  48. package/dist/hooks/scannerFormats.d.ts +11 -0
  49. package/dist/hooks/scannerFormats.d.ts.map +1 -0
  50. package/dist/hooks/scannerFormats.js +39 -0
  51. package/dist/hooks/scannerFormats.js.map +1 -0
  52. package/dist/hooks/scannerNativeTypes.d.ts +18 -0
  53. package/dist/hooks/scannerNativeTypes.d.ts.map +1 -0
  54. package/dist/hooks/scannerNativeTypes.js +2 -0
  55. package/dist/hooks/scannerNativeTypes.js.map +1 -0
  56. package/dist/hooks/scannerPlatformProfile.d.ts +23 -0
  57. package/dist/hooks/scannerPlatformProfile.d.ts.map +1 -0
  58. package/dist/hooks/scannerPlatformProfile.js +86 -0
  59. package/dist/hooks/scannerPlatformProfile.js.map +1 -0
  60. package/dist/hooks/scannerScanPasses.d.ts +23 -0
  61. package/dist/hooks/scannerScanPasses.d.ts.map +1 -0
  62. package/dist/hooks/scannerScanPasses.js +66 -0
  63. package/dist/hooks/scannerScanPasses.js.map +1 -0
  64. package/dist/hooks/selectEngine.d.ts +14 -0
  65. package/dist/hooks/selectEngine.d.ts.map +1 -0
  66. package/dist/hooks/selectEngine.js +2 -0
  67. package/dist/hooks/selectEngine.js.map +1 -0
  68. package/dist/hooks/zxingJsSensitiveDecode.d.ts +13 -0
  69. package/dist/hooks/zxingJsSensitiveDecode.d.ts.map +1 -0
  70. package/dist/hooks/zxingJsSensitiveDecode.js +54 -0
  71. package/dist/hooks/zxingJsSensitiveDecode.js.map +1 -0
  72. package/dist/labels/localizedNameMap.d.ts +37 -0
  73. package/package.json +3 -2
package/README.md CHANGED
@@ -9,7 +9,7 @@ Shared types, API contracts, and error classes for the Pi Kiosk system.
9
9
 
10
10
  ## Temporary retention
11
11
 
12
- `up-backend` keeps production `react` / `react-dom` until cold/start paths consume a Node-safe published or overlaid main barrel. Do **not** drop those deps until that consume path is proven on the version actually installed (registry tarball from `npm view`, or monorepo overlay of sibling `../shared` **2.3.2**). Same caveat as `up-backend/docs/DEPLOYMENT/DEPLOY_SEPARATE_REPOS.md`.
12
+ `up-backend` keeps production `react` / `react-dom` until cold/start paths consume a Node-safe published or overlaid main barrel. Do **not** drop those deps until that consume path is proven on the version actually installed (registry tarball from `npm view`, or monorepo overlay of sibling `../shared` **2.3.4**). Same caveat as `up-backend/docs/DEPLOYMENT/DEPLOY_SEPARATE_REPOS.md`.
13
13
 
14
14
  ## Installation
15
15
 
@@ -74,29 +74,38 @@ Frontends import React modules from `/ui`. The **target** main barrel (local ove
74
74
 
75
75
  ## Local monorepo overlay
76
76
 
77
- **Honesty (SSOT):** Live monorepo source is `shared/package.json` **2.3.2** (service-unavailable UX, ZBar WASM primary + still-image snap). All consumers pin **`^2.3.2`** in `package.json`. Lockfiles currently resolve **registry** `https://registry.npmjs.org/pi-kiosk-shared/-/pi-kiosk-shared-2.3.2.tgz` — the rewrite ships when that tarball is published **or** when monorepo overlay / local tarball bootstrap is used (below).
77
+ **Honesty (SSOT):** Live monorepo source is `shared/package.json` **2.3.4** (service-unavailable UX, ZBar WASM primary + still-image snap). All consumers pin **`^2.3.4`** in `package.json`. **Registry latest published** (check with `npm view pi-kiosk-shared version`) may lag monorepo source — until `2.3.4` is published, app-only `npm ci` with registry-only locks installs the newest tarball on npm (not necessarily 2.3.4). Monorepo dev uses overlay and/or **file tarball** locks (below).
78
+
79
+ **Committed lock reality (refresh after every `shared` bump):**
80
+
81
+ | Consumer | Typical lock `resolved` | Notes |
82
+ |----------|-------------------------|-------|
83
+ | `admin-app`, `rpapp-customer`, `rpapp-kiosk`, `rpapp-pickup`, `up-backend` | `file:../shared/pi-kiosk-shared-2.3.4.tgz` | After `npm install pi-kiosk-shared@file:../shared/pi-kiosk-shared-<version>.tgz` in each package |
84
+ | App-only / Railway (registry path) | `https://registry.npmjs.org/.../pi-kiosk-shared-<version>.tgz` | Requires publish + lock refresh to registry URL; confirm with `npm view` at deploy time |
85
+
86
+ Do **not** claim “all locks resolve registry X” unless grep of every `package-lock.json` confirms it. Stale `2.3.2` locks ship pre-rewrite outage UI on bare `npm ci`.
78
87
 
79
88
  ### Distribution paths (pick one per checkout)
80
89
 
81
90
  | Path | When | How UI rewrite reaches `node_modules` |
82
91
  |------|------|----------------------------------------|
83
92
  | **A — Monorepo overlay (local dev)** | Sibling `../shared` present | `npm install` / `npm ci` → `overlaySharedIfPresent.mjs` → `ensureDist.mjs` copies `shared/dist` into `node_modules/pi-kiosk-shared`. Vite alias reads sibling `dist` when present. |
84
- | **B — Registry `^2.3.2` (default locks)** | App-only clone / Railway | `npm ci` installs published tarball. **Requires** `npm view pi-kiosk-shared@2.3.2` to include the rewrite (publish after `shared` bump). |
85
- | **C — File tarball bootstrap (CI strict `npm ci`)** | Locks pinned to `file:../shared/pi-kiosk-shared-2.3.2.tgz` | Run `node scripts/workspace/bootstrap-pi-kiosk-shared-tarball.mjs` (repack + ephemeral integrity patch), then consumer `npm ci`. Tarball is **gitignored** — not in VCS. |
93
+ | **B — Registry `^2.3.4` (app-only deploy)** | App-only clone / Railway | `npm ci` installs published tarball. **Requires** `npm view pi-kiosk-shared@2.3.4` (or latest satisfying `^2.3.4`) to include the rewrite. |
94
+ | **C — File tarball bootstrap (CI strict `npm ci`)** | Locks pinned to `file:../shared/pi-kiosk-shared-2.3.4.tgz` | Run `node scripts/workspace/bootstrap-pi-kiosk-shared-tarball.mjs` (repack + ephemeral integrity patch), then consumer `npm ci`. Tarball is **gitignored** — not in VCS. |
86
95
 
87
96
  Verify local pack contents after `cd shared && npm run publish:local`:
88
97
 
89
98
  ```powershell
90
- tar -tf pi-kiosk-shared-2.3.2.tgz | Select-String DatabaseUnavailable
99
+ tar -tf pi-kiosk-shared-2.3.4.tgz | Select-String DatabaseUnavailable
91
100
  # dist/components/DatabaseUnavailable.js must contain "Aplikace teď není dostupná"
92
101
  ```
93
102
 
94
103
  ### Consumer lock tarball bootstrap (Strategy A — optional)
95
104
 
96
- When frontends use a **file tarball** pin (instead of registry `^2.3.2`):
105
+ When frontends use a **file tarball** pin (instead of registry `^2.3.4`):
97
106
 
98
107
  ```json
99
- "pi-kiosk-shared": "file:../shared/pi-kiosk-shared-2.3.2.tgz"
108
+ "pi-kiosk-shared": "file:../shared/pi-kiosk-shared-2.3.4.tgz"
100
109
  ```
101
110
 
102
111
  The tarball is **gitignored** (`*.tgz` in repo root `.gitignore`) and is **not** in VCS. A fresh clone has no pack file until you build it:
@@ -129,7 +138,7 @@ npm ci
129
138
 
130
139
  **Local dev (preferred):** sibling `../shared` + `postinstall`/`prepare` overlay via `ensureDist.mjs` — tarball optional when the monorepo layout is complete and overlay runs on install.
131
140
 
132
- **Registry-only / Railway app-only clones:** with **registry `^2.3.2` pins** (current monorepo `package.json`/locks), bare **`npm ci` succeeds** on app-only checkouts — no sibling tarball required. If you use **monorepo `file:` tarball pins** instead, bare `npm ci` **fails** on app-only clones (missing pack file). **`prebuildShared.mjs` runs on `predev` / `prebuild` only** — npm has already finished `install`/`ci` by then, and the script does **not** rewrite `package.json` or `package-lock.json` (it side-installs `pi-kiosk-shared` into `node_modules` with `--no-save`, which does **not** make a later strict `npm ci` succeed on `file:` pins). App-only options for `file:` pins: **(a)** run `cd shared && npm run publish:local` and ensure `../shared/pi-kiosk-shared-<version>.tgz` exists on disk before consumer `npm ci` (see [Consumer lock tarball bootstrap](#consumer-lock-tarball-bootstrap)), or **(b)** commit app-only `package.json`/lock with registry pins (same as current monorepo). Confirm with `npm view pi-kiosk-shared version` at deploy time.
141
+ **Registry-only / Railway app-only clones:** with **registry `^2.3.4` pins**, bare **`npm ci` succeeds** on app-only checkouts when the tarball is published — no sibling tarball required. If you use **monorepo `file:` tarball pins** instead, bare `npm ci` **fails** on app-only clones (missing pack file). **`prebuildShared.mjs` runs on `predev` / `prebuild` only** — npm has already finished `install`/`ci` by then, and the script does **not** rewrite `package.json` or `package-lock.json` (it side-installs `pi-kiosk-shared` into `node_modules` with `--no-save`, which does **not** make a later strict `npm ci` succeed on `file:` pins). App-only options for `file:` pins: **(a)** run `cd shared && npm run publish:local` and ensure `../shared/pi-kiosk-shared-<version>.tgz` exists on disk before consumer `npm ci` (see [Consumer lock tarball bootstrap](#consumer-lock-tarball-bootstrap)), or **(b)** commit app-only `package.json`/lock with registry pins after publish. Confirm with `npm view pi-kiosk-shared version` at deploy time.
133
142
 
134
143
  **Documented cold path (monorepo):** `npm ci` / `npm install` in each app runs lifecycle hooks → `scripts/overlaySharedIfPresent.mjs` → `shared/scripts/ensureDist.mjs` when sibling `../shared` exists:
135
144
 
@@ -166,7 +175,7 @@ npm run gate:main-barrel-node-safe
166
175
 
167
176
  From `shared/`, prove the documented cold path:
168
177
 
169
- 1. **DIAGNOSTIC** — `npm pack` a known Node-safe registry tarball (`COLD_VERSION` in `prove-pi-kiosk-shared-cold-overlay.mjs`, currently `2.2.82` — intentional historical diagnostic fixture, not the live pin) in a temp dir and assert COLD_BAD markers (never installs into a consumer with `--ignore-scripts`). Live monorepo source is `shared/package.json` **2.3.2**.
178
+ 1. **DIAGNOSTIC** — `npm pack` a known Node-safe registry tarball (`COLD_VERSION` in `prove-pi-kiosk-shared-cold-overlay.mjs`, currently `2.2.82` — intentional historical diagnostic fixture, not the live pin) in a temp dir and assert COLD_BAD markers (never installs into a consumer with `--ignore-scripts`). Live monorepo source is `shared/package.json` **2.3.4**.
170
179
  2. **PASS** — wipe that consumer’s `node_modules/pi-kiosk-shared`, then `npm install` with **scripts on** (no package args) so `prepare` / `postinstall` overlays during install; assert Node-safe barrel + `NODE_IMPORT_OK`.
171
180
 
172
181
  ```bash
@@ -0,0 +1,6 @@
1
+ export type AnalyticsPiiClass = 'none' | 'pseudonymous' | 'direct' | 'financial';
2
+ type AnalyticsPiiTagsByField = Readonly<Record<string, AnalyticsPiiClass>>;
3
+ export declare const ANALYTICS_PII_FIELD_TAGS: Readonly<Record<string, AnalyticsPiiTagsByField>>;
4
+ export declare function getAnalyticsPiiTagsForEvent(eventName: string): Readonly<Record<string, AnalyticsPiiClass>> | undefined;
5
+ export {};
6
+ //# sourceMappingURL=analyticsPiiTags.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyticsPiiTags.d.ts","sourceRoot":"","sources":["../src/analyticsPiiTags.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,cAAc,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEjF,KAAK,uBAAuB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC;AAiH3E,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAC7C,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CACT,CAAC;AAEjC,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,MAAM,GAChB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,GAAG,SAAS,CAEzD"}
package/dist/api.d.ts ADDED
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Shared API Utilities
3
+ *
4
+ * API endpoints and HTTP client for communicating with backend
5
+ * Supports multi-tenant routing and authentication headers
6
+ */
7
+ /**
8
+ * Bank transfer webhook contract (H7 — manual / Postman testing):
9
+ * - Header `x-bank-transfer-webhook-secret` — shared secret (required when webhooks enabled)
10
+ * - Header `x-webhook-timestamp` — Unix epoch seconds (required; default max skew 900s)
11
+ * - Body `providerEventId` — required provider event id (dedupe key; duplicate → HTTP 409)
12
+ * - Body `paymentId`, `amount` — required; `bankTransactionId` optional (defaults to providerEventId)
13
+ */
14
+ export declare const BANK_TRANSFER_WEBHOOK_HEADERS: {
15
+ readonly SECRET: "x-bank-transfer-webhook-secret";
16
+ readonly TIMESTAMP: "x-webhook-timestamp";
17
+ };
18
+ /**
19
+ * BAR-PR-00b — salesPointId / kioskId alias on kiosk-facing POST bodies:
20
+ * `POST /api/products/lookup-barcode` and `POST /api/v1/kiosk-auth/card-lookup`
21
+ * accept either field as a positive integer JSON number or digit-only string.
22
+ * Validators normalize to canonical `salesPointId: number` before handlers run.
23
+ * See `up-backend/docs/BARCODE/api-contracts.md`.
24
+ */
25
+ export declare const API_ENDPOINTS: {
26
+ readonly PRODUCTS: "/api/products";
27
+ readonly PRODUCT_CLICK: "/api/products/:id/click";
28
+ /** Body: `{ barcode, salesPointId? | kioskId? }` — alias normalized to `salesPointId`. */
29
+ readonly PRODUCT_LOOKUP_BARCODE: "/api/products/lookup-barcode";
30
+ /** Body: `{ cardPayload, salesPointId? | kioskId? }` — alias normalized to `salesPointId`. */
31
+ readonly KIOSK_AUTH_CARD_LOOKUP: "/api/v1/kiosk-auth/card-lookup";
32
+ readonly PAYMENT_CREATE_QR: "/api/payments/create-qr";
33
+ readonly PAYMENT_CHECK_STATUS: "/api/payments/check-status/:paymentId";
34
+ readonly PAYMENT_COMPLETE: "/api/payments/complete";
35
+ readonly PAYMENT_CANCEL: "/api/payments/cancel";
36
+ readonly PAYMENT_START_MONITORING: "/api/payments/start-monitoring";
37
+ readonly PAYMENT_STOP_MONITORING: "/api/payments/stop-monitoring";
38
+ readonly PAYMENT_GATEWAY_CREATE: "/api/payments/create-gateway";
39
+ readonly PAYMENT_GATEWAY_STATUS: "/api/payments/gateway-status/:paymentId";
40
+ readonly PAYMENT_GATEWAY_CANCEL: "/api/payments/gateway-cancel";
41
+ readonly PAYMENT_GATEWAY_METHODS: "/api/payments/gateway-methods";
42
+ readonly PAYMENT_TERMINAL_CONNECTION_TOKEN: "/api/payments/terminal/connection-token";
43
+ readonly PAYMENT_CREATE_TERMINAL: "/api/payments/terminal/create-terminal";
44
+ readonly PAYMENT_TERMINAL_CANCEL: "/api/payments/terminal/cancel";
45
+ /** Public (tenant-scoped): POST /api/{tenantCode}/webhooks/payment/stripe */
46
+ readonly PAYMENT_STRIPE_WEBHOOK_PUBLIC: "/api/{tenantCode}/webhooks/payment/stripe";
47
+ readonly PAYMENT_BANK_TRANSFER_WEBHOOK: "/api/payments/bank-transfer-webhook";
48
+ readonly PAYMENT_TEST_BANK_TRANSFER_CHECK: "/api/payments/test-bank-transfer-check";
49
+ /** Authenticated kiosk fallback for post-kiosk handoff token (Phase 5). */
50
+ readonly PAYMENT_POST_KIOSK_HANDOFF: "/api/payments/post-kiosk-handoff/:paymentId";
51
+ /** Authenticated kiosk recovery handoff for failed/timeout payments. */
52
+ readonly PAYMENT_POST_KIOSK_RECOVERY_HANDOFF: "/api/payments/post-kiosk-recovery-handoff/:paymentId";
53
+ /** Enterprise outbox release gate (bucket C — backend no-ops when obligations disabled). */
54
+ readonly PAYMENT_RELEASE_GATE: "/api/payments/release-gate/:paymentId";
55
+ readonly PAYMENT_RECEIPT_PRINT_COMPLETE: "/api/payments/:paymentId/obligations/receipt-print/complete";
56
+ readonly PAYMENT_RECEIPT_PRINT_FAILED: "/api/payments/:paymentId/obligations/receipt-print/failed";
57
+ readonly ADMIN_LOGIN: "/api/admin/login";
58
+ readonly ADMIN_FORGOT_PASSWORD: "/api/admin/forgot-password";
59
+ readonly ADMIN_RESET_PASSWORD: "/api/admin/reset-password";
60
+ readonly DEV_FORGOT_PASSWORD: "/api/dev/forgot-password";
61
+ readonly DEV_RESET_PASSWORD: "/api/dev/reset-password";
62
+ readonly ADMIN_LOGOUT: "/api/admin/logout";
63
+ readonly ADMIN_PRODUCTS: "/api/admin/products";
64
+ readonly ADMIN_PRODUCTS_INVENTORY: "/api/admin/products/inventory/:salesPointId";
65
+ readonly ADMIN_PRODUCT_INVENTORY: "/api/admin/products/:id/inventory";
66
+ readonly ADMIN_PRODUCT_INVENTORY_UPDATE: "/api/admin/products/:productId/inventory/:salesPointId";
67
+ readonly ADMIN_PRODUCT_SALES_POINT_VISIBILITY: "/api/admin/products/:productId/sales-point/:salesPointId";
68
+ readonly ADMIN_SALES_POINTS: "/api/v1/admin/sales-points";
69
+ readonly ADMIN_SALES_POINT_DETAILS: "/api/v1/admin/sales-points/:id";
70
+ /** @deprecated Use ADMIN_SALES_POINTS */
71
+ readonly ADMIN_KIOSKS: "/api/v1/admin/sales-points";
72
+ /** @deprecated Use ADMIN_SALES_POINT_DETAILS */
73
+ readonly ADMIN_KIOSK_DETAILS: "/api/v1/admin/sales-points/:id";
74
+ readonly ADMIN_LOGS: "/api/admin/logs";
75
+ readonly ADMIN_CATEGORIES: "/api/v1/admin/categories";
76
+ readonly HEALTH: "/health";
77
+ readonly HEALTH_PAYMENT_PROVIDERS: "/health/payment-providers";
78
+ readonly HEALTH_PAYMENT_PROVIDERS_CHECK_BANK_TRANSFER: "/health/payment-providers/check-bank-transfer";
79
+ readonly CHECK_TRANSACTIONS: "/api/check-new-transactions";
80
+ readonly EVENTS: "/events/:salesPointId";
81
+ /** Public SSE — Obchody / customer directory inventory-parity updates. */
82
+ readonly PUBLIC_DIRECTORY_EVENTS: "/api/v1/public/directory/events";
83
+ };
84
+ /**
85
+ * Typed HTTP client for API communication
86
+ * Features:
87
+ * - Multi-tenant support (automatic path injection)
88
+ * - Kiosk secret authentication
89
+ * - Type-safe requests and responses
90
+ * - URL validation before requests
91
+ */
92
+ export declare class APIClient {
93
+ private baseUrl;
94
+ private kioskSecret?;
95
+ private tenantCode?;
96
+ private salesPointId?;
97
+ /** UI locale for Accept-Language + error message pick (default `cs`). */
98
+ private locale;
99
+ constructor(baseUrl: string, kioskSecret?: string, tenantCode?: string, salesPointId?: number, locale?: string);
100
+ /** Update UI locale used for Accept-Language and pickLocalizedApiMessage. */
101
+ setLocale(locale: string | undefined): void;
102
+ getLocale(): string;
103
+ private injectTenantIntoEndpoint;
104
+ private request;
105
+ get<T>(endpoint: string, headers?: Record<string, string>): Promise<T>;
106
+ /**
107
+ * GET with conditional caching — returns 304 without parsing a body (G-12 catalog poll).
108
+ */
109
+ getConditional<T>(endpoint: string, ifNoneMatch?: string): Promise<{
110
+ status: 200 | 304;
111
+ data?: T;
112
+ etag?: string | null;
113
+ }>;
114
+ post<T>(endpoint: string, data?: unknown): Promise<T>;
115
+ put<T>(endpoint: string, data?: unknown): Promise<T>;
116
+ delete<T>(endpoint: string): Promise<T>;
117
+ }
118
+ /** Normalize optional UI locale; empty / missing → `cs` (platform default). */
119
+ export declare function normalizeApiClientLocale(locale: string | undefined): string;
120
+ /**
121
+ * Factory function to create API client
122
+ * @param baseUrl - Optional API base URL (defaults to localhost:3015)
123
+ * @param kioskSecret - Optional kiosk authentication secret
124
+ * @param tenantCode - Optional tenant code for multi-tenant routing
125
+ * @param salesPointId - Optional sales point id (sent as `X-Sales-Point-Id` when set; pair with secret for device auth)
126
+ * @param locale - Optional UI locale for Accept-Language + error pick (defaults to `cs`)
127
+ */
128
+ export declare const createAPIClient: (baseUrl?: string, kioskSecret?: string, tenantCode?: string, salesPointId?: number, locale?: string) => APIClient;
129
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AASA;;;;;GAKG;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B;;;CAGhC,CAAC;AAEX;;;;;;GAMG;AAIH,eAAO,MAAM,aAAa;;;IAIxB,0FAA0F;;IAE1F,8FAA8F;;;;;;;;;;;;;;;IAmB9F,6EAA6E;;;;IAI7E,2EAA2E;;IAE3E,wEAAwE;;IAExE,4FAA4F;;;;;;;;;;;;;;;;;IAmB5F,yCAAyC;;IAEzC,gDAAgD;;;;;;;;;IAWhD,0EAA0E;;CAElE,CAAC;AAIX;;;;;;;GAOG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,WAAW,CAAC,CAAS;IAC7B,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,yEAAyE;IACzE,OAAO,CAAC,MAAM,CAAS;gBAGrB,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,MAAM,EACnB,YAAY,CAAC,EAAE,MAAM,EACrB,MAAM,CAAC,EAAE,MAAM;IAYjB,6EAA6E;IAC7E,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAI3C,SAAS,IAAI,MAAM;IAInB,OAAO,CAAC,wBAAwB;YAclB,OAAO;IA8Ff,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAI5E;;OAEG;IACG,cAAc,CAAC,CAAC,EACpB,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC;QAAE,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC;QAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAyC3D,IAAI,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAOrD,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAOpD,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;CAG9C;AAED,+EAA+E;AAC/E,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAK3E;AAiBD;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAC1B,UAAU,MAAM,EAChB,cAAc,MAAM,EACpB,aAAa,MAAM,EACnB,eAAe,MAAM,EACrB,SAAS,MAAM,KACd,SAKF,CAAC"}
package/dist/api.js ADDED
@@ -0,0 +1,305 @@
1
+ import { readRequestId, setClientCorrelationId, } from './logging/index.js';
2
+ // Bridge only — must NOT import ./sentry/initSentry.js (static @sentry/react breaks Node/backend).
3
+ import { setSentryCorrelationId } from './sentry/correlationTagBridge.js';
4
+ import { pickLocalizedApiMessage } from './errors/pickLocalizedApiMessage.js';
5
+ import { buildPromoApplyAcceptLanguage } from './promo/resolveApplyPromoEventDisplayName.js';
6
+ /**
7
+ * Shared API Utilities
8
+ *
9
+ * API endpoints and HTTP client for communicating with backend
10
+ * Supports multi-tenant routing and authentication headers
11
+ */
12
+ /**
13
+ * Bank transfer webhook contract (H7 — manual / Postman testing):
14
+ * - Header `x-bank-transfer-webhook-secret` — shared secret (required when webhooks enabled)
15
+ * - Header `x-webhook-timestamp` — Unix epoch seconds (required; default max skew 900s)
16
+ * - Body `providerEventId` — required provider event id (dedupe key; duplicate → HTTP 409)
17
+ * - Body `paymentId`, `amount` — required; `bankTransactionId` optional (defaults to providerEventId)
18
+ */
19
+ export const BANK_TRANSFER_WEBHOOK_HEADERS = {
20
+ SECRET: 'x-bank-transfer-webhook-secret',
21
+ TIMESTAMP: 'x-webhook-timestamp',
22
+ };
23
+ /**
24
+ * BAR-PR-00b — salesPointId / kioskId alias on kiosk-facing POST bodies:
25
+ * `POST /api/products/lookup-barcode` and `POST /api/v1/kiosk-auth/card-lookup`
26
+ * accept either field as a positive integer JSON number or digit-only string.
27
+ * Validators normalize to canonical `salesPointId: number` before handlers run.
28
+ * See `up-backend/docs/BARCODE/api-contracts.md`.
29
+ */
30
+ // ===== API Endpoints =====
31
+ export const API_ENDPOINTS = {
32
+ // Product endpoints
33
+ PRODUCTS: '/api/products',
34
+ PRODUCT_CLICK: '/api/products/:id/click',
35
+ /** Body: `{ barcode, salesPointId? | kioskId? }` — alias normalized to `salesPointId`. */
36
+ PRODUCT_LOOKUP_BARCODE: '/api/products/lookup-barcode',
37
+ /** Body: `{ cardPayload, salesPointId? | kioskId? }` — alias normalized to `salesPointId`. */
38
+ KIOSK_AUTH_CARD_LOOKUP: '/api/v1/kiosk-auth/card-lookup',
39
+ // Payment endpoints
40
+ PAYMENT_CREATE_QR: '/api/payments/create-qr',
41
+ PAYMENT_CHECK_STATUS: '/api/payments/check-status/:paymentId',
42
+ PAYMENT_COMPLETE: '/api/payments/complete',
43
+ PAYMENT_CANCEL: '/api/payments/cancel',
44
+ PAYMENT_START_MONITORING: '/api/payments/start-monitoring',
45
+ PAYMENT_STOP_MONITORING: '/api/payments/stop-monitoring',
46
+ // Redirect gateway payment endpoints
47
+ PAYMENT_GATEWAY_CREATE: '/api/payments/create-gateway',
48
+ PAYMENT_GATEWAY_STATUS: '/api/payments/gateway-status/:paymentId',
49
+ PAYMENT_GATEWAY_CANCEL: '/api/payments/gateway-cancel',
50
+ PAYMENT_GATEWAY_METHODS: '/api/payments/gateway-methods',
51
+ PAYMENT_TERMINAL_CONNECTION_TOKEN: '/api/payments/terminal/connection-token',
52
+ PAYMENT_CREATE_TERMINAL: '/api/payments/terminal/create-terminal',
53
+ PAYMENT_TERMINAL_CANCEL: '/api/payments/terminal/cancel',
54
+ /** Public (tenant-scoped): POST /api/{tenantCode}/webhooks/payment/stripe */
55
+ PAYMENT_STRIPE_WEBHOOK_PUBLIC: '/api/{tenantCode}/webhooks/payment/stripe',
56
+ PAYMENT_BANK_TRANSFER_WEBHOOK: '/api/payments/bank-transfer-webhook',
57
+ PAYMENT_TEST_BANK_TRANSFER_CHECK: '/api/payments/test-bank-transfer-check',
58
+ /** Authenticated kiosk fallback for post-kiosk handoff token (Phase 5). */
59
+ PAYMENT_POST_KIOSK_HANDOFF: '/api/payments/post-kiosk-handoff/:paymentId',
60
+ /** Authenticated kiosk recovery handoff for failed/timeout payments. */
61
+ PAYMENT_POST_KIOSK_RECOVERY_HANDOFF: '/api/payments/post-kiosk-recovery-handoff/:paymentId',
62
+ /** Enterprise outbox release gate (bucket C — backend no-ops when obligations disabled). */
63
+ PAYMENT_RELEASE_GATE: '/api/payments/release-gate/:paymentId',
64
+ PAYMENT_RECEIPT_PRINT_COMPLETE: '/api/payments/:paymentId/obligations/receipt-print/complete',
65
+ PAYMENT_RECEIPT_PRINT_FAILED: '/api/payments/:paymentId/obligations/receipt-print/failed',
66
+ // Admin endpoints
67
+ ADMIN_LOGIN: '/api/admin/login',
68
+ ADMIN_FORGOT_PASSWORD: '/api/admin/forgot-password',
69
+ ADMIN_RESET_PASSWORD: '/api/admin/reset-password',
70
+ DEV_FORGOT_PASSWORD: '/api/dev/forgot-password',
71
+ DEV_RESET_PASSWORD: '/api/dev/reset-password',
72
+ ADMIN_LOGOUT: '/api/admin/logout',
73
+ ADMIN_PRODUCTS: '/api/admin/products',
74
+ ADMIN_PRODUCTS_INVENTORY: '/api/admin/products/inventory/:salesPointId',
75
+ ADMIN_PRODUCT_INVENTORY: '/api/admin/products/:id/inventory',
76
+ ADMIN_PRODUCT_INVENTORY_UPDATE: '/api/admin/products/:productId/inventory/:salesPointId',
77
+ ADMIN_PRODUCT_SALES_POINT_VISIBILITY: '/api/admin/products/:productId/sales-point/:salesPointId',
78
+ ADMIN_SALES_POINTS: '/api/v1/admin/sales-points',
79
+ ADMIN_SALES_POINT_DETAILS: '/api/v1/admin/sales-points/:id',
80
+ /** @deprecated Use ADMIN_SALES_POINTS */
81
+ ADMIN_KIOSKS: '/api/v1/admin/sales-points',
82
+ /** @deprecated Use ADMIN_SALES_POINT_DETAILS */
83
+ ADMIN_KIOSK_DETAILS: '/api/v1/admin/sales-points/:id',
84
+ ADMIN_LOGS: '/api/admin/logs',
85
+ ADMIN_CATEGORIES: '/api/v1/admin/categories',
86
+ // System endpoints
87
+ HEALTH: '/health',
88
+ HEALTH_PAYMENT_PROVIDERS: '/health/payment-providers',
89
+ HEALTH_PAYMENT_PROVIDERS_CHECK_BANK_TRANSFER: '/health/payment-providers/check-bank-transfer',
90
+ CHECK_TRANSACTIONS: '/api/check-new-transactions',
91
+ EVENTS: '/events/:salesPointId',
92
+ /** Public SSE — Obchody / customer directory inventory-parity updates. */
93
+ PUBLIC_DIRECTORY_EVENTS: '/api/v1/public/directory/events',
94
+ };
95
+ // ===== API Client =====
96
+ /**
97
+ * Typed HTTP client for API communication
98
+ * Features:
99
+ * - Multi-tenant support (automatic path injection)
100
+ * - Kiosk secret authentication
101
+ * - Type-safe requests and responses
102
+ * - URL validation before requests
103
+ */
104
+ export class APIClient {
105
+ baseUrl;
106
+ kioskSecret;
107
+ tenantCode;
108
+ salesPointId;
109
+ /** UI locale for Accept-Language + error message pick (default `cs`). */
110
+ locale;
111
+ constructor(baseUrl, kioskSecret, tenantCode, salesPointId, locale) {
112
+ if (!baseUrl || typeof baseUrl !== 'string') {
113
+ throw new Error('APIClient: baseUrl is required and must be a string');
114
+ }
115
+ this.baseUrl = baseUrl.replace(/\/$/, ''); // Remove trailing slash
116
+ this.kioskSecret = kioskSecret;
117
+ this.tenantCode = tenantCode;
118
+ this.salesPointId = salesPointId;
119
+ this.locale = normalizeApiClientLocale(locale);
120
+ }
121
+ /** Update UI locale used for Accept-Language and pickLocalizedApiMessage. */
122
+ setLocale(locale) {
123
+ this.locale = normalizeApiClientLocale(locale);
124
+ }
125
+ getLocale() {
126
+ return this.locale;
127
+ }
128
+ injectTenantIntoEndpoint(endpoint) {
129
+ if (!this.tenantCode) {
130
+ return endpoint;
131
+ }
132
+ if (endpoint.startsWith('/api/')) {
133
+ // Handle query strings - split endpoint and query, inject tenant into path only
134
+ const [pathPart, query] = endpoint.split('?');
135
+ const path = pathPart ?? endpoint;
136
+ const tenantPath = `/api/${this.tenantCode}${path.slice(4)}`;
137
+ return query ? `${tenantPath}?${query}` : tenantPath;
138
+ }
139
+ return endpoint;
140
+ }
141
+ async request(endpoint, options = {}) {
142
+ if (!endpoint || typeof endpoint !== 'string') {
143
+ throw new Error(`APIClient: endpoint is required and must be a string, got: ${typeof endpoint}`);
144
+ }
145
+ // Inject tenant into endpoint path if tenant is configured
146
+ const tenantEndpoint = this.injectTenantIntoEndpoint(endpoint);
147
+ const url = `${this.baseUrl}${tenantEndpoint}`;
148
+ // Validate URL before making request
149
+ try {
150
+ new URL(url);
151
+ }
152
+ catch (error) {
153
+ throw new Error(`APIClient: Invalid URL constructed: ${url}. baseUrl: ${this.baseUrl}, endpoint: ${endpoint}`);
154
+ }
155
+ const headers = {
156
+ 'Content-Type': 'application/json',
157
+ 'Accept-Language': buildPromoApplyAcceptLanguage(this.locale),
158
+ ...(options.headers || {}),
159
+ };
160
+ ensureAcceptLanguageHeader(headers, this.locale);
161
+ // Add sales point device headers when available
162
+ if (this.kioskSecret) {
163
+ headers['X-Sales-Point-Secret'] = this.kioskSecret;
164
+ }
165
+ if (typeof this.salesPointId === 'number' &&
166
+ Number.isInteger(this.salesPointId) &&
167
+ this.salesPointId > 0) {
168
+ headers['X-Sales-Point-Id'] = String(this.salesPointId);
169
+ }
170
+ const response = await fetch(url, {
171
+ ...options,
172
+ headers,
173
+ });
174
+ if (!response.ok) {
175
+ const retryAfter = response.headers.get('Retry-After');
176
+ let code;
177
+ let message = response.statusText;
178
+ let requestId = readRequestId(response);
179
+ try {
180
+ const parsed = (await response.json());
181
+ message = parsed?.error ?? parsed?.message ?? message;
182
+ code = parsed?.code;
183
+ if (requestId === undefined && typeof parsed?.requestId === 'string') {
184
+ requestId = parsed.requestId;
185
+ }
186
+ }
187
+ catch {
188
+ // keep statusText
189
+ }
190
+ message = pickLocalizedApiMessage(message, this.locale);
191
+ if (requestId !== undefined) {
192
+ setClientCorrelationId(requestId);
193
+ setSentryCorrelationId(requestId);
194
+ }
195
+ const err = new Error(`HTTP ${response.status}: ${message}`);
196
+ err.statusCode = response.status;
197
+ err.code = code;
198
+ if (requestId !== undefined) {
199
+ err.requestId = requestId;
200
+ }
201
+ if (retryAfter) {
202
+ const sec = Number(retryAfter);
203
+ if (Number.isFinite(sec) && sec > 0) {
204
+ err.retryAfterSeconds = sec;
205
+ }
206
+ }
207
+ throw err;
208
+ }
209
+ const okId = readRequestId(response);
210
+ if (okId !== undefined) {
211
+ setClientCorrelationId(okId);
212
+ setSentryCorrelationId(okId);
213
+ }
214
+ return response.json();
215
+ }
216
+ async get(endpoint, headers) {
217
+ return this.request(endpoint, { method: 'GET', headers });
218
+ }
219
+ /**
220
+ * GET with conditional caching — returns 304 without parsing a body (G-12 catalog poll).
221
+ */
222
+ async getConditional(endpoint, ifNoneMatch) {
223
+ if (!endpoint || typeof endpoint !== 'string') {
224
+ throw new Error(`APIClient: endpoint is required and must be a string, got: ${typeof endpoint}`);
225
+ }
226
+ const tenantEndpoint = this.injectTenantIntoEndpoint(endpoint);
227
+ const url = `${this.baseUrl}${tenantEndpoint}`;
228
+ const headers = {
229
+ 'Content-Type': 'application/json',
230
+ 'Accept-Language': buildPromoApplyAcceptLanguage(this.locale),
231
+ };
232
+ if (ifNoneMatch) {
233
+ headers['If-None-Match'] = ifNoneMatch;
234
+ }
235
+ if (this.kioskSecret) {
236
+ headers['X-Sales-Point-Secret'] = this.kioskSecret;
237
+ }
238
+ if (typeof this.salesPointId === 'number' &&
239
+ Number.isInteger(this.salesPointId) &&
240
+ this.salesPointId > 0) {
241
+ headers['X-Sales-Point-Id'] = String(this.salesPointId);
242
+ }
243
+ const response = await fetch(url, { method: 'GET', headers });
244
+ const etag = response.headers.get('etag');
245
+ const conditionalId = readRequestId(response);
246
+ if (conditionalId !== undefined) {
247
+ setClientCorrelationId(conditionalId);
248
+ setSentryCorrelationId(conditionalId);
249
+ }
250
+ if (response.status === 304) {
251
+ return { status: 304, etag };
252
+ }
253
+ if (!response.ok) {
254
+ const statusMessage = pickLocalizedApiMessage(response.statusText, this.locale);
255
+ throw new Error(`HTTP ${response.status}: ${statusMessage}`);
256
+ }
257
+ const data = (await response.json());
258
+ return { status: 200, data, etag };
259
+ }
260
+ async post(endpoint, data) {
261
+ return this.request(endpoint, {
262
+ method: 'POST',
263
+ body: data ? JSON.stringify(data) : undefined,
264
+ });
265
+ }
266
+ async put(endpoint, data) {
267
+ return this.request(endpoint, {
268
+ method: 'PUT',
269
+ body: data ? JSON.stringify(data) : undefined,
270
+ });
271
+ }
272
+ async delete(endpoint) {
273
+ return this.request(endpoint, { method: 'DELETE' });
274
+ }
275
+ }
276
+ /** Normalize optional UI locale; empty / missing → `cs` (platform default). */
277
+ export function normalizeApiClientLocale(locale) {
278
+ if (typeof locale === 'string' && locale.trim().length > 0) {
279
+ return locale.trim();
280
+ }
281
+ return 'cs';
282
+ }
283
+ /**
284
+ * Ensure Accept-Language is set (caller headers win when already present).
285
+ */
286
+ function ensureAcceptLanguageHeader(headers, locale) {
287
+ const hasAcceptLanguage = Object.keys(headers).some((key) => key.toLowerCase() === 'accept-language');
288
+ if (!hasAcceptLanguage) {
289
+ headers['Accept-Language'] = buildPromoApplyAcceptLanguage(locale);
290
+ }
291
+ }
292
+ /**
293
+ * Factory function to create API client
294
+ * @param baseUrl - Optional API base URL (defaults to localhost:3015)
295
+ * @param kioskSecret - Optional kiosk authentication secret
296
+ * @param tenantCode - Optional tenant code for multi-tenant routing
297
+ * @param salesPointId - Optional sales point id (sent as `X-Sales-Point-Id` when set; pair with secret for device auth)
298
+ * @param locale - Optional UI locale for Accept-Language + error pick (defaults to `cs`)
299
+ */
300
+ export const createAPIClient = (baseUrl, kioskSecret, tenantCode, salesPointId, locale) => {
301
+ // Fallback to default if not provided
302
+ const url = baseUrl || 'http://localhost:3015';
303
+ return new APIClient(url, kioskSecret, tenantCode, salesPointId, locale);
304
+ };
305
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Cross-package mirror of backend `domain/audit/auditEventCatalog.ts` AUDIT_EVENT_CODES.
3
+ * Append-only — never reorder. CI drift test keeps this in sync with domain.
4
+ */
5
+ export declare const AUDIT_EVENT_CODES: readonly ["auth.admin.login.success", "auth.admin.login.failed", "auth.admin.logout", "auth.admin.access.denied", "auth.admin.password_reset.requested", "auth.admin.password_reset.completed", "auth.admin.password_reset.failed", "auth.admin.mfa.enroll.success", "auth.admin.mfa.enroll.failed", "auth.admin.mfa.disable.success", "auth.admin.mfa.disable.failed", "auth.admin.mfa.challenge.success", "auth.admin.mfa.challenge.failed", "auth.admin.step_up.success", "auth.admin.step_up.failed", "auth.admin.break_glass.success", "auth.admin.break_glass.failed", "auth.admin.oidc.login.success", "auth.admin.oidc.login.failed", "auth.admin.oidc.invite.activated", "auth.admin.oidc.link.created", "auth.admin.oidc.link.removed", "auth.admin.oidc.link.remove_denied", "auth.admin.oidc.session.exchanged", "auth.admin.password.set", "customer.oidc.login", "customer.oidc.email_merged", "customer.oidc.link.remove_denied", "admin.invite.created", "admin.invite.resent", "admin.invite.activated", "admin.account.username_changed", "admin.account.password_changed", "admin.credentials.provider_secret.set", "admin.credentials.provider_secret.rotated", "admin.credentials.provider_secret.deleted", "admin.credentials.bank_secret.set", "admin.credentials.bank_secret.rotated", "admin.settings.updated", "admin.user.created", "admin.user.deactivated", "admin.user.reactivated", "admin.user.permanently_deleted", "admin.capability.granted", "admin.capability.revoked", "admin.capability.template_applied", "admin.exception_grant.requested", "admin.exception_grant.approved", "admin.exception_grant.rejected", "admin.exception_grant.executed", "admin.product.created", "admin.product.deactivated", "admin.product.reactivated", "admin.product.permanently_deleted", "admin.product.price_updated", "admin.product.stock_adjusted", "admin.category.deactivated", "admin.category.reactivated", "admin.category.permanently_deleted", "admin.category.icon_uploaded", "admin.category.icon_replaced", "admin.category.icon_deleted", "admin.variant.archived", "admin.variant.restored", "admin.variant.permanently_deleted", "admin.pickupPoint.deactivated", "admin.pickupPoint.reactivated", "admin.pickupPoint.permanently_deleted", "admin.donationProject.deactivated", "admin.donationProject.reactivated", "admin.donationProject.archived", "admin.customerMembership.suspended", "admin.retention.policy_updated", "admin.salesPoint.deactivated", "admin.salesPoint.reactivated", "admin.salesPoint.permanently_deleted", "admin.tenant.deactivated", "admin.tenant.permanently_deleted", "admin.tenant.reactivated", "admin.tenant.legal_closure_completed", "admin.tenant.physical_purge_started", "admin.tenant.physical_purge_completed", "admin.tenant.physical_purge_failed", "admin.tenant.physical_purge_blocked", "admin.tenant.physical_purge_scheduled", "admin.tenant.physical_purge_cancelled", "admin.tenant.contract_reopened", "admin.tenant.access_cut", "admin.tenant.logo_uploaded", "admin.tenant.logo_replaced", "admin.tenant.logo_deleted", "admin.salesPoint.image_uploaded", "admin.salesPoint.image_replaced", "admin.salesPoint.image_deleted", "admin.donation_template.created", "admin.donation_template.updated", "admin.donation_template.default_set", "admin.salesPoint.donation_projects.updated", "admin.salesPoint.donation_amounts.updated", "admin.product.media_saved", "admin.product.media_deleted", "admin.product.primary_image_changed", "admin.loyalty.physical_card_issued", "admin.loyalty.physical_card_revoked", "admin.promo.event.created", "admin.promo.event.paused", "admin.promo.reward.issued", "admin.promo.reward.revoked", "admin.promo.enrollment.revoked", "commerce.promo.reward.activated", "commerce.promo.reward.redeemed", "commerce.promo.reward.rolled_back", "commerce.promo.progress.updated", "commerce.promo.enrollment.created", "admin.product.barcode_assigned", "admin.product.barcode_cleared", "admin.product.barcode_alt_added", "admin.product.barcode_alt_removed", "admin.product.barcode_alt_promoted", "pickup.device.paired", "pickup.device.pairing.failed", "pickup.fulfillment.claim.acquired", "pickup.fulfillment.claim.released", "admin.inventory.incident.reported", "pickup.inventory.checkup_applied", "pickup.inventory.incident.opened", "inventory.incident.anomaly.signalled", "dev.tenant.created", "dev.tenant.updated", "dev.tenant.provider.updated", "dev.tenant.entitlement_policy.changed", "payment.transaction.state_changed", "payment.admin_manual_complete", "webhook_skipped_tenant_inactive", "payment.customer.refund.requested", "customer_pickup_ack_informational", "customer.receipt.downloaded", "reconciliation.transaction.refund_candidate.marked", "reconciliation.transaction.refund_candidate.unmarked", "reconciliation.bank_inbound.matched", "reconciliation.bank_inbound.attribute", "reconciliation.payment_claim.submitted", "reconciliation.payment_claim.approved", "reconciliation.payment_claim.rejected", "reconciliation.recurring_payment.missed", "reconciliation.recurring_payment.received", "reconciliation.bank_account.mode_changed", "payment.provider_wiring.verified", "payment.provider_wiring.verify_failed", "payment.provider_wiring.invalidated", "payment.cash_provider.risk_ack", "payment.cash_checkout.self_confirm", "payment.cash_shift.opened", "payment.cash_shift.closed", "payment.cash_drawer.open_signal", "export.analytics.explore.exported", "export.analytics.dev.views", "export.analytics.mission_control.exported", "analytics.mission_control.cross_tenant.read", "export.analytics.rollups.materialized", "export.transactions.exported", "export.fulfillment.exported", "export.compliance.audit_events.exported", "export.consent.grantees", "gdpr.erasure.completed", "gdpr.erasure.side_effects_pending", "platform.category.created", "platform.category.updated", "platform.category.deactivated"];
6
+ export type AuditEventCode = (typeof AUDIT_EVENT_CODES)[number];
7
+ export declare function isAuditEventCode(code: string): code is AuditEventCode;
8
+ //# sourceMappingURL=auditEventCodes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auditEventCodes.d.ts","sourceRoot":"","sources":["../src/auditEventCodes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,iBAAiB,irLA0KpB,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAIhE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,cAAc,CAErE"}