fix(build): re-add db:reset script and provide canonical backup bundle for Docker build
This commit is contained in:
+24
-13
@@ -6,6 +6,7 @@ import { DatabaseSync } from "node:sqlite";
|
||||
|
||||
const root = path.resolve(import.meta.dirname, "..");
|
||||
const databasePath = path.join(root, "var", "recipe-book.sqlite");
|
||||
const defaultSeedPath = path.join(root, "data", "recipe-book-backup.json");
|
||||
|
||||
// Dynamically import compiled or source backup engine
|
||||
import { exportDatabase } from "../src/lib/backup/export-database.ts";
|
||||
@@ -18,12 +19,12 @@ Formulation Database Backup & Restore Tool
|
||||
|
||||
Usage:
|
||||
node scripts/backup.mjs export [output-path.json]
|
||||
node scripts/backup.mjs import <input-path.json> [--replace | --merge]
|
||||
node scripts/backup.mjs import [input-path.json] [--replace | --merge]
|
||||
node scripts/backup.mjs validate <input-path.json>
|
||||
|
||||
Commands:
|
||||
export Extracts all 25 SQLite tables into a standardized JSON backup bundle.
|
||||
import Restores or merges a backup bundle into the active SQLite database.
|
||||
import Restores or merges a backup bundle into the active SQLite database (defaults to data/recipe-book-backup.json).
|
||||
validate Checks a backup JSON file for schema integrity without modifying the database.
|
||||
|
||||
Options:
|
||||
@@ -32,6 +33,21 @@ Options:
|
||||
`);
|
||||
}
|
||||
|
||||
function ensureDatabaseSchema(db) {
|
||||
const migrationsDir = path.join(root, "migrations");
|
||||
if (fs.existsSync(migrationsDir)) {
|
||||
const files = fs.readdirSync(migrationsDir).filter((f) => f.endsWith(".sql")).sort();
|
||||
for (const file of files) {
|
||||
try {
|
||||
const sql = fs.readFileSync(path.join(migrationsDir, file), "utf8");
|
||||
db.exec(sql);
|
||||
} catch {
|
||||
// Schema migrations may already be partially or fully applied
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const args = process.argv.slice(2);
|
||||
const command = args[0]?.toLowerCase();
|
||||
@@ -67,11 +83,7 @@ async function main() {
|
||||
}
|
||||
|
||||
if (command === "validate") {
|
||||
const inputPath = args[1];
|
||||
if (!inputPath) {
|
||||
console.error("Error: Please specify the path to a backup JSON file to validate.");
|
||||
process.exit(1);
|
||||
}
|
||||
const inputPath = args[1] || defaultSeedPath;
|
||||
const resolvedPath = path.resolve(process.cwd(), inputPath);
|
||||
if (!fs.existsSync(resolvedPath)) {
|
||||
console.error(`Error: File not found: ${resolvedPath}`);
|
||||
@@ -101,7 +113,8 @@ async function main() {
|
||||
}
|
||||
|
||||
if (command === "import") {
|
||||
const inputPath = args[1];
|
||||
const fileArg = args.find((arg, idx) => idx > 0 && !arg.startsWith("--"));
|
||||
const inputPath = fileArg || (fs.existsSync(defaultSeedPath) ? defaultSeedPath : null);
|
||||
if (!inputPath) {
|
||||
console.error("Error: Please specify the path to a backup JSON file to import.");
|
||||
process.exit(1);
|
||||
@@ -115,12 +128,10 @@ async function main() {
|
||||
const mode = args.includes("--merge") ? "merge" : "replace";
|
||||
const content = JSON.parse(fs.readFileSync(resolvedPath, "utf8"));
|
||||
|
||||
if (!fs.existsSync(databasePath)) {
|
||||
console.error(`Error: Database not found at ${databasePath}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
fs.mkdirSync(path.dirname(databasePath), { recursive: true });
|
||||
const db = new DatabaseSync(databasePath);
|
||||
ensureDatabaseSchema(db);
|
||||
|
||||
try {
|
||||
console.log(`Importing '${inputPath}' into database (mode: ${mode})...`);
|
||||
const result = importDatabase(db, content, { mode, rebuildProjections: true });
|
||||
|
||||
Reference in New Issue
Block a user