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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions