feat(surface-elo): mirror batchUpsert writes to canonical table
The simulator now reads surface Elo from the canonical table (participant_surface_elos). The existing per-window admin page still posts to batchUpsertSurfaceElos; without this change, those edits would silently fail to affect simulator output. Mirror every write to both tables until Phase 4 removes the per-window path entirely. Phase 3 Task 5 (partial — canonical write path; dedicated canonical admin UI deferred; existing page continues to work and now edits both tables). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
3e81dfe8da
commit
7483cd628b
1 changed files with 40 additions and 1 deletions
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
import { database } from "~/database/context";
|
||||
import { participantSurfaceElos, seasonParticipantSurfaceElos, seasonParticipants } from "~/database/schema";
|
||||
import { eq, sql } from "drizzle-orm";
|
||||
import { eq, inArray, sql } from "drizzle-orm";
|
||||
|
||||
export type CourtSurface = "hard" | "clay" | "grass";
|
||||
|
||||
|
|
@ -99,6 +99,45 @@ export async function batchUpsertSurfaceElos(
|
|||
updatedAt: sql`excluded.updated_at`,
|
||||
},
|
||||
});
|
||||
|
||||
// Mirror writes to the canonical participant_surface_elos table.
|
||||
// The simulator reads from canonical, so per-window-only edits would
|
||||
// not affect simulations. Remove the per-window path entirely in Phase 4.
|
||||
const sps = await db
|
||||
.select({ id: seasonParticipants.id, canonicalId: seasonParticipants.participantId })
|
||||
.from(seasonParticipants)
|
||||
.where(inArray(seasonParticipants.id, inputs.map((i) => i.participantId)));
|
||||
const canonicalByInputId = new Map(sps.map((sp) => [sp.id, sp.canonicalId]));
|
||||
|
||||
const canonicalRows = inputs
|
||||
.map((i) => ({
|
||||
canonicalId: canonicalByInputId.get(i.participantId),
|
||||
worldRanking: i.worldRanking ?? null,
|
||||
eloHard: i.eloHard ?? null,
|
||||
eloClay: i.eloClay ?? null,
|
||||
eloGrass: i.eloGrass ?? null,
|
||||
}))
|
||||
.filter((r): r is typeof r & { canonicalId: string } => typeof r.canonicalId === "string");
|
||||
|
||||
if (canonicalRows.length === 0) return;
|
||||
|
||||
await db
|
||||
.insert(participantSurfaceElos)
|
||||
.values(canonicalRows.map(({ canonicalId, ...rest }) => ({
|
||||
participantId: canonicalId,
|
||||
...rest,
|
||||
updatedAt: now,
|
||||
})))
|
||||
.onConflictDoUpdate({
|
||||
target: [participantSurfaceElos.participantId],
|
||||
set: {
|
||||
worldRanking: sql`excluded.world_ranking`,
|
||||
eloHard: sql`excluded.elo_hard`,
|
||||
eloClay: sql`excluded.elo_clay`,
|
||||
eloGrass: sql`excluded.elo_grass`,
|
||||
updatedAt: sql`excluded.updated_at`,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue