fde96c019785f1f93eb677593e65d4d79df14b78
- Add Swagger UI files and updated API spec for Family Safety Tracker - Replace shelf_cors_headers with custom CORS middleware in server.dart - Add request_logger middleware with timing for auth and geo routes - Add REGISTRATION_SECRET_KEY to .env for registration validation - Remove postgres port exposure from docker-compose.yml - Update opencode.json model configuration - Add crypto dependency and update Flutter web assets
Family Safety Tracker API
REST API для обмена геолокацией между членами семьи.
Аутентификация
Сервис использует JWT токены для авторизации.
JWT Токен
При успешном POST /login возвращается JWT токен:
{
"user": {...},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Структура токена:
issuer: "family_safety_tracker"payload: {"user_id": N, "login": "user"}
Авторизация
Защищённые эндпоинты (/watch, /geo, /share) требуют JWT в заголовке:
Authorization: Bearer <jwt_token>
Таблица эндпоинтов
| Метод | URL | Описание | Защита |
|---|---|---|---|
POST |
/login |
Вход в систему | — |
POST |
/reg |
Регистрация нового пользователя | — |
GET |
/watch?unique_id=... |
Получить последнюю позицию по share-ссылке | ✅ |
PUT |
/geo?id=N |
Обновить геопозицию | ✅ |
POST |
/share |
Создать share-ссылку | ✅ |
Эндпоинты
POST /login — Вход
Запрос
curl -X POST http://localhost:9090/reg \
-H "Content-Type: application/json" \
-d '{"login": "ivan", "password": "secret123"}'
PowerShell
$body = @{ login = "ivan"; password = "secret123" } | ConvertTo-Json
Invoke-RestMethod -Uri http://localhost:9090/reg -Method Post -Body $body -ContentType "application/json"
Успешный ответ (200)
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
Ошибки
| Код | Сообщение |
|---|---|
401 |
Invalid credentials — неверный логин или пароль |
POST /reg — Регистрация
Запрос
Content-Type: application/json
{"login": "maria", "password": "newpass"}
Успешный ответ (201)
Ничего не возвращается.
GET /watch?unique_id=... — Получить позицию
Запрос
Authorization: Bearer <jwt_token>
GET /watch?unique_id=a1b2c3d4-e5f6-7890-abcd-ef1234567890
Успешный ответ (200)
{
"id": 42,
"x": 55.7558,
"y": 37.6173,
"created_at": "2024-01-01T12:00:00Z",
"expires_at": "2024-01-01T12:05:00Z"
}
Ошибки
| Код | Сообщение |
|---|---|
404 |
Share link not found — неверный unique_id |
404 |
No position available — share-ссылка создана, но позиция не была добавлена |
PUT /geo?id=N — Обновить позицию
Запрос
Authorization: Bearer <jwt_token>
Content-Type: application/json
PUT /geo?id=1
{
"x": 55.7558,
"y": 37.6173
}
Успешный ответ (200)
Ничего не возвращается.
POST /share — Создать share-ссылку
Запрос
Authorization: Bearer <jwt_token>
Content-Type: application/json
{
"x": 55.7558,
"y": 37.6173
}
Успешный ответ (201)
{
"geo_id": 5,
"share_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
Примеры запросов
Регистрация
curl -X POST http://localhost:8080/reg \
-H "Content-Type: application/json" \
-d '{"login": "ivan", "password": "secret123"}'
Вход
curl -X POST http://localhost:9090/login \
-H "Content-Type: application/json" \
-d '{"login": "ivan", "password": "secret123"}'
PowerShell
$body = @{ login = "ivan"; password = "secret123" } | ConvertTo-Json
Invoke-RestMethod -Uri http://localhost:9090/login -Method Post -Body $body -ContentType "application/json"
Создание share-ссылки
TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
curl -X POST http://localhost:9090/share \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"x": 55.7558, "y": 37.6173}'
PowerShell
$token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
$body = @{ x = 55.7558; y = 37.6173 } | ConvertTo-Json
Invoke-RestMethod -Uri http://localhost:9090/share -Method Post -Headers @{ Authorization = "Bearer $token"; "Content-Type" = "application/json" } -Body $body
Получение позиции
TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
SHARE_ID="a1b2c3d4-e5f6-7890-abcd-ef1234567890"
curl "http://localhost:9090/watch?unique_id=$SHARE_ID" \
-H "Authorization: Bearer $TOKEN"
PowerShell
$token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
$shareId = "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
Invoke-RestMethod -Uri "http://localhost:9090/watch?unique_id=$shareId" -Method Get -Headers @{ Authorization = "Bearer $token" }
Обновление позиции
TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
curl -X PUT "http://localhost:9090/geo?id=1" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"x": 55.7558, "y": 37.6173}'
PowerShell
$token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
$body = @{ x = 55.7558; y = 37.6173 } | ConvertTo-Json
Invoke-RestMethod -Uri "http://localhost:9090/geo?id=1" -Method Put -Headers @{ Authorization = "Bearer $token"; "Content-Type" = "application/json" } -Body $body
Технические детали
Сервер
- Порт:
9090(изменяется черезPORT)
Технологии
- Dart (SDK
^3.10.1) - Shelf + Shelf Router — HTTP фреймворк
- PostgreSQL — база данных
- bcrypt — хэширование паролей
- dart_jsonwebtoken — JWT-токены
- dotenv — переменные окружения
Переменные окружения
| Переменная | Описание |
|---|---|
PORT |
Порт сервера (по умолчанию 8080) |
POSTGRES_HOST |
Хост PostgreSQL |
POSTGRES_DB |
База данных |
POSTGRES_USER |
Пользователь |
POSTGRES_PASSWORD |
Пароль |
JWT_SECRET |
Секрет для JWT-токенов |
Автоматическая миграция
При запуске сервера таблицы создаются автоматически:
users— пользователиgeopositions— геопозицииlogs— логи
Структура проекта
bin/
├── server.dart # Точка входа
├── routes/
│ ├── auth_routes.dart # Маршруты авторизации
│ └── geo_routes.dart # Маршруты геолокации
├── repositories/
│ ├── user_repo.dart
│ └── geoposition_repo.dart
├── models/
│ ├── user.dart
│ ├── geoposition.dart
│ └── log.dart
└── database/
└── database_provider.dart
Запуск
dart pub get
dart run bin/server.dart
Лицензия
MIT
Description
Languages
JavaScript
98%
Dart
1.7%
HTML
0.2%