108 lines
2.6 KiB
TypeScript
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(),
|
|
}),
|
|
),
|
|
});
|
|
}
|