Перейти к основному содержимому

Синхронизация прогресса

Кроссплатформенная синхронизация прогресса просмотра с разрешением конфликтов по принципу last-write-wins. Все эндпоинты требуют аутентификации.

Прогресс отслеживается посерийно для сериалов (через season + episode) и целиком для фильмов (без season/episode).

Получить прогресс

Возвращает весь прогресс текущего пользователя, опционально фильтруя по медиа:

GET /api/v1/sync/progress
Authorization: Bearer <token>

# Фильтр по конкретному фильму/сериалу
GET /api/v1/sync/progress?mediaId=kp_258687
Authorization: Bearer <token>
{
"success": true,
"data": [
{
"id": "...",
"userId": "...",
"mediaId": "kp_258687",
"mediaType": "tv",
"season": 1,
"episode": 3,
"progress": 450.0,
"duration": 2640.0,
"status": "watching",
"updatedAt": "2025-01-15T10:30:00Z"
}
]
}

Сохранить прогресс

Last write wins — сервер сравнивает updatedAt и сохраняет более новый:

PUT /api/v1/sync/progress
Authorization: Bearer <token>
Content-Type: application/json

{
"mediaId": "kp_258687",
"mediaType": "tv",
"season": 1,
"episode": 3,
"progress": 450.0,
"duration": 2640.0,
"status": "watching",
"updatedAt": "2025-01-15T10:30:00Z"
}

Параметры

ПолеТипОбязательноОписание
mediaIdstringдаKinopoisk ID (например kp_258687)
mediaTypestringдаmovie или tv
seasonintegerнетОбязателен для сериалов
episodeintegerнетОбязателен для сериалов
progressfloatдаПросмотренные секунды
durationfloatдаПолная длительность в секундах
statusstringдаwatching, completed, paused, dropped
updatedAtstringдаISO 8601 timestamp

Ответ:

{
"success": true,
"data": {
"saved": true,
"item": { ... }
}
}

Если на сервере уже есть более новая версия (по updatedAt), то saved будет false, а itemnull.

Пакетная синхронизация

Отправить локальные изменения и получить полное состояние сервера за один запрос:

POST /api/v1/sync/progress/batch
Authorization: Bearer <token>
Content-Type: application/json

{
"items": [
{
"mediaId": "kp_258687",
"mediaType": "tv",
"season": 1,
"episode": 3,
"progress": 450.0,
"duration": 2640.0,
"status": "watching",
"updatedAt": "2025-01-15T10:30:00Z"
}
]
}

Ответ:

{
"success": true,
"data": {
"saved": 1,
"items": [ ... ]
}
}

items содержит авторитетное состояние сервера после разрешения конфликтов.

Удалить прогресс

DELETE /api/v1/sync/progress?mediaId=kp_258687&season=1&episode=3
Authorization: Bearer <token>

Разрешение конфликтов

Синхронизация использует стратегию last-write-wins:

  1. Клиент отправляет updatedAt с каждым upsert
  2. Сервер сравнивает его с сохранённым документом
  3. Если время клиента новее → документ обновляется, saved: true
  4. Если время сервера новее или равно → документ сохраняется, saved: false
  5. Batch-эндпоинт разрешает все конфликты и возвращает каноническое состояние сервера

Этот подход хорошо работает при редких конфликтах. Для реального времени потребовалась бы CRDT-стратегия.