9.6 KiB
Forbidden Stars — учёт партий
Мобильное веб-приложение для учёта партий настольной игры Forbidden Stars: профили игроков (вход через Telegram, пока — dev-заглушка), группы, создание партий с рандомом фракций и фильтром по дополнениям группы, статистика и общий топ, админ-панель.
- Бэкенд / ядро + API: Python · FastAPI · SQLModel · SQLite
- Фронтенд: React · Vite · TypeScript (SPA, общается с ядром только по REST API)
- Хостинг: Raspberry Pi 4 (ARM64) в Docker
Структура
backend/ FastAPI: ядро, REST API, БД, миграции, seed
frontend/ React + Vite SPA
Dockerfile multi-stage сборка (фронт собирается node, отдаётся FastAPI)
docker-compose.yml
.env.example
Локальная разработка
Бэкенд и фронт запускаются раздельно; Vite проксирует /api на бэкенд.
1) Бэкенд
Windows PowerShell (команды по одной — в PowerShell 5.1 нет &&):
cd backend
python -m venv .venv
.\.venv\Scripts\Activate.ps1 # если ругается на политику: Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
pip install -e ".[dev]" # .[dev] — один аргумент (пакет + dev-зависимости)
Copy-Item ..\.env.example ..\.env # ЕДИНЫЙ .env лежит в КОРНЕ репозитория
alembic upgrade head # применит миграции и сидинг
python -m app.bootstrap # создаст/синхронизирует администратора из .env
uvicorn app.main:app --reload # http://localhost:8000 (Swagger: /api/docs)
Windows cmd.exe (здесь && поддерживается):
cd backend
python -m venv .venv
.venv\Scripts\activate.bat
pip install -e ".[dev]"
copy ..\.env.example ..\.env
alembic upgrade head
python -m app.bootstrap
uvicorn app.main:app --reload
Linux / macOS / Git Bash:
cd backend
python -m venv .venv && . .venv/Scripts/activate # на *nix: . .venv/bin/activate
pip install -e ".[dev]"
cp ../.env.example ../.env
alembic upgrade head
python -m app.bootstrap
uvicorn app.main:app --reload
Единый
.env— в корне репозитория (ForbidenStarsApp/.env), рядом с.env.example. Его читают и бэкенд (через абсолютный путь, независимо от рабочей папки), иdocker compose. Файл — локальный, на каждой машине свой (dev/prod различаются строкойAPP_ENV).
2) Фронт (в отдельном терминале)
cd frontend
npm install
npm run gen:api # сгенерирует типы из живого OpenAPI (бэкенд должен быть запущен)
npm run dev # http://127.0.0.1:5173 или http://localhost:5173 (оба стека)
Вход в dev-режиме — экран /login: в деве доступны оба метода (Telegram + вход по нику),
в проде — только Telegram (см. раздел «Аутентификация»).
Production (Docker на Pi)
cp .env.example .env # заполните SECRET_KEY, ADMIN_PASSWORD и пр.
docker compose build # на ARM64 собирается нативно
docker compose up -d # приложение на :8000, БД на томе
FastAPI отдаёт собранный SPA и API с одного origin. Миграции и бутстрап админа
выполняются автоматически при старте (entrypoint.sh).
Test — локальный прод-клон в контейнере
Тот же образ и поведение, что и прод (FastAPI отдаёт SPA, БД на томе, вход игроков только через Telegram), но на своей машине — для проверки прод-сборки до выката на Pi. Изолированные тома и порт 8080 (не конфликтует с dev-uvicorn на :8000).
cp .env.test.example .env.test # заполнить при необходимости
docker compose --env-file .env.test -f docker-compose.test.yml up -d --build
# открыть http://localhost:8080 (Swagger: /api/docs)
docker compose -f docker-compose.test.yml down -v # остановить и стереть тестовые данные
- Окружение принудительно
production(клон Pi), ноCOOKIE_SECURE=false(локально HTTP). - Данные — на отдельных томах
db-data-test/uploads-data-test(не пересекаются с dev и Pi). - Вход: админ-панель (
/admin/login) работает сразу по логину/паролю; вход игроков — только через Telegram (нужен бот + публичный HTTPS/туннель наlocalhost:8080). - Если пароль/секрет содержит
$, для docker compose экранируйте его как$$(для dev-uvicorn экранирование не нужно — pydantic читает$дословно).
Аутентификация
Методы входа зависят от окружения (APP_ENV):
| dev | prod | |
|---|---|---|
| Telegram Login Widget | ✓ | ✓ (единственный) |
| Вход по нику (stub) | ✓ | ✗ (физически отсутствует) |
- Stub-вход (по нику) — только для разработки. Его код физически не попадает в прод:
файлы
backend/app/auth/dev_stub.pyиbackend/app/routers/dev_auth.pyисключены из Docker-образа (.dockerignore), роутер подключается лишь приAPP_ENV != production(app/main.py), а на фронте dev-блок вырезается из прод-сборки (import.meta.env.DEV). - Telegram: сервер проверяет подпись виджета (HMAC по
TELEGRAM_BOT_TOKEN).GET /api/auth/configотдаёт доступные методы иtelegram_bot_usernameдля виджета.
Настройка Telegram (когда будете подключать реальный вход):
- Создать бота у @BotFather → получить токен и username.
/setdomainу BotFather → ваш HTTPS-домен (где открывается приложение).- В
.env:TELEGRAM_BOT_TOKEN=...,TELEGRAM_BOT_USERNAME=...(без@). - Домену нужен HTTPS (например, Cloudflare Tunnel) — виджет не работает по голому HTTP.
Админ-вход (секретная панель, логин+пароль) — отдельный механизм, доступен в обоих окружениях.
Окружения (dev / test / prod)
Один и тот же код; контур выбирается тем, чем и с каким .env запускаешь:
| dev | test (прод-клон локально) | prod (Pi) | |
|---|---|---|---|
| Запуск | uvicorn --reload + vite |
docker compose -f docker-compose.test.yml |
docker compose |
| Env-файл | .env (корень) |
.env.test (корень) |
.env (корень, на Pi) |
APP_ENV |
development |
production (форсится) |
production (форсится) |
| Раздача SPA | Vite (HMR), :5173 | FastAPI, :8080 | FastAPI, :8000 |
| База данных | backend/data/dev/… |
том db-data-test (/data) |
том db-data (/data) |
| Вход игроков | Telegram + ник (stub) | только Telegram | только Telegram |
- Структура БД одна (общие миграции Alembic), файлы разные — путь выбирается по
APP_ENV(DEV_DATABASE_URL/PROD_DATABASE_URL). Данные дева — вbackend/data/dev/(в образ не попадают:data/в.dockerignore). - В Docker идёт только прод-код: контейнер принудительно
APP_ENV=production, dev-вход (stub) физически исключён из образа.test— это тот же прод-образ, просто локально. .envодин на машину, в корне (рядом с.env.example).testиспользует свой.env.test(чтобы крутить прод-клон рядом с dev, не мешая ему). Реальные.env/.env.testхранятся только локально; рядом лежат шаблоны*.example.
Дополнения и фракции
| Дополнение | Фракции |
|---|---|
| База (всем) | Орки, Ультрамарины, Эльдары, Хаоситы |
| Forgotten Worlds | Имперская гвардия, Тау, Некроны, Тираниды |
| Forsaken Voids | Инквизиция, Сёстры битвы, Друкхари, Адептус Механикус |
Группа отмечает имеющиеся дополнения; при создании партии доступны только фракции этих дополнений (база — всегда).