[VS-NfD] Implement the orphan-file sweep and resolve Attachment.deletedAt #194

Closed
opened 2026-07-30 01:43:31 +02:00 by fable-5 · 1 comment
Collaborator

Plan reference: 20-massnahmenplan.md -> Phase 2
ADR: n/a
Effort: M (2 AT)
Depends on:

Context

Files whose page no longer embeds them are never reclaimed, so content can
survive its page indefinitely on disk. An unused nullable column that looks
like a soft-delete marker is itself a finding — a reader cannot tell
whether deletion is soft or hard.

Current state

  • apps/api/prisma/schema.prisma:530–538 documents both facts explicitly:
    the pageId link is "not touched when an image is later removed from its
    page's content — an orphan-file sweep to reclaim those is a separate
    future maintenance job (operations.md), not this one", and
    "deletedAt stays unused for now — purge hard-deletes attachments".

Acceptance criteria

  • A scheduled sweep identifies attachments no longer referenced by any
    live page document and removes row plus file, correcting quota usage.
  • A grace period protects the paste-then-insert window (an upload whose
    page does not exist yet) — proven by a test.
  • Attachment.deletedAt is either used by the sweep with documented
    semantics or removed by migration; the schema comment matches the
    outcome.
  • Test: file removed from page content is reclaimed after the grace
    period; a freshly uploaded, not-yet-embedded file is not.
  • docs/architecture/operations.md documents the job; #229 covers it.

Out of scope

Deduplication by content hash (see #199) and pond purge (#193).

**Plan reference:** `20-massnahmenplan.md` -> Phase 2 **ADR:** n/a **Effort:** M (2 AT) **Depends on:** — ## Context Files whose page no longer embeds them are never reclaimed, so content can survive its page indefinitely on disk. An unused nullable column that looks like a soft-delete marker is itself a finding — a reader cannot tell whether deletion is soft or hard. ## Current state - `apps/api/prisma/schema.prisma:530–538` documents both facts explicitly: the `pageId` link is "not touched when an image is later removed from its page's content — an orphan-file sweep to reclaim those is a separate future maintenance job (operations.md), not this one", and "`deletedAt` stays unused for now — purge hard-deletes attachments". ## Acceptance criteria - [ ] A scheduled sweep identifies attachments no longer referenced by any live page document and removes row plus file, correcting quota usage. - [ ] A grace period protects the paste-then-insert window (an upload whose page does not exist yet) — proven by a test. - [ ] `Attachment.deletedAt` is either used by the sweep with documented semantics **or** removed by migration; the schema comment matches the outcome. - [ ] Test: file removed from page content is reclaimed after the grace period; a freshly uploaded, not-yet-embedded file is not. - [ ] `docs/architecture/operations.md` documents the job; #229 covers it. ## Out of scope Deduplication by content hash (see #199) and pond purge (#193).
fable-5 added this to the M24 — VS-NfD: security quick wins milestone 2026-07-30 01:43:31 +02:00
fable-5 added the
area:storage
effort:M
vs-nfd
labels 2026-07-30 01:43:31 +02:00
Author
Collaborator

Delivered by PR #249 (0bc36aa + fence fix 02c1f18), merged to main fast-forward. CI run 494 green (493 red was the job-count fence catching the deliberate sixth job). Deviation from the AC documented in the PR: claimed-but-unembedded attachments are NOT auto-swept (panel assets are user-managed; content-reference sweeping would destroy data). Closing.

Delivered by PR #249 (0bc36aa + fence fix 02c1f18), merged to main fast-forward. CI run 494 green (493 red was the job-count fence catching the deliberate sixth job). Deviation from the AC documented in the PR: claimed-but-unembedded attachments are NOT auto-swept (panel assets are user-managed; content-reference sweeping would destroy data). Closing.
Sign in to join this conversation.
No project
No Assignees
1 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#194
No description provided.