218 lines
5.9 KiB
Markdown
218 lines
5.9 KiB
Markdown
# Cluedo HP Webapp
|
||
|
||
A small multiplayer web app that acts as a digital note sheet for a Harry Potter-inspired Cluedo game. Several logged-in players can join the same game and manage their personal clues independently.
|
||
|
||
## Features
|
||
|
||
- Login with user and admin roles
|
||
- Admin-managed user creation and deactivation
|
||
- Multiple games per user
|
||
- Join games using a short join code
|
||
- Automatic player list with host indication
|
||
- Personal note sheet for each player and game
|
||
- Categories for suspects, items, and locations
|
||
- Entry status tracking: empty, ruled out, present, or maybe
|
||
- Additional notes using `i`, `m`, and `s.<chip>`
|
||
- Winner selection by the game host
|
||
- Winner badge and confetti animation for all players
|
||
- Live updates for new players and winner changes
|
||
- Personal game statistics
|
||
- Password change functionality
|
||
- Harry Potter house themes: Default, Gryffindor, Slytherin, Ravenclaw, and Hufflepuff
|
||
- Installable as a Progressive Web App
|
||
|
||
## Technology
|
||
|
||
### Frontend
|
||
|
||
- React 18
|
||
- Vite
|
||
- Nginx as the production web server
|
||
- `canvas-confetti` for the winner animation
|
||
- `vite-plugin-pwa` for PWA support
|
||
|
||
### Backend
|
||
|
||
- Python 3.12
|
||
- FastAPI
|
||
- SQLAlchemy 2
|
||
- SQLite 3
|
||
- Passlib and bcrypt for password hashing
|
||
|
||
### Deployment
|
||
|
||
- Docker Compose
|
||
- Frontend on port `8081`
|
||
- Backend on port `8080`
|
||
- SQLite database stored in a persistent Docker volume
|
||
|
||
## Quick start with Docker
|
||
|
||
Requirements:
|
||
|
||
- Docker
|
||
- Docker Compose
|
||
|
||
1. Copy `.env.example` to `.env` and set a strong secret:
|
||
|
||
```env
|
||
BACKEND_SECRET_KEY=use-a-long-random-secret-value
|
||
```
|
||
|
||
2. Build and start the containers:
|
||
|
||
```bash
|
||
docker compose up --build
|
||
```
|
||
|
||
3. Open the application:
|
||
|
||
- Frontend: http://localhost:8081
|
||
- Backend/API: http://localhost:8080
|
||
|
||
On the first startup, the application opens a setup screen where you create the first administrator with an email address, display name, and password. The default suspects, items, and locations are seeded automatically as well.
|
||
|
||
The SQLite database is stored in the Docker volume `cluedo-data` and survives normal container restarts.
|
||
|
||
Start the containers in the background:
|
||
|
||
```bash
|
||
docker compose up -d --build
|
||
```
|
||
|
||
View logs:
|
||
|
||
```bash
|
||
docker compose logs -f backend
|
||
```
|
||
|
||
Stop the containers:
|
||
|
||
```bash
|
||
docker compose down
|
||
```
|
||
|
||
## Local development without Docker
|
||
|
||
### Backend
|
||
|
||
```bash
|
||
cd backend
|
||
python -m venv .venv
|
||
source .venv/bin/activate
|
||
pip install -r requirements.txt
|
||
|
||
export DATABASE_URL=sqlite:///./data/cluedo.db
|
||
export SECRET_KEY=use-a-long-random-secret-value
|
||
|
||
uvicorn app.main:app --reload --port 8080
|
||
```
|
||
|
||
On Windows PowerShell, set the environment variables like this:
|
||
|
||
```powershell
|
||
$env:DATABASE_URL = "sqlite:///./data/cluedo.db"
|
||
$env:SECRET_KEY = "use-a-long-random-secret-value"
|
||
uvicorn app.main:app --reload --port 8080
|
||
```
|
||
|
||
### Frontend
|
||
|
||
```bash
|
||
cd frontend
|
||
npm install
|
||
npm run dev
|
||
```
|
||
|
||
The frontend is normally available at http://localhost:5173. During development, the API must be reachable under `/api`; the production Docker setup provides this through Nginx.
|
||
|
||
Create a production build:
|
||
|
||
```bash
|
||
npm run build
|
||
```
|
||
|
||
## Project structure
|
||
|
||
```text
|
||
.
|
||
├── backend/
|
||
│ ├── app/
|
||
│ │ ├── main.py # FastAPI app, startup, seed data
|
||
│ │ ├── models.py # SQLAlchemy models
|
||
│ │ ├── db.py # SQLite engine and sessions
|
||
│ │ ├── security.py # Password and cookie logic
|
||
│ │ └── routes/ # Auth, admin, and game APIs
|
||
│ ├── Dockerfile
|
||
│ └── requirements.txt
|
||
├── frontend/
|
||
│ ├── src/
|
||
│ │ ├── App.jsx # Main UI and game flow
|
||
│ │ ├── api/client.js # API client
|
||
│ │ ├── components/ # Pages, cards, and modals
|
||
│ │ ├── styles/ # Themes and inline styles
|
||
│ │ └── utils/ # Small helpers and storage utilities
|
||
│ ├── Dockerfile
|
||
│ └── nginx.conf
|
||
├── docker-compose.yml
|
||
└── .env
|
||
```
|
||
|
||
## Data model
|
||
|
||
- `users`: users, roles, status, display names, and themes
|
||
- `games`: game name, join code, host, and winner
|
||
- `game_members`: assignment of users to games
|
||
- `entries`: seeded suspects, items, and locations
|
||
- `sheet_state`: personal status and notes for an entry
|
||
|
||
Each player has their own set of `sheet_state` records for every game. A player's notes are therefore not visible to other players.
|
||
|
||
## API overview
|
||
|
||
### Authentication
|
||
|
||
- `POST /auth/login`
|
||
- `POST /auth/logout`
|
||
- `GET /auth/me`
|
||
- `PATCH /auth/password`
|
||
- `PATCH /auth/theme`
|
||
- `GET /auth/me/stats`
|
||
|
||
### First-run setup
|
||
|
||
- `GET /setup/status`
|
||
- `POST /setup/admin`
|
||
|
||
The setup endpoint is available only while no administrator exists. After the first administrator has been created, the setup screen is disabled automatically.
|
||
|
||
### Administration
|
||
|
||
- `GET /admin/users`
|
||
- `POST /admin/users`
|
||
- `DELETE /admin/users/{user_id}` – deactivates a user
|
||
|
||
### Games
|
||
|
||
- `GET /games`
|
||
- `POST /games`
|
||
- `POST /games/join`
|
||
- `GET /games/{game_id}`
|
||
- `GET /games/{game_id}/members`
|
||
- `PATCH /games/{game_id}/winner`
|
||
- `GET /games/{game_id}/sheet`
|
||
- `PATCH /games/{game_id}/sheet/{entry_id}`
|
||
|
||
## SQLite notes
|
||
|
||
SQLite is a good fit for this application: the data volume is small, the app is intended for internal use, and write operations are short. The database file is stored inside the container at `/app/data/cluedo.db` and persisted through the `cluedo-data` volume.
|
||
|
||
For larger deployments with many concurrent write operations, PostgreSQL would still be the more robust choice. For the intended private or small-group use case, SQLite is sufficient.
|
||
|
||
## Security notes
|
||
|
||
- The values in `.env` are examples and should be changed before production use.
|
||
- When using HTTPS, set `COOKIE_SECURE` to `true`.
|
||
- The application is intended for an internal or small user group.
|
||
- The automatic database migration is intentionally pragmatic and does not replace a migration system such as Alembic.
|