Commit graph

2795 commits

Author SHA1 Message Date
feff8214f7 fix(ci): докер-секции прод-деплоев исключают друг друга через host-lock (#2950) (#2955)
All checks were successful
Deploy / changes (push) Successful in 9s
Deploy Trade-In / changes (push) Successful in 10s
Deploy Trade-In / build-browser (push) Successful in 48s
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-backend (push) Successful in 47s
Deploy / build-frontend (push) Successful in 49s
Deploy / build-worker (push) Successful in 49s
Deploy / deploy (push) Successful in 1m26s
Deploy / deploy-status (push) Successful in 3s
Deploy / perimeter-smoke (push) Successful in 13s
Deploy Trade-In / build-frontend (push) Successful in 2m59s
Deploy Trade-In / test (push) Successful in 3m52s
Deploy Trade-In / build-backend (push) Successful in 37s
Deploy Trade-In / deploy (push) Successful in 2m22s
Deploy Trade-In / deploy-status (push) Successful in 1s
Deploy Trade-In / perimeter-smoke (push) Successful in 10s
2026-08-20 08:13:56 +00:00
3b40ba09f7 fix(tradein/geocoder): темп Nominatim сдерживается перед запросом, а не после успеха (#2953) (#2954)
All checks were successful
Deploy Trade-In / changes (push) Successful in 11s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 3m32s
Deploy Trade-In / build-backend (push) Successful in 1m20s
Deploy Trade-In / deploy (push) Successful in 1m36s
Deploy Trade-In / deploy-status (push) Successful in 1s
Deploy Trade-In / perimeter-smoke (push) Successful in 9s
2026-08-20 07:55:41 +00:00
2a01dea103 fix(ci): прод-деплои в одну группу concurrency — прун одного убивал pull другого (#2950) (#2952)
All checks were successful
Deploy / changes (push) Successful in 7s
Deploy Trade-In / changes (push) Successful in 10s
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-worker (push) Successful in 51s
Deploy / build-backend (push) Successful in 52s
Deploy / build-frontend (push) Successful in 51s
Deploy Trade-In / build-browser (push) Successful in 32s
Deploy / deploy (push) Successful in 1m21s
Deploy / deploy-status (push) Successful in 1s
Deploy / perimeter-smoke (push) Successful in 11s
Deploy Trade-In / build-frontend (push) Successful in 3m30s
Deploy Trade-In / test (push) Successful in 4m15s
Deploy Trade-In / build-backend (push) Successful in 31s
Deploy Trade-In / deploy (push) Successful in 2m6s
Deploy Trade-In / deploy-status (push) Successful in 2s
Deploy Trade-In / perimeter-smoke (push) Successful in 11s
2026-08-20 07:47:48 +00:00
c93d6cbde1 fix(ptica): шесть lookup'ов /analyze глотали ошибку БД без SAVEPOINT (#2464) (#2951)
All checks were successful
Deploy / changes (push) Successful in 8s
Deploy / build-frontend (push) Has been skipped
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-backend (push) Successful in 2m15s
Deploy / build-worker (push) Successful in 3m14s
Deploy / deploy (push) Successful in 1m28s
Deploy / deploy-status (push) Successful in 1s
Deploy / perimeter-smoke (push) Successful in 10s
2026-08-20 07:38:23 +00:00
38163a1186 fix(ptica): два блока analyze_parcel глотали ошибку БД без SAVEPOINT (#2464) (#2949)
All checks were successful
Deploy / changes (push) Successful in 7s
Deploy / build-frontend (push) Has been skipped
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-backend (push) Successful in 3m13s
Deploy / build-worker (push) Successful in 3m29s
Deploy / deploy (push) Successful in 1m25s
Deploy / deploy-status (push) Successful in 0s
Deploy / perimeter-smoke (push) Successful in 10s
2026-08-20 07:19:49 +00:00
8db357ef30 test(tradein): гейт «снять noindex можно только вместе с плейсхолдерами» (#2904) (#2948)
All checks were successful
Deploy Trade-In / changes (push) Successful in 14s
Deploy Trade-In / test (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / build-backend (push) Has been skipped
Deploy Trade-In / build-frontend (push) Successful in 3m18s
Deploy Trade-In / deploy (push) Successful in 1m6s
Deploy Trade-In / deploy-status (push) Successful in 1s
Deploy Trade-In / perimeter-smoke (push) Successful in 10s
2026-08-20 07:00:09 +00:00
6bca4f7ead fix(ptica): «0 мм осадков» перестаёт означать «данных нет» (#2464) (#2947)
Some checks failed
Deploy / changes (push) Successful in 13s
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-backend (push) Successful in 2m57s
Deploy / build-worker (push) Successful in 4m25s
Deploy / build-frontend (push) Successful in 4m31s
Deploy / deploy (push) Failing after 5s
Deploy / perimeter-smoke (push) Has been skipped
Deploy / deploy-status (push) Failing after 1s
2026-08-20 07:00:01 +00:00
9e4b190303 fix(ptica): resume_geo_job больше не возобновляет что попало (#2464) (#2946)
Some checks failed
Deploy / build-backend (push) Blocked by required conditions
Deploy / build-worker (push) Blocked by required conditions
Deploy / build-frontend (push) Blocked by required conditions
Deploy / deploy (push) Blocked by required conditions
Deploy / deploy-caddy (push) Blocked by required conditions
Deploy / perimeter-smoke (push) Blocked by required conditions
Deploy / deploy-status (push) Blocked by required conditions
Deploy / changes (push) Has been cancelled
2026-08-20 06:59:55 +00:00
251eacc4b6 fix(ptica): сноска концепт-PDF печатает фактический срок распродажи, а не «30 мес» (#2464) (#2945)
All checks were successful
Deploy / changes (push) Successful in 8s
Deploy / build-frontend (push) Has been skipped
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-backend (push) Successful in 2m13s
Deploy / build-worker (push) Successful in 4m8s
Deploy / deploy (push) Successful in 1m26s
Deploy / deploy-status (push) Successful in 1s
Deploy / perimeter-smoke (push) Successful in 9s
2026-08-19 17:39:37 +00:00
56868f2bde fix(ptica): нечисловое значение от OSRM/ORS больше не даёт 500 вместо деградации (#2464) (#2944)
All checks were successful
Deploy / changes (push) Successful in 9s
Deploy / build-frontend (push) Has been skipped
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-backend (push) Successful in 2m16s
Deploy / build-worker (push) Successful in 6m44s
Deploy / deploy (push) Successful in 1m31s
Deploy / deploy-status (push) Successful in 1s
Deploy / perimeter-smoke (push) Successful in 9s
2026-08-19 17:20:28 +00:00
43c71a006d docs(ptica): три комментария, утверждавших не то, что делает код (#2464 кластер H) (#2943)
All checks were successful
Deploy / changes (push) Successful in 7s
Deploy / build-frontend (push) Has been skipped
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-backend (push) Successful in 2m4s
Deploy / build-worker (push) Successful in 3m9s
Deploy / deploy (push) Successful in 1m27s
Deploy / deploy-status (push) Successful in 1s
Deploy / perimeter-smoke (push) Successful in 9s
2026-08-19 17:09:24 +00:00
8eeb35cee5 fix(ptica): дрейф формы ответа DaData не роняет весь гео-проход (#2464) (#2942)
All checks were successful
Deploy / changes (push) Successful in 9s
Deploy / build-frontend (push) Has been skipped
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-backend (push) Successful in 2m24s
Deploy / build-worker (push) Successful in 3m45s
Deploy / deploy (push) Successful in 1m23s
Deploy / deploy-status (push) Successful in 1s
Deploy / perimeter-smoke (push) Successful in 9s
2026-08-19 16:59:49 +00:00
e543fcdd81 fix(ptica): проба глубины очереди перестаёт висеть без таймаута (#2464) (#2941)
All checks were successful
Deploy / changes (push) Successful in 9s
Deploy / build-frontend (push) Has been skipped
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-backend (push) Successful in 2m8s
Deploy / build-worker (push) Successful in 3m16s
Deploy / deploy (push) Successful in 1m19s
Deploy / deploy-status (push) Successful in 1s
Deploy / perimeter-smoke (push) Successful in 9s
2026-08-19 16:54:04 +00:00
5a7d558a5c fix(ptica): пустой слой риск-зон перестаёт означать «рисков нет» (#2934) (#2940)
All checks were successful
Deploy / changes (push) Successful in 11s
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-backend (push) Successful in 3m10s
Deploy / build-frontend (push) Successful in 4m33s
Deploy / build-worker (push) Successful in 4m42s
Deploy / deploy (push) Successful in 1m50s
Deploy / deploy-status (push) Successful in 2s
Deploy / perimeter-smoke (push) Successful in 13s
2026-08-19 16:34:26 +00:00
f3626540fc test(ptica): снятие SAVEPOINT теперь роняет тест во всех местах кластера A (#2464) (#2938)
All checks were successful
Deploy / changes (push) Successful in 14s
Deploy / build-frontend (push) Has been skipped
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-backend (push) Successful in 1m2s
Deploy / build-worker (push) Successful in 1m3s
Deploy / deploy (push) Successful in 1m17s
Deploy / deploy-status (push) Successful in 1s
Deploy / perimeter-smoke (push) Successful in 9s
2026-08-19 16:06:59 +00:00
1afa34c5a6 fix(ptica): «Риск: Низкий» больше не выглядит вердиктом (#2934) (#2939)
All checks were successful
Deploy / changes (push) Successful in 7s
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-backend (push) Has been skipped
Deploy / build-worker (push) Has been skipped
Deploy / build-frontend (push) Successful in 3m28s
Deploy / deploy (push) Successful in 1m13s
Deploy / deploy-status (push) Successful in 1s
Deploy / perimeter-smoke (push) Successful in 8s
2026-08-19 15:53:21 +00:00
a2fbe4b400 fix(ptica): job_settings не отравляет чужую сессию при сбое БД (#2464 кластер A) (#2937)
All checks were successful
Deploy / changes (push) Successful in 8s
Deploy / build-frontend (push) Has been skipped
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-backend (push) Successful in 2m24s
Deploy / build-worker (push) Successful in 3m50s
Deploy / deploy (push) Successful in 1m30s
Deploy / deploy-status (push) Successful in 1s
Deploy / perimeter-smoke (push) Successful in 10s
2026-08-19 15:42:39 +00:00
52349a39f6 fix(ptica): строка о подтоплении в PDF и DOCX перестаёт читаться как заключение (#2934) (#2935)
All checks were successful
Deploy / changes (push) Successful in 9s
Deploy / build-frontend (push) Has been skipped
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-backend (push) Successful in 2m38s
Deploy / build-worker (push) Successful in 3m8s
Deploy / deploy (push) Successful in 1m50s
Deploy / deploy-status (push) Successful in 1s
Deploy / perimeter-smoke (push) Successful in 9s
2026-08-19 15:11:10 +00:00
37bf3d0e93 fix(ptica): достоверность видит зону ПЗЗ из НСПД, а не только из пустой таблицы (#2464) (#2933)
All checks were successful
Deploy / changes (push) Successful in 9s
Deploy / build-frontend (push) Has been skipped
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-backend (push) Successful in 1m56s
Deploy / build-worker (push) Successful in 3m10s
Deploy / deploy (push) Successful in 1m54s
Deploy / deploy-status (push) Successful in 1s
Deploy / perimeter-smoke (push) Successful in 9s
2026-08-19 13:29:25 +00:00
a9e9707018 fix(tradein): обход Домклика начинается со сдвигом — комнатности 2+ перестают быть слепой зоной (#2854) (#2932)
All checks were successful
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 3m45s
Deploy Trade-In / deploy (push) Successful in 1m57s
Deploy Trade-In / deploy-status (push) Successful in 1s
Deploy Trade-In / perimeter-smoke (push) Successful in 9s
Deploy Trade-In / changes (push) Successful in 10s
Deploy Trade-In / build-backend (push) Successful in 1m49s
2026-08-19 12:48:41 +00:00
d7c00f9ab3 fix(ptica): шумовой скорер перестаёт считать водоёмы источниками шума (#2464-G) (#2931)
All checks were successful
Deploy / changes (push) Successful in 8s
Deploy / build-frontend (push) Has been skipped
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-backend (push) Successful in 2m10s
Deploy / build-worker (push) Successful in 3m7s
Deploy / deploy (push) Successful in 1m27s
Deploy / deploy-status (push) Successful in 1s
Deploy / perimeter-smoke (push) Successful in 10s
2026-08-19 12:41:59 +00:00
3c9505c8b0 test(ptica): покрыть переиспользование сессии после close() в отдаче фотографий (#2464-C) (#2930)
All checks were successful
Deploy / changes (push) Successful in 7s
Deploy / build-frontend (push) Has been skipped
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-backend (push) Successful in 2m4s
Deploy / build-worker (push) Successful in 3m19s
Deploy / deploy (push) Successful in 1m40s
Deploy / deploy-status (push) Successful in 1s
Deploy / perimeter-smoke (push) Successful in 8s
2026-08-19 11:52:13 +00:00
bc489e1a6f fix(ptica): гео-проход не тратит геокод на занятых кандидатов и не «подтверждает» их (#2464) (#2929)
Some checks failed
Deploy / build-backend (push) Blocked by required conditions
Deploy / build-worker (push) Blocked by required conditions
Deploy / build-frontend (push) Blocked by required conditions
Deploy / deploy (push) Blocked by required conditions
Deploy / deploy-caddy (push) Blocked by required conditions
Deploy / perimeter-smoke (push) Blocked by required conditions
Deploy / deploy-status (push) Blocked by required conditions
Deploy / changes (push) Has been cancelled
2026-08-19 11:52:07 +00:00
c3ea0364e7 fix(ptica): соединение БД отпускается до похода за фотографией наружу (#2464-C) (#2928)
All checks were successful
Deploy / changes (push) Successful in 8s
Deploy / build-frontend (push) Has been skipped
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-backend (push) Successful in 2m6s
Deploy / build-worker (push) Successful in 3m34s
Deploy / deploy (push) Successful in 1m21s
Deploy / deploy-status (push) Successful in 1s
Deploy / perimeter-smoke (push) Successful in 9s
2026-08-19 11:18:00 +00:00
e266f29d65 fix(ptica): защита таймаутом теперь реально ограничивает время (#2464-C) (#2927)
All checks were successful
Deploy / changes (push) Successful in 8s
Deploy / build-frontend (push) Has been skipped
Deploy / build-worker (push) Successful in 4m39s
Deploy / deploy-status (push) Successful in 1s
Deploy / perimeter-smoke (push) Successful in 9s
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-backend (push) Successful in 2m9s
Deploy / deploy (push) Successful in 1m51s
2026-08-19 10:27:58 +00:00
cf48e6d6c8 feat(tradein): позиция квартиры внутри когорты аналогов — перцентиль (#2899) (#2926)
All checks were successful
Deploy Trade-In / changes (push) Successful in 15s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 3m54s
Deploy Trade-In / build-backend (push) Successful in 1m7s
Deploy Trade-In / deploy (push) Successful in 2m6s
Deploy Trade-In / deploy-status (push) Successful in 1s
Deploy Trade-In / perimeter-smoke (push) Successful in 10s
2026-08-19 10:08:18 +00:00
d25ff668f7 ci: правка конфига прокси больше не тянет полный деплой Site Finder (#2916) (#2925)
All checks were successful
Deploy / changes (push) Successful in 8s
Deploy / perimeter-smoke (push) Successful in 9s
Deploy / deploy-caddy (push) Has been skipped
Deploy / build-worker (push) Successful in 45s
Deploy / build-frontend (push) Successful in 44s
Deploy / build-backend (push) Successful in 45s
Deploy / deploy (push) Successful in 1m8s
Deploy / deploy-status (push) Successful in 1s
2026-08-19 08:39:01 +00:00
d0071c57bc fix(tradein): фильтр выдачи Яндекса мёртв — slug ЖК ищем по странице объекта (#2860) (#2923)
All checks were successful
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / deploy-status (push) Successful in 1s
Deploy Trade-In / perimeter-smoke (push) Successful in 9s
Deploy Trade-In / changes (push) Successful in 11s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / test (push) Successful in 3m50s
Deploy Trade-In / build-backend (push) Successful in 1m41s
Deploy Trade-In / deploy (push) Successful in 1m42s
2026-08-19 08:37:40 +00:00
e86f0782da ci: смоук периметра МЕРЫ запускается сразу после деплоя (#2917) (#2922)
All checks were successful
Deploy / changes (push) Successful in 10s
perimeter-smoke-mera / smoke (push) Successful in 12s
Deploy Trade-In / changes (push) Successful in 14s
Deploy / build-frontend (push) Successful in 51s
Deploy / build-backend (push) Successful in 53s
Deploy / build-worker (push) Successful in 53s
Deploy Trade-In / build-browser (push) Successful in 40s
Deploy / deploy (push) Successful in 1m33s
Deploy / deploy-status (push) Successful in 2s
Deploy / perimeter-smoke (push) Successful in 10s
Deploy Trade-In / build-frontend (push) Successful in 2m50s
Deploy Trade-In / test (push) Successful in 4m8s
Deploy Trade-In / build-backend (push) Successful in 35s
Deploy Trade-In / deploy (push) Successful in 1m39s
Deploy Trade-In / deploy-status (push) Successful in 1s
Deploy Trade-In / perimeter-smoke (push) Successful in 10s
2026-08-19 08:13:49 +00:00
b1106916a9 Merge pull request 'fix(infra/caddy): site-блоки с секретами переживают деплой — import caddy/local/*.caddy' (#2921) from fix/caddy-garmin-import into main
All checks were successful
Deploy / changes (push) Successful in 9s
Deploy / build-backend (push) Successful in 45s
Deploy / build-worker (push) Successful in 46s
Deploy / build-frontend (push) Successful in 46s
Deploy / deploy (push) Successful in 1m25s
Deploy / deploy-status (push) Successful in 1s
2026-08-18 06:45:09 +00:00
bot-backend
f30820bb9a fix(infra/caddy): site-блоки с секретами переживают деплой — import caddy/local/*.caddy
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 11s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Successful in 59s
Деплой делает `git reset --hard origin/main`, поэтому любой site-блок,
вписанный руками в /opt/gendesign/Caddyfile, живёт до первого пуша в main.
16.08 так и вышло с garmin.gendsgn.ru: контейнер остался healthy, а хост
исчез из конфига — TLS-хендшейк стал падать `alert internal error`,
потому что сертификат для него Caddy больше не держит.

Класть такой блок в git нельзя: у него единственный рубеж аутентификации —
секрет в пути URL (апстрим-MCP аутентификации не имеет, а claude.ai
connector кастомные заголовки не шлёт).

Развязка: в репозитории только `import caddy/local/*.caddy` и сам каталог
(держится .gitignore'ом), файлы с секретами лежат на VPS untracked —
reset --hard их не трогает. Пустой glob для Caddy не ошибка,
`caddy validate` проходит, на машинах без локальных блоков import — no-op.

Проверено `caddy validate` 2.11.4 на VPS: и с пустым каталогом, и с
реальным блоком garmin — Valid configuration.
2026-08-18 09:42:53 +03:00
215b78a348 Merge pull request 'fix(tradein/estimate): залипший anchor_tier больше не глушит четыре механизма разом' (#2920) from fix/2656-anchor-tier-reset into main
All checks were successful
Deploy Trade-In / changes (push) Successful in 12s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 3m45s
Deploy Trade-In / build-backend (push) Successful in 1m10s
Deploy Trade-In / deploy (push) Successful in 1m57s
Deploy Trade-In / deploy-status (push) Successful in 1s
2026-08-17 08:00:33 +00:00
bot-backend
42b0ebe338 fix(tradein/estimate): залипший anchor_tier молча глушил IMV-blend и quarter-index
All checks were successful
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / changes (pull_request) Successful in 9s
CI / changes (pull_request) Successful in 9s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 4m32s
Флаг anchor_tier оставался равным anchor_tier_fetched ("A"/"C"), когда якорь
фактически НЕ строился — сброс делал только low-conf гейт (#audit-1), но не
Tier C corridor-гейт (#1795) и не сама _compute_same_building_anchor, когда
она отклоняет кандидата (комплов меньше estimate_sb_min_comps). Дальше по коду
залипший флаг читается как «headline построил якорь» и молча глушит IMV/Yandex
blend (#651, гейт `anchor_tier is None`) и quarter-index correction (#764
Guard-1a) — притом что радиусный headline их не получал.

Замер: 154 из 996 сделок теряют tier-флаг этой правкой, и у всех 154 изменение
цены ровно 0.000% — чинится именно залипший ФЛАГ, не ценообразование (баланс
метрик бэктеста подтверждает: единственная дельта в baseline — новая канарейка
unrecorded_lookup_calls, все остальные метрики побитово те же).

- estimator.py: сброс `anchor_tier = None` единой веткой `if anchor is None`
  после всех трёх гейтов (Tier C / low-conf / _compute_same_building_anchor);
  display-only IMV-карточка больше не гейтится по `anchor_tier is not None`
  (иначе терялась в щели «тир добыт, якорь не построен, headline подавлен»).
- backtest_estimator.py: quarter_index_lookup/quarter_indexes_lookup в реплее
  отвечают «промах» (None/{}), если сброс флага открыл путь, которого не было
  в замороженной фикстуре, вместо падения с RuntimeError; счётчик таких промахов
  уходит в baseline как unrecorded_lookup_calls (точное целое, канарейка на
  расхождение реплея с захватом). Заодно пиннится estimate_dedup_analogs_enabled
  = False внутри replay_fixture (было только в самом гейте) — иначе штатная
  регенерация baseline (--from-fixture --update-baseline) писала baseline,
  который тест не совпадал бы никогда.
- backtest_baseline.json: перегенерирован штатным путём, unrecorded_lookup_calls=0.

Выделено из #2656/PR #2661 — фильтры свежести (scraped_at) в якоре дома и в
знаменателе коэффициента выкупа остаются в исходном PR как отдельная, более
спорная правка (двигает деньги: знаменатель просаживается на ~1.3% по бакетам).
2026-08-17 10:54:07 +03:00
db4fb0a975 Merge pull request 'fix(tradein/estimate): нет индекса у аналогов — нет квартальной поправки (#2583 C3)' (#2836) from fix/2583-c3-quarter-index-fallback into main
All checks were successful
Deploy Trade-In / changes (push) Successful in 13s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 3m49s
Deploy Trade-In / build-backend (push) Successful in 1m51s
Deploy Trade-In / deploy (push) Successful in 1m42s
Deploy Trade-In / deploy-status (push) Successful in 1s
2026-08-17 07:47:27 +00:00
bot-backend
c66047683c Merge remote-tracking branch 'forgejo/main' into local/pr2836
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 9s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 4m36s
2026-08-17 10:41:25 +03:00
b474a5f44e Merge pull request 'fix(mera/b2c): житель Серова получал «вы вне области», а подсказки игнорировали выбранный город' (#2919) from fix/mera-city-parity into main
All checks were successful
Deploy Trade-In / changes (push) Successful in 14s
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / build-frontend (push) Successful in 2m34s
Deploy Trade-In / test (push) Successful in 3m56s
Deploy Trade-In / build-backend (push) Successful in 1m7s
Deploy Trade-In / deploy (push) Successful in 1m50s
Deploy Trade-In / deploy-status (push) Successful in 1s
2026-08-16 10:09:13 +00:00
bot-backend
73c4c487ed fix(mera/b2c): житель Серова получал «вы вне области», а подсказки игнорировали выбранный город
All checks were successful
CI / changes (pull_request) Successful in 10s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Successful in 1m6s
CI Trade-In / backend-tests (pull_request) Successful in 4m50s
CI Trade-In / changes (pull_request) Successful in 9s
CI Trade-In / browser-tests (pull_request) Successful in 48s
Два дефекта, найденных прогоном сценария глазами посетителя на живом домене.

## 1. Город предлагали выбрать, но отвечать по нему не умели

Дропдаун на сайте (`OBLAST_CITIES`, city-registry.ts) и списки покрытия
(`COVERAGE_GREEN/YELLOW_CITIES`, trade_in.py) — одно множество, записанное в
двух местах. Они разошлись в обе стороны:

  предлагали, но не отвечали:  Серов
  отвечали, но не предлагали:  Берёзовский, Среднеуральск, Ревда

Житель Серова выбирал СВОЙ город из НАШЕГО дропдауна и получал:

  «Этот адрес вне области, по которой мы собираем данные.
   Сейчас это Свердловская область: Екатеринбург целиком и ещё несколько
   городов вокруг.»

Про город в той же самой области. Серов при этом покрыт данными: 363 активных
объявления в радиусе 15 км, все свежие (замер по проде). Поэтому добавлен в
жёлтый тир, а не убран из дропдаунa; три недостающих города добавлены на фронт.

Шапка city-registry.ts этот риск прямо предсказывала — «перед добавлением
7-го города сверить оба списка вручную, теста на это пока нет». Теперь тест
есть: бэкендовый сьют читает TS-реестр и требует РАВЕНСТВА множеств. Плюс
проверка, что у каждого города с порогом есть центроид, — иначе порог мёртвый,
город по координатам не резолвится.

## 2. Подсказки не слушались выбранного города

`city_hint` доезжает до геокодера, но на выдачу не влияет: его смотрит только
екатеринбургский кадастровый тир (как признак «речь не про ЕКБ, тир
пропускаем»), а DaData-тир ограничен регионом целиком и хинта не принимает.

Замер: выбран Серов, введено «Ленина 1» → первой подсказкой «Невьянский р-н,
пгт Верх-Нейвинский». Человек выбирает верхний вариант и считает чужой дом —
ровно баг #2576, ради которого город и спрашивают.

Публичная ручка теперь подставляет город в саму строку запроса. Проверено на
проде: «Серов Ленина 1» даёт серовскую выдачу целиком. Для Екатеринбурга
подстановка безвредна — три разных адреса дали тот же результат с префиксом и
без, поэтому правило одно на все города, без исключения для основного трафика.

Чинится в публичной ручке, а не в геокодере: там от `city_hint` зависит
поведение закрытого контура (`target_city_ambiguous`).

## Фикстура теста

`_FAR_AWAY_CITY` стояла в 21 км от центра Серова и работала как «далеко от
всех» лишь потому, что Серов не был поддержан. Переехала в Тавду — 271 км до
ближайшего центроида.

## Мутации

  убрать Серов из покрытия (состояние прода) → падает сверка списков
  не подставлять город в строку             → падает проверка ручки
  откат                                     → 21 passed

Плюс backend 75 passed, vitest 56 passed, tsc, lint, build, isolation guard.

`city-registry.ts` добавлен в paths-фильтр БЭКЕНДОВОГО лэйна: сверку списков
делает бэкендовый тест, и без этой строки правка одного лишь дропдауна её бы
не запускала — то есть ровно тот путь, которым списки и разошлись.
2026-08-16 13:03:19 +03:00
d38e83df82 Merge pull request 'fix(mera/b2c): /estimate снова закрывался гвардом — короткий адрес завели в Caddy, но не в RouteGuard' (#2918) from fix/mera-estimate-guard-bypass into main
All checks were successful
Deploy Trade-In / changes (push) Successful in 12s
Deploy Trade-In / test (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / build-backend (push) Has been skipped
Deploy Trade-In / build-frontend (push) Successful in 2m47s
Deploy Trade-In / deploy (push) Successful in 1m2s
Deploy Trade-In / deploy-status (push) Successful in 1s
2026-08-16 07:40:54 +00:00
bot-backend
e74e9106b3 fix(mera/b2c): /estimate снова закрывался гвардом — короткий адрес завели в Caddy, но не в RouteGuard
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI / changes (pull_request) Successful in 9s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Successful in 55s
Замер на проде сразу после выкатки #2913: страница `/estimate` отдаёт 200 и
выглядит правильно, но после гидратации монтируется `GuardedRoute` —

  404 /trade-in/api/v1/me                             ×3
  404 /trade-in/api/v1/trade-in/support/anon/unread

плюс виджет чата поддержки из закрытого контура и экран «Не удалось проверить
доступ» внизу страницы. Форма при этом переставала работать ВОВСЕ: разметка с
сервера видна, поле принимает текст, а обработчики не подключены — человек
печатает адрес и не получает ни подсказок, ни ошибки. Проверено, что дело не в
API: ручной `fetch` из той же страницы отдаёт 200 и восемь подсказок.

Причина ровно та же, что чинил PR #2910 для `/`: список публичных путей в
гварде и матчер `@meraPages` в Caddyfile — одно множество, записанное в двух
местах. Тогда разошлись на `/`, теперь на `/estimate`. Оба раза страница
отдавала 200, ломалась только в браузере, и ни один тест этого не видел.

Комментарий в шапке гварда инцидент не предотвратил (он там был), поэтому
совпадение теперь запинено ТЕСТОМ: он читает Caddyfile и требует, чтобы каждый
путь из `@meraPages` проходил `isPublicPath`. Сверяемся с источником, а не
дублируем список третий раз.

Мутация — вернуть список к состоянию, которое уехало на прод:
  2 failed / 3 passed
  × пропускает короткие адреса публичного домена
  × совпадает с тем, что публичный домен реально раздаёт (Caddyfile)
откат → 5 passed.

Плюс vitest 56 passed, tsc, lint, isolation guard 41 файл.

`Caddyfile` уже в paths-фильтре фронтового лэйна (#2913), так что правка одного
лишь конфига теперь тоже гоняет этот гейт.
2026-08-16 10:39:15 +03:00
51a2d7db84 Merge pull request 'feat(mera/b2c): публичный периметр МЕРЫ — свой API, отдельный экран оценки, короткие адреса' (#2913) from feat/mera-public-api into main
All checks were successful
Deploy / changes (push) Successful in 8s
Deploy Trade-In / changes (push) Successful in 13s
Deploy Trade-In / build-browser (push) Has been skipped
Deploy / build-frontend (push) Successful in 50s
Deploy / build-backend (push) Successful in 53s
Deploy / build-worker (push) Successful in 53s
Deploy / deploy (push) Successful in 1m29s
Deploy / deploy-status (push) Successful in 2s
Deploy Trade-In / build-frontend (push) Successful in 2m40s
Deploy Trade-In / test (push) Successful in 4m0s
Deploy Trade-In / build-backend (push) Successful in 1m6s
Deploy Trade-In / deploy (push) Successful in 1m55s
Deploy Trade-In / deploy-status (push) Successful in 1s
2026-08-16 07:25:23 +00:00
bot-backend
eb7ac3d326 fix(ci): гейт Caddyfile не мог прочитать конфиг — -v $PWD из job-контейнера
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 10s
CI Trade-In / browser-tests (pull_request) Successful in 52s
CI Trade-In / frontend-checks (pull_request) Successful in 1m32s
CI / frontend-tests (pull_request) Successful in 1m36s
CI / openapi-codegen-check (pull_request) Successful in 1m59s
CI Trade-In / backend-tests (pull_request) Successful in 5m10s
CI / backend-tests (pull_request) Successful in 16m46s
Первая версия шага смонтировала `$PWD` внутрь caddy-контейнера и упала на
`open /etc/caddy/Caddyfile: no such file or directory`.

Причина: job сам исполняется внутри контейнера, а `docker run` создаёт
КОНТЕЙНЕР-БРАТ на том же демоне. Путь в `-v` резолвится на ХОСТЕ, тогда как
`$PWD` — путь внутри job-контейнера, которого на хосте нет. Классическая
ловушка docker-in-docker, и она не зависит от содержимого конфига — смонтируй
так что угодно, монтирования просто не произойдёт.

Заменено на `docker create -w /work` + `docker cp` + `docker start -a`: копия
не зависит от того, как смонтирован workspace. Копируется и каталог `caddy/` —
Caddyfile делает `import caddy/users.caddy.snippet`, без него validate падает
на импорте.

Проверено локально обе стороны: валидный конфиг → `Valid configuration`,
exit 0; конфиг с незакрытой скобкой → `unexpected EOF`, exit 1. Без второй
проверки гейт мог бы оказаться вечно-зелёным.
2026-08-16 10:07:39 +03:00
bot-backend
56194c606a fix(mera/b2c): семь дефектов публичного периметра, найденных состязательным ревью
Some checks failed
CI Trade-In / changes (pull_request) Successful in 9s
CI / changes (pull_request) Failing after 8s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Successful in 46s
CI Trade-In / frontend-checks (pull_request) Successful in 1m3s
CI Trade-In / backend-tests (pull_request) Successful in 4m42s
Ревью четырьмя независимыми линзами (периметр, семантика Caddy, политика ПДн
против кода, фронт) + по два проверяющих на каждую находку. Ниже — то, что
пережило проверку и воспроизведено на живом коде, а не выведено из чтения.

## Caddy: открытый редирект и потерянные ссылки

Захват хвоста регекспом (`^/trade-in/mera-public/(.+)$` → `redir /{re…1}`) —
открытый редирект. Захват берётся из РАСКОДИРОВАННОГО пути, поэтому
`/trade-in/mera-public/%5Cevil.example/pay` даёт цель `/\evil.example/pay`, а
браузеры трактуют `/\` как `//` — Location уводит на чужой хост. Готовая
фишинговая заготовка с домена, который напечатан внутри оферты и уходит
модератору эквайера. Заменено поимённым списком путей: такой адрес просто не
матчится.

Адреса со слэшем на конце (`/oferta/`, и длинные `…/oferta/`) отдавали 404 —
ровно те ссылки, ради сохранности которых редирект и делался. Добавлена
нормализация, цепочка замкнута (проверено: 2 перехода → 200).

Query-строка терялась: размещённые ссылки с UTM приходили бы в аналитику как
прямой заход. `uri strip_prefix` + `{uri}` переносит её. Обёртка `route`
обязательна — без неё `redir` выполняется раньше `uri` и Location равен
исходному адресу (бесконечный цикл, поймано на стенде).

`/v3` — черновое превью с маркетинговыми плейсхолдерами — было открыто на
боевом домене молча. Теперь названо вслух и запинено тестом.

## Гейты, которых не было

`caddy validate` не звал НИ ОДИН workflow, а deploy применяет конфиг не через
`reload` (тот отказался бы принять битый), а через `up -d --force-recreate` —
опечатка уводит контейнер в crash-loop и роняет ВСЕ домены. Добавлен гейт в
ci.yml, тем же образом caddy:2, что и на проде.

Проверка «роут ↔ Caddy» была односторонней и пропускала обратную ошибку —
путь, открытый наружу, о котором приложение не знает. Так и уехал `/v3`.
Теперь двусторонняя, плюс проверка, что для каждой страницы есть 301.

## Бюджет внешнего геокодера

Per-IP окна ограничивают одного клиента, но не сумму: 40/мин с адреса — это
57 600 в сутки при бесплатном тире DaData в 10 000, ОБЩЕМ с закрытым контуром.
Подтверждено на проде: достаточно упомянуть не-екатеринбургский город, чтобы
локальный тир отключился и запрос гарантированно ушёл во внешний сервис. То
есть один скрипт оставлял без подсказок платящих пилотов.

Per-IP снижен до 20/мин, добавлен общий суточный потолок 2000 и потолок
одновременных подсказок (4): кадастровый тир уходит в FDW-скан чужой базы,
держит соединение около секунды, а пул общий с B2B — полтора десятка
параллельных публичных запросов клали бы закрытый контур.

## «Адрес нигде не сохраняется» — теперь правда целиком

Две утечки, обе воспроизведены:

1. ЖУРНАЛЫ. Геокодер печатает введённую строку открытым текстом на каждый
   вызов, прод пишет stdout в persistent journald — адрес ложился на диск
   рядом с IP того же запроса в access-логе Caddy. Закрыто фильтром логов на
   время публичного запроса (contextvar, переживает await и to_thread).
   Закрытый контур логи сохраняет: они нужны для разбора жалоб пилотов.
2. МОНИТОРИНГ. sentry_sdk кладёт в событие ПОЛНОЕ тело запроса — а тело
   публичной ручки это ровно `{"q": "<адрес>"}`; `send_default_pii=False` тут
   не гейт, он про куки. Плюс брэдкрамб httpx несёт адрес в query геокодера.
   Закрыто `scrub_public_address`.

Текст п. 5.4 политики расширен до «ни в журналы веб-сервера, ни в технические
журналы, ни в мониторинг» — ровно то, что теперь обеспечено кодом.

## Фронт

- Отмена запроса подсказок откладывалась внутрь следующего debounce-такта и
  не наступала вовсе, если человек переставал печатать: ответ по старой строке
  долетал и ложился в список. Контроллер создаётся сразу, отменяется в cleanup.
- Список схлопывался на каждое нажатие — клик по намеченному пункту
  промахивался. Старая выдача висит, пока не пришла новая.
- «Комнат» с лэндинга — свободный текст: «студия» не совпадала ни с одним
  option, селект показывал пустоту, parseInt давал NaN, на сервер уходил
  rooms: null → 422 с текстом «сломалось на нашей стороне». Нормализация
  вынесена чистой функцией и покрыта тестами.
- У пробы покрытия не было ни таймаута, ни отмены: оборванное соединение
  оставляло кнопку в «Смотрим данные…» навсегда. 15 с + понятный текст.
- Ошибка подсказок глушилась в пустой список — тупик без объяснения.
- Комбобокс: Tab проваливался в кнопки подсказок, список не закрывался по
  уходу фокуса и перекрывал поля, Escape оставлял висячий aria-activedescendant.

## Проверено

Локальный стенд (реальный site-блок Caddy + заглушка): 18 маршрутов, включая
`%5C`, `//`, `%2F` — все три теперь 404. vitest 55 passed, backend 17 passed по
публичному API, tsc, lint, build, isolation guard 41 файл, caddy validate.

Мутации: снять редакцию логов → падает тест журналов; не вырезать тело запроса
→ падает тест мониторинга; убрать /estimate из Caddy → падает тест маршрутов.
2026-08-16 10:01:47 +03:00
bot-backend
208173d816 fix(mera/b2c): длинные адреса реально редиректят — redir без матчера не срабатывал
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 9s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Successful in 44s
CI Trade-In / frontend-checks (pull_request) Successful in 59s
CI Trade-In / backend-tests (pull_request) Successful in 4m38s
Проверка на живом Caddy (локальный стенд: реальный site-блок + заглушка вместо
фронта) показала, что 301 не работал вовсе: длинные адреса отдавали пустой
200. Причина — разбор Caddyfile: первый аргумент директивы, начинающийся со
слэша, читается как inline path-matcher. То есть `redir / permanent` означает
«для пути / редиректить на permanent», а не «редиректить на /»; матчер не
совпадал, директива молча не срабатывала, наружу уходило пустое тело.

Пустая страница с кодом 200 хуже 404: выглядит рабочей и не ловится ни
смоуком по коду ответа, ни глазом.

Замер после правки (`redir * <куда>`):

  /trade-in/mera-public                 301 → /
  /trade-in/mera-public/                301 → /
  /trade-in/mera-public/oferta          301 → /oferta
  /trade-in/mera-public/v3              301 → /v3
  /                                     200   upstream /trade-in/mera-public
  /estimate                             200   upstream /trade-in/mera-public/estimate
  /trade-in/api/public/mera/coverage    200   upstream /api/public/mera/coverage
  /trade-in/api/v1/me                   404
  /trade-in/v2                          404

Заодно захват сужен до `([^/].*)` — страховка от протокол-относительной цели
(`//evil.example` резолвится браузером как чужой хост). Тем же замером
проверено, что сегодня это недостижимо и без ограничения: Caddy нормализует
путь до матчинга, и `//evil.example` / `/%2Fevil.example` приезжают одним
слэшем. Ограничение оставлено как второй барьер, комментарий говорит ровно
это — а не то, что чинилась живая дыра.
2026-08-16 09:46:46 +03:00
bot-backend
b1fb7bb055 Merge remote-tracking branch 'forgejo/main' into feat/mera-public-api
All checks were successful
CI Trade-In / changes (pull_request) Successful in 7s
CI / changes (pull_request) Successful in 8s
CI Trade-In / browser-tests (pull_request) Successful in 46s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Successful in 1m7s
CI Trade-In / backend-tests (pull_request) Successful in 4m45s
# Conflicts:
#	tradein-mvp/backend/app/core/rbac.py
2026-08-16 09:28:41 +03:00
bot-backend
7424c283d5 feat(mera/b2c): отдельный экран оценки на meraocenka.ru и короткие адреса
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI / changes (pull_request) Successful in 8s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Successful in 44s
CI Trade-In / frontend-checks (pull_request) Successful in 1m2s
CI Trade-In / backend-tests (pull_request) Successful in 4m41s
## Экран проверки — /estimate

Проверка квартиры вынесена на собственный адрес: там у автокомплита есть
место под список подсказок, а у результата — место рядом с полями. Форма в
герое лэндинга осталась входной точкой и уводит сюда, донося набранное через
sessionStorage (НЕ через query — адрес в URL попал бы в access-лог Caddy рядом
с IP посетителя, а мы на той же странице обещаем ничего не хранить).

Показывает живую пробу покрытия: сколько похожих квартир продаётся рядом и
сколько в среднем висят их объявления. Ни одной рублёвой цифры — цену продаёт
платный шаг. Тексты вердикта вынесены чистой функцией (coverage-copy.ts) и
покрыты тестами: подпись под возрастом обязана говорить «объявление», а не
«продаётся» (выборка цензурирована), при неизвестном возрасте плитки нет
вообще, а пустая когорта объясняется как факт о рынке с подсказкой, что
поменять, — директива «никогда не блокировать вывод».

## Короткие адреса

Человек больше не видит /trade-in/mera-public/... — только /, /estimate,
/oferta, /refund, /privacy. Длинные адреса отдают 301 на короткие: у страницы
один канонический адрес, старые ссылки живы.

Цена решения: ссылки работают только на meraocenka.ru (короткие пути раздаёт
этот хост). Открывать лэндинг для проверки нужно там же, а не с gendsgn.ru.

Ссылки эмитятся обычным <a> (PublicLink) — next/link подставляет basePath, и
href="/estimate" уехал бы на несуществующий /trade-in/estimate.

## Три дефекта, найденных на живом сайте

1. Палитра v3 никуда не доезжала. b2c-tokens.ts не импортировал НИКТО, ни одна
   --b2c-* переменная не объявлялась, каскад молча пропускал такие декларации —
   лэндинг отдавал 200 бесцветным. Добавлен мост b2cVars, гейтом стал тест:
   каждая использованная в CSS переменная обязана быть объявлена.
2. Голый /trade-in/mera-public падал в 404 — матчер был со слэшем и звёздочкой.
   Ровно туда вела «Главная» в подвале.
3. «Для бизнеса» вела на «/» — то есть на сам лэндинг. Теперь абсолютный адрес
   B2B-контура. Пункты «Проверьте себя» и «Продажа под ключ» вели на якоря,
   которых нет нигде: приведены к виду «Статьи» — видны, но не кликабельны.

## Периметр и приватность

Подсказки переведены на POST: access-лог публичного домена пишет URI целиком,
то есть GET с ?q= сохранял бы адрес квартиры в файл. Тело в лог не попадает.
Метод запинен тестом — это часть обещания, а не стиль.

П. 5.4 политики ПДн переписан ВМЕСТЕ с кодом: прежний текст утверждал, что
адрес не покидает браузер, и это перестало быть правдой. Новый говорит точно —
передаётся, используется однократно, в базах не сохраняется. Последнее
проверено по коду: suggest() работает без кэша, проба — один SELECT, аудит
пишет строку только при наличии username. PUBLIC_ESTIMATE_ENABLED сузился до
платного шага (бесплатная проба не хранит ничего, платный расчёт хранит).

## Проверено

vitest 47 passed (9 файлов), tsc, next lint, next build, isolation guard
40 файлов, backend 75 passed, caddy validate = Valid configuration.

Мутации структурных гейтов:
  убрать --b2c-accent-text из b2cVars   → падает тест палитры
  убрать /estimate из @meraPages        → падает тест маршрутов
  добавить импорт next/link             → падает тест basePath
  откат                                 → 14 passed

Caddyfile добавлен в paths-filter фронтового лэйна: его читает тест маршрутов,
и без этой строки правка одного лишь Caddyfile не запускала бы ни один гейт.

Refs #2894, #2895
2026-08-16 09:27:04 +03:00
a617ec7939 Merge pull request 'fix(tradein): гейт номеров миграций берёт эталон из git, ручной манифест удалён' (#2786) from fix/2683-manifest-drift into main
All checks were successful
Deploy / changes (push) Successful in 8s
Deploy / build-frontend (push) Has been skipped
Deploy Trade-In / changes (push) Successful in 12s
Deploy Trade-In / build-browser (push) Successful in 46s
Deploy / build-worker (push) Successful in 53s
Deploy / build-backend (push) Successful in 54s
Deploy / deploy (push) Successful in 1m14s
Deploy / deploy-status (push) Successful in 1s
Deploy Trade-In / build-frontend (push) Successful in 2m41s
Deploy Trade-In / test (push) Successful in 4m0s
Deploy Trade-In / build-backend (push) Successful in 32s
Deploy Trade-In / deploy (push) Successful in 1m31s
Deploy Trade-In / deploy-status (push) Successful in 1s
2026-08-15 20:04:16 +00:00
22a1b3aff4 Merge pull request 'feat(tradein/ops): алерты GlitchTip доезжают в Telegram' (#2915) from feat/tradein-glitchtip-telegram-alerts into main
All checks were successful
Deploy / changes (push) Successful in 8s
Deploy Trade-In / changes (push) Successful in 12s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy / build-worker (push) Successful in 43s
Deploy / build-frontend (push) Successful in 42s
Deploy / build-backend (push) Successful in 44s
Deploy / deploy (push) Successful in 1m11s
Deploy / deploy-status (push) Successful in 1s
Deploy Trade-In / test (push) Successful in 3m48s
Deploy Trade-In / build-backend (push) Successful in 1m26s
Deploy Trade-In / deploy (push) Successful in 1m38s
Deploy Trade-In / deploy-status (push) Successful in 1s
2026-08-15 19:56:40 +00:00
58f04087bb Merge pull request 'fix(tradein/payments): тело нотификации не течёт в мониторинг и аудит, повторы банка не отбиваются лимитом' (#2794) from feat/tradein-payments-perimeter-hardening into main
All checks were successful
Deploy Trade-In / changes (push) Successful in 19s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 3m46s
Deploy Trade-In / build-backend (push) Successful in 1m24s
Deploy Trade-In / deploy (push) Successful in 2m4s
Deploy Trade-In / deploy-status (push) Successful in 1s
2026-08-15 19:48:18 +00:00
677edd5f1b Merge pull request 'chore(ops): почта GlitchTip настраивается из окружения и на worker'е тоже' (#2914) from chore/glitchtip-email-alerts into main
All checks were successful
Deploy / changes (push) Successful in 10s
Deploy / build-backend (push) Successful in 40s
Deploy / build-frontend (push) Successful in 47s
Deploy / build-worker (push) Successful in 49s
Deploy / deploy (push) Successful in 1m20s
Deploy / deploy-status (push) Successful in 1s
2026-08-15 19:47:36 +00:00
1fe0e90f66 Merge pull request 'chore(ops): зависшие job-контейнеры, лимит журнала, мёртвый блок status в Caddy' (#2912) from chore/ops-prune-logs-caddy into main
Some checks failed
Deploy / deploy-status (push) Blocked by required conditions
Deploy / build-frontend (push) Blocked by required conditions
Deploy / deploy (push) Blocked by required conditions
Deploy / changes (push) Successful in 13s
Deploy / build-backend (push) Has been cancelled
Deploy / build-worker (push) Has been cancelled
2026-08-15 19:45:46 +00:00