Tippspiel is a full-stack betting game application for managing private prediction groups around sports events. Users can create games, join existing games, add or import events, place bets, upload results, calculate scores, and view standings in a browser-based UI.
The repository is split into a Flask backend and a React frontend. Both parts are developed and tested independently, but they are designed to run together during local development: Vite serves the frontend and proxies /api requests to the Flask app on http://127.0.0.1:5000.
backend/: Flask application, SQLite database access, Firebase integration, scraping/import logic, and pytest test suitefrontend/: React + TypeScript + Vite application, component library, domain models, and Vitest test suitedeploy_backend.sh: backend deployment entry pointdeploy_frontend.sh: local frontend deployment scriptdeploy_frontend_remotely.sh: local-build, remote-copy frontend deployment script
The backend is a Flask app created in backend/main.py. It loads configuration from environment variables via backend/config.py, registers blueprints under /api, initializes Flask-Login, and optionally boots Firebase Admin for notifications.
The data layer is built around SQLite and custom model/database helpers in backend/src/models and backend/src/database. Core backend responsibilities include:
- authentication and session handling
- game creation and protected game joins
- event management and event imports from URLs
- bet submission and result processing
- score calculation and standings
- notification-related endpoints and helpers
The frontend is a React 18 + TypeScript app bootstrapped with Vite. Routing starts in frontend/src/App.tsx and is organized around a small set of pages such as login, home, game details, placing bets, and viewing bets.
The UI talks to the backend through typed domain/network helpers in frontend/src/models. The codebase is roughly split into:
pages/: route-level screenscomponents/design/: reusable UI building blockscomponents/domain/: betting/game specific UIcontexts/: user, appearance, cache, and app state providersmodels/: frontend data models and API access helpers
- Python 3.11
- Flask
- Flask-Login
- SQLite
- Firebase Admin SDK
- pytest
- pandas, BeautifulSoup, lxml, html5lib, requests, selenium for import/scraping workflows
uvfor dependency management and execution
- React 18
- TypeScript
- Vite
- Vitest
- Tailwind CSS 4
- Sass modules
- React Router
- Headless UI
- Recharts and Chart.js
- Firebase Web SDK
tippspiel/
├── backend/
│ ├── main.py # Flask app factory / startup
│ ├── config.py # Environment-based config loader
│ ├── src/
│ │ ├── blueprints/ # API routes
│ │ ├── database/ # SQLite helpers and DB files
│ │ ├── models/ # Domain and persistence logic
│ │ ├── resources/ # SQL schema and seed/import data
│ │ └── scraping/ # Source-specific scraping/import helpers
│ └── test/ # Backend tests
├── frontend/
│ ├── src/
│ │ ├── components/ # Reusable and domain-specific UI
│ │ ├── contexts/ # React contexts
│ │ ├── models/ # Frontend models and API wrappers
│ │ ├── pages/ # Route-level pages
│ │ └── styles/ # Shared styling helpers
│ └── test/ # Frontend tests
├── deploy_backend.sh
├── deploy_frontend.sh
└── deploy_frontend_remotely.sh
- Python 3.11
- Node.js and npm
uv
- Create a local backend env file from
backend/.env.example. - Install dependencies:
cd backend
uv sync- Start the backend:
cd backend
uv run python main.pyRelevant backend environment variables:
TIPPSPIEL_SECRET_KEYTIPPSPIEL_PASSWORD_SALTTIPPSPIEL_DB_PATHTIPPSPIEL_FIREBASE_CREDENTIALS_PATHTIPPSPIEL_TESTING
- Create a frontend env file from
frontend/.env.example. - Install dependencies:
cd frontend
npm install- Start the frontend dev server:
cd frontend
npm run devBy default, the Vite dev server proxies /api requests to the backend on port 5000, configured in frontend/vite.config.ts.
cd backend
uv run pytest
uv run pytest test/test_blueprint_game.pycd frontend
npm test
npm test -- --run
npm run lint
npm exec tsc -- --noEmitFor new contributors, these files give the fastest overview of how the system hangs together:
backend/main.py: backend startup, config wiring, blueprint registrationbackend/src/blueprints/game.py: representative API flow for authenticated game actionsbackend/src/models/event.py: core event/bet/result processing logicfrontend/src/App.tsx: route tree and top-level compositionfrontend/src/pages/HomePage.tsx: main authenticated landing flowfrontend/src/models/NetworkHelper.ts: central frontend API handling
Backend tests live in backend/test and use backend/test/conftest.py to provision isolated temporary SQLite databases.
Frontend tests live in frontend/test and cover domain models and selected UI behavior with Vitest.
- Production backend configuration is expected in
/etc/tippspiel/backend.env. backend/tippspiel_backend.servicecontains the systemd unit for the backend.backend/run_tippspiel_backendcontains cron entries related to periodic backend tasks.deploy_frontend_remotely.shbuilds the frontend locally and copiesfrontend/dist/to a remote host over SSH.
- New user passwords and game join passwords use a safer hash, while legacy SHA-256 hashes are upgraded on successful login/join.
- Do not rotate
TIPPSPIEL_PASSWORD_SALTuntil legacy hashes have been migrated or resets are planned. - The repository currently contains generated/local artifacts such as virtualenv,
node_modules,dist, and local SQLite files. Be deliberate when reviewing diffs and deployments.