import { v } from "convex/values"; import type { TableNames } from "./_generated/dataModel"; import { internalMutation } from "./_generated/server"; /** * Temporary bounded-batch deleter for the 2026-08-01 tenancy cutover. * Delete tables in RETIRED_TABLE_DELETE_ORDER, calling * `deleteRetiredTableBatch` repeatedly with a small limit until a table * returns fewer rows than the limit, then move to the next table. */ export const RETIRED_TABLE_DELETE_ORDER = [ "flueAttachments", "flueRuns", "flueEventEntries", "flueEventStreams", "flueConversationBatches", "flueConversationStreams", "flueAttemptMarkers", "flueSubmissions", "flueMeta", "workDeliveries", "workArtifacts", "resolverDecisions", "workAttemptEvents", "workAttempts", "workRuns", "workSlices", "designPackets", "workQuestions", "workDefinitions", "workEvents", "signalWorkAttachments", "works", "signalSources", "signalConstraints", "signals", "conversationAttachments", "conversationMessages", "conversationTurns", "conversations", ] as const; export const deleteRetiredTableBatch = internalMutation({ args: { limit: v.number(), table: v.string(), }, handler: async (ctx, args) => { const batchSize = Math.min(Math.max(Math.floor(args.limit), 1), 500); // The reduced schema no longer lists retired tables, so the name is cast. const rows = await ctx.db.query(args.table as TableNames).take(batchSize); for (const row of rows) { await ctx.db.delete(row._id); } return { deleted: rows.length }; }, });