# Generative Design + Site Finder Две продуктовые линии в одной воронке: **Site Finder** (AI-подбор инвестиционных земельных участков) + **Generative Design** (автоматическая генерация концепций застройки) для девелоперов РФ. ## North Star К концу месяца 3: **3 платящих пилота** (≥30 тыс. ₽/мес каждый) + заявка в реестр российского ПО → право на Раунд А (20–25 млн ₽). Acceptance criteria разбиты на 3 блока (функционально / бизнесово / технически). Правило перехода: 3/3 → Раунд А; 2/3 → продление Фазы 0 на 1–2 мес.; 1/3 или меньше → стоп проекта. --- ## Текущий статус (25 апреля 2026) **Инфраструктура: live.** Полный цикл автодеплоя из GitHub Actions работает. | Что | Где | Статус | |---|---|---| | Production VPS | Beget Cloud, Москва, 2 vCPU / 4 GB / 40 GB NVMe | ✅ работает | | IP сервера | `46.173.16.127` | — | | Postgres + PostGIS 3.4 | Docker, в составе compose | ✅ Up (healthy) | | Redis 7 | Docker | ✅ Up | | Backend FastAPI | Docker (образ из GHCR) | ✅ Up, `/health` отвечает | | Frontend Next.js 15 | Docker (образ из GHCR) | ✅ Up | | Caddy reverse proxy | Docker, ports 80/443 | ✅ Up (TLS ждёт домена) | | GitHub Actions deploy | `.github/workflows/deploy.yml` | ✅ build → push GHCR → ssh deploy | | GHCR пакеты | `ghcr.io/lekss361/gendesign-{backend,frontend}` | приватные, сервер авторизуется через PAT | | UFW firewall | 22 / 80 / 443 | ✅ активен | | SSH hardening | root login off, password auth off | ✅ | | Домен | — | ⏸ не подключён | | Бэкапы pg_dump | — | ⏸ не настроены | **Решение по плану разработки: pending.** Антон (второй разработчик) сообщил о доступе к ДДУ-данным. Решается в понедельник 27.04.2026 — выбор между: - **Plan A (Analytics First)** — Stage 1 переезжает на «3 плитки» аналитики (что строить / по какой цене / за какое время), Generative и Site Finder сдвигаются; - **Original plan** — Stage 1 = Generative MVP, Stage 2 = Site Finder, аналитика как enrichment. Зависит от 5 факторов канала ДДУ: легальность, поля, покрытие, свежесть, условия коммерческого использования. См. сущности `PlanA_AnalyticsFirst_Apr25` и `SalesTracking_Strategy_Apr25` в графе памяти. --- ## Структура репозитория ``` gendesign/ ├── backend/ # Python 3.12 / FastAPI / PostGIS │ ├── pyproject.toml # uv-проект, ruff/mypy/pytest конфиги │ ├── Dockerfile # с системными deps под Geo + WeasyPrint │ ├── .env.example │ ├── app/ │ │ ├── main.py # FastAPI + Sentry + /health │ │ ├── core/ # config (Pydantic Settings), db (SQLAlchemy) │ │ ├── api/v1/ # concepts.py, parcels.py │ │ ├── schemas/ # Pydantic-контракты для openapi-typescript │ │ ├── services/ │ │ │ ├── generative/ # Stage 1: geometry, teap, financial │ │ │ ├── site_finder/ # Stage 2: parser, scorer, filters │ │ │ └── exporters/ # Stage 1c: pdf, excel, dxf │ │ ├── models/parcel.py # GeoAlchemy2 + PostGIS │ │ └── workers/celery_app.py # Stage 2a: daily PKK sync │ └── tests/ ├── frontend/ # Next.js 15 / React 19 / TypeScript / Leaflet │ ├── package.json # включая `npm run codegen` → openapi-typescript │ ├── Dockerfile # multi-stage, output: standalone │ ├── public/ # static assets (gitkeep пока пусто) │ └── src/app/ │ ├── page.tsx # / — главная │ ├── concept/page.tsx # /concept — Generative Design │ └── site-finder/page.tsx # /site-finder — Site Finder ├── memory/ │ └── memory-gendesign.jsonl # хард-линк на C:\mcp\.aim — общий граф памяти ├── docs/ # стратегические документы (бизнес-план, цели MVP) ├── .env.example # шаблон prod env (POSTGRES_*, IMAGE_TAG, NEXT_PUBLIC_API_BASE_URL) ├── docker-compose.yml # dev: Postgres + Redis + backend + frontend ├── docker-compose.prod.yml # prod: образы из GHCR + Caddy + Postgres+Redis ├── Caddyfile # авто-TLS Let's Encrypt ├── Makefile # make up / down / test / codegen / migrate └── .github/workflows/ ├── ci.yml # ruff + mypy(core) + pytest + frontend build └── deploy.yml # build → push в GHCR → ssh deploy на VM ``` --- ## Технический стек (v2.2) **Backend:** Python 3.12, FastAPI, SQLAlchemy 2.0, GeoAlchemy2, Pydantic v2, Alembic, Celery + Redis, httpx **Geo:** Shapely 2.0, GeoPandas, Pyproj (WGS84 ↔ МСК-66 для Свердловской обл.) **ML:** scikit-learn (XGBoost — отложен на Фазу 1, в Discovery эвристики) **БД:** PostgreSQL 16 + PostGIS 3.4, Redis 7 **Frontend:** Next.js 15, React 19, TypeScript 5, Tailwind 4, TanStack Query, Leaflet (Mapbox в Stage 2b), react-leaflet 5 **Экспорт:** WeasyPrint (PDF), ezdxf (DXF), openpyxl (Excel) **Dev:** uv, ruff, mypy (strict только на core), pytest --- ## Команда и порядок работы **2 фуллстек-разработчика, оба part-time 20 ч/нед** — итого ~40 person-hours/нед, эффективных с координацией ~33. **Ритм:** - 1 синк/нед (30 мин, понедельник) - daily-async в Telegram - PR review обязательный - Trunk-based: feature ветки ≤ 3 дней - Codegen TS-типов из Pydantic (`npm run codegen`) — без этого 2 фуллстека плодят расхождения в API-контракте --- ## Этапы MVP (12 недель, базовый план) ### 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` до Раунда А). Production VPS поднят, GHCR-деплой работает. ### Stage 1 — Generative MVP (нед. 2–7) ⏸ pending решения по Plan A - **1a (нед. 2–3):** геометрия + API-контракт. Shapely-сервис (отступы, сетка), Pydantic-схемы, `POST /api/v1/concepts` с заглушкой. Фронт: страница `/concept`, Leaflet, импорт GeoJSON, форма параметров, 3 варианта в табах. - **1b (нед. 4–5):** алгоритм размещения. Жадное заполнение, 3 стратегии (max площадь / max инсоляция / balanced), STRtree для коллизий. Цель ≤10 сек, fallback 15 сек. - **1c (нед. 6–7):** ТЭП + финмодель + экспорты. WeasyPrint PDF, ezdxf, openpyxl. UI кнопок скачивания. **Acceptance Stage 1 (конец нед. 7):** полигон → 3 варианта → ТЭП + финмодель → PDF/Excel/DXF. ### Stage 2 — Site Finder MVP (нед. 8–12) - **2a (нед. 8–9):** data pipeline. Парсер ПКК Rosreestr (httpx async, retries), модель `Parcel` с GeoAlchemy2, ≥1000 участков Екатеринбурга. Overpass API для POI, ДОМ.РФ/ЦИАН для цен м², кеш в Redis. Опционально: воркер `sales_tracker.py` — ежесуточный мониторинг шахматок застройщиков (Velocity Score). - **2b (нед. 10–11):** скоринг + API + UI. 3 критерия (расстояние до центра, плотность POI в 1 км, цена района), `POST /api/v1/parcels/search`. Карта с градацией по рейтингу, фильтры, карточка. - **2c (нед. 12):** интеграция + полировка. Кнопка «Обсчитать концепцию», демо-наполнение 50 участков, бэкапы БД, подача в реестр ПО. ### Альтернативный план A (Analytics First) Если Антон в понедельник подтвердит легальный канал ДДУ-данных — Stage 1 переезжает на **«3 плитки» аналитики** (что строить / по какой цене / за какое время), Generative переходит на Stage 2 со Smart Defaults на основе аналитики, Site Finder — на Stage 3 с Velocity Score из ДДУ. См. `PlanA_AnalyticsFirst_Apr25` в графе. ### Что урезано из v2.2 из-за part-time × 2 - XGBoost-скоринг → Фаза 1 (с реальными данными от пилотов) - JWT-auth с refresh → перед Раундом А - mypy --strict — только на core (`generative/*`, `site_finder/scorer.py`) - Время генерации ≤ 15 сек как fallback (а не 10 сек) --- ## Quick start (локально) **Требования:** Docker Desktop, Node.js 20+, [uv](https://docs.astral.sh/uv/) (для backend dev вне Docker). ```bash # 1. Скопировать env-файлы cp backend/.env.example backend/.env cp frontend/.env.example frontend/.env cp .env.example .env # опционально, для prod compose # 2. Запустить всё docker compose up -d --build # или: make up # 3. Проверить curl http://localhost:8000/health # → {"status":"ok","environment":"dev"} # Frontend → http://localhost:3000 # Swagger docs → http://localhost:8000/docs ``` **Полезное:** ```bash make logs # tail логов всех сервисов make backend-shell # bash внутри backend контейнера make migrate # alembic upgrade head (когда добавим миграции) make test # pytest make lint # ruff check make typecheck # mypy на core make codegen # обновить TS-типы из OpenAPI ``` --- ## Production хостинг — Beget VPS **Текущая live-конфигурация:** Beget Cloud, Москва, Standard 3+ GHz, 2 vCPU / 4 GB / 40 GB NVMe. **Стоимость:** ~33 ₽/день сервер + ~5 ₽/день IPv4 = **~1140 ₽/мес**. Плюс домен .ru (~17 ₽/мес). **Что крутится на VM** (`/opt/gendesign`): - 5 контейнеров через `docker-compose.prod.yml`: postgres, redis, backend, frontend, caddy - Backend и frontend образы пуллятся из приватного GHCR - Persistent volumes: `gendesign_postgres_data`, `gendesign_redis_data`, `gendesign_caddy_*` - Backend и frontend биндятся на `127.0.0.1:8000` и `127.0.0.1:3000` — наружу выходит только Caddy на `:80`/`:443` **Доступ:** SSH-only по ключу к non-root пользователю `gendesign`. Root login отключён, password auth отключён, fail2ban Beget активен. ### Триггеры миграции на Yandex Cloud Переезжаем на YC Managed PostgreSQL + Compute + Container Registry, когда: - Подписан 3-й платящий пилот (~ конец мес. 3) - Закрылся Раунд А - Идёт переговор с госзаказчиком (нужен реестр ПО + солидная инфра) - БД > 10 GB или появилось > 50 RPS Стоимость production на YC: ~10–15 тыс ₽/мес. ### Что осталось до «infra-ready» - [ ] Купить домен .ru (REG.RU / РуЦентр), направить A-запись на `46.173.16.127` - [ ] Обновить `Caddyfile` с реальным доменом → авто-TLS Let's Encrypt - [ ] Задать `NEXT_PUBLIC_API_BASE_URL=https://<домен>` в `/opt/gendesign/.env` либо оставить пустым (frontend ходит через Caddy `/api/*` → backend) - [ ] Настроить ежесуточный `pg_dump` → Object Storage (Yandex free tier 1 GB или Selectel S3) - [ ] Sentry DSN в `backend/.env` --- ## GitHub Actions deploy Workflow `.github/workflows/deploy.yml`: 1. **Build** обоих Docker-образов (backend ~2.5 мин с нуля, frontend ~1 мин с нуля; повторно из кеша — секунды) 2. **Push** в GHCR (`ghcr.io/lekss361/gendesign-backend`, `gendesign-frontend`) с тегами `latest` и `` 3. **SSH deploy:** `docker compose -f docker-compose.prod.yml pull && up -d`, потом `curl /health` **GitHub Secrets (Settings → Secrets and variables → Actions):** | Имя | Значение | |---|---| | `DEPLOY_HOST` | `46.173.16.127` | | `DEPLOY_USER` | `gendesign` | | `DEPLOY_SSH_KEY` | приватный ключ `~/.ssh/gendesign_deploy` целиком | | `DEPLOY_PORT` | `22` (или другой, если поменяли) | `GITHUB_TOKEN` встроенный — отдельный secret для push в GHCR не нужен. **Авторизация сервера в GHCR (приватные пакеты):** Сервер авторизуется однократно через PAT с `read:packages`: ```bash # На сервере, как пользователь gendesign read -s GHCR_PAT && echo "$GHCR_PAT" | docker login ghcr.io -u lekss361 --password-stdin && unset GHCR_PAT ``` Auth сохраняется в `~/.docker/config.json` и переживает рестарт. Ротировать PAT раз в год. --- ## Память проекта (knowledge graph) Все решения, факты, риски, KPI, протоколы валидации хранятся **только в графе памяти**, не в .md-документах. Это решает проблему расхождения версий между документами. **Как устроено:** - MCP-сервер `mcp-knowledge-graph` пишет в `C:\mcp\.aim\memory-gendesign.jsonl` - Этот файл — **хард-линк** на `/memory/memory-gendesign.jsonl` - Изменения попадают в git автоматически - Синхронизация между коллегами — через `git pull` / `git push` **Правило проекта (`Feedback_MemoryFirst`):** - Все факты и решения сохраняем в граф (`context: "gendesign"`) - `.md` / `.docx` / `.pdf` Claude **не создаёт сам** — только по явному запросу - Источник правды = граф, документы = производные срезы **Рабочий цикл:** ```bash git pull # перед началом работы # ... сессия с Claude ... git add memory/memory-gendesign.jsonl git commit -m "Memory: <что добавили>" git push ``` Конфликты в `.jsonl` обычно простые (файл построчный): `git pull --rebase`, оставить **обе** стороны, `git rebase --continue`. ### Подключение коллеги Краткая инструкция для нового участника команды: 1. Установить Claude Desktop, Node.js 20+, Git 2. Клонировать репо в `C:\Users\<имя>\source\repos\gendesign` 3. `mkdir C:\mcp\.aim` 4. Создать хард-линк: ```powershell New-Item -ItemType HardLink ` -Path C:\mcp\.aim\memory-gendesign.jsonl ` -Value $PWD\memory\memory-gendesign.jsonl ``` 5. Добавить в `%APPDATA%\Claude\claude_desktop_config.json`: ```json "knowledge-graph": { "command": "npx", "args": ["-y", "mcp-knowledge-graph", "--memory-path", "C:\\mcp\\.aim"] } ``` 6. Перезапустить Claude Desktop полностью (через трей) 7. Проверить: «Покажи память контекста gendesign» Полная версия процедуры — в графе, сущность `Onboarding_Colleague_KG`. --- ## Документы стратегии В `docs/`: - `MVP_Goals_Python.md` — цели Discovery MVP, Python-стек (v2.2, апрель 2026) - `Бизнес-план v2.1 - Site Finder + Roadmap 12 месяцев.md` — бизнес-план ⚠️ Эти документы — **снимок состояния на момент написания**. Свежее состояние стратегии — в графе памяти. При расхождении доверяем графу. Релевантные сущности графа на 25.04.2026: - `Project_GenDesign` — общая шапка - `TechStack_v2.2` — Python + Next.js стек - `NorthStar_DiscoveryMVP` — 3 пилота + реестр ПО → Раунд А - `Stages_MVP_v1` — базовая разбивка по этапам - `Team_Setup` — 2 фуллстека part-time - `WorkSplit_Generative_Stage1` — кто что делает в Generative - `PlanA_AnalyticsFirst_Apr25` — pending pivot решение - `SalesTracking_Strategy_Apr25` — шахматки застройщиков - `DataSources_Pricing_Apr25` — источники цен и площадей - `Hosting_Pricing_Apr25` — сравнение провайдеров - `Hosting_Decision_Apr25` — решение по Yandex Cloud (для будущей миграции) - `Runbook_VPS_Setup_Beget` — пошаговая настройка production VM - `SSH_Setup_Apr25` — локальная настройка SSH - `Onboarding_Colleague_KG` — подключение нового участника к графу - `Feedback_MemoryFirst` — правило: память first, docs только по запросу - `Validation_Findings_Apr25` — валидация бизнес-плана --- ## Полезные ссылки - **Репо:** https://github.com/lekss361/-gendesign - **GitHub Actions:** https://github.com/lekss361/-gendesign/actions - **GHCR пакеты:** https://github.com/lekss361?tab=packages - **Production VPS:** Beget Cloud → `cp.beget.com/cloud/servers/jolly-yakov-3` - **Целевой регион Discovery:** Свердловская обл. (Екатеринбург, ПЗЗ, МСК-66) - **Конкуренты:** rTIM (только концепт-стадия, нет site-selection), TestFit (нет РФ-данных)