51 lines
1.4 KiB
TypeScript
51 lines
1.4 KiB
TypeScript
import { randomBytes } from "crypto";
|
|
import { prisma } from "@/lib/prisma";
|
|
import { getUserCourseProgress } from "@/lib/course-progress";
|
|
|
|
function makeCode() {
|
|
return `FA-${randomBytes(5).toString("hex").toUpperCase()}`;
|
|
}
|
|
|
|
export async function syncCertificateForCourse(userId: string, courseId: string) {
|
|
const { total, completed } = await getUserCourseProgress(userId, courseId);
|
|
|
|
const existing = await prisma.certificate.findUnique({
|
|
where: { userId_courseId: { userId, courseId } },
|
|
});
|
|
|
|
if (total === 0 || completed < total) {
|
|
if (existing) {
|
|
await prisma.certificate.delete({ where: { id: existing.id } });
|
|
}
|
|
return { issued: false as const };
|
|
}
|
|
|
|
if (existing) {
|
|
return { issued: true as const, code: existing.code };
|
|
}
|
|
|
|
let code = makeCode();
|
|
for (let i = 0; i < 8; i++) {
|
|
const clash = await prisma.certificate.findUnique({ where: { code } });
|
|
if (!clash) break;
|
|
code = makeCode();
|
|
}
|
|
|
|
await prisma.certificate.create({
|
|
data: { userId, courseId, code },
|
|
});
|
|
|
|
return { issued: true as const, code };
|
|
}
|
|
|
|
export async function clearCourseProgress(userId: string, courseId: string) {
|
|
const lessons = await prisma.lesson.findMany({
|
|
where: { module: { courseId } },
|
|
select: { id: true },
|
|
});
|
|
await prisma.lessonProgress.deleteMany({
|
|
where: { userId, lessonId: { in: lessons.map((l) => l.id) } },
|
|
});
|
|
await prisma.certificate.deleteMany({ where: { userId, courseId } });
|
|
}
|