@porulle/core 0.6.0 → 0.8.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 (301) hide show
  1. package/dist/auth/setup.d.ts.map +1 -1
  2. package/dist/auth/setup.js +1 -0
  3. package/dist/config/defaults.d.ts.map +1 -1
  4. package/dist/config/defaults.js +5 -0
  5. package/dist/config/types.d.ts +17 -1
  6. package/dist/config/types.d.ts.map +1 -1
  7. package/dist/generated/plugin-manifest.d.ts +3 -0
  8. package/dist/generated/plugin-manifest.d.ts.map +1 -1
  9. package/dist/generated/plugin-manifest.js +1 -0
  10. package/dist/hooks/checkout.d.ts.map +1 -1
  11. package/dist/hooks/checkout.js +16 -1
  12. package/dist/index.d.ts +1 -0
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +1 -0
  15. package/dist/interfaces/rest/index.d.ts.map +1 -1
  16. package/dist/interfaces/rest/index.js +12 -0
  17. package/dist/interfaces/rest/routes/admin/staff.d.ts +12 -0
  18. package/dist/interfaces/rest/routes/admin/staff.d.ts.map +1 -0
  19. package/dist/interfaces/rest/routes/admin/staff.js +172 -0
  20. package/dist/interfaces/rest/routes/analytics.d.ts +5 -0
  21. package/dist/interfaces/rest/routes/analytics.d.ts.map +1 -0
  22. package/dist/interfaces/rest/routes/analytics.js +24 -0
  23. package/dist/interfaces/rest/routes/carts.d.ts.map +1 -1
  24. package/dist/interfaces/rest/routes/carts.js +39 -2
  25. package/dist/interfaces/rest/routes/catalog.d.ts.map +1 -1
  26. package/dist/interfaces/rest/routes/catalog.js +17 -1
  27. package/dist/interfaces/rest/routes/checkout.d.ts.map +1 -1
  28. package/dist/interfaces/rest/routes/checkout.js +17 -0
  29. package/dist/interfaces/rest/routes/documents.d.ts +10 -0
  30. package/dist/interfaces/rest/routes/documents.d.ts.map +1 -0
  31. package/dist/interfaces/rest/routes/documents.js +40 -0
  32. package/dist/interfaces/rest/routes/orders.d.ts.map +1 -1
  33. package/dist/interfaces/rest/routes/orders.js +122 -1
  34. package/dist/interfaces/rest/routes/pricing.d.ts.map +1 -1
  35. package/dist/interfaces/rest/routes/pricing.js +36 -1
  36. package/dist/interfaces/rest/routes/settings.d.ts +5 -0
  37. package/dist/interfaces/rest/routes/settings.d.ts.map +1 -0
  38. package/dist/interfaces/rest/routes/settings.js +50 -0
  39. package/dist/interfaces/rest/routes/shipping.d.ts +5 -0
  40. package/dist/interfaces/rest/routes/shipping.d.ts.map +1 -0
  41. package/dist/interfaces/rest/routes/shipping.js +68 -0
  42. package/dist/interfaces/rest/routes/tax.d.ts +5 -0
  43. package/dist/interfaces/rest/routes/tax.d.ts.map +1 -0
  44. package/dist/interfaces/rest/routes/tax.js +68 -0
  45. package/dist/interfaces/rest/schemas/admin-staff.d.ts +899 -0
  46. package/dist/interfaces/rest/schemas/admin-staff.d.ts.map +1 -0
  47. package/dist/interfaces/rest/schemas/admin-staff.js +98 -0
  48. package/dist/interfaces/rest/schemas/analytics.d.ts +252 -0
  49. package/dist/interfaces/rest/schemas/analytics.d.ts.map +1 -0
  50. package/dist/interfaces/rest/schemas/analytics.js +33 -0
  51. package/dist/interfaces/rest/schemas/carts.d.ts +656 -0
  52. package/dist/interfaces/rest/schemas/carts.d.ts.map +1 -1
  53. package/dist/interfaces/rest/schemas/carts.js +38 -0
  54. package/dist/interfaces/rest/schemas/catalog.d.ts +1230 -2
  55. package/dist/interfaces/rest/schemas/catalog.d.ts.map +1 -1
  56. package/dist/interfaces/rest/schemas/catalog.js +48 -0
  57. package/dist/interfaces/rest/schemas/checkout.d.ts +2 -0
  58. package/dist/interfaces/rest/schemas/checkout.d.ts.map +1 -1
  59. package/dist/interfaces/rest/schemas/checkout.js +4 -0
  60. package/dist/interfaces/rest/schemas/customer-portal.d.ts +35 -0
  61. package/dist/interfaces/rest/schemas/customer-portal.d.ts.map +1 -1
  62. package/dist/interfaces/rest/schemas/documents.d.ts +509 -0
  63. package/dist/interfaces/rest/schemas/documents.d.ts.map +1 -0
  64. package/dist/interfaces/rest/schemas/documents.js +65 -0
  65. package/dist/interfaces/rest/schemas/orders.d.ts +4467 -7
  66. package/dist/interfaces/rest/schemas/orders.d.ts.map +1 -1
  67. package/dist/interfaces/rest/schemas/orders.js +330 -0
  68. package/dist/interfaces/rest/schemas/pricing.d.ts +405 -0
  69. package/dist/interfaces/rest/schemas/pricing.d.ts.map +1 -1
  70. package/dist/interfaces/rest/schemas/pricing.js +70 -0
  71. package/dist/interfaces/rest/schemas/responses.d.ts +156 -0
  72. package/dist/interfaces/rest/schemas/responses.d.ts.map +1 -1
  73. package/dist/interfaces/rest/schemas/search.d.ts +17 -0
  74. package/dist/interfaces/rest/schemas/search.d.ts.map +1 -1
  75. package/dist/interfaces/rest/schemas/settings.d.ts +397 -0
  76. package/dist/interfaces/rest/schemas/settings.d.ts.map +1 -0
  77. package/dist/interfaces/rest/schemas/settings.js +79 -0
  78. package/dist/interfaces/rest/schemas/shipping.d.ts +1093 -0
  79. package/dist/interfaces/rest/schemas/shipping.d.ts.map +1 -0
  80. package/dist/interfaces/rest/schemas/shipping.js +146 -0
  81. package/dist/interfaces/rest/schemas/tax.d.ts +1074 -0
  82. package/dist/interfaces/rest/schemas/tax.d.ts.map +1 -0
  83. package/dist/interfaces/rest/schemas/tax.js +132 -0
  84. package/dist/kernel/database/schema.d.ts +4 -0
  85. package/dist/kernel/database/schema.d.ts.map +1 -1
  86. package/dist/kernel/database/schema.js +8 -0
  87. package/dist/kernel/error-mapper.d.ts.map +1 -1
  88. package/dist/kernel/error-mapper.js +1 -0
  89. package/dist/kernel/errors.d.ts +5 -0
  90. package/dist/kernel/errors.d.ts.map +1 -1
  91. package/dist/kernel/errors.js +9 -0
  92. package/dist/kernel/hooks/types.d.ts +1 -1
  93. package/dist/kernel/hooks/types.d.ts.map +1 -1
  94. package/dist/kernel/plugin/manifest.d.ts +23 -0
  95. package/dist/kernel/plugin/manifest.d.ts.map +1 -1
  96. package/dist/kernel/plugin/manifest.js +17 -2
  97. package/dist/modules/analytics/module.d.ts.map +1 -1
  98. package/dist/modules/analytics/module.js +6 -0
  99. package/dist/modules/analytics/reports.d.ts +58 -0
  100. package/dist/modules/analytics/reports.d.ts.map +1 -0
  101. package/dist/modules/analytics/reports.js +249 -0
  102. package/dist/modules/analytics/service.d.ts +10 -0
  103. package/dist/modules/analytics/service.d.ts.map +1 -1
  104. package/dist/modules/analytics/service.js +14 -0
  105. package/dist/modules/cart/repository/index.d.ts +7 -0
  106. package/dist/modules/cart/repository/index.d.ts.map +1 -1
  107. package/dist/modules/cart/repository/index.js +25 -1
  108. package/dist/modules/cart/schema.d.ts +17 -0
  109. package/dist/modules/cart/schema.d.ts.map +1 -1
  110. package/dist/modules/cart/schema.js +2 -0
  111. package/dist/modules/cart/schemas.d.ts +1 -0
  112. package/dist/modules/cart/schemas.d.ts.map +1 -1
  113. package/dist/modules/cart/schemas.js +1 -0
  114. package/dist/modules/cart/service.d.ts +32 -0
  115. package/dist/modules/cart/service.d.ts.map +1 -1
  116. package/dist/modules/cart/service.js +58 -0
  117. package/dist/modules/catalog/entity-service.d.ts +21 -0
  118. package/dist/modules/catalog/entity-service.d.ts.map +1 -1
  119. package/dist/modules/catalog/entity-service.js +151 -6
  120. package/dist/modules/catalog/schema.d.ts +34 -0
  121. package/dist/modules/catalog/schema.d.ts.map +1 -1
  122. package/dist/modules/catalog/schema.js +5 -0
  123. package/dist/modules/catalog/schemas.d.ts +15 -1
  124. package/dist/modules/catalog/schemas.d.ts.map +1 -1
  125. package/dist/modules/catalog/schemas.js +17 -1
  126. package/dist/modules/catalog/service.d.ts +43 -1
  127. package/dist/modules/catalog/service.d.ts.map +1 -1
  128. package/dist/modules/catalog/service.js +6 -0
  129. package/dist/modules/documents/module.d.ts +7 -0
  130. package/dist/modules/documents/module.d.ts.map +1 -0
  131. package/dist/modules/documents/module.js +12 -0
  132. package/dist/modules/documents/pdf.d.ts +25 -0
  133. package/dist/modules/documents/pdf.d.ts.map +1 -0
  134. package/dist/modules/documents/pdf.js +80 -0
  135. package/dist/modules/documents/render.d.ts +32 -0
  136. package/dist/modules/documents/render.d.ts.map +1 -0
  137. package/dist/modules/documents/render.js +190 -0
  138. package/dist/modules/documents/repository/index.d.ts +25 -0
  139. package/dist/modules/documents/repository/index.d.ts.map +1 -0
  140. package/dist/modules/documents/repository/index.js +47 -0
  141. package/dist/modules/documents/schema.d.ts +214 -0
  142. package/dist/modules/documents/schema.d.ts.map +1 -0
  143. package/dist/modules/documents/schema.js +42 -0
  144. package/dist/modules/documents/service.d.ts +51 -0
  145. package/dist/modules/documents/service.d.ts.map +1 -0
  146. package/dist/modules/documents/service.js +119 -0
  147. package/dist/modules/fulfillment/service.d.ts +18 -0
  148. package/dist/modules/fulfillment/service.d.ts.map +1 -1
  149. package/dist/modules/fulfillment/service.js +85 -1
  150. package/dist/modules/media/service.d.ts +18 -0
  151. package/dist/modules/media/service.d.ts.map +1 -1
  152. package/dist/modules/media/service.js +26 -0
  153. package/dist/modules/orders/repository/index.d.ts +18 -1
  154. package/dist/modules/orders/repository/index.d.ts.map +1 -1
  155. package/dist/modules/orders/repository/index.js +86 -1
  156. package/dist/modules/orders/schema.d.ts +374 -0
  157. package/dist/modules/orders/schema.d.ts.map +1 -1
  158. package/dist/modules/orders/schema.js +52 -1
  159. package/dist/modules/orders/service.d.ts +102 -2
  160. package/dist/modules/orders/service.d.ts.map +1 -1
  161. package/dist/modules/orders/service.js +494 -23
  162. package/dist/modules/pricing/repository/index.d.ts +5 -0
  163. package/dist/modules/pricing/repository/index.d.ts.map +1 -1
  164. package/dist/modules/pricing/repository/index.js +19 -0
  165. package/dist/modules/pricing/service.d.ts +18 -0
  166. package/dist/modules/pricing/service.d.ts.map +1 -1
  167. package/dist/modules/pricing/service.js +57 -1
  168. package/dist/modules/settings/module.d.ts +6 -0
  169. package/dist/modules/settings/module.d.ts.map +1 -0
  170. package/dist/modules/settings/module.js +11 -0
  171. package/dist/modules/settings/repository/index.d.ts +16 -0
  172. package/dist/modules/settings/repository/index.d.ts.map +1 -0
  173. package/dist/modules/settings/repository/index.js +41 -0
  174. package/dist/modules/settings/schema.d.ts +121 -0
  175. package/dist/modules/settings/schema.d.ts.map +1 -0
  176. package/dist/modules/settings/schema.js +24 -0
  177. package/dist/modules/settings/service.d.ts +26 -0
  178. package/dist/modules/settings/service.d.ts.map +1 -0
  179. package/dist/modules/settings/service.js +51 -0
  180. package/dist/modules/shipping/calculator.d.ts +5 -0
  181. package/dist/modules/shipping/calculator.d.ts.map +1 -1
  182. package/dist/modules/shipping/calculator.js +10 -0
  183. package/dist/modules/shipping/module.d.ts +5 -1
  184. package/dist/modules/shipping/module.d.ts.map +1 -1
  185. package/dist/modules/shipping/module.js +4 -1
  186. package/dist/modules/shipping/repository/index.d.ts +27 -2
  187. package/dist/modules/shipping/repository/index.d.ts.map +1 -1
  188. package/dist/modules/shipping/repository/index.js +105 -1
  189. package/dist/modules/shipping/schema.d.ts +419 -0
  190. package/dist/modules/shipping/schema.d.ts.map +1 -0
  191. package/dist/modules/shipping/schema.js +56 -0
  192. package/dist/modules/shipping/service.d.ts +54 -0
  193. package/dist/modules/shipping/service.d.ts.map +1 -1
  194. package/dist/modules/shipping/service.js +161 -2
  195. package/dist/modules/tax/adapter.d.ts +13 -0
  196. package/dist/modules/tax/adapter.d.ts.map +1 -1
  197. package/dist/modules/tax/module.d.ts +5 -1
  198. package/dist/modules/tax/module.d.ts.map +1 -1
  199. package/dist/modules/tax/module.js +4 -1
  200. package/dist/modules/tax/repository/index.d.ts +38 -2
  201. package/dist/modules/tax/repository/index.d.ts.map +1 -1
  202. package/dist/modules/tax/repository/index.js +138 -1
  203. package/dist/modules/tax/schema.d.ts +355 -0
  204. package/dist/modules/tax/schema.d.ts.map +1 -0
  205. package/dist/modules/tax/schema.js +55 -0
  206. package/dist/modules/tax/service.d.ts +60 -1
  207. package/dist/modules/tax/service.d.ts.map +1 -1
  208. package/dist/modules/tax/service.js +227 -2
  209. package/dist/runtime/kernel-modules.d.ts +15 -2
  210. package/dist/runtime/kernel-modules.d.ts.map +1 -1
  211. package/dist/runtime/kernel-modules.js +4 -0
  212. package/dist/runtime/kernel-types.d.ts +5 -1
  213. package/dist/runtime/kernel-types.d.ts.map +1 -1
  214. package/dist/runtime/kernel-types.js +2 -0
  215. package/dist/runtime/server.d.ts.map +1 -1
  216. package/dist/runtime/server.js +35 -3
  217. package/dist/test-utils/create-plugin-test-app.d.ts +3 -0
  218. package/dist/test-utils/create-plugin-test-app.d.ts.map +1 -1
  219. package/dist/test-utils/create-plugin-test-app.js +15 -3
  220. package/dist/test-utils/rest-api-test-utils.d.ts.map +1 -1
  221. package/dist/test-utils/rest-api-test-utils.js +6 -0
  222. package/package.json +3 -3
  223. package/src/auth/setup.ts +1 -0
  224. package/src/config/defaults.ts +5 -0
  225. package/src/config/types.ts +17 -1
  226. package/src/generated/plugin-capabilities.d.ts +1 -0
  227. package/src/generated/plugin-manifest.ts +1 -0
  228. package/src/generated/plugin-repositories.d.ts +1 -0
  229. package/src/hooks/checkout.ts +25 -3
  230. package/src/index.ts +1 -0
  231. package/src/interfaces/rest/index.ts +12 -0
  232. package/src/interfaces/rest/routes/admin/staff.ts +218 -0
  233. package/src/interfaces/rest/routes/analytics.ts +33 -0
  234. package/src/interfaces/rest/routes/carts.ts +52 -2
  235. package/src/interfaces/rest/routes/catalog.ts +34 -0
  236. package/src/interfaces/rest/routes/checkout.ts +22 -0
  237. package/src/interfaces/rest/routes/documents.ts +61 -0
  238. package/src/interfaces/rest/routes/orders.ts +172 -1
  239. package/src/interfaces/rest/routes/pricing.ts +44 -1
  240. package/src/interfaces/rest/routes/settings.ts +61 -0
  241. package/src/interfaces/rest/routes/shipping.ts +92 -0
  242. package/src/interfaces/rest/routes/tax.ts +90 -0
  243. package/src/interfaces/rest/schemas/admin-staff.ts +110 -0
  244. package/src/interfaces/rest/schemas/analytics.ts +39 -0
  245. package/src/interfaces/rest/schemas/carts.ts +40 -0
  246. package/src/interfaces/rest/schemas/catalog.ts +53 -0
  247. package/src/interfaces/rest/schemas/checkout.ts +4 -0
  248. package/src/interfaces/rest/schemas/documents.ts +72 -0
  249. package/src/interfaces/rest/schemas/orders.ts +361 -0
  250. package/src/interfaces/rest/schemas/pricing.ts +75 -0
  251. package/src/interfaces/rest/schemas/settings.ts +93 -0
  252. package/src/interfaces/rest/schemas/shipping.ts +164 -0
  253. package/src/interfaces/rest/schemas/tax.ts +148 -0
  254. package/src/kernel/database/schema.ts +12 -0
  255. package/src/kernel/error-mapper.ts +1 -0
  256. package/src/kernel/errors.ts +11 -0
  257. package/src/kernel/hooks/types.ts +1 -0
  258. package/src/kernel/plugin/manifest.ts +38 -2
  259. package/src/modules/analytics/module.ts +10 -0
  260. package/src/modules/analytics/reports.ts +311 -0
  261. package/src/modules/analytics/service.ts +23 -0
  262. package/src/modules/cart/repository/index.ts +30 -1
  263. package/src/modules/cart/schema.ts +2 -0
  264. package/src/modules/cart/schemas.ts +1 -0
  265. package/src/modules/cart/service.ts +101 -0
  266. package/src/modules/catalog/entity-service.ts +195 -6
  267. package/src/modules/catalog/schema.ts +5 -0
  268. package/src/modules/catalog/schemas.ts +18 -1
  269. package/src/modules/catalog/service.ts +32 -2
  270. package/src/modules/documents/module.ts +19 -0
  271. package/src/modules/documents/pdf.ts +101 -0
  272. package/src/modules/documents/render.ts +231 -0
  273. package/src/modules/documents/repository/index.ts +68 -0
  274. package/src/modules/documents/schema.ts +44 -0
  275. package/src/modules/documents/service.ts +176 -0
  276. package/src/modules/fulfillment/service.ts +139 -1
  277. package/src/modules/media/service.ts +40 -0
  278. package/src/modules/orders/repository/index.ts +127 -1
  279. package/src/modules/orders/schema.ts +54 -1
  280. package/src/modules/orders/service.ts +739 -24
  281. package/src/modules/pricing/repository/index.ts +34 -0
  282. package/src/modules/pricing/service.ts +100 -1
  283. package/src/modules/settings/module.ts +18 -0
  284. package/src/modules/settings/repository/index.ts +59 -0
  285. package/src/modules/settings/schema.ts +25 -0
  286. package/src/modules/settings/service.ts +82 -0
  287. package/src/modules/shipping/calculator.ts +27 -0
  288. package/src/modules/shipping/module.ts +6 -2
  289. package/src/modules/shipping/repository/index.ts +136 -2
  290. package/src/modules/shipping/schema.ts +58 -0
  291. package/src/modules/shipping/service.ts +260 -1
  292. package/src/modules/tax/adapter.ts +9 -0
  293. package/src/modules/tax/module.ts +6 -2
  294. package/src/modules/tax/repository/index.ts +169 -2
  295. package/src/modules/tax/schema.ts +57 -0
  296. package/src/modules/tax/service.ts +313 -2
  297. package/src/runtime/kernel-modules.ts +4 -0
  298. package/src/runtime/kernel-types.ts +6 -0
  299. package/src/runtime/server.ts +36 -3
  300. package/src/test-utils/create-plugin-test-app.ts +17 -4
  301. package/src/test-utils/rest-api-test-utils.ts +6 -0
@@ -134,14 +134,17 @@ export class EntityService {
134
134
  hydrated.categories = await this.repo.findEntityCategories(entity.id, ctx);
135
135
  if (options?.includeBrands)
136
136
  hydrated.brands = await this.repo.findEntityBrands(entity.id, ctx);
137
- if (options?.includeMedia)
138
- hydrated.media = [];
137
+ if (options?.includeMedia) {
138
+ const mediaService = this.deps.services.media;
139
+ const mediaResult = await mediaService?.listEntityMedia?.(entity.id, { orgId: entity.organizationId });
140
+ hydrated.media = mediaResult?.ok && mediaResult.value ? mediaResult.value : [];
141
+ }
139
142
  if (options?.includePricing) {
140
143
  try {
141
144
  const pricingService = this.deps.services.pricing;
142
145
  const priceResult = await pricingService.listPrices({ entityId: entity.id });
143
146
  if (priceResult.ok && priceResult.value) {
144
- hydrated.pricing = priceResult.value.prices.map((p) => ({ currency: p.currency, amount: p.amount, compareAtAmount: p.compareAtAmount ?? null }));
147
+ hydrated.pricing = priceResult.value.prices.map((p) => ({ id: p.id, currency: p.currency, amount: p.amount, compareAtAmount: p.compareAtAmount ?? null, createdAt: p.createdAt }));
145
148
  }
146
149
  }
147
150
  catch { }
@@ -159,7 +162,7 @@ export class EntityService {
159
162
  const afterHooks = this.deps.hooks.resolve("catalog.afterCreate");
160
163
  const context = createHookContext({ actor, tx: ctx?.tx ?? null, logger: createLogger("catalog.create"), services: this.deps.services, context: { moduleName: "catalog" }, ...hookDatabaseArg(this.deps.database) });
161
164
  const processedInput = await runBeforeHooks(beforeHooks, input, "create", context);
162
- const entity = await this.repo.createEntity({ organizationId: orgId, type: processedInput.type, slug: processedInput.slug, status: "draft", isVisible: false, metadata: processedInput.metadata ?? {} }, ctx);
165
+ const entity = await this.repo.createEntity({ organizationId: orgId, type: processedInput.type, slug: processedInput.slug, status: "draft", isVisible: false, ...(processedInput.taxClass !== undefined ? { taxClass: processedInput.taxClass } : {}), metadata: processedInput.metadata ?? {} }, ctx);
163
166
  if (processedInput.attributes) {
164
167
  await this.repo.createAttribute({ entityId: entity.id, locale: processedInput.attributes.locale ?? "en", title: processedInput.attributes.title, subtitle: processedInput.attributes.subtitle, description: processedInput.attributes.description, richDescription: processedInput.attributes.richDescription, seoTitle: processedInput.attributes.seoTitle, seoDescription: processedInput.attributes.seoDescription }, ctx);
165
168
  }
@@ -185,7 +188,7 @@ export class EntityService {
185
188
  const afterHooks = this.deps.hooks.resolve("catalog.afterUpdate");
186
189
  const context = createHookContext({ actor, tx: ctx?.tx ?? null, logger: createLogger("catalog.update"), services: this.deps.services, context: { moduleName: "catalog" }, ...hookDatabaseArg(this.deps.database) });
187
190
  const processed = await runBeforeHooks(beforeHooks, input, "update", context);
188
- const updated = await this.repo.updateEntity(id, { ...(processed.slug !== undefined ? { slug: processed.slug } : {}), ...(processed.status !== undefined ? { status: processed.status } : {}), ...(processed.metadata !== undefined ? { metadata: processed.metadata } : {}), ...(processed.isVisible !== undefined ? { isVisible: processed.isVisible } : {}) }, ctx);
191
+ const updated = await this.repo.updateEntity(id, { ...(processed.slug !== undefined ? { slug: processed.slug } : {}), ...(processed.status !== undefined ? { status: processed.status } : {}), ...(processed.taxClass !== undefined ? { taxClass: processed.taxClass } : {}), ...(processed.metadata !== undefined ? { metadata: processed.metadata } : {}), ...(processed.isVisible !== undefined ? { isVisible: processed.isVisible } : {}) }, ctx);
189
192
  if (!updated)
190
193
  return Err(new CommerceNotFoundError("Entity not found."));
191
194
  const hookReport = await runAfterHooks(afterHooks, existing, updated, "update", context);
@@ -436,12 +439,25 @@ export class EntityService {
436
439
  return Err(new CommerceValidationError(`Option value "${optVal}" does not exist for option type "${optName}".`));
437
440
  optionValueIds.push(ov.id);
438
441
  }
439
- const variant = await this.repo.createVariant({ entityId: input.entityId, status: "active", sortOrder: 0, metadata: {}, ...(input.sku !== undefined ? { sku: input.sku } : {}) }, ctx);
442
+ const variant = await this.repo.createVariant({ entityId: input.entityId, status: "active", sortOrder: 0, metadata: {}, ...(input.sku !== undefined ? { sku: input.sku } : {}), ...(input.taxClass !== undefined ? { taxClass: input.taxClass } : {}) }, ctx);
440
443
  await this.repo.createVariantOptionValues(optionValueIds.map((optionValueId) => ({ variantId: variant.id, optionValueId })), ctx);
441
444
  return Ok(variant);
442
445
  }
443
446
  async generateVariants(entityId, strategy, actor, ctx) {
444
447
  assertPermission(actor, "catalog:update");
448
+ // Guard the strategy: a missing/malformed body (e.g. a bodyless SDK call that
449
+ // skips JSON validation) must be a 422, not a 500 from dereferencing an
450
+ // undefined strategy.
451
+ const mode = strategy?.mode;
452
+ if (mode !== "all" && mode !== "manual" && mode !== "matrix") {
453
+ return Err(new CommerceValidationError('A variant generation strategy is required: { "mode": "all" } | { "mode": "manual", "combinations": [...] } | { "mode": "matrix", "matrix": { "include"?, "exclude"? } }.'));
454
+ }
455
+ if (strategy.mode === "manual" && !Array.isArray(strategy.combinations)) {
456
+ return Err(new CommerceValidationError('strategy.combinations (string[][]) is required for mode "manual".'));
457
+ }
458
+ if (strategy.mode === "matrix" && (!strategy.matrix || typeof strategy.matrix !== "object")) {
459
+ return Err(new CommerceValidationError('strategy.matrix is required for mode "matrix".'));
460
+ }
445
461
  const entity = await this.repo.findEntityById(entityId, ctx);
446
462
  if (!entity)
447
463
  return Err(new CommerceNotFoundError("Entity not found."));
@@ -478,4 +494,133 @@ export class EntityService {
478
494
  }
479
495
  return Ok(created);
480
496
  }
497
+ // ── One-call variant creation (issue #50) ────────────────────────────────
498
+ // Upserts option axes inline, creates variants, and seeds a zero-stock
499
+ // inventory level per variant so it is sellable immediately. Retry-safe:
500
+ // axes upsert by name/value and existing combinations are skipped.
501
+ async upsertAxes(entityId, axes, ctx) {
502
+ const existingTypes = await this.repo.findOptionTypesByEntityId(entityId, ctx);
503
+ const result = new Map();
504
+ for (const axis of axes) {
505
+ let optionType = existingTypes.find((t) => t.name === axis.name);
506
+ if (!optionType) {
507
+ optionType = await this.repo.createOptionType({ entityId, name: axis.name, displayName: axis.name, sortOrder: existingTypes.length }, ctx);
508
+ existingTypes.push(optionType);
509
+ }
510
+ const existingValues = await this.repo.findOptionValuesByTypeId(optionType.id, ctx);
511
+ const valueIds = new Map();
512
+ for (const value of axis.values) {
513
+ let optionValue = existingValues.find((v) => v.value === value);
514
+ if (!optionValue) {
515
+ optionValue = await this.repo.createOptionValue({ optionTypeId: optionType.id, value, displayValue: value, sortOrder: existingValues.length, metadata: {} }, ctx);
516
+ existingValues.push(optionValue);
517
+ }
518
+ valueIds.set(value, optionValue.id);
519
+ }
520
+ result.set(axis.name, valueIds);
521
+ }
522
+ return result;
523
+ }
524
+ async existingComboKeys(entityId, ctx) {
525
+ const existing = new Map();
526
+ for (const variant of await this.repo.findVariantsByEntityId(entityId, ctx)) {
527
+ const rows = await this.repo.findVariantOptionValues(variant.id, ctx);
528
+ const key = rows.map((r) => r.optionValueId).sort().join("|");
529
+ existing.set(key, variant.id);
530
+ }
531
+ return existing;
532
+ }
533
+ async seedInventoryLevel(entityId, variantId, actor, ctx) {
534
+ const inventory = this.deps.services.inventory;
535
+ return inventory.adjustDetailed({ entityId, variantId, adjustment: 0, reason: "Variant created — seed zero-stock level" }, actor, ctx);
536
+ }
537
+ async quickCreateVariant(entityId, input, actor, ctx) {
538
+ try {
539
+ assertPermission(actor, "catalog:update");
540
+ }
541
+ catch (error) {
542
+ return Err(toCommerceError(error));
543
+ }
544
+ const entity = await this.repo.findEntityById(entityId, ctx);
545
+ if (!entity)
546
+ return Err(new CommerceNotFoundError("Entity not found."));
547
+ try {
548
+ this.assertSameOrg(entity, actor);
549
+ }
550
+ catch (error) {
551
+ return Err(toCommerceError(error));
552
+ }
553
+ const axes = Object.entries(input.options).map(([name, value]) => ({ name, values: [value] }));
554
+ const axisValueIds = await this.upsertAxes(entityId, axes, ctx);
555
+ const optionValueIds = Object.entries(input.options)
556
+ .map(([name, value]) => axisValueIds.get(name).get(value));
557
+ const key = [...optionValueIds].sort().join("|");
558
+ const existing = await this.existingComboKeys(entityId, ctx);
559
+ const existingVariantId = existing.get(key);
560
+ if (existingVariantId !== undefined) {
561
+ const variant = await this.repo.findVariantById(existingVariantId, ctx);
562
+ return Ok({ variant: variant, created: false });
563
+ }
564
+ const variant = await this.repo.createVariant({
565
+ entityId,
566
+ status: "active",
567
+ sortOrder: 0,
568
+ metadata: { generatedBy: "quick" },
569
+ ...(input.sku !== undefined ? { sku: input.sku } : {}),
570
+ ...(input.barcode !== undefined ? { barcode: input.barcode } : {}),
571
+ }, ctx);
572
+ await this.repo.createVariantOptionValues(optionValueIds.map((optionValueId) => ({ variantId: variant.id, optionValueId })), ctx);
573
+ const seeded = await this.seedInventoryLevel(entityId, variant.id, actor, ctx);
574
+ if (!seeded.ok)
575
+ return seeded;
576
+ return Ok({ variant, created: true });
577
+ }
578
+ async bulkCreateVariants(entityId, input, actor, ctx) {
579
+ try {
580
+ assertPermission(actor, "catalog:update");
581
+ }
582
+ catch (error) {
583
+ return Err(toCommerceError(error));
584
+ }
585
+ const entity = await this.repo.findEntityById(entityId, ctx);
586
+ if (!entity)
587
+ return Err(new CommerceNotFoundError("Entity not found."));
588
+ try {
589
+ this.assertSameOrg(entity, actor);
590
+ }
591
+ catch (error) {
592
+ return Err(toCommerceError(error));
593
+ }
594
+ const axisValueIds = await this.upsertAxes(entityId, input.axes, ctx);
595
+ // Empty axis list → one option-less variant.
596
+ const groups = input.axes.map((axis) => axis.values.map((value) => ({ value, id: axisValueIds.get(axis.name).get(value) })));
597
+ const combinations = cartesian(groups);
598
+ const existing = await this.existingComboKeys(entityId, ctx);
599
+ const created = [];
600
+ let skipped = 0;
601
+ for (const combo of combinations) {
602
+ const key = combo.map((c) => c.id).sort().join("|");
603
+ if (existing.has(key)) {
604
+ skipped += 1;
605
+ continue;
606
+ }
607
+ const sku = input.skuPrefix !== undefined
608
+ ? [input.skuPrefix, ...combo.map((c) => c.value)].join("-").toUpperCase().replace(/\s+/g, "-")
609
+ : undefined;
610
+ const variant = await this.repo.createVariant({
611
+ entityId,
612
+ status: "active",
613
+ sortOrder: 0,
614
+ metadata: { generatedBy: "bulk" },
615
+ ...(sku !== undefined ? { sku } : {}),
616
+ }, ctx);
617
+ await this.repo.createVariantOptionValues(combo.map((c) => ({ variantId: variant.id, optionValueId: c.id })), ctx);
618
+ const seeded = await this.seedInventoryLevel(entityId, variant.id, actor, ctx);
619
+ if (!seeded.ok)
620
+ return seeded;
621
+ existing.set(key, variant.id);
622
+ created.push(variant);
623
+ }
624
+ return Ok({ created, skipped });
625
+ }
481
626
  }
@@ -104,6 +104,23 @@ export declare const sellableEntities: import("drizzle-orm/pg-core").PgTableWith
104
104
  identity: undefined;
105
105
  generated: undefined;
106
106
  }, {}, {}>;
107
+ taxClass: import("drizzle-orm/pg-core").PgColumn<{
108
+ name: "tax_class";
109
+ tableName: "sellable_entities";
110
+ dataType: "string";
111
+ columnType: "PgText";
112
+ data: string;
113
+ driverParam: string;
114
+ notNull: false;
115
+ hasDefault: false;
116
+ isPrimaryKey: false;
117
+ isAutoincrement: false;
118
+ hasRuntimeDefault: false;
119
+ enumValues: [string, ...string[]];
120
+ baseColumn: never;
121
+ identity: undefined;
122
+ generated: undefined;
123
+ }, {}, {}>;
107
124
  metadata: import("drizzle-orm/pg-core").PgColumn<{
108
125
  name: "metadata";
109
126
  tableName: "sellable_entities";
@@ -1110,6 +1127,23 @@ export declare const variants: import("drizzle-orm/pg-core").PgTableWithColumns<
1110
1127
  identity: undefined;
1111
1128
  generated: undefined;
1112
1129
  }, {}, {}>;
1130
+ taxClass: import("drizzle-orm/pg-core").PgColumn<{
1131
+ name: "tax_class";
1132
+ tableName: "variants";
1133
+ dataType: "string";
1134
+ columnType: "PgText";
1135
+ data: string;
1136
+ driverParam: string;
1137
+ notNull: false;
1138
+ hasDefault: false;
1139
+ isPrimaryKey: false;
1140
+ isAutoincrement: false;
1141
+ hasRuntimeDefault: false;
1142
+ enumValues: [string, ...string[]];
1143
+ baseColumn: never;
1144
+ identity: undefined;
1145
+ generated: undefined;
1146
+ }, {}, {}>;
1113
1147
  status: import("drizzle-orm/pg-core").PgColumn<{
1114
1148
  name: "status";
1115
1149
  tableName: "variants";
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/modules/catalog/schema.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyB5B,CAAC;AAEF,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqB9B,CAAC;AAEF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+BhC,CAAC;AAEF,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmBtB,CAAC;AAEF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAU1B,CAAC;AAEJ,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAalB,CAAC;AAEF,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAUtB,CAAC;AAEJ,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQtB,CAAC;AAEH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASvB,CAAC;AAEH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAelB,CAAC;AAEJ,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAS7B,CAAC"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/modules/catalog/schema.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4B5B,CAAC;AAEF,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqB9B,CAAC;AAEF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+BhC,CAAC;AAEF,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmBtB,CAAC;AAEF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAU1B,CAAC;AAEJ,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAalB,CAAC;AAEF,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAUtB,CAAC;AAEJ,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQtB,CAAC;AAEH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASvB,CAAC;AAEH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiBlB,CAAC;AAEJ,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAS7B,CAAC"}
@@ -11,6 +11,9 @@ export const sellableEntities = pgTable("sellable_entities", {
11
11
  .notNull()
12
12
  .default("draft"),
13
13
  isVisible: boolean("is_visible").notNull().default(false),
14
+ // Tax class name (issue #57) — maps to tax_classes.name at checkout;
15
+ // a variant-level taxClass overrides this. Null = the org's default class.
16
+ taxClass: text("tax_class"),
14
17
  metadata: jsonb("metadata").$type().default({}),
15
18
  createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(),
16
19
  updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull(),
@@ -130,6 +133,8 @@ export const variants = pgTable("variants", {
130
133
  .notNull(),
131
134
  sku: text("sku").unique(),
132
135
  barcode: text("barcode"),
136
+ // Overrides the entity's taxClass when set (issue #57).
137
+ taxClass: text("tax_class"),
133
138
  status: text("status", { enum: ["active", "discontinued"] })
134
139
  .notNull()
135
140
  .default("active"),
@@ -3,6 +3,7 @@ export declare const CreateEntityBodySchema: z.ZodObject<{
3
3
  type: z.ZodString;
4
4
  slug: z.ZodString;
5
5
  status: z.ZodOptional<z.ZodString>;
6
+ taxClass: z.ZodOptional<z.ZodString>;
6
7
  basePrice: z.ZodOptional<z.ZodNumber>;
7
8
  currency: z.ZodOptional<z.ZodString>;
8
9
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
@@ -20,6 +21,7 @@ export declare const CreateEntityBodySchema: z.ZodObject<{
20
21
  export declare const UpdateEntityBodySchema: z.ZodObject<{
21
22
  slug: z.ZodOptional<z.ZodString>;
22
23
  status: z.ZodOptional<z.ZodString>;
24
+ taxClass: z.ZodOptional<z.ZodNullable<z.ZodString>>;
23
25
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
24
26
  isVisible: z.ZodOptional<z.ZodBoolean>;
25
27
  }, z.core.$strip>;
@@ -57,8 +59,20 @@ export declare const CreateVariantBodySchema: z.ZodObject<{
57
59
  sku: z.ZodOptional<z.ZodString>;
58
60
  options: z.ZodRecord<z.ZodString, z.ZodString>;
59
61
  price: z.ZodOptional<z.ZodNumber>;
62
+ taxClass: z.ZodOptional<z.ZodString>;
60
63
  }, z.core.$strip>;
61
- export declare const GenerateVariantsBodySchema: z.ZodObject<{}, z.core.$loose>;
64
+ export declare const GenerateVariantsBodySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
65
+ mode: z.ZodLiteral<"all">;
66
+ }, z.core.$strip>, z.ZodObject<{
67
+ mode: z.ZodLiteral<"manual">;
68
+ combinations: z.ZodArray<z.ZodArray<z.ZodString>>;
69
+ }, z.core.$strip>, z.ZodObject<{
70
+ mode: z.ZodLiteral<"matrix">;
71
+ matrix: z.ZodObject<{
72
+ include: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodString>>>;
73
+ exclude: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodString>>>;
74
+ }, z.core.$strip>;
75
+ }, z.core.$strip>], "mode">;
62
76
  export type CreateEntityInput = z.infer<typeof CreateEntityBodySchema>;
63
77
  export type UpdateEntityInput = z.infer<typeof UpdateEntityBodySchema>;
64
78
  export type CreateCategoryInput = z.infer<typeof CreateCategoryBodySchema> & {
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../../src/modules/catalog/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAItC,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;iBAiBL,CAAC;AAE/B,eAAO,MAAM,sBAAsB;;;;;iBAKL,CAAC;AAE/B,eAAO,MAAM,uBAAuB,wCAAiE,CAAC;AAEtG,eAAO,MAAM,wBAAwB;;;;;iBAKL,CAAC;AAEjC,eAAO,MAAM,wBAAwB;;;;;iBAKL,CAAC;AAEjC,eAAO,MAAM,qBAAqB;;;;iBAIL,CAAC;AAE9B,eAAO,MAAM,qBAAqB;;;;iBAIL,CAAC;AAE9B,eAAO,MAAM,0BAA0B;;;iBAGL,CAAC;AAEnC,eAAO,MAAM,2BAA2B;;iBAEL,CAAC;AAEpC,eAAO,MAAM,uBAAuB;;;;iBAIL,CAAC;AAEhC,eAAO,MAAM,0BAA0B,gCAA6D,CAAC;AAIrG,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEvE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEvE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,GAAG;IAC3E,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE3E,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,GAAG;IACrE,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAErE,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,GAAG;IAC/E,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,GAAG;IACjF,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,GAAG;IACzE,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC"}
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../../src/modules/catalog/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAItC,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;iBAkBL,CAAC;AAE/B,eAAO,MAAM,sBAAsB;;;;;;iBAML,CAAC;AAE/B,eAAO,MAAM,uBAAuB,wCAAiE,CAAC;AAEtG,eAAO,MAAM,wBAAwB;;;;;iBAKL,CAAC;AAEjC,eAAO,MAAM,wBAAwB;;;;;iBAKL,CAAC;AAEjC,eAAO,MAAM,qBAAqB;;;;iBAIL,CAAC;AAE9B,eAAO,MAAM,qBAAqB;;;;iBAIL,CAAC;AAE9B,eAAO,MAAM,0BAA0B;;;iBAGL,CAAC;AAEnC,eAAO,MAAM,2BAA2B;;iBAEL,CAAC;AAEpC,eAAO,MAAM,uBAAuB;;;;;iBAKL,CAAC;AAOhC,eAAO,MAAM,0BAA0B;;;;;;;;;;;2BASL,CAAC;AAInC,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEvE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEvE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,GAAG;IAC3E,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE3E,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,GAAG;IACrE,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAErE,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,GAAG;IAC/E,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,GAAG;IACjF,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,GAAG;IACzE,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC"}
@@ -4,6 +4,7 @@ export const CreateEntityBodySchema = z.object({
4
4
  type: z.string().openapi({ example: "physicalGood" }),
5
5
  slug: z.string().openapi({ example: "my-product" }),
6
6
  status: z.string().optional().openapi({ example: "draft" }),
7
+ taxClass: z.string().optional().openapi({ example: "standard", description: "Product tax class name (issue #57)." }),
7
8
  basePrice: z.number().optional().openapi({ example: 29.99 }),
8
9
  currency: z.string().optional().openapi({ example: "USD" }),
9
10
  metadata: z.record(z.string(), z.unknown()).optional().openapi({ example: { title: "My Product" } }),
@@ -21,6 +22,7 @@ export const CreateEntityBodySchema = z.object({
21
22
  export const UpdateEntityBodySchema = z.object({
22
23
  slug: z.string().optional(),
23
24
  status: z.string().optional(),
25
+ taxClass: z.string().nullable().optional(),
24
26
  metadata: z.record(z.string(), z.unknown()).optional(),
25
27
  isVisible: z.boolean().optional(),
26
28
  }).openapi("UpdateEntityBody");
@@ -58,5 +60,19 @@ export const CreateVariantBodySchema = z.object({
58
60
  sku: z.string().optional().openapi({ example: "SKU-001" }),
59
61
  options: z.record(z.string(), z.string()).openapi({ example: { Color: "Red" } }),
60
62
  price: z.number().optional().openapi({ example: 34.99 }),
63
+ taxClass: z.string().optional().openapi({ example: "zero", description: "Overrides the entity's tax class (issue #57)." }),
61
64
  }).openapi("CreateVariantBody");
62
- export const GenerateVariantsBodySchema = z.object({}).passthrough().openapi("GenerateVariantsBody");
65
+ const VariantMatrixRuleSchema = z.object({
66
+ include: z.array(z.array(z.string())).optional().openapi({ example: [["red", "small"]] }),
67
+ exclude: z.array(z.array(z.string())).optional().openapi({ example: [["red", "large"]] }),
68
+ });
69
+ export const GenerateVariantsBodySchema = z
70
+ .discriminatedUnion("mode", [
71
+ z.object({ mode: z.literal("all") }),
72
+ z.object({
73
+ mode: z.literal("manual"),
74
+ combinations: z.array(z.array(z.string())).openapi({ example: [["red", "small"]] }),
75
+ }),
76
+ z.object({ mode: z.literal("matrix"), matrix: VariantMatrixRuleSchema }),
77
+ ])
78
+ .openapi("GenerateVariantsBody");
@@ -74,12 +74,18 @@ export interface CatalogEntityHydrated extends SellableEntity {
74
74
  media?: Array<{
75
75
  mediaAssetId: string;
76
76
  role: string;
77
- variantId?: string;
77
+ sortOrder: number;
78
+ variantId: string | null;
79
+ url: string;
80
+ alt: string | null;
81
+ contentType: string;
78
82
  }>;
79
83
  pricing?: Array<{
84
+ id: string;
80
85
  currency: string;
81
86
  amount: number;
82
87
  compareAtAmount?: number | null;
88
+ createdAt: Date;
83
89
  }>;
84
90
  }
85
91
  export interface CatalogService {
@@ -115,6 +121,24 @@ export interface CatalogService {
115
121
  createOptionValue(input: CreateOptionValueInput, actor: Actor | null, ctx?: TxContext): Promise<Result<OptionValue>>;
116
122
  createVariant(input: CreateVariantInput, actor: Actor | null, ctx?: TxContext): Promise<Result<Variant>>;
117
123
  generateVariants(entityId: string, strategy: VariantGenerationStrategy, actor: Actor | null, ctx?: TxContext): Promise<Result<Variant[]>>;
124
+ quickCreateVariant(entityId: string, input: {
125
+ options: Record<string, string>;
126
+ sku?: string | undefined;
127
+ barcode?: string | undefined;
128
+ }, actor: Actor | null, ctx?: TxContext): Promise<Result<{
129
+ variant: Variant;
130
+ created: boolean;
131
+ }>>;
132
+ bulkCreateVariants(entityId: string, input: {
133
+ axes: Array<{
134
+ name: string;
135
+ values: string[];
136
+ }>;
137
+ skuPrefix?: string | undefined;
138
+ }, actor: Actor | null, ctx?: TxContext): Promise<Result<{
139
+ created: Variant[];
140
+ skipped: number;
141
+ }>>;
118
142
  }
119
143
  export interface CatalogServiceDeps {
120
144
  repository: CatalogRepository;
@@ -172,5 +196,23 @@ export declare class CatalogServiceImpl implements CatalogService {
172
196
  createOptionValue(input: CreateOptionValueInput, actor: Actor | null, ctx?: TxContext): Promise<Result<OptionValue>>;
173
197
  createVariant(input: CreateVariantInput, actor: Actor | null, ctx?: TxContext): Promise<Result<Variant>>;
174
198
  generateVariants(entityId: string, strategy: VariantGenerationStrategy, actor: Actor | null, ctx?: TxContext): Promise<Result<Variant[]>>;
199
+ quickCreateVariant(entityId: string, input: {
200
+ options: Record<string, string>;
201
+ sku?: string | undefined;
202
+ barcode?: string | undefined;
203
+ }, actor: Actor | null, ctx?: TxContext): Promise<Result<{
204
+ variant: Variant;
205
+ created: boolean;
206
+ }>>;
207
+ bulkCreateVariants(entityId: string, input: {
208
+ axes: Array<{
209
+ name: string;
210
+ values: string[];
211
+ }>;
212
+ skuPrefix?: string | undefined;
213
+ }, actor: Actor | null, ctx?: TxContext): Promise<Result<{
214
+ created: Variant[];
215
+ skipped: number;
216
+ }>>;
175
217
  }
176
218
  //# sourceMappingURL=service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/modules/catalog/service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,EACL,iBAAiB,EACjB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,KAAK,EACV,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,OAAO,EACb,MAAM,uBAAuB,CAAC;AAG/B,YAAY,EACV,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EACnB,MAAM,cAAc,CAAC;AAQtB,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE;YACZ,SAAS,EAAE,MAAM,CAAC;YAClB,KAAK,EAAE,OAAO,CAAC;SAChB,CAAC;KACH,CAAC;IACF,IAAI,CAAC,EAAE;QACL,KAAK,EAAE,WAAW,GAAG,WAAW,GAAG,MAAM,CAAC;QAC1C,SAAS,EAAE,KAAK,GAAG,MAAM,CAAC;KAC3B,CAAC;IACF,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,MAAM,WAAW,UAAU;IACzB,iBAAiB,CAAC,EAAE,OAAO,GAAG;QAAE,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACpD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;CACtB;AAED,MAAM,MAAM,yBAAyB,GACjC;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,GACf;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,EAAE,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,iBAAiB,CAAA;CAAE,CAAC;AAElD,MAAM,WAAW,qBAAsB,SAAQ,cAAc;IAC3D,UAAU,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACjC,QAAQ,CAAC,EAAE,KAAK,CAAC,OAAO,GAAG;QAAE,cAAc,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACzD,WAAW,CAAC,EAAE,KAAK,CAAC,UAAU,GAAG;QAAE,MAAM,EAAE,WAAW,EAAE,CAAA;KAAE,CAAC,CAAC;IAC5D,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;IAC9B,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1E,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;CACxF;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAC;IACvC,MAAM,CACJ,KAAK,EAAE,iBAAiB,EACxB,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAC1C,MAAM,CACJ,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,iBAAiB,EACxB,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAC1C,MAAM,CACJ,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IACzB,OAAO,CACL,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,UAAU,EACpB,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,EACpB,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAC1C,SAAS,CACP,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,UAAU,EACpB,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,EACpB,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAC1C,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC;IACpG,OAAO,CACL,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAC1C,OAAO,CACL,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAC1C,WAAW,CACT,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAC1C,aAAa,CACX,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,kBAAkB,EACzB,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IACzB,aAAa,CACX,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC;IACtC,cAAc,CACZ,GAAG,CAAC,EAAE,SAAS,EACf,IAAI,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACnC,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;IACtC,cAAc,CACZ,KAAK,EAAE,mBAAmB,EAC1B,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC;IACpC,eAAe,CACb,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC;IACpC,eAAe,CACb,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC;IACpC,cAAc,CACZ,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,mBAAmB,EAC1B,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC;IACpC,cAAc,CACZ,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IACzB,aAAa,CACX,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IACzB,kBAAkB,CAChB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IACzB,UAAU,CAAC,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACtD,WAAW,CACT,KAAK,EAAE,gBAAgB,EACvB,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1B,WAAW,CACT,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,gBAAgB,EACvB,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1B,WAAW,CACT,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IACzB,UAAU,CACR,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IACzB,eAAe,CACb,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IACzB,gBAAgB,CACd,KAAK,EAAE,qBAAqB,EAC5B,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;IAC/B,iBAAiB,CACf,KAAK,EAAE,sBAAsB,EAC7B,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;IAChC,aAAa,CACX,KAAK,EAAE,kBAAkB,EACzB,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAC5B,gBAAgB,CACd,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,yBAAyB,EACnC,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,GAAG,CAAC,EAAE,SAAS,GACd,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,iBAAiB,CAAC;IAC9B,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,QAAQ,EAAE,eAAe,CAAC;CAC3B;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,qBAAqB,EAAE,CAAC;IAC/B,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC,CAAC;AAEF,qBAAa,kBAAmB,YAAW,cAAc;IACvD,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAC;IACvC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;gBAE1B,IAAI,EAAE,kBAAkB;IAOpC,MAAM,CAAC,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IAI9G,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IAI1H,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAI/E,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IAIxH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IAI5H,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAInG,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IAIjG,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IAIjG,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IAIrG,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAIvI,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAIpG,cAAc,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC;IAIzG,cAAc,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IAIlH,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IAInG,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IAInG,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IAI9H,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAIvF,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAIhH,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAIrH,UAAU,CAAC,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IAIrD,WAAW,CAAC,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAIlG,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAI9G,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAIpF,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAI1G,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAI/G,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAIjH,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAIpH,aAAa,CAAC,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAIxG,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,yBAAyB,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;CAG1I"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/modules/catalog/service.ts"],"names":[],"mappings":"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"}
@@ -99,4 +99,10 @@ export class CatalogServiceImpl {
99
99
  generateVariants(entityId, strategy, actor, ctx) {
100
100
  return this.entities.generateVariants(entityId, strategy, actor, ctx);
101
101
  }
102
+ quickCreateVariant(entityId, input, actor, ctx) {
103
+ return this.entities.quickCreateVariant(entityId, input, actor, ctx);
104
+ }
105
+ bulkCreateVariants(entityId, input, actor, ctx) {
106
+ return this.entities.bulkCreateVariants(entityId, input, actor, ctx);
107
+ }
102
108
  }
@@ -0,0 +1,7 @@
1
+ import { invoiceSequences, orderDocuments } from "./schema.js";
2
+ import { DocumentsService } from "./service.js";
3
+ export declare const documentsModule: import("../../kernel/module/define.js").AppModule<{
4
+ invoiceSequences: typeof invoiceSequences;
5
+ orderDocuments: typeof orderDocuments;
6
+ }, DocumentsService, Record<string, never>>;
7
+ //# sourceMappingURL=module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../../src/modules/documents/module.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,eAAO,MAAM,eAAe;sBACN,OAAO,gBAAgB;oBAAkB,OAAO,cAAc;2CAWlF,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { defineModule } from "../../kernel/module/index.js";
2
+ import { DocumentsRepository } from "./repository/index.js";
3
+ import { invoiceSequences, orderDocuments } from "./schema.js";
4
+ import { DocumentsService } from "./service.js";
5
+ export const documentsModule = defineModule({
6
+ id: "documents",
7
+ schema: () => ({ invoiceSequences, orderDocuments }),
8
+ service: (deps) => new DocumentsService({
9
+ repository: new DocumentsRepository(deps.db.db),
10
+ services: deps.services,
11
+ }),
12
+ });
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Minimal dependency-free PDF writer (issue #47).
3
+ *
4
+ * Emits PDF 1.4 with Helvetica / Helvetica-Bold (built-in base-14 fonts, no
5
+ * embedding) and uncompressed content streams. Pure string/Uint8Array work —
6
+ * no Node-only APIs, so it runs on Cloudflare Workers and other serverless
7
+ * runtimes. Enough for text documents like invoices; not a general renderer.
8
+ */
9
+ export interface PdfTextOp {
10
+ x: number;
11
+ y: number;
12
+ size: number;
13
+ bold?: boolean | undefined;
14
+ text: string;
15
+ }
16
+ /** A4 in PDF points. */
17
+ export declare const A4: {
18
+ readonly width: 595.28;
19
+ readonly height: 841.89;
20
+ };
21
+ /**
22
+ * Builds a complete PDF document; one inner array of text ops per page.
23
+ */
24
+ export declare function buildPdf(pages: PdfTextOp[][]): Uint8Array;
25
+ //# sourceMappingURL=pdf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf.d.ts","sourceRoot":"","sources":["../../../src/modules/documents/pdf.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,SAAS;IACxB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAwB;AACxB,eAAO,MAAM,EAAE;;;CAA6C,CAAC;AA2B7D;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,GAAG,UAAU,CAoDzD"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Minimal dependency-free PDF writer (issue #47).
3
+ *
4
+ * Emits PDF 1.4 with Helvetica / Helvetica-Bold (built-in base-14 fonts, no
5
+ * embedding) and uncompressed content streams. Pure string/Uint8Array work —
6
+ * no Node-only APIs, so it runs on Cloudflare Workers and other serverless
7
+ * runtimes. Enough for text documents like invoices; not a general renderer.
8
+ */
9
+ /** A4 in PDF points. */
10
+ export const A4 = { width: 595.28, height: 841.89 };
11
+ // Escape to a PDF literal string: backslash, parens, and non-ASCII bytes as
12
+ // octal escapes (Latin-1 / WinAnsi range; anything beyond becomes "?").
13
+ function escapePdfText(text) {
14
+ let out = "";
15
+ for (const ch of text) {
16
+ const code = ch.codePointAt(0);
17
+ if (ch === "\\" || ch === "(" || ch === ")")
18
+ out += `\\${ch}`;
19
+ else if (code >= 32 && code <= 126)
20
+ out += ch;
21
+ else if (code > 126 && code <= 255)
22
+ out += `\\${code.toString(8).padStart(3, "0")}`;
23
+ else
24
+ out += "?";
25
+ }
26
+ return out;
27
+ }
28
+ function contentStream(ops) {
29
+ const parts = [];
30
+ for (const op of ops) {
31
+ const font = op.bold ? "/F2" : "/F1";
32
+ parts.push(`BT ${font} ${op.size} Tf ${op.x.toFixed(2)} ${op.y.toFixed(2)} Td (${escapePdfText(op.text)}) Tj ET`);
33
+ }
34
+ return parts.join("\n");
35
+ }
36
+ /**
37
+ * Builds a complete PDF document; one inner array of text ops per page.
38
+ */
39
+ export function buildPdf(pages) {
40
+ // Object numbering: 1 Catalog, 2 Pages, 3 F1, 4 F2, then per page: Page, Contents.
41
+ const objects = [];
42
+ const pageObjectNumbers = [];
43
+ const firstPageObj = 5;
44
+ for (let i = 0; i < pages.length; i++) {
45
+ pageObjectNumbers.push(firstPageObj + i * 2);
46
+ }
47
+ objects.push(`1 0 obj\n<< /Type /Catalog /Pages 2 0 R >>\nendobj\n`);
48
+ objects.push(`2 0 obj\n<< /Type /Pages /Kids [${pageObjectNumbers.map((n) => `${n} 0 R`).join(" ")}] /Count ${pages.length} >>\nendobj\n`);
49
+ objects.push(`3 0 obj\n<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica /Encoding /WinAnsiEncoding >>\nendobj\n`);
50
+ objects.push(`4 0 obj\n<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding >>\nendobj\n`);
51
+ for (let i = 0; i < pages.length; i++) {
52
+ const pageNum = pageObjectNumbers[i];
53
+ const contentNum = pageNum + 1;
54
+ const stream = contentStream(pages[i]);
55
+ objects.push(`${pageNum} 0 obj\n<< /Type /Page /Parent 2 0 R /MediaBox [0 0 ${A4.width} ${A4.height}] ` +
56
+ `/Resources << /Font << /F1 3 0 R /F2 4 0 R >> >> /Contents ${contentNum} 0 R >>\nendobj\n`);
57
+ objects.push(`${contentNum} 0 obj\n<< /Length ${stream.length} >>\nstream\n${stream}\nendstream\nendobj\n`);
58
+ }
59
+ const header = "%PDF-1.4\n";
60
+ let body = header;
61
+ const offsets = [];
62
+ for (const obj of objects) {
63
+ offsets.push(body.length);
64
+ body += obj;
65
+ }
66
+ const xrefOffset = body.length;
67
+ const count = objects.length + 1;
68
+ let xref = `xref\n0 ${count}\n0000000000 65535 f \n`;
69
+ for (const offset of offsets) {
70
+ xref += `${offset.toString().padStart(10, "0")} 00000 n \n`;
71
+ }
72
+ const trailer = `trailer\n<< /Size ${count} /Root 1 0 R >>\nstartxref\n${xrefOffset}\n%%EOF\n`;
73
+ const full = body + xref + trailer;
74
+ // All bytes are ASCII/Latin-1 by construction (escapePdfText), so a
75
+ // byte-per-char encoding is exact.
76
+ const bytes = new Uint8Array(full.length);
77
+ for (let i = 0; i < full.length; i++)
78
+ bytes[i] = full.charCodeAt(i) & 0xff;
79
+ return bytes;
80
+ }