Page trash: soft delete, restore, and purge job #31

Closed
opened 2026-07-04 14:52:13 +02:00 by fable-5 · 1 comment
Collaborator

Context

Deleting must be recoverable (ADR 0013): pages go to a pond-level trash with retention.

Scope

Backend: DELETE /pages/:id sets deleted_at/by; trash endpoints (list, restore, purge single); introduce the jobs table + in-app scheduler (data-model.md) with the daily trash-purge job honoring retention (instance setting, default 30 days); purge deletes state, versions (placeholder — exist from M3), cache rows, and files. Frontend: trash view per pond (restore/purge buttons), delete confirmation, deleted pages excluded everywhere.

Acceptance criteria

  • deleted page disappears from sidebar and direct URL (404 with trash hint for those who may edit)
  • restore brings content and files back intact (e2e)
  • purge job removes rows and volume files past retention (time-travel test with injected clock)
  • scheduler survives API restart and never double-runs a job (locking test)

Technical notes

  • ADR 0013, data-model.md (jobs), operations.md (job table).
  • The scheduler built here is reused by all later maintenance jobs — keep it generic (name, cadence, handler, last-run bookkeeping).

Dependencies

Depends on #23, #27.

Size: ~2 days


Conventions: English code/comments, clear human-readable code, no hard-coded UI strings (ADR 0012, add de and en), permission checks only via the shared guard (docs/architecture/permissions.md). Read the referenced ADRs before starting.

## Context Deleting must be recoverable (ADR 0013): pages go to a pond-level trash with retention. ## Scope Backend: `DELETE /pages/:id` sets `deleted_at/by`; trash endpoints (list, restore, purge single); introduce the `jobs` table + in-app scheduler (data-model.md) with the daily `trash-purge` job honoring retention (instance setting, default 30 days); purge deletes state, versions (placeholder — exist from M3), cache rows, and files. Frontend: trash view per pond (restore/purge buttons), delete confirmation, deleted pages excluded everywhere. ## Acceptance criteria - [ ] deleted page disappears from sidebar and direct URL (404 with trash hint for those who may edit) - [ ] restore brings content and files back intact (e2e) - [ ] purge job removes rows and volume files past retention (time-travel test with injected clock) - [ ] scheduler survives API restart and never double-runs a job (locking test) ## Technical notes - ADR 0013, data-model.md (`jobs`), operations.md (job table). - The scheduler built here is reused by all later maintenance jobs — keep it generic (name, cadence, handler, last-run bookkeeping). ## Dependencies Depends on #23, #27. **Size**: ~2 days --- *Conventions: English code/comments, clear human-readable code, no hard-coded UI strings (ADR 0012, add `de` **and** `en`), permission checks only via the shared guard (docs/architecture/permissions.md). Read the referenced ADRs before starting.*
fable-5 added this to the M2 — Ponds & pages, single-user editing milestone 2026-07-04 14:52:13 +02:00
fable-5 added the
backend
frontend
labels 2026-07-04 14:52:13 +02:00
Collaborator

Implemented in a645763 and closed via Closes #31. Pipeline verification for that commit:

  • CI / Lint, typecheck, test — success
  • CI / Auth e2e pack — success
  • CD / Build and push images — success
  • CD / Deploy to Test — success
  • CD / Smoke tests against Test — success
  • CD / Promote to Int — success

Acceptance criteria covered by apps/api/src/trash/trash.e2e.db.test.ts (list/restore/purge, trash-hint 404, time-travel purge via injected clock — in CI), apps/api/src/scheduler/scheduler.service.db.test.ts (locking + restart-survival — in CI), and apps/web/e2e/trash.spec.ts (UI delete/restore/purge — run locally against the dev stack).

Implemented in a645763 and closed via `Closes #31`. Pipeline verification for that commit: - CI / Lint, typecheck, test — success - CI / Auth e2e pack — success - CD / Build and push images — success - CD / Deploy to Test — success - CD / Smoke tests against Test — success - CD / Promote to Int — success Acceptance criteria covered by `apps/api/src/trash/trash.e2e.db.test.ts` (list/restore/purge, trash-hint 404, time-travel purge via injected clock — in CI), `apps/api/src/scheduler/scheduler.service.db.test.ts` (locking + restart-survival — in CI), and `apps/web/e2e/trash.spec.ts` (UI delete/restore/purge — run locally against the dev stack).
Sign in to join this conversation.
No project
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: stwaidele/dorfteich#31
No description provided.