Files
hop.noname.company/scripts/reset-transfer-records.mjs

52 lines
1.9 KiB
JavaScript

// Offline maintenance only. The NAS wrapper checks that hop is stopped first.
import Database from 'better-sqlite3';
if (!process.argv.includes('--confirm-reset-transfer-records')) {
throw Error('전송·보관 기록 초기화에는 --confirm-reset-transfer-records가 필요합니다.');
}
const path = process.env.DATABASE_PATH;
if (!path || path === ':memory:') throw Error('기존 DATABASE_PATH를 지정하세요.');
const database = new Database(path, { fileMustExist: true });
try {
database.pragma('foreign_keys = ON');
database.pragma('busy_timeout = 5000');
const tables = [
'vault_transfers',
'request_receipt_accounts',
'deletion_targets',
'deletion_operations',
'item_access',
'items',
'quota_reservations',
'file_upload_contexts',
'files',
'transfer_batches',
'transfer_requests',
'idempotency_records',
'guest_blocks',
'space_members',
'connection_spaces',
'browser_devices',
'guest_sessions',
];
const existing = new Set(
database
.prepare("SELECT name FROM sqlite_master WHERE type = 'table'")
.all()
.map((row) => row.name),
);
const users = database.prepare('SELECT count(*) AS count FROM users').get().count;
database.transaction(() => {
for (const table of tables) if (existing.has(table)) database.exec(`DELETE FROM "${table}"`);
if (database.pragma('foreign_key_check').length) throw Error('외래 키 검사 실패');
if (database.prepare('SELECT count(*) AS count FROM users').get().count !== users)
throw Error('계정 수 검사 실패');
})();
database.pragma('wal_checkpoint(TRUNCATE)');
console.log(`전송·보관 기록 초기화 완료. 계정 ${users}개와 인증·관리 설정은 유지했습니다.`);
console.log(
'uploads 폴더의 내용은 삭제하지 않았습니다. 서비스가 중지된 동안 폴더 안의 내용을 비운 뒤 재배포하세요.',
);
} finally {
database.close();
}