222 lines
5.8 KiB
Markdown
222 lines
5.8 KiB
Markdown
# Treasure Trails
|
|
|
|
An online scavenger hunt application where Game Masters create and manage hunts, Teams compete to complete clues, and Spectators can follow along in real-time.
|
|
|
|
## Features
|
|
|
|
- **Game Master Dashboard**: Create scavenger hunts with legs/clues, manage live games, view team progress
|
|
- **Team Interface**: Mobile-friendly gameplay with clues, map navigation, photo submissions, and real-time chat
|
|
- **Spectator View**: Public dashboard showing team positions and leaderboard
|
|
- **Real-time Updates**: Live tracking via WebSockets (Socket.io)
|
|
- **OpenStreetMap Integration**: All maps use OpenStreetMap data
|
|
|
|
## Tech Stack
|
|
|
|
| Component | Technology |
|
|
|-----------|------------|
|
|
| Frontend | Vue 3 + TypeScript + Vite |
|
|
| Backend | Node.js + Express |
|
|
| Real-time | Socket.io |
|
|
| Database | PostgreSQL + Prisma |
|
|
| Maps | Leaflet + OpenStreetMap |
|
|
|
|
## Prerequisites
|
|
|
|
- Node.js 20+ (for local development)
|
|
- Docker & Docker Compose
|
|
|
|
## Quick Start with Docker
|
|
|
|
The easiest way to run the application:
|
|
|
|
```bash
|
|
# Start all services (PostgreSQL, Backend, Frontend)
|
|
docker-compose up -d
|
|
|
|
# View logs
|
|
docker-compose logs -f
|
|
|
|
# Stop services
|
|
docker-compose down
|
|
```
|
|
|
|
The application will be available at:
|
|
- **Frontend**: http://localhost:5173
|
|
- **Backend API**: http://localhost:3001
|
|
|
|
## Local Development
|
|
|
|
### 1. Clone and Install Dependencies
|
|
|
|
```bash
|
|
# Backend
|
|
cd backend
|
|
npm install
|
|
|
|
# Frontend
|
|
cd ../frontend
|
|
npm install
|
|
```
|
|
|
|
### 2. Set Up Database
|
|
|
|
Create a PostgreSQL database:
|
|
|
|
```bash
|
|
# Connect to PostgreSQL
|
|
psql -U postgres
|
|
|
|
# Create database
|
|
CREATE DATABASE treasure_trails;
|
|
```
|
|
|
|
Update the database connection in `backend/.env`:
|
|
|
|
```
|
|
DATABASE_URL="postgresql://postgres:your_password@localhost:5432/treasure_trails?schema=public"
|
|
```
|
|
|
|
### 3. Initialize Database Schema
|
|
|
|
```bash
|
|
cd backend
|
|
npx prisma generate
|
|
npx prisma db push
|
|
```
|
|
|
|
### 4. Run the Backend
|
|
|
|
```bash
|
|
cd backend
|
|
npm run dev
|
|
```
|
|
|
|
The backend API will run on http://localhost:3001
|
|
|
|
### 5. Run the Frontend
|
|
|
|
```bash
|
|
cd frontend
|
|
npm run dev
|
|
```
|
|
|
|
The frontend will run on http://localhost:5173
|
|
|
|
## Usage
|
|
|
|
### As a Game Master
|
|
|
|
1. Register a new account
|
|
2. Go to Dashboard and click "Create New Game"
|
|
3. Fill in game details and click on the map to set the treasure location
|
|
4. Click "Create Game" to save as draft
|
|
5. Click "Edit Game" to add legs/clues
|
|
6. Once legs are added, click "Publish Game" to make it live
|
|
7. Use the "Live Dashboard" to monitor teams
|
|
|
|
### As a Team Member
|
|
|
|
1. Register or login
|
|
2. Browse public games or use an invite link
|
|
3. Join a game by creating a team (3-5 members) or joining an existing team
|
|
4. During the game, use the "Play" interface to:
|
|
- View current clue
|
|
- See your position on the map
|
|
- Submit photo proof
|
|
- Chat with other teams and the Game Master
|
|
|
|
### As a Spectator
|
|
|
|
1. Navigate to any public live game
|
|
2. Click "Spectate" to view:
|
|
- Live map with all team positions
|
|
- Leaderboard showing progress
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
/home/brian/Development/scavenge
|
|
├── docker-compose.yml # Docker Compose configuration
|
|
├── backend/
|
|
│ ├── Dockerfile # Backend container
|
|
│ ├── prisma/
|
|
│ │ └── schema.prisma # Database schema
|
|
│ ├── src/
|
|
│ │ ├── index.ts # Server entry point
|
|
│ │ ├── middleware/
|
|
│ │ │ └── auth.ts # JWT authentication
|
|
│ │ ├── routes/
|
|
│ │ │ ├── auth.ts # Auth endpoints
|
|
│ │ │ ├── games.ts # Game CRUD
|
|
│ │ │ ├── legs.ts # Leg/clue management
|
|
│ │ │ ├── teams.ts # Team management
|
|
│ │ │ └── upload.ts # File uploads
|
|
│ │ └── socket/
|
|
│ │ └── index.ts # Socket.io handlers
|
|
│ ├── .env # Environment variables
|
|
│ └── package.json
|
|
├── frontend/
|
|
│ ├── Dockerfile # Frontend container
|
|
│ ├── nginx.conf # Nginx configuration
|
|
│ ├── src/
|
|
│ │ ├── pages/ # Vue page components
|
|
│ │ ├── stores/ # Pinia state management
|
|
│ │ ├── services/ # API service
|
|
│ │ ├── types/ # TypeScript types
|
|
│ │ ├── router/ # Vue Router config
|
|
│ │ ├── App.vue
|
|
│ │ └── main.ts
|
|
│ └── package.json
|
|
├── application_requirements.md # Original requirements
|
|
└── README.md # This file
|
|
```
|
|
|
|
## API Endpoints
|
|
|
|
### Authentication
|
|
- `POST /api/auth/register` - Create account
|
|
- `POST /api/auth/login` - Login
|
|
- `GET /api/auth/me` - Get current user
|
|
|
|
### Games
|
|
- `GET /api/games` - List public games
|
|
- `GET /api/games/my-games` - List user's games
|
|
- `POST /api/games` - Create game
|
|
- `GET /api/games/:id` - Get game details
|
|
- `PUT /api/games/:id` - Update game
|
|
- `POST /api/games/:id/publish` - Publish game
|
|
- `GET /api/games/:id/invite` - Get invite code
|
|
|
|
### Legs
|
|
- `POST /api/legs/game/:gameId` - Add leg
|
|
- `PUT /api/legs/:legId` - Update leg
|
|
- `DELETE /api/legs/:legId` - Delete leg
|
|
- `POST /api/legs/:legId/photo` - Submit photo
|
|
|
|
### Teams
|
|
- `GET /api/teams/game/:gameId` - List teams
|
|
- `POST /api/teams/game/:gameId` - Create team
|
|
- `POST /api/teams/:teamId/join` - Join team
|
|
- `POST /api/teams/:teamId/advance` - GM advances team
|
|
- `POST /api/teams/:teamId/deduct` - GM applies time penalty
|
|
- `POST /api/teams/:teamId/disqualify` - GM disqualifies team
|
|
|
|
## Socket Events
|
|
|
|
- `join-game` - Join a game's socket room
|
|
- `team-location` - Broadcast team position
|
|
- `chat-message` - Send/receive chat
|
|
- `team-advanced` - Notify team advancement
|
|
|
|
## Environment Variables
|
|
|
|
### Backend (.env)
|
|
```
|
|
DATABASE_URL="postgresql://..."
|
|
JWT_SECRET="your-secret-key"
|
|
PORT=3001
|
|
```
|
|
|
|
## License
|
|
|
|
MIT
|