R-1271 (P2): „use my kept data” never takes a copy dated in the future — a copy more than 10 minutes past the box's clock never counts as the newest (the newest true date wins, tie local); alone it is still offered, said and not recommended. Red-proved. Commit only.
gates / gates (push) Successful in 1m33s

This commit is contained in:
2026-10-25 09:44:56 +01:00
parent 2d71270858
commit bd9f4f7b74
13 changed files with 278 additions and 32 deletions
+12 -3
View File
@@ -80,18 +80,27 @@ func (s *Server) keptBackupFor(lang string, it stacks.KeptItem, off map[string]b
// A dated folder's own unit is the copy taken with those files.
if it.UnitDir != "" {
if c, ok := s.backupMgr.KeptCopyAt(it.UnitDir, it.Drive, 1); ok {
return s.msgLang(lang, "kept.backup.with", fmtLocalTime(lang, c.Time)), c, true
name := s.msgLang(lang, "kept.backup.with", fmtLocalTime(lang, c.Time))
if backup.KeptFuture(c, time.Now()) { // R-1271: say it, never hide it
c.Future = true
name += " " + s.msgLang(lang, "kept.backup.future_note")
}
return name, c, true
}
}
} else {
local, lok = s.backupMgr.KeptDBCopy(it.App, it.Drive)
}
oc, ook := off[it.App]
c, ok := backup.KeptNewer(local, lok, oc, ook && it.App != "")
c, ok := backup.KeptNewerAt(time.Now(), local, lok, oc, ook && it.App != "")
if !ok {
return none, backup.KeptCopy{}, false
}
return s.msgLang(lang, backup.KeptCopyKey(c.Tier), fmtLocalTime(lang, c.Time)), c, true
name := s.msgLang(lang, backup.KeptCopyKey(c.Tier), fmtLocalTime(lang, c.Time))
if c.Future { // R-1271: the only copy, dated in the future — offered, and said
name += " " + s.msgLang(lang, "kept.backup.future_note")
}
return name, c, true
}
// keptOffsite asks the off-site repository ONCE for every listed app.
@@ -147,9 +147,9 @@ function showKeptChoice(d, form) {
function el(tag, cls, text) { var x = document.createElement(tag); if (cls) x.className = cls; if (text) x.textContent = text; return x; }
box.appendChild(el('h3', 'kept-choice-title', d.title));
box.appendChild(el('p', 'kept-choice-body', d.body));
function option(label, desc, choice, enabled, extra) {
function option(label, desc, choice, enabled, extra, plain) {
var o = el('div', 'kept-choice-option');
var b = el('button', enabled ? 'btn btn-primary' : 'btn btn-outline', label);
var b = el('button', enabled && !plain ? 'btn btn-primary' : 'btn btn-outline', label);
b.type = 'button';
b.disabled = !enabled;
b.setAttribute('data-kept-choice', choice);
@@ -159,7 +159,7 @@ function showKeptChoice(d, form) {
if (extra) o.appendChild(el('p', 'kept-choice-note', extra));
return o;
}
box.appendChild(option(d.use_label, d.use_offered ? d.use_desc : d.use_off, 'use', d.use_offered, ''));
box.appendChild(option(d.use_label, d.use_offered ? d.use_desc : d.use_off, 'use', d.use_offered, d.use_warn || '', !!d.use_future));
box.appendChild(option(d.fresh_label, d.fresh_desc, 'fresh', true, d.not_backed_up));
box.hidden = false;
box.scrollIntoView({behavior: 'smooth'});
@@ -501,9 +501,9 @@ function showKeptChoice(d, form) {
function el(tag, cls, text) { var x = document.createElement(tag); if (cls) x.className = cls; if (text) x.textContent = text; return x; }
box.appendChild(el('h3', 'kept-choice-title', d.title));
box.appendChild(el('p', 'kept-choice-body', d.body));
function option(label, desc, choice, enabled, extra) {
function option(label, desc, choice, enabled, extra, plain) {
var o = el('div', 'kept-choice-option');
var b = el('button', enabled ? 'btn btn-primary' : 'btn btn-outline', label);
var b = el('button', enabled && !plain ? 'btn btn-primary' : 'btn btn-outline', label);
b.type = 'button';
b.disabled = !enabled;
b.setAttribute('data-kept-choice', choice);
@@ -513,7 +513,7 @@ function showKeptChoice(d, form) {
if (extra) o.appendChild(el('p', 'kept-choice-note', extra));
return o;
}
box.appendChild(option(d.use_label, d.use_offered ? d.use_desc : d.use_off, 'use', d.use_offered, ''));
box.appendChild(option(d.use_label, d.use_offered ? d.use_desc : d.use_off, 'use', d.use_offered, d.use_warn || '', !!d.use_future));
box.appendChild(option(d.fresh_label, d.fresh_desc, 'fresh', true, d.not_backed_up));
box.hidden = false;
box.scrollIntoView({behavior: 'smooth'});
@@ -457,9 +457,9 @@ function showKeptChoice(d, form) {
function el(tag, cls, text) { var x = document.createElement(tag); if (cls) x.className = cls; if (text) x.textContent = text; return x; }
box.appendChild(el('h3', 'kept-choice-title', d.title));
box.appendChild(el('p', 'kept-choice-body', d.body));
function option(label, desc, choice, enabled, extra) {
function option(label, desc, choice, enabled, extra, plain) {
var o = el('div', 'kept-choice-option');
var b = el('button', enabled ? 'btn btn-primary' : 'btn btn-outline', label);
var b = el('button', enabled && !plain ? 'btn btn-primary' : 'btn btn-outline', label);
b.type = 'button';
b.disabled = !enabled;
b.setAttribute('data-kept-choice', choice);
@@ -469,7 +469,7 @@ function showKeptChoice(d, form) {
if (extra) o.appendChild(el('p', 'kept-choice-note', extra));
return o;
}
box.appendChild(option(d.use_label, d.use_offered ? d.use_desc : d.use_off, 'use', d.use_offered, ''));
box.appendChild(option(d.use_label, d.use_offered ? d.use_desc : d.use_off, 'use', d.use_offered, d.use_warn || '', !!d.use_future));
box.appendChild(option(d.fresh_label, d.fresh_desc, 'fresh', true, d.not_backed_up));
box.hidden = false;
box.scrollIntoView({behavior: 'smooth'});
@@ -479,9 +479,9 @@ function showKeptChoice(d, form) {
function el(tag, cls, text) { var x = document.createElement(tag); if (cls) x.className = cls; if (text) x.textContent = text; return x; }
box.appendChild(el('h3', 'kept-choice-title', d.title));
box.appendChild(el('p', 'kept-choice-body', d.body));
function option(label, desc, choice, enabled, extra) {
function option(label, desc, choice, enabled, extra, plain) {
var o = el('div', 'kept-choice-option');
var b = el('button', enabled ? 'btn btn-primary' : 'btn btn-outline', label);
var b = el('button', enabled && !plain ? 'btn btn-primary' : 'btn btn-outline', label);
b.type = 'button';
b.disabled = !enabled;
b.setAttribute('data-kept-choice', choice);
@@ -491,7 +491,7 @@ function showKeptChoice(d, form) {
if (extra) o.appendChild(el('p', 'kept-choice-note', extra));
return o;
}
box.appendChild(option(d.use_label, d.use_offered ? d.use_desc : d.use_off, 'use', d.use_offered, ''));
box.appendChild(option(d.use_label, d.use_offered ? d.use_desc : d.use_off, 'use', d.use_offered, d.use_warn || '', !!d.use_future));
box.appendChild(option(d.fresh_label, d.fresh_desc, 'fresh', true, d.not_backed_up));
box.hidden = false;
box.scrollIntoView({behavior: 'smooth'});