PR #260 second-opinion review 🔴 BLOCK → fixes: 1. nspd_bulk_client.py: _SEMAPHORE module-level → per-instance self._sem создаётся в __aenter__ под текущий event loop. Sequential asyncio.run() в search_by_quarter (11 layers × asyncio.run() per layer) bind'ил module-level semaphore к first loop'у → RuntimeError на втором вызове → все cells return_exceptions=True проглатывали → grid возвращал 0 features. 2. nspd_sync.py: harvest_quarter добавлен time_limit=900 (hard) рядом с soft_time_limit=600. Safety net если task игнорит SoftTimeLimitExceeded. 3. tests/test_nspd_client.py: добавлен _make_fake_grid_walk helper + monkeypatch NSPDClient.get_features_in_bbox_grid в 3 тестах (search_by_quarter_core_only / _with_zouit / _layers_fetched_with_risks). Без этого area layers били бы по живому NSPD API → CI flaky. Tests: 37 passed, 1 skipped (3 area-dispatch + 34 grid-walk). |
||
|---|---|---|
| .. | ||
| api | ||
| core | ||
| models | ||
| observability | ||
| schemas | ||
| scrapers | ||
| services | ||
| workers | ||
| __init__.py | ||
| main.py | ||