Fix oxlint errors: non-null assertions, sort→toSorted, unused vars

- cs-major-simulator.ts: replace 5 non-null assertions (!) with safe
  optional chaining / if-guards; replace 6 .sort() with .toSorted()
- cs2-major-stage.ts: remove unused `inArray` import
- cs2-setup.tsx: remove unused `assignedIds` variable

https://claude.ai/code/session_019w21Nkf5TvTZHH6oVHaQXR
This commit is contained in:
Claude 2026-04-05 20:26:20 +00:00
parent a0deb376a1
commit fb16db64e7
No known key found for this signature in database
3 changed files with 17 additions and 20 deletions

View file

@ -14,7 +14,7 @@
import { database } from "~/database/context"; import { database } from "~/database/context";
import { cs2MajorStageResults, participants } from "~/database/schema"; import { cs2MajorStageResults, participants } from "~/database/schema";
import { eq, and, inArray, sql } from "drizzle-orm"; import { eq, and, sql } from "drizzle-orm";
export interface Cs2StageResult { export interface Cs2StageResult {
id: string; id: string;

View file

@ -119,9 +119,6 @@ export default function AdminCs2Setup() {
const navigation = useNavigation(); const navigation = useNavigation();
const isSubmitting = navigation.state === 'submitting'; const isSubmitting = navigation.state === 'submitting';
// Build maps from existing stage results
const assignedIds = new Set(stageResults.map(r => r.participantId));
// Stage assignment state (local, submitted via form) // Stage assignment state (local, submitted via form)
const [stageSelections, setStageSelections] = useState<Record<string, string>>(() => { const [stageSelections, setStageSelections] = useState<Record<string, string>>(() => {
const initial: Record<string, string> = {}; const initial: Record<string, string> = {};

View file

@ -120,7 +120,7 @@ export function sampleField(
pool: TeamWithElo[], pool: TeamWithElo[],
fieldSize: number = FIELD_SIZE fieldSize: number = FIELD_SIZE
): TeamWithElo[] { ): TeamWithElo[] {
const sorted = [...pool].sort((a, b) => a.rank - b.rank); const sorted = [...pool].toSorted((a, b) => a.rank - b.rank);
if (sorted.length <= fieldSize) return sorted; if (sorted.length <= fieldSize) return sorted;
@ -146,8 +146,8 @@ function weightedSampleWithoutReplacement<T>(
): T[] { ): T[] {
const keys = weights.map((w) => -Math.log(Math.random()) / w); const keys = weights.map((w) => -Math.log(Math.random()) / w);
const indexed = items.map((item, i) => ({ item, key: keys[i] })); const indexed = items.map((item, i) => ({ item, key: keys[i] }));
indexed.sort((a, b) => a.key - b.key); const sortedIndexed = indexed.toSorted((a, b) => a.key - b.key);
return indexed.slice(0, count).map((x) => x.item); return sortedIndexed.slice(0, count).map((x) => x.item);
} }
// ─── Swiss stage simulation ─────────────────────────────────────────────────── // ─── Swiss stage simulation ───────────────────────────────────────────────────
@ -213,13 +213,13 @@ export function simulateSwiss(teams: TeamWithElo[], bo3: boolean): SwissResult {
if ((wins.get(winnerId) ?? 0) >= 3) { if ((wins.get(winnerId) ?? 0) >= 3) {
advancedIds.add(winnerId); advancedIds.add(winnerId);
const t = teamById.get(winnerId)!; const t = teamById.get(winnerId);
advanced.push({ id: t.id, elo: t.elo, rank: t.rank }); if (t) advanced.push({ id: t.id, elo: t.elo, rank: t.rank });
} }
if ((losses.get(loserId) ?? 0) >= 3) { if ((losses.get(loserId) ?? 0) >= 3) {
eliminatedIds.add(loserId); eliminatedIds.add(loserId);
const t = teamById.get(loserId)!; const t = teamById.get(loserId);
eliminated.push({ id: t.id, elo: t.elo, rank: t.rank, wins: wins.get(loserId) ?? 0 }); if (t) eliminated.push({ id: t.id, elo: t.elo, rank: t.rank, wins: wins.get(loserId) ?? 0 });
} }
} }
} }
@ -237,7 +237,7 @@ function groupByRecord(
for (const t of active) { for (const t of active) {
const key = `${wins.get(t.id) ?? 0}-${losses.get(t.id) ?? 0}`; const key = `${wins.get(t.id) ?? 0}-${losses.get(t.id) ?? 0}`;
if (!groups.has(key)) groups.set(key, []); if (!groups.has(key)) groups.set(key, []);
groups.get(key)!.push(t); groups.get(key)?.push(t);
} }
return groups; return groups;
} }
@ -287,7 +287,7 @@ export function simulateChampionsStage(teams: TeamWithElo[]): ChampionsResult {
} }
// Seed by rank ascending // Seed by rank ascending
const seeded = [...teams].sort((a, b) => a.rank - b.rank); const seeded = [...teams].toSorted((a, b) => a.rank - b.rank);
// Standard 8-team seeding: 1v8, 4v5, 3v6, 2v7 // Standard 8-team seeding: 1v8, 4v5, 3v6, 2v7
const bracket: [TeamWithElo, TeamWithElo][] = [ const bracket: [TeamWithElo, TeamWithElo][] = [
[seeded[0], seeded[7]], [seeded[0], seeded[7]],
@ -353,12 +353,12 @@ function calcStage3ExitQP(
const byWins = new Map<number, string[]>(); const byWins = new Map<number, string[]>();
for (const t of elimTeams) { for (const t of elimTeams) {
if (!byWins.has(t.wins)) byWins.set(t.wins, []); if (!byWins.has(t.wins)) byWins.set(t.wins, []);
byWins.get(t.wins)!.push(t.id); byWins.get(t.wins)?.push(t.id);
} }
// Assign placement slots 916 from highest wins first // Assign placement slots 916 from highest wins first
const result = new Map<string, number>(); const result = new Map<string, number>();
const winsGroups = [...byWins.entries()].sort((a, b) => b[0] - a[0]); // descending wins const winsGroups = [...byWins.entries()].toSorted((a, b) => b[0] - a[0]); // descending wins
let slotStart = 9; let slotStart = 9;
for (const [, ids] of winsGroups) { for (const [, ids] of winsGroups) {
@ -415,10 +415,10 @@ export class CSMajorSimulator implements Simulator {
const pool: TeamWithElo[] = participantIds const pool: TeamWithElo[] = participantIds
.filter((id) => eloMap.has(id)) .filter((id) => eloMap.has(id))
.map((id) => { .map((id) => {
const e = eloMap.get(id)!; const e = eloMap.get(id);
return { id, elo: e.elo, rank: e.rank }; return { id, elo: e?.elo ?? FALLBACK_ELO, rank: e?.rank ?? 9999 };
}) })
.sort((a, b) => a.rank - b.rank); .toSorted((a, b) => a.rank - b.rank);
if (pool.length === 0) { if (pool.length === 0) {
throw new Error( throw new Error(
@ -497,7 +497,7 @@ export class CSMajorSimulator implements Simulator {
} }
// Rank all participants by total QP descending. // Rank all participants by total QP descending.
const ranked = [...simQP.entries()].sort((a, b) => b[1] - a[1]); const ranked = [...simQP.entries()].toSorted((a, b) => b[1] - a[1]);
for (let rank = 0; rank < Math.min(8, ranked.length); rank++) { for (let rank = 0; rank < Math.min(8, ranked.length); rank++) {
const [pid] = ranked[rank]; const [pid] = ranked[rank];
const idx = idToIndex.get(pid); const idx = idToIndex.get(pid);
@ -564,7 +564,7 @@ function simulateOneMajor(
stage3Direct = s3; stage3Direct = s3;
} else { } else {
const field = sampleField(pool, FIELD_SIZE); const field = sampleField(pool, FIELD_SIZE);
const sorted = [...field].sort((a, b) => a.rank - b.rank); const sorted = field.toSorted((a, b) => a.rank - b.rank);
stage3Direct = sorted.slice(0, 8); stage3Direct = sorted.slice(0, 8);
stage2Direct = sorted.slice(8, 16); stage2Direct = sorted.slice(8, 16);
stage1Teams = sorted.slice(16, 32); stage1Teams = sorted.slice(16, 32);