Initial commit
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
// /app/api/enrollments/route.ts
|
||||
import { NextResponse } from 'next/server';
|
||||
import type { NextRequest } from 'next/server';
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
// --- GET --------------------------------------------------------------------
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
const enrollments = await prisma.enrollment.findMany({
|
||||
include: {
|
||||
user: { select: { id: true, name: true, email: true } },
|
||||
course: { select: { id: true, title: true, code: true, } },
|
||||
},
|
||||
orderBy: { createdAt: 'asc' },
|
||||
});
|
||||
return NextResponse.json(enrollments);
|
||||
} catch (err) {
|
||||
console.error('GET /api/enrollments error', err);
|
||||
return NextResponse.json({ error: 'Failed to fetch enrollments' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
// --- POST --------------------------------------------------------------------
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
try {
|
||||
const body = await req.json();
|
||||
|
||||
// incoming payload example:
|
||||
// { userId: "cmicsu2030000uaec0sp56gso", courseId: "cmicrx1b70000uahwilu0gh9u", role: "student" }
|
||||
const userId: string | undefined = body.userId;
|
||||
const courseId: string | undefined = body.courseId;
|
||||
// const role: string = body.role ?? 'student';
|
||||
|
||||
if (!userId || !courseId) {
|
||||
return NextResponse.json({ error: 'Missing userId or courseId' }, { status: 400 });
|
||||
}
|
||||
|
||||
// Optional: Prevent duplicate enrolments
|
||||
const existing = await prisma.enrollment.findFirst({
|
||||
where: { userId: userId, courseId: courseId },
|
||||
});
|
||||
|
||||
if (existing) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Enrollment already exists' },
|
||||
{ status: 409 }
|
||||
);
|
||||
}
|
||||
|
||||
// Create enrollment using STRING IDs
|
||||
const enrollment = await prisma.enrollment.create({
|
||||
data: {
|
||||
user: { connect: { id: userId } },
|
||||
course: { connect: { id: courseId } },
|
||||
// role: role,
|
||||
},
|
||||
include: {
|
||||
user: { select: { id: true, name: true, email: true } },
|
||||
course: { select: { id: true, title: true } },
|
||||
},
|
||||
});
|
||||
|
||||
return NextResponse.json(enrollment, { status: 201 });
|
||||
} catch (err) {
|
||||
console.error('POST /api/enrollments error', err);
|
||||
return NextResponse.json({ error: 'Failed to create enrollment' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
// --- DELETE --------------------------------------------------------------------
|
||||
|
||||
export async function DELETE(req: NextRequest) {
|
||||
try {
|
||||
const body = await req.json();
|
||||
const id = body?.id;
|
||||
|
||||
if (!id) {
|
||||
return NextResponse.json({ error: 'Missing id' }, { status: 400 });
|
||||
}
|
||||
|
||||
await prisma.enrollment.delete({
|
||||
where: { id: id }, // STRING — not Number(id)
|
||||
});
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
} catch (err) {
|
||||
console.error('DELETE /api/enrollments error', err);
|
||||
return NextResponse.json({ error: 'Failed to delete enrollment' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
// app/api/enrollments/sync.ts
|
||||
import { NextResponse } from 'next/server';
|
||||
import type { NextRequest } from 'next/server';
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth-options';
|
||||
import { prisma } from '@/lib/prisma';
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] POST endpoint called');
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] Request method:', req.method);
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] Request URL:', req.url);
|
||||
|
||||
try {
|
||||
const session = await getServerSession(authOptions);
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] Session check:', !!session?.user?.email);
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] Session user:', session?.user);
|
||||
|
||||
if (!session?.user?.email) {
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] No session or email, returning 401');
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
const userEmail = session.user.email;
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] About to parse request body...');
|
||||
|
||||
const body = await req.json();
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] Raw body received:', JSON.stringify(body, null, 2));
|
||||
|
||||
const levels: string[] = body?.levels || [];
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] Extracted levels:', levels);
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] Levels type check - isArray:', Array.isArray(levels));
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] Levels length:', levels.length);
|
||||
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] User:', userEmail);
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] Received levels:', levels);
|
||||
|
||||
if (!Array.isArray(levels) || levels.length === 0) {
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] VALIDATION FAILED!');
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] levels isArray:', Array.isArray(levels));
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] levels length:', levels?.length);
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] levels value:', levels);
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] Returning 400 - Levels array required');
|
||||
return NextResponse.json(
|
||||
{ error: 'Levels array required' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Get user
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { email: userEmail },
|
||||
});
|
||||
if (!user) {
|
||||
console.log('[SYNC-ENROLLMENTS] User not found in database:', userEmail);
|
||||
return NextResponse.json({ error: 'User not found' }, { status: 404 });
|
||||
}
|
||||
|
||||
console.log('[SYNC-ENROLLMENTS] Found user:', user.id, user.email);
|
||||
|
||||
const createdEnrollments = [];
|
||||
|
||||
// For each course level, find the course and create enrollment
|
||||
for (const level of levels) {
|
||||
try {
|
||||
console.log('[SYNC-ENROLLMENTS] Looking for course with code:', level);
|
||||
|
||||
const course = await prisma.course.findUnique({
|
||||
where: { code: level },
|
||||
});
|
||||
|
||||
if (!course) {
|
||||
console.warn(`[SYNC-ENROLLMENTS] Course code not found: ${level}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
console.log('[SYNC-ENROLLMENTS] Found course:', course.id, course.code, course.title);
|
||||
|
||||
// Check if enrollment already exists
|
||||
const existing = await prisma.enrollment.findFirst({
|
||||
where: { userId: user.id, courseId: course.id },
|
||||
});
|
||||
|
||||
if (existing) {
|
||||
console.log('[SYNC-ENROLLMENTS] Enrollment already exists:', existing.id);
|
||||
} else {
|
||||
const enrollment = await prisma.enrollment.create({
|
||||
data: {
|
||||
userId: user.id,
|
||||
courseId: course.id,
|
||||
},
|
||||
});
|
||||
console.log('[SYNC-ENROLLMENTS] Created new enrollment:', enrollment.id);
|
||||
createdEnrollments.push({
|
||||
courseCode: level,
|
||||
courseId: course.id,
|
||||
enrollmentId: enrollment.id,
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`[SYNC-ENROLLMENTS] Failed to create enrollment for level ${level}:`, err);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('[SYNC-ENROLLMENTS] Summary - Created enrollments:', createdEnrollments.length);
|
||||
console.log('[SYNC-ENROLLMENTS] Details:', createdEnrollments);
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
message: 'Enrollments synced',
|
||||
created: createdEnrollments,
|
||||
},
|
||||
{ status: 200 }
|
||||
);
|
||||
} catch (err) {
|
||||
console.error('🔥 [SYNC-ENROLLMENTS] FATAL ERROR:', err);
|
||||
console.error('🔥 [SYNC-ENROLLMENTS] Error stack:', err instanceof Error ? err.stack : 'No stack');
|
||||
return NextResponse.json(
|
||||
{ error: 'Failed to sync enrollments' },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
// app/api/enrollments/sync/route.ts
|
||||
import { NextResponse } from 'next/server';
|
||||
import type { NextRequest } from 'next/server';
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth-options';
|
||||
import { prisma } from '@/lib/prisma';
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] POST endpoint called');
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] Request method:', req.method);
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] Request URL:', req.url);
|
||||
|
||||
try {
|
||||
const session = await getServerSession(authOptions);
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] Session check:', !!session?.user?.email);
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] Session user:', session?.user);
|
||||
|
||||
if (!session?.user?.email) {
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] No session or email, returning 401');
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
const userEmail = session.user.email;
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] About to parse request body...');
|
||||
|
||||
const body = await req.json();
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] Raw body received:', JSON.stringify(body, null, 2));
|
||||
|
||||
const levels: string[] = body?.levels || [];
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] Extracted levels:', levels);
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] Levels type check - isArray:', Array.isArray(levels));
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] Levels length:', levels.length);
|
||||
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] User:', userEmail);
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] Received levels:', levels);
|
||||
|
||||
if (!Array.isArray(levels) || levels.length === 0) {
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] VALIDATION FAILED!');
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] levels isArray:', Array.isArray(levels));
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] levels length:', levels?.length);
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] levels value:', levels);
|
||||
console.log('🔥 [SYNC-ENROLLMENTS] Returning 400 - Levels array required');
|
||||
return NextResponse.json(
|
||||
{ error: 'Levels array required' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Get user
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { email: userEmail },
|
||||
});
|
||||
if (!user) {
|
||||
console.log('[SYNC-ENROLLMENTS] User not found in database:', userEmail);
|
||||
return NextResponse.json({ error: 'User not found' }, { status: 404 });
|
||||
}
|
||||
|
||||
console.log('[SYNC-ENROLLMENTS] Found user:', user.id, user.email);
|
||||
|
||||
const createdEnrollments = [];
|
||||
|
||||
// For each course level, find the course and create enrollment
|
||||
for (const level of levels) {
|
||||
try {
|
||||
console.log('[SYNC-ENROLLMENTS] Looking for course with code:', level);
|
||||
|
||||
const course = await prisma.course.findUnique({
|
||||
where: { code: level },
|
||||
});
|
||||
|
||||
if (!course) {
|
||||
console.warn(`[SYNC-ENROLLMENTS] Course code not found: ${level}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
console.log('[SYNC-ENROLLMENTS] Found course:', course.id, course.code, course.title);
|
||||
|
||||
// Check if enrollment already exists
|
||||
const existing = await prisma.enrollment.findFirst({
|
||||
where: { userId: user.id, courseId: course.id },
|
||||
});
|
||||
|
||||
if (existing) {
|
||||
console.log('[SYNC-ENROLLMENTS] Enrollment already exists:', existing.id);
|
||||
} else {
|
||||
const enrollment = await prisma.enrollment.create({
|
||||
data: {
|
||||
userId: user.id,
|
||||
courseId: course.id,
|
||||
},
|
||||
});
|
||||
console.log('[SYNC-ENROLLMENTS] Created new enrollment:', enrollment.id);
|
||||
createdEnrollments.push({
|
||||
courseCode: level,
|
||||
courseId: course.id,
|
||||
enrollmentId: enrollment.id,
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`[SYNC-ENROLLMENTS] Failed to create enrollment for level ${level}:`, err);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('[SYNC-ENROLLMENTS] Summary - Created enrollments:', createdEnrollments.length);
|
||||
console.log('[SYNC-ENROLLMENTS] Details:', createdEnrollments);
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
message: 'Enrollments synced',
|
||||
created: createdEnrollments,
|
||||
},
|
||||
{ status: 200 }
|
||||
);
|
||||
} catch (err) {
|
||||
console.error('🔥 [SYNC-ENROLLMENTS] FATAL ERROR:', err);
|
||||
console.error('🔥 [SYNC-ENROLLMENTS] Error stack:', err instanceof Error ? err.stack : 'No stack');
|
||||
return NextResponse.json(
|
||||
{ error: 'Failed to sync enrollments' },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user