Skip to content

feat(library): add recoverable trash and explicit permanent purge [L2-04] - #61

Merged
dkritarth merged 2 commits into
masterfrom
feat/trash-and-purge
Sep 12, 2026
Merged

feat(library): add recoverable trash and explicit permanent purge [L2-04]#61
dkritarth merged 2 commits into
masterfrom
feat/trash-and-purge

Conversation

@dkritarth

@dkritarth dkritarth commented Sep 12, 2026

Copy link
Copy Markdown
Owner

Closes #38

User outcome

Users can safely move papers to a recoverable Trash folder without losing notes, chats, annotations, or local files. Papers in Trash are hidden from normal library views, can be restored at any time, or can be permanently deleted with an explicit confirmation dialog that cleans up both SQLite metadata (via foreign key cascades) and on-disk files.

Acceptance criteria

  • Trash action available on paper cards to soft-delete papers (trashed_at set to ISO timestamp).
  • Trashed papers excluded from active library views and collections by default.
  • Dedicated Trash view accessible from the sidebar footer displaying trashed papers.
  • Restore action recovers paper and reinstates it into normal library navigation.
  • Permanent purge requires explicit user confirmation in a dialog.
  • Purge removes disk files in data/papers/<slug> safely with path traversal guards and atomically cascades deletion in SQLite.
  • Trashed state and purged state persist across Electron restarts.

Automated verification

  • Vitest unit tests:
    • core/library/repo.test.ts: Added 5 new tests covering trashPaper, restorePaper, purgePaper, and filtering in listPapers. (24 tests pass).
    • core/store/migrate.test.ts: Updated to schema v7 migration asserting trashed_at column presence.
    • core/store/db.test.ts: Updated expected database migration version to 7.
    • src/app/TrashView.test.tsx: 6 new tests verifying loading, restoring, dialog modal opening, canceling, confirming purge, and error handling.
    • src/app/Library.test.tsx: Added test verifying trash button moves paper to trash and updates UI.
    • src/app/Sidebar.test.tsx: Added test verifying clicking Trash invokes navigation callback.
    • src/app/App.test.tsx: Added test verifying switching to Trash view.
    • Overall unit test suite: 38 test files, 285 tests passed.
  • Type check: npm run typecheck passed with 0 errors.

Live Electron verification

  • Implemented live Playwright test test/trash-live.mjs (npm run test:gate:trash) under xvfb.
  • Ingested two papers, moved paper 1 to trash, verified it disappeared from Library while paper 2 remained visible.
  • Verified paper 1 was present in Trash view.
  • Restarted Electron instance to certify persistence across app restarts: paper 1 remained trashed and hidden in Library.
  • Tested purge modal cancellation: paper remained intact in Trash.
  • Tested Restore: paper 1 was removed from Trash view and reappeared in Library.
  • Re-trashed and confirmed permanent purge: verified paper 1 was removed from Trash, its folder on disk was deleted, and paper 2 remained unaffected in DB and on disk.

Visual and console evidence

  • Live verification output:
    === [L2-04] Live Trash & Purge Verification Starting ===
    1. Launching Electron App...
    2. Ingesting test papers...
    3. Navigating to Library...
    ✓ Both papers visible in Library
    4. Moving target paper to Trash...
    ✓ Paper 1 hidden from Library; Paper 2 remains
    5. Verifying Trash view...
    ✓ Paper 1 present in Trash view
    6. Restarting Electron to test persistence across restarts...
    ✓ Trashed state persisted across restart (Library still excludes it)
    ✓ Paper 1 still present in Trash view after restart
    7. Testing purge cancellation...
    ✓ Cancel purge kept paper in Trash without deleting
    8. Testing Restore...
    ✓ Paper 1 successfully restored to Library
    9. Re-trashing and confirming permanent purge...
    ✓ Paper 1 purged from Trash view
    ✓ Paper 1 files completely purged from disk
    ✓ Paper 2 untouched and verified
    🎉 ALL LIVE TRASH & PURGE CHECKS PASSED!
    
  • Unit test summary:
    Test Files  38 passed (38)
    Tests       285 passed (285)
    Duration    4.36s
    

Limitations and follow-ups

  • Multi-selection batch trash/restore/purge can be added in a future polish iteration.
  • Currently, auto-expiring trash (e.g. 30 days) is not implemented and papers remain in Trash until explicitly restored or purged.

Independent review

  • Architectural boundary review: No node standard modules (fs, path) imported in renderer components; all filesystem and database mutations are handled via window.vellum preload IPC bridge.
  • Security review: purgePaper enforces slug validation regex /^[a-z0-9-]+$/i and verifies normalized absolute path prefix against the library papers directory, preventing directory traversal.

@dkritarth
dkritarth merged commit b58bbf9 into master Sep 12, 2026
1 check passed
@dkritarth
dkritarth deleted the feat/trash-and-purge branch September 12, 2026 20:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[L2-04] Add recoverable Trash and explicit permanent purge

1 participant