Kiyomichi Kosaka 046e84e996
Merge pull request #4 from ok2/codex/hide-idea-input-on-decision
Add decided badge to idea cards
2025-06-08 21:56:34 +02:00
2025-06-08 13:49:38 +02:00
2025-06-08 13:33:33 +02:00
2025-06-08 13:49:38 +02:00
2025-06-08 16:29:37 +02:00
2025-06-08 21:36:41 +02:00
2025-06-08 13:23:54 +02:00
2025-06-08 13:49:38 +02:00

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 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

#!/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)

[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

{
  "id": "string",
  "name": "string",
  "description": "string",
  "startDate": "ISO-8601 timestamp",
  "endDate": "ISO-8601 timestamp",
  "createdAt": "ISO-8601 timestamp",
  "ideas": [ Idea ]
}

Idea

{
  "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

    [ { Tour }, ... ]
    

2. Create a Tour

  • Method: POST

  • URL: /tours

  • Request Body:

    {
      "name": "Europe Explorer",
      "description": "A tour across Europe",
      "startDate": "2025-07-01T00:00:00Z",
      "endDate": "2025-07-15T00:00:00Z"
    }
    
  • Response: 201 Created

    { Tour }
    

3. Get Tour Details

  • Method: GET

  • URL: /tours/{tour_id}

  • Path Parameters:

    • tour_id (string): ID of the tour
  • Response: 200 OK

    { 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:

    {
      "name": "Visit the Louvre",
      "description": "Guided museum tour",
      "startTime": "2025-07-03T10:00:00Z",
      "endTime": "2025-07-03T14:00:00Z"
    }
    
  • Response: 201 Created

    { 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:

    { "voterName": "alice@example.com" }
    
  • Response: 200 OK

    { 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

Description
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 file‐level 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.
Readme WTFPL 98 KiB
Languages
HTML 77.6%
Python 22%
Shell 0.4%