Files
MapMil/docs/contracts.md
T
gitrusprusandCursor 6dff3c1c3d Document platform architecture and Telegram proxy local setup.
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>
2026-08-15 22:57:07 +03:00

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/).