A Flask web application for managing participants, races, and results. Built for Google Cloud Platform with Firestore database and OAuth authentication.
- Participant Management: Register and manage participants with Parkrun barcode tracking
- Club Administration: Manage running clubs and their short names/aliases
- Season & Race Management: Organise races by seasons with configurable age categories
- Results Processing: Upload and manage race results via CSV or manual entry
- Public Results: Public-facing results display for race participants
- Admin Authentication: Google OAuth-based admin access control
- Bulk Operations: CSV upload for participants and race results
- Frontend: Flask with Jinja2 templates
- Backend: Python Flask application
- Database: Google Firestore (NoSQL)
- Authentication: Google OAuth 2.0
- Infrastructure: Google Cloud Run (containerized deployment)
- Secrets: Google Secret Manager
- Infrastructure as Code: OpenTofu/Terraform
cc6-app/
├── app/ # Flask application
│ ├── templates/ # HTML templates
│ ├── static/ # CSS, images, robots.txt
│ ├── app.py # Main Flask application
│ ├── api.py # API blueprint (JSON endpoints)
│ ├── auth.py # OAuth authentication
│ ├── database.py # Firestore database operations
│ ├── Dockerfile # Container configuration
│ └── test_*.py # Test files
├── tofu/ # Infrastructure as code
└── datastructure.md # Firestore data model documentation
- Google Cloud Project with billing enabled
- OpenTofu installed
- Docker (for local development)
- Python 3.14 (for local development)
-
Configure infrastructure:
cd tofu cp terraform.tfvars.example terraform.tfvars # Edit terraform.tfvars with your project details
-
Deploy infrastructure:
tofu init tofu plan tofu apply
-
Configure OAuth secrets:
- Create Google OAuth credentials in Google Cloud Console
- Store client ID and secret in Secret Manager:
gcloud secrets versions add oauth-client-id --data="your-client-id" gcloud secrets versions add oauth-client-secret --data="your-client-secret"
-
Access the application:
- The application will be deployed to Cloud Run
- Custom domain mapping available at
app.cc6.co.uk
-
Set up environment:
cd app pip install pipenv pipenv install --dev pipenv shell -
Configure environment variables:
export GOOGLE_CLOUD_PROJECT="your-project-id" export FLASK_SECRET_KEY="your-secret-key" export GOOGLE_CLIENT_ID="your-oauth-client-id" export GOOGLE_CLIENT_SECRET="your-oauth-client-secret"
-
Run locally:
python app.py
-
Run tests:
make test
GOOGLE_CLOUD_PROJECT: GCP project IDFLASK_SECRET_KEY: Flask session secret keyGOOGLE_CLIENT_ID: OAuth client IDGOOGLE_CLIENT_SECRET: OAuth client secretPORT: Application port (default: 8080)
project_id: Google Cloud Project IDregion: Deployment region (default: us-central1)domain: Custom domain for the application
The application uses Firestore with the following collections:
- participants: Runner registration data with parkrun barcode IDs
- clubs: Running club information and aliases
- seasons: Race seasons with configurable age categories
- races: Individual races within seasons
- results: Race results linked to participants
- admin_emails: Authorized administrator email addresses
See datastructure.md for detailed schema documentation.
GET /- Home pageGET /results- Public results displayGET /api/clubs- List all clubsGET /api/seasons- List all seasonsGET /api/seasons/<season>- Season details with racesGET /api/races/<season>/<race>- Race resultsGET /api/championship/<season>/<gender>- Team championship standingsGET /api/individual-championship/<season>/<gender>- Individual championship standings
GET /participants- Participant managementGET /clubs- Club managementGET /seasons- Season managementGET /races- Race managementGET /api/participants- Get participants data (JSON)POST /upload_participants- Bulk participant uploadPOST /process_upload_results- Bulk results upload
- Google OAuth 2.0 authentication for admin access
- Email-based authorization (configurable admin list)
- Secrets stored in Google Secret Manager
- HTTPS enforced in production
- Input validation and sanitization
- Cloud Run automatic logging
- Application logs available in Google Cloud Logging
- Health checks via Cloud Run
- Fork the repository
- Create a feature branch
- Make changes and add tests
- Run the test suite:
make test - Submit a pull request
This project is licensed under the MIT License.