> ## Documentation Index
> Fetch the complete documentation index at: https://veriqa.app/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Nova Stream — стриминг на телевизоре

> Пример-витрина, изображающий стриминговый сервис на телевизоре: вход по QR с дивана, карточка зрителя из claims канала и степ-ап при покупке фильма.

Nova Stream — запускаемый эмулятор **продукта**, а не одного механизма. Примеры сценариев показывают
каждый что-то одно — вход, подтверждение, степ-ап; этот связывает их так, как их встречает зритель
на телевизоре: вход, данные человека, узнавание при следующем визите и подтверждённая покупка.

Пример лежит в репозитории ([veriqa.app/source](https://veriqa.app/source)) в
`samples/dotnet/showcase/streaming-tv` и слушает `https://localhost:7350`. Подробное руководство по
настройке — его `README.md`; эта страница — обзор.

## Что видит зритель

<Steps>
  <Step title="Вход по QR с дивана">
    Телевизор перенаправляет на страницу входа Veriqa с QR-кодом. Зритель сканирует его камерой
    телефона и подтверждает вход в мессенджере — пультом ничего не набирается.
  </Step>

  <Step title="Приветственная карточка из claims канала">
    Карточка на экране собирается из того, что дал канал: отображаемое имя, имя и фамилия, аватар,
    `@username` и замаскированный ID (Telegram), замаскированный телефон (WhatsApp), адрес (Email) —
    Nova Stream запрашивает контакты при входе. Идентификаторы маскируются на сервере, полное
    значение в браузер не уходит.
  </Step>

  <Step title="Дата рождения и любимый жанр внутри входа">
    Каталог `Veriqa:ScopesClaims` объявляет оба значения, поэтому Veriqa спрашивает их своей формой
    внутри входа, а хранилище собранных claims запоминает ответ. Фильмы 18+ закрыты для зрителя, не
    достигшего этого возраста, фильмы любимого жанра идут первыми. См.
    [Постепенное обогащение профиля](/docs/ru/concepts/claim-enrichment).
  </Step>

  <Step title="Узнавание вернувшегося зрителя">
    Новичка приветствуют по имени; зритель, который уже бывал здесь, сразу попадает в каталог.
  </Step>

  <Step title="Степ-ап при покупке фильма">
    Покупка показывает QR-код и подтверждается в канале **тем зрителем, который её запросил**.
    Подтверждение от кого-то другого ничего не покупает.
  </Step>
</Steps>

Два сценария оставляют в чате разные квитанции. Вопрос входа заменяется на «Sign-in to Nova Stream
confirmed ✅» (`ReplacePrompt`); покупка сохраняет вопрос и получает квитанцию отдельным сообщением
(`NewMessage`, задан в записи клиента бэкенда), так что одобренное остаётся читаемым. См.
`OutcomeNotice` в [Конфигурации](/docs/ru/reference/configuration).

### Интерфейс на телевизоре

Интерфейс принадлежит вымышленному сервису: раскладка для просмотра с дивана, навигация пультом и ни
одного взаимодействия, которому нужен указатель.

| Клавиша | Что делает |
| - | - |
| стрелки | перемещают фокус |
| `Enter` | выбор |
| `Backspace`, Tizen `10009`, webOS `461` | закрывают окно покупки |
| `F` (десктоп) | полный экран |

Страница входа и окно подтверждения — собственные экраны Veriqa, показанные как есть: через
`AuthPageDesign` пример ставит название сервиса рядом со знаком Veriqa и приспосабливает раскладку к
большому экрану:

* телевизор показывает QR-коды всех включённых каналов рядом —
  [раскладка каналов](/docs/ru/guides/customization#раскладка-каналов) задана как `Grid`, потому что
  подходить к телевизору, чтобы переключить вкладку, никто не станет;
* кнопки «Open in …» появляются только на телефоне —
  [видимость кнопок каналов](/docs/ru/guides/customization#видимость-кнопок-каналов) задана как
  `MobileOnly`; телефон, открывший страницу, получает кнопки вместо QR;
* QR окна покупки рисуется по 12 px на модуль вместо 6 по умолчанию — его сканируют с экрана через
  всю комнату;
* таблица стилей увеличивает карточку на экранах шириной от 1600 CSS-пикселей.

**Набор каналов по языку браузера.** У клиента входа две записи `ui_config`, отличающиеся
`Channels`; пример называет одну из них в authorize-запросе по первому языку `Accept-Language`.
Запись сужает то, что включено у хоста, — это оформление, а не ограничение.

### Браузеры телевизоров

Всё, что отдаёт страница, нацелено на **ES2018** и CSS Chromium 68 — движка Tizen 5.5 и webOS 5, — с
фолбэками для Chromium 53 из webOS 4.x там, где от этого зависит раскладка. Более новый синтаксис
вроде `?.` или `??` там — ошибка разбора: скрипт не загружается вовсе. Ничего не загружается извне
origin.

## Как он устроен

Один процесс играет три роли; разнесение их по отдельным хостам не меняет ничего, кроме адресов.

| Роль | Что это |
| - | - |
| Встроенный издатель | Veriqa внутри процесса: `AddVeriqaAuthServer` → `UseVeriqaAuthServer` → `MapVeriqaAuthServer` |
| OIDC-клиент браузера | стандартный обработчик `AddOpenIdConnect`, направленный на этот же процесс |
| Бэкенд, создающий подтверждения | `VeriqaConfirmationClient`, вызывающий [API серверного подтверждения](/docs/ru/reference/confirmation-api) по HTTP |

Покупка создаёт подтверждение, которое называет **одну** ожидаемую личность — ту, что принадлежит
каналу текущей сессии (`expected_identities`). Фильм покупается, только если исход — `confirmed`, а
`matched_type` совпадает с ожидаемым типом; другой тип, `declined`, `expired` или `failed` оставляют
библиотеку без изменений. За какой фильм платит транзакция, запоминается на сервере, так что ни один
браузер не может купить один фильм, подтвердив другой.

## Запуск

* .NET SDK 10.0+ и доверенный сертификат разработки (`dotnet dev-certs https --trust`) — приложение
  вызывает само себя по HTTPS.
* **Включите хотя бы один канал и дайте ему учётные данные.** Каналы поставляются выключенными с
  пустыми учётными данными; самый короткий путь — токен бота Telegram:

```bash theme={null}
dotnet user-secrets --project samples/dotnet/showcase/streaming-tv set "Veriqa:Channels:Telegram:BotToken" "<token>"
dotnet user-secrets --project samples/dotnet/showcase/streaming-tv set "Veriqa:Channels:Telegram:Enabled" "true"
dotnet run --project samples/dotnet/showcase/streaming-tv
```

Откройте `https://localhost:7350`. WhatsApp и Email включаются так же — через их секции
`appsettings.json`. Страница входа без единого способа войти означает, что не включён ни один канал.
MAX в этот пример не входит: его пакет не подключён, включать нечего.

<Note>
  В окружении `Development` пример включает WhatsApp и Email с подставными значениями — только чтобы
  показать, как выглядит многоканальная страница входа. Довести вход до конца не может ни один из
  них — работает Telegram.
</Note>

**На настоящем телевизоре.** До `localhost` телевизор не достучится: поставьте пример за HTTP-туннель.
Код не меняется — издатель, адрес возврата, authority и публичные адреса каналов переводятся на
публичный хост переменными окружения, все вместе, а Telegram переключается в режим `Webhook`. Точный
список — в README примера; см. также [За reverse-proxy](/docs/ru/guides/reverse-proxy).

<Tip>
  Бот Telegram доставляет обновления на один адрес webhook, поэтому с одним токеном бота входы
  принимает только один из двух примеров-витрин одновременно.
</Tip>

## Видео

<CardGroup cols={2}>
  <Card title="Вход на телевизоре" icon="tv" href="/docs/ru/videos/tv-sign-in">
    Вход по QR с дивана на настоящем телевизоре — без клавиатуры и без ввода.
  </Card>

  <Card title="Step-up на телевизоре" icon="cart-shopping" href="/docs/ru/videos/tv-step-up">
    Покупка фильма, подтверждённая в мессенджере вошедшим зрителем.
  </Card>
</CardGroup>

## См. также

* [Примеры](/docs/ru/samples#примеры-витрины)
* [Поверхности входа](/docs/ru/scenarios/surfaces)
* [Smart TV и поверхности без клавиатуры](/docs/ru/research/smart-tv)
* [Второй фактор, step-up и подтверждение действий](/docs/ru/scenarios/step-up)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.