diff --git a/app/api/classrooms/[id]/stats/route.ts b/app/api/classrooms/[id]/stats/route.ts index 2a29f126..32456fad 100644 --- a/app/api/classrooms/[id]/stats/route.ts +++ b/app/api/classrooms/[id]/stats/route.ts @@ -31,35 +31,35 @@ export async function GET( return NextResponse.json({ error: "Forbidden" }, { status: 403 }); } - // Get role-specific counts - const { data: membershipData } = await supabase - .from("classroom_memberships") - .select("role") - .eq("classroom_id", classroomId); + // ⚡ Bolt Optimization: Combine independent DB queries using Promise.all to avoid waterfall + const [ + { data: membershipData }, + { count: activeAssignments }, + { data: progressData } + ] = await Promise.all([ + supabase + .from("classroom_memberships") + .select("role") + .eq("classroom_id", classroomId), + supabase + .from("classroom_assignments") + .select("*", { count: "exact", head: true }) + .eq("classroom_id", classroomId) + .eq("is_active", true), + supabase + .from("assignment_enrollments") + .select(` + status, + classroom_assignments!inner(classroom_id) + `) + .eq("classroom_assignments.classroom_id", classroomId) + ]); const totalStudents = membershipData?.filter(m => m.role === "student").length || 0; const totalInstructors = membershipData?.filter(m => m.role === "instructor").length || 0; const totalTAs = membershipData?.filter(m => m.role === "ta").length || 0; const totalMembers = membershipData?.length || 0; - // Get active assignments count - const { count: activeAssignments } = await supabase - .from("classroom_assignments") - .select("*", { count: "exact", head: true }) - .eq("classroom_id", classroomId) - .eq("is_active", true); - - // Get completion statistics - const { data: progressData } = await supabase - .from("assignment_enrollments") - .select( - ` - status, - classroom_assignments!inner(classroom_id) - ` - ) - .eq("classroom_assignments.classroom_id", classroomId); - // Calculate completion rate const totalEnrollments = progressData?.length || 0; const completedEnrollments = diff --git a/app/api/classrooms/route.ts b/app/api/classrooms/route.ts index 1843a3f7..faf69630 100644 --- a/app/api/classrooms/route.ts +++ b/app/api/classrooms/route.ts @@ -45,21 +45,37 @@ export async function GET(request: NextRequest) { const classroomIds = (memberships || []).map((m) => m.classroom_id); let classroomsMap: Record = {}; + // Get member counts for all classrooms + const memberCounts: Record = {}; + const studentCounts: Record = {}; + const instructorCounts: Record = {}; + const taCounts: Record = {}; + if (classroomIds.length > 0) { - const { data: classroomsData, error: classroomsError } = await supabase - .from("classrooms") - .select(` - id, - name, - description, - instructor_id, - join_code, - max_students, - is_active, - created_at, - updated_at - `) - .in("id", classroomIds); + // ⚡ Bolt Optimization: Fetch classrooms and member counts concurrently to avoid waterfall + const [ + { data: classroomsData, error: classroomsError }, + { data: countData } + ] = await Promise.all([ + supabase + .from("classrooms") + .select(` + id, + name, + description, + instructor_id, + join_code, + max_students, + is_active, + created_at, + updated_at + `) + .in("id", classroomIds), + supabase + .from("classroom_memberships") + .select("classroom_id, role") + .in("classroom_id", classroomIds) + ]); if (classroomsError) { console.error("Error fetching classrooms details:", classroomsError); @@ -73,22 +89,6 @@ export async function GET(request: NextRequest) { acc[classroom.id] = classroom; return acc; }, {} as Record); - } - - // Get member counts for all classrooms - // const classroomIds is already defined above - - const memberCounts: Record = {}; - const studentCounts: Record = {}; - const instructorCounts: Record = {}; - const taCounts: Record = {}; - - if (classroomIds.length > 0) { - // Get total member counts - const { data: countData } = await supabase - .from("classroom_memberships") - .select("classroom_id, role") - .in("classroom_id", classroomIds); if (countData) { countData.forEach((row) => {