Redirect /teacher/exams/grading* to /teacher/homework/submissions; remove exam grading UI/actions/data-access; add homework student workflow and update design docs.
91 lines
2.9 KiB
JavaScript
91 lines
2.9 KiB
JavaScript
require("dotenv/config");
|
||
|
||
const fs = require("node:fs");
|
||
const crypto = require("node:crypto");
|
||
const path = require("node:path");
|
||
const mysql = require("mysql2/promise");
|
||
|
||
const JOURNAL = {
|
||
"0000_aberrant_cobalt_man": 1766460456274,
|
||
"0001_flawless_texas_twister": 1767004087964,
|
||
"0002_equal_wolfpack": 1767145757594,
|
||
};
|
||
|
||
function sha256Hex(input) {
|
||
return crypto.createHash("sha256").update(input).digest("hex");
|
||
}
|
||
|
||
async function main() {
|
||
const url = process.env.DATABASE_URL;
|
||
if (!url) {
|
||
throw new Error("DATABASE_URL is not set");
|
||
}
|
||
|
||
const conn = await mysql.createConnection(url);
|
||
|
||
await conn.query(
|
||
"CREATE TABLE IF NOT EXISTS `__drizzle_migrations` (id serial primary key, hash text not null, created_at bigint)"
|
||
);
|
||
|
||
const [existing] = await conn.query(
|
||
"SELECT id, hash, created_at FROM `__drizzle_migrations` ORDER BY created_at DESC LIMIT 1"
|
||
);
|
||
if (Array.isArray(existing) && existing.length > 0) {
|
||
console.log("✅ __drizzle_migrations already has entries. Skip baselining.");
|
||
await conn.end();
|
||
return;
|
||
}
|
||
|
||
const [[accountsRow]] = await conn.query(
|
||
"SELECT COUNT(*) AS cnt FROM information_schema.tables WHERE table_schema=DATABASE() AND table_name='accounts'"
|
||
);
|
||
const accountsExists = Number(accountsRow?.cnt ?? 0) > 0;
|
||
if (!accountsExists) {
|
||
console.log("ℹ️ No existing tables detected (accounts missing). Skip baselining.");
|
||
await conn.end();
|
||
return;
|
||
}
|
||
|
||
const [[structureRow]] = await conn.query(
|
||
"SELECT COUNT(*) AS cnt FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='exams' AND column_name='structure'"
|
||
);
|
||
const examsStructureExists = Number(structureRow?.cnt ?? 0) > 0;
|
||
|
||
const [[homeworkRow]] = await conn.query(
|
||
"SELECT COUNT(*) AS cnt FROM information_schema.tables WHERE table_schema=DATABASE() AND table_name='homework_assignments'"
|
||
);
|
||
const homeworkExists = Number(homeworkRow?.cnt ?? 0) > 0;
|
||
|
||
const baselineTags = [];
|
||
baselineTags.push("0000_aberrant_cobalt_man");
|
||
if (examsStructureExists) baselineTags.push("0001_flawless_texas_twister");
|
||
if (homeworkExists) baselineTags.push("0002_equal_wolfpack");
|
||
|
||
const drizzleDir = path.resolve(__dirname, "..", "..", "drizzle");
|
||
for (const tag of baselineTags) {
|
||
const sqlPath = path.join(drizzleDir, `${tag}.sql`);
|
||
if (!fs.existsSync(sqlPath)) {
|
||
throw new Error(`Missing migration file: ${sqlPath}`);
|
||
}
|
||
const sqlText = fs.readFileSync(sqlPath).toString();
|
||
const hash = sha256Hex(sqlText);
|
||
const createdAt = JOURNAL[tag];
|
||
if (typeof createdAt !== "number") {
|
||
throw new Error(`Missing journal timestamp for: ${tag}`);
|
||
}
|
||
await conn.query(
|
||
"INSERT INTO `__drizzle_migrations` (`hash`, `created_at`) VALUES (?, ?)",
|
||
[hash, createdAt]
|
||
);
|
||
}
|
||
|
||
console.log(`✅ Baselined __drizzle_migrations: ${baselineTags.join(", ")}`);
|
||
await conn.end();
|
||
}
|
||
|
||
main().catch((err) => {
|
||
console.error("❌ Baseline failed:", err);
|
||
process.exit(1);
|
||
});
|
||
|