Replaces tradein.cad_buildings manual snapshot (36k rows, frozen 2026-05-22) with live postgres_fdw foreign table reading gendesign.v_tradein_cad_buildings directly. Also reverts PR #492 HTTP-based cadastral.py — superseded by FDW. Architecture: - gendesign DB: new role tradein_fdw_reader + flat view v_tradein_cad_buildings (EKB-only slice of cad_buildings with lat/lon flattened from geom) - networks: gendesign-postgres added to gendesign_shared (alias); tradein-postgres added to gendesign_shared for FDW connect - tradein DB: postgres_fdw extension + FOREIGN TABLE gendesign_cad_buildings - tradein backend: startup hook creates/refreshes USER MAPPING with password from env GENDESIGN_FDW_PASSWORD (password rotation handled via restart) - geocoder.py: cadastral primary for forward + reverse + suggest; Yandex/Nominatim fallback. reverse_geocode wraps Nominatim in try/except — no more HTTPStatusError → 500. - house_metadata.py and trade_in.py admin stats switched to foreign table - DROP TABLE cad_buildings in tradein (legacy snapshot removed entirely) - import-cadastre.sh deleted (no manual sync needed) Fixes: - /trade-in/api/v1/geocode/reverse 500 (Nominatim ban → no fallback) - estimate confidence_explanation=address_not_geocoded for addresses in our cadastre (e.g. Хохрякова 81) that Nominatim doesn't return Deploy ordering: main migration 100_tradein_fdw_role.sql adds role+view first (strict deploy.yml). Tradein next deploy applies 060_postgres_fdw_extension.sql and 061_drop_legacy_cad_buildings.sql (idempotent, errors ignored). Tradein backend startup creates USER MAPPING when env var present. Verify post-deploy with: docker exec tradein-postgres psql -U tradein -d tradein -c \ "SELECT count(*) FROM gendesign_cad_buildings" # expect ~36k EKB buildings.
36 lines
1.3 KiB
PL/PgSQL
36 lines
1.3 KiB
PL/PgSQL
-- tradein_fdw_reader role + v_tradein_cad_buildings view
|
|
-- Used by tradein-postgres via postgres_fdw to read live cad_buildings.
|
|
-- See meta/00_credentials.md for password rotation procedure.
|
|
BEGIN;
|
|
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'tradein_fdw_reader') THEN
|
|
CREATE ROLE tradein_fdw_reader LOGIN PASSWORD '40473b7c10c7474855c7d1aa98f0fd0a0de2499aef0cbd1fead06c9641e4dcd8';
|
|
END IF;
|
|
END$$;
|
|
|
|
GRANT CONNECT ON DATABASE gendesign TO tradein_fdw_reader;
|
|
GRANT USAGE ON SCHEMA public TO tradein_fdw_reader;
|
|
|
|
CREATE OR REPLACE VIEW v_tradein_cad_buildings AS
|
|
SELECT
|
|
cad_num,
|
|
NULLIF(trim(readable_address), '') AS readable_address,
|
|
NULLIF(floors, 0) AS floors,
|
|
CASE WHEN year_built BETWEEN 1800 AND 2100 THEN year_built END AS year_built,
|
|
round(COALESCE(build_record_area, area), 2)::numeric AS area_m2,
|
|
purpose,
|
|
ST_Y(ST_Centroid(geom))::double precision AS lat,
|
|
ST_X(ST_Centroid(geom))::double precision AS lon
|
|
FROM cad_buildings
|
|
WHERE cad_num LIKE '66:41:%'
|
|
AND geom IS NOT NULL
|
|
AND readable_address IS NOT NULL;
|
|
|
|
GRANT SELECT ON v_tradein_cad_buildings TO tradein_fdw_reader;
|
|
|
|
COMMENT ON VIEW v_tradein_cad_buildings IS
|
|
'FDW source for tradein-mvp (postgres_fdw). Flat 8-col EKB-only slice of cad_buildings. tradein.gendesign_cad_buildings maps here.';
|
|
|
|
COMMIT;
|