Files
xo-api.vending-machine/src/routes/orders.ts
2026-05-23 10:40:21 +02:00

108 lines
2.6 KiB
TypeScript

import type { Debugger as Debug } from "debug";
import type { RouteOptions, FastifyRequest, FastifyReply } from "fastify";
import { z } from "zod";
import type { Database } from "../services/database/database.js";
import {
OrderPaymentError,
OrderPaymentService,
} from "../services/order-payment-service.js";
export type OrdersRouteDeps = {
database: Database;
orderPaymentService: OrderPaymentService;
syncServerUrl: string;
debug: Debug;
};
export class OrdersRoute {
public constructor(private readonly deps: OrdersRouteDeps) {}
public async getRoutes(): Promise<Array<RouteOptions>> {
return [
{
method: "GET",
url: "/orders",
handler: this.getOrders.bind(this),
},
{
method: "GET",
url: "/orders/:id",
handler: this.getOrder.bind(this),
},
{
method: "POST",
url: "/orders",
handler: this.createOrder.bind(this),
},
];
}
private async getOrders(_request: FastifyRequest, reply: FastifyReply) {
const orders = await this.deps.database.db
.selectFrom("orders")
.selectAll()
.execute();
return reply.send(
orders.map((order) => ({
...order,
items: JSON.parse(order.items),
})),
);
}
private async getOrder(request: FastifyRequest, reply: FastifyReply) {
const { id } = OrdersRoute.getOrderSchema.parse(request.params);
const order = await this.deps.database.db
.selectFrom("orders")
.selectAll()
.where("id", "=", id)
.executeTakeFirst();
if (!order) {
return reply.status(404).send({ error: "Order not found" });
}
return reply.send({
...order,
items: JSON.parse(order.items),
syncServerUrl: this.deps.syncServerUrl,
});
}
private async createOrder(request: FastifyRequest, reply: FastifyReply) {
const { items: itemsInput } = OrdersRoute.createOrderSchema.parse(
request.body,
);
try {
const result =
await this.deps.orderPaymentService.createOrder(itemsInput);
return reply.status(201).send(result);
} catch (error) {
if (error instanceof OrderPaymentError) {
return reply.status(error.statusCode).send({ error: error.message });
}
this.deps.debug("Failed to create order: %o", error);
return reply.status(500).send({ error: "Failed to create order" });
}
}
static getOrderSchema = z.object({
id: z.string(),
});
static createOrderSchema = z.object({
items: z.array(
z.object({
id: z.string(),
quantity: z.number().int().positive(),
}),
),
});
}