TourPlanner/README.md
Oleksandr Kozachuk f077bf1f0f Complete the repo.
2025-06-08 13:49:38 +02:00

343 lines
6.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Tour Voting App
Tour Voting App is a full-stack web application for planning tours, proposing ideas, and voting on those ideas. It consists of:
* **Backend API** built with FastAPI
* **Data persistence** using per-tour JSON files in a configurable directory, with concurrency safety via file locks
* **Frontend**: Single-page HTML/JavaScript application that consumes the API
* **Helper scripts** for local development or Supervisor-based deployment
## Table of Contents
1. Features
2. Tech Stack
3. Prerequisites
4. Installation
5. Configuration
6. Development
7. Running in Production
8. Frontend Usage
9. API Reference
* Models
* Endpoints
10. Directory Structure
11. Contributing
12. License
## Features
* Create and manage tours with metadata (name, start/end dates, description)
* Add multiple ideas per tour, each with its own name, description, and optional time window
* Vote on ideas by recording unique voter names
* No external database: JSON filebased persistence
* Concurrency-safe via file locking
* Minimal static HTML/JavaScript frontend for user interaction
* Helper scripts for local development or Supervisor deployment
## Tech Stack
* **Backend**: Python 3.10+, FastAPI, Uvicorn, Pydantic, filelock
* **Frontend**: HTML, CSS, JavaScript (Fetch API)
* **Process Control (optional)**: Supervisor
* **Data storage**: JSON files, one per tour
## Prerequisites
* Python 3.10 or higher
* pip (Python package installer)
* (Optional) Supervisor for process management
## Installation
1. **Clone the repository**
git clone [https://github.com/your-organization/tour-voting-app.git](https://github.com/your-organization/tour-voting-app.git)
cd tour-voting-app
2. **Create virtual environment and install dependencies**
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
If `requirements.txt` is not provided, install directly:
pip install fastapi uvicorn pydantic filelock
## Configuration
Configure via environment variables or command-line flags:
* **DATA\_DIR**: directory to store tour JSON files (default: `./data`)
* **HOST**: address to bind the API (default: `0.0.0.0`)
* **PORT**: port for the API (default: `8000`)
Example using environment variables:
```
export DATA_DIR=./data
export HOST=0.0.0.0
export PORT=8000
```
Or via flags:
```
python server.py --data-dir ./data --host 0.0.0.0 --port 8000
```
## Development
1. Activate your virtual environment.
2. Start the server in reload mode:
```
uvicorn server:app --reload --host 0.0.0.0 --port 8000
```
3. Open `index.html` in your browser (or serve it via a local HTTP server to avoid CORS issues).
## Running in Production
Use the provided `service.sh` script and Supervisor config:
**service.sh**
```bash
#!/usr/bin/env bash
cd /path/to/tour-voting-app || exit 1
exec uvicorn server:app \
--host 0.0.0.0 \
--port 3002 \
--loop uvloop \
--workers 2 \
--access-log \
--log-level info
```
**tour.ini** (Supervisor)
```ini
[program:tour_voting_app]
command=/path/to/service.sh
directory=/path/to/tour-voting-app
autostart=true
autorestart=true
stderr_logfile=/var/log/tour_voting_app.err.log
stdout_logfile=/var/log/tour_voting_app.out.log
```
## Frontend Usage
The frontend is a single `index.html` file that interacts with the API. By default, `API_URL` is set to `http://localhost:8000/tour/v1`. To point it at a remote server, edit the `API_URL` constant near the top of `index.html`.
## API Reference
Base path: `/tour/v1`
### Models
**Tour**
```json
{
"id": "string",
"name": "string",
"description": "string",
"startDate": "ISO-8601 timestamp",
"endDate": "ISO-8601 timestamp",
"createdAt": "ISO-8601 timestamp",
"ideas": [ Idea ]
}
```
**Idea**
```json
{
"id": "string",
"name": "string",
"description": "string",
"startTime": "ISO-8601 timestamp | null",
"endTime": "ISO-8601 timestamp | null",
"voters": [ "string" ]
}
```
### Endpoints
#### 1. List Tours
* **Method**: GET
* **URL**: `/tours`
* **Response**: `200 OK`
```json
[ { Tour }, ... ]
```
#### 2. Create a Tour
* **Method**: POST
* **URL**: `/tours`
* **Request Body**:
```json
{
"name": "Europe Explorer",
"description": "A tour across Europe",
"startDate": "2025-07-01T00:00:00Z",
"endDate": "2025-07-15T00:00:00Z"
}
```
* **Response**: `201 Created`
```json
{ Tour }
```
#### 3. Get Tour Details
* **Method**: GET
* **URL**: `/tours/{tour_id}`
* **Path Parameters**:
* `tour_id` (string): ID of the tour
* **Response**: `200 OK`
```json
{ Tour }
```
* **Error**: `404 Not Found` if tour does not exist.
#### 4. Add an Idea to a Tour
* **Method**: POST
* **URL**: `/tours/{tour_id}/ideas`
* **Path Parameters**:
* `tour_id` (string): ID of the tour
* **Request Body**:
```json
{
"name": "Visit the Louvre",
"description": "Guided museum tour",
"startTime": "2025-07-03T10:00:00Z",
"endTime": "2025-07-03T14:00:00Z"
}
```
* **Response**: `201 Created`
```json
{ Idea }
```
* **Error**: `404 Not Found` if tour does not exist.
#### 5. Vote for an Idea
* **Method**: POST
* **URL**: `/tours/{tour_id}/ideas/{idea_id}/vote`
* **Path Parameters**:
* `tour_id` (string): ID of the tour
* `idea_id` (string): ID of the idea
* **Request Body**:
```json
{ "voterName": "alice@example.com" }
```
* **Response**: `200 OK`
```json
{ Idea } // Updated idea with new voter
```
* **Errors**:
* `404 Not Found` if tour or idea does not exist.
* `400 Bad Request` if voter name is missing or already voted.
## Directory Structure
```
tour-voting-app/
├── server.py # FastAPI application
├── index.html # Static frontend
├── service.sh # Startup helper script
├── tour.ini # Supervisor config
├── data/ # JSON files for tours (runtime)
├── requirements.txt # Python dependencies (optional)
└── README.md # Project documentation
```
## Contributing
1. Fork the repository.
2. Create a feature branch:
git checkout -b feature/my-feature
3. Commit your changes:
git commit -m "Add my feature"
4. Push to your branch:
git push origin feature/my-feature
5. Open a pull request.
## License
This project is licensed under the WTFPL License.
---
.gitignore
# Byte-compiled files
**pycache**/
\*.py\[cod]
\*\$py.class
# Virtual environments
.env/
.venv/
env/
venv/
# Distribution
build/
dist/
\*.egg-info/
\*.egg
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Python coverage
htmlcov/
.tox/
.coverage
.pytest\_cache/
.nox/
# Logs
\*.log
# IDEs
.vscode/
.idea/
# macOS
.DS\_Store
# Linux
\*\~
# Data files and locks
data/
\*.json
\*.lock