@endora-commerce/contracts 0.100.0

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 (327) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +34 -0
  3. package/dist/actor.d.ts +79 -0
  4. package/dist/actor.d.ts.map +1 -0
  5. package/dist/actor.js +41 -0
  6. package/dist/actor.js.map +1 -0
  7. package/dist/addresses.d.ts +134 -0
  8. package/dist/addresses.d.ts.map +1 -0
  9. package/dist/addresses.js +16 -0
  10. package/dist/addresses.js.map +1 -0
  11. package/dist/admin-actions.d.ts +367 -0
  12. package/dist/admin-actions.d.ts.map +1 -0
  13. package/dist/admin-actions.js +287 -0
  14. package/dist/admin-actions.js.map +1 -0
  15. package/dist/admin-contributions.d.ts +518 -0
  16. package/dist/admin-contributions.d.ts.map +1 -0
  17. package/dist/admin-contributions.js +495 -0
  18. package/dist/admin-contributions.js.map +1 -0
  19. package/dist/admin-i18n.d.ts +135 -0
  20. package/dist/admin-i18n.d.ts.map +1 -0
  21. package/dist/admin-i18n.js +72 -0
  22. package/dist/admin-i18n.js.map +1 -0
  23. package/dist/admin-notifications.d.ts +55 -0
  24. package/dist/admin-notifications.d.ts.map +1 -0
  25. package/dist/admin-notifications.js +16 -0
  26. package/dist/admin-notifications.js.map +1 -0
  27. package/dist/admin-roles.d.ts +125 -0
  28. package/dist/admin-roles.d.ts.map +1 -0
  29. package/dist/admin-roles.js +2 -0
  30. package/dist/admin-roles.js.map +1 -0
  31. package/dist/admin-users.d.ts +178 -0
  32. package/dist/admin-users.d.ts.map +1 -0
  33. package/dist/admin-users.js +14 -0
  34. package/dist/admin-users.js.map +1 -0
  35. package/dist/admin.d.ts +243 -0
  36. package/dist/admin.d.ts.map +1 -0
  37. package/dist/admin.js +246 -0
  38. package/dist/admin.js.map +1 -0
  39. package/dist/analytics.d.ts +123 -0
  40. package/dist/analytics.d.ts.map +1 -0
  41. package/dist/analytics.js +68 -0
  42. package/dist/analytics.js.map +1 -0
  43. package/dist/api-keys.d.ts +97 -0
  44. package/dist/api-keys.d.ts.map +1 -0
  45. package/dist/api-keys.js +64 -0
  46. package/dist/api-keys.js.map +1 -0
  47. package/dist/assets-library.d.ts +684 -0
  48. package/dist/assets-library.d.ts.map +1 -0
  49. package/dist/assets-library.js +181 -0
  50. package/dist/assets-library.js.map +1 -0
  51. package/dist/audit-logs.d.ts +141 -0
  52. package/dist/audit-logs.d.ts.map +1 -0
  53. package/dist/audit-logs.js +31 -0
  54. package/dist/audit-logs.js.map +1 -0
  55. package/dist/auth.d.ts +174 -0
  56. package/dist/auth.d.ts.map +1 -0
  57. package/dist/auth.js +27 -0
  58. package/dist/auth.js.map +1 -0
  59. package/dist/blog.d.ts +669 -0
  60. package/dist/blog.d.ts.map +1 -0
  61. package/dist/blog.js +360 -0
  62. package/dist/blog.js.map +1 -0
  63. package/dist/capabilities.d.ts +40 -0
  64. package/dist/capabilities.d.ts.map +1 -0
  65. package/dist/capabilities.js +38 -0
  66. package/dist/capabilities.js.map +1 -0
  67. package/dist/carts.d.ts +1367 -0
  68. package/dist/carts.d.ts.map +1 -0
  69. package/dist/carts.js +405 -0
  70. package/dist/carts.js.map +1 -0
  71. package/dist/catalog.d.ts +2855 -0
  72. package/dist/catalog.d.ts.map +1 -0
  73. package/dist/catalog.js +1543 -0
  74. package/dist/catalog.js.map +1 -0
  75. package/dist/cms.d.ts +872 -0
  76. package/dist/cms.d.ts.map +1 -0
  77. package/dist/cms.js +468 -0
  78. package/dist/cms.js.map +1 -0
  79. package/dist/common.d.ts +82 -0
  80. package/dist/common.d.ts.map +1 -0
  81. package/dist/common.js +72 -0
  82. package/dist/common.js.map +1 -0
  83. package/dist/comparisons.d.ts +487 -0
  84. package/dist/comparisons.d.ts.map +1 -0
  85. package/dist/comparisons.js +221 -0
  86. package/dist/comparisons.js.map +1 -0
  87. package/dist/credentials.d.ts +292 -0
  88. package/dist/credentials.d.ts.map +1 -0
  89. package/dist/credentials.js +142 -0
  90. package/dist/credentials.js.map +1 -0
  91. package/dist/credit-limits.d.ts +111 -0
  92. package/dist/credit-limits.d.ts.map +1 -0
  93. package/dist/credit-limits.js +35 -0
  94. package/dist/credit-limits.js.map +1 -0
  95. package/dist/currencies.d.ts +127 -0
  96. package/dist/currencies.d.ts.map +1 -0
  97. package/dist/currencies.js +20 -0
  98. package/dist/currencies.js.map +1 -0
  99. package/dist/custom-fields.d.ts +345 -0
  100. package/dist/custom-fields.d.ts.map +1 -0
  101. package/dist/custom-fields.js +185 -0
  102. package/dist/custom-fields.js.map +1 -0
  103. package/dist/customer-accounts.d.ts +690 -0
  104. package/dist/customer-accounts.d.ts.map +1 -0
  105. package/dist/customer-accounts.js +41 -0
  106. package/dist/customer-accounts.js.map +1 -0
  107. package/dist/customers.d.ts +305 -0
  108. package/dist/customers.d.ts.map +1 -0
  109. package/dist/customers.js +158 -0
  110. package/dist/customers.js.map +1 -0
  111. package/dist/dictionary.d.ts +580 -0
  112. package/dist/dictionary.d.ts.map +1 -0
  113. package/dist/dictionary.js +297 -0
  114. package/dist/dictionary.js.map +1 -0
  115. package/dist/email-address.d.ts +62 -0
  116. package/dist/email-address.d.ts.map +1 -0
  117. package/dist/email-address.js +64 -0
  118. package/dist/email-address.js.map +1 -0
  119. package/dist/email.d.ts +175 -0
  120. package/dist/email.d.ts.map +1 -0
  121. package/dist/email.js +45 -0
  122. package/dist/email.js.map +1 -0
  123. package/dist/envelopes.d.ts +15 -0
  124. package/dist/envelopes.d.ts.map +1 -0
  125. package/dist/envelopes.js +16 -0
  126. package/dist/envelopes.js.map +1 -0
  127. package/dist/environment-inputs.d.ts +306 -0
  128. package/dist/environment-inputs.d.ts.map +1 -0
  129. package/dist/environment-inputs.js +277 -0
  130. package/dist/environment-inputs.js.map +1 -0
  131. package/dist/erp-connector.d.ts +52 -0
  132. package/dist/erp-connector.d.ts.map +1 -0
  133. package/dist/erp-connector.js +34 -0
  134. package/dist/erp-connector.js.map +1 -0
  135. package/dist/errors.d.ts +455 -0
  136. package/dist/errors.d.ts.map +1 -0
  137. package/dist/errors.js +532 -0
  138. package/dist/errors.js.map +1 -0
  139. package/dist/google-analytics.d.ts +181 -0
  140. package/dist/google-analytics.d.ts.map +1 -0
  141. package/dist/google-analytics.js +176 -0
  142. package/dist/google-analytics.js.map +1 -0
  143. package/dist/google-tag-manager.d.ts +111 -0
  144. package/dist/google-tag-manager.d.ts.map +1 -0
  145. package/dist/google-tag-manager.js +129 -0
  146. package/dist/google-tag-manager.js.map +1 -0
  147. package/dist/i18n.d.ts +69 -0
  148. package/dist/i18n.d.ts.map +1 -0
  149. package/dist/i18n.js +59 -0
  150. package/dist/i18n.js.map +1 -0
  151. package/dist/import-export.d.ts +63 -0
  152. package/dist/import-export.d.ts.map +1 -0
  153. package/dist/import-export.js +37 -0
  154. package/dist/import-export.js.map +1 -0
  155. package/dist/index.d.ts +82 -0
  156. package/dist/index.d.ts.map +1 -0
  157. package/dist/index.js +126 -0
  158. package/dist/index.js.map +1 -0
  159. package/dist/inventory.d.ts +673 -0
  160. package/dist/inventory.d.ts.map +1 -0
  161. package/dist/inventory.js +412 -0
  162. package/dist/inventory.js.map +1 -0
  163. package/dist/invoice-ledger.d.ts +366 -0
  164. package/dist/invoice-ledger.d.ts.map +1 -0
  165. package/dist/invoice-ledger.js +114 -0
  166. package/dist/invoice-ledger.js.map +1 -0
  167. package/dist/invoices.d.ts +845 -0
  168. package/dist/invoices.d.ts.map +1 -0
  169. package/dist/invoices.js +314 -0
  170. package/dist/invoices.js.map +1 -0
  171. package/dist/kernel.d.ts +49 -0
  172. package/dist/kernel.d.ts.map +1 -0
  173. package/dist/kernel.js +19 -0
  174. package/dist/kernel.js.map +1 -0
  175. package/dist/languages.d.ts +122 -0
  176. package/dist/languages.d.ts.map +1 -0
  177. package/dist/languages.js +24 -0
  178. package/dist/languages.js.map +1 -0
  179. package/dist/linkedin-ads.d.ts +167 -0
  180. package/dist/linkedin-ads.d.ts.map +1 -0
  181. package/dist/linkedin-ads.js +156 -0
  182. package/dist/linkedin-ads.js.map +1 -0
  183. package/dist/megamenu.d.ts +556 -0
  184. package/dist/megamenu.d.ts.map +1 -0
  185. package/dist/megamenu.js +186 -0
  186. package/dist/megamenu.js.map +1 -0
  187. package/dist/meta-ads.d.ts +126 -0
  188. package/dist/meta-ads.d.ts.map +1 -0
  189. package/dist/meta-ads.js +112 -0
  190. package/dist/meta-ads.js.map +1 -0
  191. package/dist/mfa.d.ts +274 -0
  192. package/dist/mfa.d.ts.map +1 -0
  193. package/dist/mfa.js +187 -0
  194. package/dist/mfa.js.map +1 -0
  195. package/dist/modules.d.ts +1706 -0
  196. package/dist/modules.d.ts.map +1 -0
  197. package/dist/modules.js +1390 -0
  198. package/dist/modules.js.map +1 -0
  199. package/dist/newsletter.d.ts +611 -0
  200. package/dist/newsletter.d.ts.map +1 -0
  201. package/dist/newsletter.js +345 -0
  202. package/dist/newsletter.js.map +1 -0
  203. package/dist/orders.d.ts +1175 -0
  204. package/dist/orders.d.ts.map +1 -0
  205. package/dist/orders.js +630 -0
  206. package/dist/orders.js.map +1 -0
  207. package/dist/organizations.d.ts +938 -0
  208. package/dist/organizations.d.ts.map +1 -0
  209. package/dist/organizations.js +418 -0
  210. package/dist/organizations.js.map +1 -0
  211. package/dist/pagination.d.ts +21 -0
  212. package/dist/pagination.d.ts.map +1 -0
  213. package/dist/pagination.js +22 -0
  214. package/dist/pagination.js.map +1 -0
  215. package/dist/payment-methods.d.ts +472 -0
  216. package/dist/payment-methods.d.ts.map +1 -0
  217. package/dist/payment-methods.js +175 -0
  218. package/dist/payment-methods.js.map +1 -0
  219. package/dist/payment-return-url.d.ts +53 -0
  220. package/dist/payment-return-url.d.ts.map +1 -0
  221. package/dist/payment-return-url.js +35 -0
  222. package/dist/payment-return-url.js.map +1 -0
  223. package/dist/payments.d.ts +386 -0
  224. package/dist/payments.d.ts.map +1 -0
  225. package/dist/payments.js +84 -0
  226. package/dist/payments.js.map +1 -0
  227. package/dist/pim-connector.d.ts +60 -0
  228. package/dist/pim-connector.d.ts.map +1 -0
  229. package/dist/pim-connector.js +43 -0
  230. package/dist/pim-connector.js.map +1 -0
  231. package/dist/pim-field-path.d.ts +6 -0
  232. package/dist/pim-field-path.d.ts.map +1 -0
  233. package/dist/pim-field-path.js +101 -0
  234. package/dist/pim-field-path.js.map +1 -0
  235. package/dist/platform-language.d.ts +20 -0
  236. package/dist/platform-language.d.ts.map +1 -0
  237. package/dist/platform-language.js +22 -0
  238. package/dist/platform-language.js.map +1 -0
  239. package/dist/price-lists.d.ts +685 -0
  240. package/dist/price-lists.d.ts.map +1 -0
  241. package/dist/price-lists.js +330 -0
  242. package/dist/price-lists.js.map +1 -0
  243. package/dist/product-feeds.d.ts +2837 -0
  244. package/dist/product-feeds.d.ts.map +1 -0
  245. package/dist/product-feeds.js +1504 -0
  246. package/dist/product-feeds.js.map +1 -0
  247. package/dist/product-scope-overrides.d.ts +134 -0
  248. package/dist/product-scope-overrides.d.ts.map +1 -0
  249. package/dist/product-scope-overrides.js +82 -0
  250. package/dist/product-scope-overrides.js.map +1 -0
  251. package/dist/product-value-resolver.d.ts +88 -0
  252. package/dist/product-value-resolver.d.ts.map +1 -0
  253. package/dist/product-value-resolver.js +128 -0
  254. package/dist/product-value-resolver.js.map +1 -0
  255. package/dist/promotions.d.ts +678 -0
  256. package/dist/promotions.d.ts.map +1 -0
  257. package/dist/promotions.js +479 -0
  258. package/dist/promotions.js.map +1 -0
  259. package/dist/prompt-actions.d.ts +582 -0
  260. package/dist/prompt-actions.d.ts.map +1 -0
  261. package/dist/prompt-actions.js +221 -0
  262. package/dist/prompt-actions.js.map +1 -0
  263. package/dist/pwa.d.ts +293 -0
  264. package/dist/pwa.d.ts.map +1 -0
  265. package/dist/pwa.js +204 -0
  266. package/dist/pwa.js.map +1 -0
  267. package/dist/quick-order.d.ts +340 -0
  268. package/dist/quick-order.d.ts.map +1 -0
  269. package/dist/quick-order.js +177 -0
  270. package/dist/quick-order.js.map +1 -0
  271. package/dist/quote-requests.d.ts +538 -0
  272. package/dist/quote-requests.d.ts.map +1 -0
  273. package/dist/quote-requests.js +308 -0
  274. package/dist/quote-requests.js.map +1 -0
  275. package/dist/returns.d.ts +774 -0
  276. package/dist/returns.d.ts.map +1 -0
  277. package/dist/returns.js +389 -0
  278. package/dist/returns.js.map +1 -0
  279. package/dist/sales-channels.d.ts +392 -0
  280. package/dist/sales-channels.d.ts.map +1 -0
  281. package/dist/sales-channels.js +285 -0
  282. package/dist/sales-channels.js.map +1 -0
  283. package/dist/scope-notice.d.ts +60 -0
  284. package/dist/scope-notice.d.ts.map +1 -0
  285. package/dist/scope-notice.js +56 -0
  286. package/dist/scope-notice.js.map +1 -0
  287. package/dist/search.d.ts +321 -0
  288. package/dist/search.d.ts.map +1 -0
  289. package/dist/search.js +160 -0
  290. package/dist/search.js.map +1 -0
  291. package/dist/seo.d.ts +113 -0
  292. package/dist/seo.d.ts.map +1 -0
  293. package/dist/seo.js +63 -0
  294. package/dist/seo.js.map +1 -0
  295. package/dist/settings.d.ts +453 -0
  296. package/dist/settings.d.ts.map +1 -0
  297. package/dist/settings.js +337 -0
  298. package/dist/settings.js.map +1 -0
  299. package/dist/shipments.d.ts +140 -0
  300. package/dist/shipments.d.ts.map +1 -0
  301. package/dist/shipments.js +14 -0
  302. package/dist/shipments.js.map +1 -0
  303. package/dist/shipping-methods.d.ts +350 -0
  304. package/dist/shipping-methods.d.ts.map +1 -0
  305. package/dist/shipping-methods.js +99 -0
  306. package/dist/shipping-methods.js.map +1 -0
  307. package/dist/shopping-lists.d.ts +122 -0
  308. package/dist/shopping-lists.d.ts.map +1 -0
  309. package/dist/shopping-lists.js +92 -0
  310. package/dist/shopping-lists.js.map +1 -0
  311. package/dist/taxes.d.ts +106 -0
  312. package/dist/taxes.d.ts.map +1 -0
  313. package/dist/taxes.js +80 -0
  314. package/dist/taxes.js.map +1 -0
  315. package/dist/text-normalization.d.ts +199 -0
  316. package/dist/text-normalization.d.ts.map +1 -0
  317. package/dist/text-normalization.js +205 -0
  318. package/dist/text-normalization.js.map +1 -0
  319. package/dist/transactional-emails.d.ts +459 -0
  320. package/dist/transactional-emails.d.ts.map +1 -0
  321. package/dist/transactional-emails.js +212 -0
  322. package/dist/transactional-emails.js.map +1 -0
  323. package/dist/webhooks.d.ts +69 -0
  324. package/dist/webhooks.d.ts.map +1 -0
  325. package/dist/webhooks.js +53 -0
  326. package/dist/webhooks.js.map +1 -0
  327. package/package.json +46 -0
@@ -0,0 +1,243 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Admin module contracts (US4) — AdminUser, AdminRole, Impersonation,
4
+ * AuditLogEntry. Source of truth per Principle V.
5
+ *
6
+ * Permission strings are screaming-snake or `module:action` (e.g.
7
+ * `catalog:write`, `orders:read`, `customers:impersonate`). The matrix is
8
+ * stored on AdminRole as a JSONB array.
9
+ */
10
+ export declare const adminUserSchema: z.ZodObject<{
11
+ id: z.ZodString;
12
+ email: z.ZodString;
13
+ firstName: z.ZodString;
14
+ lastName: z.ZodString;
15
+ adminRoleId: z.ZodNullable<z.ZodString>;
16
+ twoFactorEnabled: z.ZodBoolean;
17
+ status: z.ZodEnum<{
18
+ active: "active";
19
+ inactive: "inactive";
20
+ }>;
21
+ lastLoginAt: z.ZodNullable<z.ZodString>;
22
+ createdAt: z.ZodString;
23
+ updatedAt: z.ZodString;
24
+ }, z.core.$strip>;
25
+ export type AdminUser = z.infer<typeof adminUserSchema>;
26
+ export declare const adminRoleSchema: z.ZodObject<{
27
+ id: z.ZodString;
28
+ code: z.ZodString;
29
+ name: z.ZodString;
30
+ permissions: z.ZodArray<z.ZodString>;
31
+ requiresTwoFactor: z.ZodBoolean;
32
+ createdAt: z.ZodString;
33
+ updatedAt: z.ZodString;
34
+ }, z.core.$strip>;
35
+ export type AdminRole = z.infer<typeof adminRoleSchema>;
36
+ export declare const adminLoginRequestSchema: z.ZodObject<{
37
+ email: z.ZodString;
38
+ password: z.ZodString;
39
+ }, z.core.$strip>;
40
+ export declare const impersonationRequestSchema: z.ZodObject<{
41
+ customerAccountId: z.ZodString;
42
+ reason: z.ZodOptional<z.ZodString>;
43
+ }, z.core.$strip>;
44
+ export type ImpersonationRequest = z.infer<typeof impersonationRequestSchema>;
45
+ export declare const impersonationStartResponseSchema: z.ZodObject<{
46
+ impersonationSessionId: z.ZodString;
47
+ impersonatedCustomerAccount: z.ZodObject<{
48
+ id: z.ZodString;
49
+ email: z.ZodString;
50
+ firstName: z.ZodString;
51
+ lastName: z.ZodString;
52
+ role: z.ZodEnum<{
53
+ organization_admin: "organization_admin";
54
+ regular_user: "regular_user";
55
+ }>;
56
+ }, z.core.$strip>;
57
+ }, z.core.$strip>;
58
+ export type ImpersonationStartResponse = z.infer<typeof impersonationStartResponseSchema>;
59
+ export declare const createAdminUserRequestSchema: z.ZodObject<{
60
+ email: z.ZodString;
61
+ password: z.ZodString;
62
+ firstName: z.ZodString;
63
+ lastName: z.ZodString;
64
+ adminRoleId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
65
+ }, z.core.$strip>;
66
+ export type CreateAdminUserRequest = z.infer<typeof createAdminUserRequestSchema>;
67
+ export declare const updateAdminUserRequestSchema: z.ZodObject<{
68
+ firstName: z.ZodOptional<z.ZodString>;
69
+ lastName: z.ZodOptional<z.ZodString>;
70
+ adminRoleId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
71
+ status: z.ZodOptional<z.ZodEnum<{
72
+ active: "active";
73
+ inactive: "inactive";
74
+ }>>;
75
+ }, z.core.$strict>;
76
+ export type UpdateAdminUserRequest = z.infer<typeof updateAdminUserRequestSchema>;
77
+ /**
78
+ * Self-update payload — every authenticated admin can edit their own
79
+ * first/last name and rotate their password without needing the
80
+ * `admin_users:manage` permission. Role and status are intentionally
81
+ * NOT exposed here.
82
+ */
83
+ export declare const updateAdminUserSelfRequestSchema: z.ZodObject<{
84
+ firstName: z.ZodOptional<z.ZodString>;
85
+ lastName: z.ZodOptional<z.ZodString>;
86
+ password: z.ZodOptional<z.ZodString>;
87
+ }, z.core.$strict>;
88
+ export type UpdateAdminUserSelfRequest = z.infer<typeof updateAdminUserSelfRequestSchema>;
89
+ /**
90
+ * Peer password reset (issue #252) — one operator sets another operator's
91
+ * password. Deliberately its own payload rather than a `password` field on
92
+ * `updateAdminUserRequestSchema`: setting a password is not an edit to a field
93
+ * alongside a name change. It has its own audit action and its own side effect
94
+ * (every session the target holds is revoked), and a request that renamed and
95
+ * reset in one call would have to answer for both.
96
+ *
97
+ * The bound matches `createAdminUserRequestSchema` — the same password, made
98
+ * by the same operator, on the same account.
99
+ */
100
+ export declare const resetAdminUserPasswordRequestSchema: z.ZodObject<{
101
+ password: z.ZodString;
102
+ }, z.core.$strict>;
103
+ export type ResetAdminUserPasswordRequest = z.infer<typeof resetAdminUserPasswordRequestSchema>;
104
+ export declare const upsertAdminRoleRequestSchema: z.ZodObject<{
105
+ code: z.ZodString;
106
+ name: z.ZodString;
107
+ permissions: z.ZodArray<z.ZodString>;
108
+ requiresTwoFactor: z.ZodOptional<z.ZodBoolean>;
109
+ }, z.core.$strip>;
110
+ export type UpsertAdminRoleRequest = z.infer<typeof upsertAdminRoleRequestSchema>;
111
+ /** Optional per-module permission declaration on `ModuleManifest.permissions`. */
112
+ export declare const modulePermissionDeclarationSchema: z.ZodObject<{
113
+ code: z.ZodString;
114
+ module: z.ZodOptional<z.ZodString>;
115
+ label: z.ZodString;
116
+ description: z.ZodOptional<z.ZodString>;
117
+ requires: z.ZodOptional<z.ZodArray<z.ZodString>>;
118
+ }, z.core.$strip>;
119
+ export type ModulePermissionDeclaration = z.infer<typeof modulePermissionDeclarationSchema>;
120
+ /**
121
+ * Row shape returned by `GET /admin/permissions`.
122
+ *
123
+ * `module` and `owners` are **not the same string**, and the whole of D-175's
124
+ * "make the ownership model visible" is that only the first used to be on the
125
+ * wire. `module` is a display grouping — `_lifecycle` files its codes under
126
+ * `module: 'module_lifecycle'`, which is no module id at all — while `owners`
127
+ * is the presence question: the modules whose effective state decides whether
128
+ * this row is offered. They differ whenever a code is shared, and a reader who
129
+ * takes `module` for the owner gets it wrong in exactly the way D-173 did.
130
+ */
131
+ export declare const permissionCatalogueEntrySchema: z.ZodObject<{
132
+ code: z.ZodString;
133
+ module: z.ZodString;
134
+ label: z.ZodString;
135
+ owners: z.ZodArray<z.ZodString>;
136
+ requires: z.ZodOptional<z.ZodArray<z.ZodString>>;
137
+ }, z.core.$strip>;
138
+ export type PermissionCatalogueEntry = z.infer<typeof permissionCatalogueEntrySchema>;
139
+ /**
140
+ * The codes a role holding `granted` is advised to add — D-175, feature 080
141
+ * T057.
142
+ *
143
+ * **Advisory, and it lives here so that there is one of it.** The role editor
144
+ * renders the shortfall and the permission inventory sweeps the declarations
145
+ * that produce it; D-175's second caution is precisely that the benchmark's
146
+ * per-module tests hand-assemble their own cross-module catalogue, so the answer
147
+ * is computed over the rows the platform already merged and nowhere else.
148
+ *
149
+ * Two narrowings, both of them the fail-safe direction:
150
+ *
151
+ * - a requirement naming a code **not among `catalogue`** is skipped. For the
152
+ * role editor that is a code with no checkbox — offering one an operator
153
+ * cannot tick is the single thing the panel must not do — and a requirement
154
+ * naming a code the *platform* does not know is a defect reported to its
155
+ * author by the inventory, not to the operator.
156
+ * - a `'*'` role holds everything, so it is advised nothing.
157
+ *
158
+ * Nothing here refuses anything: the caller renders a suggestion, and a role
159
+ * saved without it is saved.
160
+ */
161
+ export declare function missingPermissionRequirements(granted: Iterable<string>, catalogue: readonly PermissionCatalogueEntry[]): string[];
162
+ /**
163
+ * Canonical permission catalogue exposed by `GET /admin/permissions`.
164
+ * The matrix UI groups by `module`; the wildcard `*` is intentionally not
165
+ * in the catalogue (it's only granted to the bootstrap "platform_admin").
166
+ */
167
+ export declare const PERMISSION_CATALOGUE: readonly [{
168
+ readonly code: "catalog:read";
169
+ readonly module: "catalog";
170
+ readonly label: "View catalog";
171
+ }, {
172
+ readonly code: "catalog:write";
173
+ readonly module: "catalog";
174
+ readonly label: "Edit catalog";
175
+ }, {
176
+ readonly code: "orders:read";
177
+ readonly module: "orders";
178
+ readonly label: "View orders";
179
+ }, {
180
+ readonly code: "orders:write";
181
+ readonly module: "orders";
182
+ readonly label: "Edit orders / change status";
183
+ }, {
184
+ readonly code: "rfqs:handle";
185
+ readonly module: "quote_requests";
186
+ readonly label: "Handle quote requests";
187
+ }, {
188
+ readonly code: "customers:read";
189
+ readonly module: "customers";
190
+ readonly label: "View customers";
191
+ }, {
192
+ readonly code: "customers:impersonate";
193
+ readonly module: "customers";
194
+ readonly label: "Impersonate customers";
195
+ }, {
196
+ readonly code: "integrations:manage";
197
+ readonly module: "api_keys";
198
+ readonly label: "Manage API keys + webhooks";
199
+ }, {
200
+ readonly code: "audit_log:read";
201
+ readonly module: "audit_logs";
202
+ readonly label: "View audit log";
203
+ }, {
204
+ readonly code: "admin_users:manage";
205
+ readonly module: "admin_users";
206
+ readonly label: "Manage admin users + roles";
207
+ }, {
208
+ readonly code: "credit_limits:manage";
209
+ readonly module: "credit_limits";
210
+ readonly label: "Grant + adjust credit limits";
211
+ }, {
212
+ readonly code: "customers:manage";
213
+ readonly module: "customers";
214
+ readonly label: "Manage customer organizations";
215
+ }, {
216
+ readonly code: "organizations:rollup";
217
+ readonly module: "organizations";
218
+ readonly label: "Act across organization descendants";
219
+ }, {
220
+ readonly code: "blog.read";
221
+ readonly module: "blog";
222
+ readonly label: "View blog content";
223
+ }, {
224
+ readonly code: "blog.write";
225
+ readonly module: "blog";
226
+ readonly label: "Author + publish blog content";
227
+ }];
228
+ export declare const auditLogEntrySchema: z.ZodObject<{
229
+ id: z.ZodString;
230
+ actorAdminUserId: z.ZodNullable<z.ZodString>;
231
+ impersonatedCustomerAccountId: z.ZodNullable<z.ZodString>;
232
+ actedAt: z.ZodString;
233
+ action: z.ZodString;
234
+ objectType: z.ZodString;
235
+ objectId: z.ZodString;
236
+ stateBefore: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
237
+ stateAfter: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
238
+ ipAddress: z.ZodNullable<z.ZodString>;
239
+ userAgent: z.ZodNullable<z.ZodString>;
240
+ requestId: z.ZodNullable<z.ZodString>;
241
+ }, z.core.$strip>;
242
+ export type AuditLogEntry = z.infer<typeof auditLogEntrySchema>;
243
+ //# sourceMappingURL=admin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../src/admin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;;;GAOG;AAEH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;iBAW1B,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,eAAO,MAAM,eAAe;;;;;;;;iBAQ1B,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,eAAO,MAAM,uBAAuB;;;iBAGlC,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;iBAGrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,gCAAgC;;;;;;;;;;;;iBAS3C,CAAC;AACH,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAI1F,eAAO,MAAM,4BAA4B;;;;;;iBAMvC,CAAC;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAElF,eAAO,MAAM,4BAA4B;;;;;;;;kBAO9B,CAAC;AACZ,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAElF;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC;;;;kBAMlC,CAAC;AACZ,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAE1F;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mCAAmC;;kBAIrC,CAAC;AACZ,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,CAAC;AAIhG,eAAO,MAAM,4BAA4B;;;;;iBAKvC,CAAC;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAElF,kFAAkF;AAClF,eAAO,MAAM,iCAAiC;;;;;;iBAgC5C,CAAC;AACH,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC;AAE5F;;;;;;;;;;GAUG;AACH,eAAO,MAAM,8BAA8B;;;;;;iBAWzC,CAAC;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAEtF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,EACzB,SAAS,EAAE,SAAS,wBAAwB,EAAE,GAC7C,MAAM,EAAE,CAaV;AAED;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BvB,CAAC;AAIX,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;iBAa9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
package/dist/admin.js ADDED
@@ -0,0 +1,246 @@
1
+ import { z } from 'zod';
2
+ import { isoDateTimeSchema, uuidSchema } from './common.js';
3
+ /**
4
+ * Admin module contracts (US4) — AdminUser, AdminRole, Impersonation,
5
+ * AuditLogEntry. Source of truth per Principle V.
6
+ *
7
+ * Permission strings are screaming-snake or `module:action` (e.g.
8
+ * `catalog:write`, `orders:read`, `customers:impersonate`). The matrix is
9
+ * stored on AdminRole as a JSONB array.
10
+ */
11
+ export const adminUserSchema = z.object({
12
+ id: uuidSchema,
13
+ email: z.string().email(),
14
+ firstName: z.string(),
15
+ lastName: z.string(),
16
+ adminRoleId: uuidSchema.nullable(),
17
+ twoFactorEnabled: z.boolean(),
18
+ status: z.enum(['active', 'inactive']),
19
+ lastLoginAt: isoDateTimeSchema.nullable(),
20
+ createdAt: isoDateTimeSchema,
21
+ updatedAt: isoDateTimeSchema,
22
+ });
23
+ export const adminRoleSchema = z.object({
24
+ id: uuidSchema,
25
+ code: z.string(),
26
+ name: z.string(),
27
+ permissions: z.array(z.string()),
28
+ requiresTwoFactor: z.boolean(),
29
+ createdAt: isoDateTimeSchema,
30
+ updatedAt: isoDateTimeSchema,
31
+ });
32
+ export const adminLoginRequestSchema = z.object({
33
+ email: z.string().email(),
34
+ password: z.string(),
35
+ });
36
+ export const impersonationRequestSchema = z.object({
37
+ customerAccountId: uuidSchema,
38
+ reason: z.string().max(2000).optional(),
39
+ });
40
+ export const impersonationStartResponseSchema = z.object({
41
+ impersonationSessionId: uuidSchema,
42
+ impersonatedCustomerAccount: z.object({
43
+ id: uuidSchema,
44
+ email: z.string().email(),
45
+ firstName: z.string(),
46
+ lastName: z.string(),
47
+ role: z.enum(['organization_admin', 'regular_user']),
48
+ }),
49
+ });
50
+ // --- Admin user CRUD --------------------------------------------------------
51
+ export const createAdminUserRequestSchema = z.object({
52
+ email: z.string().email(),
53
+ password: z.string().min(12).max(256),
54
+ firstName: z.string().min(1).max(120),
55
+ lastName: z.string().min(1).max(120),
56
+ adminRoleId: uuidSchema.nullable().optional(),
57
+ });
58
+ export const updateAdminUserRequestSchema = z
59
+ .object({
60
+ firstName: z.string().min(1).max(120).optional(),
61
+ lastName: z.string().min(1).max(120).optional(),
62
+ adminRoleId: uuidSchema.nullable().optional(),
63
+ status: z.enum(['active', 'inactive']).optional(),
64
+ })
65
+ .strict();
66
+ /**
67
+ * Self-update payload — every authenticated admin can edit their own
68
+ * first/last name and rotate their password without needing the
69
+ * `admin_users:manage` permission. Role and status are intentionally
70
+ * NOT exposed here.
71
+ */
72
+ export const updateAdminUserSelfRequestSchema = z
73
+ .object({
74
+ firstName: z.string().min(1).max(120).optional(),
75
+ lastName: z.string().min(1).max(120).optional(),
76
+ password: z.string().min(12).max(120).optional(),
77
+ })
78
+ .strict();
79
+ /**
80
+ * Peer password reset (issue #252) — one operator sets another operator's
81
+ * password. Deliberately its own payload rather than a `password` field on
82
+ * `updateAdminUserRequestSchema`: setting a password is not an edit to a field
83
+ * alongside a name change. It has its own audit action and its own side effect
84
+ * (every session the target holds is revoked), and a request that renamed and
85
+ * reset in one call would have to answer for both.
86
+ *
87
+ * The bound matches `createAdminUserRequestSchema` — the same password, made
88
+ * by the same operator, on the same account.
89
+ */
90
+ export const resetAdminUserPasswordRequestSchema = z
91
+ .object({
92
+ password: z.string().min(12).max(256),
93
+ })
94
+ .strict();
95
+ // --- Admin role CRUD --------------------------------------------------------
96
+ export const upsertAdminRoleRequestSchema = z.object({
97
+ code: z.string().min(1).max(64),
98
+ name: z.string().min(1).max(160),
99
+ permissions: z.array(z.string().min(1).max(120)),
100
+ requiresTwoFactor: z.boolean().optional(),
101
+ });
102
+ /** Optional per-module permission declaration on `ModuleManifest.permissions`. */
103
+ export const modulePermissionDeclarationSchema = z.object({
104
+ code: z.string().min(1).max(120),
105
+ module: z.string().min(1).max(64).optional(),
106
+ label: z.string().min(1).max(160),
107
+ description: z.string().max(500).optional(),
108
+ /**
109
+ * Other codes a role holding this one needs before the surface it opens is
110
+ * whole — D-175, feature 080 T057.
111
+ *
112
+ * **It is advisory and costs nothing at runtime.** No guard reads it, no
113
+ * upsert is refused for a missing requirement, and it does not put the named
114
+ * code's owner in this module's `dependencies`: a lifecycle edge would make
115
+ * the orchestrator refuse to switch that owner off, which is D-173's inverted
116
+ * Principle XVII and the repair to reach for last. What it does is put the
117
+ * sentence an operator needs where the operator can read it — the role editor
118
+ * says *"this role grants `rfqs:handle`, which also needs `price_lists:read`"*
119
+ * with a one-click add.
120
+ *
121
+ * **Do not write a fact the platform already derives here.** The edge this
122
+ * field carries is *"a role holding A but not B gets an incomplete screen"*,
123
+ * and nothing in this repository can decide it: the coupling runs from an
124
+ * admin screen's own fetches to another module's route, and whether the
125
+ * degradation is a defect or an accepted fallback is a judgement. A module
126
+ * enforcing a code another module owns is a **different** fact, it *is*
127
+ * derived — `test/helpers/foreign-gates.ts`, D-173 — and declaring that one
128
+ * here would be two answers to one question waiting to disagree.
129
+ *
130
+ * A code more than one module declares takes the **union** of its declarers'
131
+ * requirements: a shared code opens more than one surface, each with its own
132
+ * needs, and advising more is the direction that cannot strand anybody.
133
+ */
134
+ requires: z.array(z.string().min(1).max(120)).optional(),
135
+ });
136
+ /**
137
+ * Row shape returned by `GET /admin/permissions`.
138
+ *
139
+ * `module` and `owners` are **not the same string**, and the whole of D-175's
140
+ * "make the ownership model visible" is that only the first used to be on the
141
+ * wire. `module` is a display grouping — `_lifecycle` files its codes under
142
+ * `module: 'module_lifecycle'`, which is no module id at all — while `owners`
143
+ * is the presence question: the modules whose effective state decides whether
144
+ * this row is offered. They differ whenever a code is shared, and a reader who
145
+ * takes `module` for the owner gets it wrong in exactly the way D-173 did.
146
+ */
147
+ export const permissionCatalogueEntrySchema = z.object({
148
+ code: z.string().min(1).max(120),
149
+ module: z.string().min(1).max(64),
150
+ label: z.string().min(1).max(160),
151
+ /**
152
+ * The modules whose presence keeps this code grantable — a set, because a
153
+ * shared code survives while **any** of its owners is present.
154
+ */
155
+ owners: z.array(z.string().min(1).max(64)).min(1),
156
+ /** {@link modulePermissionDeclarationSchema}'s `requires`, merged. */
157
+ requires: z.array(z.string().min(1).max(120)).optional(),
158
+ });
159
+ /**
160
+ * The codes a role holding `granted` is advised to add — D-175, feature 080
161
+ * T057.
162
+ *
163
+ * **Advisory, and it lives here so that there is one of it.** The role editor
164
+ * renders the shortfall and the permission inventory sweeps the declarations
165
+ * that produce it; D-175's second caution is precisely that the benchmark's
166
+ * per-module tests hand-assemble their own cross-module catalogue, so the answer
167
+ * is computed over the rows the platform already merged and nowhere else.
168
+ *
169
+ * Two narrowings, both of them the fail-safe direction:
170
+ *
171
+ * - a requirement naming a code **not among `catalogue`** is skipped. For the
172
+ * role editor that is a code with no checkbox — offering one an operator
173
+ * cannot tick is the single thing the panel must not do — and a requirement
174
+ * naming a code the *platform* does not know is a defect reported to its
175
+ * author by the inventory, not to the operator.
176
+ * - a `'*'` role holds everything, so it is advised nothing.
177
+ *
178
+ * Nothing here refuses anything: the caller renders a suggestion, and a role
179
+ * saved without it is saved.
180
+ */
181
+ export function missingPermissionRequirements(granted, catalogue) {
182
+ const held = new Set(granted);
183
+ if (held.has('*'))
184
+ return [];
185
+ const offered = new Set(catalogue.map((row) => row.code));
186
+ const missing = new Set();
187
+ for (const row of catalogue) {
188
+ if (!held.has(row.code))
189
+ continue;
190
+ for (const requirement of row.requires ?? []) {
191
+ if (held.has(requirement) || !offered.has(requirement))
192
+ continue;
193
+ missing.add(requirement);
194
+ }
195
+ }
196
+ return [...missing].sort();
197
+ }
198
+ /**
199
+ * Canonical permission catalogue exposed by `GET /admin/permissions`.
200
+ * The matrix UI groups by `module`; the wildcard `*` is intentionally not
201
+ * in the catalogue (it's only granted to the bootstrap "platform_admin").
202
+ */
203
+ export const PERMISSION_CATALOGUE = [
204
+ { code: 'catalog:read', module: 'catalog', label: 'View catalog' },
205
+ { code: 'catalog:write', module: 'catalog', label: 'Edit catalog' },
206
+ { code: 'orders:read', module: 'orders', label: 'View orders' },
207
+ { code: 'orders:write', module: 'orders', label: 'Edit orders / change status' },
208
+ { code: 'rfqs:handle', module: 'quote_requests', label: 'Handle quote requests' },
209
+ { code: 'customers:read', module: 'customers', label: 'View customers' },
210
+ { code: 'customers:impersonate', module: 'customers', label: 'Impersonate customers' },
211
+ // Shared gate for the API-keys and webhooks admin surfaces. The name predates
212
+ // the removal of the `integrations` module; renaming it would need a data
213
+ // migration on every admin role's permission list.
214
+ { code: 'integrations:manage', module: 'api_keys', label: 'Manage API keys + webhooks' },
215
+ // Feature 072, T017 — the module id is `audit_logs`. It said `audit_log`,
216
+ // which matches no module, so the role matrix grouped this permission under a
217
+ // phantom module. The CODE keeps its historical spelling: it is persisted in
218
+ // every admin role's permission list and renaming it would need a data migration.
219
+ { code: 'audit_log:read', module: 'audit_logs', label: 'View audit log' },
220
+ { code: 'admin_users:manage', module: 'admin_users', label: 'Manage admin users + roles' },
221
+ { code: 'credit_limits:manage', module: 'credit_limits', label: 'Grant + adjust credit limits' },
222
+ { code: 'customers:manage', module: 'customers', label: 'Manage customer organizations' },
223
+ {
224
+ code: 'organizations:rollup',
225
+ module: 'organizations',
226
+ label: 'Act across organization descendants',
227
+ },
228
+ { code: 'blog.read', module: 'blog', label: 'View blog content' },
229
+ { code: 'blog.write', module: 'blog', label: 'Author + publish blog content' },
230
+ ];
231
+ // --- Audit log --------------------------------------------------------------
232
+ export const auditLogEntrySchema = z.object({
233
+ id: uuidSchema,
234
+ actorAdminUserId: uuidSchema.nullable(),
235
+ impersonatedCustomerAccountId: uuidSchema.nullable(),
236
+ actedAt: isoDateTimeSchema,
237
+ action: z.string(),
238
+ objectType: z.string(),
239
+ objectId: z.string(),
240
+ stateBefore: z.record(z.string(), z.unknown()).nullable(),
241
+ stateAfter: z.record(z.string(), z.unknown()).nullable(),
242
+ ipAddress: z.string().nullable(),
243
+ userAgent: z.string().nullable(),
244
+ requestId: z.string().nullable(),
245
+ });
246
+ //# sourceMappingURL=admin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin.js","sourceRoot":"","sources":["../src/admin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,123 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Analytics event contracts (US10 / FR-110, FR-111).
4
+ *
5
+ * Storefront and admin emit a small, fixed set of event types into the
6
+ * platform; backend persists them and exposes aggregated read paths for the
7
+ * admin dashboard. Forwarding to an external analytics tool (e.g. GA4) is
8
+ * a separate config-flagged path that consumes the same events.
9
+ */
10
+ export declare const analyticsEventTypeSchema: z.ZodEnum<{
11
+ "product.viewed": "product.viewed";
12
+ "product.added_to_cart": "product.added_to_cart";
13
+ "cart.abandoned": "cart.abandoned";
14
+ "order.placed": "order.placed";
15
+ "search.performed": "search.performed";
16
+ "filter.clicked": "filter.clicked";
17
+ "category.viewed": "category.viewed";
18
+ }>;
19
+ export type AnalyticsEventType = z.infer<typeof analyticsEventTypeSchema>;
20
+ /**
21
+ * A single inbound analytics event. The shape is intentionally permissive
22
+ * inside `properties` — the storefront chooses what to send per event type.
23
+ */
24
+ export declare const ingestAnalyticsEventSchema: z.ZodObject<{
25
+ type: z.ZodEnum<{
26
+ "product.viewed": "product.viewed";
27
+ "product.added_to_cart": "product.added_to_cart";
28
+ "cart.abandoned": "cart.abandoned";
29
+ "order.placed": "order.placed";
30
+ "search.performed": "search.performed";
31
+ "filter.clicked": "filter.clicked";
32
+ "category.viewed": "category.viewed";
33
+ }>;
34
+ occurredAt: z.ZodOptional<z.ZodString>;
35
+ salesChannelId: z.ZodOptional<z.ZodString>;
36
+ customerAccountId: z.ZodOptional<z.ZodString>;
37
+ organizationId: z.ZodOptional<z.ZodString>;
38
+ sessionId: z.ZodOptional<z.ZodString>;
39
+ properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
40
+ }, z.core.$strip>;
41
+ export type IngestAnalyticsEvent = z.infer<typeof ingestAnalyticsEventSchema>;
42
+ /**
43
+ * Storefront sends events in batches to amortise HTTP overhead.
44
+ */
45
+ export declare const ingestAnalyticsBatchRequestSchema: z.ZodObject<{
46
+ events: z.ZodArray<z.ZodObject<{
47
+ type: z.ZodEnum<{
48
+ "product.viewed": "product.viewed";
49
+ "product.added_to_cart": "product.added_to_cart";
50
+ "cart.abandoned": "cart.abandoned";
51
+ "order.placed": "order.placed";
52
+ "search.performed": "search.performed";
53
+ "filter.clicked": "filter.clicked";
54
+ "category.viewed": "category.viewed";
55
+ }>;
56
+ occurredAt: z.ZodOptional<z.ZodString>;
57
+ salesChannelId: z.ZodOptional<z.ZodString>;
58
+ customerAccountId: z.ZodOptional<z.ZodString>;
59
+ organizationId: z.ZodOptional<z.ZodString>;
60
+ sessionId: z.ZodOptional<z.ZodString>;
61
+ properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
62
+ }, z.core.$strip>>;
63
+ }, z.core.$strip>;
64
+ export type IngestAnalyticsBatchRequest = z.infer<typeof ingestAnalyticsBatchRequestSchema>;
65
+ export declare const ingestAnalyticsBatchResponseSchema: z.ZodObject<{
66
+ accepted: z.ZodNumber;
67
+ rejected: z.ZodDefault<z.ZodArray<z.ZodObject<{
68
+ index: z.ZodNumber;
69
+ reason: z.ZodString;
70
+ }, z.core.$strip>>>;
71
+ }, z.core.$strip>;
72
+ export type IngestAnalyticsBatchResponse = z.infer<typeof ingestAnalyticsBatchResponseSchema>;
73
+ /**
74
+ * Admin aggregation read paths.
75
+ */
76
+ export declare const analyticsSummaryQuerySchema: z.ZodObject<{
77
+ from: z.ZodString;
78
+ to: z.ZodString;
79
+ salesChannelId: z.ZodOptional<z.ZodString>;
80
+ }, z.core.$strip>;
81
+ export type AnalyticsSummaryQuery = z.infer<typeof analyticsSummaryQuerySchema>;
82
+ export declare const analyticsDailyPointSchema: z.ZodObject<{
83
+ day: z.ZodString;
84
+ type: z.ZodEnum<{
85
+ "product.viewed": "product.viewed";
86
+ "product.added_to_cart": "product.added_to_cart";
87
+ "cart.abandoned": "cart.abandoned";
88
+ "order.placed": "order.placed";
89
+ "search.performed": "search.performed";
90
+ "filter.clicked": "filter.clicked";
91
+ "category.viewed": "category.viewed";
92
+ }>;
93
+ count: z.ZodNumber;
94
+ }, z.core.$strip>;
95
+ export declare const analyticsSummaryResponseSchema: z.ZodObject<{
96
+ totalsByType: z.ZodArray<z.ZodObject<{
97
+ type: z.ZodEnum<{
98
+ "product.viewed": "product.viewed";
99
+ "product.added_to_cart": "product.added_to_cart";
100
+ "cart.abandoned": "cart.abandoned";
101
+ "order.placed": "order.placed";
102
+ "search.performed": "search.performed";
103
+ "filter.clicked": "filter.clicked";
104
+ "category.viewed": "category.viewed";
105
+ }>;
106
+ count: z.ZodNumber;
107
+ }, z.core.$strip>>;
108
+ daily: z.ZodArray<z.ZodObject<{
109
+ day: z.ZodString;
110
+ type: z.ZodEnum<{
111
+ "product.viewed": "product.viewed";
112
+ "product.added_to_cart": "product.added_to_cart";
113
+ "cart.abandoned": "cart.abandoned";
114
+ "order.placed": "order.placed";
115
+ "search.performed": "search.performed";
116
+ "filter.clicked": "filter.clicked";
117
+ "category.viewed": "category.viewed";
118
+ }>;
119
+ count: z.ZodNumber;
120
+ }, z.core.$strip>>;
121
+ }, z.core.$strip>;
122
+ export type AnalyticsSummaryResponse = z.infer<typeof analyticsSummaryResponseSchema>;
123
+ //# sourceMappingURL=analytics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../src/analytics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;;;GAOG;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;EAQnC,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E;;;GAGG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;iBAQrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E;;GAEG;AACH,eAAO,MAAM,iCAAiC;;;;;;;;;;;;;;;;;;iBAE5C,CAAC;AACH,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC;AAE5F,eAAO,MAAM,kCAAkC;;;;;;iBAU7C,CAAC;AACH,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAE9F;;GAEG;AACH,eAAO,MAAM,2BAA2B;;;;iBAItC,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEhF,eAAO,MAAM,yBAAyB;;;;;;;;;;;;iBAIpC,CAAC;AAEH,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;iBAQzC,CAAC;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC"}