initialize project with basic structure and dependencies

This commit is contained in:
ImBenji
2026-04-27 20:56:49 +01:00
parent 59b85afd10
commit 8548717074
85 changed files with 19634 additions and 0 deletions
+12
View File
@@ -0,0 +1,12 @@
import { drizzle } from "drizzle-orm/better-sqlite3";
import Database from "better-sqlite3";
import * as schema from "./schema";
import { resolve } from "path";
const dbPath = process.env.DATABASE_PATH || resolve(process.cwd(), "revisione.db");
const sqlite = new Database(dbPath);
sqlite.pragma("journal_mode = WAL");
sqlite.pragma("foreign_keys = ON");
export const db = drizzle(sqlite, { schema });
+8
View File
@@ -0,0 +1,8 @@
import { migrate } from "drizzle-orm/better-sqlite3/migrator";
import { db } from "./index";
import { resolve } from "path";
const migrationsFolder = resolve(process.cwd(), "drizzle");
migrate(db, { migrationsFolder });
console.log("Migrations complete");
+92
View File
@@ -0,0 +1,92 @@
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"),
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"),
});
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"),
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'))`),
});