Revisione/server/db/schema.ts

101 lines
3.6 KiB
TypeScript

import { sqliteTable, text, integer, real } from "drizzle-orm/sqlite-core";
import { sql } from "drizzle-orm";
export const courses = sqliteTable("courses", {
id: text("id").primaryKey(),
title: text("title").notNull(),
subject: text("subject").notNull(),
status: text("status", { enum: ["processing", "ready", "error"] })
.notNull()
.default("processing"),
stage: text("stage", {
enum: ["parsing_pdfs", "analysing_sources", "building_curriculum", "finalising", "ready", "error"],
}),
costAI: real("cost_ai").default(0),
costAudio: real("cost_audio").default(0),
auditReport: text("audit_report"),
auditScore: integer("audit_score"),
auditStatus: text("audit_status", { enum: ["pending", "running", "complete", "error"] }).default("pending"),
inferenceWarning: integer("inference_warning", { mode: "boolean" }).default(false),
organisation: text("organisation"),
createdAt: text("created_at")
.notNull()
.default(sql`(datetime('now'))`),
});
export const uploads = sqliteTable("uploads", {
id: text("id").primaryKey(),
courseId: text("course_id")
.notNull()
.references(() => courses.id),
filename: text("filename").notNull(),
type: text("type", { enum: ["slides", "past_paper", "lab_worksheet"] }).notNull(),
storedPath: text("stored_path").notNull(),
extractedText: text("extracted_text"),
createdAt: text("created_at")
.notNull()
.default(sql`(datetime('now'))`),
});
export const topics = sqliteTable("topics", {
id: text("id").primaryKey(),
courseId: text("course_id")
.notNull()
.references(() => courses.id),
title: text("title").notNull(),
description: text("description").notNull(),
order: integer("order").notNull(),
prerequisiteTopicIds: text("prerequisite_topic_ids").notNull().default("[]"),
difficulty: integer("difficulty").notNull().default(1),
relevantFiles: text("relevant_files"),
status: text("status", { enum: ["pending", "generating", "ready", "error"] }).notNull().default("pending"),
});
export const lessons = sqliteTable("lessons", {
id: text("id").primaryKey(),
topicId: text("topic_id")
.notNull()
.references(() => topics.id),
content: text("content").notNull(),
ttsProvider: text("tts_provider"),
costAI: real("cost_ai").default(0),
costAudio: real("cost_audio").default(0),
costBranchAI: real("cost_branch_ai").default(0),
costBranchAudio: real("cost_branch_audio").default(0),
costTotal: real("cost_total").default(0),
branchStatus: text("branch_status", { enum: ["pending", "generating", "ready", "error"] }).notNull().default("pending"),
createdAt: text("created_at")
.notNull()
.default(sql`(datetime('now'))`),
});
export const quizQuestions = sqliteTable("quiz_questions", {
id: text("id").primaryKey(),
topicId: text("topic_id")
.notNull()
.references(() => topics.id),
question: text("question").notNull(),
type: text("type", { enum: ["mcq", "short_answer", "worked"] }).notNull(),
options: text("options"),
answer: text("answer").notNull(),
explanation: text("explanation").notNull(),
});
export const userProgress = sqliteTable("user_progress", {
id: text("id").primaryKey(),
courseId: text("course_id")
.notNull()
.references(() => courses.id),
topicId: text("topic_id")
.notNull()
.references(() => topics.id),
lessonComplete: integer("lesson_complete", { mode: "boolean" })
.notNull()
.default(false),
quizScore: integer("quiz_score"),
tookBranches: integer("took_branches", { mode: "boolean" }).notNull().default(false),
branchCount: integer("branch_count").notNull().default(0),
updatedAt: text("updated_at")
.notNull()
.default(sql`(datetime('now'))`),
});