Add send-log retention days to panel Settings.

Global administrators can set delivery journal retention (7-365 days) in SQLite;
SEND_LOG_RETENTION_DAYS seeds the initial default and the log-tailer re-reads
the value every prune cycle without a restart.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-18 21:57:48 +03:00
parent d0bf4a4226
commit 909145e5c8
20 changed files with 575 additions and 102 deletions
@@ -8,6 +8,10 @@
{{define "content"}}
<h1>Deliveries</h1>
<p class="muted">Rows older than {{.SendLogRetentionDays}} days are deleted
automatically.{{if .IsGlobal}} Change retention on
<a href="/settings">Settings</a>.{{end}}</p>
<div class="card">
<h2>Filter</h2>
<form method="get" action="/deliveries">
+16 -3
View File
@@ -77,10 +77,23 @@
</div>
</div>
<div class="card" id="deliveries-retention">
<h2>Deliveries</h2>
<p class="muted">How long rows on <a href="/deliveries">Deliveries</a> are
kept before the background sweep deletes them — the main driver of
<code>/data</code> growth over time. Does not affect <code>mail.log</code>
rotation (fourteen daily files).</p>
<label for="send_log_retention_days">Send log retention (days)</label>
<input id="send_log_retention_days" name="send_log_retention_days" type="number"
min="7" max="365" step="1" required
value="{{.FormSendLogRetentionDays}}">
</div>
<button type="submit">Save changes</button>
<p class="muted">Leave both new-password fields empty to change the username
or DMARC address only. Changing the password signs out every other session;
this one stays signed in.</p>
<p class="muted">Leave both new-password fields empty to change the username,
DMARC address, or send log retention only. Changing the password signs out
every other session; this one stays signed in.</p>
</form>
{{else}}
<div class="card narrow">
+4
View File
@@ -300,11 +300,15 @@ func TestSettingsPageDocumentsRateLimits(t *testing.T) {
if !strings.Contains(src, `id="rate-limits"`) {
t.Error("settings should include a sending rate limits card")
}
if !strings.Contains(src, `id="deliveries-retention"`) {
t.Error("settings should include a send log retention card for global administrators")
}
for _, want := range []string{
"RATE_LIMIT_MESSAGES_PER_IP",
"Level 2 — domain",
"trusted IPs",
"{{.L1Messages}} messages / {{.L1Window}} seconds",
`name="send_log_retention_days"`,
} {
if !strings.Contains(src, want) {
t.Errorf("settings rate limits card missing %q", want)