import type { Database } from "@midday/db/client"; import { type UpdateDocumentByPathParams, updateDocumentByPath, } from "@midday/db/queries"; import type { createLoggerWithContext } from "@midday/logger"; /** * Update a document by path with retry logic for race conditions. * * This handles the case where a Supabase storage trigger creates the document * record slightly after the job starts processing. If the first update returns * 0 rows (document not found), we retry after a short delay. * * @param db - Database connection * @param params - Update parameters (pathTokens, teamId, etc.) * @param logger - Logger instance for warning messages * @param maxRetries - Maximum number of attempts (default: 2) * @param delayMs - Delay between retries in milliseconds (default: 1000) * @returns Updated document records or empty array if all retries failed */ export async function updateDocumentWithRetry( db: Database, params: UpdateDocumentByPathParams, logger: ReturnType, maxRetries = 2, delayMs = 1000, ): Promise>> { for (let attempt = 1; attempt <= maxRetries; attempt++) { const result = await updateDocumentByPath(db, params); if (result && result.length > 0) { return result; } if (attempt < maxRetries) { logger.warn("Document update returned 0 rows, retrying", { attempt, maxRetries, pathTokens: params.pathTokens, teamId: params.teamId, delayMs, }); await new Promise((r) => setTimeout(r, delayMs)); } } // Final attempt failed - return empty array logger.warn("Document update failed after all retries", { pathTokens: params.pathTokens, teamId: params.teamId, maxRetries, }); return []; }