ℹ️ How this works
Data sources (Sisu/Kori — in app today)
| University | Access |
|---|---|
| Tampere (TUNI) | GET /kori/api/course-unit-search + course detail |
| University of Helsinki | GET /kori/api/course-unit-search + course detail |
| Aalto University | GET /kori/api/course-unit-search + course detail |
| University of Jyväskylä | GET /kori/api/course-unit-search + course detail |
| LUT University | GET /kori/api/course-unit-search + course detail |
Not in app yet (Peppi API pending): Turku, Oulu, Eastern Finland — see docs/peppi-research.md.
Pipeline
- Scrape — Tier A (broad) + Tier B (gen-AI) search terms; merge IDs; fetch details
- Keyword filter — regex on course text (Finnish + English gen-AI terms)
- AI filter — gpt-4.1-mini evaluates the full scraped pool; returns
relevant,reason, and skillclusters
Azure OpenAI
Set AZURE_OPENAI_API_KEY, AZURE_OPENAI_ENDPOINT (OpenAI-compatible /openai/v1 base URL), and AZURE_OPENAI_DEPLOYMENT. Credentials are not stored in the UI or logged.
Caching & logs
Data directory: /app/cache/ (CACHE_DIR on Azure). Scrape cache: {uni}_raw.json; AI cache: ai_eval_cache.json. Logs: logs/benchmark.log (rotating). Clear scrape vs AI cache separately in the sidebar. See docs/storage.md.
Limitations
Results are indicative, not comprehensive: scraping uses public API search terms and detail fetches (not authenticated bulk exports), and generative-AI relevance is inferred by regex plus an AI model. Treat counts as a lower bound with possible false positives.
Downloaded PDF reports may not display correctly in Firefox’s built-in viewer (blank or black pages). Use Chrome, Edge, or Adobe Reader instead.