Orion VMS — видеонаблюдение, организации, Flussonic DVR и PWA
  • Python 56.4%
  • TypeScript 36.4%
  • Shell 4.2%
  • JavaScript 1.9%
  • CSS 0.7%
  • Other 0.3%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-10-07 15:02:54 +03:00
apps Персонализация: оформление, профиль и сохранение входа PWA 2026-10-07 15:02:54 +03:00
deploy Персонализация: оформление, профиль и сохранение входа PWA 2026-10-07 15:02:54 +03:00
docs Персонализация: оформление, профиль и сохранение входа PWA 2026-10-07 15:02:54 +03:00
.env.example Персонализация: оформление, профиль и сохранение входа PWA 2026-10-07 15:02:54 +03:00
.gitattributes Персонализация: оформление, профиль и сохранение входа PWA 2026-10-07 15:02:54 +03:00
.gitignore Перенос Orion VMS: Phase 0–5 и установщик Debian/Ubuntu 2026-10-07 13:27:06 +03:00
AGENTS.md Перенос Orion VMS: Phase 0–5 и установщик Debian/Ubuntu 2026-10-07 13:27:06 +03:00
docker-compose.yml Персонализация: оформление, профиль и сохранение входа PWA 2026-10-07 15:02:54 +03:00
README.md Персонализация: оформление, профиль и сохранение входа PWA 2026-10-07 15:02:54 +03:00

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

  1. Скопируйте .env.example в .env и замените все значения-заполнители. JWT_SECRET должен быть длинным случайным секретом. Для настройки media server задайте независимый ключ Fernet MEDIA_CREDENTIALS_KEY (команда генерации приведена ниже); файл .env не добавляется в Git.
  2. Запустите docker compose up --build из корня репозитория.
  3. Примените миграции: docker compose exec backend alembic upgrade head.
  4. Создайте начальную организацию и администратора командой docker compose exec backend python -m app.seed. Команда использует SEED_* переменные из .env; пароль должен содержать не менее 12 символов. SEED_ADMIN_ROLE по умолчанию ADMIN; укажите SUPERADMIN только для первоначальной настройки базы без пользователей.
  5. Откройте 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 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 суперадминистратора, новые формы.