Skip to content

Раздел 1: Архитектура

Проект: ADOLF — AI-Driven Operations Layer Framework
Модуль: Watcher / Architecture
Версия: 4.0
Дата: Февраль 2026


1.1 Принципы проектирования

ПринципОписание
ДвухчастностьCollector (сбор данных) и Analyzer (аналитика) — независимые подсистемы
Автономность CollectorРаботает без подключения к основному серверу ADOLF; связь только через Knowledge Pipeline
РаспределённостьДомашние ПК как браузерные агенты, VPS как управляющий узел
ОтказоустойчивостьВыход ПК из строя не останавливает систему; автоматическое обнаружение и повторные попытки
МасштабируемостьПул ПК расширяется без изменения архитектуры (порты 9300–9399, до 100 агентов)
Защита от блокировокДомашние IP, FRP-туннели, эмуляция поведения, оркестрация чередования
Минимализм зависимостей4 npm-пакета для Collector; native HTTP-серверы без фреймворков

1.2 Топология развёртывания


1.3 Компоненты Collector

Карта процессов и портов

Процессsystemd-сервисПортПротоколОписание
frpsfrps.service7000 (туннели), 7500 (Admin API)TCP, HTTPFRP-сервер для туннелей к домашним ПК
cdp-pool.jscdp-pool.service3000HTTPУправление пулом браузеров
bot.jswatcher-bot.serviceTelegram APIБот + scheduler + orchestrator + runner
api.jswatcher-api.service3002HTTP/JSONREST API для программного доступа
monitor/server.jswatcher-monitor.service3001HTTP + WebSocketWeb-интерфейс мониторинга
nginxnginx.service443HTTPSReverse proxy + SSL (agent.adolf.su)

Взаимодействие компонентов

Жизненный цикл задачи


1.4 Подробная архитектура компонентов

cdp-pool.js — Пул браузеров

Автономный процесс, управляющий жизненным циклом подключений к домашним ПК.

Ключевые параметры: стабильность после 60 секунд online (защита от flapping), удаление из пула после 30 минут offline, автообнаружение новых ПК через FRP Admin API.

bot.js — Telegram-бот

Точка входа Collector (node bot.js). Запускает scheduler.js при старте. Принимает команды из Telegram и обрабатывает их.

Типы входных данных:

ВводИнтерпретация
WB125487Быстрый скан продавца 125487 на Wildberries
OZ465656Быстрый скан продавца 465656 на Ozon
YM213246Быстрый скан продавца 213246 на Яндекс.Маркет
Голое числоВыбор маркетплейса через inline-кнопки
/add <mp> <id> <имя>Добавление продавца в отслеживание
/scan <id>Ручной запуск сканирования
/enrich <id>Ручной запуск обогащения

Полный список команд описан в Разделе 2: Telegram-бот и планировщик.

scheduler.js — Планировщик

Работает внутри процесса bot.js. Управляет шестью циклическими задачами.

ЦиклИнтервал по умолчаниюHot-reloadОписание
checkSchedules5 минНет (после рестарта)Проверяет next_scan_at, создаёт задачи в очереди
checkEnrichSchedules5 минНет (после рестарта)Проверяет next_enrich_at, создаёт enrich-задачи
tryRunNext30 секНет (после рестарта)Берёт задачи из очереди, запрашивает ПК, запускает
monitorPCs15 секНет (после рестарта)Отслеживает online/offline ПК, отправляет алерты
rotateFiles24 часаНет (после рестарта)Удаляет старые файлы результатов
morningSummary05:00 UTC (ежедневно)ДаУтренняя сводка в Telegram

Пять интервалов планировщика применяются только после перезапуска сервиса. Остальные 18 параметров конфигурации (оркестратор, раннер, монитор) применяются мгновенно через hot-reload.

orchestrator.js — Оркестратор

Алгоритм выбора ПК для задачи. Реализует скоринговую модель с штрафами и бонусами.

История назначений хранится в таблице assignments (SQLite), что обеспечивает персистентность при перезапусках.

runner.js — Исполнитель

Запускает сканеры и обогатители как дочерние процессы (child_process.spawn).

ПараметрСканированиеОбогащение
Процессnode SKILL/scanner_*.js <seller_id>node SKILL/enricher_*.js <seller_id>
Переменные окруженияCDP_PORT, MARKETPLACE, SELLER_SLUGCDP_PORT (если нужен CDP)
Таймаут3 часа (runner.scanTimeoutMs)30 мин (runner.enrichTimeoutMs)
Повторные попыткиДо 3 (runner.maxRetries)Нет
Требует CDPВсегдаWB — нет; Ozon, YM — да
Результатresults/results_seller_<id>.jsonresults/enriched_seller_<id>.json
Архивная копияresults/catalog/{mp}_seller_{id}_{date}.jsonresults/enriched/{mp}_seller_{id}_{date}.json

Параллельность: runner поддерживает запуск нескольких задач одновременно (по числу свободных ПК). Каждая задача отслеживается в Map по scanId.


1.5 Компоненты Analyzer

Analyzer работает на основном сервере ADOLF в составе Python/FastAPI-стека.

Взаимодействие с Knowledge

Analyzer не хранит данные о конкурентах самостоятельно. Все данные извлекаются из Qdrant через модуль Knowledge:

ОперацияМетодОписание
Поиск по продавцуSemantic searchПоиск документов по seller_id + marketplace
Поиск по SKUSemantic searchПоиск обогащённых данных конкретного товара
Поиск измененийMetadata filterФильтр по subcategory: price_changes + дате
АгрегацияMulti-queryСбор данных за период для трендового анализа

Open WebUI интеграция

КомпонентТипОписание
Watcher PipelinePipelineОбработка запросов о конкурентах через RAG
Watcher ToolsToolПрямые API-вызовы для структурированных данных
Watcher AlertsNotificationPush-уведомления о критических изменениях

1.6 Потоки данных

Поток 1: Сканирование каталога

Поток 2: Обогащение данных

Поток 3: Knowledge Pipeline


1.7 Инфраструктура

FRP-туннели

FRP (Fast Reverse Proxy) обеспечивает подключение к домашним ПК без проброса портов на роутерах.

КомпонентРасположениеКонфигурация
frps (сервер)VPSПорт 7000 (туннели), 7500 (Admin API, Basic auth)
frpc (клиент)Каждый домашний ПКПробрасывает локальный Chrome CDP-порт (9222) на VPS (9300–9399)

Автоназначение портов: remotePort = 0 в конфиге frpc — сервер выделяет порт из диапазона 9300–9399 автоматически. CDP Pool обнаруживает новые туннели через FRP Admin API каждые 10 секунд.

Nginx

Reverse proxy agent.adolf.su с SSL (Let's Encrypt).

LocationUpstreamОписание
/api/v1/*127.0.0.1:3002REST API (api.js)
/api/*127.0.0.1:3001Monitor API
/ws127.0.0.1:3001WebSocket (Monitor)
/127.0.0.1:3001Frontend Monitor (через Node.js для auth-проверки)

systemd-сервисы

СервисЗависимостиОписание
frps.serviceFRP-сервер (запускается первым)
cdp-pool.servicefrps.serviceCDP Pool API
watcher-bot.servicecdp-pool.serviceTelegram-бот + scheduler + orchestrator + runner
watcher-api.serviceREST API (независимый процесс)
watcher-monitor.servicecdp-pool.serviceWeb UI backend
nginx.serviceReverse proxy

Порядок запуска: frps → cdp-pool → watcher-bot. Остальные сервисы могут запускаться параллельно.


1.8 Система конфигурации

Централизованный конфиг (config.js)

Все настраиваемые параметры хранятся в config.json и управляются через модуль config.js.

ХарактеристикаОписание
ФорматJSON (config.json)
ДефолтыВстроены в config.js, применяются при отсутствии файла
Hot-reloadfs.watchFile с интервалом 2 секунды
ВалидацияТип, min/max, кросс-валидация
APIget(dotPath), set(dotPath, value), getAll(), getSchema()
Параметров23 (7 оркестратор, 12 планировщик, 3 раннер, 1 монитор)

Группы параметров

ГруппаКол-воHot-reloadПримеры
orchestrator7ДаpenaltySameSeller, cooldownMinMs, idleBonusMax
scheduler12Частично (5 интервалов — после рестарта)defaultScanScheduleHours, enrichLimit, catalogKeepPerSeller
runner3ДаscanTimeoutMs, enrichTimeoutMs, maxRetries
monitor1ДаpollIntervalMs

Изменение через Web UI: вкладка «Настройки» на agent.adolf.su. Автосохранение с debounce 800 мс, WebSocket-синхронизация между вкладками.


1.9 Зависимости

npm-пакеты Collector

ПакетВерсияНазначение
better-sqlite3^12.6.2SQLite с синхронным API
dotenv^17.2.4Переменные окружения из .env
node-telegram-bot-api^0.63.0Telegram Bot API
playwright-core^1.58.2CDP-подключение к браузерам

Сканеры и обогатители используют playwright-core для CDP-подключения. Playwright не управляет установкой браузера — Chrome установлен на домашних ПК пользователями вручную.

Внешние зависимости Monitor

РесурсИсточникНазначение
Tailwind CSSCDNСтилизация UI
Lucide IconsCDNИконки
WebSocket (ws)npm (в monitor/package.json)Realtime-обновления

Python-зависимости Analyzer

ПакетНазначение
FastAPIREST API
CeleryФоновые аналитические задачи
RedisКэш и очередь
qdrant-clientВзаимодействие с Qdrant
httpxHTTP-запросы (при необходимости)

1.10 Безопасность

Collector

УровеньМеханизм
TelegramADMIN_CHAT_ID — доступ только для администратора
Web MonitorLogin/password, HttpOnly cookie-сессия (7 дней)
REST APIСлушает 127.0.0.1:3002 — недоступен извне напрямую
CDP PoolСлушает 127.0.0.1:3000 — только локальный доступ
FRP AdminBasic auth на 127.0.0.1:7500
NginxSSL (Let's Encrypt), проксирование через auth-проверку
.envСекреты (BOT_TOKEN, ADMIN_CHAT_ID) вне git

Analyzer

УровеньМеханизм
APIADOLF Core Middleware (JWT, роли)
ДанныеФильтрация по brand_id и access_level через ролевую модель
Open WebUIСтандартная авторизация ADOLF

1.11 Отказоустойчивость

СценарийПоведение
ПК ушёл offline во время задачиRunner фиксирует таймаут, задача переходит в failed, автоповтор (до 3 раз)
CDP Pool недоступенScheduler использует fallback: если runner не занят, пытается запустить одну задачу
Все ПК нарушают правила чередованияOrchestrator назначает cooldown (5–10 мин), задача откладывается
Ошибка сканера (CAPTCHA, crash)try/catch на уровне SKU, сохранение прогресса каждые 20 SKU, resume при рестарте
config.json повреждёнconfig.js использует встроенные дефолты
Перезапуск bot.jsСостояние задач в SQLite, очередь восстанавливается; история назначений сохранена
Потеря связи VPS → основной серверKnowledge Pipeline откладывает передачу; данные накапливаются на VPS

1.12 Файловая структура проекта

/opt/watcher/
├── bot.js                  # Telegram-бот (точка входа)
├── scheduler.js            # Планировщик задач
├── orchestrator.js         # Оркестратор (распределение по ПК)
├── runner.js               # Исполнитель задач
├── config.js               # Конфигурация (hot-reload)
├── config.json             # Файл конфига (создаётся автоматически)
├── api.js                  # REST API (:3002)
├── cdp-pool.js             # CDP Pool Service (:3000)
├── cdp.js                  # CDP Client Module
├── db.js                   # БД (SQLite)
├── utils.js                # Утилиты (computeDiff)
├── package.json            # 4 зависимости
├── .env                    # Секреты (gitignored)
├── watcher.db              # SQLite база (gitignored)
├── frp-port-memory.json    # Персистентная карта FRP-портов

├── SKILL/
│   ├── SKILL.md            # Описание skill для Claude Code
│   ├── scanner_wb.js       # Сканер Wildberries (CDP)
│   ├── scanner_ozon.js     # Сканер Ozon (CDP)
│   ├── scanner_ymarket.js  # Сканер Яндекс.Маркет (CDP)
│   ├── enricher_wb.js      # Обогатитель Wildberries (HTTP)
│   ├── enricher_ozon.js    # Обогатитель Ozon (CDP)
│   ├── enricher_ymarket.js # Обогатитель Яндекс.Маркет (CDP)
│   └── human.js            # Эмуляция поведения

├── monitor/
│   ├── server.js           # Backend Web UI (:3001)
│   ├── package.json        # Зависимость: ws
│   └── public/             # Frontend (HTML/CSS/JS)
│       ├── index.html
│       ├── login.html
│       └── ...

├── results/                # JSON-результаты (gitignored)
│   ├── results_seller_*.json     # Текущие результаты сканов
│   ├── enriched_seller_*.json    # Текущие результаты обогащения
│   ├── catalog/                  # Архив сканов (датированные)
│   └── enriched/                 # Архив обогащений (датированные)

└── logs/                   # Логи сканов (gitignored)
    └── scan_<id>_<seller>.log

Документ подготовлен: Февраль 2026
Версия: 4.0
Статус: Черновик

Документация ADOLF Platform