- Python 56.4%
- TypeScript 36.4%
- Shell 4.2%
- JavaScript 1.9%
- CSS 0.7%
- Other 0.3%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| apps | ||
| deploy | ||
| docs | ||
| .env.example | ||
| .gitattributes | ||
| .gitignore | ||
| AGENTS.md | ||
| docker-compose.yml | ||
| README.md | ||
Orion VMS
Orion VMS — система видеонаблюдения с изоляцией организаций. Phase 0–3 предоставляют вход, медиасерверы, камеры, группы, Live, ACL и избранное. Phase 4 добавляет защищенный архив через DVR-плеер Flussonic; Phase 5 — мобильную навигацию и PWA. Суперадминистратор управляет организациями и работает в выбранной организации; администраторы могут менять пароли пользователей и настройки подключения к Flussonic.
Структура
apps/
backend/ FastAPI, SQLAlchemy, Alembic
frontend/ React, TypeScript, Vite
docs/
architecture.md
development-log.md
docker-compose.yml
Требования
- Python 3.12 или новее и Node.js с npm для локального режима.
- PostgreSQL 16 для локального режима либо Docker Compose.
Запуск через Docker Compose
- Скопируйте
.env.exampleв.envи замените все значения-заполнители.JWT_SECRETдолжен быть длинным случайным секретом. Для настройки media server задайте независимый ключ FernetMEDIA_CREDENTIALS_KEY(команда генерации приведена ниже); файл.envне добавляется в Git. - Запустите
docker compose up --buildиз корня репозитория. - Примените миграции:
docker compose exec backend alembic upgrade head. - Создайте начальную организацию и администратора командой
docker compose exec backend python -m app.seed. Команда используетSEED_*переменные из.env; пароль должен содержать не менее 12 символов.SEED_ADMIN_ROLEпо умолчаниюADMIN; укажитеSUPERADMINтолько для первоначальной настройки базы без пользователей. - Откройте frontend по адресу http://localhost:5173; API доступен на http://localhost:8000 и проксируется через Nginx frontend.
Compose запускает PostgreSQL 16, backend и frontend. Flussonic устанавливается отдельно и не входит в Compose. Контейнер backend применяет миграции автоматически перед запуском API; явный повторный alembic upgrade head безопасен.
Локальная разработка
Сначала создайте локальную БД PostgreSQL 16 orion и пользователя orion, затем из PowerShell выполните команды ниже. Укажите свои локальные пароли и секреты вместо примеров.
Set-Location apps/backend
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt
$env:MEDIA_CREDENTIALS_KEY = python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
$env:DATABASE_URL = 'postgresql+psycopg://orion:<пароль>@localhost:5432/orion'
$env:JWT_SECRET = '<длинный случайный секрет>'
$env:SEED_ORGANIZATION_SLUG = 'orion-demo'
$env:SEED_ORGANIZATION_NAME = 'Orion Demo'
$env:SEED_ADMIN_EMAIL = 'admin@example.com'
$env:SEED_ADMIN_NAME = 'Администратор Orion'
$env:SEED_ADMIN_PASSWORD = '<пароль не короче 12 символов>'
# Для первого глобального администратора на полностью пустой БД:
$env:SEED_ADMIN_ROLE = 'SUPERADMIN'
alembic upgrade head
python -m app.seed
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 --no-access-log
В отдельном PowerShell окне запустите frontend. VITE_API_PROXY_TARGET используется только Vite dev server. Production Compose раздаёт статические файлы через Nginx, который самостоятельно проксирует /api/ на backend.
Set-Location apps/frontend
npm ci
$env:VITE_API_PROXY_TARGET = 'http://localhost:8000'
npm run dev -- --host 0.0.0.0
Ключ MEDIA_CREDENTIALS_KEY сгенерируйте один раз и сохраните в закрытом .env backend или окружении. При следующем запуске используйте тот же ключ: новый ключ не сможет расшифровать существующие учётные данные. Для Docker можно получить новый ключ командой docker compose run --rm --no-deps backend python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())" после сборки образа и записать результат в корневой .env.
SEED_ADMIN_ROLE по умолчанию равен ADMIN. Значение SUPERADMIN создает первую глобальную учетную запись только в базе, где еще нет пользователей. Seed не меняет существующую запись при повторном запуске; если email занят, команда завершится ошибкой. Оба Compose-файла передают этот параметр backend-контейнеру.
Установка на сервер
Для чистого Debian/Ubuntu-сервера используйте deploy/install.sh. Сценарий получает Git-токен только для чтения закрытого репозитория и пароль первого супер-администратора интерактивно, скрытым вводом. Замените примерный IP на адрес интерфейса сервера:
sudo bash deploy/install.sh --listen-ip 192.168.1.20
Сценарий установит Compose-стек, создаст .env с правами 0600 и применит seed начальной организации. После успешного seed начальный пароль удаляется из .env; сохраните его в менеджере паролей. По умолчанию приложение доступно по HTTP; для production настройте доверенный HTTPS и задайте --public-url как origin, достижимый Flussonic. Дополнительные параметры приведены в инструкции установки и сценарии в Gitea.
Перед первым push следуйте процессу проверки публикации.
Настройка media server и камер
Войдите под ADMIN, откройте «Медиасервер» и укажите адрес отдельно установленного Flussonic, имя пользователя и пароль административного API. Учётные данные принимаются для записи и не возвращаются в API. Кнопка проверки соединения показывает доступность API и число потоков, если Flussonic сообщает эту величину. CPU, RAM и сведения DVR/хранилища могут быть недоступны.
После сохранения сервера откройте «Камеры» и создайте камеру с основным и, при необходимости, дополнительным источником. Backend создаёт соответствующие потоки через адаптер. Имена потоков Orion генерируются автоматически и сохраняются при переименовании камеры. Изменение адреса/учётных данных сервера и его удаление запрещены, пока есть камеры. USER административные страницы и API недоступны.
Проверки
Backend: из apps/backend выполните python -m pytest -q. Frontend: из apps/frontend выполните npm run lint и npm run build. Тесты адаптера используют HTTP MockTransport, а не реальный Flussonic; фактическая совместимость требует проверки на установленном сервере.
Документация
- Карта проекта: компоненты, связи и точки изменения
- Архитектура и границы Phase 0
- Архитектура Phase 1
- Контракт API Phase 1
- Адаптер Flussonic
- Административный интерфейс Phase 1
- Журнал разработки
Phase 2 и тестовый сервер
Для защищенного просмотра задайте PUBLIC_BACKEND_URL, доступный из Flussonic, и случайный MEDIA_AUTH_CALLBACK_SECRET длиной от 32 символов. Значение localhost в примере подходит только когда медиасервер находится на той же машине; для LAN используйте IP Orion. Viewer-токены действуют 120 секунд и не заменяют токен входа в API.
Развертывание в LAN, API Phase 2, медиаавторизация, интерфейс Phase 2. ADMIN получает камеры своей организации. USER получает камеры по прямым разрешениям и наследуемому доступу к группам (Phase 3).
Phase 3
Администратор на странице «Пользователи» создает учетные записи и настраивает доступ к отдельным камерам и группам. Разрешение родительской группы распространяется на всех потомков; административные данные медиасервера USER недоступны. Камеры добавляются в личное избранное кнопкой с сердцем; порядок меняется перетаскиванием или кнопками и сохраняется на backend.
Архитектура Phase 3, API Phase 3, интерфейс Phase 3.
Phase 4–5 и управление платформой
Архив доступен в разделе «Архив» через штатный DVR-плеер Flussonic. Новые основные потоки используют MEDIA_DVR_NAME=panel-dvr, глубина записи по умолчанию — сутки. Обновление камеры сохраняет существующую глубину архива; дополнительные потоки не записываются повторно.
SUPERADMIN создает организации с первым администратором и выбирает рабочую организацию в шапке. В разделе «Пользователи» он также может создать новую учетную запись с ролью «Суперадминистратор». Обычный ADMIN такую роль не выдает. Для первичного повышения существующего ADMIN используется защищенная локальная команда python -m app.promote_superadmin --organization-slug <slug> --email <email> --role SUPERADMIN --confirm; она требует другого активного ADMIN домашней организации.
«Пользователи» позволяет сбросить пароль. Старые API/media JWT после этого отклоняются. «Медиасерверы» позволяет отдельно менять адрес API, внешний адрес просмотра, логин и пароль. При существующих камерах новое административное подключение проверяется до сохранения.
Мобильная навигация и PWA реализованы. Для установки на телефон нужен доверенный HTTPS и для Orion, и для медиапросмотра. Service worker хранит только публичную статическую оболочку; камеры, архив и API для офлайн-просмотра не сохраняются.
В разделе «Мои настройки» каждый пользователь меняет свой пароль и выбирает страницу после входа: Обзор, Избранное или Архив. Долговременная HttpOnly cookie восстанавливает вход после закрытия PWA; настройки хранятся на сервере. SUPERADMIN меняет название проекта, логотип и описание страницы входа в разделе «Оформление». IP камер видят только ADMIN и SUPERADMIN; камера в группе открывает отдельную страницу архива и сразу запрашивает плеер. Контракты и ограничения: персонализация и сессии, личные настройки.
Карточки Live и избранного имеют ссылку на архив рядом с кнопкой избранного. В настройках камеры можно выбрать глубину архива или задать срок в часах; текущая настройка читается из Flussonic и сохраняется, пока новый срок не выбран. Подробности: глубина архива и создание суперадминистраторов.
Архив и PWA, администрирование, API суперадминистратора, новые формы.