Документация

Архитектура приложения

Документ описывает устройство Crisis‑Monitor и взаимодействие его основных частей. Ниже приведена русская версия обзора архитектуры с дополнительными сведениями.

Flask Blueprints

Приложение разбито на несколько blueprints. Каждый из них отвечает за отдельную область функциональности.

  • auth – аутентификация пользователей и управление учётными записями. Примеры маршрутов:
  • /login и /logout – вход и выход из системы.
  • tickets – создание и просмотр тикетов. Здесь находится JSON API и страница с интерактивной картой. Маршруты:
  • /tickets – список инцидентов;
  • /tickets/<id> – подробная страница тикета;
  • /tickets/new – форма добавления записи.
  • dashboard – интерактивный дашборд /dashboard и канбан.
  • reports – генерация отчётов в PDF или CSV по адресу /reports.
  • backups – управление резервными копиями БД через административную панель.
  • /admin/backups – перечень архивов;
  • /admin/backups/create – запуск создания бэкапа.
  • localization – смена языка интерфейса. Например, /set_language/kk или /lang/kk переключит приложение на казахский, а /set_language/ru или /lang/ru переведёт его на русский.
  • print – упрощённые версии страниц для печати, например /print/briefing.
  • search – API для строки поиска. Запрос /search/?q=<term> возвращает результаты в JSON. Словарь содержит ключи tickets, users, actions, buffer_links и references.
  • monitoring – панель проверки состояния сервиса и поток событий (Server‑Sent Events).

  • teams – управление группами пользователей по адресу /teams.

  • templates – шаблоны тикетов доступны по маршруту /templates. Они позволяют администраторам сохранять типовые данные и быстро заполнять форму нового тикета.
  • admin – JSON‑интерфейс для администрирования пользователей в /admin.
  • /admin/users – список пользователей и изменение ролей.
  • notifications – настройки и расписания уведомлений.

Связи между моделями

Большинство моделей объединены в пакете app.models и используют SQLAlchemy. Модели тикетов физически расположены в файле app/tickets/models.py, который является основным источником их определения. Файл app/models/ticket.py лишь реэкспортирует эти модели и используется в качестве рекомендуемого пути импорта. Модели DisinformationCase, Sighting и Rebuttal вынесены в отдельный файл app/models/disinformation.py. Базовые сущности:

  • User – учётная запись пользователя. Связана с моделью Role через поле role_id.
  • Role и Permission формируют систему прав доступа (многие‑ко‑многим).
  • CrisisTicket – основной объект. Ссылается на множество справочников (регион, тип ЧС и т. п.), на автора (user_id) и на команду (team_id). Имеет связи «один‑ко‑многим» с TicketAttachment и TicketNote.
  • Team содержит множество пользователей через таблицу team_members.

Ниже приведена упрощённая диаграмма.

classDiagram
    class User
    class Role
    class CrisisTicket
    class TicketAttachment
    class TicketNote
    class Team
    class Region
    class EmergencyType
    class Status

    User --> Role
    User "1" --> "*" CrisisTicket
    CrisisTicket --> TicketAttachment
    CrisisTicket --> TicketNote
    CrisisTicket --> Region
    CrisisTicket --> EmergencyType
    CrisisTicket --> Status
    User --> TicketNote
    User "*" --> "*" Team : team_members

Утилиты

  • db_utils – инициализация базы и заполнение справочников.
  • backup_utils и cleanup_utils – создание архивов и удаление старых файлов.
  • monitoring – планировщик проверок состояния сервиса.
  • reminders – отправка писем и сообщений о приближающихся сроках.
  • locale_utils – переключение языка и форматирование дат.
  • undo_utils – временное хранение действий для отмены.
  • analytics – функции для аналитики и поиска кластеров.
  • archive_utils – выгрузка закрытых тикетов в CSV или JSON.
  • event_stream – очередь публикации событий для SSE.
  • external_api – обращения к стороннему сервису и логирование.
  • file_exchange – импорт и экспорт тикетов из CSV.
  • metrics – счётчики, которые используют фоновые задачи.
  • opengraph – извлечение метаданных по URL.
  • report_utils – формирование PDF‑отчётов.
  • sql_queries – сложные запросы на чистом SQL.
  • tag_suggest – подбор тегов на основе TF‑IDF.
  • telegram – простая оболочка вокруг API Telegram Bot.

ARQ worker и периодические задачи

Все периодические задачи определены в services/worker.py как ARQ cron jobs. Воркер запускается командой arq services.worker.WorkerSettings и выполняет: резервное копирование базы, очистку временных файлов, удаление устаревших действий отмены, ночную архивацию тикетов, проверку здоровья БД, обновление уровней угроз, приём данных из внешних источников (GDELT, ReliefWeb, GDACS) и автоматическую эскалацию.

MonitoringScheduler из модуля utils.monitoring запускается параллельно. Он использует отдельный поток threading.Timer для периодического выполнения проверок (например, доступности БД). При сбоях публикуется событие в event_stream и, при наличии настроек, отправляется письмо.

Запуск через системный cron

В продакшене те же функции можно вызывать через системный cron с помощью CLI-команд из cli.py. Пример конфигурации – crontab.example в корне проекта.

# Пример: ежедневный бэкап в 00:30
30 0 * * * /opt/crisis-monitor/.venv/bin/python /opt/crisis-monitor/cli.py cron-backup

Общая схема

Ниже изображена схема взаимодействия основных компонентов системы.

graph TD
    UI[Веб‑интерфейс] -->|HTTP| API
    API -->|ORM| DB[(База данных)]
    Workers[Фоновые задачи] -->|периодические операции| DB
    API -->|JSON/HTML| UI

Расширение архитектуры

При добавлении нового функционала придерживайтесь существующей структуры:

  1. Создайте файл или пакет в каталоге app и определите в нём Blueprint. Зарегистрируйте его в create_app через app.register_blueprint.
  2. Новые модели добавляйте в модуль app.models и создавайте миграцию с помощью flask db migrate && flask db upgrade.
  3. Если требуется периодическая задача, добавьте cron job в services/worker.py и соответствующую CLI-команду в cli.py.

Такой подход позволяет постепенно развивать проект, не нарушая его целостность.

Компоненты приложения должны импортировать сервисы напрямую из пакета services, например from services import ticket_service. Это помогает избежать циклических импортов.