Slim manual cloud backups and guard truncated journal rollback

This commit is contained in:
Hao19911125
2026-04-12 10:43:38 +08:00
parent aec756f180
commit 580a049442
4 changed files with 220 additions and 11 deletions

View File

@@ -1,5 +1,6 @@
import assert from "node:assert/strict";
import {
MANUAL_BACKUP_BATCH_JOURNAL_COVERAGE_KEY,
appendBatchJournal,
clearHistoryDirty,
cloneGraphSnapshot,
@@ -264,6 +265,32 @@ assert.ok(recoveryPoint);
assert.equal(recoveryPoint.path, "reverse-journal");
assert.equal(recoveryPoint.affectedJournals[0].processedRange[1], 3);
const truncatedCoverageGraph = createEmptyGraph();
truncatedCoverageGraph.historyState.chatId = "chat-truncated-history-test";
truncatedCoverageGraph.historyState[MANUAL_BACKUP_BATCH_JOURNAL_COVERAGE_KEY] = {
truncated: true,
earliestRetainedFloor: 4,
retainedCount: 4,
};
truncatedCoverageGraph.batchJournal = [
{ id: "journal-4", journalVersion: 2, processedRange: [4, 4] },
{ id: "journal-5", journalVersion: 2, processedRange: [5, 5] },
{ id: "journal-6", journalVersion: 2, processedRange: [6, 6] },
{ id: "journal-7", journalVersion: 2, processedRange: [7, 7] },
];
assert.equal(
findJournalRecoveryPoint(truncatedCoverageGraph, 3),
null,
"dirty floor earlier than retained backup coverage should reject partial rollback",
);
const retainedCoverageRecoveryPoint = findJournalRecoveryPoint(
truncatedCoverageGraph,
5,
);
assert.ok(retainedCoverageRecoveryPoint);
assert.equal(retainedCoverageRecoveryPoint.path, "reverse-journal");
assert.equal(retainedCoverageRecoveryPoint.affectedJournals.length, 3);
rollbackBatch(graph, recoveryPoint.affectedJournals[0]);
assert.equal(graph.nodes.length, 0);
assert.equal(graph.historyState.lastProcessedAssistantFloor, -1);