Skip to content

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

  1. 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.
  2. A 30-day restore window for users (D1), snapshotted when the deletion completes, so the date shown never moves.
  3. Restore is always possible for an application administrator, however old the deletion.
  4. 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 on Project.Deletion for 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 RemoveSearch holders (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 RestoreWindowDays affects 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. pmStudy is about 10.7 GB in production (from the fold's index notes). Detached Studies keep their full documents and their entries in every pmStudy index. 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