* feat(db): schema migration for bulk cadastre ingest layers (#168) Add 7 cadastre layer tables + cadastre_jobs saga-state table. Tables: - cad_parcels (36368 ЗУ ЕГРН) replaces cad_parcels_geom - cad_buildings v2 wide schema (replaces existing, backed up as cad_buildings_old_apr26) - cad_constructions (36383 Сооружения + ЕГРН, flag is_egrn) - cad_oncs (36384), cad_enk (39663), cad_zouit (4 categoryIds), cad_quarter_stats - cadastre_jobs (resumable saga state, mirrors geo_jobs pattern) GIST + BTREE indexes. Migration of cad_parcels_geom data via INSERT...SELECT. Restore v_complex_full + v_complex_buildings views after table rename. * fixup(db): address PR #169 bot review — 2 blockers + 3 lessers Blocker #1: cad_parcels_geom DROP → back-compat VIEW Old DROP TABLE would break site-finder analyze fallback (per 83_*.sql COMMENT). Now: drop old BASE TABLE (guarded by table_type), create VIEW over cad_parcels with identical 4-column signature. Callers continue to work; PR2/5 will switch. Blocker #2: K.3 redundant RENAME CONSTRAINT removed ALTER INDEX RENAME on PK index already renames the backing constraint in PG16. Second ALTER TABLE RENAME CONSTRAINT would throw 'does not exist' and abort tx. Lesser #1: cadastre_jobs.status CHECK constraint Inline CHECK (status IN ('queued','running','done','failed','zombie','cancelled','paused')) per partial-index intent and admin UI plan. Lesser #2: COMMENT ON TABLE for all 8 tables + view (keeps convention from 63, 83). Lesser #3: set_updated_at() triggers on 7 tables with updated_at column. Reuses existing function (verified present). DO $$ guards on pg_trigger for idempotent re-apply. cadastre_jobs excluded (uses heartbeat_at instead). --------- Co-authored-by: lekss361 <claudestars@proton.me> |
||
|---|---|---|
| .github/workflows | ||
| backend | ||
| data | ||
| docs | ||
| frontend | ||
| memory | ||
| ops | ||
| scripts | ||
| site-finder | ||
| .editorconfig | ||
| .env.example | ||
| .gitignore | ||
| .pre-commit-config.yaml | ||
| Caddyfile | ||
| CLAUDE.md | ||
| debug.log | ||
| docker-compose.obsidian.yml | ||
| docker-compose.prod.yml | ||
| docker-compose.yml | ||
| Makefile | ||
| README.md | ||
| sshkey.txt | ||
Generative Design + Site Finder
Две продуктовые линии в одной воронке: Site Finder (AI-подбор инвестиционных земельных участков) + Generative Design (автоматическая генерация концепций застройки) для девелоперов РФ. Целевой регион Discovery — Свердловская обл. (ЕКБ, ПЗЗ, МСК-66).
North Star
К концу месяца 3: 3 платящих пилота (≥30 тыс. ₽/мес каждый) + заявка в реестр российского ПО → право на Раунд А (20–25 млн ₽).
Текущий статус (май 2026)
Live: https://gendsgn.ru/ — HTTP/2+HTTP/3, валидный TLS, /health {"status":"ok"}. Полный CI/CD: GitHub Actions → GHCR → SSH-deploy на Beget VPS. Sentry активен (release tracking привязан к git-sha).
| Слой | Статус |
|---|---|
Аналитический калькулятор /analytics/recommend (Tier 3 per-bucket эластичность, кадастр vs рынок) |
✅ |
| DOM.РФ kn-API скрейпер (442 строящихся ЖК Свердл, sale_graph + infra + photos) | ✅ Celery beat + admin UI |
| NSPD geo bulk-fetcher (rosreestr2coord lite, без Playwright) | ✅ admin UI с per-target логами |
| Rosreestr CSV-сделки 2024Q1—2026Q1 (9 квартирных партиций, 7M строк) | ✅ |
| NSPD кадастровые кварталы + здания (709 cad-кварталов, 10 590 cad_buildings ЕКБ) | ✅ Celery beat + admin UI |
| OSM ekb_districts_geom (PostGIS-полигоны 8 районов ЕКБ) | ✅ |
| Objective ETL (Anton SQLite → PG, ports на psycopg v3) | ✅ admin UI |
Obsidian Self-hosted LiveSync vault на obsidian.gendsgn.ru (268 entities из KG) |
✅ multi-device sync |
Concept page (/concept) — Stage 1 Generative |
🟡 skeleton |
Site Finder (/site-finder) — Stage 2 |
🔴 заглушка |
Backlog: GitHub Issues (трекаемые задачи с PR-связью) + Obsidian vault (планы, ADR, research — см. ниже про разделение).
Quick start (локально)
Требования: Docker Desktop, Node.js 20+, uv для backend dev.
cp backend/.env.example backend/.env
cp frontend/.env.example frontend/.env
docker compose up -d --build
curl http://localhost:8000/health # → {"status":"ok","environment":"dev"}
# Frontend: http://localhost:3000
# Swagger: http://localhost:8000/docs
Полезные make-таргеты: logs, backend-shell, migrate, test, lint, typecheck, codegen (TS-типы из OpenAPI).
Архитектура
Backend: Python 3.12, FastAPI, SQLAlchemy 2.0, GeoAlchemy2, Pydantic v2, Celery + Redis, httpx, Shapely 2, scikit-learn.
БД: PostgreSQL 16 + PostGIS 3.4 (партиционированные rosreestr_deals, GIST на geom-полях, ~50 предметных таблиц).
Frontend: Next.js 15, React 19, TypeScript 5, Tailwind 4, TanStack Query, Leaflet/Mapbox, ECharts.
Экспорт: WeasyPrint (PDF), ezdxf (DXF), openpyxl (Excel).
Dev: uv lockfile, ruff, mypy strict (на core + generative), pytest, pre-commit hooks.
Структура монорепо:
backend/ FastAPI app, services (analytics_queries, scrapers, generative, site_finder), workers (Celery)
frontend/ Next.js app router (analytics, admin, concept, site-finder)
data/sql/ ETL артефакты — миграции схемы, загрузчики rosreestr/anton/nspd
ops/ backup.sh + deploy скрипты
scripts/ утилиты (migrate_kg_to_obsidian.py, setup-couchdb.sh, cleanup_ghosts.py)
docs/ стратегические снапшоты (актуальное knowledge — в Obsidian vault)
memory/ legacy JSONL knowledge graph (deprecated, не обновляется — данные в Obsidian)
docker-compose.prod.yml main стек (backend, frontend, postgres, redis, worker, beat, caddy)
docker-compose.obsidian.yml obsidian-стек (CouchDB) — деплоится отдельно
.github/workflows/
├── deploy.yml main → пересборка backend/frontend образов + SSH deploy
└── deploy-obsidian.yml obsidian-стек (CouchDB compose changes + bootstrap)
Аналитика — что доступно
В прод-БД ~50 предметных таблиц:
domrf_kn_*— DOM.РФ объекты, квартиры, sale_graph, infrastructure, photos (1500+ ЖК Свердл).rosreestr_deals— партиционированные ДДУ/ДКП-сделки 2024Q1—2026Q1, ~7M строк, 27 мес истории.cad_quarters_geom+cad_buildings— NSPD кадастровые кварталы и здания (cost_value, year_built, floors, geom).ekb_districts_geom— PostGIS-полигоны OSM для spatial-join.cbr_mortgage_series,yandex_realty_zk,domrf_realization,sber_ddf_metrics— макро/cross-validation.
Калькулятор /analytics/recommend считает квартирографию (5 size-бакетов) с per-bucket эластичностью через регрессию sale_graph, нормировкой на район/класс/конкурентов, кадастр-vs-рынок cross-check, и инверсным режимом «требуемая цена для срока X мес».
Подробное описание схемы БД, helper-views, FK и 27.04 history — в Obsidian vault: domains/analytics/Analytics_Dashboard_Apr27, domains/domrf/events/DomRF_Lazy_Loaded_Apr27_2026, events/Anton_Imported_Apr27_2026, domains/cadastre/Cad_Quarter_Backfill_Apr30. См. также data/sql/*.sql (DDL артефакты).
Production хостинг
Beget Cloud, Москва, 2 vCPU / 4 GB / 40 GB NVMe. Стоимость ~1 140 ₽/мес сервер + ~17 ₽/мес домен.
Два изолированных стека через docker compose, общая Docker network gendesign_shared:
-
Main стек (
docker-compose.prod.yml, projectgendesign):postgres+redis+backend(FastAPI) +worker+beat(Celery, Chromium только в worker) +frontend+caddy(auto-TLS Let's Encrypt). Backend/frontend bind на127.0.0.1— наружу только Caddy. -
Obsidian стек (
docker-compose.obsidian.yml, projectgendesign-obsidian):couchdb:3— Self-hosted LiveSync remote для multi-device sync vault'а наobsidian.gendsgn.ru. Caddy в main-стеке маршрутизирует черезgendesign_sharednetwork.
Split deploy — изменения в main НЕ перезагружают obsidian (и наоборот). Каждый стек со своим workflow.
SSH-only по ключу к non-root пользователю gendesign, fail2ban активен. UFW: 22/80/443.
GitHub Actions deploys:
.github/workflows/deploy.yml— main: триггер наbackend/**,frontend/**,Caddyfile,docker-compose.prod.yml. Build backend lean + worker-with-chromium + frontend → push в приватный GHCR → SSHgit reset --hard, sedSENTRY_RELEASE=$IMAGE_TAGвbackend/.env.runtime,compose pull && up -d,caddy reload,curl /health..github/workflows/deploy-obsidian.yml— obsidian: триггер наdocker-compose.obsidian.yml,scripts/setup-couchdb.sh,docs/obsidian-livesync.md. Без сборки образов (couchdb:3 с DockerHub), SSHcompose up -d+ idempotent bootstrap (CORS, DB, лимиты).
GitHub Secrets: DEPLOY_HOST, DEPLOY_USER, DEPLOY_SSH_KEY, DEPLOY_PORT. Сервер авторизуется в GHCR однократно через PAT с read:packages. COUCHDB_USER/COUCHDB_PASSWORD — в backend/.env.runtime на VPS (не в репе).
Триггеры миграции на Yandex Cloud: 3-й платящий пилот / Раунд А / госзаказ (нужен реестр ПО) / БД >10 GB / >50 RPS. На YC ~10–15 тыс ₽/мес.
Операционные грабли
docker compose restartНЕ перечитываетenv_file:— после правки.envвсегдаup -d --force-recreate --no-deps backend.deploy.ymlиспользуетgit reset --hard origin/main— ручные правки в/opt/gendesignбудут стёрты при следующем деплое (.env-файлы переживут — в.gitignore).- На проде всегда указывать
-f docker-compose.prod.yml(без него поднимет dev compose без Caddy). caddy reloadне сбрасывает retry-queue для ACME. При смене hostname с битым cert-state:docker volume rm gendesign_caddy_data && up -d caddy.
Roadmap (12 недель)
| Stage | Сроки | Что | Acceptance |
|---|---|---|---|
| 0 ✅ | нед. 1 | Скелет монорепо, CI, прод | curl /health = ok |
| Sprint 1 ✅ | конец апр 2026 | NSPD-скрейпер + per-bucket эластичность + кадастр cross-check + Sentry release tracking | recommend_mix Tier 3 в проде |
| 1a | нед. 2–3 | Shapely-сервис, отступы, API-контракт /concept (#5) |
GeoJSON → 3 заглушки |
| 1b | нед. 4–5 | Greedy-алгоритм, 3 стратегии, STRtree (#12) | 3 варианта ≤15с на 1 га |
| 1c | нед. 6–7 | ТЭП + финмодель + PDF/Excel/DXF (#6) | Продаваемый артефакт |
| 2a | нед. 8–9 | ПКК-парсер + sales_tracker (#7) | ≥1000 участков ЕКБ |
| 2b | нед. 10–11 | Скоринг + API + UI Site Finder (#8) | Карта с цветовой градацией |
| 2c | нед. 12 | Site Finder ↔ Generative + реестр ПО (#9) | 3 платящих пилота |
Аналитический backlog: #17 velocity-anomaly, #18 ekb_districts median refresh, #19 competitor-360, #20 mortgage-rate sensitivity, #21 cad_buildings filters в Site Finder.
Команда и память проекта
2 фуллстек-разработчика, part-time 20 ч/нед, ритм: 1 синк/нед, daily-async в Telegram, PR-review обязательный, trunk-based. Codegen TS-типов из Pydantic — npm run codegen.
Knowledge base — Obsidian vault
Источник правды — Obsidian vault на obsidian.gendsgn.ru (Self-hosted LiveSync + CouchDB). Markdown-файлы с [[wiki-links]], MOC-страницами, Graph View и тегами. Multi-device sync: desktop / laptop / iPhone / Android. 268 entities мигрированы из исторического JSONL knowledge graph (scripts/migrate_kg_to_obsidian.py), который теперь deprecated.
Структура vault:
meta/— гайды, credentials, project meta (Project_GenDesign, TechStack, NorthStar)domains/{domrf,cadastre,rosreestr,analytics,ui,api,geo,infra}/— knowledge по бизнес-доменамcode/{modules,schemas,patterns,hooks,tasks}/— code-level entitiesdecisions/— ADR / планы / политикиfixes/— bug-журналыsessions/,sprints/,events/— chronological logsresearch/,sources/,feedback/,github/,limitations/— прочееold/— архив legacy paths (redirect-stubs)
Подключение коллеги — гайды в самом vault'е:
meta/01_connect_devices.md— установка Obsidian + LiveSync на любую платформу (через Setup URI или 4 поля)meta/03_obsidian_plugins.md— какие плагины ставить (Local REST API, Templater, Dataview)meta/04_mcp_obsidian_setup.md— подключение Claude к vault через MCP
Legacy: старый knowledge graph JSONL (memory/memory-gendesign.jsonl) — снапшот на момент 2026-05-11, не обновляется. Все новые факты пишутся в Obsidian.
Где вести задачи — GitHub Issues vs Obsidian
Используем оба, но с чёткой ролью:
| GitHub Issues | Obsidian vault | |
|---|---|---|
| Что сюда | Bug + Feature + Refactor — всё с связью с кодом / PR | Knowledge: research, ADR, planning, draft-ideas |
| Lifecycle | Open → Assigned → PR → Merged → Closed | Append-only журнал решений и контекста |
| Уведомления | GitHub email/mobile + integrations | Никаких (читаешь когда сам пришёл) |
| Поиск | GitHub search + labels + milestones | BM25 + tags + Graph + MOC |
| Видимость | Команде в reviewer'ах | Всем у кого есть vault password |
| Сроки | Milestones (12-week roadmap) | Frontmatter date:, status:, due: |
Правило перехода: Obsidian fixes/Bug_X.md со status: OPEN → когда требует PR — создаём GitHub Issue, ссылку прописываем во frontmatter .md (github_issue: 42). Bug-исследование живёт в vault'е, action item — в Issues.
Что куда:
Bug_*(vault) + GitHub Issue с тегомbug→ обнаружен баг, фикс через PRdecisions/*(vault) — ADR, не нужен GitHub Issueresearch/*(vault) — анализ источников, конкуренты, метрикиsessions/*(vault) — журналы рабочих сессий- GitHub Issues
feat/*— фичи + PR на 1+ files, видимые в milestones
Полезные ссылки
| 🌐 Production | https://gendsgn.ru/ |
| 🩺 Health | https://gendsgn.ru/health |
| 📚 OpenAPI | https://gendsgn.ru/openapi.json · Swagger UI |
| 🗂 Knowledge vault | https://obsidian.gendsgn.ru (требуется Obsidian + Self-hosted LiveSync, см. vault meta/01_connect_devices.md) |
| Backlog | Issues · Milestones |
| Деплой | GitHub Actions · GHCR пакеты |
| Мониторинг | Sentry |
| Инфра | Beget VPS cp.beget.com/cloud/... · DNS |
Стратегические документы (снимки): docs/MVP_Goals_Python.md, docs/Бизнес-план v2.1 - Site Finder + Roadmap 12 месяцев.md, docs/obsidian-livesync.md. При расхождении с vault'ом — доверяем vault'у.