import { and, eq } from 'drizzle-orm'; import { NextResponse } from 'next/server'; import { type RouteHandler } from '@/lib/api/helpers'; import { parseBody, parseQuery } from '@/lib/api/route-helpers'; import { db } from '@/lib/db'; import { berths } from '@/lib/db/schema/berths'; import { NotFoundError, errorResponse } from '@/lib/errors'; import { createPending, listReservations } from '@/lib/services/berth-reservations.service'; import { createPendingSchema, listReservationsSchema } from '@/lib/validators/reservations'; // URL berthId is authoritative; make body berthId optional (ignored anyway). const createPendingBodySchema = createPendingSchema .omit({ berthId: true }) .extend({ berthId: createPendingSchema.shape.berthId.optional() }); async function assertBerthInPort(berthId: string, portId: string): Promise { const berth = await db.query.berths.findFirst({ where: and(eq(berths.id, berthId), eq(berths.portId, portId)), }); if (!berth) throw new NotFoundError('Berth'); } export const listHandler: RouteHandler = async (req, ctx, params) => { try { await assertBerthInPort(params.id!, ctx.portId); const query = parseQuery(req, listReservationsSchema); const result = await listReservations(ctx.portId, { ...query, berthId: params.id! }); const { page, limit } = query; const totalPages = Math.ceil(result.total / limit); return NextResponse.json({ data: result.data, pagination: { page, pageSize: limit, total: result.total, totalPages, hasNextPage: page < totalPages, hasPreviousPage: page > 1, }, }); } catch (error) { return errorResponse(error); } }; export const createHandler: RouteHandler = async (req, ctx, params) => { try { await assertBerthInPort(params.id!, ctx.portId); const body = await parseBody(req, createPendingBodySchema); const reservation = await createPending( ctx.portId, { ...body, berthId: params.id! }, { userId: ctx.userId, portId: ctx.portId, ipAddress: ctx.ipAddress, userAgent: ctx.userAgent, }, ); return NextResponse.json({ data: reservation }, { status: 201 }); } catch (error) { return errorResponse(error); } };