@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
@@ -0,0 +1,164 @@
1
+ import { z, createRoute } from "@hono/zod-openapi";
2
+ import { errorResponses } from "./shared.js";
3
+
4
+ // ─── Request Schemas ────────────────────────────────────────────────────────
5
+
6
+ export const CreateShippingZoneBodySchema = z.object({
7
+ name: z.string().min(1).openapi({ example: "United States" }),
8
+ countries: z.array(z.string().min(1)).min(1).openapi({ example: ["US"] }),
9
+ states: z.array(z.string().min(1)).optional().openapi({ example: ["NY", "NJ"] }),
10
+ priority: z.number().int().optional(),
11
+ isActive: z.boolean().optional(),
12
+ }).openapi("CreateShippingZoneRequest");
13
+
14
+ export const UpdateShippingZoneBodySchema = z.object({
15
+ name: z.string().min(1).optional(),
16
+ countries: z.array(z.string().min(1)).min(1).optional(),
17
+ states: z.array(z.string().min(1)).optional(),
18
+ priority: z.number().int().optional(),
19
+ isActive: z.boolean().optional(),
20
+ }).openapi("UpdateShippingZoneRequest");
21
+
22
+ export const CreateShippingRateBodySchema = z.object({
23
+ zoneId: z.uuid(),
24
+ name: z.string().min(1).openapi({ example: "Standard" }),
25
+ amount: z.number().int().nonnegative().openapi({ example: 1500, description: "Flat cost in minor units" }),
26
+ currency: z.string().length(3).optional().openapi({ example: "USD" }),
27
+ minSubtotal: z.number().int().nonnegative().optional(),
28
+ maxSubtotal: z.number().int().nonnegative().optional(),
29
+ minWeightGrams: z.number().int().nonnegative().optional(),
30
+ maxWeightGrams: z.number().int().nonnegative().optional(),
31
+ freeShippingThreshold: z.number().int().nonnegative().optional().openapi({ example: 10000, description: "Subtotal at or above which shipping is free" }),
32
+ isActive: z.boolean().optional(),
33
+ }).openapi("CreateShippingRateRequest");
34
+
35
+ export const UpdateShippingRateBodySchema = z.object({
36
+ name: z.string().min(1).optional(),
37
+ amount: z.number().int().nonnegative().optional(),
38
+ currency: z.string().length(3).optional(),
39
+ minSubtotal: z.number().int().nonnegative().nullable().optional(),
40
+ maxSubtotal: z.number().int().nonnegative().nullable().optional(),
41
+ minWeightGrams: z.number().int().nonnegative().nullable().optional(),
42
+ maxWeightGrams: z.number().int().nonnegative().nullable().optional(),
43
+ freeShippingThreshold: z.number().int().nonnegative().nullable().optional(),
44
+ isActive: z.boolean().optional(),
45
+ }).openapi("UpdateShippingRateRequest");
46
+
47
+ // ─── Shared ─────────────────────────────────────────────────────────────────
48
+
49
+ const IdParam = z.object({
50
+ id: z.uuid().openapi({ example: "550e8400-e29b-41d4-a716-446655440000" }),
51
+ });
52
+
53
+ const DataResponse = z.object({ data: z.any() }).openapi("ShippingConfigResponse");
54
+
55
+ // ─── Zone Routes ────────────────────────────────────────────────────────────
56
+
57
+ export const createShippingZoneRoute = createRoute({
58
+ method: "post",
59
+ path: "/zones",
60
+ tags: ["Shipping"],
61
+ summary: "Create a shipping zone",
62
+ request: {
63
+ body: { content: { "application/json": { schema: CreateShippingZoneBodySchema } }, required: true },
64
+ },
65
+ responses: {
66
+ 201: { content: { "application/json": { schema: DataResponse } }, description: "Zone created." },
67
+ ...errorResponses,
68
+ },
69
+ });
70
+
71
+ export const listShippingZonesRoute = createRoute({
72
+ method: "get",
73
+ path: "/zones",
74
+ tags: ["Shipping"],
75
+ summary: "List shipping zones",
76
+ responses: {
77
+ 200: { content: { "application/json": { schema: DataResponse } }, description: "Zones" },
78
+ ...errorResponses,
79
+ },
80
+ });
81
+
82
+ export const updateShippingZoneRoute = createRoute({
83
+ method: "patch",
84
+ path: "/zones/{id}",
85
+ tags: ["Shipping"],
86
+ summary: "Update a shipping zone",
87
+ request: {
88
+ params: IdParam,
89
+ body: { content: { "application/json": { schema: UpdateShippingZoneBodySchema } }, required: true },
90
+ },
91
+ responses: {
92
+ 200: { content: { "application/json": { schema: DataResponse } }, description: "Zone updated." },
93
+ ...errorResponses,
94
+ },
95
+ });
96
+
97
+ export const deleteShippingZoneRoute = createRoute({
98
+ method: "delete",
99
+ path: "/zones/{id}",
100
+ tags: ["Shipping"],
101
+ summary: "Delete a shipping zone (and its rates)",
102
+ request: { params: IdParam },
103
+ responses: {
104
+ 200: { content: { "application/json": { schema: DataResponse } }, description: "Zone deleted." },
105
+ ...errorResponses,
106
+ },
107
+ });
108
+
109
+ // ─── Rate Routes ────────────────────────────────────────────────────────────
110
+
111
+ export const createShippingRateRoute = createRoute({
112
+ method: "post",
113
+ path: "/rates",
114
+ tags: ["Shipping"],
115
+ summary: "Create a shipping rate in a zone",
116
+ request: {
117
+ body: { content: { "application/json": { schema: CreateShippingRateBodySchema } }, required: true },
118
+ },
119
+ responses: {
120
+ 201: { content: { "application/json": { schema: DataResponse } }, description: "Rate created." },
121
+ ...errorResponses,
122
+ },
123
+ });
124
+
125
+ export const listShippingRatesRoute = createRoute({
126
+ method: "get",
127
+ path: "/rates",
128
+ tags: ["Shipping"],
129
+ summary: "List shipping rates",
130
+ request: {
131
+ query: z.object({ zoneId: z.string().optional() }),
132
+ },
133
+ responses: {
134
+ 200: { content: { "application/json": { schema: DataResponse } }, description: "Rates" },
135
+ ...errorResponses,
136
+ },
137
+ });
138
+
139
+ export const updateShippingRateRoute = createRoute({
140
+ method: "patch",
141
+ path: "/rates/{id}",
142
+ tags: ["Shipping"],
143
+ summary: "Update a shipping rate",
144
+ request: {
145
+ params: IdParam,
146
+ body: { content: { "application/json": { schema: UpdateShippingRateBodySchema } }, required: true },
147
+ },
148
+ responses: {
149
+ 200: { content: { "application/json": { schema: DataResponse } }, description: "Rate updated." },
150
+ ...errorResponses,
151
+ },
152
+ });
153
+
154
+ export const deleteShippingRateRoute = createRoute({
155
+ method: "delete",
156
+ path: "/rates/{id}",
157
+ tags: ["Shipping"],
158
+ summary: "Delete a shipping rate",
159
+ request: { params: IdParam },
160
+ responses: {
161
+ 200: { content: { "application/json": { schema: DataResponse } }, description: "Rate deleted." },
162
+ ...errorResponses,
163
+ },
164
+ });
@@ -0,0 +1,148 @@
1
+ import { z, createRoute } from "@hono/zod-openapi";
2
+ import { errorResponses } from "./shared.js";
3
+
4
+ export const CreateTaxRateBodySchema = z.object({
5
+ name: z.string().min(1).openapi({ example: "NY sales tax" }),
6
+ country: z.string().min(1).openapi({ example: "US", description: "ISO 3166-1 alpha-2; \"*\" matches any country" }),
7
+ state: z.string().min(1).optional().openapi({ example: "NY" }),
8
+ rateBps: z.number().int().nonnegative().openapi({ example: 500, description: "Basis points: 500 = 5%" }),
9
+ appliesToShipping: z.boolean().optional(),
10
+ priority: z.number().int().optional(),
11
+ isActive: z.boolean().optional(),
12
+ }).openapi("CreateTaxRateRequest");
13
+
14
+ export const UpdateTaxRateBodySchema = z.object({
15
+ name: z.string().min(1).optional(),
16
+ country: z.string().min(1).optional(),
17
+ state: z.string().min(1).nullable().optional(),
18
+ rateBps: z.number().int().nonnegative().optional(),
19
+ appliesToShipping: z.boolean().optional(),
20
+ priority: z.number().int().optional(),
21
+ isActive: z.boolean().optional(),
22
+ }).openapi("UpdateTaxRateRequest");
23
+
24
+ const IdParam = z.object({
25
+ id: z.uuid().openapi({ example: "550e8400-e29b-41d4-a716-446655440000" }),
26
+ });
27
+
28
+ const DataResponse = z.object({ data: z.any() }).openapi("TaxConfigResponse");
29
+
30
+ export const createTaxRateRoute = createRoute({
31
+ method: "post",
32
+ path: "/rates",
33
+ tags: ["Tax"],
34
+ summary: "Create a tax rate",
35
+ request: {
36
+ body: { content: { "application/json": { schema: CreateTaxRateBodySchema } }, required: true },
37
+ },
38
+ responses: {
39
+ 201: { content: { "application/json": { schema: DataResponse } }, description: "Tax rate created." },
40
+ ...errorResponses,
41
+ },
42
+ });
43
+
44
+ export const listTaxRatesRoute = createRoute({
45
+ method: "get",
46
+ path: "/rates",
47
+ tags: ["Tax"],
48
+ summary: "List tax rates",
49
+ responses: {
50
+ 200: { content: { "application/json": { schema: DataResponse } }, description: "Tax rates" },
51
+ ...errorResponses,
52
+ },
53
+ });
54
+
55
+ export const updateTaxRateRoute = createRoute({
56
+ method: "patch",
57
+ path: "/rates/{id}",
58
+ tags: ["Tax"],
59
+ summary: "Update a tax rate",
60
+ request: {
61
+ params: IdParam,
62
+ body: { content: { "application/json": { schema: UpdateTaxRateBodySchema } }, required: true },
63
+ },
64
+ responses: {
65
+ 200: { content: { "application/json": { schema: DataResponse } }, description: "Tax rate updated." },
66
+ ...errorResponses,
67
+ },
68
+ });
69
+
70
+ export const deleteTaxRateRoute = createRoute({
71
+ method: "delete",
72
+ path: "/rates/{id}",
73
+ tags: ["Tax"],
74
+ summary: "Delete a tax rate",
75
+ request: { params: IdParam },
76
+ responses: {
77
+ 200: { content: { "application/json": { schema: DataResponse } }, description: "Tax rate deleted." },
78
+ ...errorResponses,
79
+ },
80
+ });
81
+
82
+ // ── Product tax classes (issue #57) ─────────────────────────────────────────
83
+
84
+ export const CreateTaxClassBodySchema = z.object({
85
+ name: z.string().min(1).regex(/^[a-z][a-z0-9_-]*$/, "lowercase slug (e.g. standard, zero)"),
86
+ rateBps: z.number().int().nonnegative().openapi({ example: 1800, description: "Basis points: 1800 = 18%" }),
87
+ isDefault: z.boolean().optional().openapi({ description: "Lines with no taxClass use the default class." }),
88
+ isActive: z.boolean().optional(),
89
+ }).openapi("CreateTaxClassRequest");
90
+
91
+ export const UpdateTaxClassBodySchema = z.object({
92
+ name: z.string().min(1).regex(/^[a-z][a-z0-9_-]*$/).optional(),
93
+ rateBps: z.number().int().nonnegative().optional(),
94
+ isDefault: z.boolean().optional(),
95
+ isActive: z.boolean().optional(),
96
+ }).openapi("UpdateTaxClassRequest");
97
+
98
+ const ClassIdParam = z.object({ id: z.uuid() });
99
+
100
+ export const createTaxClassRoute = createRoute({
101
+ method: "post",
102
+ path: "/classes",
103
+ tags: ["Tax"],
104
+ summary: "Create a product tax class",
105
+ request: { body: { content: { "application/json": { schema: CreateTaxClassBodySchema } }, required: true } },
106
+ responses: {
107
+ 201: { content: { "application/json": { schema: DataResponse } }, description: "Tax class created." },
108
+ ...errorResponses,
109
+ },
110
+ });
111
+
112
+ export const listTaxClassesRoute = createRoute({
113
+ method: "get",
114
+ path: "/classes",
115
+ tags: ["Tax"],
116
+ summary: "List product tax classes",
117
+ responses: {
118
+ 200: { content: { "application/json": { schema: DataResponse } }, description: "Tax classes." },
119
+ ...errorResponses,
120
+ },
121
+ });
122
+
123
+ export const updateTaxClassRoute = createRoute({
124
+ method: "patch",
125
+ path: "/classes/{id}",
126
+ tags: ["Tax"],
127
+ summary: "Update a product tax class",
128
+ request: {
129
+ params: ClassIdParam,
130
+ body: { content: { "application/json": { schema: UpdateTaxClassBodySchema } }, required: true },
131
+ },
132
+ responses: {
133
+ 200: { content: { "application/json": { schema: DataResponse } }, description: "Tax class updated." },
134
+ ...errorResponses,
135
+ },
136
+ });
137
+
138
+ export const deleteTaxClassRoute = createRoute({
139
+ method: "delete",
140
+ path: "/classes/{id}",
141
+ tags: ["Tax"],
142
+ summary: "Delete a product tax class",
143
+ request: { params: ClassIdParam },
144
+ responses: {
145
+ 200: { content: { "application/json": { schema: DataResponse } }, description: "Tax class deleted." },
146
+ ...errorResponses,
147
+ },
148
+ });
@@ -43,6 +43,18 @@ export * from "../../modules/webhooks/schema.js";
43
43
  // Fulfillment module
44
44
  export * from "../../modules/fulfillment/schema.js";
45
45
 
46
+ // Shipping module (runtime zones & rates)
47
+ export * from "../../modules/shipping/schema.js";
48
+
49
+ // Tax module (runtime tax rates)
50
+ export * from "../../modules/tax/schema.js";
51
+
52
+ // Settings module (org-scoped runtime settings)
53
+ export * from "../../modules/settings/schema.js";
54
+
55
+ // Documents module (fiscal sequences + issued documents)
56
+ export * from "../../modules/documents/schema.js";
57
+
46
58
  // Jobs (kernel)
47
59
  export * from "../jobs/schema.js";
48
60
 
@@ -11,6 +11,7 @@ export type HookOperation =
11
11
  | "statusChange"
12
12
  | "addItem"
13
13
  | "removeItem"
14
+ | "recover"
14
15
  | "custom";
15
16
 
16
17
  export interface Logger {
@@ -59,6 +59,14 @@ export interface PluginContext {
59
59
  transaction<T>(fn: (tx: PluginDb) => Promise<T>): Promise<T>;
60
60
  };
61
61
  logger: PluginLogger;
62
+ /**
63
+ * The Better Auth instance (issue #51) — lets plugins mint/revoke
64
+ * credentials (e.g. per-shift API keys from a POS PIN login). Present when
65
+ * routes are mounted by createServer; may be absent in bare-kernel setups,
66
+ * so plugins must degrade gracefully. Typed loosely to avoid coupling every
67
+ * plugin to Better Auth's generics — cast to the narrow surface you use.
68
+ */
69
+ auth?: unknown;
62
70
  }
63
71
 
64
72
  const UNSCOPED_WARN_COOLDOWN_MS = 60_000;
@@ -139,6 +147,18 @@ export interface CommercePluginManifest {
139
147
  hooks?: () => PluginHookRegistration[];
140
148
  routes?: (ctx: PluginContext) => PluginRouteRegistration[];
141
149
  analyticsModels?: () => unknown[];
150
+ /**
151
+ * Named API-key scopes this plugin mints credentials under (issue #51),
152
+ * merged into `config.auth.apiKeyScopes`. User-defined scopes with the
153
+ * same name win.
154
+ */
155
+ apiKeyScopes?: () => Record<string, {
156
+ prefix?: string;
157
+ description?: string;
158
+ permissions?: Record<string, string[]>;
159
+ /** Expiry bounds in DAYS (fractions allowed — 1/24 = one hour). */
160
+ keyExpiration?: { minExpiresIn?: number; maxExpiresIn?: number };
161
+ }>;
142
162
  }
143
163
 
144
164
  // ─── Plugin Dependency Tracking ──────────────────────────────────────
@@ -193,6 +213,21 @@ export function defineCommercePlugin(
193
213
  };
194
214
  }
195
215
 
216
+ // 0. API-key scopes — merge into auth.apiKeyScopes (user config wins)
217
+ if (manifest.apiKeyScopes) {
218
+ const scopes = manifest.apiKeyScopes();
219
+ result = {
220
+ ...result,
221
+ auth: {
222
+ ...(result.auth ?? {}),
223
+ apiKeyScopes: {
224
+ ...scopes,
225
+ ...(result.auth?.apiKeyScopes ?? {}),
226
+ },
227
+ },
228
+ } as CommerceConfig;
229
+ }
230
+
196
231
  // 1. Schema — push into customSchemas for kernel to register
197
232
  if (manifest.schema) {
198
233
  const schemas = manifest.schema();
@@ -220,8 +255,8 @@ export function defineCommercePlugin(
220
255
  const pluginRoutes = manifest.routes;
221
256
  result = {
222
257
  ...result,
223
- routes: (app: Hono, kernel: Kernel) => {
224
- existingRoutes?.(app, kernel);
258
+ routes: (app: Hono, kernel: Kernel, auth?: unknown) => {
259
+ existingRoutes?.(app, kernel, auth as never);
225
260
  const k = kernel as {
226
261
  config: CommerceConfig;
227
262
  services: Record<string, unknown>;
@@ -240,6 +275,7 @@ export function defineCommercePlugin(
240
275
  k.logger,
241
276
  ),
242
277
  logger: k.logger,
278
+ ...(auth !== undefined ? { auth } : {}),
243
279
  });
244
280
  for (const route of regs) {
245
281
  // ── Error boundary: wrap handler with plugin context ──
@@ -1,8 +1,10 @@
1
1
  import type { CommerceConfig } from "../../config/types.js";
2
2
  import type { DrizzleDatabase } from "../../kernel/database/drizzle-db.js";
3
3
  import { defineModule } from "../../kernel/module/index.js";
4
+ import type { SettingsService } from "../settings/service.js";
4
5
  import { DrizzleAnalyticsAdapter } from "./drizzle-adapter.js";
5
6
  import { BUILTIN_ANALYTICS_MODELS } from "./models.js";
7
+ import { RetailReportsEngine } from "./reports.js";
6
8
  import { AnalyticsService } from "./service.js";
7
9
 
8
10
  export const analyticsModule = defineModule<
@@ -17,9 +19,17 @@ export const analyticsModule = defineModule<
17
19
  for (const model of BUILTIN_ANALYTICS_MODELS) {
18
20
  adapter.registerModel(model);
19
21
  }
22
+ // Settings is resolved lazily from the shared service container — the
23
+ // settings module may instantiate after analytics.
24
+ const services = deps.services as Record<string, unknown>;
25
+ const reports = new RetailReportsEngine(
26
+ deps.db.db as DrizzleDatabase,
27
+ (orgId, group) => (services.settings as SettingsService).read(orgId, group),
28
+ );
20
29
  return new AnalyticsService({
21
30
  adapter,
22
31
  config: deps.config as CommerceConfig,
32
+ reports,
23
33
  });
24
34
  },
25
35
  });