Deleting a studyset blanked it with everything inside it once a four-second Undo was over. It now only marks it (`studyset.deletedAt`, a column as `archivedAt`): it leaves every list, count and session with what is inside it and waits in the library's Recently deleted for 14 days, saying how many are left, with Restore and Delete now. Deleting no longer asks first and offers Undo; Delete now asks. Once the 14 days are over, whichever of the person's devices looks next (as their data opens, after every sync) deletes it for good, blanking first as before; the server can't blank a payload and never writes a person's space (ADR 0007). The connector, publishing and the learner count leave deleted studysets out too. The migration adds one nullable column: app versions before it stop syncing until they update. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MMm7usAo6q9ZZRoPkWjoxi Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
52 lines
3.1 KiB
Markdown
52 lines
3.1 KiB
Markdown
# 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.
|