Problem
PR #54 ([#12] Cron Backfill) merged with silent error handling on all database upsert operations. The inline indexers (plot, storyline, donation) correctly check { error } from Supabase upserts and return appropriate HTTP errors — the backfill does not.
Issues
1. No error check on upsert operations
All three event processors (processStorylineCreated, processPlotChained, processDonation) ignore the return value of supabase.from(...).upsert(...). If an insert fails (FK violation, constraint error, etc.), the backfill silently continues and reports success.
Compare inline indexer (correct):
const { error: dbError } = await supabase.from("storylines").upsert(...);
if (dbError) {
return error(`Database error (storyline): ${dbError.message}`, 500);
}
Backfill (missing):
await supabase.from("storylines").upsert(storylineRow, { onConflict: "tx_hash,log_index" });
// ← No error handling
2. Orphaned genesis plot risk
In processStorylineCreated, the genesis plot upsert runs immediately after the storyline upsert. If the storyline insert fails, the plot insert also fails at the FK constraint level — but neither error is reported.
3. Error counter only tracks decode failures
The errors counter in the main handler only increments on catch (decoding/IPFS failures). DB failures are not counted, so the response { processed, errors } is misleading.
4. Cursor update not checked
The final backfill_cursor update also doesn't check for errors.
Acceptance Criteria
Problem
PR #54 (
[#12] Cron Backfill) merged with silent error handling on all database upsert operations. The inline indexers (plot, storyline, donation) correctly check{ error }from Supabase upserts and return appropriate HTTP errors — the backfill does not.Issues
1. No error check on upsert operations
All three event processors (
processStorylineCreated,processPlotChained,processDonation) ignore the return value ofsupabase.from(...).upsert(...). If an insert fails (FK violation, constraint error, etc.), the backfill silently continues and reports success.Compare inline indexer (correct):
Backfill (missing):
2. Orphaned genesis plot risk
In
processStorylineCreated, the genesis plot upsert runs immediately after the storyline upsert. If the storyline insert fails, the plot insert also fails at the FK constraint level — but neither error is reported.3. Error counter only tracks decode failures
The
errorscounter in the main handler only increments oncatch(decoding/IPFS failures). DB failures are not counted, so the response{ processed, errors }is misleading.4. Cursor update not checked
The final
backfill_cursorupdate also doesn't check for errors.Acceptance Criteria
upsert()calls destructure{ error }and log/count failureserrorsresponse field reflects both decode AND database failuresplotChainedEvent,storylineCreatedEvent,donationEvent)npm run lintandnpm run typecheckpass