feat(mera/b2c): правовая рамка — согласие до сохранения, удаление по сроку и по запросу — этап 4 из 8 #2547
Open
lekss361
wants to merge 1 commit from
feat/mera-b2c-privacy into main
pull from: feat/mera-b2c-privacy
merge into: lekss361:main
lekss361:main
lekss361:feat/mera-b2c-antiabuse
lekss361:feat/mera-b2c-perimeter
lekss361:fix/2013-avito-cohort-null
lekss361:fix/rbac-test-user2-expired
lekss361:fix/expire-brusnika-trial-access
lekss361:feat/tradein-domclick-house-sku-schema
lekss361:chore/design-sync-tradein
lekss361:fix/tradein-deploy-scraper-paths-filter
lekss361:fix/tradein-no-numberless-house-insert
lekss361:fix/tradein-dedup-fias-pass-no-geoguard
lekss361:feat/tradein-fias-estimate-frontend
lekss361:fix/tradein-dedup-by-fias
lekss361:feat/tradein-fias-tier-matching
lekss361:fix/tradein-v2-uiux-p1
lekss361:fix/objective-lots-dedup-1964
lekss361:fix/audit-followups-1953
lekss361:feat/concept-house-picker-1965-stage3b
lekss361:feat/concept-house-catalog-1965-stage3a
lekss361:feat/concept-live-massing-1965-stage2b
lekss361:feat/concept-recompute-1965-stage2a
lekss361:feat/concept-section-1965-stage1
lekss361:fix/best-layouts-per-object-snapshot-1956
lekss361:fix/deficit-segmentation-1959
lekss361:feat/tradein-hedonic-ground-floor
lekss361:fix/report-map-points-1961
lekss361:fix/report-microcopy-1963
lekss361:fix/report-nspd-zoning-1962
lekss361:fix/report-frontend-display-1953
lekss361:perf/tradein-estimate-audit
lekss361:perf/best-layouts-objects-first
lekss361:fix/171-migration-path
lekss361:perf/171-objective-crm-report-month-idx
lekss361:fix/1926-app-log-stdout
lekss361:fix/estimator-tiebreaker-nanalogs
lekss361:fix/1917-fetch-json-network-retry
lekss361:fix/1926-scrape-runs-total-seen
lekss361:fix/1781-house-fk-source-identity
lekss361:feat/39-osrm-per-category
lekss361:feat/1746-utility-infra-map
lekss361:fix/test-849-savepoint-count
lekss361:fix/parking-economics-by-class
lekss361:fix/zouit-engineering-area-gate
lekss361:fix/zoning-resolution-decouple
lekss361:feat/dcf-velocity-schedule
lekss361:feat/zone-regulation-backfill
lekss361:chore/mock-financial-estimate
lekss361:fix/finmodel-split-disclosure-threshold
lekss361:feat/finmodel-financing
lekss361:feat/finmodel-sitefinder-bridge
lekss361:feat/finmodel-dcf
lekss361:feat/finmodel-price-calibration
lekss361:feat/finmodel-cost-cascade
lekss361:audit/1871-p2-estimator-dedup-split
lekss361:audit/1871-p2-avito-coord
lekss361:audit/1871-p3-uiux
lekss361:audit/1871-p2-invest-moi
lekss361:audit/1871-p2-velocity-market
lekss361:audit/1871-p1-3-isreal-stubs
lekss361:audit/1871-p1-2-ghost-anchor-guard
lekss361:audit/1871-p1-scenarios-collapse
lekss361:revert/site-finder-v2
lekss361:fix/v2-remove-resource-legend
lekss361:fix/v2-map-legend-position
lekss361:feat/site-finder-v2-map-light-polish
lekss361:rollback/site-finder-home-light
lekss361:feat/site-finder-v2-cockpit
lekss361:rollback/sf-old-analysis-design
lekss361:feat/ptica-tabs-6-6-reports-params
lekss361:fix/ptica-vri-row
lekss361:feat/ptica-map-glyphs-sitefinder-dark
lekss361:fix/ptica-3d-preview-product-verdict
lekss361:fix/ptica-button-fontsize
lekss361:fix/ptica-parity-data-mapping
lekss361:chore/ptica-iso-preview-spin
lekss361:fix/ptica-inter-map-product
lekss361:fix/ptica-visual-parity
lekss361:fix/ptica-left-rail
lekss361:feat/ptica-cockpit-complete-bottom
lekss361:feat/ptica-default-and-rich-map
lekss361:feat/ptica-real-ksit-frontend
lekss361:feat/tradein-ekb-geoportal-buildings
lekss361:fix/sf-feedback-batch
lekss361:feat/avito-newbuilding-sweep
lekss361:feat/browser-concurrent-pool
lekss361:fix/backfill-kadastr-column
lekss361:fix/avito-proactive-ip-rotate
lekss361:feat/activate-domclick-sweep
lekss361:feat/avito-newbuilding-capture
lekss361:fix/house-id-fk-realtime-link
lekss361:fix/migration-162-table-if-exists
lekss361:feat/riasurt-sverdl-layers-108
lekss361:fix/sber-dataset-paths-902
lekss361:fix/conflict-resolution-freshness-1539
lekss361:feat/objective-lots-history-writer-307-obj6
lekss361:feat/velocity-mv-61
lekss361:fix/objective-mapping-is-reviewed-gate-307-obj2
lekss361:fix/cian-detail-rich-fields
lekss361:fix/avito-novostroyki-segment
lekss361:feat/yandex-novostroyki-newflat
lekss361:fix/ci-dedup-runner-storm-1709
lekss361:fix/emiss-pk-granularity-1687
lekss361:feat/listings-segment-param-1188
lekss361:fix/inn-regex-word-boundary-1682
lekss361:fix/excel-deficit-horizon-1590
lekss361:fix/admin-scrape-validation
lekss361:fix/admin-leads-interval-cast-1694
lekss361:fix/dkp-corridor-doc-p10p90-1695
lekss361:fix/weather-wind-d-allnone
lekss361:test/residential-zone-rawprops-1681
lekss361:fix/domrf-badge-regex-narrow-1686
lekss361:feat/yandex-camoufox-transport
lekss361:fix/score-sat-factor-1509
lekss361:fix/base-pace-room-bucket-1593
lekss361:fix/gate-verdict-no-blocker-1617
lekss361:fix/confidence-deal-count-window-1637
lekss361:fix/match-economics-1511-1512
lekss361:fix/listings-partial-indexes-1398
lekss361:fix/smart-suggestions-threshold-1503
lekss361:fix/dkp-corridor-percentile-1520
lekss361:fix/enrich-economics-window-1513
lekss361:fix/leads-stats-window-1383
lekss361:fix/poi-score-scale-1486
lekss361:fix/geo-weight-floor-1633
lekss361:fix/inn-regex-context-1640
lekss361:fix/domrf-status-classify-1609
lekss361:fix/emiss-period-dedup-1606
lekss361:fix/cian-paginate-tail-1393
lekss361:fix/normalize-zero-fill-guard-1638
lekss361:fix/supply-view-devgroup-key-1650
lekss361:fix/residential-zone-detect-1353
lekss361:fix/score-label-threshold-1357
lekss361:fix/trend-ratio-vprior-zero-1508
lekss361:fix/district-median-dedup-1352
lekss361:fix/supply-layers-overlap-1355
lekss361:fix/pdf-expires-at-1530
lekss361:fix/quartirography-area-bucket-1406
lekss361:fix/cad-zones-multipolygon-1344
lekss361:fix/sold-pct-market-verdict-1407
lekss361:fix/week-review-finish
lekss361:fix/week-review-backend-v2
lekss361:feat/plan-vectorization-spike-299
lekss361:fix/1668-analyze-confidence
lekss361:fix/1667-metro-block
lekss361:fix/1666-layout-velocity-beat
lekss361:chore/remove-n1-scraper
lekss361:fix/cian-kitchen-area
lekss361:feat/yandex-detail-backfill
lekss361:feat/avito-detail-backfill
lekss361:fix/best-layouts-bucket-normalization
lekss361:fix/gknspecial-incremental-commit-per-prefix
lekss361:fix/okn-objects-full-registry-load
lekss361:fix/parcel-ird-overlap-except-expand
lekss361:fix/report-assembler-confounded-keys
lekss361:fix/job-settings-json-persist-v2
lekss361:fix/nspd-geo-soft-time-limit-passthrough
lekss361:fix/nspd-soft-time-limit-v2
lekss361:fix/pilot-request-modal-validation
lekss361:fix/recommend-mix-saturation-latest-snapshot
lekss361:fix/scrape-cadastre-fail-counter-v2
lekss361:fix/izyatie-ocr-cad-normalize
lekss361:fix/job-settings-panel-json-state-persist
lekss361:fix/noise-loader-savepoint-per-row
lekss361:fix/objective-sync-config-bare-except
lekss361:fix/parcel-snapshot-mdash-double-escape
lekss361:fix/poi-loader-leap-year-date-replace
lekss361:fix/scrape-cadastre-permanent-fail-counter
lekss361:fix/usermenu-analyst-role-label
lekss361:feat/location-948b-r
lekss361:feat/location-entity-948b
lekss361:feat/insight-entity-948a
lekss361:feat/analyst-role-audit-962
lekss361:feat/cbr-inflation-macro-946
lekss361:feat/cian-zhk-resolve-972
lekss361:perf/forecast-parallel-horizons-1129
lekss361:feat/newbuilding-enrich-backfill-972
lekss361:feat/emiss-macro-indicators-946
lekss361:feat/rosstat-emiss-macro-946
lekss361:ci/frontend-vitest-job
lekss361:chore/frontend-vitest-wkt-tests
lekss361:feat/forecast-meta-footer
lekss361:feat/forecast-future-supply-competitors
lekss361:feat/forecast-docx-pptx-buttons
lekss361:feat/forecast-scoring-panel
lekss361:feat/forecast-product-tz-block
lekss361:feat/market-map-layers-999
lekss361:feat/forecast-chart-section6
lekss361:feat/forecast-export-pptx-959
lekss361:feat/forecast-export-docx-959
lekss361:feat/forecast-export-ui-959
lekss361:feat/forecast-export-telegram-959
lekss361:feat/forecast-export-md-959
lekss361:feat/analyze-response-contract-961
lekss361:feat/competitor-velocity-spatial-fallback-968
lekss361:fix/frontend-healthcheck-hostname
lekss361:feat/analyze-market-coords-999
lekss361:fix/site-finder-entry-crash-1001
lekss361:feat/horizon-selector-996
lekss361:feat/forecast-section-998
lekss361:feat/forecast-endpoint-horizon-enqueue
lekss361:feat/forecast-celery-task-persist
lekss361:feat/forecast-orchestrator-service
lekss361:feat/demand-supply-months-of-inventory
lekss361:feat/wire-district-resolver
lekss361:feat/district-vocab-reconciliation
lekss361:fix/affordability-market-spread
lekss361:fix/backtest-sig-gate
lekss361:feat/wire-978-almon-rate-regime
lekss361:feat/backtest-oos-almon-seasonal
lekss361:ci/forgejo-pytest-gate
lekss361:fix/tradein-praktika-logo-form-scroll
lekss361:feat/yandex-exhaustive-price-room
lekss361:feat/794-sber-time-adjust
lekss361:chore/bot-harness-tuning
lekss361:docs/agent-usage-throttle-qa-terminal
lekss361:fix/avito-sweep-single-run-guard
lekss361:chore/analyst-inbound-queue-tradein-db
lekss361:feat/801-preview-full-wt
lekss361:chore/bot-safety-followups
lekss361:feat/tradein-avito-imv-fix
lekss361:feat/tradein-repair-coef-calibration
lekss361:feat/tradein-avito-houses-fix
lekss361:feat/tradein-address-precision
lekss361:feat/tradein-backfill-prioritize-listings
lekss361:feat/tradein-geocode-deals-nominatim
lekss361:feat/tradein-geocode-deals-from-houses
lekss361:feat/tradein-same-building-match
lekss361:feat/claude-envvars-and-stale-cron
No reviewers
Labels
Clear labels
Admin UI / internal tools / pipeline tracker
Аналитика данных / matching
Authentication / authorization / multi-tenancy
Автоматизация / cron / scheduler
Something isn't working
Коммерческая воронка / пилоты / pipeline / реестр ПО
Operational housekeeping
Forgejo Actions / build pipeline
152-ФЗ / реестр ПО / legal / TOS
Data sources, parsers, ETL
Уникальные данные — sales tracker, CRM aggregation
README / runbooks / onboarding
This issue or pull request already exists
Developer experience / build speed
New feature or request
Находки полного мульти-агентного ревью (Claude Fable 5, 2026-06-09)
Feedback from Max (Senior partner)
Generative Design — concept generation engine
Новое ТЗ от Ген Геныча (июнь 2026): Site Finder v2 — ИИ-прогноз продуктовой стратегии девелопера. Актуальный приоритет.
Pending team sync / decision
Human review/decision required
Monitoring / metrics / logs / Sentry / Uptime
Kill-switch — all autonomous bots pause
Latency / throughput / DB query tuning
Critical / production-blocker
High priority
Normal priority
Низкий приоритет (follow-up, tech-debt)
Backend Python — FastAPI, Celery, scrapers
DB migrations, indexes, SQL
docker-compose, Caddy, workflows
Frontend — Next.js, React, TypeScript
Tests, smoke, Playwright
Скрапперы (Avito/Cian/Yandex/Rosreestr)
Security audit / secrets / vulnerabilities
Site Finder scoring quality & data layer
Stage 1: Generative MVP (нед 2-7)
Stage 2: Site Finder MVP (нед 8-12)
Blocked — needs human intervention
Closed, completed
Raw/fuzzy task filed by human — auto-analyst подхватывает: code-archeology + декомпозиция в actionable scope/* + status/ready (или split на под-issues)
Reviewer/QA вернул worker на доработку — worker сам чинит свой PR (fixup), НЕ требует human (в отличие от status/blocked)
PR merged, awaiting smoke test
Ready for pickup by worker bot
PR open, awaiting code review
Work in progress (worker claimed)
Технический долг
Trade-In MVP проект
User experience / responsive / conversion
Week review 1 — находки multi-agent аудита проекта (2026-06-14)
This will not be worked on
Trade-In Estimator — проект оценки вторичного жилья
Исходно-разрешительная документация — слой ограничений участка для analyze-таблицы
admin
Admin UI / internal tools / pipeline tracker
analytics
Аналитика данных / matching
auth
Authentication / authorization / multi-tenancy
automation
Автоматизация / cron / scheduler
bug
Something isn't working
business
Коммерческая воронка / пилоты / pipeline / реестр ПО
chore
Operational housekeeping
ci
Forgejo Actions / build pipeline
compliance
152-ФЗ / реестр ПО / legal / TOS
data
Data sources, parsers, ETL
data-moat
Уникальные данные — sales tracker, CRM aggregation
docs
README / runbooks / onboarding
duplicate
This issue or pull request already exists
dx
Developer experience / build speed
enhancement
New feature or request
Fable 5 ревью
Находки полного мульти-агентного ревью (Claude Fable 5, 2026-06-09)
feedback/max
Feedback from Max (Senior partner)
generative
Generative Design — concept generation engine
GG-форсайт
Новое ТЗ от Ген Геныча (июнь 2026): Site Finder v2 — ИИ-прогноз продуктовой стратегии девелопера. Актуальный приоритет.
needs-discussion
Pending team sync / decision
needs-human
Human review/decision required
observability
Monitoring / metrics / logs / Sentry / Uptime
pause-bots
Kill-switch — all autonomous bots pause
performance
Latency / throughput / DB query tuning
priority/p0
Critical / production-blocker
priority/p1
High priority
priority/p2
Normal priority
priority/p3
Низкий приоритет (follow-up, tech-debt)
scope/backend
Backend Python — FastAPI, Celery, scrapers
scope/db
DB migrations, indexes, SQL
scope/devops
docker-compose, Caddy, workflows
scope/frontend
Frontend — Next.js, React, TypeScript
scope/qa
Tests, smoke, Playwright
scrapers
Скрапперы (Avito/Cian/Yandex/Rosreestr)
security
Security audit / secrets / vulnerabilities
site-finder
Site Finder scoring quality & data layer
stage/1
Stage 1: Generative MVP (нед 2-7)
stage/2
Stage 2: Site Finder MVP (нед 8-12)
status/blocked
Blocked — needs human intervention
status/done
Closed, completed
status/needs-analysis
Raw/fuzzy task filed by human — auto-analyst подхватывает: code-archeology + декомпозиция в actionable scope/* + status/ready (или split на под-issues)
status/needs-fix
Reviewer/QA вернул worker на доработку — worker сам чинит свой PR (fixup), НЕ требует human (в отличие от status/blocked)
status/qa
PR merged, awaiting smoke test
status/ready
Ready for pickup by worker bot
status/review
PR open, awaiting code review
status/wip
Work in progress (worker claimed)
tech-debt
Технический долг
tradein
Trade-In MVP проект
ux
User experience / responsive / conversion
week ревью 1
Week review 1 — находки multi-agent аудита проекта (2026-06-14)
wontfix
This will not be worked on
вторичка
Trade-In Estimator — проект оценки вторичного жилья
ИРД
Исходно-разрешительная документация — слой ограничений участка для analyze-таблицы
No labels
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
Fable 5 ревью
feedback/max
generative
GG-форсайт
needs-discussion
needs-human
observability
pause-bots
performance
priority/p0
priority/p1
priority/p2
priority/p3
scope/backend
scope/db
scope/devops
scope/frontend
scope/qa
scrapers
security
site-finder
stage/1
stage/2
status/blocked
status/done
status/needs-analysis
status/needs-fix
status/qa
status/ready
status/review
status/wip
tech-debt
tradein
ux
week ревью 1
wontfix
вторичка
ИРД
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#2547
Reference in a new issue
No description provided.
Delete branch "feat/mera-b2c-privacy"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Четвёртый этап плана B2C. Наружу ничего не открывает, мержится независимо от DNS.
Три дефекта, каждый блокировал легальный публичный запуск
Адрес физлица сохранялся до любого согласия. Согласие фиксировалось только на форме заявки — то есть после записи адреса в базу. Для пилота с договором это терпимо, для человека с улицы нет. Теперь проверка стоит первой строкой расчёта, до геокодирования и до обоих мест записи адреса.
Срок жизни оценки не приводил к удалению. Поле срока применялось только как фильтр при чтении, физического удаления не было ни в одной из 23 фоновых задач — данные жили вечно вопреки декларации. У заявок срока не было вовсе.
Пути «удалите мои данные» не существовало.
Решения, которые стоит отметить
Хранение согласия — колонками на самой оценке, 1:1 с уже работающим прецедентом для заявок: IP клиента, версия политики, дословный снимок текста. Отдельную таблицу событий не заводили сознательно — согласие даётся ровно на создание этой строки, и когда строка удаляется по сроку, исчезновение доказательства вместе с данными логично: персональных данных больше нет, свидетельствовать не о чем.
Проверка не выводится из пустого имени пользователя. Первая версия так и делала — и сломала 92 несвязанных теста оценщика, которые вызывают расчёт без имени, проверяя ценовую логику. Заменено на явный флаг, который выставляет единственный боевой вызывающий. B2B-поток не тронут: поле согласия опционально, иначе сломались бы пилоты, чей фронт его вообще не шлёт.
Задача удаления засеяна выключенной. Это первая автоматическая задача в trade-in, которая удаляет персональные данные — первый прогон должен пройти под наблюдением, а не по расписанию. Тот же приём уже применялся в проекте. Включается одной командой после проверки.
Честно зафиксированные ограничения
Аноним без ссылки на оценку, без телефона и без обращения в поддержку — неидентифицируем. Удалить его данные без дополнительной идентификации невозможно, схема этого не позволяет. Записано в докстринге, а не умолчано.
Удаление чистит только копию в базе. Зеркало переписки в Telegram-топике не удаляется ничем в кодовой базе — нужен отдельный ручной шаг через API бота. Зафиксировано в коде.
События аудита этим механизмом не чистятся — там в полезной нагрузке есть адрес. Является ли журнал аудита законным основанием пережить запрос на удаление — вопрос к юристу, не инженерное решение.
Что за юристом
Конкретные сроки хранения — инженерное предложение с обоснованием, не юридический вывод. Для сконвертированных заявок нужен другой, договорной срок, и механизма пометки «сконвертирован» в схеме сейчас нет.
Test plan
uv run pytest -q— 2775 passed, 9 skippedruff checkчисто, проверка на ловушку:x::typeчистоView command line instructions
Checkout
From your project repository, check out a new branch and test the changes.Merge
Merge the changes and update on Forgejo.Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.