Files
MapMil/README.md
T
gitrusprusandCursor 9dfe713668 Add CP→CA→PI platform foundation on MapMil monorepo.
Unify parsing workers, analytics API with PostgreSQL, map UI, and PI distribution into centers/ with Docker Compose.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-30 11:43:27 +03:00

154 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MapMil Platform (ЦП → ЦА → ПИ)
Единая платформа на базе MapMil (ЦА — аналитика) и SocialParser (ЦП — парсинг).
## Архитектура
```mermaid
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
```
## Быстрый старт
1. Скопируйте `.env` из SocialParser (или создайте из `.env.example`):
```bash
cp ../SocialParser/.env .env
```
2. Убедитесь, что сессия Telegram доступна:
```bash
ls -la data/telegram.session
# symlink → ../SocialParser/data/telegram.session
```
3. Запуск:
```bash
docker compose up --build
```
4. Откройте карту: [http://localhost:8080](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:
```bash
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`):
```bash
curl http://localhost:8080/api/v1/events \
-H 'Authorization: Bearer test-pi-api-key-change-me'
```
## Поток данных
1. Аналитик создаёт задание: `POST /admin/jobs`
2. `ca-api` ставит задание в Redis (`cp:jobs`)
3. `cp-workers` забирает задание, парсит Telegram через существующую сессию
4. Результаты отправляются в `POST /internal/ingest`
5. События с координатами автоматически появляются на карте как `MapObject`
6. Внешние ПИ получают отфильтрованный срез через `/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"` |
## Остановка
```bash
docker compose down
```
Данные PostgreSQL сохраняются в volume `pgdata`.
## Legacy
Старые каталоги `backend/` и `frontend/` в корне оставлены для справки; активная разработка — в `centers/`.