# ADR 0007: Deleted studysets wait 14 days in Recently deleted - **Status:** accepted - **Date:** 2026-10-12 ## Context Deleting a studyset blanked and deleted it with everything inside it once a four-second Undo was over (ADR 0002, rule 2: blanking can't be undone, so the Undo comes first). A studyset can hold months of work and thousands of reviews, and a moment's Undo is easy to miss. People expect what they delete to stay restorable for a while, as Vaia keeps deleted studysets for 14 days in a section of their library. ## Decision 1. **A deleted studyset is marked, not deleted.** `studyset.deletedAt` records when the person deleted it (null while it isn't), a column like `archivedAt` and for the same reason (ADR 0004): deleting on one device and editing on another must not overwrite each other, which they would inside the payload, whose last writer wins whole. Only the deleted studyset is marked; what is inside it is deleted with it by ancestry, as archiving works. 2. **What is deleted counts nowhere.** The app's lists, counts, study sessions, the dashboard, reading deadlines and copies' updates read the studysets without those deleted and what is inside them; so do the server's connector, publishing and the learner count. Restoring brings it all back as it was, progress included. 3. **The library's Recently deleted lists them for 14 days** (`Studyset.keptWhenDeleted`), the most recently deleted first, each with the days it has left, Restore, and Delete now. Deleting no longer asks first; it offers Undo, as archiving does. Delete now asks, since it can't be undone. A studyset deleted inside one deleted later is listed only once the outer one is restored, and goes on its own clock. 4. **The person's devices delete them for good**, as before, blanking first: whichever device looks next once the 14 days are over (`StudysetDeletions.deleteExpired`, as the person's data opens and after every sync that went through). The server doesn't: it never writes into a person's space (ADR 0005), and the sync engine (checked with v0.0.10) stores a payload the server updates as its JSON text rather than its bytes, so it couldn't blank one. A studyset deleted by someone who never opens the app again therefore stays on the server, marked, like the rest of what they left, until their account goes (pruning, or deleting it). 5. **A restore and a deletion for good racing on two devices end deleted**: existence is the sync engine's tombstone, which a field update doesn't lift. That needs one device restoring offline in the last moments of the 14 days while another deletes it, and is accepted. ## Consequences - The migration `20261012162411835-studyset-deleted-at` adds the column. Like every change to a synced table, it locks app versions before it out of syncing until they update (ADR 0002, rule 3); `minimumAppBuild` needn't rise. - Deleted content stays on the server and in backups for up to 14 days longer than before, longer for people who stop using the app. The privacy page should say so. - Deleting a studyset still never withdraws its publication: that stays the Publish sheet's.