Restore window and kept data¶
Part of the temporary reversible deletion plan. It replaces the earlier purge design: Chris decided on 5 October 2026 that there is no actual permanent deletion.
1. Guarantees¶
- Nothing is erased. No job, schedule, TTL, route or person deletes a deleted search's Studies, the
search document, a deleted project, its statistics, its Bulk PDF records or any stored file. This keeps
T-POL-01("permanent physical erasure: not approved") intact for everything, and with it the integrated plan's ACD-R18, ACD-AE17 and AC-R2a-57. - A 30-day restore window for users (D1), snapshotted when the deletion completes, so the date shown never moves.
- Restore is always possible for an application administrator, however old the deletion.
- Deleted data stays out of normal use for as long as it is deleted: hidden from every read, refused by every write (see data model).
2. The window¶
RestoreWindowEndsAtUtc = DeletedAtUtc + RestoreWindowDays(30), stored on the operation (and onProject.Deletionfor projects).- Whether the window is open is computed when a list or a restore request is evaluated. No job runs when a window ends, and nothing changes in the data.
- Within the window: the item is listed in Recently deleted; restore by
RemoveSearchholders (searches) or the owner and application administrators (projects) (D3). - After the window: the item leaves the users' lists; a user restore answers "The restore period has ended. Ask a SyRF administrator." (HTTP 403 with a typed problem code).
- Shortening or lengthening
RestoreWindowDaysaffects new deletions only.
3. Restoring after the window¶
Recommendation: an administrator API route in the MVP, no administrator screen.
| Route (proposed) | What it does |
|---|---|
GET api/admin/deletions?scope=&projectId=&state= |
Lists deletion operations, in or after their window, with ids, scope, dates, counts and state. No names of people beyond the actor id; search and project names, because administrators need to find the item |
POST api/admin/deletions/{operationId}/restore |
Restores a deleted search or project, with the same checks, waits and statistics steps as a user restore; ledger records the administrator as actor |
- Who. Application administrators, through an application capability named with the authority programme (#3335, #3884). Both routes are audited in the deletion ledger.
- How it is used. Through Swagger (already available to administrators with the OpenIddict Swagger client) or a support script, typically after a user asks.
- Why a route and not a screen. It is meaningfully smaller: two endpoints and tests, against a screen that would need M3 design, preview acceptance, a web slice and user-guide pages. After-window restores should be rare. A minimal restricted screen (the integrated plan's "Deleted projects" view, ACD §3.3) can follow if support needs it, and would read the same routes.
- The same routes let administrators restore a project within the window too, which covers D3's "owner and application administrators" without a second UI.
4. What is kept, and where¶
| Kept data | Where it lives while deleted |
|---|---|
| A deleted search's Studies | pmStudy, under the operation's holding ProjectId, with the Deletion marker |
| The search document | pmSystematicSearch, unlinked from the project (still linked to any other project) |
| The search's import-job entry and its place in the project | The operation's link snapshot |
| A deleted project and everything in it | Unchanged, behind Project.Deletion |
| Statistics rows | pmProjectStatistics*, unchanged; not served for a deleted project (statistics) |
| Bulk PDF records (jobs, release records, storage bindings, quarantine fences) | Unchanged on the Project and in their collections; their own clean-up of cancelled uploads continues |
| Stored files: uploaded reference files, PDFs delivered to the Edinburgh share, CSV reports | Unchanged (as production's immediate deletion already leaves them today) |
| Deletion operations and ledger | pmDeletionOperation, pmDeletionLedger, for ever |
5. Storage cost¶
Keeping everything costs storage that grows with every deletion and never shrinks.
- The biggest part is Studies.
pmStudyis about 10.7 GB in production (from the fold's index notes). Detached Studies keep their full documents and their entries in everypmStudyindex. Each 1% of all Studies that ends up in deleted searches or projects keeps about 107 MB of data, plus its index entries. - The share is unknown. It depends on how often people delete and how large the deleted items are. Production's history cannot tell us (its deletions were immediate). The production-copy rehearsal on Bramble (#4068) will give the size distribution of searches and projects (open question Q1), which turns an assumed deletion rate into an estimate.
- Other stores. Project documents, statistics rows and stored files are small next to Studies, or were already retained by today's deletion (files).
- Monitoring. A gauge of detached Studies and deleted projects (from the operation counts), reported monthly against the Atlas storage figures, so growth is visible long before it matters.
This is risk K11 in decisions and risks.
6. Non-goal: permanent erasure¶
Permanent erasure of deleted data, by policy, by schedule or on request, is out of scope for this
programme. It needs its own decision (T-POL-01), a legal and retention review, its own ADR and its own
tests, covering at least: what is erased (Studies, search and project documents, statistics, Bulk PDF
records, stored files, backups and S3 object versions), who may ask for it, and how erasure is proved.
This design keeps it possible: everything belonging to one deleted search sits under one holding id and
one operation, and everything belonging to a deleted project under its id, so a future erasure would be a
scoped, auditable delete. Until then the user guide must not suggest that deleted data is erased.
7. Background work for deleted items¶
| Work | For deleted searches and projects |
|---|---|
Deletion runner (resume Requested, Deleting, Restoring after a crash; finish waits) |
Runs: a recurring schedule in project-management every few minutes, as the FEAT-024 maintenance schedules do (DefaultRecurringSchedule, misfire policy Send), with its logic in a host-neutral DeletionLifecycleRunner per ADR-021 |
| Reservation idle and suspended timeouts | Keep running (releasing is always safe) |
| Bulk PDF upload sweeper and notifier reconciler | Keep running, so cancelled uploads finish their storage clean-up |
| Statistics repair, backfills, mode-epoch batches, daily observations | Already skip a deleted project (IsProjectDeleted) |
| Statistics scheduled maintenance (history retention, delta and receipt maintenance) | Skips a deleted project (IsProjectDeleted, slice S2b, #4195), so its kept statistics stay exactly as they were until a restore |
| Exports, invitations, delegated work | Skip or deny deleted projects |