import { NextRequest, NextResponse } from "next/server"; import { getDatabase } from "../../../../lib/database/index"; import { auth } from "@clerk/nextjs/server"; import log from "@/lib/logger"; import { fitnessProfileSchema } from "@/lib/validation/schemas"; import { validateRequestBody, validationErrorResponse, } from "@/lib/validation/helpers"; import { getFitnessProfilesByGym } from "@/lib/gym-context"; import { ensureUserSynced } from "@/lib/sync-user"; export async function POST(request: NextRequest) { try { const db = await getDatabase(); // Validate request body const validation = await validateRequestBody(request, fitnessProfileSchema); if (!validation.success) { log.warn("Fitness profile validation failed", { errors: validation.errors, }); return validationErrorResponse(validation.errors); } const profileData = validation.data; // Check if user exists const user = await db.getUserById(profileData.userId); if (!user) { return NextResponse.json({ error: "User not found" }, { status: 404 }); } // Check if profile already exists const existingProfile = await db.getFitnessProfileByUserId( profileData.userId, ); let profile; if (existingProfile) { // Update - omit userId from update data const { userId, ...updateData } = profileData; profile = await db.updateFitnessProfile(userId, updateData as any); } else { // Create - omit userId since the function signature expects it separately const { userId, ...createData } = profileData; profile = await db.createFitnessProfile({ userId, ...createData } as any); } return NextResponse.json( { message: "Fitness profile saved successfully", profile, }, { status: 201 }, ); } catch (error) { log.error("Failed to save fitness profile", error); return NextResponse.json( { error: "Internal server error" }, { status: 500 }, ); } } export async function GET(request: NextRequest) { try { // First authenticate const { userId: clerkUserId } = await auth(); if (!clerkUserId) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } const db = await getDatabase(); const currentUser = await ensureUserSynced(clerkUserId, db); if (!currentUser) { return NextResponse.json({ error: "Forbidden" }, { status: 403 }); } const { searchParams } = new URL(request.url); const targetUserId = searchParams.get("userId"); // If accessing another user's profile, verify gym access if (targetUserId && targetUserId !== clerkUserId) { const isStaff = currentUser.role === "admin" || currentUser.role === "superAdmin" || currentUser.role === "trainer"; if (!isStaff) { return NextResponse.json({ error: "Forbidden" }, { status: 403 }); } // Staff need to verify target user is in same gym if (currentUser.role !== "superAdmin") { const targetUser = await db.getUserById(targetUserId); if (!targetUser || targetUser.gymId !== currentUser.gymId) { return NextResponse.json( { error: "Forbidden - Cannot access users from other gyms" }, { status: 403 }, ); } } } if (targetUserId) { const profile = await db.getFitnessProfileByUserId(targetUserId); if (!profile) { return NextResponse.json( { error: "Profile not found" }, { status: 404 }, ); } return NextResponse.json({ profile }); } // Staff get gym-scoped profiles const isStaff = currentUser.role === "admin" || currentUser.role === "superAdmin" || currentUser.role === "trainer"; if (isStaff) { const targetGymId = currentUser.role === "superAdmin" ? (searchParams.get("gymId") ?? undefined) : (currentUser.gymId ?? undefined); const profiles = targetGymId ? await getFitnessProfilesByGym(targetGymId) : await db.getAllFitnessProfiles(); return NextResponse.json({ profiles }); } // Regular users only get their own const profile = await db.getFitnessProfileByUserId(clerkUserId); return NextResponse.json({ profile: profile ? [profile] : [] }); } catch (error) { log.error("Failed to get fitness profiles", error); return NextResponse.json( { error: "Internal server error" }, { status: 500 }, ); } }