104 lines
2.5 KiB
TypeScript
104 lines
2.5 KiB
TypeScript
import { config as loadEnv } from "dotenv";
|
|
import { eq } from "drizzle-orm";
|
|
|
|
loadEnv({ path: ".env.local" });
|
|
|
|
function readArg(name: string) {
|
|
const prefix = `${name}=`;
|
|
const match = process.argv.find((arg) => arg.startsWith(prefix));
|
|
return match ? match.slice(prefix.length) : null;
|
|
}
|
|
|
|
async function main() {
|
|
const snapshotId = readArg("--snapshot-id");
|
|
const reason = readArg("--reason") || "manual-snapshot-restore";
|
|
|
|
if (!snapshotId) {
|
|
throw new Error(
|
|
"Usage: pnpm tsx scripts/system-settings/restore-snapshot.ts --snapshot-id=<id> [--reason=<reason>]"
|
|
);
|
|
}
|
|
|
|
const dbModule = await import("../../lib/db");
|
|
const schemaModule = await import("../../lib/db/schema");
|
|
|
|
const { db } = dbModule;
|
|
const { systemSettingHistory, systemSettingSnapshot, systemSettings } = schemaModule;
|
|
|
|
const [snapshot] = await db
|
|
.select({
|
|
id: systemSettingSnapshot.id,
|
|
scope: systemSettingSnapshot.scope,
|
|
data: systemSettingSnapshot.data,
|
|
})
|
|
.from(systemSettingSnapshot)
|
|
.where(eq(systemSettingSnapshot.id, snapshotId))
|
|
.limit(1);
|
|
|
|
if (!snapshot) {
|
|
throw new Error(`Snapshot not found: ${snapshotId}`);
|
|
}
|
|
|
|
const data =
|
|
snapshot.data && typeof snapshot.data === "object" && !Array.isArray(snapshot.data)
|
|
? (snapshot.data as Record<string, unknown>)
|
|
: {};
|
|
const keys = Object.keys(data);
|
|
|
|
await db.transaction(async (tx) => {
|
|
for (const key of keys) {
|
|
const [existing] = await tx
|
|
.select({ value: systemSettings.value })
|
|
.from(systemSettings)
|
|
.where(eq(systemSettings.key, key))
|
|
.limit(1);
|
|
|
|
const nextValue = data[key] ?? null;
|
|
|
|
await tx.insert(systemSettingHistory).values({
|
|
key,
|
|
previousValue: existing?.value ?? null,
|
|
nextValue,
|
|
reason,
|
|
changedAt: new Date(),
|
|
changedBy: null,
|
|
});
|
|
|
|
await tx
|
|
.insert(systemSettings)
|
|
.values({
|
|
key,
|
|
value: nextValue,
|
|
updatedAt: new Date(),
|
|
updatedBy: null,
|
|
})
|
|
.onConflictDoUpdate({
|
|
target: systemSettings.key,
|
|
set: {
|
|
value: nextValue,
|
|
updatedAt: new Date(),
|
|
updatedBy: null,
|
|
},
|
|
});
|
|
}
|
|
});
|
|
|
|
console.log(
|
|
JSON.stringify(
|
|
{
|
|
snapshotId,
|
|
scope: snapshot.scope,
|
|
restoredKeyCount: keys.length,
|
|
reason,
|
|
},
|
|
null,
|
|
2
|
|
)
|
|
);
|
|
}
|
|
|
|
main().catch((error) => {
|
|
console.error(error);
|
|
process.exit(1);
|
|
});
|