@porulle/core 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth/setup.d.ts.map +1 -1
- package/dist/auth/setup.js +1 -0
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +5 -0
- package/dist/config/types.d.ts +17 -1
- package/dist/config/types.d.ts.map +1 -1
- package/dist/generated/plugin-manifest.d.ts +3 -0
- package/dist/generated/plugin-manifest.d.ts.map +1 -1
- package/dist/generated/plugin-manifest.js +1 -0
- package/dist/hooks/checkout.d.ts.map +1 -1
- package/dist/hooks/checkout.js +16 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/interfaces/rest/index.d.ts.map +1 -1
- package/dist/interfaces/rest/index.js +12 -0
- package/dist/interfaces/rest/routes/admin/staff.d.ts +12 -0
- package/dist/interfaces/rest/routes/admin/staff.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/admin/staff.js +172 -0
- package/dist/interfaces/rest/routes/analytics.d.ts +5 -0
- package/dist/interfaces/rest/routes/analytics.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/analytics.js +24 -0
- package/dist/interfaces/rest/routes/carts.d.ts.map +1 -1
- package/dist/interfaces/rest/routes/carts.js +39 -2
- package/dist/interfaces/rest/routes/catalog.d.ts.map +1 -1
- package/dist/interfaces/rest/routes/catalog.js +17 -1
- package/dist/interfaces/rest/routes/checkout.d.ts.map +1 -1
- package/dist/interfaces/rest/routes/checkout.js +17 -0
- package/dist/interfaces/rest/routes/documents.d.ts +10 -0
- package/dist/interfaces/rest/routes/documents.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/documents.js +40 -0
- package/dist/interfaces/rest/routes/orders.d.ts.map +1 -1
- package/dist/interfaces/rest/routes/orders.js +122 -1
- package/dist/interfaces/rest/routes/pricing.d.ts.map +1 -1
- package/dist/interfaces/rest/routes/pricing.js +36 -1
- package/dist/interfaces/rest/routes/settings.d.ts +5 -0
- package/dist/interfaces/rest/routes/settings.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/settings.js +50 -0
- package/dist/interfaces/rest/routes/shipping.d.ts +5 -0
- package/dist/interfaces/rest/routes/shipping.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/shipping.js +68 -0
- package/dist/interfaces/rest/routes/tax.d.ts +5 -0
- package/dist/interfaces/rest/routes/tax.d.ts.map +1 -0
- package/dist/interfaces/rest/routes/tax.js +68 -0
- package/dist/interfaces/rest/schemas/admin-staff.d.ts +899 -0
- package/dist/interfaces/rest/schemas/admin-staff.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/admin-staff.js +98 -0
- package/dist/interfaces/rest/schemas/analytics.d.ts +252 -0
- package/dist/interfaces/rest/schemas/analytics.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/analytics.js +33 -0
- package/dist/interfaces/rest/schemas/carts.d.ts +656 -0
- package/dist/interfaces/rest/schemas/carts.d.ts.map +1 -1
- package/dist/interfaces/rest/schemas/carts.js +38 -0
- package/dist/interfaces/rest/schemas/catalog.d.ts +1230 -2
- package/dist/interfaces/rest/schemas/catalog.d.ts.map +1 -1
- package/dist/interfaces/rest/schemas/catalog.js +48 -0
- package/dist/interfaces/rest/schemas/checkout.d.ts +2 -0
- package/dist/interfaces/rest/schemas/checkout.d.ts.map +1 -1
- package/dist/interfaces/rest/schemas/checkout.js +4 -0
- package/dist/interfaces/rest/schemas/customer-portal.d.ts +35 -0
- package/dist/interfaces/rest/schemas/customer-portal.d.ts.map +1 -1
- package/dist/interfaces/rest/schemas/documents.d.ts +509 -0
- package/dist/interfaces/rest/schemas/documents.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/documents.js +65 -0
- package/dist/interfaces/rest/schemas/orders.d.ts +4467 -7
- package/dist/interfaces/rest/schemas/orders.d.ts.map +1 -1
- package/dist/interfaces/rest/schemas/orders.js +330 -0
- package/dist/interfaces/rest/schemas/pricing.d.ts +405 -0
- package/dist/interfaces/rest/schemas/pricing.d.ts.map +1 -1
- package/dist/interfaces/rest/schemas/pricing.js +70 -0
- package/dist/interfaces/rest/schemas/responses.d.ts +156 -0
- package/dist/interfaces/rest/schemas/responses.d.ts.map +1 -1
- package/dist/interfaces/rest/schemas/search.d.ts +17 -0
- package/dist/interfaces/rest/schemas/search.d.ts.map +1 -1
- package/dist/interfaces/rest/schemas/settings.d.ts +397 -0
- package/dist/interfaces/rest/schemas/settings.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/settings.js +79 -0
- package/dist/interfaces/rest/schemas/shipping.d.ts +1093 -0
- package/dist/interfaces/rest/schemas/shipping.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/shipping.js +146 -0
- package/dist/interfaces/rest/schemas/tax.d.ts +1074 -0
- package/dist/interfaces/rest/schemas/tax.d.ts.map +1 -0
- package/dist/interfaces/rest/schemas/tax.js +132 -0
- package/dist/kernel/database/schema.d.ts +4 -0
- package/dist/kernel/database/schema.d.ts.map +1 -1
- package/dist/kernel/database/schema.js +8 -0
- package/dist/kernel/error-mapper.d.ts.map +1 -1
- package/dist/kernel/error-mapper.js +1 -0
- package/dist/kernel/errors.d.ts +5 -0
- package/dist/kernel/errors.d.ts.map +1 -1
- package/dist/kernel/errors.js +9 -0
- package/dist/kernel/hooks/types.d.ts +1 -1
- package/dist/kernel/hooks/types.d.ts.map +1 -1
- package/dist/kernel/plugin/manifest.d.ts +23 -0
- package/dist/kernel/plugin/manifest.d.ts.map +1 -1
- package/dist/kernel/plugin/manifest.js +17 -2
- package/dist/modules/analytics/module.d.ts.map +1 -1
- package/dist/modules/analytics/module.js +6 -0
- package/dist/modules/analytics/reports.d.ts +58 -0
- package/dist/modules/analytics/reports.d.ts.map +1 -0
- package/dist/modules/analytics/reports.js +249 -0
- package/dist/modules/analytics/service.d.ts +10 -0
- package/dist/modules/analytics/service.d.ts.map +1 -1
- package/dist/modules/analytics/service.js +14 -0
- package/dist/modules/cart/repository/index.d.ts +7 -0
- package/dist/modules/cart/repository/index.d.ts.map +1 -1
- package/dist/modules/cart/repository/index.js +25 -1
- package/dist/modules/cart/schema.d.ts +17 -0
- package/dist/modules/cart/schema.d.ts.map +1 -1
- package/dist/modules/cart/schema.js +2 -0
- package/dist/modules/cart/schemas.d.ts +1 -0
- package/dist/modules/cart/schemas.d.ts.map +1 -1
- package/dist/modules/cart/schemas.js +1 -0
- package/dist/modules/cart/service.d.ts +32 -0
- package/dist/modules/cart/service.d.ts.map +1 -1
- package/dist/modules/cart/service.js +58 -0
- package/dist/modules/catalog/entity-service.d.ts +21 -0
- package/dist/modules/catalog/entity-service.d.ts.map +1 -1
- package/dist/modules/catalog/entity-service.js +151 -6
- package/dist/modules/catalog/schema.d.ts +34 -0
- package/dist/modules/catalog/schema.d.ts.map +1 -1
- package/dist/modules/catalog/schema.js +5 -0
- package/dist/modules/catalog/schemas.d.ts +15 -1
- package/dist/modules/catalog/schemas.d.ts.map +1 -1
- package/dist/modules/catalog/schemas.js +17 -1
- package/dist/modules/catalog/service.d.ts +43 -1
- package/dist/modules/catalog/service.d.ts.map +1 -1
- package/dist/modules/catalog/service.js +6 -0
- package/dist/modules/documents/module.d.ts +7 -0
- package/dist/modules/documents/module.d.ts.map +1 -0
- package/dist/modules/documents/module.js +12 -0
- package/dist/modules/documents/pdf.d.ts +25 -0
- package/dist/modules/documents/pdf.d.ts.map +1 -0
- package/dist/modules/documents/pdf.js +80 -0
- package/dist/modules/documents/render.d.ts +32 -0
- package/dist/modules/documents/render.d.ts.map +1 -0
- package/dist/modules/documents/render.js +190 -0
- package/dist/modules/documents/repository/index.d.ts +25 -0
- package/dist/modules/documents/repository/index.d.ts.map +1 -0
- package/dist/modules/documents/repository/index.js +47 -0
- package/dist/modules/documents/schema.d.ts +214 -0
- package/dist/modules/documents/schema.d.ts.map +1 -0
- package/dist/modules/documents/schema.js +42 -0
- package/dist/modules/documents/service.d.ts +51 -0
- package/dist/modules/documents/service.d.ts.map +1 -0
- package/dist/modules/documents/service.js +119 -0
- package/dist/modules/fulfillment/service.d.ts +18 -0
- package/dist/modules/fulfillment/service.d.ts.map +1 -1
- package/dist/modules/fulfillment/service.js +85 -1
- package/dist/modules/media/service.d.ts +18 -0
- package/dist/modules/media/service.d.ts.map +1 -1
- package/dist/modules/media/service.js +26 -0
- package/dist/modules/orders/repository/index.d.ts +18 -1
- package/dist/modules/orders/repository/index.d.ts.map +1 -1
- package/dist/modules/orders/repository/index.js +86 -1
- package/dist/modules/orders/schema.d.ts +374 -0
- package/dist/modules/orders/schema.d.ts.map +1 -1
- package/dist/modules/orders/schema.js +52 -1
- package/dist/modules/orders/service.d.ts +102 -2
- package/dist/modules/orders/service.d.ts.map +1 -1
- package/dist/modules/orders/service.js +494 -23
- package/dist/modules/pricing/repository/index.d.ts +5 -0
- package/dist/modules/pricing/repository/index.d.ts.map +1 -1
- package/dist/modules/pricing/repository/index.js +19 -0
- package/dist/modules/pricing/service.d.ts +18 -0
- package/dist/modules/pricing/service.d.ts.map +1 -1
- package/dist/modules/pricing/service.js +57 -1
- package/dist/modules/settings/module.d.ts +6 -0
- package/dist/modules/settings/module.d.ts.map +1 -0
- package/dist/modules/settings/module.js +11 -0
- package/dist/modules/settings/repository/index.d.ts +16 -0
- package/dist/modules/settings/repository/index.d.ts.map +1 -0
- package/dist/modules/settings/repository/index.js +41 -0
- package/dist/modules/settings/schema.d.ts +121 -0
- package/dist/modules/settings/schema.d.ts.map +1 -0
- package/dist/modules/settings/schema.js +24 -0
- package/dist/modules/settings/service.d.ts +26 -0
- package/dist/modules/settings/service.d.ts.map +1 -0
- package/dist/modules/settings/service.js +51 -0
- package/dist/modules/shipping/calculator.d.ts +5 -0
- package/dist/modules/shipping/calculator.d.ts.map +1 -1
- package/dist/modules/shipping/calculator.js +10 -0
- package/dist/modules/shipping/module.d.ts +5 -1
- package/dist/modules/shipping/module.d.ts.map +1 -1
- package/dist/modules/shipping/module.js +4 -1
- package/dist/modules/shipping/repository/index.d.ts +27 -2
- package/dist/modules/shipping/repository/index.d.ts.map +1 -1
- package/dist/modules/shipping/repository/index.js +105 -1
- package/dist/modules/shipping/schema.d.ts +419 -0
- package/dist/modules/shipping/schema.d.ts.map +1 -0
- package/dist/modules/shipping/schema.js +56 -0
- package/dist/modules/shipping/service.d.ts +54 -0
- package/dist/modules/shipping/service.d.ts.map +1 -1
- package/dist/modules/shipping/service.js +161 -2
- package/dist/modules/tax/adapter.d.ts +13 -0
- package/dist/modules/tax/adapter.d.ts.map +1 -1
- package/dist/modules/tax/module.d.ts +5 -1
- package/dist/modules/tax/module.d.ts.map +1 -1
- package/dist/modules/tax/module.js +4 -1
- package/dist/modules/tax/repository/index.d.ts +38 -2
- package/dist/modules/tax/repository/index.d.ts.map +1 -1
- package/dist/modules/tax/repository/index.js +138 -1
- package/dist/modules/tax/schema.d.ts +355 -0
- package/dist/modules/tax/schema.d.ts.map +1 -0
- package/dist/modules/tax/schema.js +55 -0
- package/dist/modules/tax/service.d.ts +60 -1
- package/dist/modules/tax/service.d.ts.map +1 -1
- package/dist/modules/tax/service.js +227 -2
- package/dist/runtime/kernel-modules.d.ts +15 -2
- package/dist/runtime/kernel-modules.d.ts.map +1 -1
- package/dist/runtime/kernel-modules.js +4 -0
- package/dist/runtime/kernel-types.d.ts +5 -1
- package/dist/runtime/kernel-types.d.ts.map +1 -1
- package/dist/runtime/kernel-types.js +2 -0
- package/dist/runtime/server.d.ts.map +1 -1
- package/dist/runtime/server.js +35 -3
- package/dist/test-utils/create-plugin-test-app.d.ts +3 -0
- package/dist/test-utils/create-plugin-test-app.d.ts.map +1 -1
- package/dist/test-utils/create-plugin-test-app.js +15 -3
- package/dist/test-utils/rest-api-test-utils.d.ts.map +1 -1
- package/dist/test-utils/rest-api-test-utils.js +6 -0
- package/package.json +3 -3
- package/src/auth/setup.ts +1 -0
- package/src/config/defaults.ts +5 -0
- package/src/config/types.ts +17 -1
- package/src/generated/plugin-capabilities.d.ts +1 -0
- package/src/generated/plugin-manifest.ts +1 -0
- package/src/generated/plugin-repositories.d.ts +1 -0
- package/src/hooks/checkout.ts +25 -3
- package/src/index.ts +1 -0
- package/src/interfaces/rest/index.ts +12 -0
- package/src/interfaces/rest/routes/admin/staff.ts +218 -0
- package/src/interfaces/rest/routes/analytics.ts +33 -0
- package/src/interfaces/rest/routes/carts.ts +52 -2
- package/src/interfaces/rest/routes/catalog.ts +34 -0
- package/src/interfaces/rest/routes/checkout.ts +22 -0
- package/src/interfaces/rest/routes/documents.ts +61 -0
- package/src/interfaces/rest/routes/orders.ts +172 -1
- package/src/interfaces/rest/routes/pricing.ts +44 -1
- package/src/interfaces/rest/routes/settings.ts +61 -0
- package/src/interfaces/rest/routes/shipping.ts +92 -0
- package/src/interfaces/rest/routes/tax.ts +90 -0
- package/src/interfaces/rest/schemas/admin-staff.ts +110 -0
- package/src/interfaces/rest/schemas/analytics.ts +39 -0
- package/src/interfaces/rest/schemas/carts.ts +40 -0
- package/src/interfaces/rest/schemas/catalog.ts +53 -0
- package/src/interfaces/rest/schemas/checkout.ts +4 -0
- package/src/interfaces/rest/schemas/documents.ts +72 -0
- package/src/interfaces/rest/schemas/orders.ts +361 -0
- package/src/interfaces/rest/schemas/pricing.ts +75 -0
- package/src/interfaces/rest/schemas/settings.ts +93 -0
- package/src/interfaces/rest/schemas/shipping.ts +164 -0
- package/src/interfaces/rest/schemas/tax.ts +148 -0
- package/src/kernel/database/schema.ts +12 -0
- package/src/kernel/error-mapper.ts +1 -0
- package/src/kernel/errors.ts +11 -0
- package/src/kernel/hooks/types.ts +1 -0
- package/src/kernel/plugin/manifest.ts +38 -2
- package/src/modules/analytics/module.ts +10 -0
- package/src/modules/analytics/reports.ts +311 -0
- package/src/modules/analytics/service.ts +23 -0
- package/src/modules/cart/repository/index.ts +30 -1
- package/src/modules/cart/schema.ts +2 -0
- package/src/modules/cart/schemas.ts +1 -0
- package/src/modules/cart/service.ts +101 -0
- package/src/modules/catalog/entity-service.ts +195 -6
- package/src/modules/catalog/schema.ts +5 -0
- package/src/modules/catalog/schemas.ts +18 -1
- package/src/modules/catalog/service.ts +32 -2
- package/src/modules/documents/module.ts +19 -0
- package/src/modules/documents/pdf.ts +101 -0
- package/src/modules/documents/render.ts +231 -0
- package/src/modules/documents/repository/index.ts +68 -0
- package/src/modules/documents/schema.ts +44 -0
- package/src/modules/documents/service.ts +176 -0
- package/src/modules/fulfillment/service.ts +139 -1
- package/src/modules/media/service.ts +40 -0
- package/src/modules/orders/repository/index.ts +127 -1
- package/src/modules/orders/schema.ts +54 -1
- package/src/modules/orders/service.ts +739 -24
- package/src/modules/pricing/repository/index.ts +34 -0
- package/src/modules/pricing/service.ts +100 -1
- package/src/modules/settings/module.ts +18 -0
- package/src/modules/settings/repository/index.ts +59 -0
- package/src/modules/settings/schema.ts +25 -0
- package/src/modules/settings/service.ts +82 -0
- package/src/modules/shipping/calculator.ts +27 -0
- package/src/modules/shipping/module.ts +6 -2
- package/src/modules/shipping/repository/index.ts +136 -2
- package/src/modules/shipping/schema.ts +58 -0
- package/src/modules/shipping/service.ts +260 -1
- package/src/modules/tax/adapter.ts +9 -0
- package/src/modules/tax/module.ts +6 -2
- package/src/modules/tax/repository/index.ts +169 -2
- package/src/modules/tax/schema.ts +57 -0
- package/src/modules/tax/service.ts +313 -2
- package/src/runtime/kernel-modules.ts +4 -0
- package/src/runtime/kernel-types.ts +6 -0
- package/src/runtime/server.ts +36 -3
- package/src/test-utils/create-plugin-test-app.ts +17 -4
- package/src/test-utils/rest-api-test-utils.ts +6 -0
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { OpenAPIHono } from "@hono/zod-openapi";
|
|
2
2
|
import type { Kernel } from "../../../runtime/kernel.js";
|
|
3
|
-
import { changeOrderStatusRoute, listOrdersRoute, orderLookupRoute, getOrderRoute, getOrderFulfillmentsRoute } from "../schemas/orders.js";
|
|
3
|
+
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";
|
|
4
4
|
import { type AppEnv, isUUID, mapErrorToResponse, mapErrorToStatus, parsePagination } from "../utils.js";
|
|
5
|
+
import type { CreateOrderInput } from "../../../modules/orders/service.js";
|
|
5
6
|
|
|
6
7
|
export function orderRoutes(kernel: Kernel) {
|
|
7
8
|
const router = new OpenAPIHono<AppEnv>();
|
|
@@ -59,6 +60,150 @@ export function orderRoutes(kernel: Kernel) {
|
|
|
59
60
|
return c.json({ data: result.value });
|
|
60
61
|
});
|
|
61
62
|
|
|
63
|
+
// @ts-expect-error -- openapi handler union return type
|
|
64
|
+
router.openapi(createOrderRoute, async (c) => {
|
|
65
|
+
const body = c.req.valid("json") as CreateOrderInput;
|
|
66
|
+
const result = await kernel.services.orders.create(body, c.get("actor"));
|
|
67
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
68
|
+
return c.json({ data: result.value }, 201);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// @ts-expect-error -- openapi handler union return type
|
|
72
|
+
router.openapi(refundOrderRoute, async (c) => {
|
|
73
|
+
const body = c.req.valid("json") as { amount?: number; reason?: string } | undefined;
|
|
74
|
+
const result = await kernel.services.orders.refund(
|
|
75
|
+
c.req.param("id"),
|
|
76
|
+
c.get("actor"),
|
|
77
|
+
body?.reason ?? "refunded",
|
|
78
|
+
undefined,
|
|
79
|
+
body?.amount !== undefined ? { amount: body.amount } : undefined,
|
|
80
|
+
);
|
|
81
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
82
|
+
return c.json({ data: result.value });
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// ── Notes + activity timeline (issue #56) ──────────────────────────
|
|
86
|
+
|
|
87
|
+
// @ts-expect-error -- openapi handler union return type
|
|
88
|
+
router.openapi(createOrderNoteRoute, async (c) => {
|
|
89
|
+
const body = c.req.valid("json") as { body: string; pinned?: boolean };
|
|
90
|
+
const result = await kernel.services.orders.addNote(c.req.param("id"), body, c.get("actor"));
|
|
91
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
92
|
+
return c.json({ data: result.value }, 201);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// @ts-expect-error -- openapi handler union return type
|
|
96
|
+
router.openapi(listOrderNotesRoute, async (c) => {
|
|
97
|
+
const result = await kernel.services.orders.listNotes(c.req.param("id"), c.get("actor"));
|
|
98
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
99
|
+
return c.json({ data: result.value });
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// @ts-expect-error -- openapi handler union return type
|
|
103
|
+
router.openapi(deleteOrderNoteRoute, async (c) => {
|
|
104
|
+
const result = await kernel.services.orders.deleteNote(
|
|
105
|
+
c.req.param("id"),
|
|
106
|
+
c.req.param("noteId"),
|
|
107
|
+
c.get("actor"),
|
|
108
|
+
);
|
|
109
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
110
|
+
return c.json({ data: result.value });
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// @ts-expect-error -- openapi handler union return type
|
|
114
|
+
router.openapi(orderTimelineRoute, async (c) => {
|
|
115
|
+
const result = await kernel.services.orders.timeline(c.req.param("id"), c.get("actor"));
|
|
116
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
117
|
+
return c.json({ data: result.value });
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// ── Line-level refunds (issue #52) ─────────────────────────────────
|
|
121
|
+
|
|
122
|
+
// @ts-expect-error -- openapi handler union return type
|
|
123
|
+
router.openapi(refundCapStatusRoute, async (c) => {
|
|
124
|
+
const result = await kernel.services.orders.refundCapStatus(c.get("actor"));
|
|
125
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
126
|
+
return c.json({ data: result.value });
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// @ts-expect-error -- openapi handler union return type
|
|
130
|
+
router.openapi(refundOrderLinesRoute, async (c) => {
|
|
131
|
+
const body = c.req.valid("json") as { lines: Array<{ lineItemId: string; quantity: number }>; reason?: string };
|
|
132
|
+
const result = await kernel.services.orders.refundLines(
|
|
133
|
+
c.req.param("id"),
|
|
134
|
+
body,
|
|
135
|
+
c.get("actor"),
|
|
136
|
+
);
|
|
137
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
138
|
+
return c.json({ data: result.value }, 201);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// @ts-expect-error -- openapi handler union return type
|
|
142
|
+
router.openapi(undoOrderRefundRoute, async (c) => {
|
|
143
|
+
const result = await kernel.services.orders.undoRefund(
|
|
144
|
+
c.req.param("id"),
|
|
145
|
+
c.req.param("refundId"),
|
|
146
|
+
c.get("actor"),
|
|
147
|
+
);
|
|
148
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
149
|
+
return c.json({ data: result.value });
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// @ts-expect-error -- openapi handler union return type
|
|
153
|
+
router.openapi(listOrderRefundsRoute, async (c) => {
|
|
154
|
+
const result = await kernel.services.orders.listRefunds(c.req.param("id"), c.get("actor"));
|
|
155
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
156
|
+
return c.json({ data: result.value });
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// @ts-expect-error -- openapi handler union return type
|
|
160
|
+
router.openapi(captureOrderRoute, async (c) => {
|
|
161
|
+
const body = c.req.valid("json") as { amount?: number } | undefined;
|
|
162
|
+
const result = await kernel.services.orders.capture(
|
|
163
|
+
c.req.param("id"),
|
|
164
|
+
c.get("actor"),
|
|
165
|
+
body?.amount !== undefined ? { amount: body.amount } : undefined,
|
|
166
|
+
);
|
|
167
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
168
|
+
return c.json({ data: result.value });
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
// @ts-expect-error -- openapi handler union return type
|
|
172
|
+
router.openapi(addOrderLineItemRoute, async (c) => {
|
|
173
|
+
const body = c.req.valid("json");
|
|
174
|
+
const result = await kernel.services.orders.addLineItem(
|
|
175
|
+
c.req.param("id"),
|
|
176
|
+
body,
|
|
177
|
+
c.get("actor"),
|
|
178
|
+
);
|
|
179
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
180
|
+
return c.json({ data: result.value }, 201);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
// @ts-expect-error -- openapi handler union return type
|
|
184
|
+
router.openapi(updateOrderLineItemRoute, async (c) => {
|
|
185
|
+
const body = c.req.valid("json");
|
|
186
|
+
const result = await kernel.services.orders.updateOrderLineItem(
|
|
187
|
+
c.req.param("id"),
|
|
188
|
+
c.req.param("lineItemId"),
|
|
189
|
+
body,
|
|
190
|
+
c.get("actor"),
|
|
191
|
+
);
|
|
192
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
193
|
+
return c.json({ data: result.value });
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
// @ts-expect-error -- openapi handler union return type
|
|
197
|
+
router.openapi(removeOrderLineItemRoute, async (c) => {
|
|
198
|
+
const result = await kernel.services.orders.removeLineItem(
|
|
199
|
+
c.req.param("id"),
|
|
200
|
+
c.req.param("lineItemId"),
|
|
201
|
+
c.get("actor"),
|
|
202
|
+
);
|
|
203
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
204
|
+
return c.json({ data: result.value });
|
|
205
|
+
});
|
|
206
|
+
|
|
62
207
|
// @ts-expect-error -- openapi() enforces strict response typing but our handler
|
|
63
208
|
// returns union responses (200 | 400 | 404). The route definition documents the
|
|
64
209
|
// contract; the handler returns dynamic status.
|
|
@@ -77,6 +222,32 @@ export function orderRoutes(kernel: Kernel) {
|
|
|
77
222
|
return c.json({ data: result.value });
|
|
78
223
|
});
|
|
79
224
|
|
|
225
|
+
// @ts-expect-error -- openapi handler union return type
|
|
226
|
+
router.openapi(createOrderFulfillmentRoute, async (c) => {
|
|
227
|
+
const actor = c.get("actor");
|
|
228
|
+
const orderId = c.req.param("id");
|
|
229
|
+
|
|
230
|
+
// Verify the order exists and the actor has access before recording
|
|
231
|
+
const orderResult = await kernel.services.orders.getById(orderId, actor);
|
|
232
|
+
if (!orderResult.ok) return c.json(mapErrorToResponse(orderResult.error), mapErrorToStatus(orderResult.error));
|
|
233
|
+
|
|
234
|
+
const body = c.req.valid("json") as {
|
|
235
|
+
lineItems: Array<{ orderLineItemId: string; quantity: number }>;
|
|
236
|
+
carrier?: string;
|
|
237
|
+
trackingNumber?: string;
|
|
238
|
+
trackingUrl?: string;
|
|
239
|
+
type?: string;
|
|
240
|
+
status?: string;
|
|
241
|
+
metadata?: Record<string, unknown>;
|
|
242
|
+
};
|
|
243
|
+
const result = await kernel.services.fulfillment.createFulfillment(
|
|
244
|
+
{ ...body, orderId: orderResult.value.id },
|
|
245
|
+
actor,
|
|
246
|
+
);
|
|
247
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
248
|
+
return c.json({ data: result.value }, 201);
|
|
249
|
+
});
|
|
250
|
+
|
|
80
251
|
// @ts-expect-error -- openapi handler union return type
|
|
81
252
|
router.openapi(getOrderFulfillmentsRoute, async (c) => {
|
|
82
253
|
const orderId = c.req.param("id");
|
|
@@ -4,7 +4,7 @@ import { CommerceValidationError } from "../../../kernel/errors.js";
|
|
|
4
4
|
import type { DrizzleDatabase } from "../../../kernel/database/drizzle-db.js";
|
|
5
5
|
import { CatalogRepository } from "../../../modules/catalog/repository/index.js";
|
|
6
6
|
import type { Kernel } from "../../../runtime/kernel.js";
|
|
7
|
-
import { setBasePriceRoute, createModifierRoute, listPricesRoute } from "../schemas/pricing.js";
|
|
7
|
+
import { setBasePriceRoute, createModifierRoute, listPricesRoute, listModifiersRoute, updateModifierRoute, deleteModifierRoute } from "../schemas/pricing.js";
|
|
8
8
|
import { type AppEnv, mapErrorToResponse, mapErrorToStatus, requirePerm } from "../utils.js";
|
|
9
9
|
|
|
10
10
|
export function pricingRoutes(kernel: Kernel) {
|
|
@@ -45,6 +45,49 @@ export function pricingRoutes(kernel: Kernel) {
|
|
|
45
45
|
});
|
|
46
46
|
|
|
47
47
|
router.use("/modifiers", requirePerm("pricing:manage"));
|
|
48
|
+
router.use("/modifiers/:id", requirePerm("pricing:manage"));
|
|
49
|
+
|
|
50
|
+
// @ts-expect-error -- openapi handler union return type
|
|
51
|
+
router.openapi(listModifiersRoute, async (c) => {
|
|
52
|
+
const actor = c.get("actor");
|
|
53
|
+
const entityId = c.req.query("entityId");
|
|
54
|
+
const currency = c.req.query("currency");
|
|
55
|
+
const active = c.req.query("active");
|
|
56
|
+
|
|
57
|
+
const result = await kernel.services.pricing.listModifiers({
|
|
58
|
+
...(entityId !== undefined ? { entityId } : {}),
|
|
59
|
+
...(currency !== undefined ? { currency } : {}),
|
|
60
|
+
...(active === "true" ? { active: true } : {}),
|
|
61
|
+
}, actor);
|
|
62
|
+
if (!result.ok) {
|
|
63
|
+
return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
64
|
+
}
|
|
65
|
+
return c.json({ data: result.value });
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// @ts-expect-error -- openapi handler union return type
|
|
69
|
+
router.openapi(updateModifierRoute, async (c) => {
|
|
70
|
+
const actor = c.get("actor");
|
|
71
|
+
const result = await kernel.services.pricing.updateModifier(
|
|
72
|
+
c.req.param("id"),
|
|
73
|
+
c.req.valid("json"),
|
|
74
|
+
actor,
|
|
75
|
+
);
|
|
76
|
+
if (!result.ok) {
|
|
77
|
+
return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
78
|
+
}
|
|
79
|
+
return c.json({ data: result.value });
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// @ts-expect-error -- openapi handler union return type
|
|
83
|
+
router.openapi(deleteModifierRoute, async (c) => {
|
|
84
|
+
const actor = c.get("actor");
|
|
85
|
+
const result = await kernel.services.pricing.deleteModifier(c.req.param("id"), actor);
|
|
86
|
+
if (!result.ok) {
|
|
87
|
+
return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
88
|
+
}
|
|
89
|
+
return c.json({ data: result.value });
|
|
90
|
+
});
|
|
48
91
|
|
|
49
92
|
// @ts-expect-error -- openapi() enforces strict response typing but our handler
|
|
50
93
|
// returns union responses (201 | 400 | 422). The route definition documents the
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { OpenAPIHono } from "@hono/zod-openapi";
|
|
2
|
+
import type { Kernel } from "../../../runtime/kernel.js";
|
|
3
|
+
import {
|
|
4
|
+
KNOWN_GROUP_SCHEMAS,
|
|
5
|
+
getAllSettingsRoute,
|
|
6
|
+
getSettingsGroupRoute,
|
|
7
|
+
patchSettingsGroupRoute,
|
|
8
|
+
} from "../schemas/settings.js";
|
|
9
|
+
import { type AppEnv, mapErrorToResponse, mapErrorToStatus, requirePerm } from "../utils.js";
|
|
10
|
+
|
|
11
|
+
export function settingsRoutes(kernel: Kernel) {
|
|
12
|
+
const router = new OpenAPIHono<AppEnv>();
|
|
13
|
+
|
|
14
|
+
router.use("/", requirePerm("settings:manage"));
|
|
15
|
+
router.use("/:group", requirePerm("settings:manage"));
|
|
16
|
+
|
|
17
|
+
// @ts-expect-error -- openapi handler union return type
|
|
18
|
+
router.openapi(getAllSettingsRoute, async (c) => {
|
|
19
|
+
const result = await kernel.services.settings.getAll(c.get("actor"));
|
|
20
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
21
|
+
return c.json({ data: result.value });
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// @ts-expect-error -- openapi handler union return type
|
|
25
|
+
router.openapi(getSettingsGroupRoute, async (c) => {
|
|
26
|
+
const result = await kernel.services.settings.getGroup(c.req.param("group"), c.get("actor"));
|
|
27
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
28
|
+
return c.json({ data: result.value });
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// @ts-expect-error -- openapi handler union return type
|
|
32
|
+
router.openapi(patchSettingsGroupRoute, async (c) => {
|
|
33
|
+
const group = c.req.param("group");
|
|
34
|
+
const body = c.req.valid("json");
|
|
35
|
+
|
|
36
|
+
// Known groups get typed validation; unknown groups accept any object.
|
|
37
|
+
const groupSchema = KNOWN_GROUP_SCHEMAS[group];
|
|
38
|
+
if (groupSchema) {
|
|
39
|
+
const parsed = groupSchema.safeParse(body);
|
|
40
|
+
if (!parsed.success) {
|
|
41
|
+
const isProd = process.env.NODE_ENV === "production";
|
|
42
|
+
return c.json({
|
|
43
|
+
error: {
|
|
44
|
+
code: "VALIDATION_FAILED",
|
|
45
|
+
message: isProd
|
|
46
|
+
? "Invalid input."
|
|
47
|
+
: parsed.error.issues
|
|
48
|
+
.map((i) => `${i.path.join(".")}: ${i.message}`)
|
|
49
|
+
.join("; "),
|
|
50
|
+
},
|
|
51
|
+
}, 422);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const result = await kernel.services.settings.updateGroup(group, body, c.get("actor"));
|
|
56
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
57
|
+
return c.json({ data: result.value });
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
return router;
|
|
61
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { OpenAPIHono } from "@hono/zod-openapi";
|
|
2
|
+
import type { Kernel } from "../../../runtime/kernel.js";
|
|
3
|
+
import {
|
|
4
|
+
createShippingZoneRoute,
|
|
5
|
+
listShippingZonesRoute,
|
|
6
|
+
updateShippingZoneRoute,
|
|
7
|
+
deleteShippingZoneRoute,
|
|
8
|
+
createShippingRateRoute,
|
|
9
|
+
listShippingRatesRoute,
|
|
10
|
+
updateShippingRateRoute,
|
|
11
|
+
deleteShippingRateRoute,
|
|
12
|
+
} from "../schemas/shipping.js";
|
|
13
|
+
import { type AppEnv, mapErrorToResponse, mapErrorToStatus, requirePerm } from "../utils.js";
|
|
14
|
+
|
|
15
|
+
export function shippingRoutes(kernel: Kernel) {
|
|
16
|
+
const router = new OpenAPIHono<AppEnv>();
|
|
17
|
+
|
|
18
|
+
router.use("/zones", requirePerm("shipping:manage"));
|
|
19
|
+
router.use("/zones/:id", requirePerm("shipping:manage"));
|
|
20
|
+
router.use("/rates", requirePerm("shipping:manage"));
|
|
21
|
+
router.use("/rates/:id", requirePerm("shipping:manage"));
|
|
22
|
+
|
|
23
|
+
// @ts-expect-error -- openapi handler union return type
|
|
24
|
+
router.openapi(createShippingZoneRoute, async (c) => {
|
|
25
|
+
const result = await kernel.services.shipping.createZone(c.req.valid("json"), c.get("actor"));
|
|
26
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
27
|
+
return c.json({ data: result.value }, 201);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// @ts-expect-error -- openapi handler union return type
|
|
31
|
+
router.openapi(listShippingZonesRoute, async (c) => {
|
|
32
|
+
const result = await kernel.services.shipping.listZones(c.get("actor"));
|
|
33
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
34
|
+
return c.json({ data: result.value });
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// @ts-expect-error -- openapi handler union return type
|
|
38
|
+
router.openapi(updateShippingZoneRoute, async (c) => {
|
|
39
|
+
const result = await kernel.services.shipping.updateZone(
|
|
40
|
+
c.req.param("id"),
|
|
41
|
+
c.req.valid("json"),
|
|
42
|
+
c.get("actor"),
|
|
43
|
+
);
|
|
44
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
45
|
+
return c.json({ data: result.value });
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// @ts-expect-error -- openapi handler union return type
|
|
49
|
+
router.openapi(deleteShippingZoneRoute, async (c) => {
|
|
50
|
+
const result = await kernel.services.shipping.deleteZone(c.req.param("id"), c.get("actor"));
|
|
51
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
52
|
+
return c.json({ data: result.value });
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// @ts-expect-error -- openapi handler union return type
|
|
56
|
+
router.openapi(createShippingRateRoute, async (c) => {
|
|
57
|
+
const result = await kernel.services.shipping.createRate(c.req.valid("json"), c.get("actor"));
|
|
58
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
59
|
+
return c.json({ data: result.value }, 201);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// @ts-expect-error -- openapi handler union return type
|
|
63
|
+
router.openapi(listShippingRatesRoute, async (c) => {
|
|
64
|
+
const zoneId = c.req.query("zoneId");
|
|
65
|
+
const result = await kernel.services.shipping.listRates(
|
|
66
|
+
zoneId !== undefined ? { zoneId } : undefined,
|
|
67
|
+
c.get("actor"),
|
|
68
|
+
);
|
|
69
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
70
|
+
return c.json({ data: result.value });
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// @ts-expect-error -- openapi handler union return type
|
|
74
|
+
router.openapi(updateShippingRateRoute, async (c) => {
|
|
75
|
+
const result = await kernel.services.shipping.updateRate(
|
|
76
|
+
c.req.param("id"),
|
|
77
|
+
c.req.valid("json"),
|
|
78
|
+
c.get("actor"),
|
|
79
|
+
);
|
|
80
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
81
|
+
return c.json({ data: result.value });
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// @ts-expect-error -- openapi handler union return type
|
|
85
|
+
router.openapi(deleteShippingRateRoute, async (c) => {
|
|
86
|
+
const result = await kernel.services.shipping.deleteRate(c.req.param("id"), c.get("actor"));
|
|
87
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
88
|
+
return c.json({ data: result.value });
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
return router;
|
|
92
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { OpenAPIHono } from "@hono/zod-openapi";
|
|
2
|
+
import type { Kernel } from "../../../runtime/kernel.js";
|
|
3
|
+
import {
|
|
4
|
+
createTaxRateRoute,
|
|
5
|
+
listTaxRatesRoute,
|
|
6
|
+
updateTaxRateRoute,
|
|
7
|
+
deleteTaxRateRoute,
|
|
8
|
+
createTaxClassRoute,
|
|
9
|
+
listTaxClassesRoute,
|
|
10
|
+
updateTaxClassRoute,
|
|
11
|
+
deleteTaxClassRoute,
|
|
12
|
+
} from "../schemas/tax.js";
|
|
13
|
+
import { type AppEnv, mapErrorToResponse, mapErrorToStatus, requirePerm } from "../utils.js";
|
|
14
|
+
|
|
15
|
+
export function taxRoutes(kernel: Kernel) {
|
|
16
|
+
const router = new OpenAPIHono<AppEnv>();
|
|
17
|
+
|
|
18
|
+
router.use("/rates", requirePerm("tax:manage"));
|
|
19
|
+
router.use("/rates/:id", requirePerm("tax:manage"));
|
|
20
|
+
router.use("/classes", requirePerm("tax:manage"));
|
|
21
|
+
router.use("/classes/:id", requirePerm("tax:manage"));
|
|
22
|
+
|
|
23
|
+
// @ts-expect-error -- openapi handler union return type
|
|
24
|
+
router.openapi(createTaxRateRoute, async (c) => {
|
|
25
|
+
const result = await kernel.services.tax.createTaxRate(c.req.valid("json"), c.get("actor"));
|
|
26
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
27
|
+
return c.json({ data: result.value }, 201);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// @ts-expect-error -- openapi handler union return type
|
|
31
|
+
router.openapi(listTaxRatesRoute, async (c) => {
|
|
32
|
+
const result = await kernel.services.tax.listTaxRates(c.get("actor"));
|
|
33
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
34
|
+
return c.json({ data: result.value });
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// @ts-expect-error -- openapi handler union return type
|
|
38
|
+
router.openapi(updateTaxRateRoute, async (c) => {
|
|
39
|
+
const result = await kernel.services.tax.updateTaxRate(
|
|
40
|
+
c.req.param("id"),
|
|
41
|
+
c.req.valid("json"),
|
|
42
|
+
c.get("actor"),
|
|
43
|
+
);
|
|
44
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
45
|
+
return c.json({ data: result.value });
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// @ts-expect-error -- openapi handler union return type
|
|
49
|
+
router.openapi(deleteTaxRateRoute, async (c) => {
|
|
50
|
+
const result = await kernel.services.tax.deleteTaxRate(c.req.param("id"), c.get("actor"));
|
|
51
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
52
|
+
return c.json({ data: result.value });
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// ── Product tax classes (issue #57) ───────────────────────────────
|
|
56
|
+
|
|
57
|
+
// @ts-expect-error -- openapi handler union return type
|
|
58
|
+
router.openapi(createTaxClassRoute, async (c) => {
|
|
59
|
+
const result = await kernel.services.tax.createTaxClass(c.req.valid("json"), c.get("actor"));
|
|
60
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
61
|
+
return c.json({ data: result.value }, 201);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// @ts-expect-error -- openapi handler union return type
|
|
65
|
+
router.openapi(listTaxClassesRoute, async (c) => {
|
|
66
|
+
const result = await kernel.services.tax.listTaxClasses(c.get("actor"));
|
|
67
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
68
|
+
return c.json({ data: result.value });
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// @ts-expect-error -- openapi handler union return type
|
|
72
|
+
router.openapi(updateTaxClassRoute, async (c) => {
|
|
73
|
+
const result = await kernel.services.tax.updateTaxClass(
|
|
74
|
+
c.req.param("id"),
|
|
75
|
+
c.req.valid("json"),
|
|
76
|
+
c.get("actor"),
|
|
77
|
+
);
|
|
78
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
79
|
+
return c.json({ data: result.value });
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// @ts-expect-error -- openapi handler union return type
|
|
83
|
+
router.openapi(deleteTaxClassRoute, async (c) => {
|
|
84
|
+
const result = await kernel.services.tax.deleteTaxClass(c.req.param("id"), c.get("actor"));
|
|
85
|
+
if (!result.ok) return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
|
|
86
|
+
return c.json({ data: result.value });
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
return router;
|
|
90
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { z, createRoute } from "@hono/zod-openapi";
|
|
2
|
+
import { errorResponses } from "./shared.js";
|
|
3
|
+
|
|
4
|
+
export const CreateStaffBodySchema = z.object({
|
|
5
|
+
userId: z.string().min(1).openapi({ example: "user_abc123", description: "Better Auth user id of an existing user" }),
|
|
6
|
+
role: z.string().min(1).openapi({ example: "manager" }),
|
|
7
|
+
}).openapi("CreateStaffRequest");
|
|
8
|
+
|
|
9
|
+
export const InviteStaffBodySchema = z.object({
|
|
10
|
+
email: z.email().openapi({ example: "newhire@example.com" }),
|
|
11
|
+
role: z.string().min(1).openapi({ example: "manager" }),
|
|
12
|
+
}).openapi("InviteStaffRequest");
|
|
13
|
+
|
|
14
|
+
export const UpdateStaffRoleBodySchema = z.object({
|
|
15
|
+
role: z.string().min(1).openapi({ example: "admin" }),
|
|
16
|
+
}).openapi("UpdateStaffRoleRequest");
|
|
17
|
+
|
|
18
|
+
const MemberIdParam = z.object({
|
|
19
|
+
id: z.string().min(1).openapi({ example: "mem_abc123" }),
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const DataResponse = z.object({ data: z.any() }).openapi("AdminStaffResponse");
|
|
23
|
+
|
|
24
|
+
export const listStaffRoute = createRoute({
|
|
25
|
+
method: "get",
|
|
26
|
+
path: "/staff",
|
|
27
|
+
tags: ["Admin"],
|
|
28
|
+
summary: "List staff members with their roles",
|
|
29
|
+
responses: {
|
|
30
|
+
200: { content: { "application/json": { schema: DataResponse } }, description: "Staff members" },
|
|
31
|
+
...errorResponses,
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
export const createStaffRoute = createRoute({
|
|
36
|
+
method: "post",
|
|
37
|
+
path: "/staff",
|
|
38
|
+
tags: ["Admin"],
|
|
39
|
+
summary: "Add an existing user as a staff member with a role",
|
|
40
|
+
request: {
|
|
41
|
+
body: { content: { "application/json": { schema: CreateStaffBodySchema } }, required: true },
|
|
42
|
+
},
|
|
43
|
+
responses: {
|
|
44
|
+
201: { content: { "application/json": { schema: DataResponse } }, description: "Staff member created." },
|
|
45
|
+
...errorResponses,
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
export const inviteStaffRoute = createRoute({
|
|
50
|
+
method: "post",
|
|
51
|
+
path: "/staff/invitations",
|
|
52
|
+
tags: ["Admin"],
|
|
53
|
+
summary: "Invite a teammate by email with a role",
|
|
54
|
+
request: {
|
|
55
|
+
body: { content: { "application/json": { schema: InviteStaffBodySchema } }, required: true },
|
|
56
|
+
},
|
|
57
|
+
responses: {
|
|
58
|
+
201: { content: { "application/json": { schema: DataResponse } }, description: "Invitation created." },
|
|
59
|
+
...errorResponses,
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
export const listStaffInvitationsRoute = createRoute({
|
|
64
|
+
method: "get",
|
|
65
|
+
path: "/staff/invitations",
|
|
66
|
+
tags: ["Admin"],
|
|
67
|
+
summary: "List pending staff invitations",
|
|
68
|
+
responses: {
|
|
69
|
+
200: { content: { "application/json": { schema: DataResponse } }, description: "Invitations" },
|
|
70
|
+
...errorResponses,
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
export const listStaffRolesRoute = createRoute({
|
|
75
|
+
method: "get",
|
|
76
|
+
path: "/staff/roles",
|
|
77
|
+
tags: ["Admin"],
|
|
78
|
+
summary: "Role → permission mapping staff roles resolve to",
|
|
79
|
+
responses: {
|
|
80
|
+
200: { content: { "application/json": { schema: DataResponse } }, description: "Roles" },
|
|
81
|
+
...errorResponses,
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
export const updateStaffRoleRoute = createRoute({
|
|
86
|
+
method: "patch",
|
|
87
|
+
path: "/staff/{id}",
|
|
88
|
+
tags: ["Admin"],
|
|
89
|
+
summary: "Change a staff member's role",
|
|
90
|
+
request: {
|
|
91
|
+
params: MemberIdParam,
|
|
92
|
+
body: { content: { "application/json": { schema: UpdateStaffRoleBodySchema } }, required: true },
|
|
93
|
+
},
|
|
94
|
+
responses: {
|
|
95
|
+
200: { content: { "application/json": { schema: DataResponse } }, description: "Role updated." },
|
|
96
|
+
...errorResponses,
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
export const revokeStaffRoute = createRoute({
|
|
101
|
+
method: "delete",
|
|
102
|
+
path: "/staff/{id}",
|
|
103
|
+
tags: ["Admin"],
|
|
104
|
+
summary: "Revoke a staff member's membership",
|
|
105
|
+
request: { params: MemberIdParam },
|
|
106
|
+
responses: {
|
|
107
|
+
200: { content: { "application/json": { schema: DataResponse } }, description: "Membership revoked." },
|
|
108
|
+
...errorResponses,
|
|
109
|
+
},
|
|
110
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { z, createRoute } from "@hono/zod-openapi";
|
|
2
|
+
import { errorResponses } from "./shared.js";
|
|
3
|
+
|
|
4
|
+
const DATE = /^\d{4}-\d{2}-\d{2}$/;
|
|
5
|
+
|
|
6
|
+
const ReportParamsSchema = z.object({
|
|
7
|
+
name: z.string().regex(/^[a-z][a-z0-9-]*$/).openapi({ example: "daily-journal" }),
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const ReportQuerySchema = z.object({
|
|
11
|
+
date: z.string().regex(DATE).optional().openapi({ description: "Local calendar date (single-day reports)." }),
|
|
12
|
+
from: z.string().regex(DATE).optional().openapi({ description: "Local range start, inclusive." }),
|
|
13
|
+
to: z.string().regex(DATE).optional().openapi({ description: "Local range end, inclusive." }),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const DataResponse = z.object({ data: z.any() }).openapi("AnalyticsReportResponse");
|
|
17
|
+
|
|
18
|
+
export const listReportsRoute = createRoute({
|
|
19
|
+
method: "get",
|
|
20
|
+
path: "/reports",
|
|
21
|
+
tags: ["Analytics"],
|
|
22
|
+
summary: "List the canned retail reports",
|
|
23
|
+
responses: {
|
|
24
|
+
200: { content: { "application/json": { schema: DataResponse } }, description: "Available reports." },
|
|
25
|
+
...errorResponses,
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
export const getReportRoute = createRoute({
|
|
30
|
+
method: "get",
|
|
31
|
+
path: "/reports/{name}",
|
|
32
|
+
tags: ["Analytics"],
|
|
33
|
+
summary: "Run a canned retail report (calendar math in the store's timezone)",
|
|
34
|
+
request: { params: ReportParamsSchema, query: ReportQuerySchema },
|
|
35
|
+
responses: {
|
|
36
|
+
200: { content: { "application/json": { schema: DataResponse } }, description: "Report result." },
|
|
37
|
+
...errorResponses,
|
|
38
|
+
},
|
|
39
|
+
});
|