08cf615ad7
feat(tradein/cian): surface valuation chart + rent + change-pct on /trade-in ( #530 )
Deploy Trade-In / deploy (push) Blocked by required conditions
Deploy Trade-In / changes (push) Successful in 5s
Deploy Trade-In / build-backend (push) Successful in 48s
Deploy Trade-In / build-frontend (push) Has been cancelled
2026-05-24 14:32:54 +00:00
c8675ce6e2
feat(yandex-valuation): link history rows to houses via match_or_create_house ( #531 )
Deploy Trade-In / deploy (push) Successful in 36s
Deploy Trade-In / changes (push) Successful in 5s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 44s
2026-05-24 14:28:30 +00:00
7dc11e4339
feat(tradein-api): surface backfilled houses + placement history ( #528 )
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / deploy (push) Successful in 38s
Deploy Trade-In / changes (push) Successful in 6s
Deploy Trade-In / build-backend (push) Successful in 44s
2026-05-24 14:22:50 +00:00
f2f9e5b79b
feat(tradein-ui): placement history card ( #529 )
Deploy Trade-In / deploy (push) Blocked by required conditions
Deploy Trade-In / build-frontend (push) Has been cancelled
Deploy Trade-In / changes (push) Successful in 6s
Deploy Trade-In / build-backend (push) Has been skipped
2026-05-24 14:22:16 +00:00
c6ab419100
feat(tradein-sql): bootstrap houses + link 98.8% of listings (Phase A+B) ( #527 )
Deploy Trade-In / changes (push) Successful in 6s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 41s
Deploy Trade-In / deploy (push) Successful in 37s
2026-05-24 14:17:32 +00:00
7ef4e91e50
fix(yandex-valuation): parse removed_date, fix total_floors regex, normalize NBSP ( #526 )
Deploy Trade-In / deploy (push) Successful in 34s
Deploy Trade-In / changes (push) Successful in 6s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 42s
2026-05-24 14:12:16 +00:00
591039493c
feat(tradein/cian): admin endpoints + UI for detail+newbuilding history scrape ( #525 )
Deploy Trade-In / build-backend (push) Successful in 58s
Deploy Trade-In / build-frontend (push) Successful in 1m37s
Deploy Trade-In / deploy (push) Successful in 1m45s
Deploy Trade-In / changes (push) Successful in 6s
2026-05-24 14:05:55 +00:00
0f7d6c4996
fix(tradein-imv): adapt to Avito 3-step API contract (2026-05+) ( #524 )
Deploy Trade-In / changes (push) Successful in 6s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / deploy (push) Successful in 33s
Deploy Trade-In / build-backend (push) Successful in 45s
2026-05-24 13:48:52 +00:00
bad23095cf
fix(tradein/cian): sanitize valuation cache writes (047 UNIQUE + 026/044 cols) ( #523 )
Deploy Trade-In / changes (push) Successful in 5s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 41s
Deploy Trade-In / deploy (push) Successful in 33s
2026-05-24 13:44:39 +00:00
45ee0a2945
fix(tradein-estimator): extend cohort filter to Tier S + Tier H, fix late_soviet overlap ( #522 )
Deploy Trade-In / changes (push) Successful in 7s
Deploy Trade-In / deploy (push) Successful in 33s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 42s
2026-05-24 13:14:59 +00:00
44cb5b509d
fix(beat): distinguish DB-unreachable from intentional-empty schedule ( #520 )
Deploy / build-backend (push) Successful in 1m26s
Deploy / deploy (push) Successful in 1m4s
Deploy / changes (push) Successful in 5s
Deploy / build-frontend (push) Has been skipped
Deploy / build-worker (push) Successful in 2m35s
2026-05-24 13:14:11 +00:00
d9c6b1bd01
chore(tradein): remove dead mock-fallback code from trade_in.py ( #521 )
Deploy Trade-In / changes (push) Successful in 6s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 51s
Deploy Trade-In / deploy (push) Successful in 32s
2026-05-24 13:11:13 +00:00
7cc7fafeeb
feat(tradein-estimator): cohort filter + Tier 0 for analog selection quality ( #519 )
Deploy Trade-In / deploy (push) Successful in 32s
Deploy Trade-In / changes (push) Successful in 5s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 40s
2026-05-24 13:04:58 +00:00
92d00ec874
feat(tradein-ui): mock-disclaimer + progressive enrichment + UX polish ( #517 )
Deploy Trade-In / build-frontend (push) Successful in 1m42s
Deploy Trade-In / deploy (push) Successful in 35s
Deploy Trade-In / changes (push) Successful in 5s
Deploy Trade-In / build-backend (push) Has been skipped
2026-05-24 12:58:39 +00:00
a0d50bd282
feat(tradein-estimator): tiered house-match S→H→W ( #507 )
Deploy Trade-In / changes (push) Successful in 5s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / deploy (push) Successful in 32s
Deploy Trade-In / build-backend (push) Successful in 38s
2026-05-24 12:41:12 +00:00
6cda0cf8d3
fix(tradein-estimator): restore CAST in IS NOT NULL predicates (revert audit #9 , prod fix) ( #518 )
Deploy Trade-In / changes (push) Successful in 5s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 41s
Deploy Trade-In / deploy (push) Successful in 31s
2026-05-24 12:35:28 +00:00
ac57b8e905
fix(scrapers): disable catalog-object SSR beat-cron — DOM.РФ WAF cooldown ( #516 )
Deploy / changes (push) Successful in 5s
Deploy / build-frontend (push) Has been skipped
Deploy / build-backend (push) Successful in 1m22s
Deploy / build-worker (push) Successful in 3m20s
Deploy / deploy (push) Successful in 1m5s
2026-05-24 12:21:10 +00:00
e45ff47aa6
fix(tradein-sql): remove duplicate CREATE INDEX from 050 (regression from PR #500 ) ( #515 )
Deploy Trade-In / changes (push) Successful in 6s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 26s
Deploy Trade-In / deploy (push) Successful in 35s
2026-05-24 12:16:27 +00:00
3190bbec54
fix(tradein-frontend): MapPicker focus trap + Leaflet SRI, PhotoUpload size check ( #514 )
Deploy Trade-In / changes (push) Successful in 5s
Deploy Trade-In / build-backend (push) Has been skipped
Deploy Trade-In / build-frontend (push) Successful in 1m26s
Deploy Trade-In / deploy (push) Successful in 32s
2026-05-24 12:01:17 +00:00
9402702f32
feat(tradein-estimator): unique-address-based confidence threshold ( #513 )
Deploy Trade-In / changes (push) Successful in 5s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 40s
Deploy Trade-In / deploy (push) Successful in 31s
2026-05-24 11:52:00 +00:00
3665a61e48
fix(tradein-frontend): safeUrl validator, apiFetch dedup, ListingsCard a11y, error boundary ( #512 )
Deploy Trade-In / changes (push) Successful in 5s
Deploy Trade-In / build-backend (push) Has been skipped
Deploy Trade-In / build-frontend (push) Successful in 1m24s
Deploy Trade-In / deploy (push) Successful in 32s
2026-05-24 11:47:38 +00:00
0767fb7401
fix(tradein-photos): sanitize uploaded images via Pillow re-encode ( #511 )
Deploy Trade-In / changes (push) Successful in 4s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 58s
Deploy Trade-In / deploy (push) Successful in 36s
2026-05-24 11:32:04 +00:00
f04359592f
Merge pull request 'fix(deploy): tradein_fdw_reader password — psql var interpolation in DO block' ( #510 ) from fix/tradein-fdw-psql-var-in-do into main
...
Reviewed-on: #510
2026-05-24 11:28:59 +00:00
606d3fe7c0
Merge pull request 'chore(rules): drop blocked-scope list from git-pr.md' ( #506 ) from chore/git-pr-rules-any-scope-v2 into main
...
Reviewed-on: #506
2026-05-24 11:26:10 +00:00
lekss361
08a8cf51b3
fix(deploy): mute psql set_config stdout — prevent password leak in CI logs
...
Review-bot PR #510 нашёл P0: `set_config(name,value,is_local)` возвращает
установленное значение, psql печатает rows на stdout без `-q`/`-A`/`-t`,
итог — фактический pw появляется в Forgejo Actions deploy logs (retained,
visible всем с repo read access).
Fix: оборачиваем оба `SELECT set_config(...)` в `\o /dev/null` / `\o`
brackets. Output mutes только для этих строк — NOTICE-сообщения из DO block
(idempotency signal 'tradein_fdw_reader password set') остаются видимыми.
Также добавлен rollback hint в комментарии: НЕ revert файл (вернёт сломанный
:'pw' внутри $$), а unset GENDESIGN_FDW_PASSWORD в .env.runtime на VPS.
2026-05-24 14:21:36 +03:00
7d8c22ff39
fix(tradein-estimator): atomic IMV link, batched yandex history, drop redundant CAST ( #509 )
Deploy Trade-In / deploy (push) Successful in 32s
Deploy Trade-In / changes (push) Successful in 5s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 39s
2026-05-24 11:18:12 +00:00
d4cbd4bb9f
feat(tradein-scrapers): parse listing_date from Avito + Yandex ( #508 )
Deploy Trade-In / changes (push) Successful in 5s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 39s
Deploy Trade-In / deploy (push) Has been cancelled
2026-05-24 11:17:13 +00:00
lekss361
35bf050e63
chore(rules): add decision date to self-extending guard (review #506 fixup)
...
Reviewer's optional recommendation #3 : добавить дату в hard
exception для audit trail. Также расширил wording: 'предотвращает
bot-loop где bot сам расширяет свои merge права' — делает intent
явным для будущих reviewers.
2026-05-24 14:10:53 +03:00
7f23a9b3f1
feat(tradein-imv): retry with cleaned address + categorize errors ( #505 )
Deploy Trade-In / changes (push) Successful in 5s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 40s
Deploy Trade-In / deploy (push) Successful in 38s
2026-05-24 11:04:24 +00:00
lekss361
da7814810c
fix(deploy): tradein_fdw_reader password — psql var interpolation in DO block
...
psql :'pw' substitution НЕ работает внутри dollar-quoted блока $$..$$ — это
правило psql, не bug. Symptom: deploy 2026-05-24 после merge PR #503 упал с
'syntax error at or near :' on LINE 4 of set_tradein_fdw_password.sql, :'pw'
дошёл до сервера как literal вместо интерполяции.
Fix: передаём password в DO через session GUC (set_config) — psql интерполирует
:'pw' ВНЕ dollar quote, внутри читаем через current_setting(). Очищаем GUC
после выполнения (defense-in-depth).
2026-05-24 14:03:15 +03:00
lekss361
c9737d26c9
chore(rules): drop blocked-scope list from git-pr.md — align with any-scope policy
...
Header line 10 + memory rule [Auto-merge any scope] (2026-05-16)
заявили APPROVE → merge любой scope. Body всё ещё содержал
устаревший blocked-list (data/sql, services, scrapers, и т.д.),
из-за которого session-side classifier'ы ошибочно блокировали
auto-merge approved PR (incident: PRs #501-504 ждали ручного merge).
Заменил Auto-merge scope section на Auto-merge policy:
- Любой scope OK при verdict=approve + SHA match
- Hard exception: secrets в diff + self-extending guard (изменение
самих правил всегда через human)
Также убрал Scope guard и Blocked-scope cap из Polling loop section.
2026-05-24 13:58:01 +03:00
099b8e4b59
fix(scrapers): DOM.РФ KN extras — bypass WAF + update renamed endpoints ( #503 )
Deploy / changes (push) Successful in 4s
Deploy / build-frontend (push) Has been skipped
Deploy / build-backend (push) Successful in 1m22s
Deploy / build-worker (push) Successful in 2m41s
Deploy / deploy (push) Failing after 35s
2026-05-24 10:53:28 +00:00
6bfa686f16
feat(tradein-estimator): exclude rosreestr deals from output ( #504 )
Deploy Trade-In / changes (push) Successful in 6s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 38s
Deploy Trade-In / deploy (push) Successful in 36s
2026-05-24 10:52:55 +00:00
8fc309d9ad
fix(tradein-avito): strip Emotion CSS from listings.address ( #502 )
Deploy Trade-In / build-backend (push) Blocked by required conditions
Deploy Trade-In / build-frontend (push) Blocked by required conditions
Deploy Trade-In / deploy (push) Blocked by required conditions
Deploy Trade-In / changes (push) Has been cancelled
2026-05-24 10:52:50 +00:00
1026165abb
fix(tradein-matching): pg_advisory_xact_lock to prevent duplicate house INSERTs ( #501 )
Deploy Trade-In / deploy (push) Blocked by required conditions
Deploy Trade-In / changes (push) Successful in 5s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-backend (push) Has been cancelled
2026-05-24 10:52:10 +00:00
02b48b8d04
fix(tradein-sql): rename dup 030, add trade_in_estimates geom, drop dup indexes ( #500 )
...
Deploy Trade-In / changes (push) Successful in 5s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 23s
Deploy Trade-In / deploy (push) Successful in 32s
Close 3 SQL schema findings from 2026-05-24 trade-in audit.
- Rename 030_listings_alter_yandex.sql -> 033_*.sql (resolve dup prefix with 030_avito_imv_cache_key_unique.sql).
- New 034_trade_in_estimates_geom.sql: PostGIS geom column + GIST index + backfill + BEFORE INSERT/UPDATE trigger.
- New 035_drop_duplicate_indexes.sql: drop listing_sources_listing_idx2 (dup of 028) and houses_geom_idx2 (dup of 009).
All idempotent. Deploy script uses ls|sort + no tracking table — rename is safe because original 030 already applied (IF NOT EXISTS no-op on re-run as 033).
2026-05-24 10:04:40 +00:00
ed49f6b953
fix(deploy): resolve FDW bootstrap race + extract bootstrap DO block to .sql file ( #499 )
Deploy Trade-In / changes (push) Successful in 6s
Deploy / changes (push) Successful in 5s
Deploy Trade-In / build-backend (push) Successful in 24s
Deploy Trade-In / build-frontend (push) Successful in 23s
Deploy / build-backend (push) Successful in 26s
Deploy / build-worker (push) Successful in 25s
Deploy / build-frontend (push) Successful in 25s
Deploy Trade-In / deploy (push) Successful in 33s
Deploy / deploy (push) Failing after 22s
2026-05-24 09:46:00 +00:00
03ab1faa7c
chore(claude): aggressive worktree cleanup via Forgejo PR API ( #498 )
2026-05-24 09:34:48 +00:00
998c8a17a8
chore(claude): agents view readiness — cleanup, .worktreeinclude, workflow ( #497 )
2026-05-24 09:20:26 +00:00
643064ee0c
chore(claude-rules): promote 3 deferred feedback rules from memory ( #496 )
2026-05-24 09:01:27 +00:00
94cf199276
feat(tradein): postgres_fdw live read of gendesign.cad_buildings (replaces snapshot) ( #493 )
...
Deploy Trade-In / changes (push) Successful in 5s
Deploy / changes (push) Successful in 5s
Deploy Trade-In / build-frontend (push) Successful in 26s
Deploy Trade-In / build-backend (push) Successful in 47s
Deploy / build-frontend (push) Successful in 29s
Deploy / build-backend (push) Successful in 1m24s
Deploy Trade-In / deploy (push) Successful in 40s
Deploy / build-worker (push) Successful in 2m57s
Deploy / deploy (push) Failing after 37s
Replaces tradein.cad_buildings snapshot with live postgres_fdw foreign table reading gendesign.v_tradein_cad_buildings. Fixes /trade-in/api/v1/geocode/reverse 500 (Nominatim ban) and address_not_geocoded for cadastre addresses (e.g. Хохрякова 81).
Security (deep-review fixes):
- 100_tradein_fdw_role.sql: passwordless CREATE ROLE; password set by deploy.yml ALTER ROLE bootstrap reading GENDESIGN_FDW_PASSWORD from backend/.env.runtime (via psql :'pw' var → format %L — injection-safe).
- core/fdw.py: regex whitelist [A-Za-z0-9_-]{32,256} on password, ValueError without echoing value, try/rollback on commit.
- 060_postgres_fdw_extension.sql: connect_timeout='3' on FOREIGN SERVER + ALTER ADD/SET fallback.
- geocoder.py: _cadastral_forward_sync / _cadastral_reverse_sync wrapped in asyncio.to_thread.
- 100_*.sql: REVOKE ALL ON ALL TABLES/SEQUENCES/FUNCTIONS IN SCHEMA public; only GRANT SELECT on v_tradein_cad_buildings.
- pg_user_mappings query handles PUBLIC mapping (usename IS NULL).
Tests: 3 SQL-injection guards on ensure_fdw_user_mapping + rewritten cadastral suite.
2026-05-24 08:57:30 +00:00
73bdff41a7
chore(claude-config): align with 2026 best practices ( #495 )
2026-05-24 08:48:42 +00:00
0efd2dca1d
feat(tradein): cadastral reverse geocode via main backend cad_buildings ( #492 )
Deploy Trade-In / changes (push) Successful in 5s
Deploy / changes (push) Successful in 5s
Deploy Trade-In / build-frontend (push) Successful in 25s
Deploy Trade-In / build-backend (push) Successful in 47s
Deploy / build-frontend (push) Successful in 29s
Deploy / build-backend (push) Successful in 1m25s
Deploy Trade-In / deploy (push) Successful in 37s
Deploy / build-worker (push) Successful in 2m29s
Deploy / deploy (push) Successful in 1m2s
2026-05-24 07:31:12 +00:00
7874a5c97b
feat(tradein): source-quota in estimator analogs (fix Cian/Yandex starvation) ( #491 )
Deploy Trade-In / build-backend (push) Successful in 51s
Deploy Trade-In / deploy (push) Failing after 10m2s
Deploy Trade-In / changes (push) Successful in 6s
Deploy Trade-In / build-frontend (push) Has been skipped
2026-05-23 20:59:58 +00:00
222389cba9
fix(tradein/avito): anti-bot hardening — sleep + abort + shared session ( #487 )
Deploy Trade-In / changes (push) Successful in 6s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 40s
Deploy Trade-In / deploy (push) Successful in 36s
2026-05-23 20:08:40 +00:00
726e774a7f
feat(tradein-ui): Yandex admin scraper page — mirror Avito + global delay control ( #488 )
...
Deploy Trade-In / deploy (push) Blocked by required conditions
Deploy Trade-In / changes (push) Successful in 5s
Deploy Trade-In / build-backend (push) Has been skipped
Deploy Trade-In / build-frontend (push) Has been cancelled
Replaces 5-line stub at /scrapers/yandex with full admin page mirroring Avito. 5 sections: global delay (umbrella yandex key), search around, detail snapshot, JK newbuilding, valuation. TanStack Query hooks + apiFetch, TS strict, reuses trade-in.css.
Fixup: useScraperSettings unwraps {settings:[...]} response wrapper; PUT body includes required source field (matches backend Pydantic ScraperSettingPayload). useEffect race guarded with initializedRef so 30s refetch doesn't clobber user input mid-edit.
Verdict: APPROVE — deep-code-reviewer (response shape unwrap + source field both applied).
2026-05-23 20:07:48 +00:00
52716a46c6
fix(tradein): geocode backfill + remove Avito exclusion from estimator ( #490 )
Deploy Trade-In / changes (push) Successful in 5s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 42s
Deploy Trade-In / deploy (push) Successful in 24s
2026-05-23 20:03:48 +00:00
ffb0c67c84
fix(tradein-ui): double /trade-in/ prefix in Cian page Link (PR #486 follow-up) ( #489 )
Deploy Trade-In / build-frontend (push) Successful in 1m23s
Deploy Trade-In / changes (push) Successful in 5s
Deploy Trade-In / build-backend (push) Has been skipped
Deploy Trade-In / deploy (push) Successful in 23s
2026-05-23 15:56:01 +00:00
e79c9cec88
feat(tradein): global scraper delay setting (applies across all scrapers) ( #485 )
...
Deploy Trade-In / changes (push) Successful in 5s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / deploy (push) Successful in 23s
Deploy Trade-In / build-backend (push) Successful in 50s
Add global request delay floor + per-source delay management.
- 054: seed 'global'=0 + per-source rows (avito=7, cian=5, n1=5, domrf=5, rosreestr=5)
using ON CONFLICT DO NOTHING; reuses existing 053 table from #484
- scraper_settings.py: get_scraper_delay() = max(per_source, global); _GLOBAL_KEY,
refactored _get_setting_cached(); preserved yandex umbrella alias logic
- admin.py: GET /scraper-settings + PUT /scraper-settings/{source} (ge=0.0, le=60.0);
cache invalidation on update; CAST(:d AS numeric) per psycopg v3
- avito/cian/n1 scrapers wired (yandex was wired by #484 )
- 18 unit tests pass (10 original updated for max() + 8 new global delay tests)
Closes follow-up gap from #486 (Cian admin slider min=0 now accepted by API).
2026-05-23 15:43:28 +00:00
ebfd29a0a6
feat(tradein-ui): Cian scraper admin page + global request delay control ( #486 )
Deploy Trade-In / changes (push) Successful in 4s
Deploy Trade-In / build-backend (push) Has been skipped
Deploy Trade-In / build-frontend (push) Successful in 1m21s
Deploy Trade-In / deploy (push) Successful in 24s
2026-05-23 15:36:07 +00:00