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([]);
|
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 () => {
|
it("fires when a drafted player is knocked out even though no QP changed", async () => {
|
||||||
const db = makeDbWithEliminated();
|
const db = makeDbWithEliminated();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,34 @@ export async function notifyQualifyingPointsUpdate(
|
||||||
|
|
||||||
if (qpEarnedById.size === 0 && eliminatedIds.size === 0) return;
|
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
|
// Current running QP totals for the season
|
||||||
const qpTotals = await db.query.seasonParticipantQualifyingTotals.findMany({
|
const qpTotals = await db.query.seasonParticipantQualifyingTotals.findMany({
|
||||||
where: eq(schema.seasonParticipantQualifyingTotals.sportsSeasonId, sportsSeasonId),
|
where: eq(schema.seasonParticipantQualifyingTotals.sportsSeasonId, sportsSeasonId),
|
||||||
|
|
@ -67,8 +95,6 @@ export async function notifyQualifyingPointsUpdate(
|
||||||
qpTotals.map((t) => [t.participantId, parseFloat(t.totalQualifyingPoints)])
|
qpTotals.map((t) => [t.participantId, parseFloat(t.totalQualifyingPoints)])
|
||||||
);
|
);
|
||||||
|
|
||||||
const seasonIds = seasonSports.map((s) => s.seasonId);
|
|
||||||
|
|
||||||
// Batch-fetch all season + league metadata in one query
|
// Batch-fetch all season + league metadata in one query
|
||||||
const seasons = await db.query.seasons.findMany({
|
const seasons = await db.query.seasons.findMany({
|
||||||
where: inArray(schema.seasons.id, seasonIds),
|
where: inArray(schema.seasons.id, seasonIds),
|
||||||
|
|
@ -76,21 +102,6 @@ export async function notifyQualifyingPointsUpdate(
|
||||||
});
|
});
|
||||||
const seasonMap = new Map(seasons.map((s) => [s.id, s]));
|
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)
|
// Batch-fetch participant display names once (same participants across all leagues)
|
||||||
const allParticipantIds = [...new Set([...qpEarnedById.keys(), ...eliminatedIds])];
|
const allParticipantIds = [...new Set([...qpEarnedById.keys(), ...eliminatedIds])];
|
||||||
const participants = await db.query.seasonParticipants.findMany({
|
const participants = await db.query.seasonParticipants.findMany({
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue