@porulle/core 0.7.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 (289) 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 +98 -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 +1218 -1
  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 +3110 -43
  66. package/dist/interfaces/rest/schemas/orders.d.ts.map +1 -1
  67. package/dist/interfaces/rest/schemas/orders.js +233 -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/hooks/types.d.ts +1 -1
  88. package/dist/kernel/hooks/types.d.ts.map +1 -1
  89. package/dist/kernel/plugin/manifest.d.ts +23 -0
  90. package/dist/kernel/plugin/manifest.d.ts.map +1 -1
  91. package/dist/kernel/plugin/manifest.js +17 -2
  92. package/dist/modules/analytics/module.d.ts.map +1 -1
  93. package/dist/modules/analytics/module.js +6 -0
  94. package/dist/modules/analytics/reports.d.ts +58 -0
  95. package/dist/modules/analytics/reports.d.ts.map +1 -0
  96. package/dist/modules/analytics/reports.js +249 -0
  97. package/dist/modules/analytics/service.d.ts +10 -0
  98. package/dist/modules/analytics/service.d.ts.map +1 -1
  99. package/dist/modules/analytics/service.js +14 -0
  100. package/dist/modules/cart/repository/index.d.ts +7 -0
  101. package/dist/modules/cart/repository/index.d.ts.map +1 -1
  102. package/dist/modules/cart/repository/index.js +25 -1
  103. package/dist/modules/cart/schema.d.ts +17 -0
  104. package/dist/modules/cart/schema.d.ts.map +1 -1
  105. package/dist/modules/cart/schema.js +2 -0
  106. package/dist/modules/cart/schemas.d.ts +1 -0
  107. package/dist/modules/cart/schemas.d.ts.map +1 -1
  108. package/dist/modules/cart/schemas.js +1 -0
  109. package/dist/modules/cart/service.d.ts +32 -0
  110. package/dist/modules/cart/service.d.ts.map +1 -1
  111. package/dist/modules/cart/service.js +58 -0
  112. package/dist/modules/catalog/entity-service.d.ts +21 -0
  113. package/dist/modules/catalog/entity-service.d.ts.map +1 -1
  114. package/dist/modules/catalog/entity-service.js +132 -3
  115. package/dist/modules/catalog/schema.d.ts +34 -0
  116. package/dist/modules/catalog/schema.d.ts.map +1 -1
  117. package/dist/modules/catalog/schema.js +5 -0
  118. package/dist/modules/catalog/schemas.d.ts +3 -0
  119. package/dist/modules/catalog/schemas.d.ts.map +1 -1
  120. package/dist/modules/catalog/schemas.js +3 -0
  121. package/dist/modules/catalog/service.d.ts +36 -0
  122. package/dist/modules/catalog/service.d.ts.map +1 -1
  123. package/dist/modules/catalog/service.js +6 -0
  124. package/dist/modules/documents/module.d.ts +7 -0
  125. package/dist/modules/documents/module.d.ts.map +1 -0
  126. package/dist/modules/documents/module.js +12 -0
  127. package/dist/modules/documents/pdf.d.ts +25 -0
  128. package/dist/modules/documents/pdf.d.ts.map +1 -0
  129. package/dist/modules/documents/pdf.js +80 -0
  130. package/dist/modules/documents/render.d.ts +32 -0
  131. package/dist/modules/documents/render.d.ts.map +1 -0
  132. package/dist/modules/documents/render.js +190 -0
  133. package/dist/modules/documents/repository/index.d.ts +25 -0
  134. package/dist/modules/documents/repository/index.d.ts.map +1 -0
  135. package/dist/modules/documents/repository/index.js +47 -0
  136. package/dist/modules/documents/schema.d.ts +214 -0
  137. package/dist/modules/documents/schema.d.ts.map +1 -0
  138. package/dist/modules/documents/schema.js +42 -0
  139. package/dist/modules/documents/service.d.ts +51 -0
  140. package/dist/modules/documents/service.d.ts.map +1 -0
  141. package/dist/modules/documents/service.js +119 -0
  142. package/dist/modules/fulfillment/service.d.ts +18 -0
  143. package/dist/modules/fulfillment/service.d.ts.map +1 -1
  144. package/dist/modules/fulfillment/service.js +85 -1
  145. package/dist/modules/orders/repository/index.d.ts +18 -1
  146. package/dist/modules/orders/repository/index.d.ts.map +1 -1
  147. package/dist/modules/orders/repository/index.js +86 -1
  148. package/dist/modules/orders/schema.d.ts +374 -0
  149. package/dist/modules/orders/schema.d.ts.map +1 -1
  150. package/dist/modules/orders/schema.js +52 -1
  151. package/dist/modules/orders/service.d.ts +86 -1
  152. package/dist/modules/orders/service.d.ts.map +1 -1
  153. package/dist/modules/orders/service.js +447 -20
  154. package/dist/modules/pricing/repository/index.d.ts +5 -0
  155. package/dist/modules/pricing/repository/index.d.ts.map +1 -1
  156. package/dist/modules/pricing/repository/index.js +19 -0
  157. package/dist/modules/pricing/service.d.ts +18 -0
  158. package/dist/modules/pricing/service.d.ts.map +1 -1
  159. package/dist/modules/pricing/service.js +38 -0
  160. package/dist/modules/settings/module.d.ts +6 -0
  161. package/dist/modules/settings/module.d.ts.map +1 -0
  162. package/dist/modules/settings/module.js +11 -0
  163. package/dist/modules/settings/repository/index.d.ts +16 -0
  164. package/dist/modules/settings/repository/index.d.ts.map +1 -0
  165. package/dist/modules/settings/repository/index.js +41 -0
  166. package/dist/modules/settings/schema.d.ts +121 -0
  167. package/dist/modules/settings/schema.d.ts.map +1 -0
  168. package/dist/modules/settings/schema.js +24 -0
  169. package/dist/modules/settings/service.d.ts +26 -0
  170. package/dist/modules/settings/service.d.ts.map +1 -0
  171. package/dist/modules/settings/service.js +51 -0
  172. package/dist/modules/shipping/calculator.d.ts +5 -0
  173. package/dist/modules/shipping/calculator.d.ts.map +1 -1
  174. package/dist/modules/shipping/calculator.js +10 -0
  175. package/dist/modules/shipping/module.d.ts +5 -1
  176. package/dist/modules/shipping/module.d.ts.map +1 -1
  177. package/dist/modules/shipping/module.js +4 -1
  178. package/dist/modules/shipping/repository/index.d.ts +27 -2
  179. package/dist/modules/shipping/repository/index.d.ts.map +1 -1
  180. package/dist/modules/shipping/repository/index.js +105 -1
  181. package/dist/modules/shipping/schema.d.ts +419 -0
  182. package/dist/modules/shipping/schema.d.ts.map +1 -0
  183. package/dist/modules/shipping/schema.js +56 -0
  184. package/dist/modules/shipping/service.d.ts +54 -0
  185. package/dist/modules/shipping/service.d.ts.map +1 -1
  186. package/dist/modules/shipping/service.js +161 -2
  187. package/dist/modules/tax/adapter.d.ts +13 -0
  188. package/dist/modules/tax/adapter.d.ts.map +1 -1
  189. package/dist/modules/tax/module.d.ts +5 -1
  190. package/dist/modules/tax/module.d.ts.map +1 -1
  191. package/dist/modules/tax/module.js +4 -1
  192. package/dist/modules/tax/repository/index.d.ts +38 -2
  193. package/dist/modules/tax/repository/index.d.ts.map +1 -1
  194. package/dist/modules/tax/repository/index.js +138 -1
  195. package/dist/modules/tax/schema.d.ts +355 -0
  196. package/dist/modules/tax/schema.d.ts.map +1 -0
  197. package/dist/modules/tax/schema.js +55 -0
  198. package/dist/modules/tax/service.d.ts +60 -1
  199. package/dist/modules/tax/service.d.ts.map +1 -1
  200. package/dist/modules/tax/service.js +227 -2
  201. package/dist/runtime/kernel-modules.d.ts +15 -2
  202. package/dist/runtime/kernel-modules.d.ts.map +1 -1
  203. package/dist/runtime/kernel-modules.js +4 -0
  204. package/dist/runtime/kernel-types.d.ts +5 -1
  205. package/dist/runtime/kernel-types.d.ts.map +1 -1
  206. package/dist/runtime/kernel-types.js +2 -0
  207. package/dist/runtime/server.js +1 -1
  208. package/dist/test-utils/create-plugin-test-app.d.ts +3 -0
  209. package/dist/test-utils/create-plugin-test-app.d.ts.map +1 -1
  210. package/dist/test-utils/create-plugin-test-app.js +15 -3
  211. package/dist/test-utils/rest-api-test-utils.d.ts.map +1 -1
  212. package/dist/test-utils/rest-api-test-utils.js +6 -0
  213. package/package.json +3 -3
  214. package/src/auth/setup.ts +1 -0
  215. package/src/config/defaults.ts +5 -0
  216. package/src/config/types.ts +17 -1
  217. package/src/generated/plugin-capabilities.d.ts +1 -0
  218. package/src/generated/plugin-manifest.ts +1 -0
  219. package/src/generated/plugin-repositories.d.ts +1 -0
  220. package/src/hooks/checkout.ts +25 -3
  221. package/src/index.ts +1 -0
  222. package/src/interfaces/rest/index.ts +12 -0
  223. package/src/interfaces/rest/routes/admin/staff.ts +218 -0
  224. package/src/interfaces/rest/routes/analytics.ts +33 -0
  225. package/src/interfaces/rest/routes/carts.ts +52 -2
  226. package/src/interfaces/rest/routes/catalog.ts +34 -0
  227. package/src/interfaces/rest/routes/checkout.ts +22 -0
  228. package/src/interfaces/rest/routes/documents.ts +61 -0
  229. package/src/interfaces/rest/routes/orders.ts +137 -1
  230. package/src/interfaces/rest/routes/pricing.ts +44 -1
  231. package/src/interfaces/rest/routes/settings.ts +61 -0
  232. package/src/interfaces/rest/routes/shipping.ts +92 -0
  233. package/src/interfaces/rest/routes/tax.ts +90 -0
  234. package/src/interfaces/rest/schemas/admin-staff.ts +110 -0
  235. package/src/interfaces/rest/schemas/analytics.ts +39 -0
  236. package/src/interfaces/rest/schemas/carts.ts +40 -0
  237. package/src/interfaces/rest/schemas/catalog.ts +53 -0
  238. package/src/interfaces/rest/schemas/checkout.ts +4 -0
  239. package/src/interfaces/rest/schemas/documents.ts +72 -0
  240. package/src/interfaces/rest/schemas/orders.ts +257 -0
  241. package/src/interfaces/rest/schemas/pricing.ts +75 -0
  242. package/src/interfaces/rest/schemas/settings.ts +93 -0
  243. package/src/interfaces/rest/schemas/shipping.ts +164 -0
  244. package/src/interfaces/rest/schemas/tax.ts +148 -0
  245. package/src/kernel/database/schema.ts +12 -0
  246. package/src/kernel/hooks/types.ts +1 -0
  247. package/src/kernel/plugin/manifest.ts +38 -2
  248. package/src/modules/analytics/module.ts +10 -0
  249. package/src/modules/analytics/reports.ts +311 -0
  250. package/src/modules/analytics/service.ts +23 -0
  251. package/src/modules/cart/repository/index.ts +30 -1
  252. package/src/modules/cart/schema.ts +2 -0
  253. package/src/modules/cart/schemas.ts +1 -0
  254. package/src/modules/cart/service.ts +101 -0
  255. package/src/modules/catalog/entity-service.ts +168 -3
  256. package/src/modules/catalog/schema.ts +5 -0
  257. package/src/modules/catalog/schemas.ts +3 -0
  258. package/src/modules/catalog/service.ts +30 -0
  259. package/src/modules/documents/module.ts +19 -0
  260. package/src/modules/documents/pdf.ts +101 -0
  261. package/src/modules/documents/render.ts +231 -0
  262. package/src/modules/documents/repository/index.ts +68 -0
  263. package/src/modules/documents/schema.ts +44 -0
  264. package/src/modules/documents/service.ts +176 -0
  265. package/src/modules/fulfillment/service.ts +139 -1
  266. package/src/modules/orders/repository/index.ts +127 -1
  267. package/src/modules/orders/schema.ts +54 -1
  268. package/src/modules/orders/service.ts +654 -22
  269. package/src/modules/pricing/repository/index.ts +34 -0
  270. package/src/modules/pricing/service.ts +71 -0
  271. package/src/modules/settings/module.ts +18 -0
  272. package/src/modules/settings/repository/index.ts +59 -0
  273. package/src/modules/settings/schema.ts +25 -0
  274. package/src/modules/settings/service.ts +82 -0
  275. package/src/modules/shipping/calculator.ts +27 -0
  276. package/src/modules/shipping/module.ts +6 -2
  277. package/src/modules/shipping/repository/index.ts +136 -2
  278. package/src/modules/shipping/schema.ts +58 -0
  279. package/src/modules/shipping/service.ts +260 -1
  280. package/src/modules/tax/adapter.ts +9 -0
  281. package/src/modules/tax/module.ts +6 -2
  282. package/src/modules/tax/repository/index.ts +169 -2
  283. package/src/modules/tax/schema.ts +57 -0
  284. package/src/modules/tax/service.ts +313 -2
  285. package/src/runtime/kernel-modules.ts +4 -0
  286. package/src/runtime/kernel-types.ts +6 -0
  287. package/src/runtime/server.ts +1 -1
  288. package/src/test-utils/create-plugin-test-app.ts +17 -4
  289. package/src/test-utils/rest-api-test-utils.ts +6 -0
@@ -14,6 +14,15 @@ export function checkoutRoutes(kernel) {
14
14
  router.openapi(checkoutRoute, async (c) => {
15
15
  const body = c.req.valid("json");
16
16
  const actor = c.get("actor");
17
+ // Idempotent replay: a re-submitted checkout (offline POS queue, network
18
+ // retry) returns the already-created order BEFORE the pipeline runs — no
19
+ // double payment authorization, no duplicate order.
20
+ if (body.idempotencyKey) {
21
+ const replay = await kernel.services.orders.getByIdempotencyKey(body.idempotencyKey, actor);
22
+ if (replay.ok && replay.value) {
23
+ return c.json({ data: replay.value }, 201);
24
+ }
25
+ }
17
26
  const checkoutData = {
18
27
  checkoutId: makeId(),
19
28
  cartId: body.cartId,
@@ -105,6 +114,9 @@ export function checkoutRoutes(kernel) {
105
114
  // If both lookups fail, we still allow guest checkout (customerUuid remains undefined)
106
115
  }
107
116
  const orderPayload = {
117
+ ...(body.idempotencyKey !== undefined
118
+ ? { idempotencyKey: body.idempotencyKey }
119
+ : {}),
108
120
  currency: processed.currency,
109
121
  subtotal: processed.subtotal,
110
122
  taxTotal: processed.taxTotal,
@@ -133,6 +145,11 @@ export function checkoutRoutes(kernel) {
133
145
  quantity: lineItem.quantity,
134
146
  unitPrice: lineItem.resolvedUnitPrice ?? 0,
135
147
  totalPrice: lineItem.resolvedTotal ?? 0,
148
+ // Per-line tax from product tax classes (issue #57)
149
+ taxAmount: lineItem.taxAmount ?? 0,
150
+ ...(lineItem.discountAmount !== undefined
151
+ ? { discountAmount: lineItem.discountAmount }
152
+ : {}),
136
153
  };
137
154
  return lineItem.variantId !== undefined
138
155
  ? { ...payload, variantId: lineItem.variantId }
@@ -0,0 +1,10 @@
1
+ import { OpenAPIHono } from "@hono/zod-openapi";
2
+ import type { Kernel } from "../../../runtime/kernel.js";
3
+ import { type AppEnv } from "../utils.js";
4
+ /**
5
+ * Order document rendering (issue #47). Mounted under /orders. Access
6
+ * control rides on OrderService.getById (orders:read, or orders:read:own
7
+ * for the order's customer), so no extra scope is needed here.
8
+ */
9
+ export declare function documentRoutes(kernel: Kernel): OpenAPIHono<AppEnv, {}, "/">;
10
+ //# sourceMappingURL=documents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documents.d.ts","sourceRoot":"","sources":["../../../../src/interfaces/rest/routes/documents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAOzD,OAAO,EAAE,KAAK,MAAM,EAAwC,MAAM,aAAa,CAAC;AAEhF;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,gCA6C5C"}
@@ -0,0 +1,40 @@
1
+ import { OpenAPIHono } from "@hono/zod-openapi";
2
+ import { emailInvoiceRoute, invoiceHtmlRoute, invoicePdfRoute, receiptHtmlRoute, } from "../schemas/documents.js";
3
+ import { mapErrorToResponse, mapErrorToStatus } from "../utils.js";
4
+ /**
5
+ * Order document rendering (issue #47). Mounted under /orders. Access
6
+ * control rides on OrderService.getById (orders:read, or orders:read:own
7
+ * for the order's customer), so no extra scope is needed here.
8
+ */
9
+ export function documentRoutes(kernel) {
10
+ const router = new OpenAPIHono();
11
+ router.openapi(invoicePdfRoute, async (c) => {
12
+ const result = await kernel.services.documents.renderInvoicePdf(c.req.param("id"), c.get("actor"));
13
+ if (!result.ok)
14
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
15
+ return c.body(result.value.pdf.slice().buffer, 200, {
16
+ "content-type": "application/pdf",
17
+ "content-disposition": `inline; filename="invoice-${result.value.invoiceNumber}.pdf"`,
18
+ });
19
+ });
20
+ router.openapi(invoiceHtmlRoute, async (c) => {
21
+ const result = await kernel.services.documents.renderInvoiceHtml(c.req.param("id"), c.get("actor"));
22
+ if (!result.ok)
23
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
24
+ return c.html(result.value.html);
25
+ });
26
+ router.openapi(receiptHtmlRoute, async (c) => {
27
+ const result = await kernel.services.documents.renderReceiptHtml(c.req.param("id"), c.get("actor"));
28
+ if (!result.ok)
29
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
30
+ return c.html(result.value.html);
31
+ });
32
+ // @ts-expect-error -- openapi handler union return type
33
+ router.openapi(emailInvoiceRoute, async (c) => {
34
+ const result = await kernel.services.documents.emailInvoice(c.req.param("id"), c.req.valid("json").to, c.get("actor"));
35
+ if (!result.ok)
36
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
37
+ return c.json({ data: result.value });
38
+ });
39
+ return router;
40
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"orders.d.ts","sourceRoot":"","sources":["../../../../src/interfaces/rest/routes/orders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAEzD,OAAO,EAAE,KAAK,MAAM,EAAiE,MAAM,aAAa,CAAC;AAGzG,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,gCA8HzC"}
1
+ {"version":3,"file":"orders.d.ts","sourceRoot":"","sources":["../../../../src/interfaces/rest/routes/orders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAEzD,OAAO,EAAE,KAAK,MAAM,EAAiE,MAAM,aAAa,CAAC;AAGzG,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,gCAsQzC"}
@@ -1,5 +1,5 @@
1
1
  import { OpenAPIHono } from "@hono/zod-openapi";
2
- import { changeOrderStatusRoute, listOrdersRoute, orderLookupRoute, getOrderRoute, getOrderFulfillmentsRoute, createOrderRoute, refundOrderRoute, captureOrderRoute } from "../schemas/orders.js";
2
+ import { changeOrderStatusRoute, listOrdersRoute, orderLookupRoute, getOrderRoute, getOrderFulfillmentsRoute, createOrderRoute, refundOrderRoute, captureOrderRoute, createOrderFulfillmentRoute, addOrderLineItemRoute, updateOrderLineItemRoute, removeOrderLineItemRoute, refundOrderLinesRoute, undoOrderRefundRoute, listOrderRefundsRoute, refundCapStatusRoute, createOrderNoteRoute, listOrderNotesRoute, deleteOrderNoteRoute, orderTimelineRoute } from "../schemas/orders.js";
3
3
  import { isUUID, mapErrorToResponse, mapErrorToStatus, parsePagination } from "../utils.js";
4
4
  export function orderRoutes(kernel) {
5
5
  const router = new OpenAPIHono();
@@ -69,6 +69,66 @@ export function orderRoutes(kernel) {
69
69
  return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
70
70
  return c.json({ data: result.value });
71
71
  });
72
+ // ── Notes + activity timeline (issue #56) ──────────────────────────
73
+ // @ts-expect-error -- openapi handler union return type
74
+ router.openapi(createOrderNoteRoute, async (c) => {
75
+ const body = c.req.valid("json");
76
+ const result = await kernel.services.orders.addNote(c.req.param("id"), body, c.get("actor"));
77
+ if (!result.ok)
78
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
79
+ return c.json({ data: result.value }, 201);
80
+ });
81
+ // @ts-expect-error -- openapi handler union return type
82
+ router.openapi(listOrderNotesRoute, async (c) => {
83
+ const result = await kernel.services.orders.listNotes(c.req.param("id"), c.get("actor"));
84
+ if (!result.ok)
85
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
86
+ return c.json({ data: result.value });
87
+ });
88
+ // @ts-expect-error -- openapi handler union return type
89
+ router.openapi(deleteOrderNoteRoute, async (c) => {
90
+ const result = await kernel.services.orders.deleteNote(c.req.param("id"), c.req.param("noteId"), c.get("actor"));
91
+ if (!result.ok)
92
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
93
+ return c.json({ data: result.value });
94
+ });
95
+ // @ts-expect-error -- openapi handler union return type
96
+ router.openapi(orderTimelineRoute, async (c) => {
97
+ const result = await kernel.services.orders.timeline(c.req.param("id"), c.get("actor"));
98
+ if (!result.ok)
99
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
100
+ return c.json({ data: result.value });
101
+ });
102
+ // ── Line-level refunds (issue #52) ─────────────────────────────────
103
+ // @ts-expect-error -- openapi handler union return type
104
+ router.openapi(refundCapStatusRoute, async (c) => {
105
+ const result = await kernel.services.orders.refundCapStatus(c.get("actor"));
106
+ if (!result.ok)
107
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
108
+ return c.json({ data: result.value });
109
+ });
110
+ // @ts-expect-error -- openapi handler union return type
111
+ router.openapi(refundOrderLinesRoute, async (c) => {
112
+ const body = c.req.valid("json");
113
+ const result = await kernel.services.orders.refundLines(c.req.param("id"), body, c.get("actor"));
114
+ if (!result.ok)
115
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
116
+ return c.json({ data: result.value }, 201);
117
+ });
118
+ // @ts-expect-error -- openapi handler union return type
119
+ router.openapi(undoOrderRefundRoute, async (c) => {
120
+ const result = await kernel.services.orders.undoRefund(c.req.param("id"), c.req.param("refundId"), c.get("actor"));
121
+ if (!result.ok)
122
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
123
+ return c.json({ data: result.value });
124
+ });
125
+ // @ts-expect-error -- openapi handler union return type
126
+ router.openapi(listOrderRefundsRoute, async (c) => {
127
+ const result = await kernel.services.orders.listRefunds(c.req.param("id"), c.get("actor"));
128
+ if (!result.ok)
129
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
130
+ return c.json({ data: result.value });
131
+ });
72
132
  // @ts-expect-error -- openapi handler union return type
73
133
  router.openapi(captureOrderRoute, async (c) => {
74
134
  const body = c.req.valid("json");
@@ -77,6 +137,29 @@ export function orderRoutes(kernel) {
77
137
  return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
78
138
  return c.json({ data: result.value });
79
139
  });
140
+ // @ts-expect-error -- openapi handler union return type
141
+ router.openapi(addOrderLineItemRoute, async (c) => {
142
+ const body = c.req.valid("json");
143
+ const result = await kernel.services.orders.addLineItem(c.req.param("id"), body, c.get("actor"));
144
+ if (!result.ok)
145
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
146
+ return c.json({ data: result.value }, 201);
147
+ });
148
+ // @ts-expect-error -- openapi handler union return type
149
+ router.openapi(updateOrderLineItemRoute, async (c) => {
150
+ const body = c.req.valid("json");
151
+ const result = await kernel.services.orders.updateOrderLineItem(c.req.param("id"), c.req.param("lineItemId"), body, c.get("actor"));
152
+ if (!result.ok)
153
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
154
+ return c.json({ data: result.value });
155
+ });
156
+ // @ts-expect-error -- openapi handler union return type
157
+ router.openapi(removeOrderLineItemRoute, async (c) => {
158
+ const result = await kernel.services.orders.removeLineItem(c.req.param("id"), c.req.param("lineItemId"), c.get("actor"));
159
+ if (!result.ok)
160
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
161
+ return c.json({ data: result.value });
162
+ });
80
163
  // @ts-expect-error -- openapi() enforces strict response typing but our handler
81
164
  // returns union responses (200 | 400 | 404). The route definition documents the
82
165
  // contract; the handler returns dynamic status.
@@ -92,6 +175,20 @@ export function orderRoutes(kernel) {
92
175
  return c.json({ data: result.value });
93
176
  });
94
177
  // @ts-expect-error -- openapi handler union return type
178
+ router.openapi(createOrderFulfillmentRoute, async (c) => {
179
+ const actor = c.get("actor");
180
+ const orderId = c.req.param("id");
181
+ // Verify the order exists and the actor has access before recording
182
+ const orderResult = await kernel.services.orders.getById(orderId, actor);
183
+ if (!orderResult.ok)
184
+ return c.json(mapErrorToResponse(orderResult.error), mapErrorToStatus(orderResult.error));
185
+ const body = c.req.valid("json");
186
+ const result = await kernel.services.fulfillment.createFulfillment({ ...body, orderId: orderResult.value.id }, actor);
187
+ if (!result.ok)
188
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
189
+ return c.json({ data: result.value }, 201);
190
+ });
191
+ // @ts-expect-error -- openapi handler union return type
95
192
  router.openapi(getOrderFulfillmentsRoute, async (c) => {
96
193
  const orderId = c.req.param("id");
97
194
  const actor = c.get("actor");
@@ -1 +1 @@
1
- {"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["../../../../src/interfaces/rest/routes/pricing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAKhD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAEzD,OAAO,EAAE,KAAK,MAAM,EAAqD,MAAM,aAAa,CAAC;AAE7F,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,gCAoE3C"}
1
+ {"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["../../../../src/interfaces/rest/routes/pricing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAKhD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAEzD,OAAO,EAAE,KAAK,MAAM,EAAqD,MAAM,aAAa,CAAC;AAE7F,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,gCA+G3C"}
@@ -2,7 +2,7 @@ import { OpenAPIHono } from "@hono/zod-openapi";
2
2
  import { resolveOrgId } from "../../../auth/org.js";
3
3
  import { CommerceValidationError } from "../../../kernel/errors.js";
4
4
  import { CatalogRepository } from "../../../modules/catalog/repository/index.js";
5
- import { setBasePriceRoute, createModifierRoute, listPricesRoute } from "../schemas/pricing.js";
5
+ import { setBasePriceRoute, createModifierRoute, listPricesRoute, listModifiersRoute, updateModifierRoute, deleteModifierRoute } from "../schemas/pricing.js";
6
6
  import { mapErrorToResponse, mapErrorToStatus, requirePerm } from "../utils.js";
7
7
  export function pricingRoutes(kernel) {
8
8
  const router = new OpenAPIHono();
@@ -37,6 +37,41 @@ export function pricingRoutes(kernel) {
37
37
  return c.json({ data: result.value });
38
38
  });
39
39
  router.use("/modifiers", requirePerm("pricing:manage"));
40
+ router.use("/modifiers/:id", requirePerm("pricing:manage"));
41
+ // @ts-expect-error -- openapi handler union return type
42
+ router.openapi(listModifiersRoute, async (c) => {
43
+ const actor = c.get("actor");
44
+ const entityId = c.req.query("entityId");
45
+ const currency = c.req.query("currency");
46
+ const active = c.req.query("active");
47
+ const result = await kernel.services.pricing.listModifiers({
48
+ ...(entityId !== undefined ? { entityId } : {}),
49
+ ...(currency !== undefined ? { currency } : {}),
50
+ ...(active === "true" ? { active: true } : {}),
51
+ }, actor);
52
+ if (!result.ok) {
53
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
54
+ }
55
+ return c.json({ data: result.value });
56
+ });
57
+ // @ts-expect-error -- openapi handler union return type
58
+ router.openapi(updateModifierRoute, async (c) => {
59
+ const actor = c.get("actor");
60
+ const result = await kernel.services.pricing.updateModifier(c.req.param("id"), c.req.valid("json"), actor);
61
+ if (!result.ok) {
62
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
63
+ }
64
+ return c.json({ data: result.value });
65
+ });
66
+ // @ts-expect-error -- openapi handler union return type
67
+ router.openapi(deleteModifierRoute, async (c) => {
68
+ const actor = c.get("actor");
69
+ const result = await kernel.services.pricing.deleteModifier(c.req.param("id"), actor);
70
+ if (!result.ok) {
71
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
72
+ }
73
+ return c.json({ data: result.value });
74
+ });
40
75
  // @ts-expect-error -- openapi() enforces strict response typing but our handler
41
76
  // returns union responses (201 | 400 | 422). The route definition documents the
42
77
  // contract; the handler returns dynamic status.
@@ -0,0 +1,5 @@
1
+ import { OpenAPIHono } from "@hono/zod-openapi";
2
+ import type { Kernel } from "../../../runtime/kernel.js";
3
+ import { type AppEnv } from "../utils.js";
4
+ export declare function settingsRoutes(kernel: Kernel): OpenAPIHono<AppEnv, {}, "/">;
5
+ //# sourceMappingURL=settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../../src/interfaces/rest/routes/settings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAOzD,OAAO,EAAE,KAAK,MAAM,EAAqD,MAAM,aAAa,CAAC;AAE7F,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,gCAkD5C"}
@@ -0,0 +1,50 @@
1
+ import { OpenAPIHono } from "@hono/zod-openapi";
2
+ import { KNOWN_GROUP_SCHEMAS, getAllSettingsRoute, getSettingsGroupRoute, patchSettingsGroupRoute, } from "../schemas/settings.js";
3
+ import { mapErrorToResponse, mapErrorToStatus, requirePerm } from "../utils.js";
4
+ export function settingsRoutes(kernel) {
5
+ const router = new OpenAPIHono();
6
+ router.use("/", requirePerm("settings:manage"));
7
+ router.use("/:group", requirePerm("settings:manage"));
8
+ // @ts-expect-error -- openapi handler union return type
9
+ router.openapi(getAllSettingsRoute, async (c) => {
10
+ const result = await kernel.services.settings.getAll(c.get("actor"));
11
+ if (!result.ok)
12
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
13
+ return c.json({ data: result.value });
14
+ });
15
+ // @ts-expect-error -- openapi handler union return type
16
+ router.openapi(getSettingsGroupRoute, async (c) => {
17
+ const result = await kernel.services.settings.getGroup(c.req.param("group"), c.get("actor"));
18
+ if (!result.ok)
19
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
20
+ return c.json({ data: result.value });
21
+ });
22
+ // @ts-expect-error -- openapi handler union return type
23
+ router.openapi(patchSettingsGroupRoute, async (c) => {
24
+ const group = c.req.param("group");
25
+ const body = c.req.valid("json");
26
+ // Known groups get typed validation; unknown groups accept any object.
27
+ const groupSchema = KNOWN_GROUP_SCHEMAS[group];
28
+ if (groupSchema) {
29
+ const parsed = groupSchema.safeParse(body);
30
+ if (!parsed.success) {
31
+ const isProd = process.env.NODE_ENV === "production";
32
+ return c.json({
33
+ error: {
34
+ code: "VALIDATION_FAILED",
35
+ message: isProd
36
+ ? "Invalid input."
37
+ : parsed.error.issues
38
+ .map((i) => `${i.path.join(".")}: ${i.message}`)
39
+ .join("; "),
40
+ },
41
+ }, 422);
42
+ }
43
+ }
44
+ const result = await kernel.services.settings.updateGroup(group, body, c.get("actor"));
45
+ if (!result.ok)
46
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
47
+ return c.json({ data: result.value });
48
+ });
49
+ return router;
50
+ }
@@ -0,0 +1,5 @@
1
+ import { OpenAPIHono } from "@hono/zod-openapi";
2
+ import type { Kernel } from "../../../runtime/kernel.js";
3
+ import { type AppEnv } from "../utils.js";
4
+ export declare function shippingRoutes(kernel: Kernel): OpenAPIHono<AppEnv, {}, "/">;
5
+ //# sourceMappingURL=shipping.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shipping.d.ts","sourceRoot":"","sources":["../../../../src/interfaces/rest/routes/shipping.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAWzD,OAAO,EAAE,KAAK,MAAM,EAAqD,MAAM,aAAa,CAAC;AAE7F,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,gCA6E5C"}
@@ -0,0 +1,68 @@
1
+ import { OpenAPIHono } from "@hono/zod-openapi";
2
+ import { createShippingZoneRoute, listShippingZonesRoute, updateShippingZoneRoute, deleteShippingZoneRoute, createShippingRateRoute, listShippingRatesRoute, updateShippingRateRoute, deleteShippingRateRoute, } from "../schemas/shipping.js";
3
+ import { mapErrorToResponse, mapErrorToStatus, requirePerm } from "../utils.js";
4
+ export function shippingRoutes(kernel) {
5
+ const router = new OpenAPIHono();
6
+ router.use("/zones", requirePerm("shipping:manage"));
7
+ router.use("/zones/:id", requirePerm("shipping:manage"));
8
+ router.use("/rates", requirePerm("shipping:manage"));
9
+ router.use("/rates/:id", requirePerm("shipping:manage"));
10
+ // @ts-expect-error -- openapi handler union return type
11
+ router.openapi(createShippingZoneRoute, async (c) => {
12
+ const result = await kernel.services.shipping.createZone(c.req.valid("json"), c.get("actor"));
13
+ if (!result.ok)
14
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
15
+ return c.json({ data: result.value }, 201);
16
+ });
17
+ // @ts-expect-error -- openapi handler union return type
18
+ router.openapi(listShippingZonesRoute, async (c) => {
19
+ const result = await kernel.services.shipping.listZones(c.get("actor"));
20
+ if (!result.ok)
21
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
22
+ return c.json({ data: result.value });
23
+ });
24
+ // @ts-expect-error -- openapi handler union return type
25
+ router.openapi(updateShippingZoneRoute, async (c) => {
26
+ const result = await kernel.services.shipping.updateZone(c.req.param("id"), c.req.valid("json"), c.get("actor"));
27
+ if (!result.ok)
28
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
29
+ return c.json({ data: result.value });
30
+ });
31
+ // @ts-expect-error -- openapi handler union return type
32
+ router.openapi(deleteShippingZoneRoute, async (c) => {
33
+ const result = await kernel.services.shipping.deleteZone(c.req.param("id"), c.get("actor"));
34
+ if (!result.ok)
35
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
36
+ return c.json({ data: result.value });
37
+ });
38
+ // @ts-expect-error -- openapi handler union return type
39
+ router.openapi(createShippingRateRoute, async (c) => {
40
+ const result = await kernel.services.shipping.createRate(c.req.valid("json"), c.get("actor"));
41
+ if (!result.ok)
42
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
43
+ return c.json({ data: result.value }, 201);
44
+ });
45
+ // @ts-expect-error -- openapi handler union return type
46
+ router.openapi(listShippingRatesRoute, async (c) => {
47
+ const zoneId = c.req.query("zoneId");
48
+ const result = await kernel.services.shipping.listRates(zoneId !== undefined ? { zoneId } : undefined, c.get("actor"));
49
+ if (!result.ok)
50
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
51
+ return c.json({ data: result.value });
52
+ });
53
+ // @ts-expect-error -- openapi handler union return type
54
+ router.openapi(updateShippingRateRoute, async (c) => {
55
+ const result = await kernel.services.shipping.updateRate(c.req.param("id"), c.req.valid("json"), c.get("actor"));
56
+ if (!result.ok)
57
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
58
+ return c.json({ data: result.value });
59
+ });
60
+ // @ts-expect-error -- openapi handler union return type
61
+ router.openapi(deleteShippingRateRoute, async (c) => {
62
+ const result = await kernel.services.shipping.deleteRate(c.req.param("id"), c.get("actor"));
63
+ if (!result.ok)
64
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
65
+ return c.json({ data: result.value });
66
+ });
67
+ return router;
68
+ }
@@ -0,0 +1,5 @@
1
+ import { OpenAPIHono } from "@hono/zod-openapi";
2
+ import type { Kernel } from "../../../runtime/kernel.js";
3
+ import { type AppEnv } from "../utils.js";
4
+ export declare function taxRoutes(kernel: Kernel): OpenAPIHono<AppEnv, {}, "/">;
5
+ //# sourceMappingURL=tax.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tax.d.ts","sourceRoot":"","sources":["../../../../src/interfaces/rest/routes/tax.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAWzD,OAAO,EAAE,KAAK,MAAM,EAAqD,MAAM,aAAa,CAAC;AAE7F,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,gCA2EvC"}
@@ -0,0 +1,68 @@
1
+ import { OpenAPIHono } from "@hono/zod-openapi";
2
+ import { createTaxRateRoute, listTaxRatesRoute, updateTaxRateRoute, deleteTaxRateRoute, createTaxClassRoute, listTaxClassesRoute, updateTaxClassRoute, deleteTaxClassRoute, } from "../schemas/tax.js";
3
+ import { mapErrorToResponse, mapErrorToStatus, requirePerm } from "../utils.js";
4
+ export function taxRoutes(kernel) {
5
+ const router = new OpenAPIHono();
6
+ router.use("/rates", requirePerm("tax:manage"));
7
+ router.use("/rates/:id", requirePerm("tax:manage"));
8
+ router.use("/classes", requirePerm("tax:manage"));
9
+ router.use("/classes/:id", requirePerm("tax:manage"));
10
+ // @ts-expect-error -- openapi handler union return type
11
+ router.openapi(createTaxRateRoute, async (c) => {
12
+ const result = await kernel.services.tax.createTaxRate(c.req.valid("json"), c.get("actor"));
13
+ if (!result.ok)
14
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
15
+ return c.json({ data: result.value }, 201);
16
+ });
17
+ // @ts-expect-error -- openapi handler union return type
18
+ router.openapi(listTaxRatesRoute, async (c) => {
19
+ const result = await kernel.services.tax.listTaxRates(c.get("actor"));
20
+ if (!result.ok)
21
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
22
+ return c.json({ data: result.value });
23
+ });
24
+ // @ts-expect-error -- openapi handler union return type
25
+ router.openapi(updateTaxRateRoute, async (c) => {
26
+ const result = await kernel.services.tax.updateTaxRate(c.req.param("id"), c.req.valid("json"), c.get("actor"));
27
+ if (!result.ok)
28
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
29
+ return c.json({ data: result.value });
30
+ });
31
+ // @ts-expect-error -- openapi handler union return type
32
+ router.openapi(deleteTaxRateRoute, async (c) => {
33
+ const result = await kernel.services.tax.deleteTaxRate(c.req.param("id"), c.get("actor"));
34
+ if (!result.ok)
35
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
36
+ return c.json({ data: result.value });
37
+ });
38
+ // ── Product tax classes (issue #57) ───────────────────────────────
39
+ // @ts-expect-error -- openapi handler union return type
40
+ router.openapi(createTaxClassRoute, async (c) => {
41
+ const result = await kernel.services.tax.createTaxClass(c.req.valid("json"), c.get("actor"));
42
+ if (!result.ok)
43
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
44
+ return c.json({ data: result.value }, 201);
45
+ });
46
+ // @ts-expect-error -- openapi handler union return type
47
+ router.openapi(listTaxClassesRoute, async (c) => {
48
+ const result = await kernel.services.tax.listTaxClasses(c.get("actor"));
49
+ if (!result.ok)
50
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
51
+ return c.json({ data: result.value });
52
+ });
53
+ // @ts-expect-error -- openapi handler union return type
54
+ router.openapi(updateTaxClassRoute, async (c) => {
55
+ const result = await kernel.services.tax.updateTaxClass(c.req.param("id"), c.req.valid("json"), c.get("actor"));
56
+ if (!result.ok)
57
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
58
+ return c.json({ data: result.value });
59
+ });
60
+ // @ts-expect-error -- openapi handler union return type
61
+ router.openapi(deleteTaxClassRoute, async (c) => {
62
+ const result = await kernel.services.tax.deleteTaxClass(c.req.param("id"), c.get("actor"));
63
+ if (!result.ok)
64
+ return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
65
+ return c.json({ data: result.value });
66
+ });
67
+ return router;
68
+ }