Fix code review issues in commissioner time bank adjustment

- Wrap fetch in try/finally so isAdjustingTimeBank is always reset,
  even on network errors that cause fetch to throw
- Guard against totalSeconds rounding to 0 for tiny fractional inputs
- Reject API requests when the draft is not in 'draft' status (409)
- Set input min to 0.001 so the browser rejects zero in native validation

https://claude.ai/code/session_013wxPKzLUCx3nC3LpxgjvQL
This commit is contained in:
Claude 2026-02-22 18:56:55 +00:00
parent 554a24eafb
commit c6a26b17d3
No known key found for this signature in database
2 changed files with 35 additions and 21 deletions

View file

@ -33,6 +33,10 @@ export async function action(args: any) {
return Response.json({ error: "Season not found" }, { status: 404 }); return Response.json({ error: "Season not found" }, { status: 404 });
} }
if (season.status !== "draft") {
return Response.json({ error: "Draft is not currently active" }, { status: 409 });
}
const isCommissioner = await db.query.commissioners.findFirst({ const isCommissioner = await db.query.commissioners.findFirst({
where: and( where: and(
eq(schema.commissioners.leagueId, season.leagueId), eq(schema.commissioners.leagueId, season.leagueId),

View file

@ -837,31 +837,41 @@ export default function DraftRoom() {
const unitMultipliers = { seconds: 1, minutes: 60, hours: 3600 }; const unitMultipliers = { seconds: 1, minutes: 60, hours: 3600 };
const totalSeconds = Math.round(amount * unitMultipliers[timeBankUnit]); const totalSeconds = Math.round(amount * unitMultipliers[timeBankUnit]);
if (totalSeconds === 0) {
toast.error("Adjustment rounds to 0 seconds — please enter a larger value");
return;
}
const adjustment = timeBankDirection === "add" ? totalSeconds : -totalSeconds; const adjustment = timeBankDirection === "add" ? totalSeconds : -totalSeconds;
setIsAdjustingTimeBank(true); setIsAdjustingTimeBank(true);
const formData = new FormData(); try {
formData.append("seasonId", season.id); const formData = new FormData();
formData.append("teamId", timeBankTeamId); formData.append("seasonId", season.id);
formData.append("adjustment", adjustment.toString()); formData.append("teamId", timeBankTeamId);
formData.append("adjustment", adjustment.toString());
const response = await fetch("/api/draft/adjust-time-bank", { const response = await fetch("/api/draft/adjust-time-bank", {
method: "POST", method: "POST",
body: formData, body: formData,
}); });
setIsAdjustingTimeBank(false); if (response.ok) {
const data = await response.json();
if (response.ok) { setTeamTimers((prev) => ({ ...prev, [timeBankTeamId]: data.timeRemaining }));
const data = await response.json(); const teamName = draftSlots.find((s) => s.team.id === timeBankTeamId)?.team.name;
setTeamTimers((prev) => ({ ...prev, [timeBankTeamId]: data.timeRemaining })); toast.success(`Time bank adjusted for ${teamName}`);
const teamName = draftSlots.find((s) => s.team.id === timeBankTeamId)?.team.name; setTimeBankDialogOpen(false);
toast.success(`Time bank adjusted for ${teamName}`); setTimeBankTeamId(null);
setTimeBankDialogOpen(false); } else {
setTimeBankTeamId(null); const error = await response.json();
} else { toast.error(error.error || "Failed to adjust time bank");
const error = await response.json(); }
toast.error(error.error || "Failed to adjust time bank"); } catch {
toast.error("Network error — failed to adjust time bank");
} finally {
setIsAdjustingTimeBank(false);
} }
}; };
@ -1541,7 +1551,7 @@ export default function DraftRoom() {
<div className="flex gap-2"> <div className="flex gap-2">
<input <input
type="number" type="number"
min="0" min="0.001"
step="any" step="any"
value={timeBankAmount} value={timeBankAmount}
onChange={(e) => setTimeBankAmount(e.target.value)} onChange={(e) => setTimeBankAmount(e.target.value)}