@voyantjs/products 0.52.1 → 0.52.3
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/action-ledger-drift.d.ts +29 -0
- package/dist/action-ledger-drift.d.ts.map +1 -0
- package/dist/action-ledger-drift.js +335 -0
- package/dist/action-ledger.d.ts +104 -0
- package/dist/action-ledger.d.ts.map +1 -0
- package/dist/action-ledger.js +100 -0
- package/dist/booking-extension.d.ts +3 -3
- package/dist/catalog-policy.d.ts.map +1 -1
- package/dist/catalog-policy.js +18 -0
- package/dist/content-shape.d.ts +2 -0
- package/dist/content-shape.d.ts.map +1 -1
- package/dist/content-shape.js +2 -0
- package/dist/events.d.ts +1 -1
- package/dist/events.d.ts.map +1 -1
- package/dist/route-env.d.ts +22 -0
- package/dist/route-env.d.ts.map +1 -0
- package/dist/route-env.js +1 -0
- package/dist/routes-associations.d.ts +164 -0
- package/dist/routes-associations.d.ts.map +1 -0
- package/dist/routes-associations.js +100 -0
- package/dist/routes-catalog.d.ts +436 -0
- package/dist/routes-catalog.d.ts.map +1 -0
- package/dist/routes-catalog.js +104 -0
- package/dist/routes-configuration.d.ts +773 -0
- package/dist/routes-configuration.d.ts.map +1 -0
- package/dist/routes-configuration.js +364 -0
- package/dist/routes-core.d.ts +302 -0
- package/dist/routes-core.d.ts.map +1 -0
- package/dist/routes-core.js +79 -0
- package/dist/routes-itinerary.d.ts +614 -0
- package/dist/routes-itinerary.d.ts.map +1 -0
- package/dist/routes-itinerary.js +309 -0
- package/dist/routes-maintenance.d.ts +32 -0
- package/dist/routes-maintenance.d.ts.map +1 -0
- package/dist/routes-maintenance.js +14 -0
- package/dist/routes-media.d.ts +634 -0
- package/dist/routes-media.d.ts.map +1 -0
- package/dist/routes-media.js +245 -0
- package/dist/routes-merchandising.d.ts +1108 -0
- package/dist/routes-merchandising.d.ts.map +1 -0
- package/dist/routes-merchandising.js +376 -0
- package/dist/routes-options.d.ts +363 -0
- package/dist/routes-options.d.ts.map +1 -0
- package/dist/routes-options.js +173 -0
- package/dist/routes-public.d.ts +4 -4
- package/dist/routes-translations.d.ts +477 -0
- package/dist/routes-translations.d.ts.map +1 -0
- package/dist/routes-translations.js +258 -0
- package/dist/routes.d.ts +417 -355
- package/dist/routes.d.ts.map +1 -1
- package/dist/routes.js +21 -1133
- package/dist/schema-core.d.ts +3 -3
- package/dist/schema-itinerary.d.ts +1 -1
- package/dist/schema-settings.d.ts +4 -4
- package/dist/service-catalog-plane.d.ts.map +1 -1
- package/dist/service-catalog-plane.js +48 -1
- package/dist/service-catalog.d.ts +2 -2
- package/dist/service-content-owned.d.ts.map +1 -1
- package/dist/service-content-owned.js +98 -4
- package/dist/service-public.d.ts +4 -4
- package/dist/service.d.ts +225 -97
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +91 -0
- package/dist/tasks/brochures.d.ts +1 -1
- package/dist/validation-catalog.d.ts +10 -10
- package/dist/validation-config.d.ts +17 -17
- package/dist/validation-content.d.ts +26 -26
- package/dist/validation-core.d.ts +46 -46
- package/dist/validation-core.d.ts.map +1 -1
- package/dist/validation-core.js +17 -1
- package/dist/validation-public.d.ts +25 -25
- package/dist/validation-shared.d.ts +11 -11
- package/package.json +13 -7
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import { parseJsonBody, RequestValidationError, requireUserId } from "@voyantjs/hono";
|
|
2
|
+
import { Hono } from "hono";
|
|
3
|
+
import { appendProductMutationLedgerEntry, changedMutationFields } from "./action-ledger.js";
|
|
4
|
+
import { emitProductContentChanged } from "./events.js";
|
|
5
|
+
import { productsService } from "./service.js";
|
|
6
|
+
import * as validation from "./validation.js";
|
|
7
|
+
export const productItineraryRoutes = new Hono()
|
|
8
|
+
// ==========================================================================
|
|
9
|
+
// Itineraries
|
|
10
|
+
// ==========================================================================
|
|
11
|
+
.get("/:id/itineraries", async (c) => {
|
|
12
|
+
return c.json({ data: await productsService.listItineraries(c.get("db"), c.req.param("id")) });
|
|
13
|
+
})
|
|
14
|
+
.post("/:id/itineraries", async (c) => {
|
|
15
|
+
const productId = c.req.param("id");
|
|
16
|
+
const body = await parseJsonBody(c, validation.insertItinerarySchema);
|
|
17
|
+
const row = await productsService.createItinerary(c.get("db"), productId, body);
|
|
18
|
+
if (!row) {
|
|
19
|
+
return c.json({ error: "Product not found" }, 404);
|
|
20
|
+
}
|
|
21
|
+
await appendProductMutationLedgerEntry(c, {
|
|
22
|
+
action: "create",
|
|
23
|
+
productId,
|
|
24
|
+
changedFields: changedMutationFields(body, null, row),
|
|
25
|
+
subject: "product itinerary",
|
|
26
|
+
actionName: "product.itinerary.create",
|
|
27
|
+
routeOrToolName: "products.itinerary.create",
|
|
28
|
+
});
|
|
29
|
+
await emitProductContentChanged(c.get("eventBus"), { id: productId, axis: "itinerary" });
|
|
30
|
+
return c.json({ data: row }, 201);
|
|
31
|
+
})
|
|
32
|
+
.patch("/itineraries/:itineraryId", async (c) => {
|
|
33
|
+
const itineraryId = c.req.param("itineraryId");
|
|
34
|
+
const body = await parseJsonBody(c, validation.updateItinerarySchema);
|
|
35
|
+
const before = await productsService.getItineraryById(c.get("db"), itineraryId);
|
|
36
|
+
if (!before) {
|
|
37
|
+
return c.json({ error: "Itinerary not found" }, 404);
|
|
38
|
+
}
|
|
39
|
+
const row = await productsService.updateItinerary(c.get("db"), itineraryId, body);
|
|
40
|
+
if (!row) {
|
|
41
|
+
return c.json({ error: "Itinerary not found" }, 404);
|
|
42
|
+
}
|
|
43
|
+
await appendProductMutationLedgerEntry(c, {
|
|
44
|
+
action: "update",
|
|
45
|
+
productId: row.productId,
|
|
46
|
+
changedFields: changedMutationFields(body, before, row),
|
|
47
|
+
subject: "product itinerary",
|
|
48
|
+
actionName: "product.itinerary.update",
|
|
49
|
+
routeOrToolName: "products.itinerary.update",
|
|
50
|
+
});
|
|
51
|
+
await emitProductContentChanged(c.get("eventBus"), { id: row.productId, axis: "itinerary" });
|
|
52
|
+
return c.json({ data: row });
|
|
53
|
+
})
|
|
54
|
+
.delete("/itineraries/:itineraryId", async (c) => {
|
|
55
|
+
const itineraryId = c.req.param("itineraryId");
|
|
56
|
+
const before = await productsService.getItineraryById(c.get("db"), itineraryId);
|
|
57
|
+
if (!before) {
|
|
58
|
+
return c.json({ error: "Itinerary not found" }, 404);
|
|
59
|
+
}
|
|
60
|
+
const row = await productsService.deleteItinerary(c.get("db"), itineraryId);
|
|
61
|
+
if (!row) {
|
|
62
|
+
return c.json({ error: "Itinerary not found" }, 404);
|
|
63
|
+
}
|
|
64
|
+
await appendProductMutationLedgerEntry(c, {
|
|
65
|
+
action: "delete",
|
|
66
|
+
productId: before.productId,
|
|
67
|
+
changedFields: [],
|
|
68
|
+
subject: "product itinerary",
|
|
69
|
+
actionName: "product.itinerary.delete",
|
|
70
|
+
routeOrToolName: "products.itinerary.delete",
|
|
71
|
+
});
|
|
72
|
+
await emitProductContentChanged(c.get("eventBus"), { id: before.productId, axis: "itinerary" });
|
|
73
|
+
return c.json({ success: true }, 200);
|
|
74
|
+
})
|
|
75
|
+
.post("/itineraries/:itineraryId/duplicate", async (c) => {
|
|
76
|
+
const itineraryId = c.req.param("itineraryId");
|
|
77
|
+
const body = await parseJsonBody(c, validation.duplicateItinerarySchema);
|
|
78
|
+
const source = await productsService.getItineraryById(c.get("db"), itineraryId);
|
|
79
|
+
if (!source) {
|
|
80
|
+
return c.json({ error: "Itinerary not found" }, 404);
|
|
81
|
+
}
|
|
82
|
+
const row = await productsService.duplicateItinerary(c.get("db"), itineraryId, body);
|
|
83
|
+
if (!row) {
|
|
84
|
+
return c.json({ error: "Itinerary not found" }, 404);
|
|
85
|
+
}
|
|
86
|
+
await appendProductMutationLedgerEntry(c, {
|
|
87
|
+
action: "duplicate",
|
|
88
|
+
productId: source.productId,
|
|
89
|
+
changedFields: changedMutationFields(body, null, row),
|
|
90
|
+
subject: "product itinerary",
|
|
91
|
+
actionName: "product.itinerary.duplicate",
|
|
92
|
+
routeOrToolName: "products.itinerary.duplicate",
|
|
93
|
+
});
|
|
94
|
+
await emitProductContentChanged(c.get("eventBus"), {
|
|
95
|
+
id: source.productId,
|
|
96
|
+
axis: "itinerary",
|
|
97
|
+
});
|
|
98
|
+
return c.json({ data: row }, 201);
|
|
99
|
+
})
|
|
100
|
+
// ==========================================================================
|
|
101
|
+
// Days
|
|
102
|
+
// ==========================================================================
|
|
103
|
+
.get("/:id/itineraries/:itineraryId/days", async (c) => {
|
|
104
|
+
return c.json({
|
|
105
|
+
data: await productsService.listItineraryDays(c.get("db"), c.req.param("itineraryId")),
|
|
106
|
+
});
|
|
107
|
+
})
|
|
108
|
+
.post("/:id/itineraries/:itineraryId/days", async (c) => {
|
|
109
|
+
const productId = c.req.param("id");
|
|
110
|
+
const body = await parseJsonBody(c, validation.insertDaySchema);
|
|
111
|
+
const row = await productsService.createItineraryDay(c.get("db"), productId, c.req.param("itineraryId"), body);
|
|
112
|
+
if (!row) {
|
|
113
|
+
return c.json({ error: "Itinerary not found" }, 404);
|
|
114
|
+
}
|
|
115
|
+
await appendProductMutationLedgerEntry(c, {
|
|
116
|
+
action: "create",
|
|
117
|
+
productId,
|
|
118
|
+
changedFields: changedMutationFields(body, null, row),
|
|
119
|
+
subject: "product itinerary day",
|
|
120
|
+
actionName: "product.day.create",
|
|
121
|
+
routeOrToolName: "products.day.create",
|
|
122
|
+
});
|
|
123
|
+
await emitProductContentChanged(c.get("eventBus"), { id: productId, axis: "day" });
|
|
124
|
+
return c.json({ data: row }, 201);
|
|
125
|
+
})
|
|
126
|
+
// GET /:id/days — List days for product
|
|
127
|
+
.get("/:id/days", async (c) => {
|
|
128
|
+
return c.json({ data: await productsService.listDays(c.get("db"), c.req.param("id")) });
|
|
129
|
+
})
|
|
130
|
+
// POST /:id/days — Add day to product
|
|
131
|
+
.post("/:id/days", async (c) => {
|
|
132
|
+
const productId = c.req.param("id");
|
|
133
|
+
const body = await parseJsonBody(c, validation.insertDaySchema);
|
|
134
|
+
const row = await productsService.createDay(c.get("db"), productId, body);
|
|
135
|
+
if (!row) {
|
|
136
|
+
return c.json({ error: "Product not found" }, 404);
|
|
137
|
+
}
|
|
138
|
+
await appendProductMutationLedgerEntry(c, {
|
|
139
|
+
action: "create",
|
|
140
|
+
productId,
|
|
141
|
+
changedFields: changedMutationFields(body, null, row),
|
|
142
|
+
subject: "product itinerary day",
|
|
143
|
+
actionName: "product.day.create",
|
|
144
|
+
routeOrToolName: "products.day.create",
|
|
145
|
+
});
|
|
146
|
+
await emitProductContentChanged(c.get("eventBus"), { id: productId, axis: "day" });
|
|
147
|
+
return c.json({ data: row }, 201);
|
|
148
|
+
})
|
|
149
|
+
// PATCH /:id/days/:dayId — Update day
|
|
150
|
+
.patch("/:id/days/:dayId", async (c) => {
|
|
151
|
+
const productId = c.req.param("id");
|
|
152
|
+
const dayId = c.req.param("dayId");
|
|
153
|
+
const body = await parseJsonBody(c, validation.updateDaySchema);
|
|
154
|
+
const before = await productsService.getDayForProductMutation(c.get("db"), dayId);
|
|
155
|
+
if (!before || before.productId !== productId) {
|
|
156
|
+
return c.json({ error: "Day not found" }, 404);
|
|
157
|
+
}
|
|
158
|
+
const row = await productsService.updateDay(c.get("db"), dayId, body);
|
|
159
|
+
if (!row) {
|
|
160
|
+
return c.json({ error: "Day not found" }, 404);
|
|
161
|
+
}
|
|
162
|
+
await appendProductMutationLedgerEntry(c, {
|
|
163
|
+
action: "update",
|
|
164
|
+
productId: before.productId,
|
|
165
|
+
changedFields: changedMutationFields(body, before, row),
|
|
166
|
+
subject: "product itinerary day",
|
|
167
|
+
actionName: "product.day.update",
|
|
168
|
+
routeOrToolName: "products.day.update",
|
|
169
|
+
});
|
|
170
|
+
await emitProductContentChanged(c.get("eventBus"), { id: before.productId, axis: "day" });
|
|
171
|
+
return c.json({ data: row });
|
|
172
|
+
})
|
|
173
|
+
// DELETE /:id/days/:dayId — Delete day
|
|
174
|
+
.delete("/:id/days/:dayId", async (c) => {
|
|
175
|
+
const productId = c.req.param("id");
|
|
176
|
+
const dayId = c.req.param("dayId");
|
|
177
|
+
const before = await productsService.getDayForProductMutation(c.get("db"), dayId);
|
|
178
|
+
if (!before || before.productId !== productId) {
|
|
179
|
+
return c.json({ error: "Day not found" }, 404);
|
|
180
|
+
}
|
|
181
|
+
const row = await productsService.deleteDay(c.get("db"), dayId);
|
|
182
|
+
if (!row) {
|
|
183
|
+
return c.json({ error: "Day not found" }, 404);
|
|
184
|
+
}
|
|
185
|
+
await appendProductMutationLedgerEntry(c, {
|
|
186
|
+
action: "delete",
|
|
187
|
+
productId: before.productId,
|
|
188
|
+
changedFields: [],
|
|
189
|
+
subject: "product itinerary day",
|
|
190
|
+
actionName: "product.day.delete",
|
|
191
|
+
routeOrToolName: "products.day.delete",
|
|
192
|
+
});
|
|
193
|
+
await emitProductContentChanged(c.get("eventBus"), { id: before.productId, axis: "day" });
|
|
194
|
+
return c.json({ success: true }, 200);
|
|
195
|
+
})
|
|
196
|
+
// ==========================================================================
|
|
197
|
+
// Day Services
|
|
198
|
+
// ==========================================================================
|
|
199
|
+
// GET /:id/days/:dayId/services — List services for a day
|
|
200
|
+
.get("/:id/days/:dayId/services", async (c) => {
|
|
201
|
+
return c.json({
|
|
202
|
+
data: await productsService.listDayServices(c.get("db"), c.req.param("dayId")),
|
|
203
|
+
});
|
|
204
|
+
})
|
|
205
|
+
// POST /:id/days/:dayId/services — Add service to day
|
|
206
|
+
.post("/:id/days/:dayId/services", async (c) => {
|
|
207
|
+
const productId = c.req.param("id");
|
|
208
|
+
const body = await parseJsonBody(c, validation.insertDayServiceSchema);
|
|
209
|
+
const row = await productsService.createDayService(c.get("db"), productId, c.req.param("dayId"), body);
|
|
210
|
+
if (!row) {
|
|
211
|
+
return c.json({ error: "Day not found" }, 404);
|
|
212
|
+
}
|
|
213
|
+
await appendProductMutationLedgerEntry(c, {
|
|
214
|
+
action: "create",
|
|
215
|
+
productId,
|
|
216
|
+
changedFields: changedMutationFields(body, null, row),
|
|
217
|
+
subject: "product day service",
|
|
218
|
+
actionName: "product.day_service.create",
|
|
219
|
+
routeOrToolName: "products.day_service.create",
|
|
220
|
+
});
|
|
221
|
+
await emitProductContentChanged(c.get("eventBus"), { id: productId, axis: "day" });
|
|
222
|
+
return c.json({ data: row }, 201);
|
|
223
|
+
})
|
|
224
|
+
// PATCH /:id/days/:dayId/services/:serviceId — Update service
|
|
225
|
+
.patch("/:id/days/:dayId/services/:serviceId", async (c) => {
|
|
226
|
+
const productId = c.req.param("id");
|
|
227
|
+
const serviceId = c.req.param("serviceId");
|
|
228
|
+
const body = await parseJsonBody(c, validation.updateDayServiceSchema);
|
|
229
|
+
const before = await productsService.getDayServiceForProductMutation(c.get("db"), serviceId);
|
|
230
|
+
if (!before || before.productId !== productId) {
|
|
231
|
+
return c.json({ error: "Service not found" }, 404);
|
|
232
|
+
}
|
|
233
|
+
const row = await productsService.updateDayService(c.get("db"), productId, serviceId, body);
|
|
234
|
+
if (!row) {
|
|
235
|
+
return c.json({ error: "Service not found" }, 404);
|
|
236
|
+
}
|
|
237
|
+
await appendProductMutationLedgerEntry(c, {
|
|
238
|
+
action: "update",
|
|
239
|
+
productId: before.productId,
|
|
240
|
+
changedFields: changedMutationFields(body, before, row),
|
|
241
|
+
subject: "product day service",
|
|
242
|
+
actionName: "product.day_service.update",
|
|
243
|
+
routeOrToolName: "products.day_service.update",
|
|
244
|
+
});
|
|
245
|
+
await emitProductContentChanged(c.get("eventBus"), { id: before.productId, axis: "day" });
|
|
246
|
+
return c.json({ data: row });
|
|
247
|
+
})
|
|
248
|
+
// DELETE /:id/days/:dayId/services/:serviceId — Delete service
|
|
249
|
+
.delete("/:id/days/:dayId/services/:serviceId", async (c) => {
|
|
250
|
+
const productId = c.req.param("id");
|
|
251
|
+
const serviceId = c.req.param("serviceId");
|
|
252
|
+
const before = await productsService.getDayServiceForProductMutation(c.get("db"), serviceId);
|
|
253
|
+
if (!before || before.productId !== productId) {
|
|
254
|
+
return c.json({ error: "Service not found" }, 404);
|
|
255
|
+
}
|
|
256
|
+
const row = await productsService.deleteDayService(c.get("db"), productId, serviceId);
|
|
257
|
+
if (!row) {
|
|
258
|
+
return c.json({ error: "Service not found" }, 404);
|
|
259
|
+
}
|
|
260
|
+
await appendProductMutationLedgerEntry(c, {
|
|
261
|
+
action: "delete",
|
|
262
|
+
productId: before.productId,
|
|
263
|
+
changedFields: [],
|
|
264
|
+
subject: "product day service",
|
|
265
|
+
actionName: "product.day_service.delete",
|
|
266
|
+
routeOrToolName: "products.day_service.delete",
|
|
267
|
+
});
|
|
268
|
+
await emitProductContentChanged(c.get("eventBus"), { id: before.productId, axis: "day" });
|
|
269
|
+
return c.json({ success: true }, 200);
|
|
270
|
+
})
|
|
271
|
+
// ==========================================================================
|
|
272
|
+
// Versions
|
|
273
|
+
// ==========================================================================
|
|
274
|
+
// GET /:id/versions — List versions for product
|
|
275
|
+
.get("/:id/versions", async (c) => {
|
|
276
|
+
return c.json({ data: await productsService.listVersions(c.get("db"), c.req.param("id")) });
|
|
277
|
+
})
|
|
278
|
+
// POST /:id/versions — Create version snapshot
|
|
279
|
+
.post("/:id/versions", async (c) => {
|
|
280
|
+
const userId = requireUserId(c);
|
|
281
|
+
const row = await productsService.createVersion(c.get("db"), c.req.param("id"), userId, await parseJsonBody(c, validation.insertVersionSchema, {
|
|
282
|
+
invalidJsonMessage: "Invalid JSON body",
|
|
283
|
+
}).catch((error) => {
|
|
284
|
+
if (error instanceof RequestValidationError && error.message === "Invalid JSON body") {
|
|
285
|
+
return {};
|
|
286
|
+
}
|
|
287
|
+
throw error;
|
|
288
|
+
}));
|
|
289
|
+
if (!row) {
|
|
290
|
+
return c.json({ error: "Product not found" }, 404);
|
|
291
|
+
}
|
|
292
|
+
return c.json({ data: row }, 201);
|
|
293
|
+
})
|
|
294
|
+
// ==========================================================================
|
|
295
|
+
// Notes
|
|
296
|
+
// ==========================================================================
|
|
297
|
+
// GET /:id/notes — List notes for product
|
|
298
|
+
.get("/:id/notes", async (c) => {
|
|
299
|
+
return c.json({ data: await productsService.listNotes(c.get("db"), c.req.param("id")) });
|
|
300
|
+
})
|
|
301
|
+
// POST /:id/notes — Add note to product
|
|
302
|
+
.post("/:id/notes", async (c) => {
|
|
303
|
+
const userId = requireUserId(c);
|
|
304
|
+
const row = await productsService.createNote(c.get("db"), c.req.param("id"), userId, await parseJsonBody(c, validation.insertProductNoteSchema));
|
|
305
|
+
if (!row) {
|
|
306
|
+
return c.json({ error: "Product not found" }, 404);
|
|
307
|
+
}
|
|
308
|
+
return c.json({ data: row }, 201);
|
|
309
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Env } from "./route-env.js";
|
|
2
|
+
export declare const productMaintenanceRoutes: import("hono/hono-base").HonoBase<Env, {
|
|
3
|
+
"/:id/recalculate": {
|
|
4
|
+
$post: {
|
|
5
|
+
input: {
|
|
6
|
+
param: {
|
|
7
|
+
id: string;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
output: {
|
|
11
|
+
error: string;
|
|
12
|
+
};
|
|
13
|
+
outputFormat: "json";
|
|
14
|
+
status: 404;
|
|
15
|
+
} | {
|
|
16
|
+
input: {
|
|
17
|
+
param: {
|
|
18
|
+
id: string;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
output: {
|
|
22
|
+
data: {
|
|
23
|
+
costAmountCents: number;
|
|
24
|
+
marginPercent: number;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
outputFormat: "json";
|
|
28
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
}, "/", "/:id/recalculate">;
|
|
32
|
+
//# sourceMappingURL=routes-maintenance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes-maintenance.d.ts","sourceRoot":"","sources":["../src/routes-maintenance.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAA;AAGzC,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAcjC,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { productsService } from "./service.js";
|
|
3
|
+
export const productMaintenanceRoutes = new Hono()
|
|
4
|
+
// ==========================================================================
|
|
5
|
+
// Recalculate
|
|
6
|
+
// ==========================================================================
|
|
7
|
+
// POST /:id/recalculate — Recalculate product cost and margin
|
|
8
|
+
.post("/:id/recalculate", async (c) => {
|
|
9
|
+
const result = await productsService.recalculate(c.get("db"), c.req.param("id"));
|
|
10
|
+
if (!result) {
|
|
11
|
+
return c.json({ error: "Product not found" }, 404);
|
|
12
|
+
}
|
|
13
|
+
return c.json({ data: result });
|
|
14
|
+
});
|