Implement the database archiving target (closes #43) #84

Merged
sneak merged 4 commits from issue-43-database-archiving into main 2026-08-07 22:50:08 +02:00

4 Commits

Author SHA1 Message Date
f5b4aec0bd Align docs with archive semantics; fail loud on non-positive expiry (#43)
All checks were successful
check / check (push) Successful in 2m39s
- README: rewrite the database-target documentation (target-types
  bullet and the per-webhook databases section) to describe the
  shipped archiving semantics -- separate archive-{webhookID}.db,
  debounced close/reopen for offline archiving, auto-recreate,
  creation-validated optional expiry with prune-on-open, and
  fail-loud delivery on archive write errors -- replacing the
  stale always-successful stub description.
- parseArchiveExpiry now returns an error for set-but-non-positive
  durations ("0s", "-5h") instead of silently defaulting to
  keep-forever, matching ValidateArchiveExpiry at creation time;
  the delivery then fails loudly like any other archive error.
  TestParseArchiveExpiry extended with zero and negative cases.
- databaseTarget type comment: "fire-and-forget" -> "no-retry",
  matching the fail-loud behaviour.
2026-08-07 17:27:00 +00:00
7ca62664d0 Read the expiry form value where the body is bounded (#43)
All checks were successful
check / check (push) Successful in 2m36s
The pinned CI linter's gosec G120 flagged r.FormValue in
buildDatabaseTargetConfig because the MaxBytesReader guard lives
one function up in processTargetCreate, out of static-analysis
sight. Read the expiry alongside the other form values in
processTargetCreate and pass it down as a string, matching how
the http and slack config builders receive their URL.
2026-08-07 16:59:26 +00:00
d35ad0c49e Fail deliveries on archive errors; validate expiry at creation (#43)
Some checks failed
check / check (push) Failing after 57s
Two review findings on the database archiving target:

- An archive error now records the attempt as failed with the
  error string and marks the delivery failed, instead of logging
  the error and reporting success. A target that could not do its
  one job must not claim it did.
- The archive expiry is now actually configurable: the add-target
  form gains an expiry field for database targets, and the value
  is validated at creation time via the new
  delivery.ValidateArchiveExpiry (empty, "never", or a positive
  Go duration), rejecting bad values with a 400 at the only place
  a human can fix them, mirroring how Slack target URLs are
  validated at creation.

Test updates: a forced archive failure asserts a failed delivery
with a recorded error and no archive file; config builder tests
cover empty/never/duration and rejection paths; the two engine
tests that exercise the database target now build engines with a
real webhook DB manager since archiving is no longer a no-op; the
reopen-debounce test uses a wider window so parallel test load
cannot make two rapid writes straddle it.
2026-08-07 16:36:43 +00:00
38cfe76d49 Implement the database archiving target (closes #43)
All checks were successful
check / check (push) Successful in 5s
2026-08-07 22:59:24 +07:00