Files
ds-galo/openspec/changes/trash-permanent-delete-and-empty/proposal.md
T
iu 3b745fa737 feat(photos): fix trash permanent delete and add empty trash
Permanently deleting a photo whose album was deleted failed because
authorization resolved through the album. Fall back to uploader
ownership when the photo is albumless. Add a bulk DELETE /trash that
removes every trashed photo the caller may delete (uncapped listing)
and returns the deleted count, with an «Очистить корзину» action on the
trash screen.
2026-10-11 20:54:54 +03:00

1.9 KiB

Proposal

Why

Permanently deleting a photo from the trash fails when the photo has no album (album_id IS NULL) — the normal result of deleting an album, whose photos move to the trash unbound (photos/spec.md, «Удаление альбома»). PermanentDelete authorizes through the album, so these photos can never be removed, and the UI surfaces album_not_found. In the local database 4010 of 4011 trashed photos are in this state. There is also no way to clear the trash in bulk.

What Changes

  • Fix PermanentDelete authorization so a photo without an album can be permanently deleted by a user who may delete it (its uploader), instead of failing on a missing album.
  • Add a bulk permanent-delete operation that empties the trash for the caller, skipping photos the caller is not allowed to remove, and reporting how many were deleted.
  • Add an «Очистить корзину» action on the trash screen with a confirmation dialog, refreshing the list and the rail counter afterwards.

Capabilities

New Capabilities

Modified Capabilities

  • photos: «Окончательное удаление» also covers photos with no album (deleted album); add an «Очистка корзины» requirement for bulk permanent removal.
  • ui-workspace: trash screen gains an «Очистить корзину» control with confirmation and post-action refresh.

Impact

  • Backend: backend/internal/photos/service.go (PermanentDelete), the photos repository/store (new bulk purge method), handlers.go, and a route in backend/internal/app/app.go.
  • Frontend: frontend/src/lib/api.ts, frontend/src/lib/stores/trash.svelte.ts, frontend/src/routes/(app)/trash/+page.svelte.
  • Tests: e2e/contract coverage for permanently deleting an albumless photo and for the bulk empty-trash path.