# Проверка интеграции Flutter SDK

Проверяйте и UI приложения, и фактические запросы/события. Успешная загрузка кампании не подтверждает видимый показ, а завершение вызова события не гарантирует его доставку.

## Чеклист перед выпуском

- [ ] В приложении используется `gravity_sdk 0.24.0` или совместимый обновлённый релиз; проверена фактическая сборка.
- [ ] `initialize()` завершён до первого запроса; ключ и секция соответствуют окружению.
- [ ] Android release-манифест разрешает интернет.
- [ ] Просмотры отправляются при открытии экранов, не на каждом `build()`.
- [ ] SKU, категории и `lng` совпадают с фидом, включая регистр.
- [ ] Кампания опубликована; selector, контекст, аудитория и расписание совпадают с запросом.
- [ ] Обрабатываются `FollowUrlEvent` с browser/webview, диплинки и запрос push.
- [ ] Login/SignUp содержат CUID с типом или hashedEmail.
- [ ] Выход/смена аккаунта сбрасывает профиль и персонализированный UI; очистка очереди выбрана явно.
- [ ] Headless имеет fallback; JSON проверяется до применения.
- [ ] Ручные показы привязаны к видимости, клики — к действиям; tracking SDK не дублируется.
- [ ] У покупок постоянный уникальный `uniqueTransactionId`.
- [ ] Проверены офлайн-доставка, перезапуск и блокировка автопоказа.

## Диагностика

| Симптом | Что проверить |
|---|---|
| SDK сообщает, что не инициализирован | Ключ/секция не пусты; `initialize()` завершён до вызова |
| Inline-блок не появился | Selector, контекст, публикацию, placeholder, наличие товаров в slots |
| Кампания работает, но на новом товаре старый контент | Пересоздать inline с новым `Key`; для своего запроса проверить его актуальность |
| In-app не показался | Приоритет, задержку, актуальность ответа, presentation lock, тип контента, состояние экрана |
| Tooltip не показался | Совпадение selector якоря и кампании, вызов `onReady` после layout |
| Кнопка не открывает ссылку | Обработку callback; для webview открыть внутренний экран, для browser — внешний URL |
| Headless вернул `null` | Наличие кампании, `isFetchContentOnTrack`, stale timeout, ошибки и очередь |
| Произвольного поля нет в типизированной модели | Читать `rawVariables`/`valueOf<T>()`; проверить фактический ключ и JSON-тип |
| Видимость есть, аналитики нет | Наличие events и on-обработчиков в серверном ответе; исходные объекты engagement |
| Показы завышены | Вызовы из `build()`, повторную обработку callback и return, дубли встроенного tracking |
| Покупки исчезают без сети | Настройки очереди, переполнение/срок хранения, ошибки хранилища, ID заказа |
| При ручном пользователе неправильный контент | Версию SDK: исправление идентификации запросов контента вышло в 0.24.0 |

## Проверка запросов

На тестовом устройстве включите `LogLevel.debug`. Сверьте:

1. Ключ/секцию и адрес SDK API/прокси.
2. `ctx.type`, `data`, `location` и атрибуты.
3. Идентификацию между просмотром, событием и запросом контента.
4. Выбранный контент и переменные кампании.
5. Tracking URL, которые действительно отправлены после видимости/клика.
6. Событие покупки/формы на стороне Gravity Field.

До отправки логов в поддержку удалите ключи и пользовательские данные.

## Сценарии собственной отрисовки

| Сценарий | Ожидаемый результат |
|---|---|
| Ответ пустой | Рабочий fallback; без фиктивного показа варианта |
| JSON имеет неверный тип или неизвестное действие | Fallback, без выполнения команды |
| Пользователь ушёл до ответа | Нет обновления размонтированного состояния |
| Товар изменился до ответа | Предыдущий ответ не заменяет новый UI |
| Повторное построение/прокрутка | Нет повторной загрузки или дублирующего visible impression |
| Два реальных клика | Два клика, если сервер предоставил tracking |
| Смена аккаунта | UI загружается заново для текущего пользователя |

В [A/B](./flutter_ab_test_json_guide.md) и [BDUI](./flutter_bdui_guide.md) приведены скачиваемые примеры с этими проверками.

## Сценарии очереди и блокировки

- Отключить сеть, отправить событие, перезапустить приложение: запись сохраняется до доставки, очистки или истечения срока.
- Восстановить сеть и вызвать `flushQueue()`: проверить очередь и фактическое событие с исходным временем.
- Сменить аккаунт до доставки: прежнее событие не должно приписаться новому пользователю.
- Выполнить `clearQueue()`: ожидающие события не должны появиться снова после перезапуска.
- Заблокировать автопоказ, отправить просмотр: UI не появляется; запрос контента может выполняться.
- Снять блокировку: пропущенная кампания не показывается автоматически задним числом.
- Проверить tooltip отдельно: presentation lock не блокирует этот путь.
- Отправить форму офлайн: UI может перейти к следующему действию до доставки результата.

## Обновление с прежних версий

При переходе на 0.24.0 проверьте:

- новую идентификацию контентных запросов после `setUser()`;
- наличие включённой по умолчанию очереди и выбранную политику выхода;
- `customProps`/`eventTime` и ID покупок;
- обработку headless-ответа: модель в `GravityDataResponse.data`, исходный JSON в `GravityDataResponse.json`;
- доступ к `rawVariables` и `ContentClickEngagement`;
- блокировку и актуальность автопоказа.

История релизов: [changelog 0.24.0](https://pub.dev/packages/gravity_sdk/versions/0.24.0/changelog). Полные сигнатуры: [Справочник API](./api_reference.md).
