TUM Scheduler is an intelligent course scheduling tool designed to help students at the Technical University of Munich (TUM) create, optimize, and refine their semester plans with ease.
Leveraging GenAI, the tool offers personalized course recommendations, conflict-free scheduling, and an interactive planning experience tailored to user preferences, academic goals, and interests.
- Live Demo: https://nixops-devops25.student.k8s.aet.cit.tum.de/
- Statistics: https://stats.nixops-devops25.student.k8s.aet.cit.tum.de/
- Alerts: https://push.nixops-devops25.student.k8s.aet.cit.tum.de/alerts
- Dev Server: http://ec2-16-16-198-246.eu-north-1.compute.amazonaws.com
- Documentation: Wiki
- User facing interface for semester planning
- Chat interface using the genai service
- Calendar interface synced with the schedule-manager
- Tech Stack: React (or Next.js), Shadcn/ui, FullCalendar
- The core AI assistant service
- Queries local vector database with course embeddings
- Suggests courses in interactive dialogue
- Creates and manages schedules using the schedule-manager
- Manages longterm AI memory
- Tech Stack: Python, LangGraph, Milvus, Redis, OpenAI + Ollama
- The data ingestion service
- Fetches course data by combining different TUM APIs
- Establishes connection between study programs and courses
- Abstracts away most of the complexity of the TUM database system
- Offers a simple REST API
- Tech Stack: SpringBoot, Kotlin
- The bridge between the scraper and genai services
- Pulls data from the scraper and genai
- Determines which courses need to be embedded
- Sends data to genai and triggers a new embedding job
- Monitors the running embedding
- Tech Stack: SpringBoot, Kotlin
- The service responsible for managing users schedules
- Used by the genai service with tool-calls
- Supports creating and editing schedules
- Pulls course data from the scraper
- Creates schedules and associated appointments for the calendar in the client
- Tech Stack: SpringBoot, Kotlin
For ease of use we provide a docker compose file to run the application with prebuilt images. First clone the repository:
git clone https://github.com/AET-DevOps25/team-nixops
cd team-nixops
Then create a .env
files based on the provided .env.template
And then simply run it with docker compose:
docker-compose up -d
The client UI will be available at http://localhost:3030.
The genai Swagger UI will be available at http://localhost:8000/docs.
The scraper Swagger UI will be available at http://localhost:8080/swagger-ui/index.html.
The schedule-manager Swagger UI will be available at http://localhost:8042/swagger-ui/index.html.
Alternatively follow the setup instructions for a development environment
- Nix (including flakes)
- Docker & Docker Compose
If Nix is not already installed on your system you can do so using the Determinate Nix Installer:
curl -fsSL https://install.determinate.systems/nix | sh -s -- install
You can remove Nix installed by the Determinate Nix Installer by running:
/nix/nix-installer uninstall
First clone the repository:
git clone https://github.com/AET-DevOps25/team-nixops
cd team-nixops
All services can be build with nix:
nix build .#client
nix build .#genai
nix build .#scraper
nix build .#embedding-bridge
nix build .#schedule-manager
All docker images can be built with nix:
nix build .#client.dockerImage -o client
nix build .#genai.dockerImage -o genai
nix build .#scraper.dockerImage -o scraper
nix build .#embedding-bridge.dockerImage -o embedding-bridge
nix build .#schedule-manager.dockerImage -o schedule-manager
These can then be loaded into docker using:
cat client | docker load
cat genai | docker load
cat scraper | docker load
cat embedding-bridge | docker load
cat schedule-manager | docker load
-
Running the client service:
The client service can be run with:nix run .#client
or for development with:
cd client npm run dev
The client UI will be available at http://localhost:3030.
-
Running the genai service:
The genai service needs some databases to be available. These can be started withdocker compose up -d -f genai/compose.yml
The genai service can then be run with:
nix run .#genai
or for development with:
cd genai uvicorn genai.app:app --host 0.0.0.0 --port 8000 --workers 4
-
Running the scraper service:
The genai service needs a postgres database to be available. This database can be started withdocker compose up -d -f scraper/docker-compose.yml
The scraper service can then be run with:
nix run .#scraper
or for development with:
cd scraper ./gradlew bootRun
-
Running the schedule-manager service:
The schedule-manager service can be run with:nix run .#schedule-manager
or for development with:
cd schedule-manager ./gradlew bootRun
-
Running the embedding-bridge service:
The embedding-bridge service can be run with:nix run .#embedding-bridge
or for development with:
cd embedding-bridge ./gradlew bootRun
Unit tests are automatically run during the nix build process.
Therefor all unit tests can be run using:
nix build .#client
nix build .#genai
nix build .#scraper
nix build .#embedding-bridge
nix build .#schedule-manager
Integration tests can be run using the following command:
nix flake check -L --option sandbox false --no-pure-eval
This will test all dev environments, packages, infrastructure configurations, and also run scripted tests in a VM.
The project includes GitHub Actions workflows for:
- Testing: All changes to services are tested automatically. Long integration tests are only run on
main
. - Linting: All OpenAPI and helm files are linted for correctness
- Building Docker Images: Automatically builds and pushes Docker images to GitHub Container Registry. Specifically,
latest
tracks themain
branch and versioned releases correspond to tagged commits. - Automatic Versioning: Commits that pass the CI are automatically tagged if any version is updated. Tags will have the format:
<name>@v<version>
. - Deploy Docker Images: Deploys the application to a production Kubernetes environment using helm and to a provisioned server on AWS using
podman-compose
.
All environments are provisioned with automated tools such as helm, nix and terraform to ensure that the system is reproducible with minimal MTTR from any state. Because these operations are critical and can have financial implications, these need to be performed by an admin.
Secrets: In reproducible environments it is not trivial to manage secrets as these a potentially revealed in public configuration files. To solve this we use sops — a way to store secrets that only get decrypted by authorized targets at runtime.
No decrypted secret gets written to persistent storage, ever!
The configuration that determines recipients for a secret it generated to improve maintainability.
Details can be found at the respective subfolders.
The project includes Git pre-commit hooks for:
- Formatting: All files are formatted with
nix fmt .
- Linting: All OpenAPI and helm files are linted for correctness
├── client
│ ├── src/ # source code
│ └── package.json # client dependencies
│
├── genai/
│ ├── compose.yml # docker compose for genai development
│ ├── src/ # source code
│ ├── pyproject.toml # genai dependencies
│ └── openapi.yml # genai openapi contract
│
├── scraper/
│ ├── docker-compose.yml # docker compose for scraper development
│ ├── src/ # source code
│ ├── build.gradle.kts # scraper dependencies
│ └── openapi.yaml # scraper openapi contract
│
├── embedding-bridge/
│ ├── src/ # source code
│ └── build.gradle.kts # embedding-bridge dependencies
│
├── schedule-manager/
│ ├── src/ # source code
│ ├── build.gradle.kts # schedule-manager dependencies
│ └── openapi.yaml # schedule-manager openapi contract
│
├── schedulingEngine/
│ ├── src/ # source code
│ └── build.gradle.kts # scheduling-engine dependencies
│
├── terraform/ # terraform code for custom kubernetes deployment
│ ├── admins
│ ├── hcloud
│ └── k8s
│
├── nix/
│ ├── checks/
│ ├── devShell # nix development environments
│ ├── modules/
│ ├── targets/
│ └── treefmt.nix # nix formatting setup
│
├── helm # helm deployment
│ ├── Chart.yaml
│ ├── templates/
│ │ ├── client/
│ │ ├── embedding-bridge/
│ │ ├── genai/
│ │ ├── ingress/
│ │ ├── monitoring/
│ │ ├── schedule-manager/
│ │ └── scraper/
│ ├── values.ci.yaml
│ └── values.yaml
│
├── docker-compose.yml
├── flake.lock
├── flake.nix
└── .github/workflows/ # CI/CD workflows
This project is licensed under the MIT License.