SUPER CUBE
Статус реализации. SUPER CUBE Games — серверный MVP с каталогом, авторизацией, публикацией архивов, браузерным SDK, серверным игровым runtime и аналитикой. Синтаксические проверки сами по себе не доказывают готовность интеграций: перед production необходимы runtime-тесты на целевой инфраструктуре и реальные ключи провайдеров.

1. Миссия и продуктовая концепция

Миссия SUPER CUBE Games — сделать небольшие независимые игры доступными сразу после открытия ссылки, без установки клиента и лишних шагов. Платформа — не просто список HTML-файлов: она обеспечивает публикационный процесс, каталогизацию, безопасный запуск игр, аккаунты, сохранения, измеримые данные об использовании.

Пользователи и их потребности

  • Игрок: быстро найти игру, запустить её на любом экране, вернуться к прогрессу, увидеть мнение сообщества и управлять профилем.
  • Администратор/издатель: загрузить архив, проверить закрытую сборку, отредактировать карточку, опубликовать игру, оценить качество и популярность, управлять аккаунтами игроков.
  • Разработчик: получить предсказуемый формат ZIP, небольшой асинхронный SDK, понятные ограничения среды и проверяемый путь от локальной сборки к публикации.

Продуктовые принципы

  • Instant play: каталог — главный вход в игры, карточка игры даёт контекст, явная кнопка «Играть» начинает запуск.
  • Progressive complexity: простая браузерная игра не требует собственного backend; серверная логика включается только при необходимости.
  • Server-authoritative data: сервер определяет сохранённый прогресс, длительность сессии, рейтинги, отзывы и очки.
  • Mobile-first: контролы должны работать с мышью, клавиатурой и touch; содержимое не должно превышать доступную высоту игрового окна без необходимости.
  • Observable by design: ключевые игровые действия и пользовательские потоки должны иметь метрики, которые можно диагностировать.

2. Scope и критерии успеха

Входит в MVP

  • Административный вход настраивается через ADMIN_LOGIN, ADMIN_PASSWORD и ADMIN_EMAIL.
  • Публичный каталог, поиск/фильтры и карточка-попап игры; fullscreen-страница запуска с хэдером и кнопкой назад.
  • Загрузка ZIP до 100 MiB, проверка структуры, безопасная распаковка, приватный тест, редактирование RU/EN данных и публикация.
  • Browser iframe runtime и Docker runtime для игр с серверным кодом.
  • Вход по email-коду через SMTP.
  • Оценки, множественные комментарии, ответы администратора, избранное, шаринг, облачные сохранения и профиль игрока.
  • Серверный рейтинг очков, админ-панель со статистикой, история CCU и дневной аудитории, SEO endpoints.

Вне scope текущего MVP

  • Мультисерверная оркестрация серверных игр и автоматическое горизонтальное масштабирование.
  • Полноценная защита от DDoS на сетевом уровне, античит уровня коммерческих рейтинговых соревнований и ручная модерация большого пользовательского каталога.
  • Гарантированная сохранность внутриигровой оперативной памяти сервера после аварии; постоянное игровое состояние должно храниться в БД или другом долговечном хранилище.

Измеримые признаки успешного выпуска

Критический пользовательский сценарий должен проходить end-to-end: загрузка архива → приватный preview → редактирование → публикация → доступность каталога → запуск → серверные события/время → статистика и профиль. Отдельные проверки подтверждают изоляцию черновиков, корректность ролей и отказ небезопасным запросам.

3. Системная архитектура

Browser / mobile browser
  ├─ Public UI: catalogue, game modal, fullscreen player, profile, leaderboard
  ├─ Admin UI: upload/editor, recommendations, metrics dashboards
  └─ Game iframe (sandbox, no allow-same-origin)
           │ postMessage SDK bridge
           ▼
Node.js 20+ / Express — Platform API (:3000)
  ├─ Auth + business rules + CSRF / Origin / rate limits
  ├─ Catalog + archive pipeline + private file serving
  ├─ SDK bridge + review/rating/favourite/save/share APIs
  └─ Analytics / score calculation / snapshot scheduler
           │ private HTTPS/HTTP + Bearer service token
           ▼
Data API (:4001, internal only; registered SQL allowlist)
           │ node-postgres pool
           ▼
PostgreSQL 16 (users, games, sessions, reviews, saves, analytics)

Persistent volume: storage/games, storage/avatars, uploaded archives
Separate per-game Docker runtime remains an infrastructure integration

Основные модули

  • server.js — HTTP-маршруты, middleware, страницы игр, SDK bridge, admin APIs, ping endpoint, периодические snapshots.
  • src/db.js — совместимый клиент внутреннего Data API; SQL-драйвера здесь нет.
  • shared/data-client.js и shared/data-api-session-store.js — контракт Data API и PostgreSQL-backed Express sessions.
  • data-service/server.js, data-service/schema.sql, data-service/query-catalog.json — внутренний Data API, PostgreSQL-схема и реестр разрешённых запросов.
  • src/auth.js — email-коды и сессии аккаунтов.
  • src/security.js — CSRF, нормализация и экранирование.
  • src/games.js — ZIP-валидация, распаковка, metadata parsing, preview draft.
  • src/server-game-runtime.js — Docker network/container lifecycle, readiness probe и reverse proxy.
  • src/analytics.js — игровые события, сессии, рейтинги, очки, каталожные метрики и тренды.
  • public/js/common.js — общие сетевые запросы, тема/язык, CSRF и bootstrap аккаунта.

4. Канонический формат ZIP

my-game.zip
├── index.html                 # browser client / UI
├── runtime.txt                # optional: "server" for Docker runtime
├── server/
│   └── index.js                # required when runtime.txt = server
└── media/
    ├── title.txt               # required; English title only
    ├── description.ru.txt      # required
    ├── description.en.txt      # required
    ├── tags.ru.txt             # required localized metadata source
    ├── tags.en.txt             # required; English tags are displayed/filtered
    ├── capsule.jpg             # JPG/GIF, exactly 630 × 500
    ├── screenshots/            # optional game screenshots
    │   ├── 01.jpg
    │   └── 02.webp
    └── ...                     # other promo materials

Текст — UTF-8. title.txt должен быть английским; интерфейс показывает его одинаково при любом языке страницы. Описание берётся из текущей локали. Теги для публичного каталога, фильтров и карточки всегда берутся из tags.en.txt, чтобы категории не дублировались при смене языка. runtime.txt находится в корне ZIP и содержит только browser или server; отсутствие файла означает browser.

Архивы старого формата с корневыми title.txt, description.txt и tags.txt временно поддерживаются для обратной совместимости. Новые сборки должны использовать канонический путь media/. Лимиты: ZIP до 100 MiB; распакованные данные до 250 MB; до 2,000 файлов; ограничения на traversal, абсолютные пути, symlinks, коэффициент сжатия и размер обязательных файлов.

5. Жизненный цикл публикации

  1. Администратор отправляет ZIP через drag-and-drop или файловую кнопку; интерфейс показывает точный размер в байтах, KiB/KБ и MiB/МБ.
  2. Backend проверяет архив до и в ходе распаковки и создаёт draft со стабильным slug.
  3. Черновик доступен только администратору по /games/<slug>-test; закрывается доступ как к тестовой HTML-странице, так и к ассетам.
  4. Редактор сохраняет описание и теги RU/EN обратно в файлы media/, обновляет число игроков и runtime type.
  5. После публикации браузерная игра доступна на /games/<slug>; серверная запускается/пробуждается через runtime manager.
  6. Unpublish и delete останавливают контейнер. На старте приложения опубликованные server games проходят попытку автоматического запуска.

6. SDK и модель изоляции

SDK предоставляет window.SuperCubePlatform. В browser runtime его скрипт инжектируется в HTML. В server runtime proxy вставляет /js/game-sdk.js?slug=<slug>, если приложение не подключило SDK само. API-вызовы идут из iframe через postMessage к host-странице и затем к backend. Sandbox намеренно не имеет allow-same-origin; не добавляйте этот флаг для обхода коммуникационного контракта.

МетодНазначение и ограничения
getUser()Возвращает authenticated, displayName, playerId без email.
save(data) / loadSave()Серверное облачное сохранение до 250 KB; только авторизованным. Гость при load получает null и requiresSignIn.
rate(1..5)Создать/обновить одну актуальную оценку игрока для игры.
review(text)Создать отзыв. Поддерживается несколько отзывов; пользователь редактирует только свои, администратор удаляет и отвечает.
favorite()Переключить избранное; очковая награда за игру не начисляется повторно.
share()Регистрирует намерение поделиться игрой на сервере и возвращает URL.
recordClick(label) / track(event,metadata)События действий, старта/завершения уровня; сервер проверяет допустимые типы и длину label.

Всегда обрабатывайте Promise через try/catch. Не передавайте в SDK токены, пароли, email, секреты или игровые payload большого размера. Не считайте локальный клиент авторитетным источником очков, сохранений или результатов матча.

7. Аккаунты, идентификаторы и данные

У каждого аккаунта есть внутренний numeric ID для связей базы и отдельный публичный player ID формата SC-.... Публичный лидерборд раскрывает только player ID, nickname и points. Email и внутренний идентификатор доступны администраторам по защищённому API, для аналитики и связи с игроком.

PostgreSQL хранит пользователей, игры и metadata, сессии, события, ratings, reviews/replies, favorites, cloud saves, email OTP и snapshots. Все обращения к PostgreSQL проходят через отдельный внутренний Data API; Platform API не содержит PostgreSQL-драйвер и не получает пароль БД. Файлы игр и аватары пока живут в постоянном storage/ volume. Аватарный оригинал выбирается как 512×512; клиент уменьшает до 64×64 WebP перед отправкой, сервер валидирует размеры и сохраняет маленькую производную. Неиспользуемый старый файл аватара удаляется после замены.

8. Метрики, игровое время и очки

Метрики строятся на серверных сессиях, отзывах, оценках, событиях игры и избранного. Heartbeat отправляется примерно каждые 15 секунд. Активным считается интервал, где документ видим и окно находится в фокусе; сервер принимает только ограниченный временной интервал, а не произвольное число секунд от клиента. Heartbeats прекращаются при закрытии страницы, а конец сессии отправляется keepalive-запросом.

  • CCU: уникальные игроки с живой активной сессией по heartbeat примерно за последние 45 секунд.
  • Daily players: уникальные идентичности аккаунтов и гостевых браузеров с игровыми сессиями по дате.
  • История: минутные snapshots CCU платформы и отдельных игр; ежедневные уникальные игроки агрегируются из сессий. История CCU накапливается только с момента запуска новой версии и не может быть восстановлена задним числом.
  • Админ-аналитика: пользователи, опубликованные/черновые игры, unique players, sessions, playtime, median session duration, ratings, reviews, shares, favorites и breakdown по играм/пользователям.

Очки рассчитываются только на сервере по правилам платформы: игровое активное время, качественные отзывы, добавление игр в избранное, поделиться каждой игрой не более одного раза и суммарная регулярная активность. Для одинаковой игры в избранном/шеринге повторные действия не должны давать бесконечный прирост. Самая длинная версия отзыва — источник очков за отзывы. Публичная подсказка должна совпадать с серверной формулой: 1 очко за активную минуту, +15 за полный накопленный час; за отзыв от 3 до 99 символов начисляется 10 + floor((длина − 3) / 7), от 100 символов — 25. Учитывается самый длинный корневой отзыв по игре. Избранное и первая отправка ссылки на каждую игру дают по 5 очков однократно. Время фоновой вкладки не учитывается; очки не являются денежным балансом.

CCU и heartbeat — полезная телеметрия, но не криптографическое доказательство, что реальный человек смотрит на экран. Для соревнований с призами потребуется усиление антибота, выявление аномалий, контроль нескольких сессий и независимый аудит событий.

9. Безопасность и модель угроз

  • Web requests: CSRF token на state-changing API, Origin validation, security headers, rate limiting и лимиты размера тела.
  • Authentication: hash OTP с expiry/attempt limits, secrets только в серверном окружении.
  • ZIP: проверка абсолютных путей, .., symlinks, количества файлов, распакованного размера и чрезмерной компрессии; пользовательский код не выполняется процессом платформы.
  • Browser games: iframe sandbox without allow-same-origin; черновые страницы и ассеты защищены ролью и короткоживущим подписанным cookie.
  • Server games: контейнер на игру, отдельная internal Docker network, read-only mount, non-root UID, drop capabilities, no-new-privileges, CPU/RAM/PID limits, tmpfs и отключённая внешняя сеть. Внешние user data и сохранения нужно хранить через backend/поддерживаемую БД, а не полагаться на ephemeral filesystem.
  • Network edge: app-level rate limit не заменяет CDN/WAF, защиту L3/L4, reverse proxy лимиты и мониторинг сетевой нагрузки.
Trust boundary: любой загруженный HTML/JS и любая server game — недоверенный код. Запуск Docker runtime оправдан только на выделенном хосте с корректно настроенным Docker daemon и ограниченными правами; не запускайте этот сервис с широкими привилегиями системного пользователя.

10. Интеграции

SMTP / email OTP

Почтовый transport задаётся через SMTP-переменные. Одноразовый код краткоживущий, сохраняется только хэш, число неверных попыток ограничено. Возврат OTP в интерфейс допустим только в development, но не в production.

Docker runtime

Каждая server game слушает 0.0.0.0:3000 внутри своего контейнера. Runtime manager отображает контейнерный порт 3000 на уникальный свободный порт хоста, доступный только через loopback-прокси платформы. Поэтому порт приложения платформы 3000 и внутренний порт игры 3000 не конфликтуют. Доступная из платформы задержка измеряется ping endpoint и показывается для серверных игр.

11. UX, локализация и доступность

  • Единые theme/language настройки хранятся в localStorage, поэтому переход по страницам их сохраняет.
  • Публичные UI страницы имеют RU/EN переводы. Страницы документации и SDK переводятся на русский и английский языки.
  • Названия игр всегда английские; описания локализованы; пользовательские теги видны/фильтруются только на английском.
  • Кнопка Play на карточке сразу запускает игру; клик по капсуле/остальной карточке открывает модал с описанием, рейтингом, отзывами и скриншотами из media/screenshots/.
  • Анимации должны уважать prefers-reduced-motion, а модалки — блокировать фоновую прокрутку и закрываться Escape/кнопкой с доступной подписью.
  • Все сообщения об ошибках должны быть понятными; сохранение формы следует выполнять через заранее захваченный form reference до async/await.

12. Локальный запуск и production

node --version                 # Node.js 20+
cp .env.example .env
# заполнить SESSION_SECRET, OTP_PEPPER, DATA_API_TOKEN, POSTGRES_PASSWORD, ADMIN_EMAIL, ADMIN_LOGIN и ADMIN_PASSWORD
docker compose up --build
# локально: http://localhost:3000/

Compose поднимает PostgreSQL, внутренний Data API и Platform API как отдельные сервисы. Platform API не получает DATABASE_URL и пароль PostgreSQL, а Data API не публикуется на host port. Игровые файлы и аватары по-прежнему сохраняются в постоянный storage/ volume; адаптер S3/GCS пока не подключён. Runtime manager выделен в отдельный внутренний сервис, который единственный подключён к Docker socket; Platform API вызывает его по внутреннему API с секретным токеном. Для production обязательны HTTPS, секреты через secret manager, reverse proxy/CDN/WAF, резервные копии с проверкой восстановления, мониторинг, политика конфиденциальности и условия использования. TRUST_PROXY=1 включается только за доверенным proxy. Серверные игры требуют доступного Docker Engine и runtime-образа, но в текущем Compose runtime manager ещё не выделен в отдельный сервис.

При автоматическом запуске опубликованных серверных игр приложение делает попытку поднять контейнер при старте. Если Docker недоступен или образ отсутствует, сама запись игры может быть published, но состояние пинга будет starting/offline и сообщение попадёт в server logs; публикация не равна подтверждённой готовности runtime.

13. План проверок и критерии приёмки

  1. Static checks: npm run check, валидный JSON/package manifest, проверки client JS.
  2. API smoke: /api/bootstrap, /api/games, /robots.txt, /sitemap.xml, /api/admin/metrics для admin и отказ доступа для не-admin.
  3. Archive pipeline: upload valid browser ZIP + valid server ZIP; тест отказа для traversal, absolute paths, symlinks, oversized archive, missing translations and invalid capsule size.
  4. Publishing: draft files закрыты от гостя, доступны администратору; публикация добавляет запись в каталог; unpublish/delete выключают runtime.
  5. SDK: getUser guest/auth, cloud save/load, review/rating/favorite/share, game event and activity timer.
  6. Server runtime: container health, port mapping, readiness retries, relative JS/CSS/image URLs, ping measurement, restart behavior, stop hooks.
  7. UX regressions: RU/EN persistence, docs/SDK RU/EN language switching, profile cancel/save/avatar thumbnail, comment avatar rendering, modal scroll-lock, reduced motion, mobile viewports.
  8. Operations: backups/restore, logging, disk quotas, host hardening, WAF behavior, SMTP delivery checks with real credentials.

14. Архитектурные решения (ADR summary)

ADR-001 · Platform API + internal Data API + PostgreSQL

Platform API владеет бизнес-правилами и HTTP-контрактом. Отдельный Data API — единственный компонент с драйвером PostgreSQL и принимает запросы только по реестру статических SQL-операторов с проверкой параметров; сырой SQL по сети не передаётся. Это уменьшает связанность и позволяет менять слой хранения без переделки публичного API. Express sessions также хранятся в PostgreSQL. Data API остаётся дополнительной точкой отказа, поэтому нужны health checks, тайм-ауты, backups и проверка транзакций.

ADR-002 · Vanilla JS вместо SPA-фреймворка

Каталог и админские страницы небольшие и преимущественно data-driven; нативный HTML/CSS/JS сокращает сборочную цепочку и упрощает отладку. При росте UI сложности допустимо выделить component system, не меняя REST-контракты.

ADR-003 · iframe sandbox для клиентских игр

Игра считается недоверенным code asset и не должна иметь same-origin доступ к сессии/DOM платформы. SDK bridge явный, узкий и валидирует список методов.

ADR-004 · Отдельный Docker container per server game

Нужен для server-authoritative multiplayer и пер-игровой изоляции. MVP использует локальный Docker manager и runtime probing; production следует дополнить лимитами числа одновременно работающих контейнеров, квотами CPU/disk, мониторингом, безопасной очисткой и возможным оркестратором.

ADR-005 · Server-computed score

Клиент не отправляет готовое число очков. Backend рассчитывает points из persisted sessions и допустимых действий, что устраняет простейшую накрутку подменой клиентского значения, но не заменяет антибот-модерацию.

ADR-006 · Localized descriptions, English title/tags

Отображаемое имя остаётся стабильным и индексируемым, описание зависит от языка, tags унифицированы на английском для каталожной фильтрации.

15. Приоритетный roadmap

  1. P0 — production validation: интеграционные тесты с чистой установкой зависимостей, миграции БД для существующих инсталляций, тесты на реальном Docker-хосте и проверки SMTP.
  2. P1 — operation: журналы контейнеров, рестарт/backoff, контейнерные квоты, health check, backups/restore drills, антивирус сканирования архивов, CSP и security audit.
  3. P1 — trust & safety: отчёты на отзывы/игры, moderation queue, anti-abuse thresholds, политика хранения и удаления аккаунта/данных.
  4. P1 — data reliability: проверить PostgreSQL/Data API на Docker Compose, добавить versioned schema migrations, backup/restore drills, тайм-ауты и контрактные тесты с реальной PostgreSQL.
  5. P2 — scale: вынести игровые ZIP/аватары/медиа в S3/GCS, выделить Docker runtime в отдельный ограниченный runtime-manager, добавить очередь фоновой аналитики и централизованный telemetry pipeline.
  6. P2 — product: SDK versioning, migration checks, preview diagnostics, automated compatibility checks и публикационный pipeline с release/rollback.

Инструменты и SDK

Перейти к SDK и промптам Админские метрики

HTTP API reference

Базовый URL: текущий origin платформы (например, http://localhost:3000). Ответы API — JSON, кроме страниц, файлов и sitemap. Изменяющие запросы используют cookie-сессию, credentials: 'same-origin' и CSRF-токен из GET /api/bootstrap в заголовке X-CSRF-Token. Не передавайте секреты или доверенные значения очков от клиента.

Права доступа.

«Public» — без входа; «Player» — действующая пользовательская сессия; «Admin» — проверка аккаунта ADMIN_EMAIL после входа по ADMIN_LOGIN и ADMIN_PASSWORD. Скрытие кнопки в UI не заменяет авторизацию на сервере. Неопубликованные игры и черновые ассеты недоступны гостям.

Контракт запросов и ошибок

API использует JSON, если маршрут не принимает multipart/form-data. Запись требует cookie текущей сессии и X-CSRF-Token из /api/bootstrap. Административные маршруты проверяют роль на сервере; сокрытие кнопки в UI не является контролем доступа.

  • 400 — некорректные параметры; 401 — нет сессии; 403 — отказ по CSRF/правам; 404 — ресурс недоступен; 409 — конфликт состояния; 429 — лимит запросов; 5xx — серверная ошибка.
  • Операции с побочными эффектами должны быть идемпотентными или защищёнными idempotency key.
  • Не передавайте пароли, одноразовые коды и секреты в query string.

Public / catalog

GET /healthPublic

Состояние HTTP-процесса Platform API.

GET /api/bootstrapPublic

CSRF token, текущий пользователь и доступность email-кода.

GET /api/games?lang=ru&q=word&tag=Puzzle&players=solo&minRating=3&sort=ratingPublic

Каталог. Поддерживаются players=any|solo|multi и сортировка newest|rating|players|plays.

GET /api/games/:slug/detailsPublic

Данные карточки игры: локализованное описание, обложка, скриншоты, средняя оценка и оценка авторизованного игрока.

GET /api/games/:slug/reviewsPublic

Список отзывов и ответов администрации.

GET /api/games/:slug/pingPublic

Доступность server runtime и измеренная задержка, если она применима.

GET /api/leaderboard?limit=100Public

Публичный рейтинг игроков без email и приватных полей.

POST /api/eventsPublic

Каталожные и игровые клики: JSON { "slug": "example", "type": "catalog_click" }. Допускаются catalog_click и game_click.

POST /api/games/:slug/sharePublic / Player

Учитывает действие «Поделиться» и возвращает канонический URL. Повторные очки ограничиваются серверной бизнес-логикой.

Authentication

POST /api/auth/email/start

Отправляет новый одноразовый код на email. JSON: { "email": "player@example.com" }.

POST /api/auth/email/verify

Подтверждает код email. JSON: { "email": "player@example.com", "code": "123456" }. Код имеет срок действия и лимит попыток.

POST /api/auth/password

Вход по паролю: логин администратора или email игрока и password.

POST /api/auth/logout

Завершает пользовательскую сессию.

Player & SDK

DELETE /api/me/account, GET /api/me/summaryPlayer

Удаление собственного аккаунта и получение истории, избранного и статистики профиля. Требуется активная сессия; email не передаётся игровому iframe.

PATCH /api/me/profilePlayer

Изменение никнейма и других разрешённых полей профиля.

POST /api/me/avatarPlayer

multipart/form-data с полем avatar. Исходник 512×512, сервер хранит миниатюру.

POST /api/me/password, POST /api/auth/passwordPlayer / Public

Настройка пароля аккаунта; администраторам также доступны ADMIN_LOGIN и ADMIN_PASSWORD.

GET|POST /api/games/:slug/savePlayer

Получение и сохранение облачного JSON-прогресса для текущего пользователя.

POST /api/games/:slug/ratingPlayer

JSON { "rating": 5 }, диапазон 1–5.

POST /api/games/:slug/review, PATCH /api/games/:slug/reviews/:reviewId, DELETE /api/games/:slug/reviews/:reviewIdPlayer

Создание и управление собственными комментариями; изменение и удаление проверяются сервером.

POST /api/games/:slug/reviews/:reviewId/replyAdmin

Ответ администрации на отзыв.

POST /api/games/:slug/favoritePlayer

Переключение избранного.

POST /api/sdk/session/start, POST /api/sdk/session/heartbeat, POST /api/sdk/session/end, POST /api/sdk/eventSDK

Игровые сессии, heartbeat активного времени и события уровня. Сервер перепроверяет допустимые поля.

Administrator

GET /api/admin/summary, GET /api/admin/metricsAdmin

Сводные и подробные метрики платформы и игр.

GET /api/admin/monitoringAdmin

Health, состояние server games, последние события и доступные ошибки.

GET /api/admin/gamesAdmin

Таблица управления играми, размеры архивов, метрики и URL тестовой/публичной версии.

POST /api/admin/games/uploadAdmin

Загрузка нового ZIP в multipart/form-data, поле archive.

POST /api/admin/games/:slug/updateAdmin

Обновляет сборку существующей игры, сохраняя стабильный game ID, сохранения и историю статистики.

PATCH /api/admin/games/:slug, POST /api/admin/games/:slug/capsuleAdmin

Редактирование описаний RU/EN, тегов, игроков, runtime type и замена капсулы.

POST /api/admin/games/:slug/publish, POST /api/admin/games/:slug/unpublish, DELETE /api/admin/games/:slugAdmin

Управление публикацией, остановкой runtime и удалением игры.

GET /api/admin/leaderboard, GET /api/admin/players/:id, DELETE /api/admin/players/:id, POST /api/admin/players/:id/emailAdmin

Полный рейтинг, профиль игрока, удаление пользовательского аккаунта и отправка письма.

Page & static routes

GET /, GET /games, GET /login.html, GET /profile.html, GET /leaderboard.html, GET /documentation.html, GET /sdk.htmlPages

Страницы каталога, входа, профиля, лидерборда, документации и SDK.

GET /games/:slug, GET /games/:slug-test, GET /game-files/:slug/*Game hosting

Публичная страница игры, административная тестовая страница и разрешённые ассеты игры.

GET /admin, GET /admin.html, GET /admin/metrics, GET /admin/recommendationsAdmin pages

Страницы защищены серверной проверкой администратора; это не API JSON.

GET /privacy-policy.html, GET /profile, GET /profile.html, GET /login, GET /login.htmlPages

Страницы профиля и входа.

GET /sitemap.xmlPublic

XML sitemap опубликованных игровых страниц.

GET /robots.txtPublic

Правила индексирования публичных и закрытых страниц.

GET /user-avatars/:filenamePublic media

Отдаёт WebP-миниатюру аватара; ответ — изображение, а не JSON.

Примеры запросов

1. Получить каталог

curl "http://localhost:3000/api/games?lang=en&players=solo&sort=rating"

2. Использовать CSRF-токен в браузере

const bootstrap = await fetch('/api/bootstrap', { credentials: 'same-origin' }).then(r => r.json());
const response = await fetch('/api/games/pocket-clicker/rating', {
  method: 'POST',
  credentials: 'same-origin',
  headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': bootstrap.csrfToken },
  body: JSON.stringify({ rating: 5 })
});
if (!response.ok) throw new Error((await response.json()).error || 'Request failed');
const result = await response.json();

3. Загрузить игру (администратор)

const form = new FormData();
form.append('archive', fileInput.files[0]);
const response = await fetch('/api/admin/games/upload', {
  method: 'POST', credentials: 'same-origin',
  headers: { 'X-CSRF-Token': bootstrap.csrfToken }, body: form
});
// Не задавай Content-Type вручную: браузер добавит multipart boundary.

4. Проверить server runtime

const status = await fetch('/api/games/durak-online/ping', { credentials: 'same-origin' }).then(r => r.json());
console.log(status.status, status.pingMs);

Стабильность API. В этом MVP маршруты документированы по текущему коду; отдельное формальное версионирование (/v1) пока не внедрено. До публичного SDK/API релиза следует добавить OpenAPI схему и генерировать endpoint-справочник из неё, чтобы он не расходился с исходниками.

Принципы продукта и контракт релиза

SUPER CUBE сокращает путь до игры, обеспечивает безопасную публикацию и сохраняет прогресс игрока. Обновление архива не меняет идентичность игры. Клиент не является доверенным источником оценок, сохранений, очков или многопользовательского состояния.

Продуктовые показатели

  • Активация: каталог → карточка → запуск → первая активная сессия.
  • Возврат: повторные запуски и успешное восстановление сохранения.
  • Публикация: валидный архив → приватный preview → публикация.
  • Надёжность: ошибки API, задержка, сбои сохранений и запуска серверных игр.

Границы данных и runtime

  • Platform API владеет бизнес-правилами; Data API предоставляет allowlisted операции PostgreSQL.
  • Браузерные игры работают в sandboxed iframe; серверные — в изолированном runtime.
  • Email, секреты, сохранения и внутренние ошибки Data API не попадают в публичные ответы.
  • Изменения API/SDK требуют миграций, контрактных тестов и обновления документации.

Определения метрик

  • CCU означает текущую одновременную активность, а не дневную аудиторию.
  • Дневные игроки — уникальные аккаунты/guest ID с сессией в выбранной дате.
  • Рейтинг — среднее актуальных оценок с числом оценок.
  • Медиана — медиана положительных длительностей сессий за выбранный период.

Начисление очков

  • 1 очко за каждую подтверждённую активную минуту и +15 за полный накопленный час.
  • За отзыв — 10–25 очков; 100+ символов дают 25; учитывается самый длинный отзыв по игре.
  • Избранное и первый share каждой игры дают бонус только один раз.
  • Очки не являются деньгами и рассчитываются сервером.

Контракты интеграции и примеры доступны на отдельной странице SDK и в справочнике API.