import { NextRequest, NextResponse } from 'next/server'; import { z } from 'zod'; import { prisma, getTenantPrisma } from '@/lib/prisma'; import { generateJitsiRoomName } from '@/lib/jitsi'; const CreateClassSchema = z.object({ tenantId: z.string().min(1, 'tenantId is required'), title: z.string().min(1, 'title is required'), description: z.string().optional(), startTime: z.string().or(z.date()), endTime: z.string().or(z.date()), capacity: z.number().int().positive().default(20), }); export async function POST(req: NextRequest) { try { const body = await req.json(); const validated = CreateClassSchema.parse(body); // 1. Verify tenant existence const tenant = await prisma.tenant.findUnique({ where: { id: validated.tenantId }, }); if (!tenant) { return NextResponse.json( { error: 'Tenant not found' }, { status: 404 } ); } const start = new Date(validated.startTime); const end = new Date(validated.endTime); const timestamp = Date.now(); // 2. Generate deterministic tenant-isolated Jitsi room name const tempSessionId = `temp-${Math.random().toString(36).slice(2, 8)}`; const jitsiRoomId = generateJitsiRoomName(tenant.slug, tempSessionId, timestamp); // 3. Create ClassSession in PostgreSQL via tenant-scoped Prisma client const tenantPrisma = getTenantPrisma(tenant.id); const classSession = await tenantPrisma.classSession.create({ data: { tenantId: tenant.id, title: validated.title, description: validated.description, startTime: start, endTime: end, capacity: validated.capacity, jitsiRoomId, }, }); return NextResponse.json( { success: true, classSession, roomName: classSession.jitsiRoomId, }, { status: 201 } ); } catch (error: any) { if (error instanceof z.ZodError) { return NextResponse.json( { error: 'Validation failed', details: error.issues }, { status: 400 } ); } console.error('Error creating class session:', error); return NextResponse.json( { error: error.message || 'Internal server error' }, { status: 500 } ); } } export async function GET(req: NextRequest) { try { const { searchParams } = new URL(req.url); const tenantId = searchParams.get('tenantId'); if (!tenantId) { return NextResponse.json( { error: 'tenantId query parameter is required' }, { status: 400 } ); } const tenantPrisma = getTenantPrisma(tenantId); const classes = await tenantPrisma.classSession.findMany({ orderBy: { startTime: 'asc' }, include: { bookings: { include: { user: true, }, }, }, }); return NextResponse.json({ classes }); } catch (error: any) { return NextResponse.json( { error: error.message || 'Internal server error' }, { status: 500 } ); } }