Refactor Study Desk application structure

This commit is contained in:
Elijah 2026-08-07 19:31:23 -07:00
parent faaccf8a7e
commit 089439ed90
145 changed files with 8087 additions and 3412 deletions

View file

@ -0,0 +1,83 @@
import { randomUUID } from "node:crypto";
import { mkdirSync, readFileSync, readdirSync, rmSync } from "node:fs";
import path from "node:path";
import { spawn } from "node:child_process";
import Database from "better-sqlite3";
const root = path.join(process.cwd(), ".test-databases");
const directory = path.join(root, `http-smoke-${randomUUID()}`);
if (!path.resolve(directory).startsWith(`${path.resolve(root)}${path.sep}`)) {
throw new Error("Unsafe disposable HTTP smoke path");
}
mkdirSync(directory, { recursive: true });
const databasePath = path.join(directory, "http-smoke.test.db");
const database = new Database(databasePath);
try {
database.pragma("foreign_keys = ON");
for (const migration of readdirSync(path.join(process.cwd(), "prisma", "migrations"), { withFileTypes: true })
.filter((entry) => entry.isDirectory())
.map((entry) => entry.name)
.sort()) {
database.exec(readFileSync(path.join(process.cwd(), "prisma", "migrations", migration, "migration.sql"), "utf8"));
}
} finally {
database.close();
}
const port = 3789;
const server = spawn(
process.execPath,
[path.join(process.cwd(), "node_modules", "next", "dist", "bin", "next"), "start", "-p", String(port)],
{
cwd: process.cwd(),
env: {
...process.env,
NODE_ENV: "production",
DATABASE_URL: `file:${databasePath.replaceAll("\\", "/")}`,
SESSION_SECRET: "http-smoke-secret-0123456789abcdef0123456789",
ALLOW_INITIAL_SETUP: "true",
},
stdio: ["ignore", "pipe", "pipe"],
windowsHide: true,
}
);
let output = "";
server.stdout.on("data", (chunk) => { output += chunk.toString(); });
server.stderr.on("data", (chunk) => { output += chunk.toString(); });
try {
let health;
for (let attempt = 0; attempt < 30; attempt += 1) {
try {
health = await fetch(`http://127.0.0.1:${port}/api/health`);
if (health.ok) break;
} catch {}
await new Promise((resolve) => setTimeout(resolve, 500));
}
if (!health?.ok) throw new Error(`Health check did not become ready.\n${output}`);
const login = await fetch(`http://127.0.0.1:${port}/login`);
const setup = await fetch(`http://127.0.0.1:${port}/api/auth/setup-status`);
const setupBody = await setup.json();
const protectedDot = await fetch(`http://127.0.0.1:${port}/api/decks/file.json`, { redirect: "manual" });
if (!login.ok || !setup.ok || setupBody.setupRequired !== true || setupBody.setupAllowed !== true || protectedDot.status !== 307) {
throw new Error("HTTP smoke responses did not match the production contract");
}
console.info(JSON.stringify({
health: health.status,
login: login.status,
setup: setupBody,
protectedDot: { status: protectedDot.status, location: protectedDot.headers.get("location") },
}, null, 2));
if (process.argv.includes("--stay")) {
console.info(`Browser smoke server ready at http://127.0.0.1:${port}/login`);
await new Promise(() => {});
}
} finally {
server.kill();
await new Promise((resolve) => {
if (server.exitCode !== null) return resolve();
server.once("exit", resolve);
setTimeout(resolve, 2_000);
});
rmSync(directory, { recursive: true, force: true });
}