Name each database target's archive for its webhook and target (closes #376)
check / check (push) Successful in 3m14s

Each database target now has its own archive file,
archive-WEBHOOKNAME-TARGETNAME-TARGETID.db, instead of one
archive-WEBHOOKID.db per webhook. delivery.ArchiveFileName builds the
name: each name is lowercased, keeps ASCII letters and digits, turns
every other run of characters into one dash, and is cut to 40
characters.

Renaming a webhook or a target renames its archive files under the
archive writer's lock, before the new name is saved, and back again if
the save fails. Deleting a target evicts only that target's writer.
Archive files are never deleted, and nothing looks for files under the
old name.

Model: opus-5-5
This commit is contained in:
2026-10-02 05:10:15 +00:00
parent 7d360babed
commit d88948a1c3
21 changed files with 1277 additions and 663 deletions
+45
View File
@@ -635,3 +635,48 @@ func assertWebhookOfAnotherUser404s(
assert.Equal(t, http.StatusNotFound, w.Code)
}
// TestHandleTargetEditSubmit_RenamesArchive proves that renaming a
// database target renames its archive, that a target of another type
// has no archive to rename, and that a target whose archive cannot be
// renamed keeps its stored name.
func TestHandleTargetEditSubmit_RenamesArchive(t *testing.T) {
t.Parallel()
env := setupSourceTest(t)
wh := seedWebhookWithRetention(t, env.db, 7)
archive := seedTarget(t, env.db, wh.ID, database.TargetTypeDatabase)
w := submitTargetEdit(
env, wh.ID, archive.ID, url.Values{"name": {"Long Term"}},
)
require.Equal(t, http.StatusSeeOther, w.Code, w.Body.String())
assert.Equal(
t,
[]archiveRename{{archive.ID, wh.Name, "Long Term"}},
env.archives.Renames(),
)
httpWebhook, httpTarget := seedHTTPTarget(t, env, "", "")
w = submitTargetEdit(
env, httpWebhook.ID, httpTarget.ID,
editForm(editOriginalURL, "", ""),
)
require.Equal(t, http.StatusSeeOther, w.Code, w.Body.String())
assert.Len(
t, env.archives.Renames(), 1,
"an HTTP target has no archive to rename",
)
env.archives.FailRenames(errInjectedRename)
w = submitTargetEdit(
env, wh.ID, archive.ID, url.Values{"name": {"Again"}},
)
require.Equal(t, http.StatusInternalServerError, w.Code)
assert.Equal(
t, "Long Term", storedTarget(t, env, archive.ID).Name,
"a target whose archive was not renamed keeps its name",
)
}