FOKIN SYSTEM DOC / 04 · ТЕХНИЧЕСКАЯ ДОКУМЕНТАЦИЯ
На главную

Техническая документация

Для разработчиков, DevOps и технических специалистов

Описание архитектуры, технологического стека, модели безопасности и инфраструктуры платформы Fokin System. Документ предназначен для инженеров, сопровождающих и развивающих систему, и не содержит пользовательских инструкций — они находятся в руководстве пользователя.

01Обзор системы

Fokin System — платформа автоматизации управления производственным коллективом: документооборот с согласованием и ознакомлением, табель рабочего времени, заявления сотрудников, новости и объявления, чаты и push-уведомления, а также встроенный ИИ-помощник по поиску разделов приложения.

Система состоит из трёх основных частей:

BACKEND

REST API на FastAPI, обслуживающее мобильное приложение и веб-страницы (лендинг, юридические документы, документация).

MOBILE

Кроссплатформенное приложение на React Native / Expo (Android, iOS) — основной клиент для сотрудников.

INFRASTRUCTURE

Docker Compose: PostgreSQL, Redis, Celery-воркер, Nginx с TLS, автопродление сертификатов.

02Технологический стек

Backend

КомпонентТехнологияНазначение
Web-фреймворкFastAPI + StarletteАсинхронный REST API, роутинг, middleware, шаблоны Jinja2
ASGI-серверUvicorn / GunicornВ продакшене — Gunicorn с воркерами класса UvicornWorker
ORMSQLAlchemy 2.0 (async)Асинхронный доступ к БД через asyncpg
МиграцииAlembicВерсионирование схемы базы данных
База данныхPostgreSQL 15Основное хранилище (в разработке допускается SQLite)
Кэш / брокерRedis 7Брокер и backend для Celery, rate-limiting, кэш
Фоновые задачиCeleryАсинхронная обработка (рассылки, обработка медиа и т.д.)
Валидация данныхPydantic v2Схемы запросов/ответов, валидация входных данных
АутентификацияPyJWT, bcryptJWT-токены, хеширование паролей
Push-уведомленияfirebase-adminFirebase 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Отображение и управление уведомлениями на устройстве
СетьaxiosHTTP-запросы к backend
ХранилищеAsyncStorageТокены сессии, локальные настройки
Медиаexpo-camera, expo-image-picker, expo-videoСъёмка и выбор фото/видео для новостей и документов

Инфраструктура

КомпонентТехнологияНазначение
КонтейнеризацияDocker / Docker ComposeИзолированные сервисы: web, db, redis, celery_worker, nginx, certbot
Reverse proxyNginxТерминация 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/Compose
  • seo — robots.txt, sitemap.xml, PWA manifest, App Links
  • tasks, 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.checkpw() → access_token (JWT, 60 мин) + refresh_token (JWT, 30 дней) Каждый защищённый эндпоинт → OAuth2PasswordBearer → jwt.decode(SECRET_KEY) → пользователь из БД
  • Пароли хранятся только в виде 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, тем выше должность:

0 · owner 1 · shop_chief 2 · section_chief 3 · master 4 · assistant_master 5 · worker

Пользователь может управлять только сотрудниками со строго более низкой должностью и только в пределах своей зоны ответственности (цех/участок). Отдельно существуют предоставляемые права администратора (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, что снижает влияние единичного сбоя на всю систему.
Важно. ИИ-ассистент («Фокси») обращается к локальной модели Ollama только со стороны backend. Мобильное приложение никогда не взаимодействует с Ollama напрямую — только через авторизованный эндпоинт 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.ymlGunicorn + Uvicorn workers, применяет миграции и инициализацию БД при старте
celery_workerтот же образ, что webОбработка фоновых задач
dbpostgres:15.8Основная база данных с healthcheck pg_isready
redisredis:7.4-alpineБрокер Celery, кэш, rate-limiting
nginxсобственная сборка (nginx/)TLS-терминация, реверс-прокси на 80/443
certbotcertbot/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Чек-лист безопасности

Готово. Пароли хешируются bcrypt, JWT подписываются секретом, секреты не хранятся в коде, TLS выпускается и продлевается автоматически.
Готово. В продакшене CORS и TrustedHost ограничены конкретными доменами, документация API скрыта по умолчанию.
Рекомендация. Перед релизом на внешний контур убедитесь, что FIREBASE_APP_CHECK_ENFORCED=true и заданы реальные ключи reCAPTCHA — иначе эти уровни защиты фактически отключены.
Рекомендация. Файл firebase-service-account.json и переменные окружения (.env) не должны попадать в систему контроля версий и публичные бэкапы.