This commit is contained in:
admin
2026-09-03 22:02:52 +09:00
commit 659725de15
90 changed files with 2840 additions and 0 deletions
+160
View File
@@ -0,0 +1,160 @@
import type { Address, AuthUser } from "@orderops/shared";
import type { FastifyPluginAsync, FastifyRequest } from "fastify";
import { requireEmployeeUser } from "../auth/current-user";
import type { DatabaseContext } from "../db/database";
import { cancelOrder } from "./cancel-order";
import { getOrder } from "./get-order";
import { listAuditEvents } from "./list-audit-events";
import { listOrders } from "./list-orders";
import { changeOrderItemQuantity } from "./update-order-item";
import { changeShippingAddress } from "./update-shipping-address";
interface OrderRouteOptions {
db: DatabaseContext;
}
interface SearchQuery {
query?: string;
}
interface IdParams {
orderId: string;
}
interface OrderItemParams extends IdParams {
itemId: string;
}
interface QuantityBody {
quantity: number;
}
interface CancelBody {
reason?: string;
}
type AuthenticatedRequest = FastifyRequest & { currentUser: AuthUser };
export const registerOrderRoutes: FastifyPluginAsync<OrderRouteOptions> = async (app, options) => {
app.addHook("preHandler", async (request, reply) => {
const user = await requireEmployeeUser(options.db, request, reply);
if (!user) {
return reply;
}
(request as AuthenticatedRequest).currentUser = user;
});
app.get<{ Querystring: SearchQuery }>("/orders", {
schema: {
querystring: {
type: "object",
properties: {
query: { type: "string" }
}
}
}
}, async (request) => listOrders(options.db, request.query.query));
app.get<{ Params: IdParams }>("/orders/:orderId", async (request, reply) => {
const order = await getOrder(options.db, request.params.orderId);
if (!order) {
return reply.code(404).send({ message: "Order not found." });
}
return order;
});
app.get<{ Params: IdParams }>("/orders/:orderId/audit-events", async (request) => listAuditEvents(options.db, request.params.orderId));
app.post<{ Params: OrderItemParams; Body: QuantityBody }>("/orders/:orderId/items/:itemId/quantity", {
schema: {
body: {
type: "object",
required: ["quantity"],
properties: {
quantity: { type: "number" }
}
}
}
}, async (request, reply) => {
const currentUser = (request as AuthenticatedRequest).currentUser;
const result = await changeOrderItemQuantity(options.db, {
orderId: request.params.orderId,
itemId: request.params.itemId,
quantity: request.body.quantity,
actor: currentUser.username
});
if (result.statusCode !== 200) {
return reply.code(result.statusCode).send({ message: result.message });
}
return result.order;
});
app.post<{ Params: IdParams; Body: Address }>("/orders/:orderId/shipping-address", {
schema: {
body: {
type: "object",
required: ["fullName", "line1", "city", "state", "postalCode", "country"],
properties: {
fullName: { type: "string", minLength: 1 },
line1: { type: "string", minLength: 1 },
line2: { type: ["string", "null"] },
city: { type: "string", minLength: 1 },
state: { type: "string", minLength: 1 },
postalCode: { type: "string", minLength: 1 },
country: { type: "string", minLength: 1 }
}
}
}
}, async (request, reply) => {
const currentUser = (request as AuthenticatedRequest).currentUser;
const result = await changeShippingAddress(options.db, {
orderId: request.params.orderId,
address: {
fullName: request.body.fullName,
line1: request.body.line1,
line2: request.body.line2 ?? null,
city: request.body.city,
state: request.body.state,
postalCode: request.body.postalCode,
country: request.body.country
},
actor: currentUser.username
});
if (result.statusCode !== 200) {
return reply.code(result.statusCode).send({ message: result.message });
}
return result.order;
});
app.post<{ Params: IdParams; Body: CancelBody }>("/orders/:orderId/cancel", {
schema: {
body: {
type: "object",
properties: {
reason: { type: "string" }
}
}
}
}, async (request, reply) => {
const currentUser = (request as AuthenticatedRequest).currentUser;
const result = await cancelOrder(options.db, {
orderId: request.params.orderId,
reason: request.body.reason,
actor: currentUser.username
});
if (result.statusCode !== 200) {
return reply.code(result.statusCode).send({ message: result.message });
}
return result.order;
});
};