A recommendation system prototype for Computer Science education activities that leverages automated content processing and category-based scoring algorithms to support teachers in activity selection and lesson planning.
This system was developed as part of a Master's thesis at the Technical University of Munich, Chair of Applied Education Technologies. The architecture prioritises transparency and explainability, enabling teachers to understand how recommendations are generated rather than relying on opaque black-box algorithms.
LEARN-Hub addresses the challenge of finding appropriate educational activities for computer science courses by implementing an intelligent recommendation engine. The system processes educational activity documents, analyses their pedagogical characteristics, and generates personalised recommendations based on teacher requirements such as target age group, available resources, and learning objectives aligned with Bloom's Taxonomy.
The recommendation engine implements content-based filtering with category-based scoring, offering an explainable alternative to collaborative filtering approaches. Teachers receive detailed scoring breakdowns across age appropriateness, topic relevance, duration fit, Bloom alignment, and series cohesion, fostering agency and trust in the recommendation process.
The system implements a three-tier containerised web application architecture following the System Design Document approach:
Client Subsystem: A React single-page application provides an interactive user interface for teachers and administrators. The client implements role-based access control, supports both light and dark themes, and uses Spring Security session cookies with CSRF protection for authentication.
Server Subsystem: A Spring Boot REST API server orchestrates the core application logic through specialised internal systems. The Recommendation System encapsulates the algorithmic intelligence. The User System manages identity through user, history, and favourites services. The Document System oversees content ingestion via PDF processing, LLM-assisted metadata extraction and document generation, and optional PDF-to-DOCX conversion via Adobe PDF Services.
Data Layer: PostgreSQL serves as the primary data store, managing activities, user accounts, search history, and favourites. The database schema supports complex relationships between activities, topics, and user preferences whilst maintaining referential integrity.
Containerisation: Docker Compose orchestrates three containerised services on a single host, connected via an internal bridge network. The deployment includes health checks and dependency chains to ensure proper sequencing during startup.
The architecture addresses several key quality attributes:
- Transparency (QA3): Category-based scoring with detailed breakdowns enables teachers to understand recommendations
- Maintainability (QA7): Clear, explicit code with dependency injection favours clarity over convenience
- Performance (QA5, QA6): Two-stage scoring pipeline and hard filtering ensure sub-three-second response times
- Extensibility (QA1, QA8): Comprehensive OpenAPI documentation enables integration with external learning platforms
The docs/figures/ directory contains UML diagrams documenting the system architecture:
- Deployment Diagram (
docs/figures/final-lucid-deployment.svg): Container topology, volumes, and external service dependencies - Data Model (
docs/figures/final-lucid-data-model.svg): Persisted entities (Activity, Document, Markdown) and their enumerations (ActivityStatus,MarkdownType,DocumentType)
See docs/dev-setup.md for the full development setup guide.
Quick start:
# Start PostgreSQL
docker compose -f docker/compose.yml up postgres -d
# Run migrations
make db-migrate
# Start server and client
make devIf you run the Spring Boot server locally, install LibreOffice first so soffice is available for DOCX generation. On macOS:
brew install --cask libreofficeIf you run the full stack in Docker instead, the server image already includes LibreOffice.
Once running, access the system at:
- Client: http://localhost:3001
- Server API: http://localhost:5001
- API Documentation: http://localhost:5001/api/openapi/swagger
The application requires environment variables for API integrations, security keys, and database configuration:
cp example.env .envKey configuration variables:
DB_SEED_ENABLED- Settrueto seed the database (dataset or demo activities) and create an initial admin on first startupINITIAL_ADMIN_EMAIL/INITIAL_ADMIN_PASSWORD- Credentials for the seeded admin user (random password printed to logs if left blank)LLM_BASE_URL- Base URL of the OpenAI-compatible chat API (e.g. an Ollama or GPU cluster endpoint)LLM_API_KEY- API key for the text LLMLLM_MODEL_NAME- Chat model nameLLM_IMAGE_MODEL_NAME- Optional image model for generating exercise illustrations; reusesLLM_BASE_URL/LLM_API_KEYand is enabled once this is setADOBE_PDF_SERVICES_CLIENT_ID/ADOBE_PDF_SERVICES_CLIENT_SECRET- Optional Adobe PDF Services credentials for PDF-to-DOCX conversionSESSION_TIMEOUT- Optional override for server-side session lifetimeSESSION_COOKIE_MAX_AGE- Optional override for persistent login cookie lifetimeCLIENT_ALLOWED_ORIGINS- Optional override for cross-origin client URLsPOSTGRES_DB_URI- PostgreSQL JDBC connection stringPDF_PATH- Host path for PDF file storageDOCX_CACHE_PATH- Optional host path for caching converted DOCX filesEMAIL_*/SMTP_*- SMTP service configuration for teacher verification emails
See example.env for a complete list of configurable variables.
LEARN-Hub integrates with the following external services. All integrations are optional except where noted.
The server uses a text chat model (via Spring AI's OpenAI client) for:
- Extracting structured activity metadata from uploaded PDFs
- Generating Artikulationsschema, Deckblatt, Hintergrundwissen, Übung, and Lösungsblatt markdown documents
Configure any OpenAI-compatible endpoint (Ollama, GPU cluster, cloud API):
LLM_BASE_URL=https://gpu.aet.cit.tum.de/ollama/v1
LLM_API_KEY=<key>
LLM_MODEL_NAME=qwen3:30b-a3b
Note:
LLM_BASE_URLmust point at the OpenAI-compatible API root that directly serves/chat/completions- i.e. it must include the/v1segment (e.g.http://localhost:11434/v1). Spring AI 2.0 appends/chat/completionsto this value verbatim.
When configured, the server calls the image generation API to replace [[IMAGE_PLACEHOLDER: ...]] markers in generated exercise and Tafelbild documents with actual images. Without this, placeholders are left in the markdown as-is. The image model reuses the same LLM_BASE_URL and LLM_API_KEY as the chat model (Spring AI 2.0 shares one OpenAI client), so the configured endpoint must support image generation. It is enabled once LLM_IMAGE_MODEL_NAME is set:
LLM_IMAGE_MODEL_NAME=gpt-image-1
When configured, the server converts uploaded PDFs to DOCX via the Adobe PDF Services REST API (ExportPDF operation). This enables higher-fidelity source document preservation in the editor. Without credentials the server starts normally, but DOCX export endpoints return an error.
ADOBE_PDF_SERVICES_CLIENT_ID=<client-id>
ADOBE_PDF_SERVICES_CLIENT_SECRET=<client-secret>
Converted DOCX files are cached to avoid redundant API calls; the cache location defaults to /app/data/docx-cache and can be overridden with DOCX_CACHE_PATH.
Email delivery (teacher verification codes and credentials) uses an SMTP server with STARTTLS on port 587:
SMTP_SERVER=postout.lrz.de
SMTP_PORT=587
EMAIL_USERNAME=<username>
EMAIL_PASSWORD=<password>
EMAIL_ADDRESS=<from-address>
User Documentation: https://ls1intum.github.io/LEARN-Hub/
Developer Documentation is organised in the docs/ directory by architectural layer:
docs/dev-setup.md- Quick local development setup guide
docs/core/recommendation-engine.md- Recommendation algorithm design, scoring methodology, and architectural decisions
docs/server/server-architecture.md- Server architecture and design patternsdocs/server/api.md- REST API endpoints and data modelsdocs/server/server-cicd.md- Development workflow and deployment procedures
docs/client/client-architecture.md- Client architecture and component designdocs/client/api-integration.md- Client-server integration patternsdocs/client/client-cicd.md- Build system and deployment
Server:
- Java 21 with Spring Boot 3.4.1
- Spring Data JPA with Hibernate ORM
- Flyway for database migrations
- PostgreSQL 17+ for relational data persistence
- Spring AI with OpenAI-compatible API for LLM integration
- Spring Security with server-side session authentication
- Maven for dependency management
Client:
- React 19 with TypeScript for type safety
- Vite for rapid build tooling with hot module replacement
- Tailwind CSS for utility-first styling
- shadcn/ui for accessible interface elements
- Nginx for production serving and API proxying
Infrastructure:
- Docker for containerisation with multi-stage builds
- Docker Compose for container orchestration
- GitHub Container Registry for image distribution
Development Tools:
- Maven for Java dependency management
- JUnit for server testing
- Vitest for client testing
- LibreOffice for server-side DOCX generation in local development
cd server/
make dev # Start development server
make test # Run tests
make build # Build the application
make db-migrate # Run Flyway migrationscd client/
npm run dev # Start development server
npm run test:run # Run tests
npm run build # Build for production
npm run lint # Check code quality