Skip to content

Core sync: orphaned-blob GC endpoint — owner-only POST /attachments/gc (core #64) #38

Description

@cuibonobo

Server side of haverstack/core#64. Core gets collectAttachmentGarbage({ graceMs?, dryRun? }) (owner-only on ScopedStack); the wire gets an optional owner-only endpoint, which this server — as the reference implementation — should ship.

Endpoint

POST /attachments/gc — owner-only (requireOwner), body { "graceMs"?: number, "dryRun"?: boolean }{ "deleted": [fileId...], "reclaimedBytes": number }.

Semantics are entirely core's (soft-deleted records count as references; a file's own _attachment@1 records don't, but recent ones defer collection via the grace period; deletion goes through the deleteAttachment path). The server adds the wire mapping, plus:

  • Scheduling/automation is explicitly a server concern per core #64 — decide whether this server offers any (e.g. optional interval env var) or stays invoke-only. Leaning invoke-only for v1; dryRun makes a cron-from-outside workflow safe.
  • Note the interaction with DELETE /attachments/:fileId: once core #63/#64 land, the 409 reference check also covers file-ref content references and soft-deleted records — server tests asserting current delete behavior will need updating.

Sequencing

Blocked on haverstack/core#63 (file-ref field kind) then haverstack/core#64 (BlobAdapter.listFiles(), the sweep itself). Do not ship a GC endpoint before file-ref reference semantics exist — it would delete content-referenced files (the exact blind spot core #63 documents).

Work items

Refs haverstack/core#64, haverstack/core#63, haverstack/core#60 (soft-delete-counts rationale), #32.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions