feat(site-finder): резервы мощности для ТП — электро+вода на карте §3 (#2119 Фаза A)
Наполнение карты точками подключения с ХАРАКТЕРИСТИКАМИ (свободная мощность)
из верифицированных источников (research #2119). Все источники гео-блокируют
не-RU IP — лоадеры выполняются на проде (Celery weekly + ручной docker exec).
Backend:
- Миграция 180: power_supply_centers (ПС 35-220кВ, точки + резерв МВА),
power_tp_rp_reserves (10.7k ТП/РП 6-10кВ, геокод — Фаза B),
water_supply_reserves (ЦСВ/ЦСК Водоканала). UNIQUE NULLS NOT DISTINCT на
nullable-ключах (грабли #140).
- rosseti_wfs_loader: открытый WFS портал-тп.рф (punycode) → 488 ПС Свердл обл,
индекс загрузки 256184/6/8 → open/limited/closed, voltage из имени.
- rosseti_reserve_loader: раскрытие ПП№24 (xlsx) — ЦП 35-110кВ (строка 8+)
матчится к WFS-точкам по нормализованному имени; ТП/РП <35кВ (строка 9+),
кВА-санити (>2.5 МВА для ТП → ÷1000), «н/д»→NULL, SAVEPOINT per-row.
- vodokanal_reserve_loader: DOCX-раскрытие ПП№6 (stdlib parse, vMerge
forward-fill), отрицательные резервы (город: дефицит) сохраняются со знаком.
- Endpoint GET /{cad}/connection-capacity: ПС в радиусе (ST_DWithin geography)
+ summary + вода за последний период per-system_kind. Celery: вт 04:00/04:30.
Frontend (§3):
- Карточка «Ресурсные резервы»: ближайший ЦП с резервом МВА + статус-бейдж;
вода/канализация с красным «дефицит» при отрицательном резерве + примечание.
- Слой «Центры питания (резерв)» на карте: цвет по индексу загрузки
(зелёный/янтарь/красный), попап с напряжением/мощностью/загрузкой/резервом,
легенда под картой. Числа через toFiniteNumber (Decimal→str coercion).
api-types.ts перегенерён офлайн (+131/-0, аддитивно). 39 тестов зелёные.
Deep-review: ⚠️ MINOR → все 3 замечания исправлены (NULLS NOT DISTINCT,
per-kind MAX(period), settlement-комментарий).