Add Profile/Channel entities with CRUD and remove legacy parser builder.
Introduce reusable ParserProfile and ParseChannel, pair jobs with enqueue flatten, Events admin CRUD, and drop inline/legacy parser-builder UI and aliases. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -58,12 +58,13 @@ centers/analytics/
|
||||
│ ├── routers/
|
||||
│ │ ├── objects.py # /api/health, /api/objects, media
|
||||
│ │ ├── map.py # /api/map/*
|
||||
│ │ ├── admin.py # /admin/*
|
||||
│ │ ├── parser_builder.py # /admin/parser-builder/*
|
||||
│ │ ├── admin.py # /admin/* (jobs, events, consumers)
|
||||
│ │ ├── parser_profiles.py # /admin/parser-profiles/*
|
||||
│ │ ├── parse_channels.py # /admin/parse-channels/*
|
||||
│ │ ├── internal.py # /internal/* (только ЦП)
|
||||
│ │ └── v1.py # /api/v1/* (ПИ)
|
||||
│ └── services/
|
||||
│ ├── jobs.py # Redis RPUSH
|
||||
│ ├── jobs.py # Redis RPUSH + flatten Profile/Channel
|
||||
│ ├── scheduler.py # периодический re-queue
|
||||
│ ├── ingest.py # дедуп + map sync
|
||||
│ ├── parser_builder.py # DeepSeek → HeuristicProfile (один раз)
|
||||
@@ -76,7 +77,7 @@ centers/analytics/
|
||||
├── Dockerfile # Vite build + nginx
|
||||
├── nginx.conf # proxy /api /admin /internal → ca-api
|
||||
└── src/
|
||||
├── views/ # Map, Parsers, ParserBuilder, Events, …
|
||||
├── views/ # Map, Channels, Profiles, Parsers, …
|
||||
├── components/ # карта, CRUD объектов
|
||||
├── api/ # HTTP-клиенты
|
||||
└── router/index.ts
|
||||
@@ -87,7 +88,9 @@ centers/analytics/
|
||||
| Модель | Таблица | Назначение |
|
||||
|--------|--------|------------|
|
||||
| `Event` | `events` | Нормализованное событие; UK `source_url` |
|
||||
| `ParseJob` | `parse_jobs` | Конфиг парсера, интервал, статус |
|
||||
| `ParserProfile` | `parser_profiles` | Статичный heuristic-профиль (JSON-правила) |
|
||||
| `ParseChannel` | `parse_channels` | Канал (Telegram handle) |
|
||||
| `ParseJob` | `parse_jobs` | Связка канал+профиль, интервал, статус; FK `profile_id` + `channel_id` |
|
||||
| `MapObject` | `map_objects` | Точка на карте (event или ручная) |
|
||||
| `ObjectMedia` | `object_media` | Файлы к объектам |
|
||||
| `Consumer` | `consumers` | Подписчик ПИ (hash ключа) |
|
||||
@@ -98,26 +101,34 @@ centers/analytics/
|
||||
| Prefix | Кто вызывает | Содержание |
|
||||
|--------|--------------|------------|
|
||||
| `/api/*` | UI, публичный health | Карта, объекты, медиа |
|
||||
| `/admin/*` | UI admin | Jobs, events, analytics, consumers, parser-builder |
|
||||
| `/admin/*` | UI admin | Jobs, channels, profiles, events, analytics, consumers |
|
||||
| `/internal/*` | Только ЦП | ingest, job status, listener subscriptions |
|
||||
| `/api/v1/*` | Внешние клиенты | Events с Bearer-ключом |
|
||||
|
||||
Internal защищён заголовком `X-Internal-Token` (`INTERNAL_TOKEN`).
|
||||
|
||||
### Конструктор парсера
|
||||
### Профили, каналы и пары
|
||||
|
||||
Раздел UI `/parser-builder` → `POST /admin/parser-builder/generate|preview|jobs`:
|
||||
1. **Канал** (`CRUD /admin/parse-channels`) — handle Telegram + метаданные.
|
||||
2. **Профиль** (`CRUD /admin/parser-profiles`) — Generate (DeepSeek один раз по образцу) → Preview → Save `heuristic_profile`.
|
||||
3. **Пара** (`POST /admin/jobs` с `channel_id` + `profile_id`) → `ParseJob`; при enqueue ЦА **разворачивает** пару в плоский `source_config`:
|
||||
|
||||
1. Менеджер вставляет образец поста.
|
||||
2. DeepSeek (`DEEPSEEK_API_KEY` на **ca-api**) один раз возвращает `HeuristicProfile` (regex/line/marker).
|
||||
3. Preview и сохранение job с `extract_mode=profile` + JSON профиля в `source_config`.
|
||||
4. ЦП применяет профиль статически (batch + listener); LLM на ingest не вызывается.
|
||||
```json
|
||||
{
|
||||
"channel": "<ParseChannel.channel>",
|
||||
"limit": 100,
|
||||
"extract_mode": "profile",
|
||||
"heuristic_profile": { "...из ParserProfile..." }
|
||||
}
|
||||
```
|
||||
|
||||
Roadmap: кастомные пользовательские таблицы подменяют только список `target-fields` при генерации.
|
||||
ЦП по-прежнему получает только Redis payload — без доступа к таблицам Profile/Channel.
|
||||
|
||||
Roadmap: кастомные пользовательские таблицы подменяют список `target-fields` при генерации; профиль будет ссылаться на `schema_id`.
|
||||
|
||||
### Jobs и scheduler
|
||||
|
||||
1. `POST /admin/jobs` / retry → запись `ParseJob` + `enqueue_job` (`services/jobs.py`).
|
||||
1. `POST /admin/jobs` / retry → запись `ParseJob` + `enqueue_parse_job` (flatten + RPUSH).
|
||||
2. Очередь: `cp:jobs:{family}` из `contracts/queues.py`.
|
||||
3. `services/scheduler.py` — тик ~30 с, повторная постановка активных jobs по `interval_seconds`.
|
||||
|
||||
@@ -135,8 +146,9 @@ Roadmap: кастомные пользовательские таблицы по
|
||||
| Path | View |
|
||||
|------|------|
|
||||
| `/` | `MapViewPage.vue` |
|
||||
| `/parsers` | `ParsersView.vue` |
|
||||
| `/parser-builder` | `ParserBuilderView.vue` |
|
||||
| `/channels` | `ChannelsView.vue` |
|
||||
| `/parser-profiles` | `ParserProfilesView.vue` |
|
||||
| `/parsers` | `ParsersView.vue` (связки канал+профиль) |
|
||||
| `/events` | `EventsView.vue` |
|
||||
| `/analytics` | `AnalyticsView.vue` |
|
||||
| `/consumers` | `ConsumersView.vue` |
|
||||
@@ -156,7 +168,7 @@ Roadmap: кастомные пользовательские таблицы по
|
||||
| `INTERNAL_TOKEN` | Auth ЦП ↔ ЦА |
|
||||
| `TEST_PI_API_KEY` | Seed consumer `test-pi` |
|
||||
| `UPLOAD_DIR` | Медиа (по умолчанию `/data/uploads`) |
|
||||
| `DEEPSEEK_API_KEY` | Конструктор парсера (Generate); не нужен для preview/runtime profile |
|
||||
| `DEEPSEEK_API_KEY` | Generate профиля на ca-api; не нужен для preview/runtime |
|
||||
| `DEEPSEEK_BASE_URL` / `DEEPSEEK_MODEL` | Опционально |
|
||||
|
||||
### Типовые точки входа в код
|
||||
|
||||
Reference in New Issue
Block a user