FLAGMAN
← К вопросам

Flagman: контракт веб-платформы и сетевого комплекса

Версия 0.2, черновик от 05.11.2026. Предложение веб-команды для обсуждения с Денисом. Основа: ТЗ v1.1, приложение А. Названия, поля и транспорт можно менять; важны данные и гарантии из раздела 2.

Часть решений в ТЗ v1.1 пока принята как допущения. Вопросы к технической команде собраны в разделе 8, новые: К-10…К-15.

Что изменилось с версии 0.1:

1. Кто за что отвечает

ДанныеГлавная система
Пользователи, подписки, оплата, срок права доступаВеб-платформа
Партнёры, реквизиты, начисления, выплатыВеб-платформа
Правило «один пробный период на устройство»Веб-платформа
Состояние устройств и узловСетевой комплекс
Маршрутизация, распределение клиентов по узлам, серверы проектаСетевой комплекс
Свободные места по странам и городамСетевой комплекс
Подтверждённые интервалы доступностиСетевой комплекс
Настройки роутера и удалённый доступ к немуСетевой комплекс

Платформа не находится на пути трафика и не получает посещаемые адреса.

2. Обязательные гарантии

  1. Автономность. Сетевой комплекс получает срок действия права заранее и применяет его сам. Недоступность платформы не отключает клиентов и не мешает активации: срок истекает только по valid_until, а при активации рассчитывается по term_days_from_activation.
  2. Идемпотентность. Повтор команды или события не меняет результат.
  3. Доставка событий не реже одного раза. Дубли и нарушение порядка допустимы, поэтому у каждого события есть event_id, а у изменяемых объектов version.
  4. Окончательность месяца. Комплекс явно сообщает, что данные о доступности за месяц полные. Без этого расчёт и выплаты не запускаются.
  5. Сверка. Обе стороны могут получить полный список текущих объектов и исправить расхождения.

3. Общие правила

Формат ошибки:

{ "error": { "code": "license_not_found", "message": "Описание для журнала", "retryable": false } }
Код HTTPЧто делает вызывающая сторона
2xxОперация принята
400, 404, 409, 422Повтор бесполезен, ошибка попадает в панель интеграции
401, 403Оповещение об ошибке доступа
429, 5xx, таймаутПовтор с нарастающей задержкой и тем же содержимым

4. Команды платформы к сетевому комплексу

4.1 Установить право доступа

PUT /v1/entitlements/{license_id}

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

{
  "version": 1,
  "state": "active",
  "period_type": "trial",
  "plan_code": "subscription_30d",
  "traffic_mode": "partner_nodes",
  "exit_location": { "country": "IN", "city": "Pune" },
  "valid_until": null,
  "term_days_from_activation": 33,
  "activation_expires_at": "2026-11-20T10:30:00Z",
  "max_devices": 1,
  "activation_code_hash": "sha256:9f2c..."
}

После активации и при каждом продлении платформа передаёт точную дату:

{
  "version": 3,
  "state": "active",
  "period_type": "paid",
  "plan_code": "subscription_30d",
  "traffic_mode": "partner_nodes",
  "exit_location": { "country": "IN", "city": "Pune" },
  "valid_until": "2027-01-07T10:30:00Z",
  "max_devices": 1
}
{ "license_id": "lic_01J9", "applied_version": 1, "device_id": null }

4.2 Заменить устройство

POST /v1/entitlements/{license_id}/release-device

Заголовок Idempotency-Key. Тело: { "reason": "router_replaced" }. Освобождает лицензию для новой активации. Срок при этом не меняется. Новый пробный период замена не даёт.

4.3 Зарегистрировать узел

PUT /v1/nodes/{partner_node_ref}

partner_node_ref создаёт платформа, ответ содержит код привязки для установки на роутер партнёра. Один партнёр равен одному узлу: платформа не отправит второй узел для того же partner_ref, пока первый не выведен.

{
  "partner_ref": "prt_4k2",
  "country": "IN",
  "city": "Pune",
  "router_model": "flint-2",
  "declared_public_ip": "203.0.113.10",
  "declared_downlink_mbps": 200
}

Ответ:

{ "partner_node_ref": "pn_91", "node_id": null, "claim_code": "8H2K-QP4M", "claim_expires_at": "2026-11-07T00:00:00Z", "status": "awaiting_claim" }

4.4 Привязать уже работающий узел

PUT /v1/nodes/{partner_node_ref}/link

Для партнёров, подключённых вручную раньше платформы (К-13). Заголовок Idempotency-Key. Тело: { "node_id": "node_12", "partner_ref": "prt_4k2" }. Код привязки не нужен, интервалы узла остаются доступны за прошлые месяцы.

4.5 Вывести узел из сети

POST /v1/nodes/{node_id}/retire

Заголовок Idempotency-Key. Тело: { "reason": "partner_terminated" }.

4.6 Точки выхода и ёмкость

GET /v1/exit-locations

{
  "as_of": "2026-11-05T09:00:00Z",
  "items": [
    { "country": "IN", "city": "Pune", "active_nodes": 8, "capacity_total": 40, "assigned_clients": 33, "free_slots": 7 },
    { "country": "IN", "city": "Mumbai", "active_nodes": 12, "capacity_total": 60, "assigned_clients": 50, "free_slots": 10 }
  ]
}

4.7 Доступность узлов

GET /v1/availability/intervals?month=2026-11&cursor=...

{
  "month": "2026-11",
  "month_status": "open",
  "items": [
    {
      "interval_id": "ivl_100",
      "revision": 1,
      "node_id": "node_12",
      "started_at": "2026-10-31T21:00:00Z",
      "ended_at": "2026-11-03T14:20:10Z",
      "counted": true,
      "exclusion_reason": null
    }
  ],
  "next_cursor": null
}

4.8 Выгрузка для сверки

GET /v1/snapshots/{entitlements|devices|nodes}?cursor=...

Постраничный полный список текущих объектов. Платформа запрашивает его раз в сутки.

5. События сетевого комплекса к платформе

POST {адрес_платформы}/integrations/network/v1/events

{
  "event_id": "evt_01JC8",
  "type": "device.activated",
  "occurred_at": "2026-11-05T09:12:00Z",
  "schema_version": 2,
  "data": {
    "license_id": "lic_01J9",
    "device_id": "dev_77a1",
    "hardware_id": "hw_5c1e",
    "router_model": "flint-2",
    "software_version": "1.4.2",
    "valid_until": "2026-12-08T09:12:00Z"
  }
}

Ответ 2xx значит, что событие сохранено. Иначе комплекс повторяет доставку с нарастающей задержкой не менее 72 часов.

ТипОбязательные данныеЧто делает платформа
entitlement.appliedlicense_id, versionЗакрывает команду в очереди
entitlement.failedlicense_id, version, codeПоказывает ошибку в админке, при no_free_slots предлагает другой город
device.activatedlicense_id, device_id, hardware_id, модель, версия ПО, valid_untilНачинает срок, проверяет пробный период, отмечает устройство активным
device.activation_failedlicense_id, codeПоказывает клиенту следующий шаг
device.online, device.offlinedevice_id, last_seen_atОбновляет статус в кабинете
node.claimedpartner_node_ref, node_id, фактический IPЗапускает ожидание проверки
node.check_passed, node.check_failednode_id, результаты, codeАктивирует узел или показывает причину
node.online, node.offlinenode_id, changed_atОбновляет кабинет партнёра, оповещает о простое
capacity.changedполя города из 4.6Открывает или закрывает продажи, обновляет список городов
availability.interval_correctedinterval_id, revision, поля интервалаСоздаёт корректировку
availability.month_closedmonthЗапускает расчёт начислений

События online и offline служат только для отображения. Деньги считаются только по интервалам из 4.7.

6. Основные сценарии

Подключение с пробным периодом. Клиент выбирает тариф и, для подписки $150, город → PUT entitlements с term_days_from_activation → клиент ставит ОС и вводит код → комплекс проверяет код, сам считает valid_until → device.activated → платформа записывает начало срока и подтверждает дату новой version.

Второй пробный период. Пробный период даётся один раз на учётную запись и на устройство. Платформа проверяет hardware_id в device.activated. Если устройство уже использовало пробный период: PUT entitlements с state: revoked, клиент получает счёт и подключается после оплаты (К-10).

Покупка после пробного периода и продление. Оплата USDT подтверждена блокчейном, оплата картой или по счёту подтверждена сотрудником → PUT entitlements с новым valid_until и увеличенной version. Период: 30 дней или год. Если события подтверждения нет, команда повторяется.

Неоплата. Отдельная команда не требуется: комплекс сам прекращает доступ по valid_until, в котором уже учтена отсрочка 3 дня. После этого роутер работает как обычный, без VPN.

Подключение узла. PUT nodes → партнёр вводит код → node.claimed → проверка → node.check_passed → интервалы доступности начинают учитываться.

Перенос первых партнёров. Узлы подключены вручную раньше платформы → комплекс передаёт реестр (К-13) → платформа создаёт партнёров → PUT nodes/.../link → интервалы загружаются с начала работы узла.

Закрытие месяца. 1-го числа по Москве комплекс завершает учёт → availability.month_closed не позже конца 3-го числа → платформа считает начисления. Если события нет, расчёт останавливается с оповещением, выплаты не запускаются.

7. Что нужно для интеграции

Пока стенда нет, платформа работает с эмулятором этого контракта. Реальный API подключается заменой адаптера.

8. Вопросы к технической команде

№ВопросЧто предлагаем
К-1Кто создаёт идентификаторы устройства и узла?Комплекс; лицензию создаёт платформа
К-2Как роутер подтверждает лицензию: код от платформы или иначе?Одноразовый код, в комплексе только его хеш
К-3Может ли комплекс сам считать срок при активации и отключать доступ без связи с платформой?Да, см. гарантию 1
К-4Как определяется доступность: частота проверок, что считается простоем?Опишите текущий механизм; поля counted и exclusion_reason закрывают исключения
К-5Можно ли гарантировать закрытие месяца до конца 3-го числа по Москве?Да, иначе выплата 5-го числа под угрозой
К-6Как считается ёмкость: фиксированные 5 клиентов или динамически? Когда подтвердите 5?Комплекс отдаёт готовое значение free_slots по городам
К-7Настройки маршрута, лимитов и блокировок нужны в кабинете?Нет, это зона комплекса и роутера
К-8Что удобнее для подписи: взаимный TLS или HMAC?HMAC проще для старта
К-9Когда будут контракт и тестовый стенд?Нужна конкретная дата, сейчас ответ «на днях»
К-10Есть ли у роутера постоянный идентификатор, который не меняется при переустановке ОС?Передавать его как hardware_id, без него пробный период можно получать повторно
К-11Годовая подписка идёт через серверы проекта? Сколько клиентов они держат?Да, traffic_mode: project_servers, без лимита мест на стороне платформы. Если через узлы партнёров, нужно пересмотреть цену
К-12Где клиент выбирает страну и город: в кабинете или на роутере? Можно ли менять выбор и как часто? Какие страны, кроме Индии, появятся?В кабинете, смена через exit_location
К-13Как передать первых 20 партнёров, если они подключатся раньше платформы? Хранятся ли их интервалы с первого дня?Реестр узлов с контактами партнёра, интервалы с начала работы
К-14Какие 2 модели роутеров уже опробованы и где лежат сборки?Коды и названия моделей, ссылки и контрольные суммы
К-15Что именно даёт удалённый доступ к роутерам клиента?Короткое описание для оферты и политики данных