diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/.env.example diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/.gitattributes diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/.gitignore diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..f1adf25 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,8 @@ +{ + "printWidth": 100, + "tabWidth": 2, + "singleQuote": true, + "trailingComma": "all", + "bracketSpacing": true, + "semi": true +} diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..2a94353 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,93 @@ +# AGENTS + +### Overview + +This repository is a minimal starter project. Agents interacting with it should follow the conventions below for building, linting, testing, and coding style. The guidelines are intentionally generic to accommodate future language or framework additions. If new tools are added, update this file accordingly. + +--- + +## 1. Build / Lint / Test Commands + +| Tool | Command | Purpose | +|------|---------|---------| +| npm | `npm run build` | Transpile / bundle the source code (if applicable). No default script is currently defined; add only when a build process emerges. | +| npm | `npm run lint` | Run ESLint + Prettier checks. Ensure that `lint` script is configured in `package.json`. | +| npm | `npm test` | Run the full test suite using Jest / Mocha / any test runner configured. | +| npm | `npm test -- ` | Run a *single* test or a set of tests matching the glob ``. Example: `npm test -- src/__tests__/*.spec.js`. | +| npm | `npm run format` | Auto‑format the code base using Prettier. Helpful after manual edits. | +| npm | `npm run type-check` | Run TypeScript type checking (if the project uses TypeScript). | + +**Tip**: Agents should prefer the single‑test form when debugging to avoid slow test runs. + +--- + +## 2. Code Style Guidelines + +### 2.1 Import Order + +1. **External packages** (npm modules) alphabetically. +2. **Internal modules** (relative imports) sorted by path depth. +3. **Side‑effect imports** (`"./setup"`) placed last. + +Use the ESLint `import/order` rule to enforce this. + +### 2.2 Formatting + +- Use Prettier with the repository’s `.prettierrc` configuration. +- Prefer **single quotes** for strings, unless a string contains a single quote. +- Trailing commas are mandatory in multiline arrays, objects, and function parameter lists. +- Max line width: 100 characters. + +### 2.3 Types + +- If TypeScript is used, prefer **explicit types** over `any`. +- For function parameters, use named types (`Array`, `Record`, etc.). +- Avoid type inference when the type becomes unclear. +- Export type aliases and interfaces from `types/index.ts` where appropriate. + +### 2.4 Naming Conventions + +| Element | Style | Example | +|---------|-------|---------| +| **Variables / constants** | `snake_case` for constants, `camelCase` for others | `MAX_RETRIES`, `userName` | +| **Functions** | `camelCase` | `fetchData()` | +| **Classes / Interfaces** | `PascalCase` | `UserService` | +| **Enums** | `UPPER_SNAKE_CASE` | `UserStatus` | +| **React Components** | `PascalCase` | `MyComponent` | +| **Redux Actions / Reducers** | `lower_kebab-case` | `fetch-users` | + +### 2.5 Error Handling + +- Use `try/catch` blocks around async operations. +- Wrap errors in custom error classes (e.g., `ApiError`) to provide rich context. +- Never swallow errors; always either re‑throw or log with sufficient detail. +- When interacting with external services, use exponential back‑off and timeouts. + +### 2.6 Testing + +- Tests should be in `__tests__` directories mirroring the source tree. +- Use descriptive `describe`/`it` blocks. +- Avoid global state; reset mocks before each test. +- A test file must be covered by a **single** public API surface. + +--- + +## 3. Cursor / Copilot Rules + +No `cursor` or `copilot` configuration files currently exist in the repository. If these are added in the future: + +- Place cursor rules under `.cursor/rules/`. +- Copilot instructions should be kept in `.github/copilot-instructions.md`. +- Agents should respect any `allowlist` or `blocklist` directives. + +--- + +## 4. Miscellaneous + +- All commits must pass linting and tests before merging. +- Use descriptive commit messages following the Conventional Commits spec. +- Document major decisions in the `CONTRIBUTING.md` (once created). + +--- + +If additional tooling or standards are added, update this file and communicate changes to all agents. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/CONTRIBUTING.md diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..564caa5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,11 @@ +# Dockerfile for the backend +FROM python:3.12-slim + +WORKDIR /app + +COPY backend/docker/requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +COPY backend/app ./app + +CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] \ No newline at end of file diff --git a/README.md b/README.md index aee46fd..733c0bd 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,17 @@ -exp-cats-new -=============== +# Exp-Cats + +This repository contains a minimal starter for a multiplayer‑card game “Cat Explosion”. + +## Run locally + +```bash +# start services and run backend on 8000 +docker compose up -d +# visit http://localhost:8000 +``` + +## Build + +```bash +docker build -t exp-cats:latest . +``` diff --git a/backend/.gitignore b/backend/.gitignore new file mode 100644 index 0000000..06ab2a2 --- /dev/null +++ b/backend/.gitignore @@ -0,0 +1,34 @@ +# .gitignore +# Byte-compiled / optimized / DLL files +__pycache__ +*.py[cod] +*.py[cod] +*.so +# Distribution / packaging +.Python +build +develop-eggs +dist +downloads +eggs +.eggs +lib +lib64 +parts +sdist +var +wheels +pip-wheel-metadata +share/python-wheels +*.egg-info +.installed.cfg +*.egg +MANIFEST +# Virtual env +.venv +env +# PyCharm +.idea +*.pyc +# VS Code +.vscode \ No newline at end of file diff --git a/backend/app/__init__.py b/backend/app/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/backend/app/__init__.py diff --git a/backend/app/api/auth.py b/backend/app/api/auth.py new file mode 100644 index 0000000..68e5c1f --- /dev/null +++ b/backend/app/api/auth.py @@ -0,0 +1,7 @@ +from fastapi import APIRouter + +router = APIRouter() + +@router.post("/register") +async def register(): + return {"msg": "register"} diff --git a/backend/app/api/game.py b/backend/app/api/game.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/backend/app/api/game.py diff --git a/backend/app/api/lobby.py b/backend/app/api/lobby.py new file mode 100644 index 0000000..5904cb1 --- /dev/null +++ b/backend/app/api/lobby.py @@ -0,0 +1,7 @@ +from fastapi import APIRouter + +router = APIRouter() + +@router.post("/create") +async def create_lobby(): + return {"msg": "create lobby"} diff --git a/backend/app/db.py b/backend/app/db.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/backend/app/db.py diff --git a/backend/app/main.py b/backend/app/main.py new file mode 100644 index 0000000..4d0988f --- /dev/null +++ b/backend/app/main.py @@ -0,0 +1,26 @@ +# backend/app/main.py +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware + +from .api.auth import router as auth_router +from .api.lobby import router as lobby_router +from .api.game import router as game_router + +app = FastAPI(title="Exp Cats API") + +# Allow CORS for local dev +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + +app.include_router(auth_router, prefix="/auth", tags=["auth"]) +app.include_router(lobby_router, prefix="/lobbies", tags=["lobby"]) +app.include_router(game_router, prefix="/game", tags=["game"]) + +@app.get("/") +async def root(): + return {"msg": "Welcome to Exp Cats API"} diff --git a/backend/app/models/card.py b/backend/app/models/card.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/backend/app/models/card.py diff --git a/backend/app/models/lobby.py b/backend/app/models/lobby.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/backend/app/models/lobby.py diff --git a/backend/app/models/user.py b/backend/app/models/user.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/backend/app/models/user.py diff --git a/backend/app/schemas/lobby.py b/backend/app/schemas/lobby.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/backend/app/schemas/lobby.py diff --git a/backend/app/schemas/user.py b/backend/app/schemas/user.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/backend/app/schemas/user.py diff --git a/backend/app/utils.py b/backend/app/utils.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/backend/app/utils.py diff --git a/backend/app/websocket.py b/backend/app/websocket.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/backend/app/websocket.py diff --git a/backend/docker/requirements.txt b/backend/docker/requirements.txt new file mode 100644 index 0000000..3b3b8b1 --- /dev/null +++ b/backend/docker/requirements.txt @@ -0,0 +1,11 @@ +fastapi==0.111.0 +uvicorn[standard]==0.30.0 +sqlalchemy==2.0.30 +asyncpg==0.29.0 +passlib[bcrypt]==1.7.4 +pydantic==2.7.1 +python-jose[cryptography]==3.3.0 +pytest==8.3.2 +httpx==0.27.0 +playwright==1.45.0 +alembic==1.13.2 diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/backend/tests/conftest.py diff --git a/backend/tests/test_auth.py b/backend/tests/test_auth.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/backend/tests/test_auth.py diff --git a/backend/tests/test_game_ws.py b/backend/tests/test_game_ws.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/backend/tests/test_game_ws.py diff --git a/backend/tests/test_lobby.py b/backend/tests/test_lobby.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/backend/tests/test_lobby.py diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..7b0ef5d --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,26 @@ +# docker-compose.yml for the project +version: '3.8' + +services: + backend: + build: + context: . + dockerfile: Dockerfile + image: exp-cats-backend + ports: + - '8000:8000' + environment: + - DATABASE_URL=postgresql://postgres:postgres@db:5432/exp_cats + depends_on: + - db + db: + image: postgres:15-alpine + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: exp_cats + volumes: + - db_data:/var/lib/postgresql/data + +volumes: + db_data: diff --git a/docs/technical_spec.md b/docs/technical_spec.md new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/docs/technical_spec.md diff --git a/filestructure.md b/filestructure.md new file mode 100644 index 0000000..72d6431 --- /dev/null +++ b/filestructure.md @@ -0,0 +1,60 @@ +# Файловая структура проекта + +``` +/├── .gitignore +/├── README.md +/├── CONTRIBUTING.md +/├── Dockerfile +/├── docker-compose.yml +/├── .env.example +/├── frontend +│ ├── index.html +│ ├── styles +│ │ └── main.scss +│ ├── scripts +│ │ └── main.js +│ └── public +│ └── assets +├── backend +│ ├── app +│ │ ├── __init__.py +│ │ ├── main.py # FastAPI entry point +│ │ ├── api +│ │ │ ├── auth.py +│ │ │ ├── lobby.py +│ │ │ └── game.py +│ │ ├── models +│ │ │ ├── user.py +│ │ │ ├── lobby.py +│ │ │ └── card.py +│ │ ├── schemas +│ │ │ ├── user.py +│ │ │ └── lobby.py +│ │ ├── db.py +│ │ ├── websocket.py +│ │ └── utils.py +│ ├── tests +│ │ ├── conftest.py +│ │ ├── test_auth.py +│ │ ├── test_lobby.py +│ │ └── test_game_ws.py +│ ├── alembic +│ │ └── versions +│ └── docker +│ └── requirements.txt +├── docs +│ └── technical_spec.md +└── .prettierrc +``` + +### Краткое описание каталогов + +| Каталог | Что содержит | +|---------|--------------| +| **frontend** | Статические файлы и JavaScript‑сценарии, стили SCSS | +| **backend** | Код FastAPI, модели, схемы Pydantic, база‑данных, миграции alembic, unit & integ тесты | +| **tests** | Тесты для каждого подмодуля | +| **docs** | Техническое задание, пользовательская и разраб. документация | +| **docker** | Требования и скрипты для сборки образов | + +Это простая, но в то же время мощная структура, позволяющая держать клиентскую и серверную часть изолированными, легко управлять зависимостями, а также быстро запускать проект с помощью Docker‑Compose. diff --git a/technical_spec.md b/technical_spec.md new file mode 100644 index 0000000..d40cbde --- /dev/null +++ b/technical_spec.md @@ -0,0 +1,94 @@ +# Техническое задание проекта «Клон взрывных котят – карточная игра» + +## 1. Общие сведения + +| Параметр | Значение | +|----------|----------| +| Название | «Explosive Cats – Card Game» | +| Тип проекта | Простая браузерная карточная игра • Backend: Python • Frontend: Vanilla JS/HTML+SCSS | +| Целевая аудитория | Игроки в кругу друзей (не более 4 чел.) | +| Платформы | Web‑браузер (десктоп + мобильный) | +| Технологический стек | Back‑end: FastAPI, SQLAlchemy, PostgreSQL (опционально для хранения результатов), Docker. Front‑end: HTML5 Canvas, Vanilla JS, SCSS. Dev‑тех: Docker‑Compose, Prettier, ESLint, pytest. + +## 2. Функциональные требования + +| Номер | Функциональность | Описание | Приоритет | +|------|-------------------|----------|-----------| +| 1 | Аутентификация | Регистрация/вход по email+пароль, JWT. | Критический | +| 2 | Создание/присоединение лобби | Игрок может создать lobby с уникальным кодом, поделиться им. Другие игроки вводят код – присоединяются. | Критический | +| 3 | Карточная система | Карточки с уникальными эффектами (прыжок, взрыв, защита). | Критический | +| 4 | Правила игры | Ходы, эффект карт, окончание игры. | Критический | +| 5 | Синхронизация | Через WebSocket: передача состояния колод, очков, активного игрока, эффекта. | Критический | +| 6 | UI/UX | Таблица очков, колоды, активный игрок. | Средний | +| 7 | Сохранение результатов | Сохраняем победы/поражения. | Средний | +| 8 | Тесты | Unit tests для API, integration tests для WebSocket, UI tests (Playwright). | Средний | + +## 3. Нефункциональные требования + +- Масштабируемость: до 10 одновременных игр – простая Docker‑композиция. +- Безопасность: базовый HTTPS, защита от CSRF/XSS, rate‑limiting (не более 10 запросов/минута). +- Документация: Swagger/OpenAPI, README, CONTRIBUTING. +- Версионирование не требуется. +- CI/CD не предусмотрено – ручная сборка Docker, запуск при изменении. + +## 4. Архитектура + +``` ++----------------+ +----------------+ +| Client (Browser)|<------->| WebSocket Server | ++----------------+ +----------------+ + | + v ++----------------+ +----------------+ +----------------+ +----------------+ +| HTTP API Server|<------->| Database (PostgreSQL)|<------->| Admin UI | ++----------------+ +----------------+ +----------------+ +----------------+ +``` + +* HTTP API – CRUD для пользователей, лобби, статистики. | +* WebSocket – real‑time передача игрового состояния. | +* PostgreSQL – долговременное хранение результатов. | +* Docker‑compose – разворачивает все сервисы. + +## 5. План разработки + +| Итерация | Длительность | Результат | +|-----------|---------------|-----------| +| 1 | 1 неделя | Проектный репозиторий, Dockerfile, docker‑compose, базовый API `auth/register, auth/login`. | +| 2 | 1 неделя | JWT, Swagger, CRUD игроков и лобби. | +| 3 | 1 неделя | WebSocket‑сервер, реализация лобби и простого UI без карты. | +| 4 | 2 недели | Реализация карточек, колоды, правила игры, клиентский Canvas. | +| 5 | 1 неделя | Тесты, финальная сборка Docker, обновление документации. | + +## 6. Технологические детали + +### Backend +- **FastAPI** – асинхронный фреймворк, WebSocket поддержка. | +- **SQLAlchemy** – ORM, Alembic migrations. | +- **Uvicorn** – ASGI сервер. | +- **Passlib** – хэширование паролей. | +- **PyJWT** или **fastapi-users** – JWT. + +### Frontend +- **Vanilla JS** – ES6 modules, fetch API, async/await. | +- **Canvas API** – отрисовка карты и карточек. | +- **SCSS** – стили, BEM. | + +### Test & Dev +- **pytest** – unit tests для API. | +- **playwright** – UI‑тесты. | +- **Docker‑compose** – разворот для dev. | + +## 7. Минимальные риски + +- Синхронизация: использовать простую модель с версионированием состояния. | +- Производительность: WebSocket‑соединения простейшие, 4 игрока. +- Безопасность: базовый HTTPS/CSRF/XSS. + +## 8. Дальнейшие шаги + +1. Создать `README.md`, `CONTRIBUTING.md`. | +2. Настроить `docker-compose.yml` (API, PostgreSQL). | +3. Реализовать базовый CRUD + auth. | +4. Переход к итерациям. + +> **Важно**: Уровень покрытия тестами – минимум 80 %.