Short-circuit QP notifier when nothing drafted is involved
Widening the tennis-sync gate to fire on any elimination means notifyQualifyingPointsUpdate now runs on essentially every early-round sync, since most eliminated players are undrafted. Fetch the draft picks first and bail before the QP-total, season, participant, user, and Discord lookups when no drafted participant earned QP or was knocked out this sync — avoiding a full query battery just to send nothing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LkPWxSCunhPFknNUTXm4aZ
This commit is contained in:
parent
8900bf79dc
commit
5be8ac3f2f
2 changed files with 51 additions and 17 deletions
|
|
@ -373,6 +373,29 @@ describe("notifyQualifyingPointsUpdate", () => {
|
|||
expect(call.eliminated).toEqual([]);
|
||||
});
|
||||
|
||||
it("short-circuits before the QP-total/season lookups when nothing drafted is involved", async () => {
|
||||
// A knockout occurred but the player isn't drafted in any league. The notifier
|
||||
// is invoked (the sync fires it on any elimination) but must not run the rest
|
||||
// of its query battery just to send nothing.
|
||||
const db = makeDb({
|
||||
draftPicks: { findMany: vi.fn().mockResolvedValue([]) },
|
||||
});
|
||||
|
||||
await notifyQualifyingPointsUpdate(
|
||||
SPORTS_SEASON_ID,
|
||||
SCORING_EVENT_ID,
|
||||
db as never,
|
||||
new Set(["p-nonexistent"]),
|
||||
new Set(["p-undrafted"])
|
||||
);
|
||||
|
||||
expect(db.query.draftPicks.findMany).toHaveBeenCalledOnce();
|
||||
expect(db.query.seasonParticipantQualifyingTotals.findMany).not.toHaveBeenCalled();
|
||||
expect(db.query.seasons.findMany).not.toHaveBeenCalled();
|
||||
expect(db.query.seasonParticipants.findMany).not.toHaveBeenCalled();
|
||||
expect(sendQualifyingPointsUpdateNotification).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("fires when a drafted player is knocked out even though no QP changed", async () => {
|
||||
const db = makeDbWithEliminated();
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,34 @@ export async function notifyQualifyingPointsUpdate(
|
|||
|
||||
if (qpEarnedById.size === 0 && eliminatedIds.size === 0) return;
|
||||
|
||||
const seasonIds = seasonSports.map((s) => s.seasonId);
|
||||
|
||||
// Batch-fetch all draft picks for all leagues at once, grouped by season.
|
||||
// Fetched before the remaining lookups so we can short-circuit when nothing
|
||||
// that happened this sync was actually drafted: during a Grand Slam's early
|
||||
// rounds most eliminated players are undrafted, and the notifier now fires on
|
||||
// every sync that has any elimination — no point running the rest of the
|
||||
// queries just to send nothing.
|
||||
const allPicks = await db.query.draftPicks.findMany({
|
||||
where: inArray(schema.draftPicks.seasonId, seasonIds),
|
||||
with: { team: true },
|
||||
});
|
||||
const picksBySeasonId = new Map<string, (typeof allPicks)[number][]>();
|
||||
const draftedParticipantIds = new Set<string>();
|
||||
for (const pick of allPicks) {
|
||||
draftedParticipantIds.add(pick.participantId);
|
||||
const bucket = picksBySeasonId.get(pick.seasonId);
|
||||
if (bucket) {
|
||||
bucket.push(pick);
|
||||
} else {
|
||||
picksBySeasonId.set(pick.seasonId, [pick]);
|
||||
}
|
||||
}
|
||||
|
||||
const hasDraftedQP = [...qpEarnedById.keys()].some((id) => draftedParticipantIds.has(id));
|
||||
const hasDraftedEliminated = [...eliminatedIds].some((id) => draftedParticipantIds.has(id));
|
||||
if (!hasDraftedQP && !hasDraftedEliminated) return;
|
||||
|
||||
// Current running QP totals for the season
|
||||
const qpTotals = await db.query.seasonParticipantQualifyingTotals.findMany({
|
||||
where: eq(schema.seasonParticipantQualifyingTotals.sportsSeasonId, sportsSeasonId),
|
||||
|
|
@ -67,8 +95,6 @@ export async function notifyQualifyingPointsUpdate(
|
|||
qpTotals.map((t) => [t.participantId, parseFloat(t.totalQualifyingPoints)])
|
||||
);
|
||||
|
||||
const seasonIds = seasonSports.map((s) => s.seasonId);
|
||||
|
||||
// Batch-fetch all season + league metadata in one query
|
||||
const seasons = await db.query.seasons.findMany({
|
||||
where: inArray(schema.seasons.id, seasonIds),
|
||||
|
|
@ -76,21 +102,6 @@ export async function notifyQualifyingPointsUpdate(
|
|||
});
|
||||
const seasonMap = new Map(seasons.map((s) => [s.id, s]));
|
||||
|
||||
// Batch-fetch all draft picks for all leagues at once, grouped by season
|
||||
const allPicks = await db.query.draftPicks.findMany({
|
||||
where: inArray(schema.draftPicks.seasonId, seasonIds),
|
||||
with: { team: true },
|
||||
});
|
||||
const picksBySeasonId = new Map<string, (typeof allPicks)[number][]>();
|
||||
for (const pick of allPicks) {
|
||||
const bucket = picksBySeasonId.get(pick.seasonId);
|
||||
if (bucket) {
|
||||
bucket.push(pick);
|
||||
} else {
|
||||
picksBySeasonId.set(pick.seasonId, [pick]);
|
||||
}
|
||||
}
|
||||
|
||||
// Batch-fetch participant display names once (same participants across all leagues)
|
||||
const allParticipantIds = [...new Set([...qpEarnedById.keys(), ...eliminatedIds])];
|
||||
const participants = await db.query.seasonParticipants.findMany({
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue