Refactor map tools and drop SocialParser runtime dependency.

Add filtered map API, creamy-caprice-style toolbar (dates, layers, search), Yandex ru tiles, and store Telegram session in MapMil/data instead of mounting SocialParser.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-30 20:56:30 +03:00
co-authored by Cursor
parent 2c16bc0b56
commit 1d6d54ab9f
28 changed files with 3182 additions and 616 deletions
+26 -18
View File
@@ -1,6 +1,6 @@
# MapMil Platform (ЦП → ЦА → ПИ)
Единая платформа на базе MapMil (ЦА аналитика) и SocialParser (ЦП парсинг).
Единая платформа: ЦА (аналитика и карта) + ЦП (парсинг Telegram).
## Архитектура
@@ -18,7 +18,7 @@ flowchart LR
| Центр | Контейнеры | Назначение |
|-------|------------|------------|
| **ЦА** | `ca-db`, `ca-api`, `ca-frontend` | PostgreSQL, ingest API, карта, distribution API |
| **ЦП** | `cp-workers` | Парсинг Telegram (код из SocialParser) |
| **ЦП** | `cp-workers` | Парсинг Telegram (`centers/parsing/workers`) |
| **Общее** | `redis` | Очередь заданий ЦА → ЦП |
## Структура monorepo
@@ -32,24 +32,24 @@ MapMil/
│ └── parsing/
│ └── workers/ # CP workers (Telethon)
├── contracts/ # Shared schemas (ingest, jobs)
├── data/ # telegram.session (symlink → SocialParser)
├── data/ # telegram.session (локально, не в git)
├── docker-compose.yml
└── .env # TELEGRAM_* из SocialParser
└── .env # TELEGRAM_API_ID, TELEGRAM_API_HASH, …
```
## Быстрый старт
1. Скопируйте `.env` из SocialParser (или создайте из `.env.example`):
1. Создайте `.env` из примера и укажите ключи Telegram:
```bash
cp ../SocialParser/.env .env
cp .env.example .env
# отредактируйте TELEGRAM_API_ID и TELEGRAM_API_HASH
```
2. Убедитесь, что сессия Telegram доступна:
2. Положите сессию Telegram в `data/telegram.session` (файл Telethon SQLite). Если мигрируете со старого SocialParser:
```bash
ls -la data/telegram.session
# symlink → ../SocialParser/data/telegram.session
cp ../SocialParser/data/telegram.session data/
```
3. Запуск:
@@ -66,7 +66,7 @@ docker compose up --build
| Раздел | Путь | Описание |
|--------|------|----------|
| **Карта** | `/` | Интерактивная карта с объектами, таймлайном и CRUD. Поддерживает `?eventId=` для перехода к событию |
| **Карта** | `/` | Интерактивная карта событий: навигация по датам (flatpickr), пресеты периода, фильтры региона/темы/источника, подложки Яндекс/OSM/Topo/ESRI, линейка, полноэкранный режим, центрирование по координатам и городам, поиск населённых пунктов (Nominatim). CRUD для ручных объектов (ПКМ). Поддерживает `?eventId=` |
| **Парсеры** | `/parsers` | Создание заданий Telegram-парсинга, таблица статусов с автообновлением (5 с), повтор failed-заданий |
| **События** | `/events` | Фильтрация, пагинация, просмотр деталей, ссылка «На карте» для событий с координатами |
| **Аналитика** | `/analytics` | KPI-карточки, график динамики ingest за 30 дней, топ населённых пунктов и регионов |
@@ -76,26 +76,34 @@ docker compose up --build
**Важно:** существующий файл сессии **не удаляется и не пересоздаётся**.
- Оригинал: `SocialParser/data/telegram.session`
- В репозитории MapMil: `data/telegram.session` — симлинк для локальной разработки
- В Docker `cp-workers`: каталог `../SocialParser/data` монтируется как `/data` (read-write; Telethon обновляет SQLite-сессию)
- Локально: `data/telegram.session` (SQLite Telethon, в `.gitignore`)
- В Docker `cp-workers`: каталог `./data` монтируется как `/data` (read-write)
- Путь в контейнере: `/data/telegram.session`
- Переменные из `.env`: `TELEGRAM_API_ID`, `TELEGRAM_API_HASH`, `TELEGRAM_SESSION_PATH=/data/telegram.session`
> Симлинк не работает внутри Docker — compose монтирует каталог `SocialParser/data` целиком.
Файл сессии и `.env` добавлены в `.gitignore` и не коммитятся.
Файл сессии и `.env` не коммитятся.
## API
### Карта (совместимость MapMil)
### Карта
| Метод | Путь | Описание |
|-------|------|----------|
| GET | `/api/health` | Health check |
| GET | `/api/objects` | Объекты на карте (включая события с координатами) |
| GET | `/api/map/objects` | Объекты на карте с данными события; фильтры: `date_from`, `date_to`, `on_date`, `region`, `topic`, `source_type`, `search`, `event_id` |
| GET | `/api/map/filters` | Справочники для фильтров: `regions`, `topics`, `source_types`, `available_dates`, `date_bounds` |
| GET | `/api/objects` | Объекты (legacy, без фильтров события) |
| POST | `/api/objects` | Создать объект вручную |
#### Инструменты карты (UI)
- **Даты:** кнопки ❮❮/❮/❯/❯❯, календарь flatpickr, пресеты периода (1 неделя — 1 год / день)
- **Фильтры:** регион, тема, источник (из `/api/map/filters`)
- **Подложки:** Яндекс Карты / Спутник (ru_RU), OpenStreetMap, OpenTopoMap, ESRI Satellite
- **Инструменты:** линейка (PolylineMeasure), полноэкранный режим, координаты/города, поиск Nominatim
- **Точки:** маркеры из ingest + popup; ручные объекты — CRUD и drag
- **Обновление:** polling `/api/map/objects` каждые 30 с
### ЦА Admin
| Метод | Путь | Описание |