Техническая документация
Для разработчиков, DevOps и технических специалистов
Описание архитектуры, технологического стека, модели безопасности и инфраструктуры платформы Fokin System. Документ предназначен для инженеров, сопровождающих и развивающих систему, и не содержит пользовательских инструкций — они находятся в руководстве пользователя.
01Обзор системы
Fokin System — платформа автоматизации управления производственным коллективом: документооборот с согласованием и ознакомлением, табель рабочего времени, заявления сотрудников, новости и объявления, чаты и push-уведомления, а также встроенный ИИ-помощник по поиску разделов приложения.
Система состоит из трёх основных частей:
REST API на FastAPI, обслуживающее мобильное приложение и веб-страницы (лендинг, юридические документы, документация).
Кроссплатформенное приложение на React Native / Expo (Android, iOS) — основной клиент для сотрудников.
Docker Compose: PostgreSQL, Redis, Celery-воркер, Nginx с TLS, автопродление сертификатов.
02Технологический стек
Backend
| Компонент | Технология | Назначение |
|---|---|---|
| Web-фреймворк | FastAPI + Starlette | Асинхронный REST API, роутинг, middleware, шаблоны Jinja2 |
| ASGI-сервер | Uvicorn / Gunicorn | В продакшене — Gunicorn с воркерами класса UvicornWorker |
| ORM | SQLAlchemy 2.0 (async) | Асинхронный доступ к БД через asyncpg |
| Миграции | Alembic | Версионирование схемы базы данных |
| База данных | PostgreSQL 15 | Основное хранилище (в разработке допускается SQLite) |
| Кэш / брокер | Redis 7 | Брокер и backend для Celery, rate-limiting, кэш |
| Фоновые задачи | Celery | Асинхронная обработка (рассылки, обработка медиа и т.д.) |
| Валидация данных | Pydantic v2 | Схемы запросов/ответов, валидация входных данных |
| Аутентификация | PyJWT, bcrypt | JWT-токены, хеширование паролей |
| Push-уведомления | firebase-admin | Firebase Cloud Messaging, Firebase App Check |
| Логирование | loguru | Структурированные логи с ротацией |
| Обработка медиа | Pillow, ffmpeg-python | Миниатюры изображений, обработка видео |
| HTTP-клиент | httpx | Запросы к внешним сервисам (reCAPTCHA, Ollama и др.) |
Мобильное приложение
| Компонент | Технология | Назначение |
|---|---|---|
| Платформа | React Native 0.81 + Expo SDK 54 | Единая кодовая база для Android и iOS |
| Навигация | React Navigation 6 | Вкладки, стеки экранов, deep-линки из уведомлений и ИИ-помощника |
| Push / авторизация | @react-native-firebase (auth, messaging, app-check) | Push-уведомления и защита API-запросов приложения |
| Локальные уведомления | @notifee/react-native | Отображение и управление уведомлениями на устройстве |
| Сеть | axios | HTTP-запросы к backend |
| Хранилище | AsyncStorage | Токены сессии, локальные настройки |
| Медиа | expo-camera, expo-image-picker, expo-video | Съёмка и выбор фото/видео для новостей и документов |
Инфраструктура
| Компонент | Технология | Назначение |
|---|---|---|
| Контейнеризация | Docker / Docker Compose | Изолированные сервисы: web, db, redis, celery_worker, nginx, certbot |
| Reverse proxy | Nginx | Терминация TLS, проксирование на web-сервис, раздача статики |
| TLS-сертификаты | Let's Encrypt / certbot | Автоматический выпуск и продление HTTPS-сертификатов |
| ИИ-модель | Ollama (qwen2.5:7b-instruct) | Локальная LLM для ИИ-помощника, без внешних API |
03Архитектура и модули
Backend построен как модульный монолит: единое FastAPI-приложение с разделением на роутеры по доменным областям. Каждый роутер инкапсулирует эндпоинты, бизнес-логику и обращения к своим моделям данных.
users— регистрация, вход, профилиstructure— иерархия должностей, цеха/отделыacting— временное замещение руководителейadmin— административные операции
documents— категории, создание, согласование, ознакомление, отчётыtimesheet— табель рабочего времениstatements— заявления сотрудников
chat— личные сообщения (WebSocket)group_chat— групповые чатыnews— лента новостейannouncements— объявленияnotifications— push/in-app уведомленияai— чат с ИИ-помощником
health— healthcheck для Docker/Composeseo— robots.txt, sitemap.xml, PWA manifest, App Linkstasks,testing— служебные и тестовые эндпоинты
Слои приложения: app/api/routers (HTTP-эндпоинты) → app/models (SQLAlchemy-модели) → app/schemas (Pydantic-схемы) → app/core (аутентификация, конфигурация, middleware, интеграции) → app/utils (хранилище файлов, вспомогательные функции).
04Данные и хранение
Основные доменные модели (app/models): users, documents, timesheet, statements, structure, news, announcements, chat.
Подключение к базе выполняется асинхронно через SQLAlchemy 2.0 + asyncpg; строка подключения формируется в app/core/config.py и может быть переопределена переменной окружения DATABASE_URL (например, для локальной разработки на SQLite через aiosqlite). Эволюция схемы управляется через Alembic (alembic upgrade head выполняется автоматически при старте продакшен-контейнера).
Файловое хранилище
Медиафайлы (документы, фото, видео) не привязаны к единственному диску: слой app.utils.storage умеет сохранять и искать файлы на нескольких дисках (STORAGE_DISKS) по одной из стратегий — first_available, round_robin или most_free_space — с запасным вариантом STORAGE_ROOT, если диски не заданы. Раздача файлов идёт через потоковый эндпоинт /media/{file_path} с определением MIME-типа и корректной обработкой отсутствующих файлов/ошибок хранилища.
05Аутентификация и роли
- Пароли хранятся только в виде bcrypt-хеша (
app/core/auth.py), сам пароль никогда не сохраняется и не логируется. - Access- и refresh-токены — это подписанные JWT (
PyJWT, алгоритмHS256по умолчанию) с полямиsub,role,id,exp,token_type. - Вход возможен по e-mail/паролю или по номеру телефона с одноразовым SMS-кодом (через HiLink-модем, с резервным вариантом SMS.ru/SMSC).
- Веб-страницы (лендинг, документация) используют отдельный механизм сессий на cookie (
SessionMiddleware), независимый от мобильной JWT-авторизации.
Ролевая модель
Иерархия должностей не захардкожена — она хранится в таблице positions и кэшируется в памяти процесса (app/core/roles.py) с перечитыванием при старте и при изменении оргструктуры. Чем меньше level, тем выше должность:
Пользователь может управлять только сотрудниками со строго более низкой должностью и только в пределах своей зоны ответственности (цех/участок). Отдельно существуют предоставляемые права администратора (AdminPermission) и механизм временного замещения руководителя (acting) на период его отсутствия.
06Безопасность
Защита транспортного уровня и заголовков
- HTTPS/TLS — терминируется на Nginx, сертификаты выпускаются и автоматически продлеваются через
certbot(Let's Encrypt), сервис перепроверяет сертификат раз в 12 часов. - CORS — в продакшене разрешён только фиксированный список доменов (
CORS_ORIGINS), по умолчанию без wildcard. TrustedHostMiddleware— защищает от подделки заголовкаHost; в продакшене список разрешённых хостов не содержит*.- ProxyFix — корректно восстанавливает исходную схему (
X-Forwarded-Proto) и хост (X-Forwarded-Host) за обратным прокси. - GZip — сжатие ответов свыше 1000 байт.
Защита сессий и секретов
- Секреты (
SECRET_KEY,SESSION_SECRET_KEY, пароль БД, сервисный аккаунт Firebase) задаются только через переменные окружения / Docker-секреты; в продакшене приложение не запускается, если ключевые секреты не заданы явно. - Сессионная cookie подписывается
SESSION_SECRET_KEY, имеет флагsame_site=laxи помечаетсяhttps_only=Trueв продакшене. - Файл сервисного аккаунта Firebase монтируется в контейнер как read-only секрет, а не копируется в образ.
Защита от автоматизированных и мошеннических запросов
- Firebase App Check — опционально принудительно проверяет, что запрос пришёл из подлинного экземпляра мобильного приложения, а не стороннего клиента.
- Google reCAPTCHA Enterprise — верификация токена с анализом риска (score) при чувствительных действиях (например, вход).
- Rate-limiting SMS-кодов — через Redis: не чаще одного SMS в 60 секунд и не более пяти за 15 минут на один номер телефона.
Эксплуатационная безопасность
- Swagger/ReDoc (
/docs,/redoc) и схемаopenapi.jsonотключены в продакшене по умолчанию (ENABLE_API_DOCS=false) и доступны только при явном включении. robots.txtзакрывает от индексации служебные пути (/api/,/docs,/redoc,/admin/, тестовые WebSocket-страницы).- Логи в продакшене используют уровень
INFO(неDEBUG), чтобы снизить риск утечки чувствительных данных в журналы. - Каждый контейнер ограничен лимитами CPU/RAM и имеет healthcheck, что снижает влияние единичного сбоя на всю систему.
POST /api/ai/chat, что исключает прямой доступ к модели и её инфраструктуре извне.07Реальное время и уведомления
Личные и групповые чаты (chat, group_chat) работают поверх WebSocket-соединений (пакет websockets), что обеспечивает доставку сообщений без постоянного опроса сервера.
Push-уведомления о новых документах, согласованиях, сообщениях и объявлениях доставляются на устройства через Firebase Cloud Messaging (app/core/fcm.py); локальное отображение и управление уведомлениями на устройстве — через Notifee.
08ИИ-интеграция
Встроенный ИИ-помощник работает на базе собственной (self-hosted) языковой модели Ollama (qwen2.5:7b-instruct), развёрнутой на том же сервере — без отправки данных во внешние облачные ИИ-сервисы.
- Единая точка входа —
POST /api/ai/chat(app/api/routers/ai.py), доступная только авторизованным пользователям мобильного приложения. - Системный промпт включает каталог разделов приложения (
APP_SECTIONS), что позволяет модели отвечать ссылками вида[Название](app://ключ)на реальные экраны — приложение превращает их в кликабельную навигацию. - Ответы проходят санитизацию: ссылки на несуществующие разделы заменяются обычным текстом, чтобы в интерфейсе не появлялись нерабочие кнопки.
- Реализована защита от переключения модели на другой язык ответа (анализ языка ответа, повторные попытки генерации, запасной ответ на русском при неудаче).
09Фоновые задачи
Долгие или отложенные операции выполняются асинхронно через Celery с брокером и result backend на Redis (app/core/celery_app.py). Задачи декларируются в app/tasks и исполняются отдельным сервисом celery_worker в Docker Compose — это изолирует тяжёлые операции от обработки HTTP-запросов и позволяет масштабировать воркеры независимо от web-сервиса.
10Инфраструктура и деплой
Продакшен развёртывается через docker-compose.prod.yml как набор взаимосвязанных сервисов:
| Сервис | Образ / сборка | Роль |
|---|---|---|
web | собственный, app/Dockerfile.prod.yml | Gunicorn + Uvicorn workers, применяет миграции и инициализацию БД при старте |
celery_worker | тот же образ, что web | Обработка фоновых задач |
db | postgres:15.8 | Основная база данных с healthcheck pg_isready |
redis | redis:7.4-alpine | Брокер Celery, кэш, rate-limiting |
nginx | собственная сборка (nginx/) | TLS-терминация, реверс-прокси на 80/443 |
certbot | certbot/certbot | Выпуск и автопродление TLS-сертификатов каждые 12 часов |
- Каждый сервис имеет
healthcheck, и зависимые сервисы (например,webотdbиredis) стартуют только после того, как зависимость станет «healthy». - Данные БД, Redis и загруженные медиафайлы хранятся в именованных Docker-томах (
postgres_data,redis_data,media_data), переживающих пересоздание контейнеров. - Логи всех сервисов ограничены по размеру (
json-file, до 3 файлов по 10 МБ) — предотвращает переполнение диска сервера. - Каждому сервису заданы лимиты CPU/RAM, что защищает от деградации всей системы из-за одного перегруженного контейнера.
11Логирование и мониторинг
- Логирование —
loguruс двумя приёмниками: консоль (уровеньDEBUGв разработке,INFOв продакшене) и файлinfo.logс автоматической ротацией (10 МБ), хранением 10 дней и сжатием в zip. - Время обработки запросов — отдельный
TimingMiddlewareлогирует длительность каждого HTTP-запроса, включая запросы, завершившиеся ошибкой. - Проверка состояния — эндпоинт
/health, используемый Docker healthcheck для автоматического перезапуска нездоровых контейнеров. - Обработка ошибок валидации — все ошибки валидации запросов (422) логируются с телом запроса для быстрой диагностики проблем интеграции.
12Мобильное приложение
Мобильный клиент собран на Expo (управляемый workflow с нативными модулями через expo-dev-client / expo-build-properties) и поддерживает Android и iOS из единой кодовой базы.
- Навигация реализована через
React Navigation(вкладки + стеки), с поддержкой программных переходов по deep-ссылкам из push-уведомлений и ответов ИИ-помощника. - Push-уведомления и аутентификация интегрированы с Firebase (
@react-native-firebase/auth,messaging,app-check). - Состояние авторизации и токены хранятся локально через
AsyncStorage. - Медиафункции (камера, выбор фото/видео, миниатюры видео, расшаривание и открытие файлов) реализованы через соответствующие модули
expo-*.
13Чек-лист безопасности
FIREBASE_APP_CHECK_ENFORCED=true и заданы реальные ключи reCAPTCHA — иначе эти уровни защиты фактически отключены.firebase-service-account.json и переменные окружения (.env) не должны попадать в систему контроля версий и публичные бэкапы.