ADR
ADR-004: Connector abstraction
ADR-004: Connector abstraction
Статус: ✅ Accepted
Дата: 2026-06-11
Автор: openclaw-architect
Контекст
EcoYar использует как минимум 4 внешние системы, содержащие сигналы спроса:
- Яндекс.Метрика — аналитика посещений, поисковые запросы
- Яндекс.Директ — рекламные кампании, ключевые слова
- PHPShop — каталог товаров, заказы
- 1С (УНФ) — учёт, клиенты, отгрузки
Каждая система имеет разный API, разный формат данных, разную аутентификацию. Нужна единая абстракция для подключения внешних источников.
Рассматривались подходы:
- Индивидуальные интеграции — каждая система сама по себе
- Connector abstraction — единый интерфейс для всех
Решение
Выбираем Connector abstraction.
Все внешние интеграции реализуют единый интерфейс Connector:
interface Connector {
readonly id: string;
readonly type: ConnectorType;
// Получить сигналы из источника
fetchSignals(config: ConnectorConfig): Promise<Signal[]>;
// Отправить оффер в канал (для экспериментов)
pushOffer(offer: Offer, config: ConnectorConfig): Promise<PushResult>;
// Отследить эксперимент (получить метрики по вариантам)
trackExperiment(experiment: Experiment, config: ConnectorConfig): Promise<ExperimentTrackingData>;
// Получить измерения (конверсии, визиты и т.д.)
pullMeasurements(config: ConnectorConfig, period: TimeRange): Promise<Measurement[]>;
// Проверить доступность и валидность конфигурации
healthCheck(config: ConnectorConfig): Promise<HealthStatus>;
}
Абстракция в MVP
В MVP v0.1 Connector abstraction создаётся как интерфейс в packages/types/, но все коннекторы реализуются позже (v0.2). Данные импортируются вручную.
Последствия
Положительные (+)
- Единый контракт: Все интеграции выглядят одинаково для системы
- Расширяемость: Новый источник = новая реализация Connector
- Тестирование: Можно мокать Connector в тестах
- Изоляция: Проблемы одного коннектора не влияют на другие
Отрицательные (-)
- Overhead: Абстракция может не подойти для специфичных API
- Leaky abstraction: Уникальные возможности каждого источника могут не вписаться в общий контракт
Стратегия смягчения
- ConnectorConfig — generic, можно передавать специфичные параметры
- fetchSignals возвращает унифицированный Signal[], но raw_data хранит оригинал
- Методы помечены как optional (throw если не поддерживается)
- Используем паттерн Adapter — каждый Connector адаптирует конкретный API к общему интерфейсу
Связанные документы
- CONNECTOR_CONTRACTS.md (детали интерфейса)
- ARCHITECTURE_PRINCIPLES.md (Domain-Core Separation, Open-Closed Contexts)
- SCOPE_MVP_V0_1.md (Connector abstraction в фундаменте)
- DECISION_LOG.md (#004)