UNDERCOVER is a dark, game-show style web app for an AI Club event where teams stake Byte-Coins to identify which candidate is the AI bot. This repo follows the screenshot structure with a FastAPI backend, static HTML/CSS/JS frontend, dual database setup, and GitHub-ready project files.
- Team registration with a 1,000 Byte-Coin starting balance
- Round 1 first-impression questions, 25s timer, candidate responses, and initial staking
- Round 2 cross-examination, team selector, spin-wheel multiplier, double-down, and switch mechanics
- Round 3 bounty phrase prompt engineering, candidate response feed, bounty bonus, and final all-in stake
- Grand reveal, session leaderboard, global leaderboard table, and session closeout
- Mock AI mode for local demos plus OpenAI-compatible candidate generation via environment variables
- Dual database configuration for human game data and AI personality data
.
├── backend/
│ ├── main.py
│ ├── config.py
│ ├── database.py
│ ├── models.py
│ ├── schemas.py
│ ├── services/
│ │ ├── bot_service.py
│ │ ├── coin_service.py
│ │ └── wheel_service.py
│ ├── routers/
│ │ ├── auth.py
│ │ ├── round1.py
│ │ ├── round2.py
│ │ ├── round3.py
│ │ └── results.py
│ └── requirements.txt
├── frontend/
│ ├── pages/
│ │ ├── index.html
│ │ ├── round1.html
│ │ ├── round2.html
│ │ ├── round3.html
│ │ ├── results.html
│ │ └── end.html
│ ├── css/
│ │ └── style.css
│ └── js/
│ ├── api.js
│ ├── coins.js
│ ├── round1.js
│ ├── round2.js
│ ├── round3.js
│ └── results.js
├── database/
│ ├── human_db.sql
│ └── personality_db.sql
├── .env.example
├── .gitignore
└── README.md
- Backend: FastAPI, SQLAlchemy, Pydantic
- Frontend: HTML, CSS, vanilla JavaScript modules
- Database: SQLite by default for local development; MySQL-compatible URLs supported
- AI: Mock mode by default; OpenAI-compatible mode available
cd backend
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp ../.env.example .env
uvicorn main:app --reload --host 0.0.0.0 --port 8000Open http://localhost:8000.
Copy .env.example to backend/.env for local development.
HOST_PASSWORD=LeetCode124
CANDIDATE_PASSWORD=LeetCode124
HUMAN_DATABASE_URL=sqlite:///./.local/human.db
PERSONALITY_DATABASE_URL=sqlite:///./.local/personality.db
AI_PROVIDER=mock
OPENAI_API_KEY=
OPENAI_MODEL=gpt-4.1-miniTo enable OpenAI responses:
AI_PROVIDER=openai
OPENAI_API_KEY=your_key_here| Method | Endpoint | Purpose |
|---|---|---|
| POST | /api/team/register |
Register a team |
| POST | /api/session/start |
Start a host-created session |
| POST | /api/round/stake |
Submit a stake |
| POST | /api/round1/questions |
Generate Round 1 candidate responses |
| POST | /api/round2/questions |
Generate Round 2 candidate responses |
| GET | /api/round2/select-teams/{session_id} |
Select teams for follow-up questions |
| GET | /api/round2/wheel |
Spin reward multiplier |
| POST | /api/round/double-down |
Double down in Round 2 |
| POST | /api/round/switch |
Switch suspect in Round 2 |
| POST | /api/round/prompt |
Submit Round 3 prompt |
| POST | /api/lifeline/use |
Use one lifeline |
| GET | /api/leaderboard/session/{session_id} |
Session leaderboard |
| GET | /api/leaderboard/global |
Master leaderboard |
| POST | /api/candidate/reveal |
Reveal candidate identity |
| POST | /api/session/end/{session_id} |
Close session and save results |
Local development works with SQLite automatically. For MySQL, create two databases and run:
mysql -u root -p < database/human_db.sql
mysql -u root -p < database/personality_db.sqlThen update:
HUMAN_DATABASE_URL=mysql+pymysql://user:password@localhost:3306/human_db
PERSONALITY_DATABASE_URL=mysql+pymysql://user:password@localhost:3306/personality_db- The staking multiplier is calculated server-side and only the final multiplier is returned to the UI.
- Recovery Grant is applied automatically after Round 2 actions when a team drops below 300 Byte-Coins.
- The default correct AI candidate is
D, configurable when creating a session. - Host and candidate approval password defaults to
LeetCode124.