Page:
Architecture
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
- ❌ Мобильные приложения (только адаптивный веб)