Files
ds-galo/openspec/changes/archive/2026-10-11-trash-permanent-delete-and-empty/tasks.md
T

2.5 KiB

Tasks

1. Fix permanent delete for albumless photos

  • 1.1 In photos.Service.PermanentDelete, when p.AlbumID == "", authorize by p.UploaderID == userID instead of calling albums.Access; keep the album-role check when an album is present. Verify with a Go test that permanently deletes an albumless trashed photo (add to backend/internal/e2e/sqlite_test.go) and passes.
  • 1.2 Confirm object garbage collection still runs for albumless deletes (PhotoObjectIDs + MarkObjectDeleting); verify the test asserts the photo row is gone and an unbound object is marked deleting.

2. Add empty-trash operation

  • 2.1 Add a photos repository/store method that lists all accessible trashed photo identities (id, album_id, uploader_id) without the 200-item display cap; verify with a test that seeds more than 200 trashed photos and asserts all are returned.
  • 2.2 Add Service.EmptyTrash(ctx, userID) that authorizes each listed photo with the same rules as PermanentDelete (album role when bound, uploader when albumless), skips forbidden ones, and returns the deleted count; verify with a test where a shared album holds another user's trashed photo — the foreign photo remains, the caller's are removed, and the count matches.
  • 2.3 Add Handler.EmptyTrash and the DELETE /trash route returning { "deleted": n }; verify with an HTTP-level test asserting the status code and response body.
  • 2.4 Add end-to-end coverage: emptying an empty trash returns 0, and after emptying a non-empty trash TrashCount is 0; verify with make test.

3. Trash screen action

  • 3.1 Add photosApi.emptyTrash() calling DELETE /trash in frontend/src/lib/api.ts; verify with npm run check.
  • 3.2 Add an «Очистить корзину» control to frontend/src/routes/(app)/trash/+page.svelte, enabled only when the list is non-empty, opening the existing ConfirmDialog; on confirm call emptyTrash, then reload the list and call trash.load(); verify by clearing a non-empty trash and observing the empty state and a busy state during the call.
  • 3.3 Verify the rail counter reflects the result: after clearing, the trash count in AlbumRail becomes 0 (observable in the running app).

4. Integration verification

  • 4.1 Run make test (backend) and npm run check plus npm run build (frontend); verify all pass with no regressions.

Workflow follow-up

  • Run /opsx-apply to implement this change.
  • Archive the change after review and verification (sync delta specs into main specs).