fix(media): a bundle delete removes only what the bundle listing shows #276
No reviewers
Labels
No labels
bug
enhancement
needs-triage
ready-for-agent
ready-for-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Cloonar/deckle!276
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "afk/269"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #269
What
POST /api/media/deletewith a bundle reference used to delete any file in the page's bundle directory, including the page's own_index.md,_index.<lang>.md,notes.txtand dotfiles. Now it removes a file only whenGET /api/media/bundlewould list it. Any other name answers404 library.refNotFound {ref}, the file stays on disk, and no WIP snapshot is taken. Library references are unaffected.How
media.BundleResourceType(dir, name) Typeininternal/media/library.go. It returnsTypeUnknownfor a missing entry, a directory, any.md(case-insensitive), or a file that does not sniff as an allowed type.handleMediaBundleandhandleMediaDeleteboth call it. The server's duplicate sniffersniffFileTypeis removed.docs/api.md, sectionPOST /api/media/delete, now says a bundle reference must name a file the listing shows, and its 404 line covers that case.GET /api/media/bundleis unchanged. No skill orAGENTS.mddescribes this route.Tests
TestBundleResourceType(internal/media): jpeg, png and pdf return their types..mdnames (including a jpeg named_index.md),notes.txt,.gitkeep, subdirectories (including a directory namedphotos.jpg) and missing names are refused.TestMediaDeleteBundleRefusesNonResources: deletes of_index.md,_index.de.md,notes.txt,.gitkeep,suband..each answer 404library.refNotFoundwithargs.ref, and the files remain.TestMediaDeleteBundleRefusalTakesNoWipSnapshot: after a refusal, the WIP tip is still the baseline commit.TestMediaDeleteBundleAgreesWithListing: every listed ref deletes with 200, and every name on disk the listing omits gets 404 and stays.go vet ./...andgo test ./...pass (afternpm run buildinweb/).🤖 Generated with Claude Code
POST /api/media/delete with {ref, page} deleted any file in the page's bundle directory that passed the traversal guard — the page's own _index.md, a translation, notes, dotfiles. The predicate the bundle listing applied inline (not a directory, not .md, sniffs as an allowed type) is now media.BundleResourceType, called by both the listing and the delete; a name it refuses answers 404 library.refNotFound {ref}, stays on disk and takes no WIP snapshot. The server's duplicate sniffFileType is gone. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>[autoland] verdict: pass
PASS — ci/build-and-test green (go vet ./..., go test ./..., web build+test). Diff matches #269's acceptance criteria: one owner media.BundleResourceType (internal/media/library.go) called by both the bundle listing and the bundle delete, server duplicate sniffFileType removed, refusal is 404 library.refNotFound before any write/snapshot, tests cover refusals, no-snapshot and listing⇔delete agreement, docs/api.md updated.