# RaidBoss Platform — Full documentation (RU) Docs version: 0.1.1 TypeScript SDK: @raidboss/platform-sdk@0.1.0 Flutter SDK: raidboss_platform_sdk@0.1.3 Default language is Russian. English mirror: /en/llms-full.txt Placeholders: YOUR_APP_CODE, YOUR_PUBLIC_KEY, YOUR_API_URL. --- # Обзор Slug: welcome/overview # Документация RaidBoss Platform RaidBoss Platform — middleware для продуктовых приложений. UI и бизнес-логика остаются в вашем приложении. Платформа отвечает за **каталог**, **права (entitlements)**, **пейволы**, **платежи**, **устройства**, **remote config** и **аналитику**. Документация публичная, версионируется и удобна для людей и ИИ. **По умолчанию — русский.** Английский — переключатель **EN** в шапке или пути `/en/...`. ## С чего начать 1. Создайте **приложение** в админке Platform. 2. Добавьте **права**, затем **тарифы** с ценами, затем **пейвол**. 3. Выпустите **public SDK key** (`rb_pub_…`). 4. Подключите SDK по [быстрому старту](/welcome/quickstart). | Пакет | Платформа | Версия | | --- | --- | --- | | `@raidboss/platform-sdk` | TypeScript / Web / RN | см. сайдбар | | `raidboss_platform_sdk` | Flutter / Dart | см. сайдбар | ## Модель ```text Application └── Entitlements (коды фич, которые проверяет приложение) └── Plans (что покупают) + Plan prices └── связь plan → entitlements └── Paywalls (оффер для клиента) └── Users / devices / payments / subscriptions ``` - Проверяйте **коды прав**, а не названия тарифов. - **Free** работает офлайн и **не** идёт через оплату. - **Платный доступ аддитивен**: free-фичи остаются; платные права добавляются. - После покупки кэшируйте снимок прав для офлайна. ## Разделы ### Концепции - [Права](/concepts/entitlements) - [Тарифы и цены](/concepts/plans) - [Пейволы](/concepts/paywalls) - [Free и офлайн](/concepts/free-offline) ### SDK - [TypeScript / Web](/sdk/typescript) - [Flutter](/sdk/flutter) - [Справка API](/sdk/api-reference) ### Для ИИ - [`/llms.txt`](/llms.txt) — индекс (RU) - [`/llms-full.txt`](/llms-full.txt) — полный текст (RU) - [`/en/llms-full.txt`](/en/llms-full.txt) — English - [`/raw/.md`](/raw/welcome/overview.md) — одна страница См. [Для ИИ-ассистентов](/welcome/ai). --- # Быстрый старт Slug: welcome/quickstart # Быстрый старт Плейсхолдеры в документации: | Плейсхолдер | Смысл | | --- | --- | | `YOUR_API_URL` | Базовый URL Platform API | | `YOUR_APP_CODE` | Код приложения из админки | | `YOUR_PUBLIC_KEY` | Public key `rb_pub_…` | | `YOUR_ACCESS_TOKEN` | JWT пользователя из вашего Auth | ## 1. Админка (один раз) 1. Создайте приложение → `YOUR_APP_CODE`. 2. Добавьте права (например `premium_feature`, `cloud_sync`). 3. Создайте тарифы (включая опциональный `free`) и привяжите права к **платным**. 4. Создайте пейвол `main` и цены. 5. Скопируйте `YOUR_PUBLIC_KEY`. ## 2. TypeScript ```ts import { RaidBossPlatformClient } from "@raidboss/platform-sdk"; const platform = new RaidBossPlatformClient({ apiUrl: "YOUR_API_URL", applicationCode: "YOUR_APP_CODE", publicKey: "YOUR_PUBLIC_KEY", getAccessToken: async () => YOUR_ACCESS_TOKEN, }); await platform.registerUser({ platform: "web" }); await platform.registerDevice({ installation_id: "stable-uuid-on-device", platform: "web", app_version: "1.0.0", }); const { data: paywall } = await platform.getPaywall("main"); const canPremium = await platform.hasEntitlement("premium_feature"); ``` ## 3. Flutter ```dart final platform = RaidBossPlatformClient( apiUrl: 'YOUR_API_URL', applicationCode: 'YOUR_APP_CODE', publicKey: 'YOUR_PUBLIC_KEY', getAccessToken: () async => YOUR_ACCESS_TOKEN, ); await platform.registerUser(platform: 'android'); await platform.registerDevice( installationId: installationId, platform: 'android', appVersion: '1.0.0', ); final paywall = await platform.getPaywall(paywallCode: 'main'); final canPremium = await platform.hasEntitlement('premium_feature'); ``` ## 4. Покупка (только платные) ```ts const price = paywall.paywall_items?.[0]?.plan_prices; if (price && !RaidBossPlatformClient.isFreePrice(price)) { const { data } = await platform.createPayment({ plan_price_id: String(price.id), return_url: "https://your.app/pay/return", }); // открыть data.confirmation_url } ``` Не вызывайте `createPayment` для free (`is_free` / `works_offline` / `requires_purchase: false`). ## 5. Правило гейтинга ```text если фича free-local → разрешить (даже offline) иначе если есть сеть → sync entitlements, обновить кэш, проверить код иначе → проверить кэш + expires_at ``` Далее: [Права](/concepts/entitlements) · [Платежи](/guides/payments) · [Офлайн](/concepts/free-offline) --- # Для ИИ-ассистентов Slug: welcome/ai # Для ИИ-ассистентов Дайте модели один из URL (подставьте ваш docs-хост): | Ресурс | Назначение | | --- | --- | | `/llms.txt` | Индекс страниц + версии (**русский**, по умолчанию) | | `/llms-full.txt` | Полная документация одним файлом (RU) | | `/en/llms.txt` / `/en/llms-full.txt` | English | | `/raw/.md` | Одна страница (RU) | | `/raw/en/.md` | Одна страница (EN) | | `/changelog` | Что изменилось | ## Шаблон промпта ```text Прочитай https://YOUR_DOCS_HOST/llms-full.txt Интегрируй RaidBoss Platform в это приложение. Используй плейсхолдеры из документации. Не выдумывай секреты. Проверяй entitlement-коды, а не названия тарифов. Free работает офлайн без createPayment. Кэшируй entitlements для офлайн-доступа к платным фичам. ``` ## Версии - В сайдбаре: **docs**, **TypeScript**, **Flutter**. - При изменениях SDK обновляются changelog и `lib/nav.ts`. ## Обезличивание - `YOUR_APP_CODE`, `YOUR_API_URL`, `YOUR_PUBLIC_KEY` - Не кладите service-role / секреты платежей в клиент - Примерные коды прав: `premium_feature`, `cloud_sync` --- # Приложения Slug: concepts/applications # Приложения **Application** — один продукт, который использует Platform API и SDK. ## Поля | Поле | Роль | | --- | --- | | `code` | Стабильный id для SDK (`YOUR_APP_CODE`) | | `name` | Название в админке | | `status` | Публичные эндпоинты отдают только `active` | | Public key | `rb_pub_…` для пейвола и платежей | | Payments | Включает платный checkout | ## Идентификация клиента - `X-Application-Code: YOUR_APP_CODE` или `X-Application-Id: ` - при необходимости `X-Public-Key: YOUR_PUBLIC_KEY` - `Authorization: Bearer YOUR_ACCESS_TOKEN` для user-scoped маршрутов ## Что внутри приложения Права, тарифы/цены, пейволы, пользователи, устройства, платежи/подписки, remote config, feature flags, события аналитики. --- # Права (entitlements) Slug: concepts/entitlements # Права (entitlements) **Entitlement** — право на фичу. В коде проверяйте **коды**, не названия тарифов. ## Поля в админке | Поле | Обязательно | Заметки | | --- | --- | --- | | `code` | да | Стабильный, латиница: `hasEntitlement('code')` | | `name` | да | Только для админки | | `description` | нет | Опционально | ## Примеры ```text premium_feature cloud_sync export_hd ``` ## Runtime ```ts const ok = await platform.hasEntitlement("premium_feature"); ``` ```dart final ok = await platform.hasEntitlement('premium_feature'); ``` `GET .../entitlements/me` возвращает `codes[]` и строки с `source`, `starts_at`, `expires_at`, `is_lifetime`. ## Правила - Free-локальные фичи обычно **без** entitlement — всегда открыты в клиенте. - Платные возможности — **с** entitlement. - Лучше одно право на capability, а не на каждый прайс. --- # Тарифы и цены Slug: concepts/plans # Тарифы и цены ## Тариф (plan) | Поле | Заметки | | --- | --- | | `code` | Стабильный id (`yearly_premium`, `free`) | | `name` | На пейволе | | `billing_type` | `one_time` \| `recurring` \| `lifetime` \| `free` | | `duration_days` | Срок для временных тарифов | | `is_lifetime` | Без expiry | | `status` | На публичный пейвол — `active` | | entitlements | Какие права даёт покупка | ## Цена (plan_prices) | Поле | Заметки | | --- | --- | | `amount` | Реальная сумма. `0` = free | | `currency` | например `RUB` | | `discount_percent` | Только для UI (зачёркнутая цена) | | `payment_provider` | `yookassa` или `free` | | `is_active` | Должен быть true | В ответе API также: `compare_at_amount`, `has_discount`, `display`, `is_free`, `requires_purchase`, `works_offline`. ## Free - `billing_type: free` и/или `amount: 0` - Для каталога / сравнения на пейволе - **Не покупается** — `createPayment` → `free_plan_offline` - Фичи free — локальный дефолт в приложении ## Платный - `amount > 0` - После успеха — период подписки + выдача прав - Доступ **добавляется** к free-локальным фичам --- # Пейволы Slug: concepts/paywalls # Пейволы **Paywall** — именованная конфигурация экрана выбора тарифа. ## Поля | Поле | Заметки | | --- | --- | | `code` | Обычно `main` | | `name` | В админке | | `title` / `subtitle` | Тексты для UI клиента | | `status` | Публично только `active` | | items | Упорядоченный список `plan_price_id` | ## Элементы | Поле | Заметки | | --- | --- | | `plan_price_id` | Цена для показа / покупки | | `position` | Порядок | | `is_recommended` | Подсветка | | `badge` | Опциональный бейдж | | `custom_title` / `custom_subtitle` | Переопределения | ## Запрос ```http GET /v1/applications/{app_code}/paywalls/{paywall_code} X-Public-Key: YOUR_PUBLIC_KEY ``` JWT не нужен. В payload — план, цена, display-поля, entitlements для буллетов. ## Клиент - Рендерит свой UI из payload - Не вызывает `createPayment` при `is_free` / `works_offline` - Для оплаты берёт `plan_price_id` выбранного item --- # Free и офлайн Slug: concepts/free-offline # Free и офлайн ## Free Базовый **локальный** режим приложения: - Работает **без интернета** - **Не** вызывает `createPayment` - Обычно **без** серверных entitlements - Может быть на пейволе для сравнения (`is_free: true`) ## Free + платный Покупка **добавляет** права, не убирает free. ```text доступ = free-local ∪ активные платные entitlements ``` ## Офлайн после покупки | Кто | Поведение | | --- | --- | | Приложение | При последнем онлайне сохранить снимок (`codes`, `expires_at`, `is_lifetime`). Offline: free всегда; платное — из кэша до expiry. | | Админка / API | Только онлайн. Отзывы применяются при следующем sync. | ## Алгоритм клиента ```text canUse(feature): if feature in FREE_LOCAL_SET: return true if network: snapshot = getMyEntitlements() saveCache(snapshot) return snapshot.codes.contains(feature) cached = loadCache() if missing or expired (и не lifetime): return false return cached.codes.contains(feature) ``` SDK даёт сетевые API; **кэш — ответственность приложения**. --- # TypeScript / Web SDK Slug: sdk/typescript # TypeScript / Web — `@raidboss/platform-sdk` ## Установка Пакет монорепозитория: ```text @raidboss/platform-sdk ``` ```ts import { RaidBossPlatformClient, createRaidBossClient, RaidBossPlatformError, } from "@raidboss/platform-sdk"; ``` ## Создание клиента ```ts const platform = new RaidBossPlatformClient({ apiUrl: "YOUR_API_URL", applicationCode: "YOUR_APP_CODE", publicKey: "YOUR_PUBLIC_KEY", getAccessToken: async () => tokenOrNull, }); ``` ## Методы | Метод | Auth | Public key | Заметки | | --- | --- | --- | --- | | `getPaywall(code?)` | нет | рекомендуется | По умолчанию `main` | | `registerUser(...)` | да | — | После login/signup | | `registerDevice(...)` | да | — | Стабильный `installation_id` | | `getMyEntitlements()` | да | — | Снимок + `codes` | | `hasEntitlement(code)` | да | — | Удобный хелпер | | `hasAnyEntitlement(codes)` | да | — | | | `createPayment(...)` | да | нужен | Только платные | | `checkout(...)` | да | нужен | Алиас | | `activateLicenseKey(...)` | да | — | Активация ключа | | `listDevices` / `revokeDevice` | да | — | Устройства | | `getConfig` / `getFeatures` | config: нет / features: да | — | Remote | | `trackEvent` / `trackEvents` | да | — | Аналитика | | `isFreePrice(price)` static | — | — | Детект free | ## Free ```ts if (RaidBossPlatformClient.isFreePrice(price)) { // не вызывать createPayment } ``` Ошибка API при попытке оплаты free: `free_plan_offline`. --- # Flutter SDK Slug: sdk/flutter # Flutter — `raidboss_platform_sdk` ## Установка ```yaml dependencies: raidboss_platform_sdk: path: ../path/to/raidboss_platform_sdk ``` ```dart import 'package:raidboss_platform_sdk/raidboss_platform_sdk.dart'; ``` ## Создание клиента ```dart final platform = RaidBossPlatformClient( apiUrl: 'YOUR_API_URL', applicationCode: 'YOUR_APP_CODE', publicKey: 'YOUR_PUBLIC_KEY', getAccessToken: () async => accessTokenOrNull, ); ``` ## Методы | Метод | Auth | Public key | Заметки | | --- | --- | --- | --- | | `getPaywall` | нет | нужен | По умолчанию `main` | | `registerUser` | да | — | После Auth | | `registerDevice` | да | — | Стабильный `installationId` | | `getMyEntitlements` / `hasEntitlement` | да | — | Права | | `createPayment` | да | нужен | Только платные | | `activateLicenseKey` | да | — | Ключ | | `getConfig` / `getFeatures` | config: нет | — | Remote | | `trackEvent` | да | — | Аналитика | | `PaywallData.isFreePrice(i)` | — | — | Free | ## Free ```dart if (paywall.isFreePrice(0)) { // локальный free — без createPayment } ``` Модели: `EntitlementSnapshot`, `PaywallData`, `PaymentResult`, `RaidBossPlatformException`. --- # Справка API Slug: sdk/api-reference # Справка API Базовый URL: `YOUR_API_URL` JSON. Конверт: `{ "data": ... }` или `{ "error": "code", "message": "..." }`. ## Заголовки | Header | Когда | | --- | --- | | `Content-Type: application/json` | с телом | | `X-Application-Code` | идентификация приложения | | `X-Application-Id` | альтернатива коду | | `X-Public-Key` | пейвол + платежи | | `Authorization: Bearer ` | user-scoped | ## Публичные ```http GET /v1/applications/{app_code}/paywalls/{paywall_code} X-Public-Key: YOUR_PUBLIC_KEY ``` ```http GET /v1/applications/{app_code}/config?platform=web&app_version=1.0.0 ``` ## С авторизацией ```http POST /v1/applications/{app_code}/users/register GET /v1/applications/{app_code}/entitlements/me POST /v1/payments POST /v1/applications/{app_code}/license-keys/activate POST /v1/devices/register GET /v1/devices?application_code=YOUR_APP_CODE DELETE /v1/devices/{device_id} GET /v1/applications/{app_code}/features POST /v1/events POST /v1/events/batch ``` Платёж free → `400 free_plan_offline`. Webhook провайдера платежей настраивается на Platform API, не на маркетинг-сайт. Секреты провайдера — только на сервере. --- # Чеклист интеграции Slug: guides/checklist # Чеклист интеграции ## Админка - [ ] Приложение создано и `active` - [ ] Коды прав совпадают с гейтами в продукте - [ ] Платные тарифы привязаны к правам - [ ] Опциональный free на пейволе (права не обязательны) - [ ] Пейвол `main` active - [ ] Public key выпущен - [ ] Платежи включены + креды провайдера ## Клиент - [ ] SDK: `YOUR_API_URL`, `YOUR_APP_CODE`, `YOUR_PUBLIC_KEY` - [ ] `getAccessToken` отдаёт JWT после логина - [ ] `registerUser` после signup/signin - [ ] `registerDevice` со стабильным installation id - [ ] Гейты по **кодам** прав - [ ] Free-local без сети - [ ] `createPayment` только если `requires_purchase` - [ ] Кэш entitlements для офлайна - [ ] После return — refresh entitlements - [ ] Нет service_role / секретов платежей в клиенте --- # Платежи Slug: guides/payments # Платежи ## Поток ```text 1. Пользователь выбирает платную plan_price 2. createPayment(plan_price_id, return_url) 3. API создаёт платёж у провайдера + pending в Platform 4. Приложение открывает confirmation_url 5. Webhook → succeeded → права / период подписки 6. Приложение обновляет entitlements (+ кэш) ``` ## Правила - Нужны JWT + public key - Секреты провайдера не в клиенте - Free не оплачивается - После return — `getMyEntitlements()` Ошибка free: `free_plan_offline`. `discount_percent` — только UI; в оплату идёт `amount`. --- # Лицензионные ключи Slug: guides/license-keys # Лицензионные ключи ```ts await platform.activateLicenseKey({ key: "RB-XXXXXXXX-…", installation_id: "optional-stable-id", }); ``` ```dart await platform.activateLicenseKey( key: 'RB-XXXXXXXX-…', installationId: installationId, ); ``` Нужен JWT. После успеха — обновить entitlements и офлайн-кэш. Лимиты ключей — на сервере. --- # Remote Config и флаги Slug: guides/config # Remote Config и флаги ## Config ```ts const { data } = await platform.getConfig({ platform: "web", app_version: "1.0.0", }); // data.config → Record ``` Без auth. Без секретов. Дефолты держите в клиенте для офлайна. ## Features ```ts const { data } = await platform.getFeatures({ platform: "android", app_version: "1.0.0", }); // data.features → Record ``` Нужен auth. Kill-switches и поэтапный rollout. Монетизацию проверяйте через entitlements. --- # Аналитика Slug: guides/analytics # Аналитика ```ts await platform.trackEvent({ event: "paywall_viewed", platform: "web", app_version: "1.0.0", properties: { paywall_code: "main" }, }); ``` ```dart await platform.trackEvent( event: 'paywall_viewed', platform: 'ios', appVersion: '1.0.0', properties: {'paywall_code': 'main'}, ); ``` Нужен JWT. Имена событий — ваш словарь; держите стабильную таксономию. --- # Changelog Slug: changelog/index # Changelog Версии в сайдбаре: **docs** / **TS** / **Flutter**. Язык по умолчанию — **русский**. Английский — переключатель EN или `/en/...`. ## 2026-07-19 — docs 0.1.1 ### Docs - i18n: RU по умолчанию, EN по переключателю (`/en/...`) - `/llms.txt` и `/llms-full.txt` — русский; `/en/llms*.txt` — English ## 2026-07-19 — docs 0.1.0 ### Docs - Первый публичный сайт документации - Индексы для ИИ, концепции, гайды, SDK ### `@raidboss/platform-sdk` 0.1.0 - Клиент: paywall, entitlements, payments, devices, config, features, events - `isFreePrice`, отказ оплаты free (`free_plan_offline`) ### `raidboss_platform_sdk` 0.1.3 - Flutter-клиент, `PaywallData.isFreePrice`, helpers снимка прав