storage: 服务端存储加固(原子落盘fsync/损坏隔离/墓碑14天GC/空同步不落盘/当日首份快照不可变/每周深快照/大批删除前置快照/health增强)
This commit is contained in:
@@ -75,7 +75,8 @@ async function main() {
|
||||
check('LWW 反向: 旧 work_start 被墓碑', tombsOf(lwwR2).some(t => t.table === 'setting' && t.uuid === 'su1'))
|
||||
|
||||
await post('/api/sync', { tables: { memo: [row('memo', { uuid: 'mt1', title: '待删', content: 'x', updated_at: '2026-04-01T00:00:00' }), row('memo', { uuid: 'ms2', title: '更迟', content: 'y', updated_at: '2030-01-01T00:00:00' })] } }, tokA)
|
||||
const delPush = await post('/api/sync', { tombstones: [{ table: 'memo', uuid: 'mt1', deleted_at: '2026-04-02T00:00:00' }] }, tokA)
|
||||
// deleted_at 用当前时间:过期墓碑会被服务端 14 天 GC 自动回收(这是预期行为,不能用老日期验证回传)
|
||||
const delPush = await post('/api/sync', { tombstones: [{ table: 'memo', uuid: 'mt1', deleted_at: new Date().toISOString() }] }, tokA)
|
||||
check('墓碑同步后行被清除', !((rowsOf(delPush).memo || []).some(x => x.uuid === 'mt1')))
|
||||
check('新于删除时间的行保留(防误删)', (rowsOf(delPush).memo || []).some(x => x.uuid === 'ms2'))
|
||||
check('墓碑记录回传', tombsOf(delPush).some(t => t.table === 'memo' && t.uuid === 'mt1'))
|
||||
@@ -127,7 +128,10 @@ async function main() {
|
||||
const aRec = regJson.users.find(u => u.username === 'audit_a')
|
||||
check('注册表仅存哈希不存明文密码', !!aRec && !JSON.stringify(aRec).includes('aapass'))
|
||||
await new Promise(r => globalThis.setTimeout(r, 400))
|
||||
check('启动自动备份已生成', fsMod.existsSync('server/data/backups/' + new Date().toISOString().slice(0, 10) + '/registry.json'))
|
||||
// 当日首份快照不可变:registry.json 可能位于当日基准目录或其 _t 时间戳副本
|
||||
const today = new Date().toISOString().slice(0, 10)
|
||||
const todayDirs = fsMod.readdirSync('server/data/backups').filter(d => d.startsWith(today))
|
||||
check('启动自动备份已生成', todayDirs.length > 0 && todayDirs.some(d => fsMod.existsSync('server/data/backups/' + d + '/registry.json')), todayDirs.join(','))
|
||||
const hInfo = await fetch(BASE + '/api/health').then(x => x.json()).catch(() => ({}))
|
||||
check('health 暴露备份状态', hInfo && hInfo.backup === 'local-only', hInfo.backup)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user