Архитектура · FinDrive
Архитектурный комитет · интеграция с бэкофисом FinDrive

Два капабилити, которые видит бэкофис

AutoParser отдаёт бэкофису FinDrive ровно две точки интеграции — оценку справедливой цены и мониторинг залоговых авто. Ниже — какие БД, сервисы и бизнес-процессы стоят за каждой из них, сверено напрямую по коду репозитория. Сам API-контракт (submit+poll, KPI, топология) описан отдельным документом интеграции — здесь речь только о данных и устройстве самого AutoParser.

01

База данных и схема данных

Одна рабочая БД, изолированная от остальных проектов на сервере. Ниже — только домены, задействованные в оценке и мониторинге; общий пул объявлений питает обе точки интеграции.

Технология

PostgreSQL 16, отдельный контейнер compose-проекта autoparser на hz-sandbox. Порт наружу не публикуется — доступ только через docker exec. Данные на выделенном SSD-томе.

Доступ из кода

SQLAlchemy 2.0 (Declarative + Mapped), драйвер psycopg (psycopg3). Схема версионируется Alembic-миграциями.

Изоляция

БД не шарится с другими проектами сервера (finstar-portfolio, dealer-watch, compliance). Отдельная SQLite — только подписчики Telegram-бота нотифаера, общая с dealer-watch, бизнес-данных не хранит.

Отдельной БД для FinDrive backoffice в контуре AutoParser нет

Заявки и клиенты хранятся в MongoDB бэкофиса. AutoParser получает только pass-through order_id/order_url на таблице monitored_vehicle — это ссылка на заявку, а не копия её данных.

Схема — 23 таблицы (src/autoparser/db/models.py), сгруппированные по доменам:

Краулинг

ТаблицаКлючевые поляСвязи
source_sitecode, name—
crawl_runsearch_url, status, счётчики страниц/записей→ source_site

Объявления

ТаблицаКлючевые поляСвязи
vehicle_listingexternal_id, brand/model/year, price_rub, vin_full/masked, listing_status, dealer_shop_url→ source_site, → catalog_generation
vehicle_snapshotprice_rub, mileage_km, observed_at — delta-запись при изменении→ vehicle_listing, → crawl_run

Каталог (наш) & Каталог (внешний, Cars-Base)

ТаблицаКлючевые поляСвязи
catalog_brand → catalog_model → catalog_generationslug/name, year_start/end, match_phraseиерархия по цепочке
carbase_mark / carbase_model / carbase_generationзеркало справочника Cars-Base→ catalog_* (nullable, матчинг)

Оценка (valuation)

ТаблицаКлючевые поляСвязи
valuation_runmode, request/pricing/sgr/risk_matrix (JSONB), report—
valuation_feedbackverdict, comment, correct_price_rub→ valuation_run (CASCADE)
valuation_jobstatus (queued/running/done/error), idempotency_key→ valuation_run

Мониторинг залога

ТаблицаКлючевые поляСвязи
monitored_vehiclevin_full, status, order_id/order_url (FinDrive)→ vehicle_listing
monitored_listingstatus (active/sold/unavailable), last_price_rub→ monitored_vehicle, → vehicle_listing
monitoring_eventevent_type, payload, notified_at (outbox Telegram)→ monitored_vehicle, → vehicle_listing

Домены «Дилеры» и «Дилерский сток» (8 таблиц: dealer, dealer_account, dealer_account_listing, dealer_link_candidate, dealer_metric_snapshot, dealer_shop_crawl, dealer_event, dealer_stock_snapshot) — отдельная внутренняя бизнес-линия AutoParser (мониторинг витрин дилеров-клиентов), не связана с интеграцией с бэкофисом FinDrive. Здесь не показаны.

02

Application Services, выявляющие бизнес-сущности

Явного DDD-слоя application_service/ в коде нет — но фактическое разделение обязанностей ему соответствует.

Роутеры (web/app.py) тонкие и делегируют в сервисные модули; сервисные модули оркестрируют выявление бизнес-сущностей и не занимаются HTTP; repository-слой (pipeline/repository.py, monitoring/repo.py, dealers/repo.py) — только CRUD/upsert, без бизнес-логики.

Python owns arithmetic, LLM owns reasoning

Все числа считает детерминированный код. LLM участвует только в интерпретации — аналитический отчёт, фотосверка — и никогда не пересчитывает цифры.

СервисПутьВходВыход (бизнес-сущность)Тип
Нормализация объявленийsources/*/normalizer.pyсырой HTML/JSON площадкиVehicleListingDTOдетерминированный
Ingestion (per-source)pipeline/*_ingest.pyстраницы источникаvehicle_listing + vehicle_snapshotдетерминированный
VIN-идентификацияagent/vin_identify.pyVIN-префиксбренд/модель/комплектациядетерминированный
Матчинг залогаmonitoring/matcher.pyзаявка + пул объявленийранжированные candidate (score/reasons)детерминированный
Оркестрация мониторингаmonitoring/service.py + photo_match.pyзаявка + фото залогаmonitored_vehicle/monitored_listing + событиесмешанный
Оценка цены — арифметикаagent/pricing.pyвыборка аналоговfair_price, риск-матрица, срок продажидетерминированный
Оценка цены — оркестраторagent/valuation.py (+ SGR-tools)ValuationRequestvaluation_run + отчётсмешанный

FinDrive-заявки/клиенты как полноценные сущности (Order/Client) в репозитории AutoParser не моделируются — они живут в MongoDB бэкофиса; AutoParser получает только order_id/order_url как pass-through-поле.

Сервисы дилерского домена (dealers/{dedup,linker,discovery}.py) и Telegram-уведомления (monitoring/notify.py, dealers/notify.py) обслуживают другие процессы AutoParser — канал не проходит через бэкофис (тот получает результат через polling, а не push) — здесь не показаны.

03

Ландшафт бизнес-процессов

Две точки интеграции с бэкофисом FinDrive, общий источник объявлений, единый партнёрский фасад наружу — без выдуманных связей, только то, что реально есть в коде.

Общий вход (не специфичен для FinDrive)

Сбор и нормализация
объявлений ⇒
sources/*/normalizer.py
pipeline/*_ingest.py
Avito · Drom · Auto.ru ·
Freshauto · Autospot · CloakBrowser
питает → Точку 1 и → Точку 2

Точка 1 · Оценка справедливой цены

Оценка справедливой
цены ⇒
agent/pricing.py
agent/valuation.py (+ SGR)
LLM-провайдер (LiteLLM/OpenRouter)
Бэкофис FinDrive
также питает → Партнёрский API
valuation_run→
Верификация оценки
(feedback) ⇒
agent/feedback_repo.py
/feedback
Оператор-верификатор

Точка 2 · Мониторинг залога

Мониторинг залоговых
авто ⇒
monitoring/matcher.py
monitoring/service.py
Бэкофис FinDrive · LLM-vision ·
сайты-источники (адресный поиск)
также питает → Партнёрский API

Наружу — единый фасад

Партнёрский интеграционный API ⇒
web/app.py (/api/v1/*)
web/partner_docs.py
Бэкофис FinDrive
← вход: Точка 1 (submit+poll) · Точка 2 (submit+poll)

Детали по каждому процессу:

#ПроцессВнутренние компонентыВнешние компонентыВходВыход
0Сбор и нормализация объявлений (общий вход)sources/*/normalizer.py, pipeline/*_ingest.py, pipeline/repository.pyAvito, Drom, Auto.ru, Freshauto, Autospot; CloakBrowserHTML/JSON страницы источниковvehicle_listing + vehicle_snapshot
1Точка 1 — Оценка справедливой ценыagent/pricing.py, agent/valuation.py, risk_matrix.py, sell_time.py, SGR-tools, web/jobs.pyLLM-провайдер; Бэкофис FinDriveзаявка на оценкуvaluation_run (fair_price, риск-матрица, срок продажи, отчёт)
1aВерификация оценкиagent/feedback_repo.py, /feedbackОператор-верификаторvaluation_runvaluation_feedback
2Точка 2 — Мониторинг залоговых автоmonitoring/{matcher,service,status_check,targeted_search,photo_match,repo}.pyБэкофис FinDrive; LLM-vision; сайты-источникиVIN+характеристики+фото + пул объявленийmonitored_vehicle/monitored_listing + событие
3Партнёрский интеграционный APIweb/app.py (/api/v1/*), web/partner_docs.pyБэкофис FinDriveHTTP submit/pollрезультаты точек 1 и 2 (Bearer + Idempotency-Key)

Мониторинг дилеров и Telegram-уведомления — отдельные процессы AutoParser вне контура интеграции с бэкофисом FinDrive, здесь не показаны (см. раздел 2 выше).

Контракт интеграции с бэкофисом — отдельно

Методика оценки цены →