import { routes } from "@deadhead/schema"; import type { FastifyInstance } from "fastify"; import { dispatchContract, dispatchReposition, dispatchTutorial } from "../game/dispatch"; import { registerRoute } from "../http/route"; import { RESOLVE_ARRIVALS_JOB } from "../jobs/definitions"; import type { AppContext } from "./context"; import { withPlayer } from "./with-player"; /** Contract, tutorial and reposition dispatches. */ export function registerDispatchRoutes(app: FastifyInstance, ctx: AppContext): void { registerRoute(app, routes.createDispatch, ctx.options, async (input, { playerId, request }) => { const result = await withPlayer(ctx, playerId, async (tx, now) => { switch (input.kind) { case "contract": return { dispatch: await dispatchContract(tx, playerId, input, now) }; case "tutorial": return { dispatch: await dispatchTutorial(tx, playerId, input.contractId, now) }; case "reposition": return { dispatch: await dispatchReposition(tx, playerId, input, now) }; } }); // Resolve at arrival even if the player never comes back (Step 7.2). Sent after // the dispatch commits; if sending fails, lazy resolution on read still covers it. try { await ctx.jobs.send( RESOLVE_ARRIVALS_JOB, { playerId, dispatchId: result.dispatch.id }, ctx.toBaseTime(result.dispatch.arrivalAt), ); } catch (error) { request.log.error({ err: error }, "Could not schedule the arrival job"); } return result; }); }