gendesign/backend/app
lekss361 ed3c128528 feat(nspd): TIER 4 opportunity layers + red lines (#94 PR2 of 4)
- NSPDClient: QUARTER_OPPORTUNITY_LAYERS (auction/scheme/free/future/oopt)
  + QuarterDump.opportunity field
- nspd_sync: harvest_quarter accepts include_opportunity, denorm cols
  has_auction_parcels + opportunity_count in UPSERT
- quarter_dump_lookup:
  - _get_opportunity_parcels (sort by distance, early-exit on count=0)
  - _get_red_lines (query existing dump.red_lines core path, layer='red_lines')
- SQL 89_*: has_auction_parcels + opportunity_count + partial index
- Pydantic: OpportunityParcel + RedLine schemas
- /analyze: nspd_opportunity_parcels + nspd_red_lines fields
- Frontend: NspdOpportunityBlock + NspdRedLinesBlock + LandTab integration
- Tests: 28 total (11 PR1 + 17 PR2), all pass

Red lines uses existing core harvest path (layer 879243 already in dump.red_lines
from PR1+core) — no duplicate harvest, no red_lines_count_v2 column needed.

Part of #94
2026-05-16 19:06:22 +03:00
..
api feat(nspd): TIER 4 opportunity layers + red lines (#94 PR2 of 4) 2026-05-16 19:06:22 +03:00
core refactor(admin): extract _check_token into shared AdminTokenAuth dep (#133) 2026-05-14 23:45:44 +03:00
models feat(jobs): centralized job_settings API + DB-driven beat schedule 2026-05-11 15:38:13 +03:00
schemas feat(nspd): TIER 4 opportunity layers + red lines (#94 PR2 of 4) 2026-05-16 19:06:22 +03:00
scrapers feat(cadastre): per-category NSPD snapshot — Phase 1.5 (ZOUIT/ENK) (#180) 2026-05-15 16:53:49 +03:00
services feat(nspd): TIER 4 opportunity layers + red lines (#94 PR2 of 4) 2026-05-16 19:06:22 +03:00
workers feat(nspd): TIER 4 opportunity layers + red lines (#94 PR2 of 4) 2026-05-16 19:06:22 +03:00
__init__.py init 2026-04-25 13:45:19 +03:00
main.py feat(etl): objective_complex_mapping backfill via pg_trgm (#203) (#214) 2026-05-16 12:47:09 +00:00