From 6ab74f01aaf1ac042a269c7660b3e564b93350c7 Mon Sep 17 00:00:00 2001 From: NotBigGhost Date: Tue, 16 Jun 2026 16:53:41 +0300 Subject: [PATCH] first commit --- README.md | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..42188aa --- /dev/null +++ b/README.md @@ -0,0 +1,163 @@ +# 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 нет `&&`): +```powershell +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** (здесь `&&` поддерживается): +```bat +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:** +```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) Фронт (в отдельном терминале) +```bash +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) + +```bash +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). + +```bash +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 (когда будете подключать реальный вход):** +1. Создать бота у [@BotFather](https://t.me/BotFather) → получить **токен** и **username**. +2. `/setdomain` у BotFather → ваш HTTPS-домен (где открывается приложение). +3. В `.env`: `TELEGRAM_BOT_TOKEN=...`, `TELEGRAM_BOT_USERNAME=...` (без `@`). +4. Домену нужен 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 | Инквизиция, Сёстры битвы, Друкхари, Адептус Механикус | + +Группа отмечает имеющиеся дополнения; при создании партии доступны только фракции +этих дополнений (база — всегда).