gendesign/backend/app/services/site_finder
lekss361 af39e95f83
fix(site-finder): SQLAlchemy syntax error :weights::jsonb → CAST(:weights AS jsonb) (#152)
Production POST /weight-profiles → 500 SyntaxError.

## Root cause

SQLAlchemy text() parser трактует ':weights' followed by '::jsonb' двусмысленно:
- ':weights' — named param binding (должен стать %(weights)s)
- '::jsonb' — PG cast operator

Parser НЕ распознаёт :weights как параметр когда сразу следует :: cast.
Result: psycopg видит literal ':weights' в SQL → syntax error.

```
LINE 5: ($1, $2, :weights::jsonb, $3, $4)
                   ^
parameters: {user_id, profile_name, is_default, description}
            ↑ note: 'weights' missing — SQLAlchemy skipped it
```

## Fix

Replace ambiguous :weights::jsonb с CAST(:weights AS jsonb):
- _INSERT (line 102)
- _UPDATE dynamic 'weights = :weights::jsonb' (line 273)

CAST() syntax не имеет ambiguity, SQLAlchemy корректно bind'ит :weights.

## Affected endpoints

- POST /api/v1/admin/site-finder/weight-profiles (create)
- PUT /api/v1/admin/site-finder/weight-profiles/{id} (update with weights)

Refs: user report 2026-05-15

Co-authored-by: lekss361 <claudestars@proton.me>
2026-05-15 08:12:18 +03:00
..
__init__.py init 2026-04-25 13:45:19 +03:00
cadastre_fetch.py feat(site-finder): auto-fetch cadastre geometry on-demand (#93) (#95) 2026-05-12 09:02:17 +03:00
filters.py init 2026-04-25 13:45:19 +03:00
gate_verdict.py feat(site-finder): gate verdict aggregator — can-build-MKD signal (#32 G5 sub-PR 1/2) (#142) 2026-05-15 00:59:53 +03:00
noise_loader.py feat(site-finder): isochrones UI + networks VKH + OSM substations 2026-05-11 21:48:21 +03:00
parser.py init 2026-04-25 13:45:19 +03:00
poi_loader.py feat(site-finder): v3.1 — cad_parcels_geom, analyze fallback, POI lat/lon, OSM expand 2026-05-11 19:52:19 +03:00
pzz_loader.py fix(pzz_loader): replace bare db.rollback() with SAVEPOINT per-row (#124) 2026-05-14 23:29:23 +03:00
quarter_dump_lookup.py feat(site-finder): integrate nspd_quarter_dumps cache в analyze_parcel (#94 Sprint 1.1 FINAL) (#116) 2026-05-13 09:14:19 +03:00
scorer.py init 2026-04-25 13:45:19 +03:00
velocity.py feat(site-finder): D2 velocity-score from domrf_kn_sale_graph (#34 sub-PR 1/2) (#146) 2026-05-15 01:24:53 +03:00
weight_profiles.py fix(site-finder): SQLAlchemy syntax error :weights::jsonb → CAST(:weights AS jsonb) (#152) 2026-05-15 08:12:18 +03:00