import { env } from "cloudflare:workers"; import { CAPS } from "../limits"; import { forgetReachability } from "./reachable"; import type { RepoRow } from "~/lib/types"; /** Every KV namespace that caches a repository's objects or derived data, keyed by its Artifacts name. */ const PREFIXES = ["commit:", "tree:", "blob:", "diff:v2:", "compare:v1:", "path-log:v1:", "last-commit:v2:"]; /** * Best-effort purge of a repository's cached objects after deletion or a visibility change (GIT-A13). Every * read path re-checks permission before touching these keys, so this is hygiene rather than access control; * the loop is bounded by `CAPS.cachePurgeKeys` and never throws into the caller. */ export async function purgeRepoCaches(repo: Pick): Promise { await forgetReachability(repo.id); let budget = CAPS.cachePurgeKeys; for (const prefix of PREFIXES) { let cursor: string | undefined; while (budget > 0) { const page = await env.KV.list({ prefix: `${prefix}${repo.artifacts_name}:`, cursor, limit: Math.min(budget, 1000), }); for (const key of page.keys) await env.KV.delete(key.name); budget -= page.keys.length; if (page.list_complete) break; cursor = page.cursor; } if (budget <= 0) break; } }