ClauseGuard / web /app /api /teams /route.ts
gaurv007's picture
Build all missing features: PDF/DOCX upload, team system (5 seats, invites, shared dashboard), API keys (generate/revoke/limits), custom clause rules (CRUD + regex)
89ccd89 verified
import { NextRequest, NextResponse } from "next/server";
import { createClient } from "@/lib/supabase/server";
import crypto from "crypto";
// GET — fetch current team + members
export async function GET() {
const supabase = await createClient();
const { data: { user } } = await supabase.auth.getUser();
if (!user) return NextResponse.json({ error: "Not authenticated" }, { status: 401 });
const { data: profile } = await supabase.from("profiles").select("team_id, plan").eq("id", user.id).single();
if (!profile?.team_id) return NextResponse.json({ team: null, members: [], invites: [] });
const { data: team } = await supabase.from("teams").select("*").eq("id", profile.team_id).single();
const { data: members } = await supabase.from("profiles").select("id, email, full_name, avatar_url").eq("team_id", profile.team_id);
const { data: invites } = await supabase.from("team_invites").select("*").eq("team_id", profile.team_id).eq("status", "pending");
return NextResponse.json({ team, members: members || [], invites: invites || [] });
}
// POST — create team or invite member
export async function POST(req: NextRequest) {
const supabase = await createClient();
const { data: { user } } = await supabase.auth.getUser();
if (!user) return NextResponse.json({ error: "Not authenticated" }, { status: 401 });
const body = await req.json();
// Create team
if (body.action === "create") {
const { data: profile } = await supabase.from("profiles").select("plan, team_id").eq("id", user.id).single();
if (profile?.plan !== "team") return NextResponse.json({ error: "Team plan required" }, { status: 403 });
if (profile?.team_id) return NextResponse.json({ error: "Already in a team" }, { status: 400 });
const { data: team, error } = await supabase.from("teams").insert({
name: body.name || "My Team", owner_id: user.id,
}).select().single();
if (error) return NextResponse.json({ error: error.message }, { status: 500 });
await supabase.from("profiles").update({ team_id: team.id }).eq("id", user.id);
return NextResponse.json({ team });
}
// Invite member
if (body.action === "invite") {
const { data: profile } = await supabase.from("profiles").select("team_id").eq("id", user.id).single();
if (!profile?.team_id) return NextResponse.json({ error: "No team" }, { status: 400 });
// Check seat limit
const { count } = await supabase.from("profiles").select("id", { count: "exact" }).eq("team_id", profile.team_id);
const { data: team } = await supabase.from("teams").select("max_seats").eq("id", profile.team_id).single();
if ((count || 0) >= (team?.max_seats || 5)) return NextResponse.json({ error: "Team is full (max 5 seats)" }, { status: 400 });
const { error } = await supabase.from("team_invites").insert({
team_id: profile.team_id, email: body.email, invited_by: user.id, role: body.role || "member",
});
if (error) return NextResponse.json({ error: error.message }, { status: 500 });
return NextResponse.json({ success: true });
}
// Accept invite
if (body.action === "accept") {
const { data: invite } = await supabase.from("team_invites")
.select("*").eq("id", body.invite_id).eq("email", user.email).eq("status", "pending").single();
if (!invite) return NextResponse.json({ error: "Invite not found" }, { status: 404 });
await supabase.from("profiles").update({ team_id: invite.team_id }).eq("id", user.id);
await supabase.from("team_invites").update({ status: "accepted" }).eq("id", invite.id);
return NextResponse.json({ success: true });
}
return NextResponse.json({ error: "Invalid action" }, { status: 400 });
}
// DELETE — remove member or leave team
export async function DELETE(req: NextRequest) {
const supabase = await createClient();
const { data: { user } } = await supabase.auth.getUser();
if (!user) return NextResponse.json({ error: "Not authenticated" }, { status: 401 });
const { memberId } = await req.json();
if (memberId === user.id) {
// Leave team
await supabase.from("profiles").update({ team_id: null }).eq("id", user.id);
} else {
// Remove member (owner only)
const { data: profile } = await supabase.from("profiles").select("team_id").eq("id", user.id).single();
const { data: team } = await supabase.from("teams").select("owner_id").eq("id", profile?.team_id).single();
if (team?.owner_id !== user.id) return NextResponse.json({ error: "Only owner can remove members" }, { status: 403 });
await supabase.from("profiles").update({ team_id: null }).eq("id", memberId);
}
return NextResponse.json({ success: true });
}