1 Architecture
Morozovka Admin edited this page 2026-10-21 07:06:53 +03:00
This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Архитектура

Схема

Интернет
  ↓
Внешний сервер 31.128.43.79 (nginx, HTTPS)
  ├─ git.morozovka.space    → 10.8.0.2:80 (Gitea)
  └─ portal.morozovka.space → 10.8.0.2:80 (портал)
  ↓
OpenVPN tun0
  ↓
Малина 192.168.50.1 (socat, MTU 1200)
  ↓ ethernet
Сервер 3 morozovka 192.168.50.3
  ├─ nginx (порт 80) → 127.0.0.1:8000
  ├─ Gitea (127.0.0.1:3000, SQLite)
  ├─ Flask-портал (gunicorn, 127.0.0.1:8000)
  ├─ PostgreSQL 15 (morozovka_portal)
  └─ Ollama (11434, LLM отложен)

Паттерны кода

Модули (app/modules/*.py)

Каждый модуль использует def register(app): + @app.route(...) внутри.

Не Blueprints — потому что endpoint'ы должны совпадать с именами функций (все существующие url_for работают).

Регистрация в main.py:

from .modules import auth_routes
auth_routes.register(app)

Хелперы (app/helpers.py)

  • Фильтры Jinja: msk_strftime, date_ru, is_image, file_icon, format_size
  • Декораторы: @login_required, @require_role(...)
  • Permissions: project_permissions(), workshop_permissions(), get_space_permissions(), get_folder_permissions(), check_file_access()
  • Хлебные крошки: build_breadcrumbs()
  • Уведомления: notify_user(), notify_users(), notify_subscribers()
  • Email: send_email() — без SMTP в journalctl, с SMTP — реально
  • Uploads: _save_uploaded_files() — v2.0 с версиями
  • Slug: _slugify(), _unique_space_slug()

Модели (app/models.py)

27 таблиц SQLModel. Правило: изменения только через Alembic.

Модули роутов

Модуль Что
auth_routes Регистрация, логин, OAuth, пароль, сессии
schedule_routes Расписание + ассистент + админка
projects_routes Проекты, канбан, участники, посты, файлы
workshops_routes Мастер-классы
files_routes Файлы v2.0
admin_routes Пользователи
notifications_routes Колокольчик
gitea_routes Приём вебхуков
feed_routes Общая лента
onboarding_routes Тур для новичков
dashboard_routes Персональный дашборд

Роли

Роль Описание
admin Полный доступ + /admin/*
professor Управление расписанием
lead Создание проектов, МК-пространств
member Проекты (участник), МК
student Запись на МК, просмотр
guest Только публичное

Granular-права в проектах: 7 флагов на участника (can_view_files, can_edit_files, can_view_repo, can_post_feed, can_edit_own_posts, can_edit_any_post, can_manage_members).

Granular-права в файлах:

  • Пространства: viewer/editor/manager через FileSpaceACL
  • Папки: 4 флага (can_view, can_upload, can_delete, can_manage) через FileFolderACL
  • Наследование: папка → пространство

Асинхронные задачи

Что Где Когда
Google Calendar sync systemd timer Каждые 15 мин
Email-уведомления подписчикам threading.Thread При изменении статуса/события
Gitea-кэш in-memory (5 мин TTL) При /projects/<id>/gitea-stats
Уведомления-колокольчик JS poll 30s На каждой открытой странице

Стек данных

  • PostgreSQL 15: 27 таблиц (портал)
  • SQLite: Gitea (отдельно, портал не пишет)
  • Файлы: /var/lib/gitea/portal-files/ (общий том с Gitea, 3.6 ТБ)
  • Бэкапы: пока нет (см. Security)

Что НЕ делаем

  • ❌ Flask Blueprints (сломает url_for)
  • ❌ React/Vue/SPA (только vanilla JS + Jinja2)
  • ❌ ORM-миграции без Alembic
  • ❌ Мобильные приложения (только адаптивный веб)