feat(admin): lapse sweep and the four renewal notices

Hourly sweep marks expired Free instances lapsed and sends at most one
notice per instance per pass, most urgent first, recorded on the document
so a restart cannot re-send.

Deletion warnings are suppressed when the reaper is off. Promising a
deletion that will never happen is a lie, and a scarier one than silence.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
mrhid6
2026-07-26 13:20:00 +01:00
co-authored by Claude Opus 5
parent 909ddb884e
commit 372a8c5ddf
4 changed files with 228 additions and 0 deletions
+4
View File
@@ -17,6 +17,7 @@ import (
"github.com/mrhid6/vantage/admin/internal/db"
"github.com/mrhid6/vantage/admin/internal/inject"
"github.com/mrhid6/vantage/admin/internal/licensing"
"github.com/mrhid6/vantage/admin/internal/lifecycle"
"github.com/mrhid6/vantage/admin/internal/mail"
"github.com/mrhid6/vantage/admin/internal/models"
)
@@ -72,6 +73,9 @@ func main() {
defer stopReconcile()
inject.StartReconciler(reconcileCtx)
lifecycle.SetPortalURL(cfg.PublicURL)
lifecycle.Start(reconcileCtx, cfg.ReapAfter)
srv := &http.Server{
Addr: cfg.Addr,
Handler: api.Routes(cfg),