Unify parsing workers, analytics API with PostgreSQL, map UI, and PI distribution into centers/ with Docker Compose. Co-authored-by: Cursor <cursoragent@cursor.com>
5.4 KiB
5.4 KiB
MapMil Platform (ЦП → ЦА → ПИ)
Единая платформа на базе MapMil (ЦА — аналитика) и SocialParser (ЦП — парсинг).
Архитектура
flowchart LR
CA[ЦА Analytics Center]
CP[ЦП Parsing Center]
PI[ПИ External Consumers]
CA -->|jobs via Redis| CP
CP -->|POST /internal/ingest| CA
CA -->|GET /api/v1/events| PI
| Центр | Контейнеры | Назначение |
|---|---|---|
| ЦА | ca-db, ca-api, ca-frontend |
PostgreSQL, ingest API, карта, distribution API |
| ЦП | cp-workers |
Парсинг Telegram (код из SocialParser) |
| Общее | redis |
Очередь заданий ЦА → ЦП |
Структура monorepo
MapMil/
├── centers/
│ ├── analytics/
│ │ ├── api/ # CA backend (FastAPI + PostgreSQL)
│ │ └── frontend/ # CA admin UI (Vue + Leaflet)
│ └── parsing/
│ └── workers/ # CP workers (Telethon)
├── contracts/ # Shared schemas (ingest, jobs)
├── data/ # telegram.session (symlink → SocialParser)
├── docker-compose.yml
└── .env # TELEGRAM_* из SocialParser
Быстрый старт
- Скопируйте
.envиз SocialParser (или создайте из.env.example):
cp ../SocialParser/.env .env
- Убедитесь, что сессия Telegram доступна:
ls -la data/telegram.session
# symlink → ../SocialParser/data/telegram.session
- Запуск:
docker compose up --build
- Откройте карту: http://localhost:8080
Сохранение Telegram-сессии
Важно: существующий файл сессии не удаляется и не пересоздаётся.
- Оригинал:
SocialParser/data/telegram.session - В репозитории MapMil:
data/telegram.session— симлинк для локальной разработки - В Docker
cp-workers: файл монтируется напрямую как../SocialParser/data/telegram.session:/data/telegram.session:ro - Путь в контейнере:
/data/telegram.session - Переменные из
.env:TELEGRAM_API_ID,TELEGRAM_API_HASH,TELEGRAM_SESSION_PATH=/data/telegram.session
Симлинк не работает внутри Docker — compose монтирует исходный файл из SocialParser.
Файл сессии и .env добавлены в .gitignore и не коммитятся.
API
Карта (совместимость MapMil)
| Метод | Путь | Описание |
|---|---|---|
| GET | /api/health |
Health check |
| GET | /api/objects |
Объекты на карте (включая события с координатами) |
| POST | /api/objects |
Создать объект вручную |
ЦА Admin
| Метод | Путь | Описание |
|---|---|---|
| POST | /admin/jobs |
Создать задание парсинга (ставится в Redis) |
| GET | /admin/jobs |
Список заданий |
| GET | /admin/events |
Все события |
| POST | /admin/consumers |
Создать подписчика ПИ |
Пример задания Telegram:
curl -X POST http://localhost:8080/admin/jobs \
-H 'Content-Type: application/json' \
-d '{"source_type":"telegram","source_config":{"channel":"creamy_caprice","limit":50}}'
ЦП → ЦА (internal)
| Метод | Путь | Описание |
|---|---|---|
| POST | /internal/ingest |
Приём batch событий (заголовок X-Internal-Token) |
ПИ Distribution API
| Метод | Путь | Описание |
|---|---|---|
| GET | /api/v1/events |
События с фильтром по API-ключу |
Тестовый consumer test-pi создаётся при старте с ключом из TEST_PI_API_KEY (по умолчанию test-pi-api-key-change-me):
curl http://localhost:8080/api/v1/events \
-H 'Authorization: Bearer test-pi-api-key-change-me'
Поток данных
- Аналитик создаёт задание:
POST /admin/jobs ca-apiставит задание в Redis (cp:jobs)cp-workersзабирает задание, парсит Telegram через существующую сессию- Результаты отправляются в
POST /internal/ingest - События с координатами автоматически появляются на карте как
MapObject - Внешние ПИ получают отфильтрованный срез через
/api/v1/events
Миграция EventRecord → Event
| SocialParser | CA Event |
|---|---|
event |
description / title |
date (dd.mm.yy) |
event_date |
geolocation |
latitude, longitude |
locality |
locality, region |
source_url |
source_url |
| — | source_type = "telegram" |
Остановка
docker compose down
Данные PostgreSQL сохраняются в volume pgdata.
Legacy
Старые каталоги backend/ и frontend/ в корне оставлены для справки; активная разработка — в centers/.