Some checks failed
Deploy to Cloudflare Workers / deploy (push) Has been cancelled
182 lines
4.7 KiB
TypeScript
182 lines
4.7 KiB
TypeScript
import type { SupabaseClient } from "@supabase/supabase-js";
|
|
import { defaultLeagueRules } from "@/lib/rules/schema";
|
|
import { slugify } from "@/lib/utils";
|
|
|
|
export async function deleteLeague(supabase: SupabaseClient, leagueId: string) {
|
|
const { error } = await supabase.from("leagues").delete().eq("id", leagueId);
|
|
if (error) throw new Error(error.message);
|
|
}
|
|
|
|
export async function listLeaguesForMaster(
|
|
supabase: SupabaseClient,
|
|
userId: string,
|
|
isGlobalMaster: boolean
|
|
) {
|
|
if (isGlobalMaster) return listLeagues(supabase);
|
|
|
|
const { data: owned } = await supabase
|
|
.from("leagues")
|
|
.select("*")
|
|
.eq("created_by", userId);
|
|
|
|
const { data: assigned } = await supabase
|
|
.from("league_masters")
|
|
.select("leagues(*)")
|
|
.eq("user_id", userId);
|
|
|
|
type LeagueRow = Awaited<ReturnType<typeof listLeagues>>[number];
|
|
const merged: LeagueRow[] = [
|
|
...(owned ?? []),
|
|
...((assigned ?? [])
|
|
.map((a) => a.leagues as LeagueRow | null)
|
|
.filter(Boolean) as LeagueRow[]),
|
|
];
|
|
return Array.from(new Map(merged.map((l) => [l.id, l])).values()).sort(
|
|
(a, b) =>
|
|
new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
|
|
);
|
|
}
|
|
|
|
export async function listLeagues(supabase: SupabaseClient) {
|
|
const { data, error } = await supabase
|
|
.from("leagues")
|
|
.select("*")
|
|
.order("created_at", { ascending: false });
|
|
if (error) throw new Error(error.message);
|
|
return data;
|
|
}
|
|
|
|
export async function createLeague(
|
|
supabase: SupabaseClient,
|
|
userId: string,
|
|
input: { name: string; description?: string }
|
|
) {
|
|
const { data: league, error } = await supabase
|
|
.from("leagues")
|
|
.insert({
|
|
name: input.name,
|
|
slug: slugify(input.name) + "-" + Date.now().toString(36),
|
|
description: input.description || null,
|
|
created_by: userId,
|
|
})
|
|
.select()
|
|
.single();
|
|
|
|
if (error) throw new Error(error.message);
|
|
|
|
await supabase.from("league_rules").insert({
|
|
league_id: league.id,
|
|
version: 1,
|
|
rules: defaultLeagueRules,
|
|
created_by: userId,
|
|
});
|
|
|
|
return league;
|
|
}
|
|
|
|
export async function getLeague(supabase: SupabaseClient, leagueId: string) {
|
|
const { data, error } = await supabase
|
|
.from("leagues")
|
|
.select("*, competitions(*)")
|
|
.eq("id", leagueId)
|
|
.single();
|
|
if (error) throw new Error(error.message);
|
|
return data;
|
|
}
|
|
|
|
export async function createCompetition(
|
|
supabase: SupabaseClient,
|
|
userId: string,
|
|
leagueId: string,
|
|
input: {
|
|
name: string;
|
|
tournament_mode: "league" | "cup";
|
|
timezone?: string;
|
|
}
|
|
) {
|
|
const { data, error } = await supabase
|
|
.from("competitions")
|
|
.insert({
|
|
league_id: leagueId,
|
|
name: input.name,
|
|
tournament_mode: input.tournament_mode,
|
|
timezone: input.timezone || "UTC",
|
|
created_by: userId,
|
|
})
|
|
.select()
|
|
.single();
|
|
if (error) throw new Error(error.message);
|
|
return data;
|
|
}
|
|
|
|
export async function getCompetition(
|
|
supabase: SupabaseClient,
|
|
competitionId: string
|
|
) {
|
|
const { data, error } = await supabase
|
|
.from("competitions")
|
|
.select("*, leagues(id, name)")
|
|
.eq("id", competitionId)
|
|
.single();
|
|
if (error) throw new Error(error.message);
|
|
return data;
|
|
}
|
|
|
|
export async function activateCompetition(
|
|
supabase: SupabaseClient,
|
|
competitionId: string
|
|
) {
|
|
const { error } = await supabase.rpc("activate_competition", {
|
|
p_competition_id: competitionId,
|
|
});
|
|
if (error) throw new Error(error.message);
|
|
}
|
|
|
|
export async function generateFixtures(
|
|
supabase: SupabaseClient,
|
|
competitionId: string,
|
|
mode: "league" | "cup"
|
|
) {
|
|
const fn = mode === "cup" ? "generate_cup_bracket" : "generate_league_fixtures";
|
|
const { data, error } = await supabase.rpc(fn, {
|
|
p_competition_id: competitionId,
|
|
});
|
|
if (error) throw new Error(error.message);
|
|
return data;
|
|
}
|
|
|
|
export async function getStandings(
|
|
supabase: SupabaseClient,
|
|
competitionId: string
|
|
) {
|
|
const { data, error } = await supabase
|
|
.from("competition_standings")
|
|
.select("*")
|
|
.eq("competition_id", competitionId);
|
|
if (error) throw new Error(error.message);
|
|
return data;
|
|
}
|
|
|
|
export async function saveLeagueRules(
|
|
supabase: SupabaseClient,
|
|
userId: string,
|
|
leagueId: string,
|
|
rules: object
|
|
) {
|
|
const { data: latest } = await supabase
|
|
.from("league_rules")
|
|
.select("version")
|
|
.eq("league_id", leagueId)
|
|
.order("version", { ascending: false })
|
|
.limit(1)
|
|
.single();
|
|
|
|
const { error } = await supabase.from("league_rules").insert({
|
|
league_id: leagueId,
|
|
version: (latest?.version ?? 0) + 1,
|
|
rules,
|
|
created_by: userId,
|
|
});
|
|
if (error) throw new Error(error.message);
|
|
}
|