# Архитектура Портал — монолит на Django 5.2 LTS. Код разложен по четырём приложениям в каталоге `network/`. ## Приложения ### `network.base` Ядро. Содержит почти всю предметную логику: | Файл / каталог | Содержимое | |---|---| | `models.py` | Все модели предметной области | | `views/` | HTML-представления, разбитые по доменам | | `forms.py` | Формы | | `admin.py` | Настройка админки | | `tasks.py` | Задачи Celery | | `rating_tasks.py` | Оценка наблюдений | | `scheduling.py` | Расчёт окон наблюдений | | `auto_scheduling.py` | Автопланирование | | `launch_scheduler.py` | Планирование наблюдений новых запусков | | `skyfield_pass_utils.py` | Общие примитивы геометрии пролёта | | `orbital_satellite_params.py` | Расчёт орбитальных параметров | | `tle_utils.py`, `tle_priority.py` | Разбор TLE и отбор победителя по источникам | | `spacetrack_client.py` | Клиент Space-Track | | `stats.py`, `station_stat_calculator.py` | Статистика | | `influx.py` | Выгрузка в InfluxDB | | `perms.py` | Права на планирование и публикацию | | `managers.py`, `signals.py`, `decorators.py`, `templatetags/` | Инфраструктурное | | `management/commands/` | Management-команды | ### `network.api` REST API на DRF. Обращается к моделям `network.base` через сериализаторы и ViewSet'ы; схема генерируется `drf-spectacular`. См. [](../api/index.md). ### `network.users` Кастомная модель пользователя и профиль. От неё зависят `Station.owner`, `Observation.author` и права. ### `network.analytics` Суточные метрики: собственные модели, запросы, задачи, HTML- и API-представления, своя management-команда. См. [](../analytics.md). ## Разбиение представлений HTML-представления сознательно разложены по доменам, а не свалены в один `views.py`: ``` network/base/views/ ├── generic.py общие страницы ├── observation.py наблюдения ├── station.py станции ├── satellite.py спутники ├── transmitter.py передатчики ├── scheduling.py ручное планирование ├── auto_scheduling.py настройки автопланирования ├── launch.py запуски ├── decay.py сошедшие с орбиты ├── gallery.py галерея снимков └── statistics.py сводная статистика ``` Правило: HTML-представления идут в `network/base/views/<домен>.py`, эндпоинты API — в `network/api/views.py` классами DRF. ## Маршруты верхнего уровня `network/urls.py`: | Префикс | Что | |---|---| | `/` | Основные страницы (`network.base.urls`) | | `/admin/` | Админка Django | | `/users/` | Профили | | `/accounts/` | django-allauth | | `/api/` | REST API | | `/oidc/` | mozilla-django-oidc | | `/analytics/` | Дашборд аналитики | | `/i18n/`, `/jsi18n/` | Переключение языка и JS-каталог переводов | При `DEBUG` дополнительно подключаются Django Debug Toolbar (`/__debug__/`) и раздача `/media/`. ```{note} Схема OpenAPI не отдаётся приложением: маршрутов Swagger/ReDoc нет, схема генерируется офлайн командой `./manage.py spectacular` в CI и публикуется вместе с документацией. ``` ## Асинхронная часть Celery с Redis в качестве брокера и backend'а результатов. Приложение — `network/celery.py`, там же собирается расписание периодических задач. Полный список — [](../tasks.md). ## Внешние зависимости | Направление | Через что | |---|---| | SatNOGS DB | HTTP, `DB_API_ENDPOINT`, опционально через прокси `SATNOGS_DB_PROXY_URL` | | SatNOGS Network | HTTP, `NETWORK_API_ENDPOINT` | | Space-Track | `spacetrack_client.py`, сессионный логин + один массовый запрос | | CelesTrak | HTTP, прямые URL | | S3 | `django-storages` / `boto3` | | InfluxDB | `influxdb-client`, опционально | | Keycloak | `mozilla-django-oidc` | | Mapbox | SDK и токен | ## Слои и потоки данных ``` Клиент станции ──► /api/jobs/ ──────────────► Observation (запланировано) │ └── приём ──► /api/observations/ (аудио, водопад) /api/demoddata/ (кадры) │ ▼ rate_observation ──► статус наблюдения │ ▼ decode_*, process_audio, zip/archive │ ▼ generate_daily_metrics ──► аналитика ``` Планирование идёт встречным потоком: `fetch_tle` → `LatestTleSet` → `predict_available_observation_windows` → `create_new_observation` → задания для клиента.