# 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.` - 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.