helpers.ts

This commit is contained in:
nicksales72
2026-03-12 16:41:51 -04:00
parent 071df023af
commit e67d1d1774
3 changed files with 59 additions and 56 deletions

View File

@@ -12,6 +12,7 @@ import { eq } from 'drizzle-orm';
import { MATCH_STATES, GAME_STATES, type MatchConfig } from './types'; import { MATCH_STATES, GAME_STATES, type MatchConfig } from './types';
import { notifyMatchCreated, notifyMatchFinished } from '$lib/server/discord/client'; import { notifyMatchCreated, notifyMatchFinished } from '$lib/server/discord/client';
import { updateElo } from './rating'; import { updateElo } from './rating';
import { getExpectedPicker, getMatchOrThrow, assertState, getMatchFull } from './helpers';
// ── Create Match ──────────────────────────────────────────────────────── // ── Create Match ────────────────────────────────────────────────────────
@@ -343,58 +344,3 @@ export async function cancelMatch(matchId: string) {
return getMatchFull(matchId); return getMatchFull(matchId);
} }
// ── Helpers ─────────────────────────────────────────────────────────────
function getExpectedPicker(
participants: { id: string; pickOrder: number | null; score: number }[],
gameCount: number
) {
const sorted = [...participants].sort((a, b) => (a.pickOrder ?? 99) - (b.pickOrder ?? 99));
const pickerIndex = gameCount % sorted.length;
return sorted[pickerIndex];
}
export async function getMatchFull(matchId: string) {
const m = await db.query.match.findFirst({
where: eq(match.id, matchId),
with: {
mappool: {
with: { slots: true }
},
participants: {
with: {
team: true,
players: true
}
},
games: {
with: {
slot: true,
scores: {
with: { player: true },
orderBy: (s, { desc }) => [desc(s.score)]
}
},
orderBy: (g, { asc }) => [asc(g.gameNumber)]
}
}
});
if (!m) throw new Error('Match not found');
return m;
}
async function getMatchOrThrow(matchId: string) {
const m = await db.query.match.findFirst({
where: eq(match.id, matchId)
});
if (!m) throw new Error('Match not found');
return m;
}
function assertState(current: string, expected: string) {
if (current !== expected) {
throw new Error(`Match is ${current}, expected ${expected}`);
}
}

View File

@@ -0,0 +1,56 @@
import { db } from '$lib/server/db';
import { match } from '$lib/server/db/schema';
import { eq } from 'drizzle-orm';
export function getExpectedPicker(
participants: { id: string; pickOrder: number | null; score: number }[],
gameCount: number
) {
const sorted = [...participants].sort((a, b) => (a.pickOrder ?? 99) - (b.pickOrder ?? 99));
const pickerIndex = gameCount % sorted.length;
return sorted[pickerIndex];
}
export async function getMatchFull(matchId: string) {
const m = await db.query.match.findFirst({
where: eq(match.id, matchId),
with: {
mappool: {
with: { slots: true }
},
participants: {
with: {
team: true,
players: true
}
},
games: {
with: {
slot: true,
scores: {
with: { player: true },
orderBy: (s, { desc }) => [desc(s.score)]
}
},
orderBy: (g, { asc }) => [asc(g.gameNumber)]
}
}
});
if (!m) throw new Error('Match not found');
return m;
}
export async function getMatchOrThrow(matchId: string) {
const m = await db.query.match.findFirst({
where: eq(match.id, matchId)
});
if (!m) throw new Error('Match not found');
return m;
}
export function assertState(current: string, expected: string) {
if (current !== expected) {
throw new Error(`Match is ${current}, expected ${expected}`);
}
}

View File

@@ -2,7 +2,8 @@ import { db } from '$lib/server/db';
import { match, matchGame, matchParticipant, user } from '$lib/server/db/schema'; import { match, matchGame, matchParticipant, user } from '$lib/server/db/schema';
import { eq, and } from 'drizzle-orm'; import { eq, and } from 'drizzle-orm';
import { MATCH_STATES, GAME_STATES, type MatchConfig } from './types'; import { MATCH_STATES, GAME_STATES, type MatchConfig } from './types';
import { getMatchFull, submitRoll, pickMap, submitGameScores, cancelMatch } from './engine'; import { submitRoll, pickMap, submitGameScores, cancelMatch } from './engine';
import { getMatchFull } from './helpers';
import { env } from '$env/dynamic/private'; import { env } from '$env/dynamic/private';
// matchId → lowercase usernames of all expected players // matchId → lowercase usernames of all expected players