b48e7dbc65
RunAsync now calls a new RunPostIngestCleanupAsync at the end of each crawl: archive out-of-scope/duplicate listings, merge duplicate + fold junk facilities, and backfill missing Tehran coords. All in-place, reversible for listings, guarded for facilities, and pure DB+CPU (no AI/network) so it is cheap to run every ingest. The cleanup counts are appended to the run-log detail. This keeps legacy + freshly-arrived junk from accumulating without the admin having to click the cleanup buttons after each run. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>