Add developer docs for CA/CP/PI flows and wire cp-workers to the host SOCKS proxy so local Telegram auth and parsing work reliably. Co-authored-by: Cursor <cursoragent@cursor.com>
89 lines
3.6 KiB
Markdown
89 lines
3.6 KiB
Markdown
# Contracts — общие схемы
|
|
|
|
Каталог [`contracts/`](../contracts/) — shared truth для формы данных и маршрутизации между ЦА и ЦП.
|
|
|
|
Правило платформы: **сначала contracts**, потом реализация в CA/CP/UI.
|
|
|
|
---
|
|
|
|
## Модули
|
|
|
|
| Файл | Назначение |
|
|
|------|------------|
|
|
| [`jobs.py`](../contracts/jobs.py) | Контракт задания. Payload задания в Redis |
|
|
| [`ingest.py`](../contracts/ingest.py) |Контракт результата. Событие и пакет ingest |
|
|
| [`sources.py`](../contracts/sources.py) | Контракт настроек парсера. Схемы `source_config` по `source_type` |
|
|
| [`queues.py`](../contracts/queues.py) | Контракт доставки задания нужному воркеру. `source_type` → family → Redis key |
|
|
|
|
ЦА при admin CRUD валидирует конфиг через `parse_source_config`.
|
|
ЦП адаптеры должны отдавать dict, совместимые с `IngestEventItem`.
|
|
|
|
> На практике CA дублирует часть DTO в `app/schemas.py` для FastAPI; при изменении формы сверяйте оба места и UI.
|
|
|
|
---
|
|
|
|
## JobPayload (`jobs.py`)
|
|
|
|
```python
|
|
class JobPayload(BaseModel):
|
|
job_id: int
|
|
source_type: str
|
|
source_config: dict = {}
|
|
```
|
|
|
|
Уходит в Redis как JSON. Семейство очереди выбирается по `source_type`, не по содержимому config.
|
|
|
|
---
|
|
|
|
## Ingest (`ingest.py`)
|
|
|
|
Ключевые поля `IngestEventItem`:
|
|
|
|
| Поле | Обязательность | Заметка |
|
|
|------|----------------|---------|
|
|
| `source_url` | да | Стабильный URL; дедуп в ЦА |
|
|
| `source_type` | да (часто default) | Должен соответствовать адаптеру |
|
|
| `raw_text` / `title` / `description` | нет | Текст события |
|
|
| `latitude` / `longitude` | нет | Без них точка на карту не создаётся |
|
|
| `event_date`, `locality`, `region`, `topic` | нет | Фильтры карты и ПИ |
|
|
| `tags`, `metadata` | нет | Расширения |
|
|
|
|
Пакет: `{ job_id?, events: [...] }`.
|
|
Listener добавляет флаг `listener: true` на стороне CA API (см. internal schemas).
|
|
|
|
---
|
|
|
|
## Source config (`sources.py`)
|
|
|
|
| source_type | Модель | Главные поля |
|
|
|-------------|--------|--------------|
|
|
| `telegram` | `TelegramSourceConfig` | `channel`, `limit`, `extract_mode` (`heuristic`\|`llm`) |
|
|
| `crawl4ai` | `Crawl4AISourceConfig` | `urls`, `extract_mode`, `extract_schema`, `domain_profile` |
|
|
| `viina` | `ViinaSourceConfig` | `urls` / `texts`, `input_mode` |
|
|
|
|
Реестр: `CONFIG_MODELS` + `parse_source_config(source_type, raw)`.
|
|
|
|
---
|
|
|
|
## Очереди (`queues.py`)
|
|
|
|
```text
|
|
SOURCE_FAMILY = {
|
|
"telegram": "telegram", # cp:jobs:telegram
|
|
"crawl4ai": "web", # cp:jobs:web
|
|
"viina": "nlp", # cp:jobs:nlp
|
|
}
|
|
```
|
|
|
|
- `queue_key_for_source(source_type)` — куда enqueue из ЦА.
|
|
- Legacy-ключ `cp:jobs` ещё может дренироваться telegram-воркерами (совместимость).
|
|
|
|
При добавлении нового `source_type` обязательно:
|
|
|
|
1. схема в `sources.py`;
|
|
2. запись в `SOURCE_FAMILY`;
|
|
3. адаптер + registry + (при необходимости) новый Docker-сервис;
|
|
4. поля формы в `ParsersView.vue`.
|
|
|
|
Чеклист: [`.cursor/skills/add-parser-adapter/`](../.cursor/skills/add-parser-adapter/).
|