@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,355 @@
1
+ /**
2
+ * Product tax classes (issue #57) — standard / reduced / zero-rated etc.
3
+ * Sellable entities and variants reference a class by name (`taxClass`
4
+ * column); checkout computes per-line tax from the class rate, with cart
5
+ * discounts pro-rated across lines first. Lines with no class use the org's
6
+ * default class (isDefault). When classes exist for an org they take
7
+ * precedence over region rates and the adapter for line taxation.
8
+ */
9
+ export declare const taxClasses: import("drizzle-orm/pg-core").PgTableWithColumns<{
10
+ name: "tax_classes";
11
+ schema: undefined;
12
+ columns: {
13
+ id: import("drizzle-orm/pg-core").PgColumn<{
14
+ name: "id";
15
+ tableName: "tax_classes";
16
+ dataType: "string";
17
+ columnType: "PgUUID";
18
+ data: string;
19
+ driverParam: string;
20
+ notNull: true;
21
+ hasDefault: true;
22
+ isPrimaryKey: true;
23
+ isAutoincrement: false;
24
+ hasRuntimeDefault: false;
25
+ enumValues: undefined;
26
+ baseColumn: never;
27
+ identity: undefined;
28
+ generated: undefined;
29
+ }, {}, {}>;
30
+ organizationId: import("drizzle-orm/pg-core").PgColumn<{
31
+ name: "organization_id";
32
+ tableName: "tax_classes";
33
+ dataType: "string";
34
+ columnType: "PgText";
35
+ data: string;
36
+ driverParam: string;
37
+ notNull: true;
38
+ hasDefault: false;
39
+ isPrimaryKey: false;
40
+ isAutoincrement: false;
41
+ hasRuntimeDefault: false;
42
+ enumValues: [string, ...string[]];
43
+ baseColumn: never;
44
+ identity: undefined;
45
+ generated: undefined;
46
+ }, {}, {}>;
47
+ name: import("drizzle-orm/pg-core").PgColumn<{
48
+ name: "name";
49
+ tableName: "tax_classes";
50
+ dataType: "string";
51
+ columnType: "PgText";
52
+ data: string;
53
+ driverParam: string;
54
+ notNull: true;
55
+ hasDefault: false;
56
+ isPrimaryKey: false;
57
+ isAutoincrement: false;
58
+ hasRuntimeDefault: false;
59
+ enumValues: [string, ...string[]];
60
+ baseColumn: never;
61
+ identity: undefined;
62
+ generated: undefined;
63
+ }, {}, {}>;
64
+ rateBps: import("drizzle-orm/pg-core").PgColumn<{
65
+ name: "rate_bps";
66
+ tableName: "tax_classes";
67
+ dataType: "number";
68
+ columnType: "PgInteger";
69
+ data: number;
70
+ driverParam: string | number;
71
+ notNull: true;
72
+ hasDefault: false;
73
+ isPrimaryKey: false;
74
+ isAutoincrement: false;
75
+ hasRuntimeDefault: false;
76
+ enumValues: undefined;
77
+ baseColumn: never;
78
+ identity: undefined;
79
+ generated: undefined;
80
+ }, {}, {}>;
81
+ isDefault: import("drizzle-orm/pg-core").PgColumn<{
82
+ name: "is_default";
83
+ tableName: "tax_classes";
84
+ dataType: "boolean";
85
+ columnType: "PgBoolean";
86
+ data: boolean;
87
+ driverParam: boolean;
88
+ notNull: true;
89
+ hasDefault: true;
90
+ isPrimaryKey: false;
91
+ isAutoincrement: false;
92
+ hasRuntimeDefault: false;
93
+ enumValues: undefined;
94
+ baseColumn: never;
95
+ identity: undefined;
96
+ generated: undefined;
97
+ }, {}, {}>;
98
+ isActive: import("drizzle-orm/pg-core").PgColumn<{
99
+ name: "is_active";
100
+ tableName: "tax_classes";
101
+ dataType: "boolean";
102
+ columnType: "PgBoolean";
103
+ data: boolean;
104
+ driverParam: boolean;
105
+ notNull: true;
106
+ hasDefault: true;
107
+ isPrimaryKey: false;
108
+ isAutoincrement: false;
109
+ hasRuntimeDefault: false;
110
+ enumValues: undefined;
111
+ baseColumn: never;
112
+ identity: undefined;
113
+ generated: undefined;
114
+ }, {}, {}>;
115
+ createdAt: import("drizzle-orm/pg-core").PgColumn<{
116
+ name: "created_at";
117
+ tableName: "tax_classes";
118
+ dataType: "date";
119
+ columnType: "PgTimestamp";
120
+ data: Date;
121
+ driverParam: string;
122
+ notNull: true;
123
+ hasDefault: true;
124
+ isPrimaryKey: false;
125
+ isAutoincrement: false;
126
+ hasRuntimeDefault: false;
127
+ enumValues: undefined;
128
+ baseColumn: never;
129
+ identity: undefined;
130
+ generated: undefined;
131
+ }, {}, {}>;
132
+ updatedAt: import("drizzle-orm/pg-core").PgColumn<{
133
+ name: "updated_at";
134
+ tableName: "tax_classes";
135
+ dataType: "date";
136
+ columnType: "PgTimestamp";
137
+ data: Date;
138
+ driverParam: string;
139
+ notNull: true;
140
+ hasDefault: true;
141
+ isPrimaryKey: false;
142
+ isAutoincrement: false;
143
+ hasRuntimeDefault: false;
144
+ enumValues: undefined;
145
+ baseColumn: never;
146
+ identity: undefined;
147
+ generated: undefined;
148
+ }, {}, {}>;
149
+ };
150
+ dialect: "pg";
151
+ }>;
152
+ /**
153
+ * Runtime tax rates (issue #45).
154
+ *
155
+ * Per-region rates in basis points (500 = 5%). When rates exist for an
156
+ * organization and the calculation has a destination address, they take
157
+ * precedence over the configured tax adapter, which remains the fallback.
158
+ * State-specific matches beat country-level matches; multiple matches at
159
+ * the same specificity are summed (e.g. GST + PST).
160
+ */
161
+ export declare const taxRates: import("drizzle-orm/pg-core").PgTableWithColumns<{
162
+ name: "tax_rates";
163
+ schema: undefined;
164
+ columns: {
165
+ id: import("drizzle-orm/pg-core").PgColumn<{
166
+ name: "id";
167
+ tableName: "tax_rates";
168
+ dataType: "string";
169
+ columnType: "PgUUID";
170
+ data: string;
171
+ driverParam: string;
172
+ notNull: true;
173
+ hasDefault: true;
174
+ isPrimaryKey: true;
175
+ isAutoincrement: false;
176
+ hasRuntimeDefault: false;
177
+ enumValues: undefined;
178
+ baseColumn: never;
179
+ identity: undefined;
180
+ generated: undefined;
181
+ }, {}, {}>;
182
+ organizationId: import("drizzle-orm/pg-core").PgColumn<{
183
+ name: "organization_id";
184
+ tableName: "tax_rates";
185
+ dataType: "string";
186
+ columnType: "PgText";
187
+ data: string;
188
+ driverParam: string;
189
+ notNull: true;
190
+ hasDefault: false;
191
+ isPrimaryKey: false;
192
+ isAutoincrement: false;
193
+ hasRuntimeDefault: false;
194
+ enumValues: [string, ...string[]];
195
+ baseColumn: never;
196
+ identity: undefined;
197
+ generated: undefined;
198
+ }, {}, {}>;
199
+ name: import("drizzle-orm/pg-core").PgColumn<{
200
+ name: "name";
201
+ tableName: "tax_rates";
202
+ dataType: "string";
203
+ columnType: "PgText";
204
+ data: string;
205
+ driverParam: string;
206
+ notNull: true;
207
+ hasDefault: false;
208
+ isPrimaryKey: false;
209
+ isAutoincrement: false;
210
+ hasRuntimeDefault: false;
211
+ enumValues: [string, ...string[]];
212
+ baseColumn: never;
213
+ identity: undefined;
214
+ generated: undefined;
215
+ }, {}, {}>;
216
+ country: import("drizzle-orm/pg-core").PgColumn<{
217
+ name: "country";
218
+ tableName: "tax_rates";
219
+ dataType: "string";
220
+ columnType: "PgText";
221
+ data: string;
222
+ driverParam: string;
223
+ notNull: true;
224
+ hasDefault: false;
225
+ isPrimaryKey: false;
226
+ isAutoincrement: false;
227
+ hasRuntimeDefault: false;
228
+ enumValues: [string, ...string[]];
229
+ baseColumn: never;
230
+ identity: undefined;
231
+ generated: undefined;
232
+ }, {}, {}>;
233
+ state: import("drizzle-orm/pg-core").PgColumn<{
234
+ name: "state";
235
+ tableName: "tax_rates";
236
+ dataType: "string";
237
+ columnType: "PgText";
238
+ data: string;
239
+ driverParam: string;
240
+ notNull: false;
241
+ hasDefault: false;
242
+ isPrimaryKey: false;
243
+ isAutoincrement: false;
244
+ hasRuntimeDefault: false;
245
+ enumValues: [string, ...string[]];
246
+ baseColumn: never;
247
+ identity: undefined;
248
+ generated: undefined;
249
+ }, {}, {}>;
250
+ rateBps: import("drizzle-orm/pg-core").PgColumn<{
251
+ name: "rate_bps";
252
+ tableName: "tax_rates";
253
+ dataType: "number";
254
+ columnType: "PgInteger";
255
+ data: number;
256
+ driverParam: string | number;
257
+ notNull: true;
258
+ hasDefault: false;
259
+ isPrimaryKey: false;
260
+ isAutoincrement: false;
261
+ hasRuntimeDefault: false;
262
+ enumValues: undefined;
263
+ baseColumn: never;
264
+ identity: undefined;
265
+ generated: undefined;
266
+ }, {}, {}>;
267
+ appliesToShipping: import("drizzle-orm/pg-core").PgColumn<{
268
+ name: "applies_to_shipping";
269
+ tableName: "tax_rates";
270
+ dataType: "boolean";
271
+ columnType: "PgBoolean";
272
+ data: boolean;
273
+ driverParam: boolean;
274
+ notNull: true;
275
+ hasDefault: true;
276
+ isPrimaryKey: false;
277
+ isAutoincrement: false;
278
+ hasRuntimeDefault: false;
279
+ enumValues: undefined;
280
+ baseColumn: never;
281
+ identity: undefined;
282
+ generated: undefined;
283
+ }, {}, {}>;
284
+ priority: import("drizzle-orm/pg-core").PgColumn<{
285
+ name: "priority";
286
+ tableName: "tax_rates";
287
+ dataType: "number";
288
+ columnType: "PgInteger";
289
+ data: number;
290
+ driverParam: string | number;
291
+ notNull: true;
292
+ hasDefault: true;
293
+ isPrimaryKey: false;
294
+ isAutoincrement: false;
295
+ hasRuntimeDefault: false;
296
+ enumValues: undefined;
297
+ baseColumn: never;
298
+ identity: undefined;
299
+ generated: undefined;
300
+ }, {}, {}>;
301
+ isActive: import("drizzle-orm/pg-core").PgColumn<{
302
+ name: "is_active";
303
+ tableName: "tax_rates";
304
+ dataType: "boolean";
305
+ columnType: "PgBoolean";
306
+ data: boolean;
307
+ driverParam: boolean;
308
+ notNull: true;
309
+ hasDefault: true;
310
+ isPrimaryKey: false;
311
+ isAutoincrement: false;
312
+ hasRuntimeDefault: false;
313
+ enumValues: undefined;
314
+ baseColumn: never;
315
+ identity: undefined;
316
+ generated: undefined;
317
+ }, {}, {}>;
318
+ createdAt: import("drizzle-orm/pg-core").PgColumn<{
319
+ name: "created_at";
320
+ tableName: "tax_rates";
321
+ dataType: "date";
322
+ columnType: "PgTimestamp";
323
+ data: Date;
324
+ driverParam: string;
325
+ notNull: true;
326
+ hasDefault: true;
327
+ isPrimaryKey: false;
328
+ isAutoincrement: false;
329
+ hasRuntimeDefault: false;
330
+ enumValues: undefined;
331
+ baseColumn: never;
332
+ identity: undefined;
333
+ generated: undefined;
334
+ }, {}, {}>;
335
+ updatedAt: import("drizzle-orm/pg-core").PgColumn<{
336
+ name: "updated_at";
337
+ tableName: "tax_rates";
338
+ dataType: "date";
339
+ columnType: "PgTimestamp";
340
+ data: Date;
341
+ driverParam: string;
342
+ notNull: true;
343
+ hasDefault: true;
344
+ isPrimaryKey: false;
345
+ isAutoincrement: false;
346
+ hasRuntimeDefault: false;
347
+ enumValues: undefined;
348
+ baseColumn: never;
349
+ identity: undefined;
350
+ generated: undefined;
351
+ }, {}, {}>;
352
+ };
353
+ dialect: "pg";
354
+ }>;
355
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/modules/tax/schema.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAcpB,CAAC;AAEJ;;;;;;;;GAQG;AACH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoBlB,CAAC"}
@@ -0,0 +1,55 @@
1
+ import { boolean, index, integer, pgTable, text, timestamp, uniqueIndex, uuid } from "drizzle-orm/pg-core";
2
+ import { organization } from "../../auth/auth-schema.js";
3
+ /**
4
+ * Product tax classes (issue #57) — standard / reduced / zero-rated etc.
5
+ * Sellable entities and variants reference a class by name (`taxClass`
6
+ * column); checkout computes per-line tax from the class rate, with cart
7
+ * discounts pro-rated across lines first. Lines with no class use the org's
8
+ * default class (isDefault). When classes exist for an org they take
9
+ * precedence over region rates and the adapter for line taxation.
10
+ */
11
+ export const taxClasses = pgTable("tax_classes", {
12
+ id: uuid("id").defaultRandom().primaryKey(),
13
+ organizationId: text("organization_id")
14
+ .notNull()
15
+ .references(() => organization.id, { onDelete: "cascade" }),
16
+ name: text("name").notNull(),
17
+ // Basis points: 1000 = 10%
18
+ rateBps: integer("rate_bps").notNull(),
19
+ isDefault: boolean("is_default").notNull().default(false),
20
+ isActive: boolean("is_active").notNull().default(true),
21
+ createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(),
22
+ updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull(),
23
+ }, (table) => ({
24
+ orgNameUnique: uniqueIndex("tax_classes_org_name_unique").on(table.organizationId, table.name),
25
+ }));
26
+ /**
27
+ * Runtime tax rates (issue #45).
28
+ *
29
+ * Per-region rates in basis points (500 = 5%). When rates exist for an
30
+ * organization and the calculation has a destination address, they take
31
+ * precedence over the configured tax adapter, which remains the fallback.
32
+ * State-specific matches beat country-level matches; multiple matches at
33
+ * the same specificity are summed (e.g. GST + PST).
34
+ */
35
+ export const taxRates = pgTable("tax_rates", {
36
+ id: uuid("id").defaultRandom().primaryKey(),
37
+ organizationId: text("organization_id")
38
+ .notNull()
39
+ .references(() => organization.id, { onDelete: "cascade" }),
40
+ name: text("name").notNull(),
41
+ // ISO 3166-1 alpha-2, uppercase. "*" matches any country.
42
+ country: text("country").notNull(),
43
+ // Optional state/province code; null = the whole country.
44
+ state: text("state"),
45
+ // Basis points: 500 = 5%, 875 = 8.75%
46
+ rateBps: integer("rate_bps").notNull(),
47
+ appliesToShipping: boolean("applies_to_shipping").notNull().default(true),
48
+ priority: integer("priority").notNull().default(100),
49
+ isActive: boolean("is_active").notNull().default(true),
50
+ createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(),
51
+ updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull(),
52
+ }, (table) => ({
53
+ orgIdx: index("idx_tax_rates_org").on(table.organizationId),
54
+ countryIdx: index("idx_tax_rates_country").on(table.country, table.state),
55
+ }));
@@ -1,12 +1,48 @@
1
+ import type { Actor } from "../../auth/types.js";
2
+ import type { TxContext } from "../../kernel/database/tx-context.js";
1
3
  import { type Result } from "../../kernel/result.js";
2
4
  import type { TaxAdapter, TaxCalculationParams, TaxCalculationResult, TaxReportParams, TaxVoidParams } from "./adapter.js";
5
+ import type { TaxClass, TaxRate, TaxRatesRepository } from "./repository/index.js";
3
6
  interface TaxServiceDeps {
4
7
  adapter: TaxAdapter | undefined;
8
+ repository?: TaxRatesRepository;
5
9
  }
6
10
  export declare class TaxService {
7
11
  private adapter;
12
+ private repository;
8
13
  constructor(deps: TaxServiceDeps);
9
- calculate(params: TaxCalculationParams): Promise<Result<TaxCalculationResult>>;
14
+ /**
15
+ * Calculates tax. Resolution order:
16
+ * 1. Product tax classes (issue #57) — when the org defines active classes,
17
+ * each line taxes by its class (variant taxClass beats entity taxClass;
18
+ * unclassed lines use the default class or 0), with `orderDiscount`
19
+ * pro-rated across lines first. Returns per-line results in `lines`.
20
+ * 2. Runtime tax rates for the org matching `toAddress` (issue #45) —
21
+ * state-specific matches beat country-level; matches at the winning
22
+ * specificity are summed (e.g. GST + PST).
23
+ * 3. The configured tax adapter.
24
+ * 4. Zero tax.
25
+ */
26
+ calculate(params: TaxCalculationParams, orgId?: string, ctx?: TxContext): Promise<Result<TaxCalculationResult>>;
27
+ /** Per-line class-based tax with cart-discount pro-ration (issue #57). */
28
+ private calculateByClasses;
29
+ createTaxClass(input: {
30
+ name: string;
31
+ rateBps: number;
32
+ isDefault?: boolean | undefined;
33
+ isActive?: boolean | undefined;
34
+ }, actor?: Actor | null, ctx?: TxContext): Promise<Result<TaxClass>>;
35
+ listTaxClasses(actor?: Actor | null, ctx?: TxContext): Promise<Result<TaxClass[]>>;
36
+ updateTaxClass(id: string, patch: {
37
+ name?: string | undefined;
38
+ rateBps?: number | undefined;
39
+ isDefault?: boolean | undefined;
40
+ isActive?: boolean | undefined;
41
+ }, actor?: Actor | null, ctx?: TxContext): Promise<Result<TaxClass>>;
42
+ deleteTaxClass(id: string, actor?: Actor | null, ctx?: TxContext): Promise<Result<{
43
+ deleted: true;
44
+ }>>;
45
+ private matchRuntimeRates;
10
46
  reportTransaction(params: TaxReportParams): Promise<Result<{
11
47
  transactionId: string;
12
48
  }>>;
@@ -14,6 +50,29 @@ export declare class TaxService {
14
50
  transactionId: string;
15
51
  }>>;
16
52
  requireConfigured(): Result<TaxAdapter>;
53
+ private requireRepository;
54
+ createTaxRate(input: {
55
+ name: string;
56
+ country: string;
57
+ state?: string | undefined;
58
+ rateBps: number;
59
+ appliesToShipping?: boolean | undefined;
60
+ priority?: number | undefined;
61
+ isActive?: boolean | undefined;
62
+ }, actor?: Actor | null, ctx?: TxContext): Promise<Result<TaxRate>>;
63
+ listTaxRates(actor?: Actor | null, ctx?: TxContext): Promise<Result<TaxRate[]>>;
64
+ updateTaxRate(id: string, patch: {
65
+ name?: string | undefined;
66
+ country?: string | undefined;
67
+ state?: string | null | undefined;
68
+ rateBps?: number | undefined;
69
+ appliesToShipping?: boolean | undefined;
70
+ priority?: number | undefined;
71
+ isActive?: boolean | undefined;
72
+ }, actor?: Actor | null, ctx?: TxContext): Promise<Result<TaxRate>>;
73
+ deleteTaxRate(id: string, actor?: Actor | null, ctx?: TxContext): Promise<Result<{
74
+ deleted: true;
75
+ }>>;
17
76
  }
18
77
  export {};
19
78
  //# sourceMappingURL=service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/modules/tax/service.ts"],"names":[],"mappings":"AACA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EACV,UAAU,EACV,oBAAoB,EACpB,oBAAoB,EACpB,eAAe,EACf,aAAa,EACd,MAAM,cAAc,CAAC;AAEtB,UAAU,cAAc;IACtB,OAAO,EAAE,UAAU,GAAG,SAAS,CAAC;CACjC;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAyB;gBAE5B,IAAI,EAAE,cAAc;IAI1B,SAAS,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAe9E,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAKtF,eAAe,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAKxF,iBAAiB,IAAI,MAAM,CAAC,UAAU,CAAC;CAMxC"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/modules/tax/service.ts"],"names":[],"mappings":"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"}