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
This commit is contained in:
2026-04-16 17:59:06 +03:00
parent 2d96a1a135
commit 5a45c8b52e
14 changed files with 1142 additions and 53 deletions

173
README.md
View File

@@ -2,44 +2,27 @@
Бэкенд для логистической платформы. Управление заказами на перевозку, водителями, транспортом и складами. При создании заказа строится реальный маршрут через OSRM, считается стоимость перевозки, трекинг водителя в реальном времени через WebSocket.
Репозиторий: [github.com/anxi0uz/logiflow](https://github.com/anxi0uz/logiflow.git)
## Стек
- **Go 1.25** — Chi v5, oapi-codegen, pgx/v5, go-redis
- **Go 1.25** — Chi v5, oapi-codegen, pgx/v5, go-redis, errgroup
- **PostgreSQL** — миграции через Goose
- **Redis** — хранение JWT access/refresh токенов
- **Nominatim** — геокодинг адресов (OpenStreetMap, без ключа)
- **OSRM** — построение маршрутов и расчёт дистанции
- **Prometheus + Grafana** — мониторинг
- **Prometheus + Grafana** — мониторинг HTTP метрик
- **Podman** — контейнеризация
## Запуск
## Быстрый старт
```bash
# поднять все сервисы
make up
# пересобрать и поднять
make build-up
# остановить
make down
# для деплоя (pull + build + up)
make deploy
```
Перед запуском создать сеть:
Создать сеть:
```bash
podman network create LogiflowNetwork
```
Скопировать `.env` и заполнить секреты:
Создать `.env` и заполнить:
```bash
cp .env.example .env
```
Обязательные переменные:
```
LOGIFLOW_DATABASE_USER=
LOGIFLOW_DATABASE_PASSWORD=
LOGIFLOW_DATABASE_NAME=
@@ -47,16 +30,44 @@ 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 = 5000.0 # базовая ставка, руб
perKm = 100.0 # руб/км
perKg = 15.0 # руб/кг
perM3 = 600.0 # руб/м³
baseFee = 500.0 # базовая ставка, руб
perKm = 25.0 # руб/км
perKg = 3.0 # руб/кг
perM3 = 150.0 # руб/м³
```
Цена заказа считается по формуле:
@@ -68,12 +79,12 @@ total = baseFee + distance_km * perKm + weight_kg * perKg + volume_m3 * perM3
| Роль | Возможности |
|---|---|
| `client` | Создаёт заказы, следит за своими заявками |
| `driver` | Меняет свой статус, видит назначенные маршруты |
| `manager` | Назначает водителей на заказы |
| `admin` | Создаёт профили водителей и менеджеров, видит всё |
| `client` | Создаёт и отменяет свои заказы, следит за статусом |
| `driver` | Меняет свой статус, видит назначенные заказы, двигает статус in_transit/delivered |
| `manager` | Назначает водителей на заказы, управляет статусами, смотрит отчёты |
| `admin` | Создаёт профили водителей, видит всё |
Клиенты регистрируются сами через `POST /auth/register`. Водителей и менеджеров создаёт только администратор.
Клиенты регистрируются через `POST /auth/register`. Роль назначается вручную в БД. Водителей создаёт `admin`, менеджеров — авторизованный пользователь.
## Авторизация
@@ -83,6 +94,83 @@ JWT (HS256) + refresh токены. Access токен живёт 24 часа, re
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` | Отметить прочитанным |
## Флоу заказа
```
@@ -110,4 +198,21 @@ orders (created_by_id → users, driver_id → drivers, manager_id → managers)
notifications (user_id → users)
```
Сервер поднимается на `localhost:3001`, Grafana на `localhost:3000`, Prometheus на `localhost:9090`.
## Мониторинг
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/...
```