initialize project with basic structure and dependencies
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
import { db } from "../../../db/index";
|
||||
import { courses, uploads, topics, lessons, quizQuestions, userProgress } from "../../../db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { verifyLicenseKey } from "../../../utils/license";
|
||||
import { rm } from "fs/promises";
|
||||
import { resolve } from "path";
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const key = getHeader(event, "x-license-key") ?? "";
|
||||
if (!verifyLicenseKey(key)) {
|
||||
throw createError({ statusCode: 401, message: "Invalid or expired license key" });
|
||||
}
|
||||
|
||||
const id = getRouterParam(event, "id")!;
|
||||
|
||||
const course = await db.query.courses.findFirst({ where: eq(courses.id, id) });
|
||||
if (!course) throw createError({ statusCode: 404, message: "Course not found" });
|
||||
|
||||
// delete child records in order
|
||||
const courseTopics = await db.query.topics.findMany({ where: eq(topics.courseId, id) });
|
||||
|
||||
for (const topic of courseTopics) {
|
||||
await db.delete(lessons).where(eq(lessons.topicId, topic.id));
|
||||
await db.delete(quizQuestions).where(eq(quizQuestions.topicId, topic.id));
|
||||
await db.delete(userProgress).where(eq(userProgress.topicId, topic.id));
|
||||
}
|
||||
|
||||
await db.delete(topics).where(eq(topics.courseId, id));
|
||||
await db.delete(uploads).where(eq(uploads.courseId, id));
|
||||
await db.delete(userProgress).where(eq(userProgress.courseId, id));
|
||||
await db.delete(courses).where(eq(courses.id, id));
|
||||
|
||||
// clean up uploaded files on disk
|
||||
try {
|
||||
const uploadDir = resolve(process.cwd(), "uploads", id);
|
||||
await rm(uploadDir, { recursive: true, force: true });
|
||||
} catch {
|
||||
// non-fatal
|
||||
}
|
||||
|
||||
return { ok: true };
|
||||
});
|
||||
@@ -29,7 +29,8 @@ export default defineEventHandler(async (event) => {
|
||||
? await db.query.lessons.findMany({ where: inArray(lessons.topicId, topicIds) })
|
||||
: [];
|
||||
|
||||
const lessonTopicIds = new Set(lessonRows.map((l) => l.topicId));
|
||||
const lessonMap: Record<string, typeof lessonRows[0]> = {};
|
||||
for (const l of lessonRows) lessonMap[l.topicId] = l;
|
||||
|
||||
return {
|
||||
...course,
|
||||
@@ -37,7 +38,8 @@ export default defineEventHandler(async (event) => {
|
||||
...t,
|
||||
prerequisiteTopicIds: JSON.parse(t.prerequisiteTopicIds ?? "[]"),
|
||||
progress: progressMap[t.id] ?? null,
|
||||
hasLesson: lessonTopicIds.has(t.id),
|
||||
hasLesson: !!lessonMap[t.id],
|
||||
lessonCost: lessonMap[t.id]?.costTotal ?? null,
|
||||
})),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { db } from "../../../db/index";
|
||||
import { topics, lessons } from "../../../db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { generateLesson } from "../../../utils/generateLesson";
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const id = getRouterParam(event, "id")!;
|
||||
|
||||
const topic = await db.query.topics.findFirst({ where: eq(topics.id, id) });
|
||||
if (!topic) throw createError({ statusCode: 404, message: "Topic not found" });
|
||||
|
||||
if (topic.status === "ready") {
|
||||
return { status: "ready" };
|
||||
}
|
||||
|
||||
if (topic.status === "generating") {
|
||||
return { status: "generating" };
|
||||
}
|
||||
|
||||
try {
|
||||
await generateLesson(id);
|
||||
return { status: "ready" };
|
||||
} catch (err: any) {
|
||||
console.error(`[generate.post] topic ${id} failed: ${err?.message ?? err}`);
|
||||
return { status: "error" };
|
||||
}
|
||||
});
|
||||
@@ -14,5 +14,6 @@ export default defineEventHandler(async (event) => {
|
||||
return {
|
||||
...lesson,
|
||||
content: JSON.parse(lesson.content),
|
||||
branchStatus: lesson.branchStatus,
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user