brackt/app/routes/api/queue.remove.ts

47 lines
1.4 KiB
TypeScript
Raw Normal View History

import { getAuth } from "@clerk/react-router/server";
import { database } from "~/database/context";
import * as schema from "~/database/schema";
import { eq } from "drizzle-orm";
import { removeFromQueue, getTeamQueue } from "~/models/draft-queue";
Add TypeScript types and improve draft validation (#28) * Code review fixes: type safety, security hardening, and dead code removal - Fix Socket.IO event types: draft-paused and draft-resumed were typed as () => void but are emitted with { seasonId, paused } data payloads - Fix draft.force-manual-pick: add missing season.status === "draft" guard so commissioners cannot force picks outside an active draft; add duplicate pick-number check so a slot cannot be assigned two picks (the previous code only checked participant uniqueness, not slot uniqueness) - Replace args: any with ActionFunctionArgs / Route.LoaderArgs across all API routes and league loaders; replace (auth as any).userId casts with proper const { userId } = await getAuth(args) destructuring - Remove unused isSnakeDraft = true dead variable from draft.make-pick - Replace autodraftSettings: any and draftSlots: any[] in draft-utils with properly typed InferSelectModel / DraftSlot types - Update force-manual-pick tests: sequence draftPicks.findFirst mock for the two-call flow; add new tests for status-check and slot-uniqueness https://claude.ai/code/session_01FKq2gPFYpgdfxr8cw4Z2AZ * Fix RouterContextProvider type errors in action test files Cast context argument to RouterContextProvider in test helpers so ActionFunctionArgs strict typing is satisfied without weakening the production action signatures back to any. https://claude.ai/code/session_01FKq2gPFYpgdfxr8cw4Z2AZ --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-02-22 19:26:45 -08:00
import type { ActionFunctionArgs } from "react-router";
export async function action(args: ActionFunctionArgs) {
const { request } = args;
Add TypeScript types and improve draft validation (#28) * Code review fixes: type safety, security hardening, and dead code removal - Fix Socket.IO event types: draft-paused and draft-resumed were typed as () => void but are emitted with { seasonId, paused } data payloads - Fix draft.force-manual-pick: add missing season.status === "draft" guard so commissioners cannot force picks outside an active draft; add duplicate pick-number check so a slot cannot be assigned two picks (the previous code only checked participant uniqueness, not slot uniqueness) - Replace args: any with ActionFunctionArgs / Route.LoaderArgs across all API routes and league loaders; replace (auth as any).userId casts with proper const { userId } = await getAuth(args) destructuring - Remove unused isSnakeDraft = true dead variable from draft.make-pick - Replace autodraftSettings: any and draftSlots: any[] in draft-utils with properly typed InferSelectModel / DraftSlot types - Update force-manual-pick tests: sequence draftPicks.findFirst mock for the two-call flow; add new tests for status-check and slot-uniqueness https://claude.ai/code/session_01FKq2gPFYpgdfxr8cw4Z2AZ * Fix RouterContextProvider type errors in action test files Cast context argument to RouterContextProvider in test helpers so ActionFunctionArgs strict typing is satisfied without weakening the production action signatures back to any. https://claude.ai/code/session_01FKq2gPFYpgdfxr8cw4Z2AZ --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-02-22 19:26:45 -08:00
const { userId } = await getAuth(args);
if (!userId) {
return Response.json({ error: "Unauthorized" }, { status: 401 });
}
const formData = await request.formData();
const queueId = formData.get("queueId");
const teamId = formData.get("teamId");
if (!queueId || !teamId) {
return Response.json({ error: "Missing required fields" }, { status: 400 });
}
const db = database();
// Verify user owns this team
const team = await db.query.teams.findFirst({
where: eq(schema.teams.id, teamId as string),
});
if (!team || team.ownerId !== userId) {
return Response.json({ error: "Unauthorized" }, { status: 403 });
}
// Remove from queue
await removeFromQueue(queueId as string);
// Get updated queue
const updatedQueue = await getTeamQueue(teamId as string);
// TODO: Emit socket event for real-time update
// const io = getSocketIO();
// io.to(`draft-${seasonId}`).emit("queue-updated", { teamId, queue: updatedQueue });
return Response.json({ success: true, queue: updatedQueue });
}