What happened

Direct SQL fix to update_exclusions corrected the DB, but Redis still held stale data. Broccoli hits Redis first, never reached the DB, kept skipping 289 locations. The 2 locations edited via UI worked because UI calls invalidate cache automatically.

The rule

  • API updates → cache invalidated automatically ✅
  • Direct SQL updates → cache not invalidated — must clear manually ❌

Redis had no TTL — stale data lived forever until explicitly cleared.

Correct order for manual fixes

  1. Fix DB via SQL
  2. Clear Redis: POST /locations/clear-cache
  3. Re-run the sync

Debugging mental model

Always check all three layers — they can disagree:

API response ← Redis ← PostgreSQL

If API looks wrong but DB is correct, suspect cache.