Store a target's settings as columns (closes #543)
check / check (push) Waiting to run

A target's settings move from the per-type JSON string in
targets.config to columns: url, headers, timeout_seconds,
forward_query, archive_expiry and archive_rotation. A column a type
does not use stays empty. headers holds the header map as JSON text
through GORM's JSON serializer, and archive_expiry holds a
time.Duration, 0 meaning never. The forms check each setting once,
with the same refusals and messages, and the edit form is filled from
the columns, so the per-type config structs, their parsers and the
"could not be read" branches are gone. A delivery task carries the
six settings in place of the JSON string; tests check that each copy
into a task, and back out of one, keeps all six.

Model: opus-5-5
This commit was merged in pull request #554.
This commit is contained in:
2026-10-15 23:02:39 +02:00
parent ded39aa158
commit 8406c77949
71 changed files with 1665 additions and 2168 deletions
+5 -16
View File
@@ -199,22 +199,11 @@ func (s *Sweeper) sweep(ctx context.Context) {
}
}
// sweepTarget prunes the archive of a single database target.
// A missing, empty, or "never" expiry parses as a zero duration
// and is skipped entirely, so those archives are never pruned.
// sweepTarget prunes the archive of a single database target. A
// target with an ArchiveExpiry of 0 keeps its archive forever and is
// skipped entirely, so that archive is never pruned.
func (s *Sweeper) sweepTarget(target *database.Target) {
expiry, err := ParseExpiry(target.Config)
if err != nil {
s.log.Error(
"archive sweep: invalid database target config",
"webhook_id", target.WebhookID,
"target_id", target.ID,
"error", err,
)
return
}
expiry := target.ArchiveExpiry
if expiry <= 0 {
return
}
@@ -223,7 +212,7 @@ func (s *Sweeper) sweepTarget(target *database.Target) {
return
}
err = s.writers.sweepArchive(target.ID, expiry)
err := s.writers.sweepArchive(target.ID, expiry)
if err == nil {
return
}