brackt/app/services/__tests__/draft-discord.server.test.ts

276 lines
9.1 KiB
TypeScript
Raw Normal View History

Add Discord draft pick announcements (#460) * Add Discord draft pick announcements Posts a message to the league Discord webhook each time a pick is made, announcing the picked participant and pinging the next team on the clock if their owner has opted into Discord notifications. Enabled via a separate toggle in league settings (independent from standings update notifications). https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn * Address code review feedback on Discord pick announcements - Fix "on the clock" timing: read currentPickNumber fresh from DB post-autodraft-chain (matches sendOnTheClockEmail guarantee) - Remove outer try/catch from notifyPickMadeOnDiscord so callers' .catch() is not dead code - Add missing draft-discord.server.test.ts with 12 tests covering all early-exit and happy paths - Fix silent empty-string fallback for missing pickedSlot: warn and skip instead - Eliminate sequential season→league DB queries by accepting leagueId as a direct param - Show "save webhook URL to configure options" hint when URL is typed but not yet saved - Remove block-scope braces at both call sites (plain const declarations) - Remove redundant "Round N, Pick M" description line (title already carries this info) - Inline pickInRoundFor helper to avoid circular import with draft-utils https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn * Fix lint errors from review fixes - Remove unused logger import (no longer needed after removing try/catch) - Remove unused OWNER_ID constant in test fixture - Use toSorted() instead of sort() in sendDraftOrderNotification https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-05-20 19:55:48 -07:00
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
vi.mock("~/database/context", () => ({
database: vi.fn(),
}));
vi.mock("~/services/discord", () => ({
sendPickAnnouncementNotification: vi.fn().mockResolvedValue(undefined),
}));
vi.mock("~/models/account", () => ({
findDiscordIdsByUserIds: vi.fn().mockResolvedValue(new Map()),
}));
import { notifyPickMadeOnDiscord } from "../draft-discord.server";
import { sendPickAnnouncementNotification } from "~/services/discord";
import { findDiscordIdsByUserIds } from "~/models/account";
// ---------------------------------------------------------------------------
// Fixtures
// ---------------------------------------------------------------------------
const SEASON_ID = "season-1";
const LEAGUE_ID = "league-1";
const TEAM_ID = "team-1";
const NEXT_TEAM_ID = "team-2";
const NEXT_OWNER_ID = "owner-2";
const WEBHOOK_URL = "https://discord.com/api/webhooks/123/abc";
/** 2-team draft; snake: pick 1→team1, pick 2→team2, pick 3→team2, pick 4→team1 */
const DRAFT_SLOTS = [
{ teamId: TEAM_ID, draftOrder: 1 },
{ teamId: NEXT_TEAM_ID, draftOrder: 2 },
];
const BASE_PARAMS = {
seasonId: SEASON_ID,
leagueId: LEAGUE_ID,
pickedTeamName: "Alpha FC",
participantName: "Erling Haaland",
sportName: "Soccer",
pickNumber: 1,
nextPickNumber: 2,
Add Discord draft pick announcements (#460) * Add Discord draft pick announcements Posts a message to the league Discord webhook each time a pick is made, announcing the picked participant and pinging the next team on the clock if their owner has opted into Discord notifications. Enabled via a separate toggle in league settings (independent from standings update notifications). https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn * Address code review feedback on Discord pick announcements - Fix "on the clock" timing: read currentPickNumber fresh from DB post-autodraft-chain (matches sendOnTheClockEmail guarantee) - Remove outer try/catch from notifyPickMadeOnDiscord so callers' .catch() is not dead code - Add missing draft-discord.server.test.ts with 12 tests covering all early-exit and happy paths - Fix silent empty-string fallback for missing pickedSlot: warn and skip instead - Eliminate sequential season→league DB queries by accepting leagueId as a direct param - Show "save webhook URL to configure options" hint when URL is typed but not yet saved - Remove block-scope braces at both call sites (plain const declarations) - Remove redundant "Round N, Pick M" description line (title already carries this info) - Inline pickInRoundFor helper to avoid circular import with draft-utils https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn * Fix lint errors from review fixes - Remove unused logger import (no longer needed after removing try/catch) - Remove unused OWNER_ID constant in test fixture - Use toSorted() instead of sort() in sendDraftOrderNotification https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-05-20 19:55:48 -07:00
round: 1,
rawPickInRound: 1,
Add Discord draft pick announcements (#460) * Add Discord draft pick announcements Posts a message to the league Discord webhook each time a pick is made, announcing the picked participant and pinging the next team on the clock if their owner has opted into Discord notifications. Enabled via a separate toggle in league settings (independent from standings update notifications). https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn * Address code review feedback on Discord pick announcements - Fix "on the clock" timing: read currentPickNumber fresh from DB post-autodraft-chain (matches sendOnTheClockEmail guarantee) - Remove outer try/catch from notifyPickMadeOnDiscord so callers' .catch() is not dead code - Add missing draft-discord.server.test.ts with 12 tests covering all early-exit and happy paths - Fix silent empty-string fallback for missing pickedSlot: warn and skip instead - Eliminate sequential season→league DB queries by accepting leagueId as a direct param - Show "save webhook URL to configure options" hint when URL is typed but not yet saved - Remove block-scope braces at both call sites (plain const declarations) - Remove redundant "Round N, Pick M" description line (title already carries this info) - Inline pickInRoundFor helper to avoid circular import with draft-utils https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn * Fix lint errors from review fixes - Remove unused logger import (no longer needed after removing try/catch) - Remove unused OWNER_ID constant in test fixture - Use toSorted() instead of sort() in sendDraftOrderNotification https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-05-20 19:55:48 -07:00
isDraftComplete: false,
totalTeams: 2,
draftSlots: DRAFT_SLOTS,
};
function makeLeague(overrides: object = {}) {
return {
id: LEAGUE_ID,
discordWebhookUrl: WEBHOOK_URL,
discordPicksAnnouncementEnabled: true,
...overrides,
};
}
function makeTeam(id: string, ownerId: string | null = null, name = "Beta United") {
return { id, name, ownerId };
}
function makeOwner(id: string, discordPingEnabled = true) {
return { id, discordPingEnabled };
}
function makeMockDb(overrides: {
league?: object | null;
nextTeam?: object | null;
owner?: object | null;
} = {}) {
const league = "league" in overrides ? overrides.league : makeLeague();
const nextTeam = "nextTeam" in overrides ? overrides.nextTeam : makeTeam(NEXT_TEAM_ID, NEXT_OWNER_ID);
const owner = "owner" in overrides ? overrides.owner : makeOwner(NEXT_OWNER_ID);
return {
query: {
leagues: { findFirst: vi.fn().mockResolvedValue(league) },
teams: { findFirst: vi.fn().mockResolvedValue(nextTeam) },
users: { findFirst: vi.fn().mockResolvedValue(owner) },
},
};
}
// ---------------------------------------------------------------------------
// Tests
// ---------------------------------------------------------------------------
beforeEach(() => {
vi.clearAllMocks();
vi.mocked(sendPickAnnouncementNotification).mockResolvedValue(undefined);
Add Discord draft pick announcements (#460) * Add Discord draft pick announcements Posts a message to the league Discord webhook each time a pick is made, announcing the picked participant and pinging the next team on the clock if their owner has opted into Discord notifications. Enabled via a separate toggle in league settings (independent from standings update notifications). https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn * Address code review feedback on Discord pick announcements - Fix "on the clock" timing: read currentPickNumber fresh from DB post-autodraft-chain (matches sendOnTheClockEmail guarantee) - Remove outer try/catch from notifyPickMadeOnDiscord so callers' .catch() is not dead code - Add missing draft-discord.server.test.ts with 12 tests covering all early-exit and happy paths - Fix silent empty-string fallback for missing pickedSlot: warn and skip instead - Eliminate sequential season→league DB queries by accepting leagueId as a direct param - Show "save webhook URL to configure options" hint when URL is typed but not yet saved - Remove block-scope braces at both call sites (plain const declarations) - Remove redundant "Round N, Pick M" description line (title already carries this info) - Inline pickInRoundFor helper to avoid circular import with draft-utils https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn * Fix lint errors from review fixes - Remove unused logger import (no longer needed after removing try/catch) - Remove unused OWNER_ID constant in test fixture - Use toSorted() instead of sort() in sendDraftOrderNotification https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-05-20 19:55:48 -07:00
process.env.APP_URL = "https://test.brackt.com";
});
afterEach(() => {
delete process.env.APP_URL;
});
describe("notifyPickMadeOnDiscord", () => {
it("returns early when league has no webhook URL", async () => {
const db = makeMockDb({ league: makeLeague({ discordWebhookUrl: null }) });
await notifyPickMadeOnDiscord({ ...BASE_PARAMS, db: db as never });
expect(sendPickAnnouncementNotification).not.toHaveBeenCalled();
});
it("returns early when picks announcement toggle is disabled", async () => {
const db = makeMockDb({ league: makeLeague({ discordPicksAnnouncementEnabled: false }) });
await notifyPickMadeOnDiscord({ ...BASE_PARAMS, db: db as never });
expect(sendPickAnnouncementNotification).not.toHaveBeenCalled();
});
it("returns early when league is not found", async () => {
const db = makeMockDb({ league: null });
await notifyPickMadeOnDiscord({ ...BASE_PARAMS, db: db as never });
expect(sendPickAnnouncementNotification).not.toHaveBeenCalled();
});
it("sends announcement with correct pick details", async () => {
const db = makeMockDb();
await notifyPickMadeOnDiscord({ ...BASE_PARAMS, db: db as never });
expect(sendPickAnnouncementNotification).toHaveBeenCalledWith(
expect.objectContaining({
webhookUrl: WEBHOOK_URL,
pickedTeamName: "Alpha FC",
participantName: "Erling Haaland",
sportName: "Soccer",
pickNumber: 1,
round: 1,
pickInRound: 1,
isDraftComplete: false,
})
);
});
it("builds the draft URL from APP_URL env var", async () => {
const db = makeMockDb();
await notifyPickMadeOnDiscord({ ...BASE_PARAMS, db: db as never });
expect(sendPickAnnouncementNotification).toHaveBeenCalledWith(
expect.objectContaining({
draftUrl: `https://test.brackt.com/leagues/${LEAGUE_ID}/draft/${SEASON_ID}`,
})
);
});
it("passes nextTeamName based on caller-supplied nextPickNumber", async () => {
// pick 3 in a 2-team snake: round 2 (reversed) → draftOrder 2 → NEXT_TEAM_ID → "Beta United"
const db = makeMockDb();
Add Discord draft pick announcements (#460) * Add Discord draft pick announcements Posts a message to the league Discord webhook each time a pick is made, announcing the picked participant and pinging the next team on the clock if their owner has opted into Discord notifications. Enabled via a separate toggle in league settings (independent from standings update notifications). https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn * Address code review feedback on Discord pick announcements - Fix "on the clock" timing: read currentPickNumber fresh from DB post-autodraft-chain (matches sendOnTheClockEmail guarantee) - Remove outer try/catch from notifyPickMadeOnDiscord so callers' .catch() is not dead code - Add missing draft-discord.server.test.ts with 12 tests covering all early-exit and happy paths - Fix silent empty-string fallback for missing pickedSlot: warn and skip instead - Eliminate sequential season→league DB queries by accepting leagueId as a direct param - Show "save webhook URL to configure options" hint when URL is typed but not yet saved - Remove block-scope braces at both call sites (plain const declarations) - Remove redundant "Round N, Pick M" description line (title already carries this info) - Inline pickInRoundFor helper to avoid circular import with draft-utils https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn * Fix lint errors from review fixes - Remove unused logger import (no longer needed after removing try/catch) - Remove unused OWNER_ID constant in test fixture - Use toSorted() instead of sort() in sendDraftOrderNotification https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-05-20 19:55:48 -07:00
await notifyPickMadeOnDiscord({ ...BASE_PARAMS, nextPickNumber: 3, db: db as never });
Add Discord draft pick announcements (#460) * Add Discord draft pick announcements Posts a message to the league Discord webhook each time a pick is made, announcing the picked participant and pinging the next team on the clock if their owner has opted into Discord notifications. Enabled via a separate toggle in league settings (independent from standings update notifications). https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn * Address code review feedback on Discord pick announcements - Fix "on the clock" timing: read currentPickNumber fresh from DB post-autodraft-chain (matches sendOnTheClockEmail guarantee) - Remove outer try/catch from notifyPickMadeOnDiscord so callers' .catch() is not dead code - Add missing draft-discord.server.test.ts with 12 tests covering all early-exit and happy paths - Fix silent empty-string fallback for missing pickedSlot: warn and skip instead - Eliminate sequential season→league DB queries by accepting leagueId as a direct param - Show "save webhook URL to configure options" hint when URL is typed but not yet saved - Remove block-scope braces at both call sites (plain const declarations) - Remove redundant "Round N, Pick M" description line (title already carries this info) - Inline pickInRoundFor helper to avoid circular import with draft-utils https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn * Fix lint errors from review fixes - Remove unused logger import (no longer needed after removing try/catch) - Remove unused OWNER_ID constant in test fixture - Use toSorted() instead of sort() in sendDraftOrderNotification https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-05-20 19:55:48 -07:00
expect(sendPickAnnouncementNotification).toHaveBeenCalledWith(
expect.objectContaining({ nextTeamName: "Beta United" })
);
});
it("uses caller-supplied nextPickNumber instead of reading from DB", async () => {
const db = makeMockDb();
Add Discord draft pick announcements (#460) * Add Discord draft pick announcements Posts a message to the league Discord webhook each time a pick is made, announcing the picked participant and pinging the next team on the clock if their owner has opted into Discord notifications. Enabled via a separate toggle in league settings (independent from standings update notifications). https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn * Address code review feedback on Discord pick announcements - Fix "on the clock" timing: read currentPickNumber fresh from DB post-autodraft-chain (matches sendOnTheClockEmail guarantee) - Remove outer try/catch from notifyPickMadeOnDiscord so callers' .catch() is not dead code - Add missing draft-discord.server.test.ts with 12 tests covering all early-exit and happy paths - Fix silent empty-string fallback for missing pickedSlot: warn and skip instead - Eliminate sequential season→league DB queries by accepting leagueId as a direct param - Show "save webhook URL to configure options" hint when URL is typed but not yet saved - Remove block-scope braces at both call sites (plain const declarations) - Remove redundant "Round N, Pick M" description line (title already carries this info) - Inline pickInRoundFor helper to avoid circular import with draft-utils https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn * Fix lint errors from review fixes - Remove unused logger import (no longer needed after removing try/catch) - Remove unused OWNER_ID constant in test fixture - Use toSorted() instead of sort() in sendDraftOrderNotification https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-05-20 19:55:48 -07:00
await notifyPickMadeOnDiscord({ ...BASE_PARAMS, db: db as never });
expect((db.query as Record<string, unknown>).seasons).toBeUndefined();
});
it("shows the immediate next drafter, not the post-autodraft-chain drafter", async () => {
// Regression: manual pick #1 by alpha; beta immediately autodrafts (#2); DB advances to pick #3.
// Discord for pick #1 must show beta ("On the clock: beta"), not gamma.
// Uses a 3-team snake: pick 1→alpha, pick 2→beta, pick 3→gamma.
const ALPHA_ID = "team-alpha";
const BETA_ID = "team-beta";
const GAMMA_ID = "team-gamma";
const threeTeamSlots = [
{ teamId: ALPHA_ID, draftOrder: 1 },
{ teamId: BETA_ID, draftOrder: 2 },
{ teamId: GAMMA_ID, draftOrder: 3 },
];
const betaTeam = { id: BETA_ID, name: "Beta Squad", ownerId: null };
const db = makeMockDb({ nextTeam: betaTeam });
await notifyPickMadeOnDiscord({
...BASE_PARAMS,
pickNumber: 1,
nextPickNumber: 2, // immediately after alpha's pick — before beta's autodraft
totalTeams: 3,
draftSlots: threeTeamSlots,
db: db as never,
});
expect(sendPickAnnouncementNotification).toHaveBeenCalledWith(
expect.objectContaining({ nextTeamName: "Beta Squad" })
);
Add Discord draft pick announcements (#460) * Add Discord draft pick announcements Posts a message to the league Discord webhook each time a pick is made, announcing the picked participant and pinging the next team on the clock if their owner has opted into Discord notifications. Enabled via a separate toggle in league settings (independent from standings update notifications). https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn * Address code review feedback on Discord pick announcements - Fix "on the clock" timing: read currentPickNumber fresh from DB post-autodraft-chain (matches sendOnTheClockEmail guarantee) - Remove outer try/catch from notifyPickMadeOnDiscord so callers' .catch() is not dead code - Add missing draft-discord.server.test.ts with 12 tests covering all early-exit and happy paths - Fix silent empty-string fallback for missing pickedSlot: warn and skip instead - Eliminate sequential season→league DB queries by accepting leagueId as a direct param - Show "save webhook URL to configure options" hint when URL is typed but not yet saved - Remove block-scope braces at both call sites (plain const declarations) - Remove redundant "Round N, Pick M" description line (title already carries this info) - Inline pickInRoundFor helper to avoid circular import with draft-utils https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn * Fix lint errors from review fixes - Remove unused logger import (no longer needed after removing try/catch) - Remove unused OWNER_ID constant in test fixture - Use toSorted() instead of sort() in sendDraftOrderNotification https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-05-20 19:55:48 -07:00
});
it("passes nextOwnerDiscordId when owner has discordPingEnabled", async () => {
vi.mocked(findDiscordIdsByUserIds).mockResolvedValue(new Map([[NEXT_OWNER_ID, "discord-999"]]));
const db = makeMockDb();
await notifyPickMadeOnDiscord({ ...BASE_PARAMS, db: db as never });
expect(sendPickAnnouncementNotification).toHaveBeenCalledWith(
expect.objectContaining({ nextOwnerDiscordId: "discord-999" })
);
});
it("omits nextOwnerDiscordId when owner has discordPingEnabled: false", async () => {
const db = makeMockDb({ owner: makeOwner(NEXT_OWNER_ID, false) });
await notifyPickMadeOnDiscord({ ...BASE_PARAMS, db: db as never });
expect(findDiscordIdsByUserIds).not.toHaveBeenCalled();
expect(sendPickAnnouncementNotification).toHaveBeenCalledWith(
expect.objectContaining({ nextOwnerDiscordId: undefined })
);
});
it("omits nextTeamName when next team has no owner", async () => {
const db = makeMockDb({ nextTeam: makeTeam(NEXT_TEAM_ID, null) });
await notifyPickMadeOnDiscord({ ...BASE_PARAMS, db: db as never });
expect(sendPickAnnouncementNotification).toHaveBeenCalledWith(
expect.objectContaining({ nextTeamName: "Beta United", nextOwnerDiscordId: undefined })
);
});
it("skips next-team lookup and passes isDraftComplete: true when draft is done", async () => {
const db = makeMockDb();
await notifyPickMadeOnDiscord({ ...BASE_PARAMS, isDraftComplete: true, db: db as never });
expect(db.query.teams.findFirst).not.toHaveBeenCalled();
Add Discord draft pick announcements (#460) * Add Discord draft pick announcements Posts a message to the league Discord webhook each time a pick is made, announcing the picked participant and pinging the next team on the clock if their owner has opted into Discord notifications. Enabled via a separate toggle in league settings (independent from standings update notifications). https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn * Address code review feedback on Discord pick announcements - Fix "on the clock" timing: read currentPickNumber fresh from DB post-autodraft-chain (matches sendOnTheClockEmail guarantee) - Remove outer try/catch from notifyPickMadeOnDiscord so callers' .catch() is not dead code - Add missing draft-discord.server.test.ts with 12 tests covering all early-exit and happy paths - Fix silent empty-string fallback for missing pickedSlot: warn and skip instead - Eliminate sequential season→league DB queries by accepting leagueId as a direct param - Show "save webhook URL to configure options" hint when URL is typed but not yet saved - Remove block-scope braces at both call sites (plain const declarations) - Remove redundant "Round N, Pick M" description line (title already carries this info) - Inline pickInRoundFor helper to avoid circular import with draft-utils https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn * Fix lint errors from review fixes - Remove unused logger import (no longer needed after removing try/catch) - Remove unused OWNER_ID constant in test fixture - Use toSorted() instead of sort() in sendDraftOrderNotification https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-05-20 19:55:48 -07:00
expect(sendPickAnnouncementNotification).toHaveBeenCalledWith(
expect.objectContaining({ isDraftComplete: true, nextTeamName: undefined })
);
});
it("suppresses errors thrown by sendPickAnnouncementNotification — caller's .catch handles them", async () => {
vi.mocked(sendPickAnnouncementNotification).mockRejectedValue(new Error("webhook down"));
const db = makeMockDb();
// The function itself does NOT swallow errors; the caller chains .catch().
await expect(
notifyPickMadeOnDiscord({ ...BASE_PARAMS, db: db as never })
).rejects.toThrow("webhook down");
});
it("uses sequential (not snake-adjusted) pick number in Discord title for even rounds", async () => {
// 13-team draft, pick #22: round 2 (even/reversed), rawPickInRound=9, snake-adjusted slot=5
// Discord should say "Round 2, Pick 9" not "Round 2, Pick 5"
const db = makeMockDb();
await notifyPickMadeOnDiscord({
...BASE_PARAMS,
pickNumber: 22,
round: 2,
rawPickInRound: 9,
totalTeams: 13,
db: db as never,
});
expect(sendPickAnnouncementNotification).toHaveBeenCalledWith(
expect.objectContaining({ pickNumber: 22, round: 2, pickInRound: 9 })
);
});
Add Discord draft pick announcements (#460) * Add Discord draft pick announcements Posts a message to the league Discord webhook each time a pick is made, announcing the picked participant and pinging the next team on the clock if their owner has opted into Discord notifications. Enabled via a separate toggle in league settings (independent from standings update notifications). https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn * Address code review feedback on Discord pick announcements - Fix "on the clock" timing: read currentPickNumber fresh from DB post-autodraft-chain (matches sendOnTheClockEmail guarantee) - Remove outer try/catch from notifyPickMadeOnDiscord so callers' .catch() is not dead code - Add missing draft-discord.server.test.ts with 12 tests covering all early-exit and happy paths - Fix silent empty-string fallback for missing pickedSlot: warn and skip instead - Eliminate sequential season→league DB queries by accepting leagueId as a direct param - Show "save webhook URL to configure options" hint when URL is typed but not yet saved - Remove block-scope braces at both call sites (plain const declarations) - Remove redundant "Round N, Pick M" description line (title already carries this info) - Inline pickInRoundFor helper to avoid circular import with draft-utils https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn * Fix lint errors from review fixes - Remove unused logger import (no longer needed after removing try/catch) - Remove unused OWNER_ID constant in test fixture - Use toSorted() instead of sort() in sendDraftOrderNotification https://claude.ai/code/session_01Tvwsv3LfL9JUqxoLct8dTn --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-05-20 19:55:48 -07:00
});