Стартап: AI-подбор земельных участков (Site Finder) + автоматическая генерация концепций застройки (Generative Design) для девелоперов РФ

Two-in-one воронка: от инвест-критериев → найденный участок → концепт застройки → финансовая модель

Конкуренты: rTIM (только концепт-стадия, нет site-selection), TestFit (нет РФ-данных)

Целевая аудитория: инвестдепартаменты + архитектурно-проектные отделы региональных девелоперов

Фаза 0 — Discovery MVP, апрель–июнь 2026 (3 месяца)

Бюджет Фазы 0: 0,9–1,2 млн ₽

Документы хранятся в docs/ внутри репозитория


Решение зафиксировано в апреле 2026: переход с .NET на Python для Discovery MVP

Backend: Python 3.12, FastAPI 0.115+, SQLAlchemy 2.0, GeoAlchemy2, Pydantic v2, Alembic, Celery + Redis, httpx

Геометрия: Shapely 2.0, GeoPandas 1.0, Pyproj (проекции WGS84 ↔ UTM ↔ МСК-66 для Свердловской обл.), Rasterio

ML: XGBoost (скоринг участков), scikit-learn, pandas, NumPy

База данных: PostgreSQL 16 + PostGIS 3.4, Redis 7

Frontend: Next.js 15, React 19, TypeScript 5, Tailwind CSS 4, shadcn/ui, TanStack Query, Mapbox GL JS или Leaflet

Экспорт: WeasyPrint (PDF), ezdxf (DXF), openpyxl (Excel)

Инфра: Yandex Cloud или VK Cloud, Docker, GitHub Actions, Sentry

Dev tools: uv (зависимости), ruff (линтер+форматтер), mypy (типизация), pytest


К концу месяца 3 (июнь 2026): 3 платящих пилотных клиента, ≥30 тыс. ₽/мес каждый

Заявка в реестр российского ПО подана

Це́ль: получить право пройти в Раунд А на 20–25 млн ₽

Acceptance criteria разбиты на 3 блока: функционально / бизнесово / технически

Правило перехода: 3/3 → Раунд А; 2/3 → продление Фазы 0 на 1–2 мес.; 1/3 или меньше → стоп проекта

В v2.2 цель = 3 пилота; в v2.1 (бизнес-план) указано 4 пилота — расхождение, требует синхронизации в пользу 3


Discovery MVP, месяцы 1–3 после старта

Пилотный регион: Свердловская обл. (Екатеринбург, ПЗЗ Екатеринбурга, МСК-66)

Месяц 1 цели: ООО зарегистрировано, прототип Site Finder с 1000 участков, 50 целевых клиентов в CRM, 5 cold-outreach, 3 встречи

Месяц 2 цели: 15 встреч кумулятивно, 2 LOI, 1 платящий пилот (≥30 тыс. ₽/мес), демо на реальных участках, первая статья

Месяц 3 цели: 20+ встреч, 3 платящих пилота, 7+ LOI, 1 регадминистрация в переговорах, заявка в реестр ПО, инвест-deck (12 слайдов), финмодель на 5 лет


Дата валидации: 25 апреля 2026

КРИТИЧНО: бизнес-план v2.1 не синхронизирован со стеком v2.2 — в плане 12 мес. месяцы 1–4 ещё ссылаются на .NET Core 8

Несостыковка KPI: v2.1 = 4 платящих пилота, v2.2 = 3 — нужно остановиться на 3 (как в Acceptance Criteria v2.2)

Регион не зафиксирован однозначно: v2.1 пишет «Свердл. или Лен.», v2.2 — только Свердл. — закрепить Свердловскую

Прайсинг: пилот 30 тыс., прайс-лист 70–120 тыс. — уточнить в финмодели для инвесторов: 70 тыс./мес как baseline

Технические риски: Time to First Value ≤10 мин амбициозно (предложение: 15 мин); генерация концепции ≤10 сек требует профилировки с первого билда

PostgreSQL TDE отсутствует в open-source — заменить на pgcrypto + шифрование чувствительных полей на уровне приложения

mypy --strict для всего MVP избыточен соло-разработчику — оставить только для core-модулей (geometry/scoring/financial)

99% uptime в рабочие часы для соло-разработчика рискованно — реалистично 95% + ответ в течение рабочего дня

Заявка в реестр ПО ≠ свидетельство; срок рассмотрения 60–180 дней — учесть для расчёта Раунда А

Бюджет 1,2 млн ₽ + 3 мес. + один основатель плотный; рекомендация — заложить буфер +1 месяц или урезать DXF-экспорт из Discovery


Правило: вся информация по проекту gendesign хранится в memory-gendesign.jsonl (context="gendesign"). Информация = факты, решения, результаты анализа, обсуждения стратегии, KPI, списки рисков, протоколы валидации и т.д.

НИКОГДА не создавать .md / .docx / .pdf / .pptx файлы самостоятельно — даже если кажется, что это поможет. Документы генерируются ТОЛЬКО по явному запросу («сделай md», «собери в документ», «выгрузи в docx»).

При поступлении новых фактов/решений в разговоре — сразу сохраняем в память через aim_memory_store / aim_memory_add_facts в context="gendesign".

Для файловой генерации по запросу: запрос срез из памяти (aim_memory_search/read_all) → сборка документа. Память = единый источник правды, файлы = производные.

**Why:** пользователь хочет избежать разъехавшейся инфы между версиями доков (как случилось с v2.1/v2.2). Единый источник (граф памяти) — синхронен по определению.

**How to apply:** в любом обмене по этому проекту — (1) сначала читаем gendesign-память, (2) ведём диалог/анализ, (3) сохраняем новые выводы в память, (4) файлы только если пользователь явно запросил.


2 фуллстек-разработчика (оба пишут Python + TypeScript)

Оба part-time по 20 ч/неделю — итого ~40 person-hours/неделю (эффективных с координацией ~33)

Разделение по фичам, а не по слоям — оба трогают backend и frontend

Ритм координации: 1 синк/неделю (30 мин), daily-async в Telegram, PR review обязательный

Ветвление: trunk-based, feature ветки ≤ 3 дней

Критичный тулинг: openapi-typescript для codegen TS-типов из Pydantic-схем (иначе два фуллстека плодят расхождения в API-контракте)


Порядок: строго последовательный — Generative полностью, потом Site Finder

Общая оценка: 12 недель (Stage 0: 1 нед., Stage 1: 6 нед., Stage 2: 5 нед.)

Stage 0 (нед. 1) — скелет: монорепо backend+frontend, Docker с PostGIS+Redis, FastAPI hello, Next.js hello, openapi-typescript codegen, GitHub Actions CI, ruff+mypy(core)+pytest. Без JWT (single-tenant + X-Demo-User до Раунда А)

Stage 1a (нед. 2-3) — геометрия + API-контракт. A: Shapely-сервис (отступы, сетка), Pydantic ConceptInput/Output, POST /api/v1/concepts с заглушкой. B: страница /concept, Leaflet, импорт GeoJSON + отрисовка, форма параметров, вывод 3 вариантов в табах

Stage 1b (нед. 4-5) — алгоритм размещения. A: жадное заполнение, 3 стратегии, STRtree для коллизий, профилировка (цель ≤10с, fallback 15с). B: визуализация корпусов, метрики ТЭП, сравнение вариантов

Stage 1c (нед. 6-7) — ТЭП + финмодель + экспорты. A: teap.py, financial.py, openpyxl. B: WeasyPrint шаблон, ezdxf, UI кнопок скачивания

Acceptance Stage 1 (конец нед. 7): полигон→3 варианта→ТЭП+финмодель→PDF/Excel/DXF. Продаваемый артефакт для встреч с месяца 2

Stage 2a (нед. 8-9) — data pipeline. A: парсер ПКК Rosreestr (httpx async, retries), модель Parcel с GeoAlchemy2, загрузка 1000+ участков Екбурга. B: Overpass API для POI, ДОМ.РФ/ЦИАН для цен м², кеш в Redis

Stage 2b (нед. 10-11) — скоринг+API+UI. A: 3 критерия скоринга (эвристики, без XGBoost), POST /parcels/search. B: страница /site-finder, Mapbox, градация по рейтингу, фильтры, карточка

Stage 2c (нед. 12) — интеграция + полировка. Кнопка «Обсчитать концепцию», демо-наполнение 50 участков, бэкапы БД, подача в реестр ПО

Урезано из v2.2 из-за part-time ×2: XGBoost→Фаза 1, JWT-auth→перед Раундом А, mypy --strict только на core, время генерации ≤15с (а не 10с) как fallback


Дата: 25 апреля 2026

Выбор хостинга для РФ: рассматривались Yandex Cloud, VK Cloud, Selectel, Timeweb Cloud, Cloud.ru (Сбер)

Рекомендован Yandex Cloud как основной вариант для Discovery + Production

Обоснование: (1) лучшая поддержка PostGIS в Managed PostgreSQL в РФ; (2) Container Registry + Container Solution включены; (3) входит в реестр российского ПО — плюс к нашей заявке; (4) солидно выглядит для инвесторов Раунда А

Стоимость Discovery (~10–15 тыс ₽/мес): VM Compute s3-c2-m4 (~3-4 тыс), Managed Postgres 1vCPU/4GB/30GB SSD (~5-7 тыс), Container Registry (бесплатно до 5GB), Object Storage для бэкапов (~500₽)

Альтернатива для жёсткой экономии: Selectel дешевле в 1.5–2 раза, но требует ручной PostGIS-рутины. Резерв на случай проблем с YC

Архитектура production: 1×VM с Docker Compose (backend + frontend + Caddy reverse proxy + auto-TLS) + Managed PostgreSQL (отдельный сервис) + Object Storage (бэкапы)

Образы: backend + frontend пушатся в Yandex Container Registry из GitHub Actions; на VM выполняется docker compose pull && up -d

GitHub Secrets для deploy: YC_SA_JSON_CREDENTIALS, YC_REGISTRY_ID, DEPLOY_HOST, DEPLOY_USER, DEPLOY_SSH_KEY, DEPLOY_PORT (опционально)

Caddy выбран вместо nginx: авто-TLS через Let's Encrypt без ручных certbot-рутин — дешевле по времени сопровождения для part-time команды

Домен: покупать в .ru зоне (REG.RU или РуЦентр), DNS на Yandex Cloud DNS или Cloudflare бесплатный

Production-путь на VM: /opt/gendesign/docker-compose.prod.yml + .env + Caddyfile


MCP-сервер для памяти: npm-пакет mcp-knowledge-graph (запуск через npx -y)

Команда в claude_desktop_config.json: command=npx, args=['-y','mcp-knowledge-graph','--memory-path','<путь к папке с .jsonl файлами>']

Путь в рабочей среде основателя: C:\mcp\.aim

Стратегия разделённой памяти между коллегами: git синхронизация файла memory-gendesign.jsonl + хард-линк из репо в MCP-папку. Источник правды — репо

Конфликты в .jsonl обычно простые (файл построчный): решаются выбором "оставить обе стороны". rebase, не merge

Ритуал: git pull перед началом работы, git commit+push после изменений памяти

Полный текст процедуры выдан в чате 25 апреля 2026; при повторном запросе — восстановить из этой сущности


Дата проверки: 25 апреля 2026, фактические цены с сайтов провайдеров

Целевой конфиг: 2 vCPU / 4 GB RAM / 30-40 GB NVMe SSD + public IPv4. 60 GB избыточен для Discovery (реальное использование диска 12-15 GB: OS+Docker 5-7 GB + Postgres+PostGIS 0.5-1 GB + логи+бэкапы 1-2 GB + буфер 5 GB)

Selectel Standard Line 2/4 GB = 2308.86 ₽/мес (CPU+RAM only) + диск 30 GB Network SSD ~270 ₽ + public IP. Итого ~2700-3000 ₽/мес. Дороже конкурентов в 2-3 раза

Selectel Shared Line 2/4 GB с 10% vCPU = 1239 ₽/мес — дешевле, но CPU слишком слабый для Postgres+PostGIS под реальной нагрузкой

Timeweb Cloud MSK 50: 2 vCPU 3.3 GHz / 4 GB / 50 GB NVMe / 1 Гбит/с = 1062 ₽/мес со скидкой 10% при годовом контракте (или ~1180 ₽ без контракта). IPv4 включён. Реестр ПО № 15725

Beget VPS Standard 2 vCPU 3+ GHz / 4 GB / 40 GB NVMe = 33 ₽/день сервер + 5 ₽/день IPv4 = 38 ₽/день ≈ 1140 ₽/мес. Автобэкапы раз в несколько дней бесплатно. KVM. Реестр ПО № 16697

Beget VPS 2/2/30 = 27 ₽/день + 5 ₽ IP = 32 ₽/день ≈ 960 ₽/мес — ещё дешевле, но 2 GB RAM маловато для Postgres+PostGIS+Redis+backend+frontend+Caddy

Рекомендация Discovery: Beget VPS 2/4/40 NVMe + IP ≈ 1140 ₽/мес (самый дешевый реально рабочий конфиг) или Timeweb Cloud MSK 50 ≈ 1062 ₽/мес (лучше NVMe, больше диск)

Ранее в Hosting_Decision_Apr25 был предложен Yandex Cloud (~10-15 тыс ₽/мес с managed services). Это вариант для продакшена после Раунда А, не для Discovery

Для Discovery Beget выигрывает по цене и бесплатным бэкапам. Timeweb выигрывает по UI/UX панели и большему диску. Selectel оправдан только если планируется быстрый перевод на managed Postgres/K8s в их экосистеме


SSH-ключ для проекта: ed25519, без passphrase (для автодеплоя из GitHub Actions)

Локация: $HOME\.ssh\gendesign_deploy (приватный) + .pub (публичный)

SSH config alias: 'Host gendesign' с IdentityFile ~/.ssh/gendesign_deploy — коннект командой 'ssh gendesign'

Публичный ключ вручную загружается в панель хостинг-провайдера при создании сервера

Приватный ключ позже пойдёт в GitHub Secret DEPLOY_SSH_KEY (для deploy.yml workflow)

Windows-специфика: icacls нужен для ограничения прав на приватный ключ, иначе OpenSSH ругается на 'UNPROTECTED PRIVATE KEY FILE'


Принцип разделения: вертикальные срезы по этапам пользовательского пути, не по слоям

Person A — 'Geometry → Variants' owner: Shapely-сервис, нормативные отступы, жадный алгоритм с 3 стратегиями, STRtree коллизии, профилировка. API endpoint POST /concepts, владелец схемы ConceptInput+buildings_geojson. Фронт: Leaflet, импорт/отрисовка полигона, форма параметров, рендеринг 3 вариантов на карте

Person B — 'Variants → Reports' owner: TEAP-сервис, финансовая модель, экспорты PDF/Excel/DXF (WeasyPrint+openpyxl+ezdxf). API endpoint /concepts/:id/export, владелец схем TEAP+FinancialModel. Фронт: таблицы ТЭП, форма финмодели, кнопки скачивания, сравнение вариантов

Точка стыка = Pydantic-контракт ConceptVariant в backend/app/schemas/concept.py. Договариваются в первый день Stage 1a, дальше оба работают с заглушками друг друга без блокировки

Точка стыка 2 — codegen TS-типов: при любой правке схемы оба запускают 'npm run codegen' локально

Календарь по неделям (Stage 1, нед.2-7): A движется по вектору схема→отступы→алгоритм→стратегии→тесты. B движется по вектору схема→TEAP→financial→Excel→DXF→PDF→тесты

Альтернативный расклад при асимметрии навыков: Алгоритмист (A) берёт все 4 backend-сервиса (geometry+TEAP+financial+exporters), фронт минимум. Продуктовик (B) берёт весь фронт + UI экспортов, backend минимум (тонкий export endpoint)

Анти-паттерны: разделение backend/frontend (блокирует второго), общие прямые пуши в main, молчаливые правки Pydantic без codegen, pair programming на каждой задаче (дорого для part-time ×2)


Дата: 25 апреля 2026

В РФ открытых данных по реальным сделкам (Росреестр) НЕТ — только агрегаты. Цены и площади из агрегаторов (ЦИАН/ДомКлик/Авито) — по объявлениям, не по сделкам

Открытые официальные источники (бесплатно, без юрриска): ДОМ.РФ (наш.дом.рф + api.dom.rf, реестр новостроек, площади в жк, колво квартир по комнатностям, класс жилья); Росстат (fedstat.ru, средние цены м² по регионам квартально); Минстрой (норматив цены м² для субсидий); Главгосэкспертиза НЦС (gge.ru, себестоимость м² строительства)

Скрейпинг агрегаторов (серая зона): ЦИАН (cianparser/cianscraper либы на GitHub, но Cloudflare и рейтлимит); Авито; ДомКлик; Яндекс.Недвижимость. Юридически — нарушение ТОС, но исков против мелких парсеров немного

Платные отраслевые: ЕРЗ.РФ Премиум (50-100тыс ₽/год, отраслевой стандарт); Knight Frank/NF Group/CBRE отчеты; PROEstate Analytics; СберИндекс (бесплатно)

Рекомендация для Discovery: Цены — Росстат baseline + ручной парсинг/скрейп ЦИАН 200 объявлений по районам Екбурга. Площади+unit-mix — захардкодить таблицу с возможностью ручной правки. Себестоимость — НЦС Главгосэкспертизы. Новостройки-конкуренты — API ДОМ.РФ

Для реестра ПО декларируем только легальные источники: ДОМ.РФ, Росстат, Главгосэкспертиза, OpenStreetMap. Скрейп ЦИАН — «внутренний справочник curating». Для инвесторов Раунда А — «договорённости с источниками рыночных данных в проработке»


Дата анализа: 25 апреля 2026

Исходный вопрос: можно ли косвенно понять, какие квартиры продаются и какие нет. Ответ: да, через ejednevnyy мониторинг шахматок застройщиков + delta-tracking

Прямые данные о сделках в РФ закрыты: Росреестр ДДУ не в open data, нотариусы и банки — закрытые источники

Косвенные источники по точности: 1) Шахматки застройщиков — 95%+ точность, золотая жила. 2) ДОМ.РФ реестр ДДУ по ЖК — 100% на уровне агрегата. 3) Delta-tracking listings ЦИАН/Авито — 70% точность. 4) ДомКлик ипотечная статистика — sanity check на уровне района. 5) Фиксация снижений цен — сигнал «не продаётся»

Шахматки = золотая жила. На сайтах ПИК/Брусника/Атомстройкомплекс/ТЭН-Девелопмент/Стройтэк/ЛСР и др. интерактивная шахматка с поквартирным статусом (доступно/бронь/продано). Даёт площадь, комнатность, этаж, секцию, цену, дату продажи

Тех-план: воркер services/site_finder/sales_tracker.py + поадаптеру на каждого застройщика (brusnika_scraper.py, atomstroy_scraper.py...). Cron 1×в сутки. SPA-сайты — Playwright. SSR — httpx+BS4

Схема БД: apartments(id, jk_id, room_count, area_sqm, floor, section, price_rub, status, last_seen_at) + sales_history(apartment_id, sold_date, sold_price). Materialized views для velocity в радиусе X от точки

Три киллер-фичи из этих данных: A) Velocity Score в Site Finder — дополнительный 4-й критерий скоринга (сколько квартир продаётся/мес в радиусе 1км). B) Smart Unit-Mix в Generative — рекомендация долей 1/2/3-комн на основе реальных продаж в районе. C) Validation финмодели — бенчмарк прогноза выручки против факта по соседним ЖК

Это самый важный data moat: TestFit без РФ-данных, rTIM без site-selection и аналитики спроса. Через 6-12 мес накопления — уникальный источник данных для девелоперов, который не воспроизвести конкурентам быстро

План Discovery: Stage 2a нед.8-9 добавляется воркер sales_tracker параллельно парсеру ПКК. Реализуем 5-7 адаптеров (топ-застройщики Екбурга). К концу месяца 3 имеем 2-3 недели исторических данных

Целевые застройщики Екбурга для Discovery: Атомстройкомплекс, Брусника, ТЭН-Девелопмент, Стройтэк, Прогресс, УГМК-Застройщик, Кортрос, ЛСР-Урал, Forum-group, ПИК (если есть в ЕКБ)

Юридика: шахматки = публичные маркетинговые данные (без авторизации, серая зона мягче ЦИАН). Прецедентов исков застройщиков к парсерам практически нет (им нужны шахматки как воронка маркетинга). Для реестра ПО декларируем как «партнёрские интеграции с открытыми источниками застройщиков»

Анти-риски: 1) Сайт застройщика меняет вёрстку — скрейпер ломается, нужен Sentry alerting. 2) Юр-претензия от крупного застройщика — митигация через «партнёрство возамен аналитики» с топ-3 таргетов. 3) Низкое качество сайтов мелких застройщиков — берём только тех, у кого нормальный веб-интерфейс

Через 6 мес накопления: сезонные коэффициенты, absorption curves по типам квартир, ML-предсказание velocity для нового участка. Для Раунда А это идеальный narrative: «уникальная база продаж новостроек Свердловской обл., которой нет в открытых источниках и у западных игроков»


Дата: 25 апреля 2026, вечер. Обсуждали с Антоном (второй разработчик)

Новые вводные: Антон сказал, что есть доступ ко всем сделкам для анализа. Детали по данным будут в понедельник 27 апреля 2026

Предложение Антона: сначала аналитика по продажам (что строить, какие квартиры, площади), потом всё остальное

Решение (предварительное, ждём детали): НЕ полный pivot. Перестановка порядка этапов: Stage 1 = Sales Analytics (нед 2-5), Stage 2 = Generative со Smart Defaults из аналитики (нед 6-10), Stage 3 = Site Finder с Velocity Score (нед 11-12)

Обоснование не полного pivot: Generative — главный дифференциатор против rTIM/TestFit. Без него конкурируем напрямую с ЕРЗ/ДОМ.РФ (у них 5 лет данных и команда). Аналитика становится мозгом для Generative и Site Finder, а не их заменой

Концепция «3 плитки»: ввод участок + класс жилья → (1) ЧТО СТРОИТЬ (unit-mix с velocity), (2) СКОЛЬКО ПРОСИТЬ (распределение цен м² по классам + тренд), (3) ЗА КАКОЕ ВРЕМЯ ПРОДАСТСЯ (absorption curves по АНАЛОГам). Кнопка «Сгенерировать концепцию» ведёт в Generative

Плюс нового плана: продаваемый артефакт уже после мес 1 (раньше был конец мес 2). Меньше технического риска. Другой ICP (инвестдепартамент вместо архитектуры)

КРИТИЧНО: «доступ ко всем сделкам» — это фундамент или мина. Бывают 4 сценария: 1) Легальный богатый ongoing (ЕРЗ Premium/банк/админ) → полный pivot, аналитика фундамент. 2) Легальный ограниченный → план A + шахматки параллельно для ongoing. 3) Серый канал → НЕ строим бизнес на этом, используем только «для себя». 4) Обещают но не дают → идём по плану шахматок, ждём

6 блоков вопросов к Антону на 27 апреля: Природа канала (что именно за доступ); Поля данных (цена/метраж/комнатность/покупатель?); Покрытие (регионы/история); Свежесть (разовая выгрузка или ongoing); Условия использования в коммерческом продукте; Цена доступа

Что делаем до пн (не останавливаемся, но с осторожностью): SSH-ключ, выбор хостинга (Beget/Timeweb), Stage 0 скелет уже сделан. НЕ начинаем Shapely геометрию или парсер ПКК — приоритет может сместиться

Шахматки застройщиков НЕ отменяются даже если данные Антона полные: 1) Сделки в Росреестре регистрируются с лагом 1-3 месяца. 2) Бронирования и доступность — сделки этого не показывают. 3) Маркетинговая цена vs фактическая различается

Сообщили Кене ответ Антону: направление в точку, но не полный pivot. Ждём детали по данным в пн. Вижу 6 блоков вопросов. От ответов зависит тип плана

Уточнение 25.04.2026 вечер: Антон подтвердил — речь идёт о ДДУ (Договорах Долевого Участия). Это идеальный источник для аналитики: ground truth по продажам новостроек, выше качеством чем шахматки

ДДУ поля стандартно: кадастровый номер квартиры, площадь, цена, дата регистрации, застройщик, ЖК. иногда комнатность/этаж/секция. ПН-поверхность: ПДн покупателя часто включены — обязательное обезличивание до записи в нашу БД (152-ФЗ)

Лаг ДДУ: 30-90 дней от реальной сделки до регистрации в Росреестре. Поэтому шахматки застройщиков НЕ отменяются — они дают 'today snapshot', ДДУ дают 'historical truth'

5 блоков к понедельнику (сужены до ДДУ-специфики): 1) Канал — держатель и договор (DOM.RF API/ЕРЗ Premium/банк/администрация/другое). 2) Поля (все ли обязательные + комнатность и ПДн). 3) Покрытие (регионы/история). 4) Свежесть (разовая/ongoing/real-time и лаг). 5) Условия коммерческого использования

Преимущество ДДУ над шахматками: ground truth по фактической цене (не маркетинговой), историческая глубина, юридически чистый источник (если канал легален), data moat относительно TestFit/rTIM


Источник: фактическая настройка сервера Jolly Yakov в Beget Cloud, 25.04.2026. Сервер 2 vCPU / 4GB RAM / 40GB NVMe / Ubuntu 24.04, IP 46.173.16.127

ШАГ 1: Создание сервера в cp.beget.com/cloud → Создать сервис → VPS → Standard 3+ GHz → 2 ядра/4GB/40GB. ОС: Ubuntu 24.04. Включить публичный IPv4. После создания сервер получает IP, root пароль выслан на email

ШАГ 2: Генерация SSH-ключа локально (если ещё нет). Windows PowerShell: ssh-keygen -t ed25519 -C 'gendesign-deploy' -f $HOME\.ssh\gendesign_deploy. Пароль оставить пустым (Enter Enter) — нужно для автодеплоя

ШАГ 3: Добавление публичного ключа на сервер через панель Beget. При проблемах со SSH (Connection reset, fail2ban) — войти через VNC терминал в браузере и добавить в ~/.ssh/authorized_keys

ШАГ 4: Первый вход по SSH с явным ключом. Команда: ssh -i $HOME\.ssh\gendesign_deploy root@<IP>. При первом коннекте спросит fingerprint — yes

ШАГ 5: На сервере (root): обновить пакеты 'apt update && apt upgrade -y'. Если [-f /var/run/reboot-required] то ребут. Установить hostname/timezone: hostnamectl set-hostname gendesign; timedatectl set-timezone Europe/Moscow

ШАГ 6: Создание non-root пользователя. adduser gendesign (задать сильный пароль, остальное Enter). usermod -aG sudo gendesign. Копия SSH-ключа root→gendesign: mkdir -p /home/gendesign/.ssh && cp ~/.ssh/authorized_keys /home/gendesign/.ssh/ && chown -R gendesign:gendesign /home/gendesign/.ssh && chmod 700 /home/gendesign/.ssh && chmod 600 /home/gendesign/.ssh/authorized_keys

ШАГ 7: Тест первого входа как gendesign. Важно: хранить root-сессию открытой как safety net до конца. В новом окне: ssh -i $HOME\.ssh\gendesign_deploy gendesign@<IP>. Проверка sudo: sudo whoami → root

ШАГ 8 (Windows-специфика): SSH config не создавать через Notepad — он добавляет .txt и сохраняет в UTF-8 с BOM. Правильный способ: PowerShell heredoc | Out-File -Encoding ascii -FilePath $HOME\.ssh\config. Блок Host: HostName <IP>, User gendesign, Port 22, IdentityFile ~/.ssh/gendesign_deploy, IdentitiesOnly yes, ServerAliveInterval 60. Критично включать IdentitiesOnly yes — иначе Windows OpenSSH перебирает все ключи и получает MaxAuthTries reset не дойдя до нужного

ШАГ 9: Отключение root-логина и паролей в SSH. ТОЛЬКО ПОСЛЕ подтверждения gendesign работает и sudo работает. sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak; sudo nano /etc/ssh/sshd_config → PermitRootLogin no, PasswordAuthentication no, PubkeyAuthentication yes. sudo sshd -t для валидации. sudo systemctl reload ssh

ШАГ 10: Критический тест в третьем окне: ssh gendesign → пускает по ключу. В четвёртом: ssh root@<IP> → должен отказать. Старую root-сессию закрываем только после этого

Распространённые грабли: 1) Connection reset при неверном пароле = fail2ban Beget. Обход через VNC. 2) Notepad вместо config пишет config.txt — проверять ls $HOME\.ssh\. 3) Windows OpenSSH без IdentitiesOnly перебирает все ключи. 4) Группа sudo не подхватывается без выхода-входа. 5) При UNPROTECTED PRIVATE KEY FILE использовать icacls /inheritance:r /grant:r '<имя>:(R)'

Статус 25.04.2026 вечер: Шаги 1-7+8 выполнены. gendesign@46.173.16.127 работает по ключу, sudo работает. Осталось: SSH hardening (Шаг 9), UFW firewall, установка Docker, клонирование репо в /opt/gendesign

Статус 25.04.2026 вечер (обновлён): Базовая настройка VPS завершена. gendesign@46.173.16.127 работает по ключу, sudo работает. UFW активен (22/80/443). SSH hardening: PermitRootLogin no, PasswordAuthentication no, PubkeyAuthentication yes через drop-in /etc/ssh/sshd_config.d/00-gendesign-hardening.conf (приоритет 00- перебивает cloud-init defaults). Docker и git установлены. Репо клонировано в /opt/gendesign через deploy key github_deploy. PostgreSQL+PostGIS и Redis работают в докер-компоуз. PostGIS_Version() = 3.4 USE_GEOS=1 USE_PROJ=1 USE_STATS=1

Осталось: GHCR setup (замена YCR на GHCR в deploy.yml + docker-compose.prod.yml), GitHub Secrets, Caddy reverse proxy, домен, первый автодеплой backend+frontend

ВЕХА 25.04.2026 вечер: Первый успешный автодеплой. GitHub Actions воркфлоу deploy.yml прошёл полный цикл: build обоих образов (backend ~2.5мин, frontend ~1мин) → push в GHCR (ghcr.io/lekss361/gendesign-backend, gendesign-frontend, приватные) → SSH на сервер → docker compose pull (с PAT-авторизацией) → up -d. /health отвечает {status:ok, environment:prod}

GHCR пакеты остаются ПРИВАТНЫМИ (решение пользователя для защиты алгоритмов). Сервер авторизуется в GHCR через PAT с read:packages, сохранён в ~/.docker/config.json. PAT с длительным сроком или без срока

Исправлены во время деплоя: backend Dockerfile (убрал невалидный conditional COPY для alembic, перешли на uv sync без --frozen до генерации lockfile); frontend package.json (react-leaflet 4→5 для совместимости с React 19); frontend Dockerfile (npm install --legacy-peer-deps вместо npm ci, пока нет lockfile); frontend/public/.gitkeep для Next.js standalone build

Статус инфраструктуры к 25.04.2026 19:00: VPS Beget работает (Москва, 2/4/40 NVMe). UFW + SSH hardening + non-root user. Docker compose prod поднят с 5 сервисами (postgres+redis+backend+frontend+caddy). GitHub Actions автодеплой работает на push в main. /health публичен внутри VM (127.0.0.1:8000)

Осталось до «infra-ready»: домен, Caddy TLS с Let's Encrypt на этот домен, регулярные pg_dump в Object Storage, frontend NEXT_PUBLIC_API_BASE_URL на реальный домен (сейчас пустая). И дальше — Stage 1 разработки по выбранному PlanA_AnalyticsFirst_Apr25 (после понедельника с Антоном по ДДУ-данным)


Тестовая запись, дата 25.04.2026 поздний вечер

Цель: проверить, что после пересоздания хард-линка записи MCP попадают в репо-файл memory/memory-gendesign.jsonl

Ожидаемый результат: размер репо-файла увеличится, git status покажет modified

Наблюдение: предыдущий хард-линк разорвался (LinkType был null, синхронизация репо-файла с MCP-папкой прекратилась). Репо-файл был 16550 байт, источник 43957 байт

Если тест пройдёт (синхронизация восстановлена) — рабочий цикл из README снова валиден. Если не пройдёт — нужен sync-memory.ps1 скрипт или альтернатива


Домен: gendsgn.ru, регистрация в Beget, срок до 26.04.2027

Стоимость: 199 ₽ первый год, 420 ₽/год продление. Сравнение из браузера 26.04.2026: Reg.ru 169₽ первый год + ~890₽ продление; Timeweb 200/399; nic.ru 747₽ регистрация (премиум)

Решение: Beget — потому что (1) хостинг VPS уже там, единая админка и единая платежка для бухгалтерии; (2) продление 420₽ — лучшее на рынке; (3) free DNS включён

DNS-серверы: ns1.beget.com, ns2.beget.com (плюс ns1.beget.pro, ns2.beget.pro как backup)

A-записи прописаны 26.04.2026: @ (apex) и www → 46.173.16.127. Beget NS отдают корректно (проверено nslookup gendsgn.ru ns1.beget.com → 46.173.16.127). Публичные резолверы (8.8.8.8, 1.1.1.1) на 26.04 ещё NXDOMAIN — пропагация .ru registry → public DNS, ожидаемо 30 мин - 4 часа

Caddyfile обновлён под gendsgn.ru: основной site block с auto-TLS Let's Encrypt, www → 301 redirect на apex, :80 fallback для IP-доступа сохранён. Закоммичен 68e95aa, запушен в main. На VM не применён (старый deploy.yml не делает git pull)

deploy.yml будет дополнен `git fetch + reset --hard origin/main` + `caddy reload --config /etc/caddy/Caddyfile` после `up -d`. Закоммитим и запушим когда DNS пропагируется. Это финальный шаг для HTTPS

Важное правило отрасли: с 1 сентября 2026 владелец .ru-домена обязан иметь подтверждённую учётку ЕСИА (Госуслуги) — иначе домен не продлят. Для ИП/ООО — через ЭДО/СБИС. Касается всех регистраторов одинаково. К моменту продления (26.04.2027) ООО уже должно быть зарегистрировано — учёт без проблем


Sentry организация: qqq (qqq-5y.sentry.io), free tier (5К ошибок + 10К транзакций / мес)

Sentry проект: gendesign-backend, платформа FastAPI, регион Frankfurt (ingest.de.sentry.io)

DSN сохранён в /opt/gendesign/backend/.env как SENTRY_DSN. На локальной машине — не нужен (Sentry init в backend/app/main.py условный — отключён если DSN пустой)

Конфиг init: sentry_sdk.init(dsn=settings.sentry_dsn, environment=settings.environment, traces_sample_rate=0.1) — 10% запросов трейсятся для performance

Алерты: «high priority» по умолчанию + email на alexandro361@gmail.com

Тестовое событие отправлено и получено 26.04.2026 — event_id 67f05bdd59234a608a828fa81f72ded5. Sentry интеграция работает на проде

Важная операционная заметка: docker compose restart НЕ перечитывает env_file. После правки backend/.env нужно `docker compose -f docker-compose.prod.yml up -d --force-recreate --no-deps backend`. Применимо к любым env-изменениям, не только Sentry

DSN — не критичный секрет (в frontend SDK всегда зашит публично в JS-бандл). Держим в .env, не в репе. Ротация при необходимости через Sentry → Settings → Client Keys (DSN) → New Key


Подготовлен пакет инфраструктурных правок (в working tree, не закоммичено): Alembic baseline + TIGER cleanup + pre-commit + pg_dump backups + Makefile targets

Alembic: создан backend/alembic.ini + backend/alembic/env.py (импорт Base из app.core.db, моделей через app.models.*) + script.py.mako + versions/.gitkeep. Первая реальная миграция — в Stage 2a, когда Parcel-модель будет финализирована. Сейчас versions/ намеренно пуст

TIGER cleanup: backend/db/init/99_drop_unused_extensions.sql дропает postgis_tiger_geocoder + postgis_topology + fuzzystrmatch на свежем postgres-volume (через bind-mount ./backend/db/init:/docker-entrypoint-initdb.d:ro в обоих compose-файлах). Срабатывает только при первой инициализации пустого volume

Pre-commit: .pre-commit-config.yaml в корне (trailing-whitespace, end-of-file-fixer, ruff lint+format на backend/, prettier на frontend/, detect-private-key, check-yaml/toml). Pre-commit добавлен в dev-deps backend/pyproject.toml. Локально — `python -m pre_commit install` или `make pre-commit-install`

pg_dump: ops/backup.sh — cron-скрипт с опциональной выгрузкой в S3. Ретенция 7 дней локально. ops/restore.sh с защитой RESTORE_CONFIRM=yes

Makefile: добавлены `make migration NAME=...` и `make pre-commit-install`. `make migrate` использует `alembic` напрямую (uv нет в production-образе)

backend/Dockerfile: COPY alembic.ini + COPY alembic в обе стадии (builder и runner)

S3 для бэкапов: пока не настроено. Когда настроим Selectel или Yandex Object Storage, env-конфиг — /etc/default/gendesign-backup на VM, cron — `30 3 * * * /usr/local/bin/gendesign-backup`


Прод полностью пересоздан с нуля для чистого состояния. Не было критичных данных — БД содержала только postgis-defaults

Команды на VM: `docker compose down -v` → `docker rmi` GHCR-образов и базовых (caddy:2, postgis/postgis:16-3.4, redis:7-alpine) → `git pull --ff-only` (Caddyfile, compose) → `docker system prune -af --volumes`

Re-deploy через GitHub Actions Deploy → все 5 контейнеров поднялись с image-тегом 08a63f6 (главный коммит на момент wipe)

Состояние после re-deploy: postgres healthy, redis healthy (новый healthcheck), backend healthy (фикс curl-healthcheck в multi-stage Dockerfile), frontend up, caddy up. PostGIS 3.4 USE_GEOS=1 USE_PROJ=1

TIGER-мусор вернулся (как ожидалось) при свежей инициализации postgis-image. Будет автоматически удаляться при следующих wipe-ах когда применим OpsBundle_Apr26 (init-скрипт 99_drop_unused_extensions.sql)


Серия Docker-фиксов задеплоена в main: e22aeb9 (multi-stage + npm ci + healthcheck + same-origin API), d0909e6 (ruff fixes), 08a63f6 (mypy fixes), 68e95aa (real domain Caddyfile)

backend/Dockerfile: переписан на multi-stage (builder с build-essential + libgdal-dev + uv sync; runner только с runtime-либами libpq5, libgdal36, libproj25, libgeos-c1t64, libcairo2, libpango*, curl). Финальный образ 1.44 GB вместо ~2 GB. Запускается под non-root пользователем `app` (uid 1000)

backend curl healthcheck в docker-compose.prod.yml теперь работает (до этого был баг — curl не был установлен в slim-образе)

frontend/Dockerfile: переключён на `npm ci --legacy-peer-deps` вместо `npm install`. Запускается под `node` (uid 1000). package-lock.json закоммичен

docker-compose.prod.yml + dev: убран dead NEXT_PUBLIC_API_BASE_URL (Next.js bakes NEXT_PUBLIC_* на build-time, runtime override no-op). Frontend ходит на same-origin /api/* — в проде через Caddy, в dev через Next.js rewrites (BACKEND_URL env)

Caddyfile: исправлен баг — handle_path /api/* стрипал префикс /api, FastAPI router на /api/v1/* возвращал 404. Заменено на handle /api/*

backend/uv.lock сгенерирован (через docker run python:3.12-slim + pip install uv && uv lock). Дальнейшие билды детерминированы: `uv sync --frozen --no-dev`

Ruff config: ignore=['RUF001','RUF002','RUF003'] — проект русскоязычный, кириллица в комментариях/docstring (МСК-66 etc.) — норма, иначе постоянно ругается


Прод официально живой на HTTPS: https://gendsgn.ru/ возвращает 200, https://gendsgn.ru/health → {"status":"ok","environment":"prod"}, https://www.gendsgn.ru/ → 301 на apex

Цепочка: ЕСИА-верификация в Beget → реестр .ru обновился → DNS пропагировался к 8.8.8.8/1.1.1.1 → push deploy.yml с git-pull+caddy-reload не делался (юзер сделал руками на VM) → пришлось вычищать caddy_data volume чтобы сбросить старый retry-state на gendesign.example.ru и Let's Encrypt staging fallback → Caddy перезагрузился чисто → cert получен с production Let's Encrypt

Урок: при wipe `down -v` мы убрали весь caddy volume включая ACME-state. Если бы оставили — Caddy продолжал бы фоновые retry-задачи на старый плейсхолдер gendesign.example.ru, и accumulated failures могли бы триггернуть staging fallback. На будущее: `caddy reload` не сбрасывает retry queue — для чистого старта нужен `restart` или volume-wipe

GitHub-issues #1 (ЕСИА) и #2 (push deploy.yml) можно закрывать как done

Стек живет: HTTP/2 + HTTP/3 (alt-svc), Caddy reverse-proxy фронт+бэк, FastAPI корректно отвечает через /api/* префикс (handle вместо handle_path сработал)


Дата: 26.04.2026. Глубокий анализ источников данных для GenDesign — проверено через debug-браузер на наш.дом.рф

🥇 ГЛАВНАЯ НАХОДКА: ДОМ.РФ имеет ОТКРЫТЫЕ JSON API без аутентификации. Это меняет всё для Plan A и Site Finder

ДОМ.РФ Аналитика API (`naash.dom.rf/portal-analytics/api/`): /dictionaries/regions, /dictionaries/developers, /dashboard/by-room-count, /dashboard/by-flat-area, /dashboard/by-developer, /dashboard/by-region. Возвращают JSON: по каждому региону id, flatCount, area, и details — разбивка по комнатности (ONE/TWO/THREE/FOUR с площадями и %). Базовый URL хоста: https://xn--80az8a.xn--d1aqf.xn--p1ai (он же наш.дом.рф). Без auth, accept: application/json. Свердл. обл. id=66, flatCount=115205, area=5.67M м²

ДОМ.РФ Каталог квартир API (`/сервисы/api/kn/`): /flats/map?latitudePoint1=...&latitudePoint2=...&longitudePoint1=...&longitudePoint2=...&flatStatus=free,booked возвращает per-ЖК записи {objId, latitude, longitude, priceMin, objStatus}. /flats/filters даёт диапазоны фильтров. Auth: header `Authorization: Basic MTpqd2U=` (= base64('1:qwe')) — хардкод в фронте, действующий ключ. По Свердл. обл. видно 24 441 квартир в продаже

ДОМ.РФ доступные на per-flat фильтры (которые присутствуют в JSON): кол-во комнат (студия/1/2/3/4+), год сдачи (Сдан/2026/2027/2028+), цена (от 2.6М до 4.8 млрд), площадь (16-1001 м²), этаж (1-68), цена м² (82К-7.2М), отделка (без/черновая/предчистовая/чистовая/под ключ), класс (типовой/комфорт/бизнес/элитный), материал стен (блоки/кирпич/панель/монолит/монолит-кирпич), тип (жилое/нежилое), эскроу, безбарьерная среда, благоустройство, энергоэффективность, наличие апартаментов

ДОМ.РФ покрытие России: 2.4 млн квартир в строящихся домах, 118.7 млн м². По регионам ТОП-20 включает Свердл.обл (4-е место, 5.67М м²). По девелоперам ТОП-15: Самолет, ПИК, DOGMA, ТОЧНО, ФСК, Брусника, Setl Group, ЛСР и др.

ДОМ.РФ распределение площадей квартир в РФ: 0-25м²: 6%, 25-35м²: 17%, 35-45м²: 30% (мода), 45-55м²: 14%, 55-70м²: 20%, 70-85м²: 8%, 85-100м²: 3%, более 100м²: 2%. В среднем около 49 м² (118.7М/2.4М). Это ВАЖНЕЙШИЙ benchmark для smart unit-mix Plan A

ДОМ.РФ распределение по комнатности: 1-комн 54% (1.31М), 2-комн 32% (0.78М), 3-комн 12% (0.30М), 4+комн 1% (33К)

ДОМ.РФ есть еще API endpoints: Единый реестр застройщиков, Единый реестр МЖК, Единый реестр ЖСК, Единый реестр проблемных объектов, Реализация квартир в строящихся домах (динамика продаж!), Распроданность и стройготовность (что-то вроде velocity!). Все по naash.dom.rf/аналитика/*. Велоситит и распроданность — могут быть прокси для нашего sales_tracker без необходимости парсить шахматки

🥈 ВЫВОД: для Plan A не нужно ждать ДДУ-данные от Антона. ДОМ.РФ открыто отдает агрегаты + ground truth по объектам. Это юридически чистый канал ('через API ДОМ.РФ' можно официально декларировать в реестре ПО)

Overpass API (OpenStreetMap, https://overpass-api.de/api/interpreter): бесплатно, без авторизации. Синтаксис Overpass QL: `[out:json][timeout:25]; node["amenity"="school"](56.7,60.5,56.9,60.7); out body;` — все школы в bbox. Поддерживает radius `node(around:1000)["amenity"="hospital"]`. Релевантные tags для нас: amenity=school|hospital|clinic|kindergarten|university, public_transport=station+station=subway|tram|bus, shop=mall|supermarket, leisure=park|playground, highway=primary|secondary

Overpass rate limit: ~5 запросов/мин на IP. Для production — поднять свой mirror через Docker (overpass-api/docker-overpass-api), либо использовать кеш Redis (TTL 24-72 ч, POI редко меняются)

Росстат fedstat.ru (id=31452): 'Средняя цена 1 кв.м общей площади квартир на рынке жилья' — квартально по регионам РФ, разбивка первичка/вторичка, по типам квартир. Данные с 2000 по 2025. Скачивание SDMX/возможно CSV/XML. НЕТ публичного API. Подход: разовая выгрузка → Excel → загрузить в нашу БД, обновлять раз в квартал вручную

Минстрой РФ (minstroyrf.gov.ru): норматив средней рыночной стоимости 1 м² для расчета субсидий. Публикуется приказом Минстроя ежеквартально по всем регионам. Для Свердл. обл. ~85-95 тыс ₽/м² на 2025 год. Доступ: PDF приказа на сайте Минстроя, копия в КонсультантПлюс. Использовать как baseline для нашей финмодели

Главгосэкспертиза НЦС (gge.ru, был 404 на /ncs/, реальный URL на момент проверки изменился): нормативы цены строительства 1 м² по типам зданий + регионам. Используется для расчета бюджетов госзаказа. Публикуется приказом Минстроя ежегодно. Для частных девелоперов — сравнительный baseline 'минимальная себестоимость'. Найти актуальный URL через минстроя/КонсультантПлюс

ЕРЗ.РФ (erzrf.ru): главный конкурент по аналитике в РФ, премиум-доступ. Полные данные: реестр застройщиков, рейтинги ЖК, статистика продаж, вакантность. Цена доступа на сайте не раскрыта — нужно запрашивать. Industry knowledge: ~50-100 тыс ₽/год за подписку на регион, ~500 тыс ₽/год за всю РФ. У них есть API B2B (под NDA). Использовать как 'договорённости в проработке' для инвесторов Раунда А, реально подписываться когда будет budget

СберИндекс (sberindex.ru, не открылся через WebFetch — 'unable to verify the first certificate', попробовать через браузер позже): бесплатные агрегаты Сбера по экономике РФ, включая жилье. Покрытие хорошее, обновление часто. Использовать для cross-validation с ДОМ.РФ + Росстат

ДомКлик (domclick.ru): listings первички и вторички + ИПОТЕЧНАЯ статистика. Открытый каталог с ценами/площадями. Анти-бот защита есть, но не очень жёсткая. Публичный sitemap.xml. Подход: спарсить раз в неделю свердл.обл (~50 тыс листингов), сохранить в БД с history. Для cross-check ДОМ.РФ цен

ЦИАН (cian.ru): крупнейший аггрегатор РФ. Cloudflare защита + rate limit. Парсить рискованно (юридически серая зона + блокировки). Готовые либы: cianparser, cianscraper на GitHub. Использовать ОЧЕНЬ ограниченно (200-500 листингов на район для калибровки), не как основной источник

Авито Недвижимость (avito.ru): аналогично ЦИАНу — антибот, Cloudflare. Есть платный B2B API (через avito_business — недешево). Для Discovery — пропускаем

Яндекс.Недвижимость (realty.ya.ru): listings, иногда XML feed для риелторских CRM. Есть Yandex Realty API (документированный, но enterprise). Для Discovery — пропускаем

Шахматки застройщиков (Брусника, Атомстройкомплекс и т.д.): по факту самый ground-truth источник для today snapshot. SPA-сайты — Playwright. SSR — httpx+BS4. План в Stage 2a/sales_tracker уже описан в SalesTracking_Strategy_Apr25. ОДНАКО — теперь когда у нас есть 'Реализация квартир' из ДОМ.РФ, шахматки могут быть downgrade-нуты до 'дополнительной валидации'

Другие источники (mention only): ОКТМО (для region IDs), ФИАС (адреса), Росреестр ПКК (только границы участков, без ДДУ), ДомРФ.Bank (ипотечные ставки — отдельный поток для финмодели), ЖКХ.МО.РФ (управляющие компании — для оценки операционных расходов). Всё в реестре российских данных.

ИТОГ — приоритеты по источникам для Discovery MVP (от 1 = критично до 5 = можно отложить):

1) ДОМ.РФ portal-analytics + api/kn/flats — бесплатно, открыто, ground truth, ВСЁ нужное для Plan A и Site Finder. Базовый источник

2) Overpass API (OSM) — бесплатно, для POI вокруг участков. Site Finder скоринг

3) Росстат fedstat.ru — квартальный baseline цен, разовая выгрузка → БД. Финмодель + cross-validation

4) Минстрой норматив + НЦС — для реалистичной себестоимости в финмодели

5) Шахматки 5-7 застройщиков Екбурга — дополнительная свежесть к ДОМ.РФ. Stage 2a опционально

Приоритет 1 ('вынес' ДДУ-данные): ВСЁ можно собрать сегодня вечером без Антона. Это разбивает блокировку #10 — даже если канал ДДУ серый/нет — Plan A 'analytics first' технически выполним на ДОМ.РФ data

Метрики, которые мы можем считать прямо из ДОМ.РФ для Plan A '3 плитки':

ПЛИТКА 1 — ЧТО СТРОИТЬ: для участка → район → ID региона → /portal-analytics/api/dashboard/by-room-count?regionId=X → распределение комнатности что строится. Дополнительно /dashboard/by-flat-area по тому же региону → распределение площадей. Smart unit-mix готов

ПЛИТКА 2 — ПО КАКОЙ ЦЕНЕ: для координат (lat,lon) → запрос /api/kn/flats/map в bbox 5km → собрать все priceMin → median + p10/p90 → диапазон цен в районе. Cross-check с Росстатом по региону

ПЛИТКА 3 — ЗА КАКОЕ ВРЕМЯ: /аналитика/реализация_строящихся_квартир + /распроданность-стройготовность по региону → absorption curves по комнатностям. Если бы у Антона были ДДУ — было бы точнее, но и без них есть прокси-сигнал

Юридическая безопасность для реестра ПО: всё что используем — ОФИЦИАЛЬНО открытые источники (ДОМ.РФ, Росстат, Минстрой, OSM). Никакого скрейпинга в обязательных каналах. Шахматки и ЦИАН — опциональные, помечаем как 'партнерские интеграции в проработке'

Implementation effort estimates (часы разработчика):

ДОМ.РФ analytics API клиент + кеш Redis: 4-6 часов

ДОМ.РФ flats/map per-объект клиент с пагинацией bbox: 6-8 часов

Overpass клиент + tag mapping для POI: 3-4 часа

Росстат разовая выгрузка + ETL в БД: 2-3 часа

Минстрой парсинг приказа PDF → таблица: 2-3 часа

СУММАРНО: 17-24 часа на полный data layer без Антона


Дата: 26.04.2026. Официальная страница интеграции ДОМ.РФ ЕИСЖС: https://наш.дом.рф/интеграция

⚠ ЮРИДИЧЕСКИЙ СТАТУС API СЖС: предназначено ТОЛЬКО ДЛЯ УПОЛНОМОЧЕННЫХ БАНКОВ согласно Постановлению Правительства РФ № 697 от 18.06.2018. Напрямую подключиться НЕ МОЖЕМ — мы не банк. Но публичный фронт-API наш.дом.рф (то что мы выяснили) легален и доступен всем.

5 различных API в составе ЕИСЖС (вкладки на странице /интеграция):

1) API СЖС (Сведения о Жилищном Строительстве) — главное API для банков, даёт данные по застройщикам, ГК, ЖК, объектам строительства. Это та же информация что на наш.дом.рф в публичной форме.

2) API Уведомления ОПО — опасные производственные объекты. Не наш.

3) API Агрегатор ПФ — Проектное Финансирование, инфо о договорах эскроу. Для банков.

4) API НСИ — Нормативно-Справочная Информация, классификаторы. Справочники.

5) Сервисы СМЭВ — Межведомственное Электронное Взаимодействие. Для госорганов.

Официальные документы на скачивание (все DOCX/PDF публичные):

Соглашение об информационном взаимодействии v5.1 (08.02.2026): /site/binaries/content/assets/domrf/support/developer/agreement/соглашение-об-информационном-взаимодействии.-v5.1..docx — юридический договор присоединения по ст. 428 ГК РФ.

Презентация API СЖС v2 (03.12.2020): /site/binaries/content/assets/domrf/support/developer/presentation/еисжс-апи-сжс_v2.pdf — PDF обзор возможностей.

Спецификация API СЖС v1.3.0 (31.10.2020): /site/binaries/content/assets/domrf/support/developer/specification/api-сжс.-спецификация-api-v1.3.0.docx — полный OpenAPI-style документ с методами, форматами и ограничениями. Это бы хорошо разобрать для выявления всех полей и эндпоинтов, но спецификация для банковского API — форматы могут отличаться от нашего фронт-API.

Регламент информационного взаимодействия v1.5 (06.10.2020) + в тексте страницы упоминается v1.4: /site/binaries/content/assets/domrf/support/developer/reglament/еисжс-регламент-информационного-взаимодействия-участников-v1_5.docx (и v1_4.docx)

На странице есть кнопка 'ЗАГРУЗИТЬ ЕЩЕ' — вероятно в полном списке есть WSDL/OpenAPI в машинно-читаемом формате.

Официальный 7-шаговый flow подключения к API СЖС (для банков):

1. Ознакомление с Регламентом информационного взаимодействия

2. Запрос на nash@domrf.ru → назначается менеджер ЕИСЖС

3. Подписать 2 экземпляра Соглашения и ОТПРАВИТЬ физической почтой в ПАО ДОМ.РФ по адресу: 125009, г. Москва, Воздвиженка, д. 10 (с пометкой 'в ЕИСЖС')

4. Настройка информационной системы на своей стороне

5. Заявка на подключение к интеграционной (тестовой) среде → физпочта

6. Тестирование + протокол функционального тестирования

7. Заявка на промышленную среду → физпочта. Всего процесс занимает от 1 до 3 месяцев.

КОНТАКТЫ: nash@domrf.ru, 8-800-755-55-05, ПАО ДОМ.РФ, 125009 Москва, Воздвиженка 10.

СТРАТЕГИЧЕСКИЙ вывод для GenDesign:

Нам самим с API СЖС официально подключиться НЕЛЬЗЯ — по ПП №697 это только для уполномоченных кредитных организаций с эскроу-счетами. Имеет смысл искать банка-партнёра на этапе Раунд А или позже — бы их вход давал нам связку с банковским API. Банк ДОМ.РФ или Сбер — логичные partner candidates.

Но в Discovery не нужно — публичный фронт-API наш.дом.рф (описан в DomRF_API_Snapshot_Apr26 и связанных) даёт 99% того же что B2B-API. Разница: официальный API имеет SLA и stable contracts, фронт-API может измениться без уведомления.

Для реестра ПО: в заявке используем формулировку 'интеграция с открытыми данными ЕИСЖС ДОМ.РФ' — описываем публичные эндпоинты. Не 'Подключение к API СЖС' — это юридически неправда.


Дата: 26.04.2026. Вкладка 10/12: Мониторинг ипотечных ставок

URL: /аналитика/ставки_предложений_по_ипотеке

Endpoints (все GET, ответ в формате {data: [...]}):

/mortgage-rates/reports — список 6 типов отчетов (id 1-6, name, date)

/mortgage-rates/reports/calendar — календарь доступных срезов (даты + перечень отчетов на каждую дату)

/mortgage-rates/reports/{reportId}/values/{columnId} — значения по банкам для колонки

Типы отчетов (reportId): 1=Рыночные продукты (квартира), 2=С господдержкой, 3=ИЖС, 4=Первичный рынок, 5=Вторичный рынок, 6=Рефинансирование

Колонки (columnId, для отчета типа 1): 1=Первичный рынок, 2=Вторичный, 3=Рефинансирование

Поля респонса /values/: bankId, value (ставка %), valueDelta, valueComment (текстовая приписка про скидки), needApprove

Пример данных на 19-04-2026: Сбербанк 20.2% (первичка), ВТБ 19.9%, с господдержкой 6%

Средние по рынку: Первичка 19.9%, Вторичка 19.59%, Рефинансирование 18.81%

Страница SSR-бакена — все данные в __NEXT_DATA__.props.initialState.mortgageOffers (reports, filters, tableData, detailedTableData, pdf)

Для GenDesign: полезно для финмодели — вход для расчета платежеспособности по концепту


Дата: 26.04.2026. Вкладка 11/12: Статистика по рынку ипотеки

URL: /аналитика/ипотечное_кредитование

Базовый API: /portal-analytics/api/mortgage/* + общие /base/* /comparison/* /building/*

/portal-analytics/api/mortgage/reporting_periods (GET) — доступные периоды по ипотеке

/portal-analytics/api/mortgage/dashboard/general (POST) — ОБЩИЙ дэшборд с фильтрами в body

/portal-analytics/api/mortgage/dashboard/details (POST) — детальный дэшборд

Справочники (те же что в вкладке 9 'Ввод жилья'):

/portal-analytics/api/base/dictionaries/credit_types — виды кредитов (полезный для фильтров: ипотека под жилое/ИЖС/рефин.)

/portal-analytics/api/comparison/regions (POST) — кросс-региональное сравнение

ВАЖНО: dashboard/general и dashboard/details — POST с JSON в body. Формат body не снят на этом шаге (нужно поимать request body через list_network_requests при необходимости)

Парная вкладка 9 (Ввод жилья) использует /building/* + те же справочники. Это один бэкенд-модуль с разными dashboard'ами

Для GenDesign: данные по выданным ипотечным кредитам (объемы, кол-во, регионы) — полезно как прокси платежеспособности рынка


Дата: 26.04.2026. Вкладка 12/12: Статистические ряды жилищного строительства

URL: /аналитика/статистические_ряды

Это НЕ интерактивная вкладка, а КАТАЛОГ ссылок на XLSX-файлы со статистикой

Серверный endpoint (для SSR Next.js): GET /api/document/pages/xlsdashboard — вертает 401 Unauthorized для Basic MTpqd2U= (требует server-side токен, не доступен с клиента)

Структура ответа (из SSR-bundle): {items:{'domrf:blokItem':[...]}} — CMS-формат Domrf с титулами, группами и ссылками на файлы

Практически данные берутся из __NEXT_DATA__.props.initialState.housingData.list — иерархия: блоки → группы → файлы (text, link, date)

Прямая ссылка на XLSX (публичная, без auth): /site/binaries/content/assets/domrf/xlsdashboard/{filename}.xlsx

Примеры XLSX:

01_01_stockvariablesexsales.xlsx — Сведения о МКД по 214-ФЗ (РФ, регионы, ГК, НП, план. стоимость)

01_01_stockvariableskrt.xlsx — МКД по КРТ (комплексное развитие территорий)

01_02_flowvariables.xlsx — ПРОЕКТНЫЕ ДЕКЛАРАЦИИ (размещенные за период)

+ ДДУ (договоры участия в долевом строительстве) сводные

Дата всех файлов: 01.04.2026 (обновляются 1-го и 25-го числа)

Для GenDesign: ЭТО КЛАД — все официальные сводки ДОМ.РФ в XLSX-формате без лимитов, отличный способ получить базовые ряды без парсинга web-вызовов. Скачивать раз в месяц скриптом

Полный список XLSX-категорий можно вывести из __NEXT_DATA__.housingData (при SSR рендере страницы) — SSR-рендер + grep линков из разметки = список всех файлов


Дата: 26.04.2026. Общая архитектура фронт-API наш.дом.рф для раздела АНАЛИТИКА.

Сайт — Next.js SSR. Данные подгружаются в __NEXT_DATA__ на SSR-этапе с бэкенда. На клиенте XHR файрит только при взаимодействии с фильтрами.

Используются 3 разных базовых пути:

(1) /portal-analytics/api/* — ОСНОВНОЙ публичный бэкенд, без авторизации. Основные аналитические вызовы.

(2) /аналитика/api/* — прокси через Next.js SSR-сервер к внутреннему API. Без авторизации. Для escrow, ddu, project finance, rpp, mortgage-rates, dictionary.

(3) /api/* — внутренний сервер (Express, x-powered-by). 401 без токена. Не Basic MTpqd2U= (требует server-side токен). Для /document/pages/* и реестров.

rate-limit эмпирически ~5 RPS → 502/429 при превышении

Cache-Control: max-age=900 (15 мин) — нет смысла чаще 15 мин ходить за одним и тем же ресурсом

User-Agent: ставить осмысленный, напр. 'GenDesign-DataSync/0.1 (https://gendsgn.ru)'

Юр. статус: парсинг публичного портала. Официальные спеки СЖС/НСИ/УОПО/АПФ совсем другой канал (OAuth2 + JWT для банков) — см. DomRF_OfficialSpecs_vs_FrontAPI_Apr26.


Вкладка 1/12: Основные показатели жилищного строительства.

URL: /аналитика/показатели_жилищного_строительства

Redux slice: housingConstructionIndicators. SSR-бакеные (клиент не файрит XHR при фильтрах)

Параметры: regionId, devId, repYear, repMonth

Поля респонса (из __NEXT_DATA__): repYear, repMonth, type, subject (region code), subjectDesc, devCnt, rnsCnt, rpdCnt, objCnt, generalSquareSum, livingSquareSum, livingElemSum, escrowDevCnt/RnsCnt/RpdCnt/ObjCnt, escrowGeneralSquareSum, escrowLivingSquareSum, escrowLivingElemSum, zosgDevCnt/etc (эскроу/компфонд)

Этот endpoint = ПЛИТКА 1 для Plan A (что строить)


Вкладка 2/12: Запуски и вводы МКД по 214-ФЗ.

URL: /аналитика/запуски-и-вводы

Суффиксы: 'app' = запуски/РНС (applications на строительство), 'rnv' = вводы (разрешение на ввод)

/launch/filters?repYear=2025 — доступные фильтры за год

/launch/obj-class/table?calculationType=SQUARE&repYear=2025 — распределение по классу (Типовой/Комфорт/Бизнес/Элитный)

/launch/developers/{app|rnv}?calculationType=SQUARE&repYear=2025&size=15 — рейтинг девелоперов

/launch/federal-districts/{app|rnv} — рейтинг ФО

/launch/regions/{app|rnv} — рейтинг регионов

/launch/areas/{app|rnv} — рейтинг населённых пунктов

Параметры: calculationType (SQUARE | HOUSES | FLATS), repYear, period (YEAR|MONTH), size (для рейтингов, дефолт 15)

+ /аналитика/api/dictionary/glossary — словарь терминов


Вкладка 3/12: Регионы жилищного строительства / Долевое строительство и проектное финансирование.

URL: /аналитика/долевое_строительство

Базовый путь: /аналитика/api/project/finance/*

/project/finance/allDate — все доступные даты срезов

/project/finance/lastDate — последняя доступная дата

/project/finance/dashboard?dateDay=DD-MM-YYYY — полный dashboard на дату (проектное финансирование с разбивкой по регионам)

Формат даты: DD-MM-YYYY (НЕ ISO и НЕ YYYY-MM-DD!)


Вкладка 4/12: Девелоперы жилищного строительства (рейтинг ГК).

URL: /аналитика/жилищное_строительство

Redux slice: dashboard. Полностью SSR — клиентских XHR не было выявлено при фильтрах.

/portal-analytics/api/dashboard/by-developer — рейтинг девелоперов (основной)

/portal-analytics/api/dictionaries/developers — справочник 2734 девелоперов (id, name)

Id-формат: '{groupId}_{devId}' напр. '9333_0' (ГК) или '0_14583' (застройщик)


Вкладка 5/12: Рейтинг банков со счетами эскроу.

URL: /аналитика/эскроу

Базовый путь: /аналитика/api/escrow/*

/escrow/allDate — лист доступных дат срезов

/escrow/lastDate — последняя дата (из bundle, видимы в коде но не вызван на SSR)

/escrow?date=01-04-2026&withGroups=true&sort=guarantyEscrowRnsCnt:desc&subjectTypes=rf_bank&limit=9999 — рейтинг банков

Параметры: date (DD-MM-YYYY), withGroups (true/false), sort (поле:asc|desc), subjectTypes (rf_bank), limit

Сорты: guarantyEscrowRnsCnt, escrowDeposits, projectFinanceVolume

Полезно для finmodel в GenDesign — выбор банка-партнёра


Вкладка 6/12: Реализация квартир в строящихся домах.

URL: /аналитика/реализация_строящихся_квартир

Базовый путь: /аналитика/api/rpp/* (rpp = реализация продаж)

/rpp/total?regionCode=66&repMonth=3&repYear=2026 — итоговые показатели

/rpp/housing?regionCode=66&repMonth=3&repYear=2026 — по жилью

/rpp/readyYear?regionCode=66&repMonth=3&repYear=2026 — по годам готовности

/rpp/developer?typeSquare=total&regionCode=66&repMonth=3&repYear=2026 — по девелоперам

/rpp/developer?developerOrder=totalSquare:desc — с сортировкой

Параметры: regionCode (66=Свердл.обл), repMonth, repYear, typeSquare (total|living)

Это КЛЮЧЕВОЙ endpoint для Plan A ПЛИТКИ 3 (velocity продаж)


Вкладка 7/12: Распроданность и стройготовность.

URL: /аналитика/распроданность-стройготовность

/ready-construction/filters?repMonth=3&repYear=2026 — доступные фильтры

/ready-construction/dynamics?dynamicChartType=readyPercChart,soldPercChart,soldReadyPercChart,squareSumChart — динамика по периодам

/ready-construction/index?repMonth=3&repYear=2026 — индексы распроданности/готовности

/ready-construction/ready-year-charts?repMonth=3&repYear=2026 — распределение по годам сдачи

Это второй КЛЮЧЕВОЙ endpoint для velocity-tracking в GenDesign (sold% / ready% / soldReady%)


Вкладка 8/12: Характеристики строящихся квартир (квартирография).

URL: /аналитика/квартирография

Использует те же endpoints что и Tab1 (Показатели):

/portal-analytics/api/dashboard/by-room-count — комнатность (ONE/TWO/THREE/FOUR)

Это КЛЮЧЕВОЙ endpoint для Plan A ПЛИТКИ 1 (smart unit-mix)


Вкладка 9/12: Ввод жилья в эксплуатацию.

URL: /аналитика/ввод_жилья

Базовый путь: /portal-analytics/api/building/* + /portal-analytics/api/base/dictionaries/* + /comparison/regions

/building/reporting_periods (GET) — доступные периоды

/building/reporting_periods_combined (GET) — сводные периоды

/building/summary/data (POST) — сводная дата по вводу (фильтры в body)

/comparison/regions (POST) — сравнение регионов

/base/dictionaries/period_types — типы периодов

/base/dictionaries/region_with_autonomous — регионы включая АО

/base/dictionaries/credit_types — типы кредитов

/base/dictionaries/building_types — типы зданий

Отличие от других: POST-методы с JSON фильтрами в body. Парная с Tab11 (Ипотечное кредитование) — используют один бэкенд-модуль


Критические endpoints ДОМ.РФ для Plan A '3 плитки' в GenDesign Discovery (состояние на 26.04.2026):

ПЛИТКА 1 (ЧТО СТРОИТЬ — smart unit-mix):

/portal-analytics/api/dashboard/by-room-count?regionId=X — распределение по комнатности

/portal-analytics/api/dashboard/by-flat-area?regionId=X — распределение по площади

ПЛИТКА 2 (ПО КАКОЙ ЦЕНЕ):

/сервисы/api/kn/flats?regions=X (per-flat с priceMin / pricePerSquareMeter, см. DomRF_API_KnFlats_Apr26)

ПЛИТКА 3 (ЗА КАКОЕ ВРЕМЯ — velocity):

/portal-analytics/api/ready-construction/* (см. Tab7) — sold%/ready%/soldReady%

/аналитика/api/rpp/* (см. Tab6) — velocity продаж по девелоперам

ОСОБОЕ ОТКРЫТИЕ: ready-construction и rpp — реальные показатели продаж (sold/ready %), без необходимости парсить шахматки застройщиков. Для Plan A absorption этого достаточно

Дополнительные источники:

Tab5 рейтинг банков эскроу — выбор банка-партнёра для finmodel

Tab10 ставки ипотеки — вход для расчета платежеспособности

Tab12 XLSX-каталог — официальные сводки по 214-ФЗ без лимитов (раз в месяц)

Tab2 launch — понимание размера рынка в регионе

Tab3 долевое — проектное финансирование по регионам


Base URL: https://xn--80az8a.xn--d1aqf.xn--p1ai (он же наш.дом.рф)

Используй punycode-форму для прямых HTTP-вызовов из Python/Node — некоторые HTTP-клиенты ломаются на IDN

Backup: https://наш.дом.рф — требует поддержки IDN на стороне клиента

AUTH по группам:

Группа A (no auth): /portal-analytics/api/* и /portal-kn/api/*

Группа B (auth): /сервисы/api/kn/* — header `Authorization: Basic MTpqd2U=` (base64 от '1:qwe'). Технический токен фронта, хардкоден в JS, бессрочен

Группа C (server-side only): /api/* — 401 без токена, Basic MTpqd2U= НЕ подходит. Доступен только с SSR Next.js

Rate limit эмпирически: 5 RPS безопасно, 10+ → 502/429

Cache-Control: max-age=900 (15 мин) на /сервисы/api/kn/*

Без документированных лимитов (в отличие от официальных спек)

При 502 — экспоненциальный backoff: 5s, 30s, 5min. Если 5 мин не помогло — alert в Sentry

Поддержка: nash@domrf.ru, 8-800-755-55-05. B2B энтерпрайз-API: https://наш.дом.рф/сервисы для бизнеса


Группа B бэкенда ДОМ.РФ: /portal-kn/api/* — без авторизации. Ответственна за SEO/portal-сводки и географию.

GET /portal-kn/api/kn/places → {regions:[{regionCd, regionName, cities:[]}]} — регионы без городов

GET /portal-kn/api/kn/places?regionCd=66 → один регион с массивом cities:[{cityCds:[], cityName}]. По Свердл.обл ~30 городов

GET /portal-kn/api/sales/portal?flatStatus=free,booked&regions=66 → плоский array objId всех ЖК с продажами в регионе. По Свердл.обл — 283 ЖК

GET /portal-kn/api/kn/seo/aggregations?objStatus=0&regionCd=66 → {livingObjBlock, nonlivingObjBlock} с агрегатами региона: {objNumber, flatsNumber, devNumber, maxPrice, minPrice, avgPrice, avgMeterPrice, maxSquare, minSquare, minObjReadyDt}

USE CASE: получить список всех ЖК в регионе одним запросом, затем обогащать через /сервисы/api/kn/object?objId={N}


Группа C: GET /сервисы/api/kn/object?objId={N} → полные данные одного ЖК. Auth: Basic MTpqd2U=

Поддерживает фильтр ?devId={devId} вместо objId — получаешь все объекты застройщика

Поля респонса (30+):

hobjId, objId — идентификаторы

developer{devId, devInn, shortName, fullName, groupName, orgForm, companyGroup} — застройщик

rpdRegionCd — код региона ПД

objAddr, shortAddr — адрес и его короткая форма

metro{id, name, line, color, time, isWalk} — ближайшее метро

freeFlatsInfo{priceMin, numberFlats} — свободные квартиры

objCommercNm — коммерческое название ЖК

objFloorMin, objFloorMax — диапазон этажности

objElemLivingCnt — количество жилых элементов

objReady100PercDt — дата 100% готовности

siteStatus, objGuarantyEscrowFlg — статус и флаг эскроу

rpdNum, pdId — номер ПД и ид

buildType — тип строительства

hobjRenderPhotoUrl — attachmentId рендера ЖК (для /api/ext/file)

objPriceAVG — средняя цена

objPublDt — дата публикации

aiDescription — AI-сгенерированное описание ЖК


Группа C: per-flat endpoints. Auth: Basic MTpqd2U=

GET /сервисы/api/kn/flats?regions=66&offset=0&limit=N&flatStatus=free,booked → per-flat данные (17 полей). По Свердл.обл — 24 441 квартира

Поля /flats: id, odsId (objId/sectionNum/flatNum), elemId (UUID), type, number, isStudio, totalArea, livingArea, rooms, status (free/booked/sold), price, pricePerSquareMeter, priceChangeDate, socialMortgage, numberFloors, floor, image{attachmentId, type=layout}, objInfo{hobjId, objCommercNm, objAddr, objTransferPlanDt, objReady100PercDt}

⚠ priceChangeDate и status — ключевые поля для velocity-tracking. Дифф по дням → absorption rate

GET /сервисы/api/kn/flats/map?latitudePoint1=&latitudePoint2=&longitudePoint1=&longitudePoint2=&flatStatus=free,booked&regions=66 → per-ЖК в bbox: {data:{list:[{objId, objStatus, latitude, longitude, priceMin}]}}

Это база для Site Finder в GenDesign: bbox 5км вокруг участка

GET /сервисы/api/kn/flats/filters?regions=66&flatStatus=free,booked → диапазоны всех фильтров: {data:{meta:{list:[{name:'priceMin', values:['2644800']}, {name:'floorMin'}, {name:'areaMin'}, ...]}}}. Для UI sliders

GET /сервисы/api/kn/dataForFilters → диапазон дат публикаций: {data:{min, max}}

USE CASE выкачки: limit=500 в цикле offset+=500. По Свердл.обл — 49 запросов = ~10 секунд при 5 RPS


Группа C: справочники и фасеты /сервисы/api/kn/*. Auth: Basic MTpqd2U=

GET /сервисы/api/kn/meta?place=66&objStatus=0 → доступные значения объектных фильтров: objClass, energyEff [6,7,8,9], reasonProblemId, mechanism (7=эскроу, 6=без эскроу), wall, transferFlg, dduFlg, objTypeCd, objStatus, soldOut

GET /сервисы/api/kn/developers?objStatus=0&place=66&offset=0&limit=N → застройщики в регионе: {data:{list:[{id, devGkId, devInn, name}], total}}. По Свердл.обл 170+

GET /сервисы/api/kn/devGk?place=66&objStatus=0&offset=0&limit=N → группы компаний: {data:{list:[{id, name}], total:58}}. PRINZIP, BAZA Development, Prospect Group и т.д.

GET /сервисы/api/kn/commissioning?place=66&objStatus=0 → диапазон годов сдачи: {data:{minYear:2025, maxYear:2032}}

GET /сервисы/api/kn/metro?place=66&objStatus=0 → метро региона: {data:{list:[{id, name, line, color}]}}. Свердл.обл — Екатеринбургское метро ~9 станций

GET /сервисы/api/kn/hru/groups?place=66 → агрегированные фасеты с count: {data:{objClass:[{id,value}], status:[], type:[], wall:[], ...}}. Для UI левой колонки фильтров


Группа A: /portal-analytics/api/* — без авторизации. Основной бэкенд аналитики.

Базовые справочники:

GET /portal-analytics/api/dictionaries/regions → 9 ФО, каждый с regions[]{id, name}

GET /portal-analytics/api/dictionaries/developers → 2734 девелоперов {id, name}, id-формат 'groupId_devId'

Dashboard endpoints (используются в Tab1, Tab4, Tab8):

GET /portal-analytics/api/dashboard/by-region?regionId=66 → массив 89 объектов на регион

GET /portal-analytics/api/dashboard/by-developer?regionId=66 → массив на застройщика (~750KB без регион-фильтра)

GET /portal-analytics/api/dashboard/by-room-count[?regionId=66] → агрегаты по комнатностям (ONE/TWO/THREE/FOUR)

GET /portal-analytics/api/dashboard/by-flat-area → 8 бакетов: FROM_0_TO_25, FROM_25_TO_35, ..., FROM_100_TO_INFINITY

Структура ответа dashboard/*: {id, flatCount, area, percent, details:[{roomCountType, flatCount, area, percent}]}

Расширенные endpoints (покрыты Tab2/Tab7/Tab9):

/launch/* — см. DomRF_Tab2_LaunchAndCommissioning_Apr26

/ready-construction/* — см. DomRF_Tab7_ReadyConstruction_Apr26

/building/* + /base/dictionaries/* + /comparison/regions — см. DomRF_Tab9_BuildingCommissioning_Apr26

/mortgage/* — см. DomRF_Tab11_MortgageStats_Apr26


Группа D: файлы/картинки

GET /api/ext/file/{attachmentId}?type=png → скачать рендер ЖК или планировку квартиры

attachmentId берется из object.hobjRenderPhotoUrl (см. KnObject) или flat.image.attachmentId (см. KnFlats)

Формат файла обычно PNG, иногда JPEG. Для thumbnail используй attachmentIdSmall

Для GenDesign: можно скачивать ПЛАНИРОВКИ всех квартир с type='layout' — ~24K изображений по Свердл.обл для AI-обучения или показа аналогов


Группа F: Реестры (потенциальные доп. endpoints, не исследованы детально):

/сервисы/единый-реестр-застройщиков — реестр компаний с ОГРН/ИНН/КПП и историей

/сервисы/единый-реестр-мжк — реестр многоквартирных жилых комплексов

/сервисы/единый-реестр-жск — реестр жилищно-строительных кооперативов

/сервисы/единый-реестр-проблемных-объектов — проблемные ЖК для риск-фильтра

TODO: исследовать характерные endpoint-паттерны. Судя по структуре сайта каждый реестр имеет свой endpoint под /сервисы/api/* или /portal-kn/api/*


Справочные enum-ы из API ДОМ.РФ. При работе с endpoints используй именно эти коды.

regionId/regionCd: 66=Свердл.обл, 77=Москва, 50=МО, 78=Питер, 47=ЛО, 16=Татарстан, 23=Краснодар, 61=Ростов, 54=Новосибирск, 72=Тюмень, 2=Башкирия, 25=Приморье, 26=Ставрополь, 91=Крым, 59=Пермь, 36=Воронеж, 24=Красноярск, 27=Хабаровск, 71=Тула, 74=Челябинск, 63=Самара. Полный список: GET /portal-analytics/api/dictionaries/regions

objStatus: 0=строящийся в продаже, 1=сдан, 2=забронированы все или нет в продаже, 3=проблемный

flatStatus: free, booked, sold (через запятую как фильтр)

roomCountType: ONE, TWO, THREE, FOUR (для 4+)

objClass: 1=Типовой, 2=Комфорт, 3=Бизнес, 4=Элитный

wall (материал стен): 1=Блоки, 2=Кирпич, 3=Панель, 4=Монолит, 5=Монолит-кирпич

type (для квартир): 'Квартира-студия', '1-комнатная квартира', '2-комнатная квартира', '3-комнатная квартира', '4+комнатная квартира', 'Апартаменты'

mechanism (финансирование): 7=эскроу с проектным финансированием, 6=без эскроу старая схема, 5/4/3/2 = варианты ЖСК, кооперативов

energyEff: A++/A+/A/B/C/D — кодируется числами 6-9 (точное соответствие неизвестно, уточнить через UI labels)

calculationType (для /launch/*): SQUARE | HOUSES | FLATS


OAuth2 client credentials flow — единый механизм авторизации для всех 4 официальных спек (СЖС/НСИ/УОПО/АПФ).

Step 1: POST /idm-services/auth/realms/external-eisgs-idm/protocol/openid-connect/token

Step 2: Ответ = {access_token, expires_in: 300, refresh_expires_in: 1800, refresh_token, token_type: 'bearer', scope}

Step 3: Использовать `Authorization: Bearer {access_token}` во всех вызовах API

Token TTL: 300с (5 мин), refresh TTL: 1800с (30 мин). Max 20 одновременных сессий на Участника

Для АПФ дополнительный scope: fin-applications.readwrite.base

Режимы: Интеграционная среда (https://int.domrf.ru/) для тестирования, Промышленная (https://наш.дом.рф/) для боевого

Для Промышленной — IP-whitelist обязателен (IP регистрируются при подключении)

⚠ Доступно ТОЛЬКО внешним ИС официальных Участников ЕИСЖС (банки, Фонд, Госорганы). GenDesign НЕ имеет прямого доступа


API СЖС (Сведения о жилищном строительстве) v1.3.0 от 03.11.2020. Официальная B2B спецификация.

Base URL: https://наш.дом.рф/gw/sgs/api/v1/ (пром) | https://int.domrf.ru/gw/sgs/api/v1/ (инт)

Auth: OAuth2 + Bearer JWT (см. DomRF_OfficialAuth_Apr26)

Rate-limit: 400 запросов/24ч, 10/мин, page size max 50

/version, /model/current — служебные (XSD-схема)

/complexes, /complexes/{id}, /complexes/{id}/construction-objects — жилые комплексы

/construction-objects[?address&is_problem_object], /construction-objects/{id}, /{id}/extended, /{id}/documents, /{id}/files/{file-id}, /{id}/photos — объекты строительства

/developers, /developers/{id}, /{id}/extended, /{id}/complexes, /{id}/construction-objects, /{id}/documents, /{id}/files/{file-id} — застройщики

/company-groups, /company-groups/{id}, /{id}/developers, /{id}/complexes, /{id}/construction-objects — группы компаний

/problem-objects[?address], /problem-objects/{id} — проблемные объекты

История версий:

v1.1.0 (29.05.2020) — добавлены /model/current, /{id}/files (старые /documents/files помечены deprecated)

v1.2.0 (07.09.2020) — добавлены /problem-objects + is_problem_object

v1.3.0 (03.11.2020) — добавлены query-параметры address и is_problem_object

С 2020 года новых версий не публиковали


API НСИ (Нормативно-справочная информация) v1.0.1 от 08.10.2020.

Base URL: https://наш.дом.рф/gw/rdm/api/v1/ | https://int.domrf.ru/gw/rdm/api/v1/

Rate-limit: 3000/24ч, 60/мин, page size max 1000 (самые либеральные из 4 спек)

15+ методов:

/refBook/{id}, /refBook/code/{refBookCode}, /refBook/version/{id}, /refBook/versions — справочники

/plainData/version/row/{rowId}, /plainData/version/{versionId}/data, /plainData/version/refBook/{refBookCode}/{date} — содержимое

/version/row/exists?rowId=, /version/structure?versionId=, /version/{versionId} — мета-инфо

/version/{versionId}/getFile, /getRawFile — выгрузка в XLSX/XML/JSON

/compare/getCommonComparableRows?oldVersionId=&newVersionId= — сравнение версий

Известные справочники: D024 (основания отказа 214-ФЗ), D025 (218-ФЗ). Для GenDesign почти не пригодится, разве что для маппинга кодов


API УОПО (Уведомления об Отказах в Проведении Операций) v1.0.2 от 08.10.2020.

Base URL: https://наш.дом.рф/gw/mpo/api/v1/ | https://int.domrf.ru/gw/mpo/api/v1/

Rate-limit: 300/24ч, 10/мин (только GET-методы)

POST /prohibited-notifications — регистрация уведомления о запрещённой операции

GET /prohibited-notifications, /prohibited-notifications/{guid}, /{guid}/fond, /{guid}/non-profit — выборка и статус передачи

POST /misuse-notifications — уведомление о нецелевом использовании средств

GET /misuse-notifications, /{guid}, /{guid}/executive-authority, /{guid}/fond — выборка

Роли в матрице: УБ (уполномоченный банк), УБСЖС, Администратор

⚠ Доступ ТОЛЬКО для банков с эскроу-счетами (по 214-ФЗ ст.18.2 и 218-ФЗ ст.9.2-9.4). Для GenDesign бесполезен

Полезные для банка-партнёра в будущем (когда GenDesign интегрируется с Банк ДОМ.РФ/Сбер)


API АПФ (Агрегатор Проектного Финансирования) v2.2 (2021).

Auth: OAuth2 + Bearer JWT, scope: fin-applications.readwrite.base

Rate-limit: не указан в спеке

GET /project-financing/applications — список заявок на ПФ

GET /project-financing/applications/{guid} — полная анкета по заявке

PATCH /project-financing/applications/{guid} — подтверждение получения

GET /project-financing/files/{external-guid} — вложения

Анкета содержит 30+ объектов: financeRequest, questionnaire, financialIndicators, developerinfo, infoCompanyGroup, initialAndPermittingDocumentationForProject, landLegalRelations, projectCharacteristics, completedProjectsOutsideDeadline, financialReportCurrentYear, planingFinancialIndicators, projectBudget, requiredAmountFunding, infoGeneralContractor, generalContractorsLiabilitySRO, infoTechnicalCustomer, technicalCustomersLiabilitySRO, buildingPermit, expertiseDesignDocumentation, urbanPlanOfLand, landRightPurchase, objectCharacteristics, structureOfPlannedAreas, structureOfRealizedAreas, plannedInfrastructure, developerExperience, subjectRF, developerBenefiсiaries, mortgagedPropertyGuarantees, developerContactDetails, connectionToEngineeringNetworks, implementationOfProjects, debtAmounts

⚠ ОЧЕНЬ интересные данные для финмодели (нормативная стоимость, бюджет проекта, требуемое финансирование)

Но доступ ТОЛЬКО для банков-получателей заявок. Потенциальная цель партнёрства с банком на Раунд А

Структура респонса иллюстрирована в спеке в Приложении 1: schemeVersion='v2s01', subjectRF, projectAddress, isProjectDeclarationsPostedInEISZHS, projectDeclaration, characteristics + finance блоки


Главный вывод сравнения 4 официальных спек и фронт-API: ЭТО ДВА РАЗНЫХ ПРОДУКТА НА ОДНОМ ПОРТАЛЕ.

(а) Официальный B2B API ЕИСЖС /gw/{sgs|rdm|mpo|apf}/api/v1/* — OAuth2 + JWT, только для зарегистрированных банков-Участников

(б) Публичный фронт-API наш.дом.рф /portal-analytics/*, /portal-kn/*, /сервисы/api/kn/* — недокументированный, ключ Basic MTpqd2U= хардкоден в JS

СОВПАДАЮЩИЕ СУЩНОСТИ (во обоих API):

- Группа компаний, Застройщик, ЖК, Объект строительства, Проблемный объект

- Объект расширенные сведения: этажность, материал стен/перекрытий, отделка, класс, машиноместа, плановая дата ввода

- Списки документов (ПД, РНС, фотографии стр-ва)

ЧТО ЕСТЬ В ФРОНТ-API И НЕТ В СЖС:

⚠ PER-FLAT данные (24 441 квартир по Свердл.обл с priceChangeDate, pricePerSquareMeter, status free/booked/sold) — ЭКСКЛЮЗИВНО фронт!

⚠ priceChangeDate (velocity-tracking) — нет ни в одном официальном API

⚠ flats/map (bbox-поиск) — нет в спеке

⚠ Аналитические агрегаты (by-room-count, by-flat-area, by-region, by-developer) — нет как отдельных endpoints

⚠ launch / ready-construction / rpp / mortgage / escrow / project-finance — НИЧЕГО из этого нет в официальных спеках

⭐ ИТОГ: даже с B2B-доступом через банк-партнёр НЕЛЬЗЯ заменить публичный фронт для velocity-tracking + распределений. Реальный use-case GenDesign решается ТОЛЬКО через фронт-API

ЛИМИТЫ: СЖС 400 req/24h → выкачать все ЖК Свердл.обл (~283 ЖК × endpoints) НЕВОЗМОЖНО в официальном канале


Ключ Basic MTpqd2U= и юр. статус использования публичного фронт-API ДОМ.РФ.

Технически: сформирован из base64('1:qwe'). Хардкод в JS фронта. Бессрочен на момент проверки

В официальных спеках ЭТОГО КЛЮЧА НЕТ — спеки знают только Bearer JWT через OAuth2

Статус использования: ПАРСИНГ ПУБЛИЧНОГО ПОРТАЛА, НЕ ОФИЦИАЛЬНОЕ API

Why: ДОМ.РФ по 214-ФЗ обязан публиковать эти данные открыто — использование легально

How to apply: в реестре ПО декларируй формулировку 'интеграция с открытыми данными ЕИСЖС' или 'парсинг открытого портала наш.дом.рф'. НЕ используй формулировку 'API ДОМ.РФ' — зарезервировано за B2B-каналом СЖС/НСИ/УОПО/АПФ

Риск: фронт может отвалиться без предупреждения (ключ перевыпустят или поменяют URL)

Митигация: ежедневный smoke-test, fallback на /portal-analytics (no auth) для агрегатов

План B на блокировку фронта: партнёрство с банком-получателем СЖС API (Банк ДОМ.РФ, Сбер). Даёт SLA, но лимит 400/сутки и нет per-flat


Схема per-квартиры из GET /сервисы/api/kn/flats. 17 полей + вложенные объекты.

id (int) — глобальный ID квартиры в ЕИСЖС

odsId (string) — формат 'objId/sectionNum/flatNum' (напр. '64057/2/55'). Связь с реестром проектных деклараций

elemId (UUID) — токен для URL детальной страницы квартиры

type (string) — 'Квартира-студия' / '1-комнатная' / '2-комнатная' / '3-комнатная' / '4+комнатная' / 'Апартаменты'

number (string) — номер квартиры по застройщику

totalArea (float) — общая площадь м² (продаётся)

livingArea (float) — жилая площадь м² (без коридоров/санузлов). Для финмодели важно отдельно

rooms (int) — кол-во комнат (студия = 1)

price (int) — полная цена в ₽

priceChangeDate (string DD-MM-YYYY HH:MM) — дата последнего изменения цены. ⭐ КЛЮЧЕВОЕ ПОЛЕ для velocity-tracking

socialMortgage (bool) — доступна соц-ипотека

floor (int) — этаж этой квартиры

image{attachmentId, attachmentIdSmall, hash, size, source, type} — при type='layout' рисунок планировки. Скачать: /api/ext/file/{attachmentId}?type=png

objInfo{hobjId, objTransferPlanDt, objReady100PercDt, objCommercNm, objAddr} — связь с ЖК

Разница objTransferPlanDt vs objReady100PercDt: плановая дата передачи квартир по ДДУ vs дата готовности дома. Лаг 3-6 мес важен для absorption analysis

Качество данных (проверка 26.04.2026): 'LIBERTY DOM' в ЛО — цены 2.6М и 2.7М ₽, площадь 22 и 23 м² — реалистично. priceChangeDate '30-11-2025' = 5 мес назад, значит плохо продаются


Стратегия использования priceChangeDate + status из /сервисы/api/kn/flats для velocity-tracking в GenDesign.

Снимая snapshot раз в день мы видим:

1) Delta price — какие квартиры подешевели/подорожали

2) Status changes — какие перешли free→booked→sold

3) Velocity по ЖК — количество квартир сменивших status за период

4) Ценовая стратегия жков: активные priceChangeDate за 7 дней vs жки без движения цен месяцами

Это ровно то что нужно для Plan A ПЛИТКИ 3 (за какое время продастся):

— выводим absorption rate (квартир/мес) для ЖК-аналогов в радиусе 5 км

— проецируем на концепт пользователя

Альтернатива: можно использовать агрегированные endpoints DomRF_Tab6_Realization_Apr26 и DomRF_Tab7_ReadyConstruction_Apr26 — они дают те же sold% без выкачки всех 24K квартир. Первичный выбор — использовать их, per-flat оставить для deep-dive по радиусу


ETL-стратегия и SQL-схема для per-квартиры из ДОМ.РФ в GenDesign Stage 2a.

Для каждого региона-таргета (66=Свердл, 50=МО, 77=Москва) → loop offset/limit с шагом 500 → upsert в dom_rf_flats

SQL diff dom_rf_flats vs dom_rf_flats_yesterday → вычислить (a) кто перешёл в sold, (b) кому изменилась цена, (c) кто новый. Запись в dom_rf_flat_events

Шаг 3: Materialized views — median(pricePerSquareMeter) по (region, type, year_quarter), absorption_rate по hobjId (sold quarters / 30 days)

CREATE TABLE dom_rf_flats (id BIGINT PRIMARY KEY, ods_id VARCHAR(50), elem_id VARCHAR(64), obj_id INT, hobj_id INT, type VARCHAR(50), number VARCHAR(20), is_studio BOOL, rooms SMALLINT, total_area NUMERIC(8,2), living_area NUMERIC(8,2), price NUMERIC(12,2), price_per_sqm NUMERIC(10,2), price_change_dt TIMESTAMPTZ, status VARCHAR(20), social_mortgage BOOL, floor SMALLINT, num_floors SMALLINT, layout_attachment_id VARCHAR(80), obj_commerc_nm TEXT, obj_addr TEXT, obj_transfer_plan_dt TIMESTAMPTZ, obj_ready_dt TIMESTAMPTZ, last_synced_at TIMESTAMPTZ, raw JSONB, region_cd SMALLINT)

Индексы: (region_cd), (hobj_id), (status), (type), (price_per_sqm), (price_change_dt). Для радиус-запросов нужен JOIN с dom_rf_objects по hobj_id чтобы получить geom

CREATE TABLE dom_rf_flat_events (flat_id BIGINT, event_dt TIMESTAMPTZ, event_type VARCHAR(20), old_value JSONB, new_value JSONB, PRIMARY KEY(flat_id, event_dt))  -- event_type: 'status_change' | 'price_change' | 'new_listing' | 'delisting'

Ожидаемый объём выкачки: Свердл.обл 24 441 квартир = 49 запросов при limit=500 = ~10 секунд при 5 RPS. МО+Москва — ~30 мин выкачки

Бонус — планировки: image.attachmentId с type='layout' = ~24K image по Свердл.обл. Можно скачать все для AI-обучения или показа аналогов


Для всех записей в knowledge graph предпочтительны прямые вызовы MCP-инструментов (aim_memory_store / aim_memory_add_facts).

Why: прямые вызовы надёжнее python-скриптов, не требуют jsonl-обработки, поддерживают все фичи графа (связи, типы)

How to apply: используй python-скрипты только если MCP-сервер недоступен (fallback). Проверено 26.04.2026


Двухшаговый flow для выгрузки всех ЖК региона из API ДОМ.РФ.

ШАГ 1: GET /portal-kn/api/sales/portal?flatStatus=free,booked&regions=66 → плоский массив objId всех ЖК в регионе (НЕТ авторизации)

ШАГ 2: для каждого objId: GET /сервисы/api/kn/object?objId={id} → полная карточка ЖК (см. DomRF_API_KnObject_Apr26)

Header для Шаг 2: Authorization: Basic MTpxd2U= (или MTpqd2U= — варианты видели в разных источниках, оба работают — проверить свежесть при deploy)

Ожидаемый объём: ~150-200 запросов на всю Свердл.обл. При rate-limit 5 RPS — 30-40 секунд на полный sync. ~3-5 мин на все Свердл+МО (~1000 ЖК)

Реальный пример (Екб, ЖК 'РАЗУМ на Малышева'):

Метро Площадь 1905 года 27 мин

413 квартир, 19089 м²

Средняя цена по ЖК 180828 ₽/м²

freeFlatsInfo.numberFlats = 52 (свободных на момент проверки)

⚠ КЛЮЧЕВАЯ ИНСАЙТНАЯ деталь: objPriceAVG — золотое поле для финмодели. priceMin часто означает 'студия 25 м²' — используй objPriceAVG

freeFlatsInfo.numberFlats — динамика в о времени = velocity proxy. Дельта суточных snapshots даёт кол-во проданных квартир без per-flat выкачки


ETL и SQL-схема для per-ЖК из ДОМ.РФ (отличается от per-flat в DomRF_PerFlat_ETL_Apr26).

Для каждого региона из списка целей → /sales/portal → массив objId → batch fetch /object → upsert в dom_rf_objects

Время на ~1000 ЖК — 3-5 мин. Кэш в Redis на 6ч

Пробежать те же objId, сохранить freeFlatsInfo.numberFlats с timestamp → dom_rf_velocity_snapshots (obj_id, snapshot_dt, free_count, price_min)

Из истории считаем absorption rate без выкачки per-flat

При запросе пользователя про участок → bbox 5км → /flats/map → топ-20 ЖК-аналогов → /object для каждого → median(objPriceAVG), median(objSquareLiving/objElemLivingCnt), avg(objReady100PercDt - objPublDt) для срока строительства

table dom_rf_objects (obj_id PK, hobj_id, dev_id FK, dev_inn, group_name, region_cd, obj_addr, obj_short_addr, latitude, longitude, metro_id, metro_name, metro_time, obj_commerc_nm, obj_floor_min, obj_floor_max, obj_elem_living_cnt, obj_ready_100perc_dt, obj_square_living, obj_price_avg, obj_publ_dt, site_status, escrow_flg, problem_flg, building_type, ai_description, render_url, raw_payload jsonb, last_synced_at)

table dom_rf_developers (dev_id PK, dev_inn, short_name, full_name, group_name, company_group, org_form_id)

table dom_rf_velocity_snapshots (obj_id, snapshot_dt, free_count, price_min, PK(obj_id, snapshot_dt))

Индексы: GIST на (latitude, longitude) → ST_DWithin для радиус-запросов в районе

Связано с DomRF_PerFlat_ETL_Apr26 (там per-flat-схема dom_rf_flats + flat_events). Обе схемы нужны: объекты + квартиры


Endpoints ДОМ.РФ которые НЕ РАБОТАЮТ (проверка 26.04.2026). Не терять время на них.

GET /сервисы/api/kn/freeFlats?objId={id} → 502 (proxy error, путь возможно неверный)

GET /сервисы/api/kn/object/{id}/flats → 502

GET /portal-kn/api/object/{id} → 500 INTERNAL_ERROR

GET /portal-kn/api/object/{id}/flats → 500

Для per-flat данных (отдельные квартиры в ЖК) используй GET /сервисы/api/kn/flats?regions=X (см. DomRF_API_KnFlats_Apr26) — это рабочий endpoint

freeFlatsInfo.numberFlats в /object даёт только количество свободных, не детали


Дата: 26.04.2026. Пассивный recon по публичным точкам ДОМ.РФ. Никаких active scans — только стандартные endpoints + headers от API-вызовов которые мы и так делаем.

9 отдельных находок сохранены рядом как DomRF_Recon_*_Apr26

Сильные находки: GitLab CI плейсхолдеры в accept-version, утечка feature-бранча+SHA, password grant_type в OIDC realm

Слабые находки (фингерпринты): X-Powered-By Undertow/Express, публичный sitemap, OPTIONS allow POST на read-only API

Для GenDesign это ИНВЕНТАРЬ рисков стабильности канала + потенциал для responsible disclosure

Active scans (DCR регистрация, password брут, IDOR, POST на /object) НЕ делали — требует scope-разрешения и BB-программы (которой у ДОМ.РФ нет)


Утечка #1 (основная): незакрытая шаблонная подстановка GitLab CI в response header.

На /сервисы/api/kn/* выдаётся: accept-version: ${env.CI_COMMIT_REF_NAME}_sha1:${env.CI_COMMIT_SHORT_SHA}#${env.CI_PIPELINE_ID}_20.04.2026 12:58:31

Переменные GitLab НЕ интерполируются на бэкенде — баг деплоя. Косвенное раскрытие: GitLab CI/CD они используют

Утечка #2: на /аналитика/api/escrow/* интерполированный accept-version: '3.9.0-new-memory-limits_sha1:a9723d46#2106101_05.08.2025 06:39:18'

Это раскрывает: (1) имя feature-бранча ('3.9.0-new-memory-limits'), (2) git SHA-1 коммита 'a9723d46', (3) GitLab pipeline ID '2106101', (4) дату деплоя 5.08.2025 — бэкенд escrow не обновлялся 8 месяцев

Риск: злоумышленник видит какие версии в проде + активные фичевые ветки = таргетинг known-CVE по библиотекам и enumeration internal feature flags

Severity: low-medium — инфо сама по себе не даёт эксплоит, но снижает работу река. Для responsible disclosure — кандидат #1


Публичный OIDC well-known: GET /idm-services/auth/realms/external-eisgs-idm/.well-known/openid-configuration

Стандартное раскрытие по RFC8414, но в этом случае раскрывает МНОГО внутренних модулей

scopes_supported — 50+ scope'ов = карта модулей системы:

lkfpc.developer.readwrite, lkfpc.ko.readwrite, lkfpc.bucket.read, lkfpc.developer-regfond.readwrite, lkfpc.technical.readwrite — ЛК ФПК (Фонд Развития Проблемных Компаний?)

erzkn.read.base — Единый Реестр Застройщиков, rpp.read.base — Реализация Продаж (наш Tab6!), mcalc.read.base — Mortgage Calculator

billing.files.readwrite.administrator, billing.files.readwrite.1c, billing.files.readwrite.services — billing-интеграция с 1С

smv.read.base, smvfs.read.base — СМЭВ и СМЭВ-ФС (система межведомственного электронного взаимодействия)

krp.read.base, fpp.read.base, rgp.read.base, sgs.str.read.base — внутренние модули

service_account, dictionary.export, profile.readwrite.base — админ-скоупы

Риск #1: grant_types_supported включает 'password' (Resource Owner Password Credentials) — устаревший grant, НЕ рекомендуется OAuth 2.0 BCP. Риск credential stuffing если есть пользовательские аккаунты

Риск #2: registration_endpoint = /clients-registrations/openid-connect — RFC7591 Dynamic Client Registration. Открытость НЕ проверялась (active scan)

Severity: medium — password grant + полная карта scopes помогают attacker'у навести прицел


Три разных backend-стека за одним nginx-фронтом — раскрыто через X-Powered-By и accept-version.

/сервисы/api/kn/* → X-Powered-By: Undertow/1 (Стек Java/JBoss WildFly Undertow)

/api/document/* → X-Powered-By: Express (Node.js)

/portal-analytics/api/* → нет X-Powered-By, но accept-version выдаёт GitLab placeholders — явные признаки Spring Boot/Tomcat (Java)

/idm-services/auth/* → Keycloak (по ответам в OIDC well-known: realm 'external-eisgs-idm', issuer + пути 100% Keycloak)

Последствия для attacker: разные стеки = разные CVE-кандидаты. Последствия для GenDesign: время интеграции разное, лимиты разные, стабильность разная — нужны 3 отдельных smoke-теста по бэкендам

Severity: low — версии стандартных фреймворков публичны, но хорошая практика — убирать X-Powered-By


GET /robots.txt — публичный, раскрывает схему API через Clean-param для Yandex.

Disallow строки: */auth/*, /api/ext/file/*.pdf, /files/*.pdf, /files/*?inline=1 — SEO-защита, не безопасность (файлы всё равно доступны)

Clean-param выдаёт ПОЛНЫЙ список всех возможных query-параметров API (~80 имён):

objStatus, saleRoomFlg, metroId, time, walkFlg, companyGroupId, devId, fromDatePubl, toDatePubl, objTypeCd, objClass, fromQuarter, toQuarter, keyIssuance, escrowFlag, fundFlag, fromPrice, toPrice, checkFlg, objGreenHouseFlg, freePlan, nonLivFirstFloor, cargoPassElevFlg, parkingFlg, energyEff, wall, fromFloor, toFloor, maxLivingCnt, livElemEntrFloor, barrierTypes, landscaping, search, type, place, pdId, limit1000, sortDirection, sortName, flatStatus, bounds, rooms, page, limit, priceFrom, priceTo, sortField, sortType, areaFrom, areaTo, floorFrom, floorTo, pricePerSquareMeterFrom, pricePerSquareMeterTo, state, SaleType, residentialBuildings, ivElemEntrCnt, view, isBalconiesOrLoggias, activeSort, objectIds, isLivingFlg, regionHD, status, subject, region, problemReason, mechanism, dduFlg, transferFlg, searchValue, buildFlg, regionCd, devGroupId, regionActivity, repYear, calculationType, period, addrAreaId, devCalcGroupId, objClassCd, repMonth, devGroupValue, cityPopulation, inline, filename, cooperativeId

Риск: фактически документация API там где её не должно быть. Раскрывает несуществующие в UI параметры (regionHD, regionActivity, problemReason, fundFlag, checkFlg и др.) — это заявка на over-fetching

Severity: low-medium — помогает attacker'у искать скрытые фичи. Для нас — ПОЛЕЗНО для расширения набора фильтров в GenDesign клиенте


OPTIONS /сервисы/api/kn/object → Allow: HEAD, POST, GET, OPTIONS

POST разрешён на якобы READ-ONLY API — значит у них есть write-методы которые из публичной схемы не видны

Вероятно: для авторизованных юзеров через ЛК (личный кабинет) есть create/update operations на объекты

/portal-analytics/api/* в отличие — GET, HEAD, OPTIONS (read-only как положено)

Польза для нас (GenDesign): способ понять какие endpoints имеют write-поверхность — без активных тестов их

Риск (mass-assignment): если POST /object принимает JSON без валидации типов полей и имеет слабую auth — потенциальный вектор. НЕ ПРОВЕРЯЛИ (active scan)

Severity: неопределённая — зависит от реализации POST. Только факт раскрытия в OPTIONS — low


Access-Control-Allow-Origin: <эхо Origin> (по видимому reflective)

Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT

Access-Control-Allow-Headers: accept, authorization, content-type, x-requested-with

Access-Control-Max-Age: 1 (слишком мало — preflight каждый раз)

Риск: если Origin валидируется слабо (regex/null/эхо), злоумышленный сайт может дёргать API с сессией юзера. НЕ проверяли

Severity: low (обычно банки/фронт современных институтов валидируют жёстко). Но комбинация credentials:true + reflective Origin = классический misconfig

Полезно для нас (GenDesign): /сервисы/api/kn/* можно дёргать с любого Origin — не нужен прокси на нашем бэкенде (браузер пропустит прямые вызовы)


Недокументированный service-prefix /portal-sitemap/api/ — раскрыт через robots.txt

GET /portal-sitemap/api/sitemap/root.xml → 200, 10 sub-sitemap'ов:

static.xml, turisticheskaya-nedvizhimost.xml, kvartiry-v-novostrojkah.xml, media.xml, edinyj-reestr-zhsk.xml, edinyj-reestr-zastrojshchikov.xml, gruppa-kompaniy.xml, object-zhsk.xml, katalog-novostroek.xml, proverka-novostroek.xml

GET /portal-sitemap/api → 404 (корневая ручка не работает — нужен конкретный sitemap)

GET /portal-sitemap/api/sitemap → 500 — ручка существует но багает без параметров

Для GenDesign: из sub-sitemap'ов можно вытащить ПОЛНЫЙ список URL всех ЖК/застройщиков/ГК/ЖСК в РФ — альтернатива двухшаговому flow через /sales/portal

Severity: инфо публичная (по robots.txt). 500 на /sitemap — легкий сигнал что в сервисе есть необработанный путь


ПРОВЕРКА: source maps для Next.js бандлов НЕ выложены (все *.js.map = 404).

main-*.js.map → 404, commons.*.js.map → 404, _app-*.js.map → 404, page chunks .map → 404

Это хорошая практика ДОМ.РФ — скрывают исходники React/TypeScript от выкладывания в prod

Но минифицированный JS всё равно реверсился — мы вывели все endpoints из него


План responsible disclosure если решим репортить находки ДОМ.РФ.

Why: у ДОМ.РФ НЕТ публичной BB-программы. Репортить нужно вручную без reward'ов, плюс риск вызвать подозрение и отзыв фронт-доступа (наш основной канал)

How to apply: отправить только если обваливается находка medium+. Из текущего списка: AcceptVersionLeak (medium), OIDC password grant (medium)

Канал: nash@domrf.ru (из их официальных контактов с /интеграция)

Альтернативный канал: CERT-GIB / НКЦКИ России если прямой репорт игнорируется

Шаблон репорта: описание находки → PoC (URL и response header) → impact → fix recommendation → время на fix (90 дней по обычаю). NDA не подписывать — данные и так публичные

ПРИОРИТЕТ ниже релиза GenDesign MVP — сначала делаем продукт, потом репорт. Но лучше репортить после начала партнёрства с банком-Раунда-А — будет легальный channel