FitnessApp/app/api/classes/route.ts

109 lines
3.0 KiB
TypeScript

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 }
);
}
}