Ctrl K
ComunidadGuías…

docs/manifest-deletion.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Deleted-version manifest cleanup

Deleting a version keeps its `version_files` row, so its delta files survive
the 7-day restore window; delta storage GC reclaims the R2 objects afterwards
(see [delta storage](delta-storage.md)). `on_version_update` only finalizes the
version's counters: one short transaction on one write pool sets
`manifest_count` to 0 and decrements `apps.manifest_bundle_count` once
(retries cannot double-decrement). An inline `app_versions.manifest` is cleared
only when the version has a `version_files` row; otherwise it is the only
reference GC sees, so it stays. Statements have a 15-second timeout and lock
waits a two-second timeout. There are no per-file connections or network calls.

Cleanup and manifest persistence take the existing per-version advisory lock and
lock the version row. Persistence rechecks deletion while locked, so an upload
that passed its earlier route check cannot add references to a deleted version.

The manifest-file trash/delete/restore system is fully removed, including its
restore helper and `manifest_trash_restore_pending` table. The migration drops
that table and any records it contains; there is no recovery drain or replacement
collector. The sweeper only requeues database cleanup, rotates versions by their
last requeue time, and leaves counter finalization to the handler.
Sweeper retries also finish ZIP and metadata cleanup after the final database
batch, including deletions that exceeded the original five queue attempts.

Deploy the handler and drain old in-flight handlers before applying the migration
that drops the recovery table. First run the database-only
`scripts/reclaim_deleted_version_manifests.ts` with an explicit `SUPABASE_DB_URL`.
It replaces the old manual R2 trash script: it marks legacy zero-count versions
for requeue without touching objects or app counters. Its one-time scan uses the
existing `(deleted_at, id)` index in 50-version pages, shares version locks with
cleanup, preserves timestamp microseconds, and handles null deletion dates.
Each committed page saves a local checkpoint; failures retain the prior
checkpoint and write a report containing the affected version IDs. Rerun with the
same database/checkpoint to resume. `MANIFEST_REQUEUE_CHECKPOINT` can override the
default file in the temporary directory. This is a rollout operation, not a cron.

On databases with more than 10,000 versions,
prebuild the retry index using `scripts/ops/deleted_manifest_retry_index.sql`,
outside a transaction. The migration refuses an inline index build above that
size and bounds lock waits and statement duration on smaller databases.
Channel unlinking, bundle cache purge, metadata/storage-statistics updates and
canonical version-owned ZIP trash/retry remain part of version deletion.

The sweeper remains a service-role-only cron RPC, called once per sweep. Its
candidate search starts from deleted versions ordered by `updated_at, id`
(`idx_app_versions_deleted_manifest_pending`), filtered to positive counters or
legacy JSON. Finished versions leave that index; normal sweeps never probe
manifest rows or scan finished deletion history. It updates at
most the requested batch. No new RLS function, public RPC, cron, or extension is
introduced. Cleanup queries target one version; they do not scan all manifests.