# Техническое задание ## Система мониторинга транспорта в реальном времени --- ## 1. Общие сведения | Параметр | Значение | |----------|----------| | Название проекта | Transport Monitoring System | | Тип | Учебный проект | | Версия ТЗ | 1.0 | | Дата | 2025-12-18 | | Срок разработки | 2 недели | | Frontend фреймворк | Vue 3 (выбран) | --- ## 2. Цели и задачи проекта ### 2.1 Цель Разработка веб-системы для мониторинга местоположения транспортных средств в реальном времени с визуализацией на карте и хранением истории перемещений. ### 2.2 Задачи - Отображение текущего положения транспорта на интерактивной карте - Обновление позиций в реальном времени (WebSocket) - Хранение и просмотр истории перемещений - Генерация событий (остановки, превышение скорости) - Симуляция данных для демонстрации работы системы --- ## 3. Технологический стек ### 3.1 Backend | Компонент | Технология | Версия | |-----------|------------|--------| | Язык | Python | 3.11+ | | Фреймворк | FastAPI | 0.104+ | | ORM | SQLAlchemy | 2.0+ | | Миграции | Alembic | 1.12+ | | База данных | PostgreSQL | 15+ | | WebSocket | FastAPI WebSockets | встроено | ### 3.2 Frontend | Компонент | Технология | Версия | |-----------|------------|--------| | Фреймворк | Vue 3 | 3.4+ | | Сборщик | Vite | 5.0+ | | Карты | Leaflet | 1.9+ | | UI-компоненты | Naive UI | 2.35+ | | HTTP-клиент | Axios | 1.6+ | ### 3.3 Инфраструктура | Компонент | Технология | |-----------|------------| | Контейнеризация | Docker + Docker Compose | | Reverse Proxy | Nginx 1.25+ | | Тайлы карты | OpenStreetMap | ### 3.4 Nginx (Reverse Proxy) Nginx выступает единой точкой входа: - `/` → статика Vue (production) или проксирование на Vite (development) - `/api/*` → проксирование на FastAPI backend - `/ws/*` → проксирование WebSocket на backend ``` ┌─────────────────────────────────────────────────────────────┐ │ Nginx (:80) │ ├─────────────────────────────────────────────────────────────┤ │ / → Frontend (статика или Vite dev:5173) │ │ /api/* → Backend (FastAPI :8000) │ │ /ws/* → Backend WebSocket (:8000) │ └─────────────────────────────────────────────────────────────┘ ``` --- ## 4. Функциональные требования ### 4.1 Модуль "Диспетчер" (главный экран) #### FR-1.1 Карта - [ ] Отображение интерактивной карты на базе Leaflet + OSM - [ ] Маркеры транспортных средств с иконками по типу (автобус, грузовик, легковой) - [ ] Всплывающая подсказка при наведении на маркер (название, скорость) - [ ] Центрирование карты по выбранному объекту #### FR-1.2 Список объектов - [ ] Боковая панель со списком всех транспортных средств - [ ] Поиск/фильтрация по названию - [ ] Индикатор статуса: движется (зелёный), стоит (жёлтый), нет связи (серый) - [ ] Клик по объекту — выделение на карте + открытие карточки #### FR-1.3 Карточка объекта - [ ] Название и тип ТС - [ ] Текущие координаты (lat, lon) - [ ] Скорость (км/ч) - [ ] Направление движения (heading) - [ ] Время последней точки - [ ] Статус (движется/стоит) ### 4.2 Модуль "История движения" #### FR-2.1 Запрос истории - [ ] Выбор временного диапазона: 30 мин / 1 час / 24 часа / произвольный - [ ] Кнопка "Показать трек" #### FR-2.2 Отображение трека - [ ] Полилиния маршрута на карте - [ ] Цветовая индикация скорости (опционально) - [ ] Маркеры начала и конца маршрута #### FR-2.3 Таблица точек - [ ] Список точек: время, координаты, скорость - [ ] Клик по строке — центрирование карты на точке - [ ] Экспорт в CSV (опционально) ### 4.3 Модуль "Реалтайм обновления" #### FR-3.1 WebSocket соединение - [ ] Автоматическое подключение при загрузке страницы - [ ] Переподключение при обрыве связи - [ ] Индикатор статуса соединения в UI #### FR-3.2 Обновление данных - [ ] Плавное перемещение маркеров при получении новых координат - [ ] Обновление данных в карточке объекта - [ ] Обновление статусов в списке объектов ### 4.4 Модуль "События" #### FR-4.1 Типы событий - [ ] `LONG_STOP` — остановка более N минут (настраиваемый порог) - [ ] `OVERSPEED` — превышение скорости (порог настраивается) - [ ] `CONNECTION_LOST` — нет данных более 5 минут #### FR-4.2 Лента событий - [ ] Панель с последними событиями (10-20 штук) - [ ] Фильтр по типу события - [ ] Клик по событию — переход к объекту на карте ### 4.5 Модуль "Симулятор" #### FR-5.1 Генерация данных - [ ] Python-скрипт для имитации движения N объектов - [ ] Реалистичное движение по координатам (не телепортация) - [ ] Случайные остановки и изменения скорости - [ ] Отправка данных через REST API или WebSocket --- ## 5. Архитектура системы ### 5.1 Общая схема ``` ┌─────────────────┐ │ │ │ Nginx │ :80 │ (reverse proxy)│ │ │ └────────┬────────┘ │ ┌──────────────────┼──────────────────┐ │ /api, /ws │ / │ ▼ │ ▼ ┌─────────────────┐ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │ │ │ │ │ │ Симулятор │────▶ Backend │ │ Frontend │ │ (Python) │POST│ (FastAPI) │ │ (Vue 3) │ │ │ │ :8000 │ │ :5173 (dev) │ └─────────────────┘ └────────┬────────┘ └─────────────────┘ │ │ SQL ▼ ┌─────────────────┐ │ │ │ PostgreSQL │ :5432 │ │ └─────────────────┘ ``` ### 5.2 Структура проекта ``` transport/ ├── docker-compose.yml ├── docs/ │ └── TECHNICAL_SPECIFICATION.md ├── nginx/ │ ├── nginx.conf # Основной конфиг │ ├── conf.d/ │ │ └── default.conf # Конфиг сервера │ └── Dockerfile # (опционально, для кастомизации) ├── backend/ │ ├── Dockerfile │ ├── requirements.txt │ ├── alembic/ │ │ └── versions/ │ ├── alembic.ini │ ├── app/ │ │ ├── __init__.py │ │ ├── main.py # FastAPI приложение │ │ ├── config.py # Настройки │ │ ├── database.py # Подключение к БД │ │ ├── models/ │ │ │ ├── __init__.py │ │ │ ├── vehicle.py │ │ │ ├── position.py │ │ │ └── event.py │ │ ├── schemas/ │ │ │ ├── __init__.py │ │ │ ├── vehicle.py │ │ │ ├── position.py │ │ │ └── event.py │ │ ├── routers/ │ │ │ ├── __init__.py │ │ │ ├── vehicles.py │ │ │ ├── positions.py │ │ │ └── events.py │ │ ├── services/ │ │ │ ├── __init__.py │ │ │ ├── event_detector.py │ │ │ └── websocket_manager.py │ │ └── websocket.py # WS эндпоинт │ └── simulator/ │ └── run.py # Симулятор данных ├── frontend/ │ ├── Dockerfile │ ├── package.json │ ├── vite.config.js │ ├── index.html │ └── src/ │ ├── main.js │ ├── App.vue │ ├── components/ │ │ ├── MapView.vue │ │ ├── VehicleList.vue │ │ ├── VehicleCard.vue │ │ ├── TrackHistory.vue │ │ └── EventFeed.vue │ ├── composables/ │ │ ├── useWebSocket.js │ │ └── useVehicles.js │ └── stores/ │ └── vehicles.js └── README.md ``` --- ## 6. API спецификация ### 6.1 REST API #### Транспортные средства | Метод | Эндпоинт | Описание | |-------|----------|----------| | GET | `/api/vehicles` | Список всех ТС | | GET | `/api/vehicles/{id}` | Информация о ТС | | POST | `/api/vehicles` | Создать ТС | | PUT | `/api/vehicles/{id}` | Обновить ТС | | DELETE | `/api/vehicles/{id}` | Удалить ТС | #### Позиции | Метод | Эндпоинт | Описание | |-------|----------|----------| | GET | `/api/vehicles/{id}/positions` | История позиций ТС | | POST | `/api/ingest/position` | Принять новую позицию | | GET | `/api/vehicles/{id}/last-position` | Последняя позиция ТС | **Query параметры для `/api/vehicles/{id}/positions`:** - `from` — начало периода (ISO 8601) - `to` — конец периода (ISO 8601) - `limit` — максимум записей (default: 1000) #### События | Метод | Эндпоинт | Описание | |-------|----------|----------| | GET | `/api/events` | Список событий | | GET | `/api/vehicles/{id}/events` | События конкретного ТС | **Query параметры для `/api/events`:** - `type` — тип события (LONG_STOP, OVERSPEED, CONNECTION_LOST) - `from` / `to` — временной диапазон - `limit` — максимум записей ### 6.2 WebSocket API #### Подключение ``` ws://localhost/ws/positions ``` *(Nginx проксирует на backend:8000)* #### Формат сообщений (сервер → клиент) ```json { "type": "position_update", "data": { "vehicle_id": 1, "lat": 55.7558, "lon": 37.6173, "speed": 45.5, "heading": 180, "timestamp": "2025-12-18T12:00:00Z" } } ``` ```json { "type": "event", "data": { "id": 123, "vehicle_id": 1, "type": "OVERSPEED", "payload": {"speed": 95, "limit": 60}, "timestamp": "2025-12-18T12:00:00Z" } } ``` --- ## 7. Структура базы данных ### 7.1 Таблица `vehicles` | Поле | Тип | Описание | |------|-----|----------| | id | SERIAL PRIMARY KEY | Идентификатор | | name | VARCHAR(100) NOT NULL | Название/номер ТС | | type | VARCHAR(50) | Тип: bus, truck, car | | created_at | TIMESTAMP | Дата создания | ### 7.2 Таблица `positions` | Поле | Тип | Описание | |------|-----|----------| | id | SERIAL PRIMARY KEY | Идентификатор | | vehicle_id | INTEGER FK | Ссылка на vehicles | | timestamp | TIMESTAMP NOT NULL | Время фиксации | | lat | DOUBLE PRECISION | Широта | | lon | DOUBLE PRECISION | Долгота | | speed | REAL | Скорость (км/ч) | | heading | REAL | Направление (0-360) | **Индексы:** - `idx_positions_vehicle_ts` ON (vehicle_id, timestamp DESC) ### 7.3 Таблица `events` | Поле | Тип | Описание | |------|-----|----------| | id | SERIAL PRIMARY KEY | Идентификатор | | vehicle_id | INTEGER FK | Ссылка на vehicles | | timestamp | TIMESTAMP NOT NULL | Время события | | type | VARCHAR(50) NOT NULL | Тип события | | payload | JSONB | Дополнительные данные | **Индексы:** - `idx_events_vehicle_ts` ON (vehicle_id, timestamp DESC) - `idx_events_type` ON (type) --- ## 8. Нефункциональные требования ### 8.1 Производительность - Система должна поддерживать минимум 100 одновременных объектов - Частота обновления позиций: 1 раз в 1-2 секунды на объект - Время отклика API: < 500 мс для 95% запросов ### 8.2 Надёжность - WebSocket должен автоматически переподключаться при обрыве - При недоступности БД — graceful degradation с логированием ошибок ### 8.3 Развёртывание - Запуск всей системы одной командой: `docker-compose up` - Автоматическое применение миграций при старте ### 8.4 Безопасность (упрощённо для учебного проекта) - CORS настроен для локальной разработки - Валидация входных данных на уровне Pydantic-схем - (Опционально) Базовая авторизация через API-ключ --- ## 9. Этапы разработки ### Этап 1: Инфраструктура - [ ] Настройка Docker Compose (Nginx + PostgreSQL + backend + frontend) - [ ] Конфигурация Nginx (проксирование /api, /ws, статика) - [ ] Базовая структура FastAPI приложения - [ ] Подключение к БД, настройка Alembic - [ ] Базовая структура Vue-приложения ### Этап 2: CRUD и карта - [ ] Модели и миграции для vehicles, positions - [ ] REST API для vehicles - [ ] Endpoint POST /ingest/position - [ ] Фронт: отображение карты с маркерами - [ ] Фронт: список объектов + карточка ### Этап 3: Реалтайм - [ ] WebSocket manager на бэкенде - [ ] Broadcast новых позиций всем клиентам - [ ] Фронт: подключение к WS, обновление маркеров - [ ] Симулятор: базовая версия ### Этап 4: История и события - [ ] GET /vehicles/{id}/positions с фильтрами - [ ] Модель events + детектор событий - [ ] Фронт: отображение трека на карте - [ ] Фронт: таблица точек + лента событий ### Этап 5: Финализация - [ ] Улучшение UI/UX - [ ] Доработка симулятора (реалистичные маршруты) - [ ] Тестирование под нагрузкой (100 объектов) - [ ] Документация для запуска и демонстрации --- ## 10. Запуск проекта ### Требования - Docker 20.10+ - Docker Compose 2.0+ ### Команды ```bash # Клонировать репозиторий git clone cd transport # Запустить всё docker-compose up --build # Доступ (всё через Nginx на порту 80) # Приложение: http://localhost # API: http://localhost/api # API Docs: http://localhost/api/docs # WebSocket: ws://localhost/ws/positions # Запустить симулятор (в отдельном терминале) docker-compose exec backend python -m simulator.run ``` ### Docker Compose сервисы | Сервис | Порт (внутренний) | Порт (внешний) | Описание | |--------|-------------------|----------------|----------| | nginx | 80 | 80 | Reverse proxy, точка входа | | backend | 8000 | - | FastAPI, доступен только через nginx | | frontend | 5173 (dev) | - | Vue dev server, доступен только через nginx | | postgres | 5432 | 5432* | База данных | *Порт PostgreSQL открыт наружу для удобства разработки (подключение через IDE/DBeaver) --- ## 11. Критерии приёмки | № | Критерий | Приоритет | |---|----------|-----------| | 1 | Карта отображается с маркерами объектов | Обязательно | | 2 | Позиции обновляются в реальном времени (WS) | Обязательно | | 3 | История движения показывается на карте | Обязательно | | 4 | Система запускается через docker-compose up | Обязательно | | 5 | Симулятор генерирует тестовые данные | Обязательно | | 6 | Лента событий отображается | Желательно | | 7 | Поддержка 100+ объектов без лагов | Желательно | | 8 | Экспорт истории в CSV | Опционально | --- *Документ составлен: 2025-12-18*