feat: implement stop alias management for Telegram import

- Added TelegramStopAliasService for handling stop aliases in the database.
- Created API endpoints for managing stop aliases (list, create, update, delete).
- Introduced TelegramStopAliases component in the frontend for user interaction with stop aliases.
- Updated TelegramImportService to utilize stop aliases for message processing.
- Enhanced telegramCancellationParser to resolve stop names using aliases.
- Added migration script to create telegram_stop_aliases table and seed initial data.
- Updated documentation to include details about stop alias functionality.
This commit is contained in:
2026-10-03 01:31:11 +03:00
parent f7f0b039dd
commit 666a0b268f
12 changed files with 439 additions and 25 deletions

View File

@@ -12,6 +12,25 @@
Новые однозначные отмены публикуются автоматически. `TELEGRAM_AUTO_PUBLISH=false` переводит все распознанные отмены на проверку. В админке на странице **«Уведомления» → «Отмены из Telegram»** доступны состояние подключения, ручная проверка канала, исходные сообщения, ссылки на оригинал и история. При ручной публикации оператор проверяет маршрут, текст и день отмены; срок до полуночи назначается сервером.
### Словарь остановок и текст уведомления
В блоке **«Отмены из Telegram» → «Словарь названий остановок»** можно добавлять, изменять и удалять соответствия: название из канала → конкретная остановка из каталога выбранного города. Например, `ЗОДЧЕГО` → `Зодчего Иоанна`. Для разных сокращений одной остановки создайте несколько записей. Регистр, пробелы, знаки препинания и различие `ё/е` не учитываются; два эквивалентных сокращения в одном городе запрещены. Если есть несколько платформ с одним названием, выберите нужную остановку по адресу/ID. Отключённая остановка требует исправления соответствия и ручной проверки.
Миграция **014** добавляет словарь и начальные соответствия `АВ/ВОКЗАЛ` → `Автовокзал`, `ЗОДЧЕГО` → `Зодчего Иоанна` только для Полоцка и только при единственной действующей остановке с таким названием. При неоднозначности соответствие задаёт администратор. Уже сохранённые соответствия при повторном запуске миграции не перезаписываются.
Изменения словаря учитываются при следующем чтении канала, включая сообщения **на проверке с неизменившимся исходным текстом** в трёхдневном окне. Уже опубликованные или отклонённые сообщения повторно из-за изменения словаря не публикуются. Для распознанных отмен backend формирует лаконичный текст без приветствия и подписи перевозчика. Например:
```text
Отмена отдельных рейсов №27
02.10.2026: не выполняются рейсы:
Автовокзал — 15:43, 16:43
Зодчего Иоанна — 15:58, 16:58
Источник: https://t.me/avp2Polotsk/1166
```
При нескольких направлениях формируются отдельные уведомления с соответствующими отправлениями. Исходный текст остаётся в истории импорта. В ручной проверке распознанный текст также подставляется в удобочитаемом виде; выбор направления подставляет его отправления, пока оператор не изменил текст самостоятельно. Если сообщение не удалось разобрать, текст для ручной правки остаётся исходным.
## Установка
Для существующей базы применить миграцию **013** один раз, до запуска новой версии backend. Она также переводит UTC-значения времени существующих алертов из `timestamp` в `timestamptz`. Это соответствует принятому формату хранения UTC в админке. При наличии вручную внесённых локальных времен сначала проверить их и сделать резервную копию базы.
@@ -19,9 +38,13 @@
```bash
docker compose exec -T postgres psql -U transit_admin -d polotsk_transit \
-f /docker-entrypoint-initdb.d/013_telegram_alert_import.sql
docker compose exec -T postgres \
psql -v ON_ERROR_STOP=1 --single-transaction -U transit_admin -d polotsk_transit \
< backend/migrations/014_telegram_stop_aliases.sql
```
На чистой базе Docker применяет миграцию автоматически. **Не запускайте `npm run migrate` на существующей базе**: старые init-миграции проекта не поддерживают повторный запуск.
Если миграция 013 уже установлена, для обновления словаря достаточно миграции **014** и пересборки backend/frontend. На чистой базе Docker применяет обе миграции автоматически. **Не запускайте `npm run migrate` на существующей базе**: старые init-миграции проекта не поддерживают повторный запуск.
### Авторизация аккаунта
@@ -85,6 +108,10 @@ FCM TTL ограничен остатком срока действия алер
- `GET /api/v1/telegram-import` — безопасный статус и до 100 сообщений, сначала требующие проверки.
- `POST /api/v1/telegram-import/sync` — чтение настроенного канала; запрещено в другом городе.
- `POST /api/v1/telegram-import/:id/review` — `content_hash`, `action: publish|dismiss`; для публикации также `service_date`, `route_id`, `title`, `message`.
- `GET /api/v1/telegram-import/stop-aliases` — словарь выбранного города.
- `POST /api/v1/telegram-import/stop-aliases` — `alias`, `stop_id`; добавить соответствие.
- `PUT /api/v1/telegram-import/stop-aliases/:id` — `alias`, `stop_id`; изменить соответствие.
- `DELETE /api/v1/telegram-import/stop-aliases/:id` — удалить соответствие.
Обычные unit-тесты: `cd backend && npm test`. SQL-тесты используют временный PostgreSQL runtime PGlite и не обращаются к рабочей базе: