Complete the repo.

This commit is contained in:
Oleksandr Kozachuk
2025-06-08 13:49:38 +02:00
parent 94ea328614
commit f077bf1f0f
3 changed files with 371 additions and 144 deletions
+341 -2
View File
@@ -1,3 +1,342 @@
# TourPlanner
# Tour Voting App
Tour Planner is a lightweight FastAPI-based service that lets you create “tours, propose ideas for each tour, and vote on those ideas. It stores each tour as a JSON file in a configurable data directory (with filelevel locking for safe concurrent access), and ships with a minimal static HTML/JavaScript frontend along with helper scripts for local development or deployment under Supervisor.
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