Midday / apps /worker /src /utils /document-update.ts
Jules
Final deployment with all fixes and verified content
c09f67c
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<typeof createLoggerWithContext>,
maxRetries = 2,
delayMs = 1000,
): Promise<Awaited<ReturnType<typeof updateDocumentByPath>>> {
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 [];
}