gendesign/scripts
bot-backend d046eaada2
All checks were successful
CI Trade-In / changes (pull_request) Successful in 10s
CI / changes (pull_request) Successful in 11s
CI Trade-In / browser-tests (pull_request) Has been skipped
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 4m49s
feat(mera/b2c): публичный API МЕРЫ — /api/public/mera/{suggest,coverage}
Первый шаг к отдельному B2C-интерфейсу оценки на meraocenka.ru: домен получает
собственную поверхность бэкенда вместо того, чтобы тянуть куски закрытого
контура.

## Отдельный префикс, а не проброс кусков /api/v1/*

На meraocenka.ru действует allowlist-by-default. Открыть там API можно было
двумя способами: перечислить нужные v1-пути поимённо — или завести префикс, под
которым по определению не лежит ничего закрытого. Выбран второй: при первом
одна опечатка в матчере (`/trade-in/api/*` вместо точного пути) открывает
наружу весь v1 — ~20 ручек, включая PDF расчётов, фотографии и админку. Цена
ошибки, а не удобство.

Добавить сюда приватную ручку теперь нужно СПЕЦИАЛЬНО — положив файл в
app/api/public/. Случайно нельзя.

## Ноль записей в БД

Обе ручки только читают: /coverage — один SELECT, /suggest — прокси
автокомплита. Это условие, при котором публичная форма работает ДО контура
согласия 152-ФЗ (#2895: сегодня адрес физлица попадает в trade_in_estimates
раньше согласия, а пути удаления в бэкенде нет). Платный расчёт, который писать
будет, открывается только вместе с ним.

## Делегирование, а не копии

Обе ручки вызывают те же функции, что обслуживают закрытый контур
(v1.geocode.suggest_addresses, v1.trade_in.coverage_probe). Разбор #2894
показал, чем кончается вторая копия когорты: проба отвечает «данные есть» там,
где платный расчёт видит ноль. Публичный ответ переиспользует
CoverageProbeResponse — на нём уже стоит гейт «ни одного price-подобного поля».

## Бюджеты

Общего 300/60с мало: /suggest через DaData-тир — платный внешний вызов, абуз
стоит денег. Свои per-IP окна: 40/мин на подсказки (человек с debounce'ом
тратит единицы на адрес), 15/мин на пробу.

## Проверено

11 тестов, из них структурные: набор ручек под /api/public проверяется на
РАВЕНСТВО (третья, добавленная без правки теста, роняет сборку) и сверяется с
rbac._PUBLIC_PATHS в обе стороны — чтобы не осталось открытого пути-призрака.
Рядом висит закрытый маршрут-двойник: без него «аноним получает 200» одинаково
зелёный и когда исключение точечное, и когда auth-гейт снят целиком.

Мутации:
  убрать пути из rbac._PUBLIC_PATHS → 7 failed / 4 passed
  снять бюджет с /coverage         → 2 failed / 9 passed
  откат                            → 11 passed

Плюс 72 passed на связке rbac + coverage + version, `caddy validate` = Valid
configuration, ruff чист.

Смоук периметра дополнен парой, которую нельзя разделять: публичные ручки
отвечают 200 анонимно И /trade-in/api/v1/* на этом домене по-прежнему 404.
Зелёная только первая проверка = API открыт целиком, а тест этого не заметил.

Refs #2894, #2895
2026-08-15 22:32:53 +03:00
..
auth fix(ops): repair broken main-DB backup + harden auth scripts/docs (#71 #427 #429 #428) 2026-06-13 20:13:04 +05:00
claude-hooks chore(claude): security hardening — dangerous-commands hook, settings в git, restricted DB, throttle (#2150) 2026-07-02 15:23:11 +00:00
bootstrap_glitchtip.sh fix(infra): bootstrap_glitchtip — \gexec instead of DO block (psql var trap) (#219) 2026-05-16 15:54:29 +00:00
bootstrap_schema_migrations.sh feat(infra): auto-apply data/sql/*.sql migrations in deploy pipeline (#150) (#151) 2026-05-15 08:06:54 +03:00
build_osrm.sh feat(analyze): per-category OSRM routing (foot vs driving) (#39 A3) 2026-06-27 04:30:25 +05:00
check-migration-lock-timeout.py fix(migrations): закрепить lock_timeout для блокирующего DDL и ловить невалидные индексы (#2791) 2026-08-07 11:21:28 +00:00
check-workflow-ports.py ci: гейт против публикации занятых на VPS портов в workflow (#2757) (#2759) 2026-08-06 21:40:05 +00:00
cleanup-merged-worktrees.sh fix(devops): cleanup-merged-worktrees.sh — 3 бага, найденные вживую на 69 забытых worktree (#2418) 2026-07-04 13:00:14 +00:00
cleanup-stale-claims.sh chore(claude): extend self-extending tripwire + pause-bots guard for stale-claims 2026-05-29 17:36:20 +03:00
cleanup-worktrees-aggressive.py fix(week-review): автофиксы код-ревью — 169 issue (label «week ревью 1») 2026-06-15 20:21:11 +05:00
cleanup_ghosts.py fix(week-review): автофиксы код-ревью — 169 issue (label «week ревью 1») 2026-06-15 20:21:11 +05:00
migrate_kg_to_obsidian.py fix(week-review): автофиксы код-ревью — 169 issue (label «week ревью 1») 2026-06-15 20:21:11 +05:00
setup-bot-env.ps1 feat(claude): env-vars refactor + stale-claim cron (Phase 2 finalization) 2026-05-28 00:24:45 +03:00
setup-couchdb.sh feat(deploy): split obsidian stack from main + path-filtered GHA 2026-05-11 09:51:31 +03:00
smoke-mera-perimeter.sh feat(mera/b2c): публичный API МЕРЫ — /api/public/mera/{suggest,coverage} 2026-08-15 22:32:53 +03:00
start-analyst.ps1 chore(bots): per-role launcher scripts + move bot pipeline to forgejo MCP 2026-05-30 10:38:10 +03:00
start-backend.ps1 chore(bots): per-role launcher scripts + move bot pipeline to forgejo MCP 2026-05-30 10:38:10 +03:00
start-bot.ps1 chore(agents): reviewer back to Opus (revert model-part of aa3d012) 2026-05-31 17:16:57 +03:00
start-frontend.ps1 chore(bots): per-role launcher scripts + move bot pipeline to forgejo MCP 2026-05-30 10:38:10 +03:00
start-qa.ps1 chore(bots): per-role launcher scripts + move bot pipeline to forgejo MCP 2026-05-30 10:38:10 +03:00
start-reviewer.ps1 chore(bots): per-role launcher scripts + move bot pipeline to forgejo MCP 2026-05-30 10:38:10 +03:00