8.5 KiB
NetworkService — полная карта API-вызовов
Все HTTP-вызовы, выполняемые приложением. Класс NetworkService (services/net/NetworkService.h/cpp).
Аутентификация
| Метод | Путь | Слот | Описание |
|---|---|---|---|
| POST | /api/v1/auth/login |
loginAndSetup() |
Вход по api_key, получение токенов |
| POST | /api/v1/auth/refresh_token |
refreshToken() (private) |
Обновление access_token |
Токены сохраняются в config.ini. Авто-рефреш за 30 минут до истечения — scheduleNextRefresh().
Desktop
| Метод | Путь | Слот | Описание |
|---|---|---|---|
| POST | /api/v1/desktop/ |
loginAndSetup() |
Создание desktop при первом запуске (если desktop_id не сохранён) |
Ответ: сохраняет desktop_id и profile_id в config.ini.
Device
| Метод | Путь | Слот | Описание |
|---|---|---|---|
| POST | /api/v1/device/ |
createDevice() |
Регистрация нового Android устройства |
| PATCH | /api/v1/device/{api_id} |
updateDevice() |
Обновление статуса/батареи устройства |
| POST | /api/v1/device/add_screenshot/{api_id} |
postDeviceScreenshot() |
Загрузка скриншота (multipart/form-data, image/jpeg) |
api_id — UUID, получаемый при создании и сохраняемый в таблице devices.
Profile / Material
| Метод | Путь | Слот | Описание |
|---|---|---|---|
| POST | /api/v1/profile/bank_profile |
postBankProfile() |
Создать банк-профиль |
| PATCH | /api/v1/profile/bank_profile/{id} |
patchBankProfile() |
Обновить банк-профиль |
| POST | /api/v1/profile/material |
postMaterial() |
Создать материал (карту) |
postBankProfile сохраняет bank_profile_id в таблице applications.
postMaterial сохраняет material_id (UUID) в таблице accounts.
Tasks
| Метод | Путь | Слот | Auth | Описание |
|---|---|---|---|---|
| GET | /api/v1/task/get_tasks |
getTasks() |
Bearer | Получить очередь задач (поллинг каждые 5 сек) |
| POST | /api/v1/task/task_result |
postTaskResult() |
Bearer | Отправить результат задачи |
getTasks() — асинхронный (без QEventLoop), использует сигнал tasksReceived(QJsonArray).
postTaskResult() — вызывается из sendTaskResult() в EventHandler в отдельном QThread.
Устаревшие эндпоинты (legacy)
Используют старый multipart/form-data API с токеном в теле. Пути задаются в config.ini напрямую как полные URL.
| Слот | Ключ в config.ini | Статус |
|---|---|---|
postEventStatus() |
net/eventStatusUpdate |
⚠️ устарел, используется в updateEventThread |
postAppStatus() |
net/appStatusUpdate |
используется при смене статуса приложения |
insertTransactionData() |
net/transactionInsert |
создание транзакции |
updateTransactionData() |
net/transactionUpdate |
обновление транзакции |
getPayments() |
net/paymentsGet |
⚠️ старый поллинг задач (заменён на getTasks) |
Конфигурация путей (config.ini)
[net]
apiBase = http://localhost:9999
pathAuthLogin = /api/v1/auth/login
pathAuthRefresh = /api/v1/auth/refresh_token
pathDesktopCreate = /api/v1/desktop/
pathDevice = /api/v1/device/
pathDeviceScreenshot = /api/v1/device/add_screenshot/
pathBankProfile = /api/v1/profile/bank_profile
pathMaterial = /api/v1/profile/material
pathGetTasks = /api/v1/task/get_tasks
pathTaskResult = /api/v1/task/task_result
Если ключ отсутствует — используется значение по умолчанию (захардкожено в конструкторе NetworkService).
Авторизация в запросах
- Bearer —
Authorization: Bearer <access_token>изconfig.ini [common/access_token] - Legacy — поле
tokenв multipart-теле (изconfig.ini [common/token])
Таймауты и ретраи
Каждый синхронный запрос крутится в локальном QEventLoop под охраной QTimer. Если таймер сработал раньше, чем reply->finished — это client timeout: запрос аборитится и повторяется заново.
Параметры
| Параметр | Значение | Где |
|---|---|---|
| Лимит ожидания | 30 секунд | kDefaultTimeoutMs — все запросы |
| Лимит ожидания (dump) | 120 секунд | kDumpTimeoutMs — только postMonitoringDump (большой zip-архив) |
| Макс. попыток | 3 | kMaxRequestAttempts — 1 основная + 2 повтора |
| Пауза между попытками | 0 | Ретрай идёт сразу после abort |
Константы и helper awaitReply() — в анонимном namespace в services/net/NetworkService.cpp.
Когда ретраим
Ретрай срабатывает только при client timeout (наш QTimer сработал, reply не успел завершиться). На любых других исходах ретрая нет:
| Исход | Ретрай? | Почему |
|---|---|---|
| Client timeout (наш QTimer) | ✅ да | сеть моргнула — стоит попробовать |
| HTTP 4xx (401/404/409/…) | ❌ нет | детерминированная ошибка, повтор не поможет |
| HTTP 5xx | ❌ нет | сервер ответил — это бизнес-сбой, не транспортный |
ConnectionRefused / DNS / SSL |
❌ нет | повтор не починит инфраструктурную проблему |
success: false в JSON |
❌ нет | прикладная ошибка |
После каждой неудачной попытки в лог пишется Network timeout (POST) attempt N/3: <details>; если все 3 попытки таймаутнулись — финальная строка Timeout (POST) after 3 attempts: <details> плюс запись в GeneralLogDAO (для postJson/patchJson).
Покрытие методов
| Метод | Ретрай | Примечание |
|---|---|---|
postJson |
✅ | |
patchJson |
✅ | |
getJson |
✅ | |
deleteJson |
✅ | |
get(path, params) |
✅ | используется getPayments() (legacy) |
syncBanksIfEmpty() инлайн-GET |
✅ | |
postDeviceScreenshot() |
✅ | multipart пересобирается на каждой попытке |
postMonitoringLog() |
✅ | multipart пересобирается на каждой попытке |
postMonitoringDump() |
✅ | timeout 120s; multipart пересобирается |
post(QHttpMultiPart*, path) |
❌ | multipart передаётся снаружи и удаляется вместе с reply; колл-сайты (postEventStatus/insertTransactionData/…) — legacy |
getTasks() |
❌ | асинхронный (без QEventLoop); таймаут просто аборитит reply |
Идемпотентность
⚠️ POST-запросы, создающие ресурсы (/desktop/, /device/, /profile/bank_profile, /profile/material), при ретрае могут создать дубль, если первая попытка дошла до сервера, но ответ потерялся. Сейчас защиты от этого нет — полагаемся на то, что 3 timeout-а подряд это редкая ситуация. Если станет проблемой — добавлять идемпотентные ключи на стороне бэкенда.