v0.307.0: after a restart the Databases table lists each database once, not every pre-restore undo copy
gates / gates (push) Successful in 1m14s

Seen on demo-hp 2026-10-10 (adventurelog x4, bookstack x4). The synthesised run skips IsUndo files; only undo copies
-> no synthesised run. Two tests, both red-proved. v0.306.0 (R-570) was built but never delivered; 0.307.0 carries it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-10-10 15:19:43 +02:00
parent 9e5b88146e
commit fc6466a50a
3 changed files with 81 additions and 5 deletions
+13 -4
View File
@@ -1311,6 +1311,12 @@ func (m *Manager) GetFullStatus(nextDBDump time.Time) *FullBackupStatus {
var results []DumpResult
var latestTime time.Time
for _, f := range status.DumpFiles {
// 2026-10-10: a `pre-restore-` undo copy (R-379) is not part of any run — it stays in the file
// list, never in the run's table (demo-hp listed adventurelog four times after a restart).
// Pinned by TestSynthesisedRunListsNoUndoCopy.
if f.IsUndo {
continue
}
results = append(results, DumpResult{
DB: DiscoveredDB{StackName: f.StackName, DBType: f.DBType, ContainerName: f.StackName},
FilePath: f.FileName,
@@ -1323,10 +1329,13 @@ func (m *Manager) GetFullStatus(nextDBDump time.Time) *FullBackupStatus {
}
// R-519: after a restart the run's result is not in memory, so it is SYNTHESISED from the files. A run
// the stop cut off left a fresh .sql beside last night's tars — "Success" must not be read off that.
status.LastDBDump = &DBDumpStatus{
LastRun: latestTime,
Results: results,
Success: m.runInterrupted.IsZero(),
// Only undo copies on disk → no run to show (nil, as with no files at all).
if len(results) > 0 {
status.LastDBDump = &DBDumpStatus{
LastRun: latestTime,
Results: results,
Success: m.runInterrupted.IsZero(),
}
}
}