Online cinema · Production

PrimeTime

Полноценный онлайн-кинотеатр с нейросетевыми рекомендациями, гибридным семантическим поиском и собственной ML-инфраструктурой. Каталог ~290 000 единиц контента, работает в продакшене.

~290k
единиц контента
~55k
строк кода (3 репо)
78
gRPC-методов
10
прод-сервисов
Что это

Стриминговый продукт уровня индустрии

Не учебный CRUD, а самостоятельный коммерческий сервис с CI/CD, реальными пользователями и нетривиальными инженерными задачами.

🎬 Каталог и контент

Фильмы, сериалы, аниме. Персоны, студии и сети (TMDB), связи: сиквелы / приквелы / спин-оффы. Фасетный каталог на Elasticsearch.

🧠 Рекомендации

Собственная двухбашенная нейросеть (Two-Tower). Главная — лента объяснимых полок: «Вам понравился „X“ — вот похожее».

🔎 Гибридный поиск

BM25 + семантический kNN + LLM-нормализация запроса. «кино где парень застрял во времени» → находит «День сурка».

📊 Аналитика просмотров

Точный трекинг watch-сессий (хиты ≥30с), агрегаты, real-time дашборды в админке.

🔐 Авторизация

JWT (access/refresh) с проверкой ревокации, вход по email и Telegram, бесшовный refresh.

✉️ Telegram-рассылки

Кампании, тест-сообщения, авто-отписка при блокировке бота. Маркетинговая аналитика источников трафика.

Архитектура

Типобезопасный контракт через всю систему

Frontend и backend связаны единым proto-файлом. Транспорт — бинарный gRPC-Web через Envoy. Изменил поле в контракте → TypeScript ломается там, где контракт нарушен.

Браузер ──gRPC-Web──▶ Envoy proxy ──gRPC :50051──▶ NestJS микросервис (Nuxt 4 SSR) (gRPC-Web→gRPC) Auth · Catalog · Search · Shelves · Recommendation · Balancer · Analytics │ ┌──────────────┬───────────────┬────────────┼──────────────┐ ▼ ▼ ▼ ▼ ▼ PostgreSQL 17 Elasticsearch pgvector Redis Infinity (источник (текст + (kNN / (кэш + (эмбеддинги истины) фасеты) смысл) локи) gte-768d) ▲ ai-recommendation (офлайн обучение Two-Tower, TensorFlow.js)

Frontend

Nuxt 4 · Vue 3 · TypeScript · Pinia · SCSS · gRPC-Web. SSR + гидрация, фирменная liquid-вёрстка 1rem=1px. Разбор →

Backend

NestJS 10 · gRPC · Prisma 6 · multi-schema PostgreSQL · Bull-очереди · cron. 26 сервисов, 18 контроллеров. Разбор →

ML

TensorFlow.js · Two-Tower · in-batch sampled-softmax · pgvector HNSW. Эмбеддинги gte-multilingual-base (768d). Разбор →

Технологический стек

Осознанный выбор под каждую задачу

СлойТехнологии
FrontendNuxt 4Vue 3TypeScript 5PiniaSCSS 7-1VeeValidate+YupConnectRPCBun
BackendNestJS 10gRPCPrisma 6Passport JWTBullRBAC
ДанныеPostgreSQL 17pgvector (HNSW)Elasticsearch 8Redispg_trgm / GIN
ML / AITensorFlow.jsTwo-Towergte-multilingual-baseInfinity ServerTimeweb LLMMovieLens 25M
ИнфраDockerEnvoyimgproxyGitLab CI/CDnginx-proxyVPS
Платформа данных

Каждое хранилище — по делу

Разделение ответственности, а не «зоопарк зависимостей». PostgreSQL — источник истины; ES, pgvector и Redis — производные представления, пересобираемые из PG.

Откуда данные

Kinopoisk API (контент) через отказоустойчивый балансировщик с ротацией токенов и circuit breaker · TMDB (студии) · MovieLens 25M (прайор для ML).

Консистентность

Идемпотентные upsert по натуральному ключу · транзакционные Bull-консьюмеры · reconcile с защитой от усечённого ответа провайдера · кросс-store sync через updatedAt → cron → ES.

Поиск

Elasticsearch (BM25 + фасеты) + pgvector (семантика) объединяются через Reciprocal Rank Fusion с байесовским взвешиванием популярности (формула IMDb Top-250).

Производительность

Двухстадийный HNSW-поиск (разбор EXPLAIN в коде), stale-while-revalidate + single-flight на Redis, батч-загрузка карточек без N+1.

Продакшен-инфраструктура

10 контейнеров, каждый с ясной ролью

core-api-grpc — gRPC backend :50051

core-web — Nuxt SSR :4503

pgvector/pg17 — БД + векторы

elasticsearch 8.12 — текст + фасеты

envoy v1.28 — gRPC-Web → gRPC

infinity — embedding-сервер :1919

redis — кэш / локи / rate-limit

imgproxy — ресайз постеров

pgadmin — админка БД

wordpress — блог / SEO

SEO и доступность

Уровень медиа-проекта, не SPA

schema.org JSON-LD

Movie / TVSeries с aggregateRating, BreadcrumbList, динамический ItemList «Рекомендуем». Генерируется на SSR.

Server-side sitemap

Sitemap index с пагинированными картами (watch / genre / staff / playlist), генерируется из gRPC с кэш-заголовками.

Canonical + OG

Canonical, rel=prev/next для листингов, полный OpenGraph, Yandex.Metrika с защитой от дубль-вставки.

Итог

Зрелый продукт, а не прототип

  • Сквозная типобезопасность от proto-контракта до Vue-шаблона.
  • Собственная ML-инфраструктура end-to-end: данные → обучение → инференс → векторный поиск.
  • Производительность как инженерная дисциплина: профилирование БД, двухстадийный HNSW, кэш-стратегии.
  • Distributed-паттерны: circuit breaker, single-flight, stale-while-revalidate, ротация токенов.
  • Объяснимые рекомендации и гибридный поиск — функции, которые обычно делает отдельная команда.

Подробные технические разборы по слоям: frontend · backend · ml · о системе. Профиль автора и оценка инженерного уровня — инженерный профиль.