Commit graph

14 commits

Author SHA1 Message Date
e673811a20 feat(parcels): layout signature schemas + extractor (#113 PR A) (#193)
All checks were successful
Deploy / changes (push) Successful in 4s
Deploy / build-backend (push) Successful in 1m45s
Deploy / build-frontend (push) Has been skipped
Deploy / build-worker (push) Successful in 3m1s
Deploy / deploy (push) Successful in 49s
2026-05-16 07:52:34 +00:00
4deb1b0284 feat(parcels): connection-points endpoint (Forgejo #115 Phase 1 backend) (#190)
Some checks failed
Deploy / changes (push) Successful in 5s
Deploy / build-frontend (push) Failing after 0s
Deploy / build-worker (push) Successful in 5m11s
Deploy / deploy (push) Failing after 0s
Deploy / build-backend (push) Successful in 3m44s
2026-05-16 05:58:27 +00:00
e561df1b55 feat(parcels): competitors endpoint (Forgejo #112 Phase 1 backend) (#191)
Some checks failed
CI / backend (push) Successful in 1m16s
Deploy / changes (push) Successful in 6s
Deploy / build-backend (push) Failing after 12s
Deploy / build-worker (push) Failing after 12s
Deploy / build-frontend (push) Failing after 0s
Deploy / deploy (push) Failing after 0s
CI / frontend (push) Successful in 2m17s
2026-05-15 22:21:05 +00:00
lekss361
99e2210919
fix(cadastre): NSPD response parse — properties.category + top-level meta (#168) (#177)
* fix(cadastre): NSPD response parse — properties.category + top-level meta (#168)

* fix(cadastre): test fixtures use real NSPD shape — properties.category + top-level meta (#168)

Bot review of #177 flagged that fixtures still used legacy properties.categoryId
+ data.meta — meaning CI exercised only fallback branches, not primary paths
where the actual bug lived. Pattern of 3 consecutive "live-only" parse fixes
(#175 verify, #176 headers, #177 parse) confirmed need for test coverage.

Changes:
- test_nspd_bulk_client.py: sample_quarter_response → properties.category +
  meta moved to top-level (real NSPD shape verified live)
- test_cadastre_bulk.py: 7 fixtures categoryId → category (regex replace)
- test_nspd_bulk_feature_parse_basic: primary path now exercised

Plus schema hardening per bot review:
- NSPDBulkFeature.category_id: `is not None` check (not truthy `or`)
  to avoid edge case category=0; int() wrapped in try/except so
  non-numeric ID (e.g. "ЗУ") doesn't crash upsert_features loop.

35/35 tests pass locally.

---------

Co-authored-by: lekss361 <claudestars@proton.me>
2026-05-15 15:40:01 +03:00
lekss361
b7889d113b
feat(cadastre): NSPDBulkClient + schemas for bulk ingest (#168 PR2/5) (#170)
Add async NSPD client (nspd_bulk_client.py) with 3 new methods:
- search_by_quarter: REST /api/geoportal/v2/search/geoportal — snapshot 20 per cat + meta totals
- wms_feature_info: WMS GetFeatureInfo для grid-walk discovery
- list_objects_in_building: tab-group-data (Q3 deferred — код ready)

Rate limit: asyncio.Semaphore(3) + 0.05s jitter.
429 → exponential backoff 2→4→8s, max 3 retries.
403 (WAF) → raise immediately, no retry.

Pydantic schemas (nspd_bulk.py): NSPDBulkFeature, QuarterSnapshot, ObjectsListing
with extra='allow' to preserve unknown fields → raw_props JSONB downstream.

15 unit tests + 4 e2e (real NSPD, skipped in CI by default).

Co-authored-by: lekss361 <claudestars@proton.me>
2026-05-15 12:50:41 +03:00
lekss361
c31da62e8d feat(analytics): recommend_mix v3.1-v3.4 - noise + 2D competitors + 24m cap + success-driven 2026-05-11 22:19:41 +03:00
lekss361
2847262953 feat(analytics): extend recommend comparables with cad_quarter, lat/lon, buildings_n 2026-05-11 17:30:09 +03:00
lekss361
fe2a881cec feat(api,analytics): bulk geo backfill + complex_buildings query
- POST /api/v1/admin/scrape/geo/bulk — splits pending Sverdlovsk cad-nums
  into N chunks (parallelism 1..10, default 5), creates N jobs and enqueues
  each in queue=geo. source_kind='rosreestr_pending_chunk' for tracking.
- analytics_queries.complex_buildings(db, obj_id) — returns list of buildings
  from cad_buildings (cad_num, floors, area, purpose, name, address, geom).
- object_detail: LEFT JOIN v_complex_buildings, adds buildings_count.
- top_developers: adds complexes_count via correlated subquery.
- GET /api/v1/analytics/object/{obj_id}/buildings → list[ComplexBuilding].
2026-05-11 15:56:17 +03:00
lekss361
2fee7739e8 feat(jobs): centralized job_settings API + DB-driven beat schedule
- JobSetting ORM model (JSONB extra_config) + Pydantic schemas
- GET/PUT /api/v1/admin/jobs/settings + /{job_type} (X-Admin-Token auth)
- celery_app.py builds beat_schedule from job_settings DB (env fallback
  retained for safety on first deploy / DB unreachable)
- nspd_geo task reads rate_ms from job_settings when per-job row has
  no override
- enqueue/resume geo jobs route to queue_name from job_settings
- Worker container: --queues=celery,scrape_kn,geo (one container,
  three named queues — kn sweep no longer blocks nspd_geo)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 15:38:13 +03:00
lekss361
132d57a3f3 fix recommend page 2026-04-29 08:16:22 +03:00
lekss361
7a23aa9edc fix: heartbeat-based zombie autoclean (10min) + Phase A heartbeats; ship recommend velocity calculator
Scraper resume:
- /admin/scrape/queue autoclean уменьшен с 60min started_at до 10min
  COALESCE(heartbeat_at, started_at). Не режет валидные long sweeps.
- Phase A пишет heartbeat после каждого objStatus fetch (3min Phase A
  больше не рискует быть отмеченной как zombie при новом 10min threshold).

Recommend (Уровень 1 калькулятор):
- POST /api/v1/analytics/recommend/mix с velocity baseline (sale_graph),
  price elasticity (regr_slope/r2 на sale_graph, fallback -1.5),
  inverse mode (target_months → required price_factor), liquidity score
  24mo, headline.
- /analytics/recommend: RecommendVelocityPanel (price slider 0.85..1.15
  + 4 KPI Чек/Срок/Темп/Ликвидность + методология эластичности),
  RecommendLiquidityChart (cumulative 0..36 mo с пунктиром на 24).
- BucketsTable: +колонки Темп и Срок, цены/выручка масштабируются по
  priceFactor live.
- Все слайдеры и target_months считаются клиентски — никаких round-trip.

Fix: SQLAlchemy не парсит :cls::text — заменено на CAST(:cls AS TEXT).
2026-04-28 22:54:03 +03:00
lekss361
ecc0dbafd5 add predict 2026-04-27 21:28:02 +03:00
lekss361
6c4ba1777a deploy.yml: sync compose+Caddyfile from git, reload caddy after up 2026-04-26 13:31:26 +03:00
lekss361
b95559eac9 init 2026-04-25 13:45:19 +03:00