Skip to content

KiOui/TOSTI

TOSTI - Tartarus Order System for Take-away Items

CI Deploy License: MIT

TOSTI is a comprehensive web application designed for Tartarus to manage take-away orders and various other features for student associations at Radboud University.

🚀 Features

Core Features

  • Order Management System: Online ordering system for take-away items (such as tostis)
  • Financial Transactions: User balance tracking and transaction management
  • User Authentication: SAML-based SSO integration (with Radboud University via SURFconext)
  • Music Control: Spotify and Marietje integration for controlling music players
  • Room Reservations: Venue reservation system with calendar integration
  • Borrel Management: Event reservation system with inventory tracking
  • Age Verification: Yivi-based age verification system
  • Smart Fridge Access: Digital lock system for automated fridge access, using TOSTI-fridge-client
  • QR Code Identification: Token-based user identification system
  • Bookkeeping Integration: Synchronization with Silvasoft accounting system

Additional Features

  • Multi-venue support with separate canteens (North/South)
  • Real-time order status tracking
  • Statistics and analytics dashboard
  • OAuth2 API for third-party integrations
  • iCal feeds for reservations
  • Automated music scheduling

🏗️ Architecture

TOSTI is built using:

  • Backend: Django 5.1 (Python)
  • Frontend: Django templates with Bootstrap 5
  • Database: PostgreSQL (production) / SQLite (development)
  • Caching: File-based cache (production) / In-memory (development)
  • Authentication: SAML2 (via djangosaml2)
  • API: Django REST Framework with OAuth2
  • Task Scheduling: Custom cron implementation
  • Containerization: Docker & Docker Compose

📁 Project Structure

website/
├── age/                    # Age verification module
├── announcements/          # System announcements
├── associations/           # Student associations management
├── borrel/                 # Event/borrel reservation system
├── cron/                   # Custom cron job implementation
├── fridges/                # Smart fridge access control
├── orders/                 # Core ordering system
├── qualifications/         # User qualifications (e.g., borrel brevet)
├── silvasoft/              # Bookkeeping integration
├── status_screen/          # Order status display
├── thaliedje/              # Music player control
├── tosti/                  # Main application settings
├── transactions/           # Financial transactions
├── users/                  # User management
├── venues/                 # Venue reservation system
└── yivi/                   # Yivi integration for age verification

🛠️ Development Setup

Prerequisites

  • Python 3.14+ (recommended to use pyenv)
  • uv for dependency management
  • Git

Installation

  1. Clone the repository

    git clone https://github.com/KiOui/TOSTI.git
    cd TOSTI
  2. Install uv

    curl -LsSf https://astral.sh/uv/install.sh | sh
  3. Set up uv environment

    uv sync --locked --all-extras --dev
  4. Set up the database

    cd website
    uv run ./manage.py migrate
  5. Create a superuser

    uv run ./manage.py createsuperuser
  6. Load initial data (optional)

    uv run ./manage.py loaddata tosti/fixtures/default.json
  7. Run the development server

    uv run ./manage.py runserver

The application will be available at http://localhost:8000.

Development Notes

  • SAML authentication is disabled in development mode
  • Use /admin-login in production for local authentication
  • API documentation is available at /api/docs

Vendored frontend libraries

All third-party JS/CSS is vendored in-repo — no CDN dependencies at runtime. To bump versions:

# Vue (use the production build only — the dev build emits a runtime warning)
curl -sfL https://unpkg.com/vue@<X.Y.Z>/dist/vue.global.prod.js \
  -o website/tosti/static/tosti/js/vue.global.prod.js

# qrcode.vue
curl -sfL https://unpkg.com/qrcode.vue@<X.Y.Z>/dist/qrcode.vue.browser.min.js \
  -o website/tosti/static/tosti/js/qrcode.vue.browser.min.js

# Chart.js (used on the statistics page; the bundle references its sourcemap)
curl -sfL https://cdn.jsdelivr.net/npm/chart.js@<X.Y.Z>/dist/chart.umd.min.js \
  -o website/tosti/static/tosti/js/chart.umd.min.js
curl -sfL https://cdn.jsdelivr.net/npm/chart.js@<X.Y.Z>/dist/chart.umd.min.js.map \
  -o website/tosti/static/tosti/js/chart.umd.min.js.map

# FullCalendar 6+ — CSS is inlined into the JS, no separate stylesheet
curl -sfL https://cdn.jsdelivr.net/npm/fullcalendar@<X.Y.Z>/index.global.min.js \
  -o website/venues/static/venues/js/fullcalendar.index.global.min.js

# Bootstrap (grab both minified and unminified + source maps)
BS=<X.Y.Z>
for f in js/bootstrap.bundle.js js/bootstrap.bundle.js.map \
         js/bootstrap.bundle.min.js js/bootstrap.bundle.min.js.map \
         css/bootstrap.css css/bootstrap.css.map \
         css/bootstrap.min.css css/bootstrap.min.css.map; do
  curl -sfL "https://cdn.jsdelivr.net/npm/bootstrap@$BS/dist/$f" \
    -o "website/tosti/static/tosti/$f"
done

# Swagger UI (used on /api/docs)
SW=<X.Y.Z>
for f in swagger-ui-bundle.js swagger-ui-bundle.js.map \
         swagger-ui-standalone-preset.js swagger-ui-standalone-preset.js.map; do
  curl -sfL "https://cdn.jsdelivr.net/npm/swagger-ui-dist@$SW/$f" \
    -o "website/tosti/static/tosti/js/$f"
done
for f in swagger-ui.css swagger-ui.css.map; do
  curl -sfL "https://cdn.jsdelivr.net/npm/swagger-ui-dist@$SW/$f" \
    -o "website/tosti/static/tosti/css/$f"
done

The Neucha font is also self-hosted under website/tosti/static/tosti/fonts/.

Verify Vue: head -2 website/tosti/static/tosti/js/vue.global.prod.js should print the expected version, and the file should be a single-line minified bundle (not ~16 000 lines of source — that would be the dev build in disguise).

🐳 Production Deployment

TOSTI runs in production as a Docker Compose stack on a VM. Deployments are automated: every push to master that passes CI (test + lint + image build) is deployed by .github/workflows/deploy.yaml.

Deployment configuration — docker-compose.yml, Caddyfile, .env.example — lives in deploy/. See deploy/README.md for VM prerequisites, required GitHub secrets, and rollback procedure.

To run the stack manually (e.g. on a fresh VM before CI is wired up):

cd deploy
cp .env.example .env  # fill in POSTGRES_PASSWORD, DJANGO_SECRET_KEY, YIVI_TOKEN, SENTRY_DSN
docker compose up -d

🔧 Configuration

Specific configuration is managed through Django Constance for runtime settings:

  • General: Footer text, cleaning scheme URL
  • Email: Notification recipients for reservations
  • Shifts: Default maximum orders per shift
  • Music (Thaliedje): Start/stop times, holiday mode
  • Silvasoft: API credentials for bookkeeping
  • Fridges: Daily opening requirements

📡 API

TOSTI provides a RESTful API with OAuth2 authentication.

Available Scopes

  • read: Read access to the API
  • write: Write access to the API
  • orders:order: Place orders
  • orders:manage: Manage all orders
  • thaliedje:request: Request songs
  • thaliedje:manage: Control music players
  • transactions:write: Create transactions

API Documentation

Interactive API documentation is available at /api/docs when running the application.

🧪 Testing

Run the test suite:

cd website
uv run python manage.py test

Run with coverage:

uv run coverage run website/manage.py test website/
uv run coverage report

🔍 Code Quality

Linting

uv run black website
uv run flake8 website
uv run pydocstyle website

Checks

The project uses GitHub Actions for automated testing and linting on every push.

🤝 Contributing

Contributions are welcome!

Development Workflow

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Run tests and linting
  5. Submit a pull request

Code Style

  • Follow PEP 8
  • Use Black for formatting
  • Write docstrings for all functions
  • Maximum line length: 119 characters

📧 Contact

🔒 Security

For security vulnerabilities, please email www-tosti@science.ru.nl instead of creating a public issue.

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments

  • Original developers: Lars van Rhijn, Job Doesburg
  • All contributors who have helped improve TOSTI
    • CNCZ for hosting infrastructure