import { redirect } from "next/navigation"; import type { Database } from "@/lib/types"; import { createSupabaseAdminClient } from "@/lib/supabase/admin"; import { createSupabaseRouteClient } from "@/lib/supabase/route"; import { createSupabaseServerClient } from "@/lib/supabase/server"; export type AgencyContext = { userId: string; agencyId: string; role: "owner" | "admin" | "member"; }; export function assertAgencyAdmin(context: AgencyContext) { if (context.role !== "owner" && context.role !== "admin") { throw new Error("Forbidden"); } } type AgencyMemberSummary = Pick< Database["public"]["Tables"]["agency_members"]["Row"], "agency_id" | "role" >; async function getOrCreateAgencyMembership( userId: string, email?: string | null, ) { const supabase = createSupabaseServerClient() as any; const admin = createSupabaseAdminClient() as any; const { data: existingMembership } = (await supabase .from("agency_members") .select("agency_id, role") .eq("user_id", userId) .order("created_at", { ascending: true }) .limit(1) .maybeSingle()) as { data: AgencyMemberSummary | null }; if (existingMembership) { return existingMembership; } const defaultAgencyName = email ? `${email.split("@")[0] ?? "New"} Agency` : "New Agency"; const { data: createdAgency, error: agencyError } = (await admin .from("agencies") .insert({ name: defaultAgencyName }) .select("id") .single()) as { data: Pick | null; error: { message: string } | null; }; if (agencyError || !createdAgency) { throw new Error( `Unable to create agency: ${agencyError?.message ?? "no row returned"}`, ); } const { error: membershipError } = await admin.from("agency_members").insert({ agency_id: createdAgency.id, user_id: userId, role: "owner", }); if (!membershipError) { return { agency_id: createdAgency.id, role: "owner" as const, }; } // If another request created membership first, fall back to a fresh read. const { data: retriedMembership } = (await supabase .from("agency_members") .select("agency_id, role") .eq("user_id", userId) .order("created_at", { ascending: true }) .limit(1) .maybeSingle()) as { data: AgencyMemberSummary | null }; if (retriedMembership) { return retriedMembership; } throw new Error("Unable to create agency membership"); } export async function getServerAgencyContextOrRedirect(): Promise { const supabase = createSupabaseServerClient(); const { data: { user }, } = await supabase.auth.getUser(); if (!user) { redirect("/login"); } const membership = await getOrCreateAgencyMembership(user.id, user.email); return { userId: user.id, agencyId: membership.agency_id, role: membership.role, }; } export async function getRouteAgencyContextOrThrow(): Promise { const supabase = createSupabaseRouteClient(); const db = supabase as any; const { data: { session }, } = await supabase.auth.getSession(); if (!session?.user) { throw new Error("Unauthorized"); } const { data: membership } = (await db .from("agency_members") .select("agency_id, role") .eq("user_id", session.user.id) .order("created_at", { ascending: true }) .limit(1) .maybeSingle()) as { data: AgencyMemberSummary | null }; if (!membership) { throw new Error("No agency membership"); } return { userId: session.user.id, agencyId: membership.agency_id, role: membership.role, }; }