Files
logiflow/README.md
anxi0uz 5a45c8b52e feat: implement order workflow, metrics, and handler unit tests
- implement UpdateOrderStatus and GetOrdersReport service methods
- implement all order, user handlers (UpdateMe, GetMyTrips, CancelOrder, GetOrder, etc.)
- extract OrderServicer interface for testability
- add Prometheus metrics middleware (requests total, duration)
- fix GetAll storage flavor for PostgreSQL ($1 placeholders)
- add 17 unit tests for order handlers via httptest
- wire Grafana datasource and update Prometheus scrape config
- update README with full API reference, pricing, roles, monitoring
2026-04-16 17:59:06 +03:00

219 lines
8.0 KiB
Markdown
Raw Blame History

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.
# Logiflow
Бэкенд для логистической платформы. Управление заказами на перевозку, водителями, транспортом и складами. При создании заказа строится реальный маршрут через OSRM, считается стоимость перевозки, трекинг водителя в реальном времени через WebSocket.
Репозиторий: [github.com/anxi0uz/logiflow](https://github.com/anxi0uz/logiflow.git)
## Стек
- **Go 1.25** — Chi v5, oapi-codegen, pgx/v5, go-redis, errgroup
- **PostgreSQL** — миграции через Goose
- **Redis** — хранение JWT access/refresh токенов
- **Nominatim** — геокодинг адресов (OpenStreetMap, без ключа)
- **OSRM** — построение маршрутов и расчёт дистанции
- **Prometheus + Grafana** — мониторинг HTTP метрик
- **Podman** — контейнеризация
## Быстрый старт
Создать сеть:
```bash
podman network create LogiflowNetwork
```
Создать `.env` и заполнить:
```bash
LOGIFLOW_DATABASE_USER=
LOGIFLOW_DATABASE_PASSWORD=
LOGIFLOW_DATABASE_NAME=
LOGIFLOW_REDIS_PASSWORD=
LOGIFLOW_JWT_KEY=
```
Поднять все сервисы:
```bash
make up # запуск
make build-up # пересборка + запуск
make down # остановка
make deploy # pull + пересборка + запуск (для деплоя)
```
## Сервисы
| Сервис | Адрес |
|---|---|
| API | `http://localhost:3001` |
| Grafana | `http://localhost:3000` |
| Prometheus | `http://localhost:9090` |
| Метрики | `http://localhost:3001/metrics` |
## Конфигурация
Конфиг читается из `configs/config.toml`, переменные окружения с префиксом `LOGIFLOW_` перекрывают файл.
```toml
[server]
host = "0.0.0.0"
port = 3001
readTimeout = "10s"
writeTimeout = "30s"
idleTimeout = "60s"
[redis]
refreshTokenTTL = "168h"
accessTokenTTL = "24h"
[pricing]
baseFee = 500.0 # базовая ставка, руб
perKm = 25.0 # руб/км
perKg = 3.0 # руб/кг
perM3 = 150.0 # руб/м³
```
Цена заказа считается по формуле:
```
total = baseFee + distance_km * perKm + weight_kg * perKg + volume_m3 * perM3
```
## Роли
| Роль | Возможности |
|---|---|
| `client` | Создаёт и отменяет свои заказы, следит за статусом |
| `driver` | Меняет свой статус, видит назначенные заказы, двигает статус in_transit/delivered |
| `manager` | Назначает водителей на заказы, управляет статусами, смотрит отчёты |
| `admin` | Создаёт профили водителей, видит всё |
Клиенты регистрируются через `POST /auth/register`. Роль назначается вручную в БД. Водителей создаёт `admin`, менеджеров — авторизованный пользователь.
## Авторизация
JWT (HS256) + refresh токены. Access токен живёт 24 часа, refresh — 7 дней в HTTP-only cookie. Оба хранятся в Redis — при логауте удаляются.
```
Authorization: <access_token>
```
## API
### Auth
| Метод | Путь | Описание |
|---|---|---|
| POST | `/auth/register` | Регистрация клиента |
| POST | `/auth/login` | Вход, получение токенов |
| POST | `/auth/logout` | Выход, инвалидация токенов |
| POST | `/auth/refresh` | Обновление access токена |
### Пользователь
| Метод | Путь | Описание |
|---|---|---|
| GET | `/me` | Профиль текущего пользователя |
| PATCH | `/me` | Обновить имя, аватар, пароль |
| DELETE | `/me` | Удалить аккаунт |
| GET | `/me/trips` | История поездок (driver) |
### Заказы
| Метод | Путь | Описание |
|---|---|---|
| GET | `/orders` | Список заказов (по роли) |
| POST | `/orders` | Создать заказ |
| GET | `/orders/{id}` | Получить заказ |
| DELETE | `/orders/{id}` | Отменить заказ |
| PATCH | `/orders/{id}/status` | Обновить статус |
| GET | `/orders/{id}/route` | Маршрут заказа |
| GET | `/orders/{id}/route/ws` | WebSocket трекинг |
### Водители
| Метод | Путь | Описание |
|---|---|---|
| GET | `/drivers` | Список водителей |
| POST | `/drivers` | Создать водителя (admin) |
| GET | `/drivers/{slug}` | Получить водителя |
| PUT | `/drivers/{slug}` | Обновить водителя |
| DELETE | `/drivers/{slug}` | Удалить водителя |
| PATCH | `/drivers/me/status` | Обновить свой статус (driver) |
### Менеджеры
| Метод | Путь | Описание |
|---|---|---|
| GET | `/managers` | Список менеджеров |
| POST | `/managers` | Создать менеджера |
| GET | `/managers/{slug}` | Получить менеджера |
| DELETE | `/managers/{slug}` | Удалить менеджера |
### Склады
| Метод | Путь | Описание |
|---|---|---|
| GET | `/warehouses` | Список складов |
| POST | `/warehouses` | Создать склад |
| GET | `/warehouses/{slug}` | Получить склад |
| PUT | `/warehouses/{slug}` | Обновить склад |
| DELETE | `/warehouses/{slug}` | Удалить склад |
### Транспорт
| Метод | Путь | Описание |
|---|---|---|
| GET | `/vehicles` | Список ТС |
| POST | `/vehicles` | Добавить ТС |
| GET | `/vehicles/{slug}` | Получить ТС |
| PUT | `/vehicles/{slug}` | Обновить ТС |
| DELETE | `/vehicles/{slug}` | Удалить ТС |
### Отчёты
| Метод | Путь | Описание |
|---|---|---|
| GET | `/reports/orders` | Отчёт по заказам (manager) |
| GET | `/reports/dashboard` | Дашборд (manager) |
### Уведомления
| Метод | Путь | Описание |
|---|---|---|
| GET | `/notifications` | Список уведомлений |
| PATCH | `/notifications/{id}/read` | Отметить прочитанным |
## Флоу заказа
```
Клиент создаёт заказ (адреса → Nominatim → координаты → OSRM → маршрут)
Менеджер назначает водителя (pending → assigned)
Водитель начинает поездку (assigned → in_transit)
Трекинг по WebSocket — current_index двигается по массиву координат
Водитель завершает (in_transit → delivered)
```
## Структура БД
```
users
├── drivers (user_id) → vehicles
└── managers (user_id) → warehouses
orders (created_by_id → users, driver_id → drivers, manager_id → managers)
└── routes (order_id) — JSONB координаты маршрута, current_index
notifications (user_id → users)
```
## Мониторинг
Prometheus собирает метрики с `/metrics`. Grafana доступна на `localhost:3000` (admin/admin).
Доступные метрики:
- `logiflow_http_requests_total` — кол-во запросов по методу, пути, статусу
- `logiflow_http_duration_seconds` — latency запросов
Конфиг Prometheus: `configs/prometheus.yml`
Datasource Grafana: `configs/datasources/`
## Тесты
Юнит тесты хендлеров через `httptest` без реальной БД:
```bash
go test ./tests/...
```