- FastAPI backend: PostGIS estimator + 3 scrapers (Avito/Cian/Yandex)
- Next.js 15 frontend: tradein.html mockup design, basePath=/trade-in
- WeasyPrint PDF (Брусника-style 4-page report)
- Address autocomplete с typo-tolerance + 6 EKB presets
- Изолированный docker stack gendesign-tradein (отдельная postgres БД)
- Caddy inline routes: gendsgn.ru/trade-in/* и /trade-in/api/v1/*
- Forgejo Actions: .forgejo/workflows/deploy-tradein.yml (shell-based GHCR login)
- Триггер только по paths: tradein-mvp/** (не пересекается с deploy.yml)
- Образы: ghcr.io/lekss361/gendesign-tradein-{backend,frontend}:latest
Первый запуск на сервере (вручную, один раз):
- создать /opt/gendesign/tradein-mvp/.env.runtime (postgres pwd, contact email)
- docker network create gendesign_shared (если нет)
- docker compose -p gendesign-tradein up -d
- docker compose -p gendesign exec caddy caddy reload
439 lines
23 KiB
Markdown
439 lines
23 KiB
Markdown
# Trade-In MVP — Roadmap «Максимум»
|
||
|
||
> Решение 19.05 вечером: убираем привязку к срокам, делаем максимально хорошо.
|
||
> План структурирован по архитектурным слоям, не по дням. Катимся сверху-вниз —
|
||
> каждый следующий слой требует, чтобы предыдущий был стабилен.
|
||
|
||
## Видение продукта
|
||
|
||
**Что есть у Брусники:** 4-стр PDF с медианой цен, диапазоном, аналогами и сравнением «их обмен vs самопродажа». Один white-label (Брусника). Один продукт.
|
||
|
||
**Что мы делаем поверх:**
|
||
|
||
1. **Парсим больше источников** (6 vs ~5 у Брусники): Авито, Циан, Дом.Клик, Я.Недвижимость, Н1, Дом.РФ
|
||
2. **Кликабельные ссылки** на каждый аналог — Брусника не даёт
|
||
3. **Real-time freshness** — индикатор «обновлено N минут назад» на каждом источнике
|
||
4. **Объяснимый confidence** — `high (12 аналогов, разброс ±8%)` вместо «качество данных может быть не очень»
|
||
5. **POI окружение** — школы / метро / магазины с decay по расстоянию (переиспользуем код gendesign Site Finder)
|
||
6. **Тренд цен** — график за 6/24 мес. в этом районе
|
||
7. **Map view** — карта с точками аналогов + heatmap
|
||
8. **Multi-tenant white-label** — PRINZIP / Практика / любой бренд через query param
|
||
9. **JSON API + iframe widget** — для интеграции в чужие CRM
|
||
10. **Похожие сделки в том же доме** — точные совпадения если есть
|
||
11. **AI narrative summary** — короткое описание квартиры от LLM
|
||
12. **Прогноз срока продажи** — median days_on_market по выборке
|
||
13. **Score breakdown explainability** — почему именно эта цена (как Site Finder)
|
||
14. **Photo upload** на cover PDF
|
||
15. **Shareable URL** + QR-код в PDF
|
||
|
||
---
|
||
|
||
## Слой 1 — Core data layer (фундамент)
|
||
|
||
Без него ничего не работает. Каждый последующий слой строится поверх.
|
||
|
||
### 1.1 Postgres schema
|
||
- `listings` — объявления (id, source, source_url, lat, lon, address, rooms, area, floor, total_floors, year_built, house_type, repair_state, price, price_per_m2, photo_urls jsonb, listing_date, scraped_at, dedup_hash, raw_payload jsonb, geom GEOMETRY(Point, 4326))
|
||
- `deals` — фактические сделки (тот же набор + deal_date, source = 'rosreestr' пока)
|
||
- `geocode_cache` — address → lat/lon кэш (избегаем повторных Yandex hits)
|
||
- `audit_log` — каждый POST /estimate (ip, user_agent, input, estimate_id, ts)
|
||
- `house_metadata` — кэш данных ЕКБ Геопортала по координатам/кадастру (этажи, год, материал, кол-во квартир)
|
||
- Индексы: GIST на geom, btree на (rooms, scraped_at), unique на dedup_hash
|
||
|
||
### 1.2 Geocoder + Suggest
|
||
- `app/services/geocoder.py` — Yandex Geocoder через httpx + кэш в `geocode_cache`
|
||
- `app/services/suggest.py` — Yandex Suggest для frontend autocomplete (proxy через backend, не светим API key в браузере)
|
||
- Fallback к Nominatim если Яндекс упал / лимит
|
||
|
||
### 1.3 Scraper framework
|
||
- `app/services/scrapers/base.py` — общий BaseScraper
|
||
- Retry через `tenacity` (3 попытки, exp backoff)
|
||
- Rotation: пул из 5-10 User-Agent + Accept-Language
|
||
- Sleep 5-10 sec между запросами (без бана)
|
||
- Поддержка Playwright если scrapy не справляется (Циан иногда JS-render требует)
|
||
- Дедупликация: `dedup_hash = sha256(source + source_url + price)` уникальный
|
||
- Каждый scraper возвращает list[ScrapedLot] — единая Pydantic схема
|
||
|
||
---
|
||
|
||
## Слой 2 — Парсеры источников
|
||
|
||
### 2.1 Авито (приоритет 1 — стартуем с него)
|
||
- URL: `/ekaterinburg/kvartiry/prodam?radius=N&geoCoords=lat,lon&list_view=1`
|
||
- Парс HTML через `selectolax` (быстрее BeautifulSoup)
|
||
- Поля: address, rooms, area, floor/total_floors, price, listing_date, photo, deeplink
|
||
- Edge case: «частный риэлтор» vs «агентство» — фильтруем спам
|
||
|
||
### 2.2 Циан ✅ ДЕПЛОЕН
|
||
- URL: `https://ekaterinburg.cian.ru/cat.php?...`
|
||
- ВАЖНО: Циан банит httpx по TLS fingerprint → `curl_cffi(impersonate="chrome120")`
|
||
- 2025+ верстка БЕЗ `__NEXT_DATA__` — парсим DOM по `data-mark` атрибутам:
|
||
`OfferTitle`, `MainPrice`, `Description`; адрес из множественных `data-name="GeoLabel"`
|
||
- Multi-room scrape: `fetch_around_multi_room()` по rooms=1/2/3/4 → ~108 unique lots
|
||
- Cron каждый час: `45 * * * * /opt/tradein-mvp/deploy/cron-scrape.sh cian fast`
|
||
|
||
### 2.3 Росреестр сделки
|
||
- Дамп из prod gendesign `rosreestr_deals` (6.83M строк, partitioned по кварталам)
|
||
- SSH туннель → `pg_dump --table rosreestr_deals --where "region_code = 66"` → restore локально
|
||
- Регулярный refresh: weekly Celery task
|
||
|
||
### 2.4 Дом.Клик
|
||
- API: `https://api.domclick.ru/...` (публичный, без auth, JSON)
|
||
- Поля: те же + ипотечные опции (мы пока игнорим)
|
||
|
||
### 2.5 Я.Недвижимость ✅ ДЕПЛОЕН
|
||
- URL: `https://realty.yandex.ru/ekaterinburg/kupit/kvartira/?rgid=240970&offerType=SELL`
|
||
- State в `<script id="initial_state_script">` JSON; path `state.map.offers.points`
|
||
- DATE_DESC возвращает одинаковые 20 лотов независимо от geoLat/geoLon
|
||
- Multi-room (`STUDIO/1/2/3/PLUS_4`) даёт 5× expansion → ~100 unique/anchor
|
||
- Deep mode (5 rooms × 3 sorts × 2 pages = 30 запросов / ~150s) → ~300 unique/anchor
|
||
- EXACT coords из `offer.location.point` (precision: EXACT) — без anchor jitter
|
||
- Cron каждые 3 часа: `0 */3 * * * /opt/tradein-mvp/deploy/cron-scrape.sh yandex deep`
|
||
|
||
### 2.6 Н1.ru (региональный, Урал)
|
||
- HTML scrape, очень простая структура
|
||
- Сильнее представлен в ЕКБ чем федералы
|
||
|
||
### 2.7 Дом.РФ (наш.дом.рф)
|
||
- API `kn-api` уже есть в gendesign (Playwright scraper)
|
||
- Только новостройки (ДДУ) — для вторички не критично, опционально
|
||
|
||
### 2.8 ЕКБ Геопортал (citymap.ekburg.ru)
|
||
- WMS/WFS API для зданий
|
||
- По lat/lon отдаёт: этажность, год постройки, материал, кол-во квартир, кадастровый номер
|
||
- Кэш в `house_metadata`
|
||
|
||
---
|
||
|
||
## Слой 3 — Aggregation model
|
||
|
||
### 3.1 Замена `_mock_estimate()` на реальный SQL
|
||
```sql
|
||
SELECT
|
||
percentile_cont(0.5) WITHIN GROUP (ORDER BY price_per_m2) AS median_ppm2,
|
||
percentile_cont(0.25) WITHIN GROUP (ORDER BY price_per_m2) AS q1_ppm2,
|
||
percentile_cont(0.75) WITHIN GROUP (ORDER BY price_per_m2) AS q3_ppm2,
|
||
COUNT(*) AS n_analogs
|
||
FROM listings
|
||
WHERE ST_DWithin(geom, ST_MakePoint(:lon, :lat)::geography, 800)
|
||
AND rooms = :rooms
|
||
AND area BETWEEN :area * 0.85 AND :area * 1.15
|
||
AND scraped_at > NOW() - interval '14 days'
|
||
```
|
||
|
||
### 3.2 Confidence score (объяснимый)
|
||
- `n_analogs ≥ 10 AND IQR/median < 0.15` → `high` («Найдено 12 аналогов, разброс цены ±8%»)
|
||
- `n_analogs ≥ 5 OR IQR/median < 0.25` → `medium`
|
||
- иначе → `low` («Только 3 аналога в радиусе 800м, рекомендуем проверить ручной поиск»)
|
||
|
||
### 3.3 Outlier detection
|
||
- Tukey fence: цена вне `[Q1 - 1.5*IQR, Q3 + 1.5*IQR]` → исключаем
|
||
- Логи: сколько отфильтровали
|
||
|
||
### 3.4 House match (приоритетные аналоги)
|
||
- Если есть листинг с тем же кадастровым номером дома → отдельно показываем как «в этом же доме»
|
||
- Соседние дома (тот же квартал) — следующий приоритет
|
||
|
||
### 3.5 Price trend
|
||
- Group by month, last 6/12/24 мес.
|
||
- Linear regression slope → "цены растут на N% / год"
|
||
|
||
### 3.6 Прогноз days_on_market
|
||
- Median + percentile по выборке
|
||
- «Аналогичные квартиры продаются за 30-90 дней»
|
||
|
||
---
|
||
|
||
## Слой 4 — Дифференциация (фишки выше Брусники)
|
||
|
||
### 4.1 POI окружение
|
||
- Reuse `app/services/poi_score.py` из gendesign
|
||
- Категории: school / kindergarten / metro_stop / bus_stop / shop_mall / shop_supermarket / park / hospital / pharmacy
|
||
- Distance decay (gendesign формула)
|
||
- Bonus к привлекательности района (не к цене, отдельно)
|
||
|
||
### 4.2 Map view
|
||
- Leaflet с пинами на каждый аналог
|
||
- Цветовая heatmap цен по м²
|
||
- Кликабельные popup'ы
|
||
|
||
### 4.3 AI narrative summary
|
||
- LLM call (Claude / GPT) → 2-3 предложения о квартире
|
||
- Промпт: «На основе следующих данных опиши квартиру: ...»
|
||
- Пример: «Двушка на Малышева в кирпичном доме 1985 года, требует ремонта. Цена в верхнем квартиле по району из-за центра.»
|
||
|
||
### 4.4 White-label
|
||
- Query param `?brand=prinzip|praktika|generic`
|
||
- В DB табличка `brands` (slug, logo_url, primary_color, footer_text)
|
||
- Header + PDF cover читают из brand
|
||
|
||
### 4.5 Shareable + QR
|
||
- URL `/trade-in?id=<uuid>` ✓ done
|
||
- В PDF cover — QR-код этого URL (через `segno` lib)
|
||
|
||
### 4.6 Photo upload
|
||
- `<input type="file" multiple accept="image/*">`
|
||
- Upload в `static/photos/<estimate_id>/`
|
||
- Первая фото → cover PDF
|
||
|
||
---
|
||
|
||
## Слой 5 — UX
|
||
|
||
### 5.1 Address autocomplete
|
||
- Yandex Suggest (через backend proxy)
|
||
- Debounced 300ms
|
||
- Показывать full address с городом
|
||
|
||
### 5.2 Кликабельные analogs
|
||
- В `AnalogsTable.tsx` — `<a href={listing.source_url} target="_blank">`
|
||
- Логотип источника рядом (Авито/Циан/...)
|
||
|
||
### 5.3 Loading states
|
||
- `EstimateProgress.tsx` уже есть скелет — заполнить:
|
||
- «Геокодируем адрес...»
|
||
- «Парсим Циан (12 объявлений)...»
|
||
- «Парсим Авито (28 объявлений)...»
|
||
- «Считаем медиану...»
|
||
- «Готово!»
|
||
|
||
### 5.4 Empty / error states
|
||
- 0 аналогов в 800м → fallback 2 км + warning
|
||
- Адрес не распознан → suggest альтернативы
|
||
- Парсер упал → grace degradation (показываем что есть)
|
||
|
||
### 5.5 Mobile + iPad
|
||
- Sticky form слева → переход в полноэкранный modal на mobile
|
||
- Tap-friendly buttons (min 44px)
|
||
- iPad: 2-column layout сохраняется
|
||
|
||
### 5.6 Dark mode (низкий приоритет)
|
||
- CSS vars уже подготовлены — добавить `@media (prefers-color-scheme: dark)` overrides
|
||
|
||
---
|
||
|
||
## Слой 6 — PDF
|
||
|
||
### 6.1 Кликабельные ссылки
|
||
- WeasyPrint поддерживает `<a href>` — просто добавить в шаблон
|
||
- В таблице аналогов адрес делаем линком
|
||
|
||
### 6.2 White-label header
|
||
- Logo + название бренда читается из `brands` таблицы
|
||
- PDF cover: бренд-цвет accent
|
||
|
||
### 6.3 График цен (стр. 3)
|
||
- Render chart как SVG через Python (`matplotlib` → SVG) или send to backend chart-renderer
|
||
- Линия median + диапазон Q1-Q3 + точки сделок
|
||
|
||
### 6.4 Карта на cover
|
||
- Static map image от Yandex Static Maps API
|
||
- Пин на квартире + circle радиуса поиска
|
||
|
||
### 6.5 QR-code
|
||
- `segno.make(shareable_url).save(buffer)` → embed в HTML template
|
||
|
||
### 6.6 Freshness footer
|
||
- «Данные собраны 19.05.2026 23:15. Источники: Авито (47), Циан (38), Росреестр сделки (12). Confidence: high.»
|
||
|
||
---
|
||
|
||
## Слой 7 — Auth + Analytics + Monitoring
|
||
|
||
(отложено из MVP, добавим перед demo Геныча/Тёмы)
|
||
|
||
### 7.1 Простой password gate
|
||
- Middleware: проверка cookie/header с shared secret
|
||
- Set-cookie на 30 дней при правильном вводе
|
||
- HTML form `/login` с одним полем «Пароль»
|
||
|
||
### 7.2 Audit log
|
||
- Каждый POST /estimate → INSERT в `audit_log` (ip, ua, input, output uuid)
|
||
- Каждый GET /estimate/{id}/pdf → INSERT
|
||
- Каждый click на оригинал листинга — если хотим точно (frontend → POST /analytics/event)
|
||
|
||
### 7.3 Analytics dashboard
|
||
- `/admin/analytics` — простая страница: топ-адреса, статистика по дням, conversion (form_open → form_submit → pdf_download)
|
||
- Или PostHog self-hosted (если хочется UI без писательства)
|
||
|
||
### 7.4 Rate limiting
|
||
- slowapi (FastAPI-friendly) — 10 POST /estimate per minute per IP
|
||
|
||
### 7.5 Monitoring
|
||
- Backend logs → файл + опционально Loki
|
||
- Health checks Caddy перепингует backend каждые 30 сек
|
||
|
||
---
|
||
|
||
## Слой 8 — Deployment & Production
|
||
|
||
### 8.1 Smoke test
|
||
- `make smoke-test` bash: 5 курлов на разные адреса ЕКБ → проверка HTTP 200 + confidence != low
|
||
- Запускать в CI и перед каждым деплоем
|
||
|
||
### 8.2 Backup strategy
|
||
- Cron pg_dump → S3 daily (или local если S3 нет)
|
||
- Test restore раз в неделю
|
||
|
||
### 8.3 Production deploy
|
||
- Опция A: deploy в существующий gendesign monorepo (просто merge изменений TI-2/TI-3 + новые парсеры) → выкатить на gendsgn.ru/trade-in
|
||
- Опция B: отдельный subdomain `tradein.gendsgn.ru` через отдельный docker stack на том же VPS
|
||
- Опция C: совсем отдельный VPS / отдельная репа в Forgejo
|
||
|
||
Решим когда дойдём — пока локально.
|
||
|
||
### 8.4 Multi-tenant infrastructure
|
||
- White-label через subdomain: `prinzip.tradein.gendsgn.ru` / `praktika.tradein.gendsgn.ru`
|
||
- Caddy wildcard cert + tenant detection из Host header
|
||
|
||
---
|
||
|
||
## Слой 9 — Advanced (после core готов)
|
||
|
||
### 9.1 ML-модель цены
|
||
- XGBoost regression на исторических сделках Росреестра
|
||
- Features: rooms, area, floor/total_floors, year, distance_to_center, POI score
|
||
- Сравнение с simple median: насколько лучше / стабильнее
|
||
|
||
### 9.2 iframe widget
|
||
- `<iframe src="https://tradein.gendsgn.ru/embed?brand=prinzip&width=400">`
|
||
- Минимальная форма + результат
|
||
- Для интеграции в чужие CRM
|
||
|
||
### 9.3 JSON API для интеграций
|
||
- API key auth
|
||
- POST /api/v2/trade-in/estimate с rate limits
|
||
- Документация Swagger
|
||
|
||
### 9.4 Push notifications
|
||
- «В вашем районе 2-к продалась за 11.5M — на 8% ниже вашей оценки»
|
||
- WebPush или Telegram bot
|
||
|
||
### 9.5 PRINZIP CRM integration
|
||
- API call в их 102K заявок
|
||
- Авто-оценка по конверту заявки
|
||
|
||
### 9.6 Птица integration
|
||
- Подсветка домов где ≥20% квартир в Циан/Авито
|
||
- Карта расселения + потенциальная стоимость участка
|
||
|
||
### 9.7 Multi-region
|
||
- После ЕКБ — Пермь, Челябинск, Новосибирск, Москва, СПб
|
||
- Yandex Geocoder покрывает всё
|
||
|
||
---
|
||
|
||
## Что уже есть (стартовая позиция)
|
||
|
||
✅ Backend: FastAPI + `/estimate` (mock) + `/estimate/{id}` + PDF endpoint + Pydantic schemas
|
||
✅ Frontend: Next.js page + 5 компонентов (EstimateForm/Result/Progress/PriceRangeBar/AnalogsTable)
|
||
✅ Infra: docker-compose (caddy + frontend + backend + postgres) запущен на localhost:8080
|
||
✅ Postgres: таблица `trade_in_estimates` создаётся автоматом
|
||
✅ PDF: WeasyPrint 4-page (cover/listings/deals/offer) работает
|
||
✅ Shareable URL: `/trade-in?id=<uuid>` ✓
|
||
✅ Reference docs: PDF Брусники + PDF Птицы в `docs/`
|
||
|
||
## Что сделано ночью 19→20 мая 2026
|
||
|
||
### Слой 1 — Core data layer
|
||
- ✅ **1.1** PostgreSQL schema: listings + deals + geocode_cache + audit_log + house_metadata + brands + PostGIS GIST индексы + auto-update geom trigger
|
||
- ✅ **1.2** Geocoder service (Yandex когда дашь key + Nominatim fallback) с кэшем 90 дней. Live тест: «ул. Малышева 30 Екатеринбург» → (56.8333, 60.5945), confidence exact
|
||
- ✅ **1.3** Scraper framework — BaseScraper async context + tenacity retry + 5 ротируемых User-Agent + ScrapedLot единая Pydantic схема + save_listings с дедуп
|
||
|
||
### Слой 2 — Парсеры
|
||
- ✅ **2.1 Авито парсер** — код готов (`scrapers/avito.py`), 2 стратегии (mobile API + HTML scrape). С маки через V2Box банится (302/429) — заработает с VPS Beget.
|
||
- 💾 **Seed данные** — 120 листингов + 60 сделок на 10 центральных улицах ЕКБ, реалистичное распределение (12 студий / 30 1к / 45 2к / 25 3к / 8 4к) с jitter цен и координат для тестирования
|
||
|
||
### Слой 3 — Aggregation
|
||
- ✅ **3.1** SQL aggregation поверх listings + deals: PostGIS `ST_DWithin` 800м (fallback 2 км) + комнаты ± 0 + площадь ±15% + Tukey IQR outlier filter + median/Q1/Q3 + confidence high/medium/low с человекочитаемым объяснением
|
||
|
||
### Слой 5 + 6 — Дифференциация vs Брусники
|
||
- ✅ **5.2** Frontend AnalogsTable теперь:
|
||
- **Source badges** цветные (avito/cian/domklik)
|
||
- **Distance column** (167м / 628м / 1.2км)
|
||
- **Кликабельные строки** — открывают оригинальное объявление в новой вкладке
|
||
- **Confidence explanation плашка** под медианой «Найдено 15 аналогов, разброс ±7%»
|
||
- **Source pills** + **freshness indicator** «● обновлено N мин назад»
|
||
- ✅ **6.1** PDF Listings/Deals таблицы: source badges + distance + кликабельные `<a href>` адреса (WeasyPrint)
|
||
- ✅ **6.5** **QR-код на cover** PDF (`segno` lib) — шёрить отчёт через QR scan
|
||
- ✅ **6.6** Freshness footer в PDF + список источников
|
||
|
||
### Слой 4 — White-label
|
||
- ✅ **4.4** Multi-tenant brands в Postgres (generic / prinzip / praktika) + `GET /api/v1/brand/{slug}` endpoint + `/pdf?brand=prinzip` query param. PDF header адаптируется (PRINZIP → чёрный header, generic → синий)
|
||
|
||
## Что НЕ сделано пока
|
||
|
||
### Слой 2 — Парсеры (отложено до prod deploy)
|
||
- 🟡 ЦИАН парсер — фреймворк готов, нужен код. Прод-IP обойдёт ban
|
||
- 🟡 Росреестр дамп из gendesign-postgres-1 (через SSH туннель)
|
||
- 🟡 ДомКлик, Я.Недвижимость, Н1, Дом.РФ
|
||
|
||
### Слой 3 — Advanced aggregation
|
||
- 🟡 House match — приоритетные аналоги в том же доме
|
||
- 🟡 Price trend regression (last 6mo slope) для «цены растут N%/год»
|
||
- 🟡 Прогноз days_on_market для «продаётся за 30-90 дней»
|
||
|
||
### Слой 4 — Доп. дифференциация
|
||
- 🟡 POI окружение (reuse gendesign) — школы/метро/магазины с decay
|
||
- 🟡 Map view (Leaflet) — пины + heatmap цен
|
||
- 🟡 AI narrative summary (LLM call) — описание квартиры
|
||
- 🟡 Photo upload на cover PDF
|
||
|
||
### Слой 5 — UX
|
||
- 🟡 Yandex Suggest autocomplete (нужен Yandex key)
|
||
- 🟡 Loading states «Парсим Циан... Авито... Расчёт...»
|
||
- 🟡 Empty state fallback
|
||
- 🟡 Mobile / iPad responsive
|
||
|
||
### Слой 6 — PDF extra
|
||
- 🟡 График цен на странице 3
|
||
- 🟡 Карта c пином на cover (Yandex Static Maps API)
|
||
- 🟡 Photo на cover (если загружено)
|
||
|
||
### Слой 7 — Auth + Analytics
|
||
- 🟡 Shared password middleware
|
||
- 🟡 Audit log INSERT с каждого POST /estimate
|
||
- 🟡 PostHog / analytics dashboard
|
||
- 🟡 Rate limiting
|
||
|
||
### Слой 8 — Deploy
|
||
- 🟡 Production deploy (gendsgn.ru/trade-in OR tradein.gendsgn.ru subdomain)
|
||
- 🟡 Backup cron pg_dump → S3
|
||
- 🟡 Smoke-test bash script
|
||
- 🟡 CI с авто-парсингом для freshness
|
||
|
||
### Слой 9 — Advanced
|
||
- 🟡 ML модель цены (XGBoost)
|
||
- 🟡 iframe widget
|
||
- 🟡 JSON API + key auth
|
||
- 🟡 PRINZIP CRM integration (102K заявок)
|
||
- 🟡 Птица integration (расселение)
|
||
- 🟡 Multi-region (Москва, СПб)
|
||
|
||
---
|
||
|
||
## Приоритет реализации
|
||
|
||
Иду сверху вниз, но внутри слоя могу параллелить независимые таски (например, 2.1 Авито и 2.2 Циан — независимые).
|
||
|
||
**Критический путь** (минимум чтобы вообще работало):
|
||
1.1 → 1.2 → 1.3 → 2.1 → 3.1 → 3.2 → 5.2 → 6.1
|
||
|
||
Всё остальное — incremental quality wins поверх.
|
||
|
||
---
|
||
|
||
## Решения 19.05.2026
|
||
|
||
- ✅ Геокодинг: **Yandex Geocoder + Suggest API**
|
||
- ✅ Источники к MVP: **Авито + Циан + Росреестр (дамп с prod)**, затем +ДомКлик/Я.Нед/Н1/Дом.РФ
|
||
- ✅ Auth: отложен в Слой 7 (добавим перед demo)
|
||
- ✅ Срок: убран, делаем максимально хорошо
|
||
- ✅ Деплой: пока локально, продакшен решим когда дойдём
|
||
|
||
## Что нужно от Антона
|
||
|
||
1. **Yandex Geocoder API key** — registration на developer.tech.yandex.ru (10 мин). Альтернатива — переиспользуем gendesign'овский если есть
|
||
2. Подтверждение SSH доступа к prod (gendesign_deploy ключ уже работает) для `pg_dump rosreestr_deals`
|
||
3. **Logo PRINZIP** (svg/png) — когда дойдём до Слоя 6.2, не блокирует старт
|
||
4. Решение по production deploy (Слой 8.3) — но это позже
|