Learning - Releases

← App details

Nextcloud 33

Learning 4.0.0
Release Details
UpdatedApril 3, 2026, 5:59 p.m.
Changelog

Breaking Changes

  • Requires Nextcloud 33+: The frontend runtime now targets the current Vue-3-compatible Nextcloud stack and drops NC 29-31.
  • Frontend Runtime Upgrade: Vue 2.7, @nextcloud/vue@8, vue-router@3, and Pinia 2 are replaced by their Vue-3-compatible counterparts.

Changed

  • Bootstrap Migration: Main app, admin settings, personal settings, privacy page, and imprint page now mount via createApp() with vue-router@4 and Pinia 3.
  • Build Stack Modernized: Frontend bundling moved from webpack to Vite with five classic Nextcloud-compatible entry bundles and explicit per-entry stylesheet loading in templates.
  • Nextcloud UI Imports Updated: Components now import from @nextcloud/vue/components/*, aligning the app with @nextcloud/vue@9.

Fixed

  • Vue 3 Compatibility Cleanup: Removed legacy this.$set / this.$delete, .native, .sync, $listeners, and renamed old lifecycle hooks (beforeDestroy / destroyed) to Vue-3 equivalents.
  • Template Parser Compliance: template v-for keys were moved to fragment roots, avoiding Vue-3 SFC compiler failures in calculator and context UIs.
  • Transition Semantics: Onboarding and VirtuProf transition classes were updated from old *-enter rules to Vue-3-compatible *-enter-from variants.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureuKpZyG3/E4EekkSul9Kig8uryzXS/0Sjt6KEWa9H2pm4ZkgpNGo6DRpq9DbdwVxMdg05FQNrVyu6ctDgtDwHci1AhaDDac0rc934k2JaAy4UTfugkPoBxPPnwVkAuAOn6pLfmSYJ4SIk5dB4vUHvsmaHpVtUpgtJOWcanPm35NsHIp2pZNds8hHmV/5T18IVWLBAq4o4AGyq2gNxGYgWnYBTJ3nHVhvcaEyRjZzUBcOByGsB02aEyq/o2z7/EmXPPWoRy2c9YatnzXe5kcnD0NBxAT3UhS3EZ1I7D7s2vLCx+HPaRwjdnWf7kIXD2+744wbc3967wqDZUstqTZR1/8xkgve01BFczjpXV9DDu8NlIpB9ITo6TBrRyXO2mZOOfjNvA0Jd9PP8mNZeXX/paKXxSFk0FdScJpqwrDj6frVvvEzySAeq137aoF9UDSYvBQiio6lOLz/MKpaRntLy0sXXL4pj+kfQVBWRynL+uHdAetzTURkf7K7uZDFUnSk0g0hL30ETeuNLw1TMgefSQn/Xvaar0gEfttsdkpkr4juEtzGoBEeET7iAEY09NnOZYfKGW2W+eGqRoPf73BNj7wMnXUT0nOG6pfMIYXCkgAu9NQVXKr+B2CnjvPn5GFc9Cu421WL8Q+Q9jh6jm/YZEuDTHqKHLxVa5UCgWMMGIIw=
Signature digestsha512
Dependencies
Required Nextcloud versions >=33.0.0,<36.0.0
Minimum Integer bits32
PHP>=8.1.0

Nextcloud 31

Learning 3.6.0
Release Details
UpdatedMarch 30, 2026, 4:56 a.m.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignaturejQ1Xdi636ODYsfoC8Sr3MU9s6K0a/PIOZvbo0ea4D/TpW/NiVKu49cZC8JLt8oFbyp2qVI27LVBXEplSF6V004H1NMqHdnC3zhqEbs/BzRH9CIKZW7Ouzs2Qj7obBiBiszYtamVpxRvxt3bfCiIfac9mn6yMJ2OvsqDohraIT5Mh84kyuW4ibPVun/8hX2/qndkvsQQvKnO+GL8UHRV1UhiSG/ezTdjZbinc0ZVU06oWXJFuP2YXpFPc+GHG8RMBP6N3KeqmK+rMZ6lKaZY5fl//pnr8AbASDKYK0MjWQFsqLrei9R/iQbsHqjlT3vT5o0Sssrw0m++5ysCJhTb0uEPgeLvg4DUOige/iCegy+NZFb+qgb7oezetZD8s/aWxZTR645y1MZS4va5kgdAVreT0rvHDDZvx9UuKr4smMvAxX1DEUKgzqP/AMellHcwb4BVE9pVwOENp5oKttpoJXKoH/Lnwu+o+1o5m4+JH/SHHGJBCmXYeehFscARZceC9lNYsBTHL+uKILOszxJXK0OkwrFCVCGTnXFfO0hn23gwjECPGP/zwB8OwlwedZXjaZkAMomIulAxghFIw5arSOoX85kv7bOlwerVJ7jfHs8GYIqBn3b+bWzVn5MQEumuUiKBi01WH7vbjn5Neuxi7YfSBkjJjeQFOFlGEmwFwcrs=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 3.4.0
Release Details
UpdatedMarch 28, 2026, 5:03 p.m.
Changelog

Changed — UX-Navigation Struktur

  • Instructor Tab Groups: 17 instructor tabs organized into 5 logical groups (Lernraum, Teilnehmer, Kommunikation, Wettbewerb, Verwaltung) with visual separators.
  • Abenteuer Standalone: Adventure mode promoted from Arena sub-mode to its own CourseDetail tab, independently gatable via mode_config.
  • Arena Submode Gating: Each Arena mode (Duel, Gameshow, Oldschool) individually hideable per course rules. Arena tab disappears when all sub-modes disabled.

Changed — Code-Hygiene & Settings

  • Settings Split: Instructors now see two sub-tabs in Settings: "Kurs-Verwaltung" (admin) and "Meine Einstellungen" (personal). Students see only personal settings.
  • Zeitreise Removed: Removed 1270+ lines of dead Zeitreise/HackThroughTime frontend code (component, characters, navigation, mode_config key).
  • German Labels: All UI-visible labels now go through t() translation. ModeIdentityBanner labels localized.

Added — Simulator-Praxis-Sessions

  • Practicum Engine: Pure-JS state machine for guided session management with localStorage persistence and browser-reload recovery.
  • 11 Practicum Sessions: Real-world IT scenarios across all 7 simulators (42 steps total). Firewall, DNS, and Routing get 2 sessions each.
  • PracticumRunner UI: New "Praxis" tab in every simulator with step-by-step instructions, context explanations, progress bar ("Schritt X von Y"), and score summary.

Added — Student Dashboard

  • Heute Screen: New default landing page for students with SmartQueue widget (due cards count + "Jetzt lernen"), Daily Challenge card, streak display, and daily progress.
  • Global Feed: Aggregates announcements from all enrolled courses chronologically with course-name badges and pagination.
  • Pools Navigation: Direct "Pools" tab in student main navigation — one click to PoolList.

Added — DevCloud Integration & Leitner

  • Talk Room Link: Instructors can set a Talk room token per course. Clickable link appears in course header, opens NC Talk in new tab.
  • Materials for Students: Students now see the Materialien tab (read-only) when a course has a material folder set.
  • Buddy Matching: New "Lernpartner" tab shows who can help with your topics and whom you can help, based on Telos help_offer/help_wanted data.
  • Course-Aware Tools: Werkzeuge tab filters simulators based on active course's enabled_tools. No course active = all tools visible.
  • Sprint Intervals: Instructors can activate sprint mode per course (4h/12h/1d/2d instead of 1d/3d/7d/14d Leitner intervals) for intensive courses.

Fixed

  • Badge Duplicate Crash: Session completion no longer fails with 400 when badge already exists. Fixed catch to use OCP\DB\Exception (NC 30 wraps Doctrine exceptions).
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
Signaturely5UiDEZdUJh6uSRREEijl3s87EIDnAeze3Y9KBfIECnaFvdafIwluTTl1XeyEvAaGshOHIXMmtfVvnYA9dMLyIj+jKvSeWlFKgbTsMS7hRvCiuqGcoFBPuOm8rDzIk6AXTGieQFgNIho9p68tRzQ2MF1mFJ/qnd3ayGiasJtT7W7rbUQYNAtzL3n4CpmxVZi4msMamM+K7c0O7e6/pmQJ3HCmtpjurPs8MJzAJQf5dyTQQuDa44T9aOSi4ucDAnS+aETU20UH0C8HWU15un+T0FeIP8//J8VxHFkP4g6BzrHF9mA52QKgUnUTkxYcH1qVhL7TcKjvfGScG3MjnSV92hvpVlEDZhMNAGkCwORAPMG22r4moEOmLse0r4/tMkSZ/4InV5kc3NYmZFzigT3yBnZGmsTxyvVb1PdAGi0uNhIvS2Ay8nq6tARMz1lFMv3iz8y9MmwSwIsyMGIUq5xWG49/Fj9rqB6HvEj7lmojVhuGm4eBEiJ6dnuyu91l1O5sML68xbiaHk1lv+Q4Qy6THYKX5MKFcCTbFxfs+4acZRgquRLpLFDGkXtpJMs4XMjSCygcdKQy2bk6TSnncyhPFUiMCDkhavR/QICmtQw/RBJatqdf9+f6LT87zhA4g2jO9XXq6EcoaSTn0k7aS3eghXGRHumpYSNCDMXxuPnjI=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 3.0.0
Release Details
UpdatedMarch 24, 2026, 6:55 a.m.
Changelog

Added — Story RPG "Abenteuer" Mode

  • Story Engine: Full campaign-based RPG learning mode with branching narratives, skill checks, and character classes (Architect, Security, SysAdmin, Helpdesk). 20 campaigns across CompTIA Network+, Security+, CySA+, Linux+, and A+.
  • KI-Erzähler: Gemini-powered dynamic narrator with freetext player actions, NPC dialog generation, and role-based prompts. Fallback to static text when AI unavailable.
  • Skill Checks: In-story quiz phases with 3 questions per check, batch submission, pass/fail branching to different scenes.
  • 20 Campaigns: Real-world IT incident scenarios — SolarWinds, WannaCry, Log4Shell, Colonial Pipeline, Equifax, plus 6 Security+ exam-oriented campaigns (Phishing, Zero Trust, Crypto, Compliance, IR, Cloud) and an AI Security campaign.
  • Coop Mode: Infrastructure for multiplayer campaign sessions (UI placeholder, backend ready).

Added — "Zeitreise" Hack Through Time

  • 7 Epoch Campaign System: Phone Phreaking (1960s), WarGames (1980s), The Worm (1990s), Bobby Tables (2000s), Shadow Brokers (2010s), Supply Chain (2020s), Quantum Dawn (Future).
  • Period-Accurate CSS Themes: Each epoch has its own visual theme (terminal-green, amber-on-black, retro-web, etc.).
  • CHRONOS Guide: AI narrator character that guides players through hacking history.
  • Museum Facts: Historical sidebars with real dates, events, and technical details.
  • Character Classes: Epoch-specific roles (Phreaker, Hacker, Script Kiddie, Analyst, etc.).

Added — Visual Identity System

  • Design Tokens: CSS custom property layer (--lnc-*) with dark/light scopes and motion utilities.
  • 13 Character Registry: SVG silhouette avatars with emotion states (idle, celebrate, alert) for all NPCs.
  • Campaign Intro Animation: Full-screen intro with title, difficulty badge, and character reveal.
  • Dialogue Stage: NPC dialog component with portrait, speech bubble, and emotion tags.
  • Paper & Circuits Narrative Skin: Dark theme for adventure mode with subtle circuit-board patterns.

Added — RAG & Document Intelligence (v4.1)

  • Document Upload & Extraction: Instructors can link Nextcloud folders as course material, scan for files, and extract text from PDF/Markdown.
  • Chunking Pipeline: Automatic text chunking with keyword extraction for semantic search.
  • Multi-Source RAG Context: VirtuProf answers now cite course materials with [Quelle: filename, Kap. X] format.
  • 4000-Token Budget: Smart context window management prioritizing relevant chunks.

Added — Oldschool Board Games (v5.0)

  • Lernwürfel: "Mensch ärgere dich nicht" inspired board game with dice rolls and question challenges.
  • Wissensturm: Trivial Pursuit tower game with category-based progression.

Added — Personal Learning Bot (v4.0)

  • GeminiService: 5-layer security stack (API key isolation, input sanitization, output filtering, rate limiting, audit logging).
  • VirtuProf Chat: AI-powered learning assistant with chat-first UI, language auto-detection, and chat memory.
  • Note Generator: Gemini-based topic summaries saved to Nextcloud Files.
  • Lernprofil: Passive user learning profile with weekly study plan generation.
  • Auto-Triggers: Exam auto-notes, wrong-answer threshold alerts, weekly plan background job.
  • Ticket Triage: AI-powered support ticket classification and draft FAQ responses.
  • AI Consent: Opt-in consent overlay before first AI interaction, GDPR-compliant.

Added — Tools

  • Subnet Calculator: Browser-based IPv4 subnet calculator with CIDR/mask input, binary display, and VLSM planner.
  • Subnetting Question Pool: 50+ subnet calculation practice questions.

Added — Quality & Testing

  • ESLint: Vue/JS linting with no-v-html error rule, 0 errors enforced.
  • Pre-Push Hook: 4-gate quality check (Security scan, ESLint, Vitest 67 tests, PHPStan Level 5).
  • Playwright Browser Tests: 67 automated checks covering navigation, campaigns, time travel, tools, VirtuProf, security. 52 PASS / 11 FAIL / 4 SKIP.
  • PHPUnit: 12 service-level unit tests (Training, Leitner, Analytics, Course).
  • Test Strategy: 4-gate pyramid documented in CLAUDE.md.

Fixed

  • Campaign skill-checks now always use pre-loaded questions from scene response (no separate API call).
  • Campaign start always creates fresh session (no stale resume from previous play).
  • Missing Abenteuer/Oldschool/Zeitreise toggles in course mode settings.
  • WannaCry campaign: corrected from email dropper to SMB worm narrative.
  • PBQ subtype auto-detection from config structure when pbq_subtype not set.
  • Empty skill-check pools handled gracefully (skip to next scene instead of crash).
  • Narrative garbage fallback when Gemini returns malformed text.
  • AI rate-limits on VirtuProf available()/status() endpoints.
  • ESLint: empty catch blocks, v-if with v-for separation, escaped quotes in templates.

Security

  • Gemini language mirroring prevention (no prompt echo).
  • Story mode injection guards on freetext actions.
  • Story mode rate-limits (10 starts/min, 60 scenes/min).
  • Pre-push security scan for hardcoded secrets.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureMWUO0JmVVcGH0NNuBs36k/SJ6luN5fkUQPaxu+CxY+5FdW/X4uAAD6NgGuM/jQsqSyKsns4V1UgbtV15xhOlHyO8/fOrnIeU1tifv52U+Sud8OdnMeCy9eQ8TmbbZwrsxT7er+1hmRgrJPC+b1++4bWDE57D6tJ85xAeJ4TeNMkSQDAy8PGI7PnhG1ae0Xx4DAXAjIm6+GZqeletoRknfiLPpLyUcF2EMOqOxdWjXhDVEGhXMLgPUcJnLPi6avTjN/CCEK1awEzVr4IhaUUI86Dub/68KQmeOFZRusIARkqmY5Bq0ER9xzcWKf26pyl10xr1GJUh2sQB+Utw3cszgq6VPS8KdsVJ3a15+uqdinFxo8QHhJz409tF9RdQnqye+0WJ2qa4d4PbndPeAiAcu3z27tlmVDmwouvxrYco4wDgUSIW3lzayLjR8IiONHylfIZ56idwu/EAYEU2u9/0oKVDeGi+Izt6z4/aX9iTjuV29T1uB1e2aasUIWyRttCFBZ01PIaJqMfubHMvRmDrcjb9U4OKUTqLg58u29eeQMimHB9O3ij0n6zQn2MJdxnnahO5seMg5tuLwRETHbcxQ0yNLskSLvSDgIa8vBr/leUgUtBPUCbIx4msuV3Tuy7HpA9Lg+3C7ZkqOIne6k0vakIc4KPjAPL/SLBwZusxfDI=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 2.6.0
Release Details
UpdatedMarch 17, 2026, 5:58 p.m.
Changelog

Added

  • Calendar Token: Per-user ICS subscription token for external calendar apps. GET /api/v1/user/calendar-token returns token + subscription URL. POST /api/v1/user/calendar-token/regenerate invalidates old token. Token stored in NC preferences (never expires until regenerated).
  • Public ICS Feed: GET /api/v1/calendar/{token}.ics — unauthenticated ICS endpoint for calendar subscriptions. Uses token-to-user reverse lookup via oc_preferences.
  • Calendar Sync in Personal Settings: ICS URL field with one-click copy and regenerate button.
  • ICS UID domain fix: UID fields now use actual NC hostname (parse_url(getBaseUrl(), PHP_URL_HOST)) instead of literal @nextcloud.
  • AI Explain button: POST /api/ai/explain schedules a text2text task explaining why an answer is correct/incorrect. "💡 Explain this" button appears after answering in LeitnerMode and TrainingMode (only shown when AI is available).
  • At-Risk CSV Export: GET /api/courses/{courseId}/at-risk/export/csv — downloads at-risk student list as CSV (Name, Risk Level, Risk Reasons, Accuracy, Last Active). Export button in course progress tab.
  • Batch Pool Assignment: Add-pool modal in CourseDetail now supports multi-select (checkboxes) — select multiple pools and add them all with one click.

Changed

  • ExportController: Replaced anonymous class with DataDownloadResponse for ICS response (cleaner code, no custom render() override needed). ICS body extracted to buildIcsBody() — shared by authenticated and token-based endpoints.
  • AIService::getTaskStatus() now includes output (raw text) in status response alongside questions array — needed for explain results.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignaturegpWcIhT4IeeSqVyKoOjXGch+flHYM9TICkDbyl7oRxuCOBH6sfYOwu5upyqwzGKl05TIRX2bqIrJiNj+ULif8rORhf3hvt03mhVuDCU1RuH9AbsD9VNvyw5Rf69FDXWD/44jH4JBjQHhD0E9MoY/Kud6Cog6W7SmIXEmGlHNz7mbopa2OoZZws6AA+SwjkDvK9BbvDrae3brEkSc2udTdi2HqSa8tbKPouwE3vdEdHWJWF3/j7P+4GM5cDXIT0B4g9eyL8r8Q1AKO0Xu/1pGPddNmeDz4gK4cQFGJF1KhhgAMEA7EM9/7wkMW6hrONfD57PJywCdeJhMTGVgGbjzLRreJ57GuI4jPhjqumOsiXRS3Evyn5LmO/q7FXn54hl1VBZBb7Kdj/t46wZzeV+vkKP/TFu2a/Amr99KFDWnNhKaF0eg/xYBAyGdNE162L7lHjXUlu5o6d1iO8i8y1NQoexyta7cqo019m4/BjhAr1QWAo5QsFJQ6hD7t8oA6Es50yFIi39Vzn2vFrkNuoUkrGtUNUH5mxEoDTCaHeLKBokStXztfaXsZzRBsi7Eem70Hqh65PQ4GAA7/BIKksrGR9XXRbbQG6ZBa1NN2iZaPDNF6t+zbq9EcfpITq7aLOthuU2OEkW4zm2Ds6wrxE+gFU+fxCePWR5H7g3OJuOcwjk=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 2.5.0
Release Details
UpdatedMarch 16, 2026, 8:57 a.m.
Changelog

Added

  • Daily missions: mission progress model plus claim endpoint (GET /api/v1/missions, POST /api/v1/missions/{missionKey}/claim).
  • Mission XP claims table: Migration Version002000 adds learning_user_mission_claims with one-claim-per-mission-per-day guarantee.
  • Streak freeze tokens: weekly reset token support in streak calculation (streak_freeze_tokens, last_freeze_reset_week in learning_user_stats).
  • Badge tiers: new bronze/silver/gold/platinum tiers for session count, mastery count, and streak milestones.
  • Analytics UI updates: Daily mission cards with claim action and freeze-token visibility.

Changed

  • Streak handling: streak computation can bridge one missed day when freeze token is available; token is consumed on activity-side calls.
  • App version: bumped to 2.5.0.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureBtgrr+hdTfM0f4h9yPsjjpUL18GMWeoMLCyfuSk+f0aj+R2D8WpUaWos8YBBAdFtoTYGKeykyLd+Ww/8ckGusCAhrB8BiV2IDSKhna3EreyedyjQ7tI9KXrif6dvkN/8FQB3JsWSXyLujapZYGX0lsvVxwf6rzmLIsOhC5gAGD+aCHwsZDxzi2bWVr3iyMaQq1rqd7HxGMUZq6E67lRr2bKCXTK46QEX1TnGw/jtv7gMg5Kq0pG39oRgOTtpjNc/0VJR/KUw4PujcVYMaOyLOlJlNjN0bZjgsgyijcACSi5L3gF8/M7yKvHFwZK/MKaWozRsTu1fJBtvrblhCBeJvoAGanAW+1gCE4SyNzClU/ToY/utQGJWUFNhARuMHjmqkAiFjfoev57XvvKIlC3mBF9U8oRIL9uQY+O6D1d1oynxvyVLvCmMOzw36xzHcEr7Hygu6PJUEOS79QkROIBiivsT91fAgRyFnStnbrM+0Az8Jiyis1mRU3lzOOSEIomZoapMevwMgngBQUwfUPDeQysmaz5DdpmDNW6oHbjV8WwIItNkK2sZm4VoDMud+PyGbLBIG/3HBjQVS1Hrhc4cjpoBgVLASsIVh6qIzQAsJnpagFsxxAm9azNMiNm1vgvcqRUnVStk0hi4B4pO3pr76/K/h3m7Y7MJDu0n736r4Ww=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 2.2.0
Release Details
UpdatedMarch 10, 2026, 11:40 a.m.
Changelog

Fixed

  • Course Pool Access: Course members and instructors can now access pools assigned to their courses. Previously only pool owners and explicitly shared users had access, causing "Pool not found" errors for enrolled students.

Changed

  • PoolService: Extracted findPoolRow() helper, added hasCoursePoolAccess() fallback in find() method
  • 5 Services updated: LeitnerService, PoolService, QuestionService, TrainingService, TranslationService — all hasPoolAccess() methods now check course membership as a third access path

Technical

  • 5 changed files, 165 insertions, 12 deletions
  • No database migration needed — uses existing learning_course_pools and learning_course_members tables
  • Course pool access grants read-only permission (permission: 'read')
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureFBngcENmOE/Ve20qo9FeQJkBZjOrpUJTFGqEhPB/hOp0PGIfvsZVFJylcJKnv59uVAjcElJIo3wtL5tG9b2sz0PtW60Fz24pb4NLxMewiUPNxKvBX7C7wcKNpf+H1nk3i/aGYPOiTZd6YTtMut1bDQ9zFdlXVxWjUCMAEZFJxMo0TG2IGD+bB+r2NGyh0okA2DN7+FVhCuRg/jF32BMFTtXD1X3qvmc2cQ6ls3F3hnDMrmpifXb2wzCAfAfBUyYoVCbwWyRL5Ig4iTZlk/TB5GmiPl2lncIGB3cMu8Ad0cJz26Ch+TMdbaSJdRtDCxQvCr9EwsL4mWR2BvsTqMUdybDA2C2aqPfRVjBg6oyP45C6z8KgE2XsMxzyzOI+E6leQ80nmmgBDx63+Yns4nXyAbFVegYan+8mQGm7PLDO3gtdossWxTiB3tptBTTljdSM3v+eHkncaTmIl/o1BOtMdznuhCHFUatKW1Bt+cDNBZg6gweghbJmBXfj9sFyqL/L+nZodDqXO5avLstGJoC0p7S5TmTM2L75kjKJxJe1IRMQUUldzH17NxDPeFP5bcPNZbPrujsFhjKNXFGzv2knPfZoV4oIGPbMQ+FNTWOn0jU6yik2o6sHsSMZfMMvr/MLwGdamYHOSbQba5FKE6FJh7LljZ1vaJqhwRAR08JFptE=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 2.1.0
Release Details
UpdatedFeb. 26, 2026, 3:56 p.m.
Changelog

Added

  • Free Text Questions: New open question type — users type free-text answers instead of selecting from choices. Fuzzy matching (case-insensitive, Levenshtein distance ≤2 for short answers, substring matching for long answers)
  • CSV/JSON Export: Download question pools as CSV or JSON files. Roundtrip-compatible with import — export then re-import produces identical questions
  • ExportController.php: New controller with exportCsv() and exportJson() endpoints, DataDownloadResponse for browser download
  • XP Streak Multipliers: Tier-based XP bonuses replace old linear formula — 1.5x at 3-day streak, 2x at 7-day, 3x at 30-day streak
  • XP Multiplier Badge: Visible multiplier indicator (1.5x / 2x / 3x) in Pool List when streak bonus is active
  • Open Question Import: CSV format question,model_answer,open and JSON "type": "open" with single model answer
  • Open Question in all modes: Training, Leitner, Smart Queue, Exam (textarea + batch submit), Daily Challenge — SwipeMode filters out open questions

Changed

  • XpService: getStreakMultiplier() and applyMultiplier() replace linear 1.0 + (streak * 0.01) formula
  • LeitnerService: All XP awards (correct answer, mastery bonus, daily goal) now use streak multiplier via XpService
  • UserStateController: state() response includes xp_multiplier field; answerChallenge() applies streak multiplier to challenge XP
  • QuestionForm.vue: New "Free text" answer type option with model answer textarea
  • QuestionList.vue: "Freitext" badge for open questions, model answer display, Export CSV/JSON dropdown
  • ImportDialog.vue: Help text updated with open-question format examples for both CSV and JSON
  • SwipeMode.vue: Filters out open questions (not compatible with swipe/tap interaction)
  • routes.php: 2 new export routes (71 total)

Technical

  • 1 new file (ExportController.php), 22 changed files
  • No database migration needed — question_type VARCHAR(20) already supports open, answer_ids TEXT stores JSON
  • QuestionService::isOpenAnswerCorrect() static helper used by TrainingService, LeitnerService, and UserStateController
  • Rate limit on export endpoints: 10 requests per 60 seconds
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureHyyUtHF7C32M+YZc15dn2kRI/DltaewXzt5Im3Zu3rPS12Q+ICmOK+AhT/TicLBFR3Zr21BjtyhcjcrFf5JmXIG9c65OEEyK2ApbXAa5HfFFhUbPIAjj+z2eG3F2+71DrFluPVg5imtKCJ1+zmZfNC3EFI+UFhUFPGor76KTJphQrT01qMaD21XuWlbr59lOI3PLuV+qENWBC2pvQMcBDTyfDEpanPR/NRZ9I31TqA5qj9d6su9UYxW0AO/21Dz6cTvUx6AeJksLyRjQsGEMZhvp5Lv3k3X4fiBp4q6j/VKtt/R89eCbNAjEcubZwYsAx6TA6gK1FtfOwO++7pU4EPzDlKFTBUpqoXJFvelF+SRg5h5oNJYU4zoJRCRV7IOIwliR//2G4Rh5bKenEELEhJ47l8lHfdw2vAkY1zMcOFRoTmda27VPD4W+uOBnd+7sXUSlPLCPRZYmZTMuFehgnPvLM8jN7e57ldBnzYw2AfSkS8vFmsIiT/TqhUknc7kFUAMD3Cz0PmofWWM+CbglCnD/HURBJW6FYX8dnA7fJhkyi7wSeC9nFc9TAU3jlVRiL/RA/wAmlxP2ZXJUk4JpuzxsdAwuBXkDRgnrmjnz31WdiqAI9f8HOPh9vc9ttbbMXP35llqMTa3T9NfnMZR0pkY0SKXcmSbAK3IHsv4dPI0=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 2.0.0
Release Details
UpdatedFeb. 26, 2026, 11:35 a.m.
Changelog

Added

  • Role-Based Navigation: Students start at Courses view (no Pools tab), instructors keep both tabs. App title simplified to "Lernen" for students
  • Onboarding Hint System: 7 dismissible info cards (localStorage-based) explaining Smart Queue, Leitner boxes, Daily Goal, Daily Challenge, and welcome messages for both roles
  • hintMixin.js: Reusable Vue mixin for localStorage-backed hint dismiss/check across all components
  • Mode Descriptions: One-line explanation shown below the active mode selector (Training, Leitner, Wahr/Falsch, Exam, Stats, Manage)
  • Pool-from-Course Navigation: "Back to Course" button when opening a pool from course context (instead of losing context by switching to Pools view)

Changed

  • App.vue: Mode selector filtered by role — students see only Train/Leitner/Wahr-Falsch/Exam (no Stats, no Manage)
  • PoolList.vue: Create Pool button, Share/Edit/Delete actions hidden for students. Better empty state text
  • CourseList.vue: Student empty state now explains that the instructor enrolls them
  • LeitnerMode.vue: Box labels improved — "Neu — taeglich wiederholen", "Lernphase — nach 1 Tag", "Bekannt — nach 3 Tagen", "Gut — nach 7 Tagen", "Gemeistert — nach 14 Tagen"
  • SmartQueue.vue: Better empty state ("Open a pool and start the Leitner system"), ready state shows priority sorting info
  • PoolList.vue: "Jetzt Lernen" → "Start learning", "Trouble Spots" → "Trouble spots" (consistency)
  • de.json: ~60 new German translation keys for all hints, mode descriptions, empty states, and v1.8/v1.9 UI strings
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureX22wHYsHapYtxGW+/4w3wuihpu0uy3Mi5x076ajJx5VbizQVWSF8uURw2bu+y/pQn4GZxinHK/JxHWqcCdU86MB3ThayzDX7ySTGx/z016eudjyAYAYGPx84KJ+ciGXFFiiS+QA7ebnPjnm/8O365ve4tVtv+7EqjHzOwntJnlT+GL9FAYiUS1z5UzFSuI02nNz3GXc3PG1NeWf3M1iAG9Q26zjv3n4q0mV1/GstjWvuJ5bAH/C8eNWtumTPjDq0/sBza15+DPzBtTuSDanieXSPi+EG2geKozRNe7fWBCWflVScnK38+9ke0vQsC+cgNMgsS+t9Qquv1IHQqbQLzEpFRq88LcWfar9VH0YFG9E1FaX2XrbF+59lZdM39NvwLrOCIfJFt7Qpnv/9Zkv4voezhaST8lKLI7FC/jCNhDcN6IpLPj3a8VuYsyMfu2vq3A1VDAyq7qb7T0l7T/FTRVQG2DlxZLnRMSMsQgFHmbiP2/5S553/N9JErAgrY85op8ucOCv83ysvUOYLVNtXHbPq9YyH+7GXDK0OsIvIfoK+gsaj/qcBt2x88FH1SlpY0VLDkZ7huBC21rvKTV0lT3sXyNo0H2HKPGR14Xm8DsN5GCIaljf0ErOJRfsxX9nUpDqU5aqWk8ABK+kyTldmwViOizIzc0uMMdeu0G7bUWE=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 1.9.0
Release Details
UpdatedFeb. 26, 2026, 9:25 a.m.
Changelog

Added

  • AI Question Generator: Paste text (lecture notes, textbook excerpts) and let AI generate multiple-choice questions. Three-step workflow: input → AI generation → editable preview → bulk import into pool
  • AIService.php: NC TaskProcessing API (NC 30+) with TextProcessing fallback (NC 29) — runtime detection, no app-level API key management
  • AIController.php: 4 new endpoints — GET /api/ai/available, POST /api/ai/generate, GET /api/ai/status/{taskId}, POST /api/ai/import/{taskId}
  • AIGenerator.vue: Full wizard with textarea input, question count slider (5-30), language selector, polling progress, editable preview with select/deselect all, inline editing of questions and answers
  • At-Risk Early Warning: Instructors see which students are falling behind on the Course Progress tab. Rule-based risk scoring with 5 weighted signals (inactivity >7d, accuracy <50%, box-1 stall >60%, lost streak, <3 sessions in 14d)
  • At-Risk API: GET /api/courses/{courseId}/at-risk — returns students with risk_level (high/medium), risk_reasons array, last_active, accuracy
  • Remediation Queue: Focused practice on hardest questions (≥3 wrong answers, <30% accuracy, box ≤2). "Trouble Spots" button on Pool List with item count
  • Remediation API: GET /api/leitner/remediation (items), GET /api/leitner/remediation/count (lightweight count)
  • Daily Challenge: One random question per day from user's pools with +15 XP bonus for correct answers. Deterministic selection via crc32(userId + date) — same question per user per day
  • Daily Challenge API: GET /api/v1/daily-challenge, POST /api/v1/daily-challenge/answer
  • Migration V001600: Adds last_challenge_date (VARCHAR 10) and last_challenge_correct (BOOLEAN) to learning_user_stats

Changed

  • QuestionList.vue: "Generate with AI" button visible when AI provider is configured (checks /api/ai/available)
  • PoolList.vue: "Trouble Spots" button (orange, warning style) and inline Daily Challenge card with answer submission
  • SmartQueue.vue: New mode prop (queue | remediation) with conditional API endpoint, titles, and empty states
  • App.vue: Wires openRemediation event from PoolList to SmartQueue with mode="remediation", new smartQueueMode state
  • CourseDetail.vue: At-Risk section on Progress tab — collapsible card grid with risk badges and reason tags
  • routes.php: 9 new routes (ai: 4, leitner: 2, user_state: 2, course: 1) — 69 total

Security

  • AI Rate Limits: generate endpoint limited to 5/min, import limited to 10/min
  • AI Input Validation: Text length 50-50000 chars, word count capped at 3000 for LLM input
  • AI User Isolation: Task status checks verify userId matches task owner
  • At-Risk Access Control: Endpoint restricted to course instructors via validateInstructor()
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
Signaturedp2AlnFQwp1Cy8OCA/kE3gVqTvYhN9ORN/Oa86Lk0jjsYVLVFDHML+2ga4rlw5rjLTzojVtzB4BM1uJdyu/fRrdCUz9DhBBxIgNLNto8oIzu6HOYkE4TCB38quz5MGBbCVvZWnjmKb0ugYvzixvpy7ZPJnAWB5bwfj8C8AJqeEbbqqClkbjE4SAO9sxLfJbzDyWK7au4/It+H5gOO1yzXzUL6azX31M4acCwXZNI8AMRj6UHHqudtLsb9WgEC+cIHGEOfArbdIN9MDh1eDU3R17uuPjJw19g0KqZsc/NqGb/XuPUmHOHdcr8XzHDO4gYxp6FTEiMR8anCFogfEzpfrwGr/RAFzFBI0zfZ0+cbLHCNW3xrPVy/hOKGTlYXUHroalE6cvYdniSoXvQ09m6GlynsCauLZ8+hCb679ewlremqakW3E5RLtPL+xkP/ti0b8nev0Mdd9smil0YbrtPA6kJyk5JgllkPT3xhDDOtYrH+yrX2VNp5f4ypdWkPS8hM/SHId2W5q2D6K9XHVymde1aeA7AYPfa5/c62k7bvmwLbbNOWF4stKfq8MCA83RXASbfeHnAbdNbFltSPB9CT8oHBlBikwxk32iVKyoGEzuKZbAtZhC1x69ryyO0Uw5BAx6vexGDJUdgQb3PyeN5i2tV3Z2s3GCtHMjF+y0E8tY=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 1.6.0
Release Details
UpdatedFeb. 25, 2026, 7:30 p.m.
Changelog

Added

  • ConsistencyCheckJob: Daily background job that reconciles learning_user_stats against source-of-truth tables — self-healing for XP, level, sessions, mastered counts, and streaks
  • Composite Leitner indices: (user_id, box) and (user_id, next_review) on learning_leitner_items for faster aggregations and due-question queries (Migration Version001300)

Fixed

  • HIGH: LeitnerService::answerQuestion() now wraps box update, stats update, XP increment, and badge award in a single DB transaction — prevents partial writes on crashes
  • HIGH: Optimistic concurrency control on Leitner item update (WHERE box = :oldBox AND correct_count = :old AND incorrect_count = :old) — detects and rejects concurrent modifications including Box-5→5 lost updates
  • HIGH: Box-5 mastery bonus (+25 XP, +1 mastered, badge check) now only awarded on actual promotion (Box <5→5), not on repeated correct answers in Box 5 — prevents XP/stats inflation
  • HIGH: Badge notifications and Activity events now dispatched after transaction commit — prevents ghost notifications on rollback
  • MEDIUM: Demotion fallback (updateUserStats()) moved after Leitner item update — recalc now sees correct box value instead of overcounting
  • MEDIUM: syncLevel() deferred to after transaction commit — eliminates lock contention under concurrent reviews
  • MEDIUM: Cache invalidation moved after transaction commit (was inside write sequence, could serve stale data on rollback)
  • LOW: Multi-select answer validation uses batch IN query instead of N+1 per-answer queries

Performance

  • Leitner box aggregations (stats, mastery counts) use composite index instead of full table scan
  • Due-question queries benefit from (user_id, next_review) index — faster Leitner review loading
  • ConsistencyCheckJob processes max 500 users per run, oldest-updated first — all users eventually reconciled
  • ConsistencyCheckJob logs progress and catches per-user errors without aborting the batch
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureKQnhIvGaYFr9qdGYI0R0k4GLBar4u3swxmHkT+MfcE1phTVpyAm8O9s/s1TIz7qIDG3TA7CcjVDPTh57M2WysEi8/Yu8OZgE2pjJbsTOOssjRtFoGUqzyU4AR74azP5w3f/wdgk0jiIEQvOV+4aM3fENSOSktpfeGZzhch0xHUfON9kS2h4x8+8AqH9M/xkPJvS0dUIUoGNGYsug8qu3HkRcBxsH7n4hYzg3ycx+eL8vWpwfhFOhAV70cpcHOrK/oVz0ra4tl06LdPDNWeCB3AYCHU8hcehaPr+VsNJmgOdBoRf7JbesAu5YOB25qy340wJ+XlLonXe03NTq+xoG67Na0laU9cs+j56X856ik8G0UeT4vIywTObfh0iKmtqk/pUKzv0YopTYl/iSPtU/hTquoXnSYbEALoyPyh9aJpgpKXEn7d7qyoMo5/9Bx1owdXNxIi7gGtue1MMrFTkCIEm3/SMFWmA4XBXSRt2zP4sEUKaE1L8STzO57jFtpzt/WfC47ccCRktkLEkXDIIpwYwjHQYol7P/luO1OqUwJVefFnC52Fc4tJDrabMIbLqfOqwUPip0o18zcqsaNpTVyc6Mw+VLgO6MkP6lmdWfq0nvpBpKMu5e7cySJoT440xsvCBTWIIcfQyYcMJGxFscSondANcYYAg/ixhtChuTd5U=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 1.5.0
Release Details
UpdatedFeb. 25, 2026, 2:35 p.m.
Changelog

Added

  • Consolidated User State API: GET /api/v1/user/state — single endpoint replaces 4 separate calls (XP, streak, badges, progress)
  • Denormalized learning_user_stats table: O(1) reads for XP, level, streak, sessions, mastered counts (Migration Version001200)
  • Background Notification Job: NotificationJob (TimedJob every 4h) replaces widget-triggered notifications
  • Activity-App Integration: Badge unlock events appear in Nextcloud Activity stream with toggle in Activity settings
  • Timezone-aware badges: Night Owl and Early Bird badges respect user's Nextcloud timezone setting
  • XpService: Dedicated service for XP calculation, session XP increment, level computation
  • Response caching: User state endpoint cached for 30s per user via ICacheFactory
  • Composite index on learning_sessions(user_id, completed_at) for faster XP/streak queries
  • time_limit_seconds column on learning_sessions for Speed Demon badge support

Changed

  • BadgeService refactored from 430 to ~200 lines — XP/streak methods extracted to XpService
  • Dashboard Widget is now pure read-only (~140 lines) — no longer sends notifications as side-effect
  • AnalyticsDashboard.vue: 4 API calls consolidated to 1, with fallback to legacy endpoints for rolling deploys
  • countUp.js: Respects prefers-reduced-motion — immediately shows final value without animation
  • BadgeUnlock.vue: Added aria-live="polite" region for screenreader announcements
  • LeitnerService: Box-5 promotion updates denormalized total_mastered counter
  • TrainingService: Session completion updates denormalized stats via XpService

Fixed

  • HIGH: Leitner XP now synced to learning_user_stats — correct answers award 5 XP, Box-5 mastery awards 25 XP bonus
  • HIGH: Race condition in stats UPSERT — all INSERT paths wrapped in UniqueConstraintViolationException catch with UPDATE retry
  • HIGH: SQL injection in incrementSessionXp$currentStreak now uses createNamedParameter() instead of string concatenation
  • HIGH: NotificationJob memory exhaustion — fetchAll() replaced with streaming fetch() loop; N+1 due-count queries replaced with single batch query
  • HIGH: Level-race in XpService — stale getTotalXpFromStats() read eliminated; syncLevel() is monotonic (AND current_level < :newLevel) to prevent concurrent stale-level overwrites
  • HIGH: Stats INSERT fallback uses updateUserStats() full recalc — preserves historical XP, sessions, and mastered counts for first-write users
  • HIGH: total_mastered demotion — Box 5→1 transition now decrements total_mastered counter with updateUserStats() fallback for missing stats rows
  • MEDIUM: User state cache invalidated on every Leitner answer (not just correct), after share-badge awards, and at END of completeSession() (after all badge/streak writes)
  • MEDIUM: Migration backfill is per-step idempotent — each INSERT...SELECT skips existing users via NOT IN clause (safe for partial re-runs)
  • MEDIUM: Migration backfill includes Leitner-only users (no completed sessions but have reviewed cards)
  • MEDIUM: Frontend fallback triggers on any error (not just 404) for rolling-deploy resilience
  • LOW: Removed dead $totalMastered variable in LeitnerService (computed but never used)

Performance

  • Dashboard load: 4 XHR → 1 XHR for gamification data
  • XP calculation: O(n) SQL aggregate → O(1) stats table read
  • Notifications: synchronous widget side-effect → async background job
  • NotificationJob: filters to users active in last 30 days (skips dormant accounts on large instances)
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureOyK9vuzcblU3s5znaUXHm8WvkECMxcl4Jz5Xt1pNg4mTSvtO0R26bat9p9AMH75j70QPKj0FUJYI6jhObMU7X/lUu6b6+UhvO+RCtzO3/4OQ+gwULA4qSX4oWzmiG6obxmI51H0AnBOCwLb/JuVlbJJzDWuaSetL7fZX5oOEGoNuom7ZK3eoPovLG0d94fhldGhXBph8D6iUsySsmxuA1nU/nFE8kFTXAj89xHxPb1V6G4omNw+0K7mfjshDC++A44/zibOE/XvHYhLPmch/MvvHyPkJ7jMXzhOsSJYB+EAQMGEVMig4tOf6Cug9HFd3+adiHIPP+UpyI3R1lZP5YNSMsuvDviDHXI16P25mr87PZO6/XcOxbwRV+eG7aiRlRTtgvgbfCPQacIJfT+zzZzGytY2sa+htxiTis0sdQY2BdsdtlwD75NmlP37KEZFJuG6y+4TTV7kN6iTueYxfoYTcQ9irz82FrgNYTAgWAgNXJ6K9rnlHlBAc7ZU9+VT6tNzi39eJflwwLJKPjhPyBKiZ10ycIPwgJYLAtbTQdaYF7rmBDVM8xkS+KSjvyErD+vzV+lZRVy6G2zHZpiRhPSFHGc1ytWa3o180ukeo0fw2/fz29R/OcIxFupinMuAPeaoHE2yrGkHvg8yJSHq2Scen7Bp1AhNmiL8BIbSAHe4=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 1.4.0
Release Details
UpdatedFeb. 25, 2026, 10:28 a.m.
Changelog

Added

  • Achievements / Badges: 14 badges across 6 categories (sessions, performance, mastery, streak, social, fun)
  • XP & Levels: Experience points calculated from sessions, Leitner reviews, accuracy bonuses, and streak multiplier
  • Badge Unlock Overlay: Animated full-screen overlay with confetti when earning a badge
  • Analytics Dashboard: Achievements grid with earned/locked status, badge progress bars, XP level bar
  • Session Juice: Animated score count-up (countUp.js), Personal Best detection, improvement vs. average display
  • XP display: "+X XP" shown on all results screens (Training, Exam, Swipe, Leitner)
  • Nextcloud Notifications: Badge unlock notifications, streak-at-risk warnings, due card reminders
  • Badge progress tracking: API endpoint showing progress towards unearned badges
  • New DB table learning_user_badges (Migration Version001100)
  • 2 new API endpoints: GET /api/badges, GET /api/badges/progress

Changed

  • Training complete response now includes newly_earned_badges, xp_earned, is_personal_best, improvement, average_accuracy
  • Leitner answer response now includes newly_earned_badges when card reaches Box 5
  • Share creation now triggers badge check for "Sharing is Caring"
  • Streak endpoint now triggers streak badge checks
  • Dashboard widget sends streak warning and due reminder notifications
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureYuFGppj5TQhlB5nd+fXqJurxGQUn7l0FFIqbWhXJMf9xPEi/g3wKdx7qukdK2ttz1Rf5xEbSdoLsGj3q1F7V5DZ+4+4GmMewS+MlYE4GA9ESFIA6lHLYxThICgb3G2lEGtImmp57tmGv7dzAiPqIH4pEdC0KT/iO08+VGy5R5s1gS5r36nHSrytf5C7JUBSSmOg6rVpUFIccDaXv8zn1f9sWWAZw4pRptDx+X29foqY2Zt4S/Swuz/SOGWKyfhhPw/x6RHjB3vnJIxx64Oi4Rom8BNdrU911RtMUFXLcnxq4xsv7VO2wGMkjNHegpL2yNr68yJSEm0bOjmVih06XMpJDNC0KN4S0vwnUkDIm1t9Dk1zxSPK5ba/PlQrTFxMVwratZsc1Uz0b/VqUBaZTu9oEBMpBm4CTrSf8XK29CNQ5EQXAzMSB0UUz0TqPpL2rI9kkcejJl0cololPd8N5R5jJpQ5miguwm6UjfTrIJzaizm6MAtXg+wx/DFfTyaSS936v1JEaRGIy4XkeQ9ZAAnSANlx9o8HTyLnWc7v6EsdkSo/7q88h7FaFUrlgkb3Gv7CQLBIJZ2jLtYa/2jv5gHQrg3c9unmIPLK8njpwS5+KgMH1V8LsyvraUW9ejzfmGv/BuN+reNyvToEoP8JIFPLs7SP1areV9svmkEnjIT8=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 1.3.4
Release Details
UpdatedFeb. 19, 2026, 2:46 p.m.
Changelog

Security

  • CRITICAL: Close training-session oracle — startSession(exam) auto-completes open training sessions on same pool
  • CRITICAL: Defense-in-depth in submitAnswer/submitBatch — suppress correct_answer fields via cross-session check
  • HIGH: Strip explanation field from Question API during active exam to prevent indirect answer leakage
  • Rate-limits on ShareController and TranslationController write endpoints

Fixed

  • Leitner feedback shows hint when correct answers are suppressed during active exam
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureajCD73Wim+3CcebKFs72Co993wGojtfsPy8b+Gde+kx+EhPmDpzYEGdgbb54ZBqpDmJAroHIbaqZa0FfK8SwvFwC2JZ7WOp4xwOAjp+V7ruKvXu24MmzsH2wUp9U2ec+sO+EG9+ebsDELjaFEf2m6EMbRhw+/QUzsE51kaA10RaTwoNfTu29LLraGaEEFVWh9R5x5jbqNj9Wdvfq/vNNTp/XTm4SBLnAsD+7ymyMucfwHyn4ZYGspXdNd8v0HS6ZRe3JjtcOd+IjwEebZ4b2KPBCrnGs8sr+6zer7FItbLUOq2MxxdhaOml1yTQIPzeyuJPnFvmLJOw0FHJvsn/ZMMjCpByVSrf2MBua3yW4DcB/Z9m3yBwM3lQ98QUQDgmAfHwU1zG3P5ijvxFvaOz5XW3sFsCaktXfGtFfrMgUgbN8aee/7hZkA36Vi+zIUsbs+eExv5QvDn6bG21DrE8022vnfZ7gY9HFQESVMGsnZc9yqdeGJn9F09jScGcZvyinjtUUCe2/SRfjPHHa9JWvZ84pQuO+0OyAbvIEOlwz64r5qNatt47yoxAEzEUsu8oFQP2s+PX/Ni/yyEIWbH4LaK0qCPTulJKvujaq1fukSchT+9UMBVKxEebC672M1LtejtJnJfZVUp6WuAecz2QmBU4Va6WFDVLSkbAiz6ON/Jg=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0

Nextcloud 30

Learning 3.6.0
Release Details
UpdatedMarch 30, 2026, 4:56 a.m.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignaturejQ1Xdi636ODYsfoC8Sr3MU9s6K0a/PIOZvbo0ea4D/TpW/NiVKu49cZC8JLt8oFbyp2qVI27LVBXEplSF6V004H1NMqHdnC3zhqEbs/BzRH9CIKZW7Ouzs2Qj7obBiBiszYtamVpxRvxt3bfCiIfac9mn6yMJ2OvsqDohraIT5Mh84kyuW4ibPVun/8hX2/qndkvsQQvKnO+GL8UHRV1UhiSG/ezTdjZbinc0ZVU06oWXJFuP2YXpFPc+GHG8RMBP6N3KeqmK+rMZ6lKaZY5fl//pnr8AbASDKYK0MjWQFsqLrei9R/iQbsHqjlT3vT5o0Sssrw0m++5ysCJhTb0uEPgeLvg4DUOige/iCegy+NZFb+qgb7oezetZD8s/aWxZTR645y1MZS4va5kgdAVreT0rvHDDZvx9UuKr4smMvAxX1DEUKgzqP/AMellHcwb4BVE9pVwOENp5oKttpoJXKoH/Lnwu+o+1o5m4+JH/SHHGJBCmXYeehFscARZceC9lNYsBTHL+uKILOszxJXK0OkwrFCVCGTnXFfO0hn23gwjECPGP/zwB8OwlwedZXjaZkAMomIulAxghFIw5arSOoX85kv7bOlwerVJ7jfHs8GYIqBn3b+bWzVn5MQEumuUiKBi01WH7vbjn5Neuxi7YfSBkjJjeQFOFlGEmwFwcrs=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 3.4.0
Release Details
UpdatedMarch 28, 2026, 5:03 p.m.
Changelog

Changed — UX-Navigation Struktur

  • Instructor Tab Groups: 17 instructor tabs organized into 5 logical groups (Lernraum, Teilnehmer, Kommunikation, Wettbewerb, Verwaltung) with visual separators.
  • Abenteuer Standalone: Adventure mode promoted from Arena sub-mode to its own CourseDetail tab, independently gatable via mode_config.
  • Arena Submode Gating: Each Arena mode (Duel, Gameshow, Oldschool) individually hideable per course rules. Arena tab disappears when all sub-modes disabled.

Changed — Code-Hygiene & Settings

  • Settings Split: Instructors now see two sub-tabs in Settings: "Kurs-Verwaltung" (admin) and "Meine Einstellungen" (personal). Students see only personal settings.
  • Zeitreise Removed: Removed 1270+ lines of dead Zeitreise/HackThroughTime frontend code (component, characters, navigation, mode_config key).
  • German Labels: All UI-visible labels now go through t() translation. ModeIdentityBanner labels localized.

Added — Simulator-Praxis-Sessions

  • Practicum Engine: Pure-JS state machine for guided session management with localStorage persistence and browser-reload recovery.
  • 11 Practicum Sessions: Real-world IT scenarios across all 7 simulators (42 steps total). Firewall, DNS, and Routing get 2 sessions each.
  • PracticumRunner UI: New "Praxis" tab in every simulator with step-by-step instructions, context explanations, progress bar ("Schritt X von Y"), and score summary.

Added — Student Dashboard

  • Heute Screen: New default landing page for students with SmartQueue widget (due cards count + "Jetzt lernen"), Daily Challenge card, streak display, and daily progress.
  • Global Feed: Aggregates announcements from all enrolled courses chronologically with course-name badges and pagination.
  • Pools Navigation: Direct "Pools" tab in student main navigation — one click to PoolList.

Added — DevCloud Integration & Leitner

  • Talk Room Link: Instructors can set a Talk room token per course. Clickable link appears in course header, opens NC Talk in new tab.
  • Materials for Students: Students now see the Materialien tab (read-only) when a course has a material folder set.
  • Buddy Matching: New "Lernpartner" tab shows who can help with your topics and whom you can help, based on Telos help_offer/help_wanted data.
  • Course-Aware Tools: Werkzeuge tab filters simulators based on active course's enabled_tools. No course active = all tools visible.
  • Sprint Intervals: Instructors can activate sprint mode per course (4h/12h/1d/2d instead of 1d/3d/7d/14d Leitner intervals) for intensive courses.

Fixed

  • Badge Duplicate Crash: Session completion no longer fails with 400 when badge already exists. Fixed catch to use OCP\DB\Exception (NC 30 wraps Doctrine exceptions).
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
Signaturely5UiDEZdUJh6uSRREEijl3s87EIDnAeze3Y9KBfIECnaFvdafIwluTTl1XeyEvAaGshOHIXMmtfVvnYA9dMLyIj+jKvSeWlFKgbTsMS7hRvCiuqGcoFBPuOm8rDzIk6AXTGieQFgNIho9p68tRzQ2MF1mFJ/qnd3ayGiasJtT7W7rbUQYNAtzL3n4CpmxVZi4msMamM+K7c0O7e6/pmQJ3HCmtpjurPs8MJzAJQf5dyTQQuDa44T9aOSi4ucDAnS+aETU20UH0C8HWU15un+T0FeIP8//J8VxHFkP4g6BzrHF9mA52QKgUnUTkxYcH1qVhL7TcKjvfGScG3MjnSV92hvpVlEDZhMNAGkCwORAPMG22r4moEOmLse0r4/tMkSZ/4InV5kc3NYmZFzigT3yBnZGmsTxyvVb1PdAGi0uNhIvS2Ay8nq6tARMz1lFMv3iz8y9MmwSwIsyMGIUq5xWG49/Fj9rqB6HvEj7lmojVhuGm4eBEiJ6dnuyu91l1O5sML68xbiaHk1lv+Q4Qy6THYKX5MKFcCTbFxfs+4acZRgquRLpLFDGkXtpJMs4XMjSCygcdKQy2bk6TSnncyhPFUiMCDkhavR/QICmtQw/RBJatqdf9+f6LT87zhA4g2jO9XXq6EcoaSTn0k7aS3eghXGRHumpYSNCDMXxuPnjI=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 3.0.0
Release Details
UpdatedMarch 24, 2026, 6:55 a.m.
Changelog

Added — Story RPG "Abenteuer" Mode

  • Story Engine: Full campaign-based RPG learning mode with branching narratives, skill checks, and character classes (Architect, Security, SysAdmin, Helpdesk). 20 campaigns across CompTIA Network+, Security+, CySA+, Linux+, and A+.
  • KI-Erzähler: Gemini-powered dynamic narrator with freetext player actions, NPC dialog generation, and role-based prompts. Fallback to static text when AI unavailable.
  • Skill Checks: In-story quiz phases with 3 questions per check, batch submission, pass/fail branching to different scenes.
  • 20 Campaigns: Real-world IT incident scenarios — SolarWinds, WannaCry, Log4Shell, Colonial Pipeline, Equifax, plus 6 Security+ exam-oriented campaigns (Phishing, Zero Trust, Crypto, Compliance, IR, Cloud) and an AI Security campaign.
  • Coop Mode: Infrastructure for multiplayer campaign sessions (UI placeholder, backend ready).

Added — "Zeitreise" Hack Through Time

  • 7 Epoch Campaign System: Phone Phreaking (1960s), WarGames (1980s), The Worm (1990s), Bobby Tables (2000s), Shadow Brokers (2010s), Supply Chain (2020s), Quantum Dawn (Future).
  • Period-Accurate CSS Themes: Each epoch has its own visual theme (terminal-green, amber-on-black, retro-web, etc.).
  • CHRONOS Guide: AI narrator character that guides players through hacking history.
  • Museum Facts: Historical sidebars with real dates, events, and technical details.
  • Character Classes: Epoch-specific roles (Phreaker, Hacker, Script Kiddie, Analyst, etc.).

Added — Visual Identity System

  • Design Tokens: CSS custom property layer (--lnc-*) with dark/light scopes and motion utilities.
  • 13 Character Registry: SVG silhouette avatars with emotion states (idle, celebrate, alert) for all NPCs.
  • Campaign Intro Animation: Full-screen intro with title, difficulty badge, and character reveal.
  • Dialogue Stage: NPC dialog component with portrait, speech bubble, and emotion tags.
  • Paper & Circuits Narrative Skin: Dark theme for adventure mode with subtle circuit-board patterns.

Added — RAG & Document Intelligence (v4.1)

  • Document Upload & Extraction: Instructors can link Nextcloud folders as course material, scan for files, and extract text from PDF/Markdown.
  • Chunking Pipeline: Automatic text chunking with keyword extraction for semantic search.
  • Multi-Source RAG Context: VirtuProf answers now cite course materials with [Quelle: filename, Kap. X] format.
  • 4000-Token Budget: Smart context window management prioritizing relevant chunks.

Added — Oldschool Board Games (v5.0)

  • Lernwürfel: "Mensch ärgere dich nicht" inspired board game with dice rolls and question challenges.
  • Wissensturm: Trivial Pursuit tower game with category-based progression.

Added — Personal Learning Bot (v4.0)

  • GeminiService: 5-layer security stack (API key isolation, input sanitization, output filtering, rate limiting, audit logging).
  • VirtuProf Chat: AI-powered learning assistant with chat-first UI, language auto-detection, and chat memory.
  • Note Generator: Gemini-based topic summaries saved to Nextcloud Files.
  • Lernprofil: Passive user learning profile with weekly study plan generation.
  • Auto-Triggers: Exam auto-notes, wrong-answer threshold alerts, weekly plan background job.
  • Ticket Triage: AI-powered support ticket classification and draft FAQ responses.
  • AI Consent: Opt-in consent overlay before first AI interaction, GDPR-compliant.

Added — Tools

  • Subnet Calculator: Browser-based IPv4 subnet calculator with CIDR/mask input, binary display, and VLSM planner.
  • Subnetting Question Pool: 50+ subnet calculation practice questions.

Added — Quality & Testing

  • ESLint: Vue/JS linting with no-v-html error rule, 0 errors enforced.
  • Pre-Push Hook: 4-gate quality check (Security scan, ESLint, Vitest 67 tests, PHPStan Level 5).
  • Playwright Browser Tests: 67 automated checks covering navigation, campaigns, time travel, tools, VirtuProf, security. 52 PASS / 11 FAIL / 4 SKIP.
  • PHPUnit: 12 service-level unit tests (Training, Leitner, Analytics, Course).
  • Test Strategy: 4-gate pyramid documented in CLAUDE.md.

Fixed

  • Campaign skill-checks now always use pre-loaded questions from scene response (no separate API call).
  • Campaign start always creates fresh session (no stale resume from previous play).
  • Missing Abenteuer/Oldschool/Zeitreise toggles in course mode settings.
  • WannaCry campaign: corrected from email dropper to SMB worm narrative.
  • PBQ subtype auto-detection from config structure when pbq_subtype not set.
  • Empty skill-check pools handled gracefully (skip to next scene instead of crash).
  • Narrative garbage fallback when Gemini returns malformed text.
  • AI rate-limits on VirtuProf available()/status() endpoints.
  • ESLint: empty catch blocks, v-if with v-for separation, escaped quotes in templates.

Security

  • Gemini language mirroring prevention (no prompt echo).
  • Story mode injection guards on freetext actions.
  • Story mode rate-limits (10 starts/min, 60 scenes/min).
  • Pre-push security scan for hardcoded secrets.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureMWUO0JmVVcGH0NNuBs36k/SJ6luN5fkUQPaxu+CxY+5FdW/X4uAAD6NgGuM/jQsqSyKsns4V1UgbtV15xhOlHyO8/fOrnIeU1tifv52U+Sud8OdnMeCy9eQ8TmbbZwrsxT7er+1hmRgrJPC+b1++4bWDE57D6tJ85xAeJ4TeNMkSQDAy8PGI7PnhG1ae0Xx4DAXAjIm6+GZqeletoRknfiLPpLyUcF2EMOqOxdWjXhDVEGhXMLgPUcJnLPi6avTjN/CCEK1awEzVr4IhaUUI86Dub/68KQmeOFZRusIARkqmY5Bq0ER9xzcWKf26pyl10xr1GJUh2sQB+Utw3cszgq6VPS8KdsVJ3a15+uqdinFxo8QHhJz409tF9RdQnqye+0WJ2qa4d4PbndPeAiAcu3z27tlmVDmwouvxrYco4wDgUSIW3lzayLjR8IiONHylfIZ56idwu/EAYEU2u9/0oKVDeGi+Izt6z4/aX9iTjuV29T1uB1e2aasUIWyRttCFBZ01PIaJqMfubHMvRmDrcjb9U4OKUTqLg58u29eeQMimHB9O3ij0n6zQn2MJdxnnahO5seMg5tuLwRETHbcxQ0yNLskSLvSDgIa8vBr/leUgUtBPUCbIx4msuV3Tuy7HpA9Lg+3C7ZkqOIne6k0vakIc4KPjAPL/SLBwZusxfDI=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 2.6.0
Release Details
UpdatedMarch 17, 2026, 5:58 p.m.
Changelog

Added

  • Calendar Token: Per-user ICS subscription token for external calendar apps. GET /api/v1/user/calendar-token returns token + subscription URL. POST /api/v1/user/calendar-token/regenerate invalidates old token. Token stored in NC preferences (never expires until regenerated).
  • Public ICS Feed: GET /api/v1/calendar/{token}.ics — unauthenticated ICS endpoint for calendar subscriptions. Uses token-to-user reverse lookup via oc_preferences.
  • Calendar Sync in Personal Settings: ICS URL field with one-click copy and regenerate button.
  • ICS UID domain fix: UID fields now use actual NC hostname (parse_url(getBaseUrl(), PHP_URL_HOST)) instead of literal @nextcloud.
  • AI Explain button: POST /api/ai/explain schedules a text2text task explaining why an answer is correct/incorrect. "💡 Explain this" button appears after answering in LeitnerMode and TrainingMode (only shown when AI is available).
  • At-Risk CSV Export: GET /api/courses/{courseId}/at-risk/export/csv — downloads at-risk student list as CSV (Name, Risk Level, Risk Reasons, Accuracy, Last Active). Export button in course progress tab.
  • Batch Pool Assignment: Add-pool modal in CourseDetail now supports multi-select (checkboxes) — select multiple pools and add them all with one click.

Changed

  • ExportController: Replaced anonymous class with DataDownloadResponse for ICS response (cleaner code, no custom render() override needed). ICS body extracted to buildIcsBody() — shared by authenticated and token-based endpoints.
  • AIService::getTaskStatus() now includes output (raw text) in status response alongside questions array — needed for explain results.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignaturegpWcIhT4IeeSqVyKoOjXGch+flHYM9TICkDbyl7oRxuCOBH6sfYOwu5upyqwzGKl05TIRX2bqIrJiNj+ULif8rORhf3hvt03mhVuDCU1RuH9AbsD9VNvyw5Rf69FDXWD/44jH4JBjQHhD0E9MoY/Kud6Cog6W7SmIXEmGlHNz7mbopa2OoZZws6AA+SwjkDvK9BbvDrae3brEkSc2udTdi2HqSa8tbKPouwE3vdEdHWJWF3/j7P+4GM5cDXIT0B4g9eyL8r8Q1AKO0Xu/1pGPddNmeDz4gK4cQFGJF1KhhgAMEA7EM9/7wkMW6hrONfD57PJywCdeJhMTGVgGbjzLRreJ57GuI4jPhjqumOsiXRS3Evyn5LmO/q7FXn54hl1VBZBb7Kdj/t46wZzeV+vkKP/TFu2a/Amr99KFDWnNhKaF0eg/xYBAyGdNE162L7lHjXUlu5o6d1iO8i8y1NQoexyta7cqo019m4/BjhAr1QWAo5QsFJQ6hD7t8oA6Es50yFIi39Vzn2vFrkNuoUkrGtUNUH5mxEoDTCaHeLKBokStXztfaXsZzRBsi7Eem70Hqh65PQ4GAA7/BIKksrGR9XXRbbQG6ZBa1NN2iZaPDNF6t+zbq9EcfpITq7aLOthuU2OEkW4zm2Ds6wrxE+gFU+fxCePWR5H7g3OJuOcwjk=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 2.5.0
Release Details
UpdatedMarch 16, 2026, 8:57 a.m.
Changelog

Added

  • Daily missions: mission progress model plus claim endpoint (GET /api/v1/missions, POST /api/v1/missions/{missionKey}/claim).
  • Mission XP claims table: Migration Version002000 adds learning_user_mission_claims with one-claim-per-mission-per-day guarantee.
  • Streak freeze tokens: weekly reset token support in streak calculation (streak_freeze_tokens, last_freeze_reset_week in learning_user_stats).
  • Badge tiers: new bronze/silver/gold/platinum tiers for session count, mastery count, and streak milestones.
  • Analytics UI updates: Daily mission cards with claim action and freeze-token visibility.

Changed

  • Streak handling: streak computation can bridge one missed day when freeze token is available; token is consumed on activity-side calls.
  • App version: bumped to 2.5.0.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureBtgrr+hdTfM0f4h9yPsjjpUL18GMWeoMLCyfuSk+f0aj+R2D8WpUaWos8YBBAdFtoTYGKeykyLd+Ww/8ckGusCAhrB8BiV2IDSKhna3EreyedyjQ7tI9KXrif6dvkN/8FQB3JsWSXyLujapZYGX0lsvVxwf6rzmLIsOhC5gAGD+aCHwsZDxzi2bWVr3iyMaQq1rqd7HxGMUZq6E67lRr2bKCXTK46QEX1TnGw/jtv7gMg5Kq0pG39oRgOTtpjNc/0VJR/KUw4PujcVYMaOyLOlJlNjN0bZjgsgyijcACSi5L3gF8/M7yKvHFwZK/MKaWozRsTu1fJBtvrblhCBeJvoAGanAW+1gCE4SyNzClU/ToY/utQGJWUFNhARuMHjmqkAiFjfoev57XvvKIlC3mBF9U8oRIL9uQY+O6D1d1oynxvyVLvCmMOzw36xzHcEr7Hygu6PJUEOS79QkROIBiivsT91fAgRyFnStnbrM+0Az8Jiyis1mRU3lzOOSEIomZoapMevwMgngBQUwfUPDeQysmaz5DdpmDNW6oHbjV8WwIItNkK2sZm4VoDMud+PyGbLBIG/3HBjQVS1Hrhc4cjpoBgVLASsIVh6qIzQAsJnpagFsxxAm9azNMiNm1vgvcqRUnVStk0hi4B4pO3pr76/K/h3m7Y7MJDu0n736r4Ww=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 2.2.0
Release Details
UpdatedMarch 10, 2026, 11:40 a.m.
Changelog

Fixed

  • Course Pool Access: Course members and instructors can now access pools assigned to their courses. Previously only pool owners and explicitly shared users had access, causing "Pool not found" errors for enrolled students.

Changed

  • PoolService: Extracted findPoolRow() helper, added hasCoursePoolAccess() fallback in find() method
  • 5 Services updated: LeitnerService, PoolService, QuestionService, TrainingService, TranslationService — all hasPoolAccess() methods now check course membership as a third access path

Technical

  • 5 changed files, 165 insertions, 12 deletions
  • No database migration needed — uses existing learning_course_pools and learning_course_members tables
  • Course pool access grants read-only permission (permission: 'read')
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureFBngcENmOE/Ve20qo9FeQJkBZjOrpUJTFGqEhPB/hOp0PGIfvsZVFJylcJKnv59uVAjcElJIo3wtL5tG9b2sz0PtW60Fz24pb4NLxMewiUPNxKvBX7C7wcKNpf+H1nk3i/aGYPOiTZd6YTtMut1bDQ9zFdlXVxWjUCMAEZFJxMo0TG2IGD+bB+r2NGyh0okA2DN7+FVhCuRg/jF32BMFTtXD1X3qvmc2cQ6ls3F3hnDMrmpifXb2wzCAfAfBUyYoVCbwWyRL5Ig4iTZlk/TB5GmiPl2lncIGB3cMu8Ad0cJz26Ch+TMdbaSJdRtDCxQvCr9EwsL4mWR2BvsTqMUdybDA2C2aqPfRVjBg6oyP45C6z8KgE2XsMxzyzOI+E6leQ80nmmgBDx63+Yns4nXyAbFVegYan+8mQGm7PLDO3gtdossWxTiB3tptBTTljdSM3v+eHkncaTmIl/o1BOtMdznuhCHFUatKW1Bt+cDNBZg6gweghbJmBXfj9sFyqL/L+nZodDqXO5avLstGJoC0p7S5TmTM2L75kjKJxJe1IRMQUUldzH17NxDPeFP5bcPNZbPrujsFhjKNXFGzv2knPfZoV4oIGPbMQ+FNTWOn0jU6yik2o6sHsSMZfMMvr/MLwGdamYHOSbQba5FKE6FJh7LljZ1vaJqhwRAR08JFptE=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 2.1.0
Release Details
UpdatedFeb. 26, 2026, 3:56 p.m.
Changelog

Added

  • Free Text Questions: New open question type — users type free-text answers instead of selecting from choices. Fuzzy matching (case-insensitive, Levenshtein distance ≤2 for short answers, substring matching for long answers)
  • CSV/JSON Export: Download question pools as CSV or JSON files. Roundtrip-compatible with import — export then re-import produces identical questions
  • ExportController.php: New controller with exportCsv() and exportJson() endpoints, DataDownloadResponse for browser download
  • XP Streak Multipliers: Tier-based XP bonuses replace old linear formula — 1.5x at 3-day streak, 2x at 7-day, 3x at 30-day streak
  • XP Multiplier Badge: Visible multiplier indicator (1.5x / 2x / 3x) in Pool List when streak bonus is active
  • Open Question Import: CSV format question,model_answer,open and JSON "type": "open" with single model answer
  • Open Question in all modes: Training, Leitner, Smart Queue, Exam (textarea + batch submit), Daily Challenge — SwipeMode filters out open questions

Changed

  • XpService: getStreakMultiplier() and applyMultiplier() replace linear 1.0 + (streak * 0.01) formula
  • LeitnerService: All XP awards (correct answer, mastery bonus, daily goal) now use streak multiplier via XpService
  • UserStateController: state() response includes xp_multiplier field; answerChallenge() applies streak multiplier to challenge XP
  • QuestionForm.vue: New "Free text" answer type option with model answer textarea
  • QuestionList.vue: "Freitext" badge for open questions, model answer display, Export CSV/JSON dropdown
  • ImportDialog.vue: Help text updated with open-question format examples for both CSV and JSON
  • SwipeMode.vue: Filters out open questions (not compatible with swipe/tap interaction)
  • routes.php: 2 new export routes (71 total)

Technical

  • 1 new file (ExportController.php), 22 changed files
  • No database migration needed — question_type VARCHAR(20) already supports open, answer_ids TEXT stores JSON
  • QuestionService::isOpenAnswerCorrect() static helper used by TrainingService, LeitnerService, and UserStateController
  • Rate limit on export endpoints: 10 requests per 60 seconds
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureHyyUtHF7C32M+YZc15dn2kRI/DltaewXzt5Im3Zu3rPS12Q+ICmOK+AhT/TicLBFR3Zr21BjtyhcjcrFf5JmXIG9c65OEEyK2ApbXAa5HfFFhUbPIAjj+z2eG3F2+71DrFluPVg5imtKCJ1+zmZfNC3EFI+UFhUFPGor76KTJphQrT01qMaD21XuWlbr59lOI3PLuV+qENWBC2pvQMcBDTyfDEpanPR/NRZ9I31TqA5qj9d6su9UYxW0AO/21Dz6cTvUx6AeJksLyRjQsGEMZhvp5Lv3k3X4fiBp4q6j/VKtt/R89eCbNAjEcubZwYsAx6TA6gK1FtfOwO++7pU4EPzDlKFTBUpqoXJFvelF+SRg5h5oNJYU4zoJRCRV7IOIwliR//2G4Rh5bKenEELEhJ47l8lHfdw2vAkY1zMcOFRoTmda27VPD4W+uOBnd+7sXUSlPLCPRZYmZTMuFehgnPvLM8jN7e57ldBnzYw2AfSkS8vFmsIiT/TqhUknc7kFUAMD3Cz0PmofWWM+CbglCnD/HURBJW6FYX8dnA7fJhkyi7wSeC9nFc9TAU3jlVRiL/RA/wAmlxP2ZXJUk4JpuzxsdAwuBXkDRgnrmjnz31WdiqAI9f8HOPh9vc9ttbbMXP35llqMTa3T9NfnMZR0pkY0SKXcmSbAK3IHsv4dPI0=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 2.0.0
Release Details
UpdatedFeb. 26, 2026, 11:35 a.m.
Changelog

Added

  • Role-Based Navigation: Students start at Courses view (no Pools tab), instructors keep both tabs. App title simplified to "Lernen" for students
  • Onboarding Hint System: 7 dismissible info cards (localStorage-based) explaining Smart Queue, Leitner boxes, Daily Goal, Daily Challenge, and welcome messages for both roles
  • hintMixin.js: Reusable Vue mixin for localStorage-backed hint dismiss/check across all components
  • Mode Descriptions: One-line explanation shown below the active mode selector (Training, Leitner, Wahr/Falsch, Exam, Stats, Manage)
  • Pool-from-Course Navigation: "Back to Course" button when opening a pool from course context (instead of losing context by switching to Pools view)

Changed

  • App.vue: Mode selector filtered by role — students see only Train/Leitner/Wahr-Falsch/Exam (no Stats, no Manage)
  • PoolList.vue: Create Pool button, Share/Edit/Delete actions hidden for students. Better empty state text
  • CourseList.vue: Student empty state now explains that the instructor enrolls them
  • LeitnerMode.vue: Box labels improved — "Neu — taeglich wiederholen", "Lernphase — nach 1 Tag", "Bekannt — nach 3 Tagen", "Gut — nach 7 Tagen", "Gemeistert — nach 14 Tagen"
  • SmartQueue.vue: Better empty state ("Open a pool and start the Leitner system"), ready state shows priority sorting info
  • PoolList.vue: "Jetzt Lernen" → "Start learning", "Trouble Spots" → "Trouble spots" (consistency)
  • de.json: ~60 new German translation keys for all hints, mode descriptions, empty states, and v1.8/v1.9 UI strings
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureX22wHYsHapYtxGW+/4w3wuihpu0uy3Mi5x076ajJx5VbizQVWSF8uURw2bu+y/pQn4GZxinHK/JxHWqcCdU86MB3ThayzDX7ySTGx/z016eudjyAYAYGPx84KJ+ciGXFFiiS+QA7ebnPjnm/8O365ve4tVtv+7EqjHzOwntJnlT+GL9FAYiUS1z5UzFSuI02nNz3GXc3PG1NeWf3M1iAG9Q26zjv3n4q0mV1/GstjWvuJ5bAH/C8eNWtumTPjDq0/sBza15+DPzBtTuSDanieXSPi+EG2geKozRNe7fWBCWflVScnK38+9ke0vQsC+cgNMgsS+t9Qquv1IHQqbQLzEpFRq88LcWfar9VH0YFG9E1FaX2XrbF+59lZdM39NvwLrOCIfJFt7Qpnv/9Zkv4voezhaST8lKLI7FC/jCNhDcN6IpLPj3a8VuYsyMfu2vq3A1VDAyq7qb7T0l7T/FTRVQG2DlxZLnRMSMsQgFHmbiP2/5S553/N9JErAgrY85op8ucOCv83ysvUOYLVNtXHbPq9YyH+7GXDK0OsIvIfoK+gsaj/qcBt2x88FH1SlpY0VLDkZ7huBC21rvKTV0lT3sXyNo0H2HKPGR14Xm8DsN5GCIaljf0ErOJRfsxX9nUpDqU5aqWk8ABK+kyTldmwViOizIzc0uMMdeu0G7bUWE=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 1.9.0
Release Details
UpdatedFeb. 26, 2026, 9:25 a.m.
Changelog

Added

  • AI Question Generator: Paste text (lecture notes, textbook excerpts) and let AI generate multiple-choice questions. Three-step workflow: input → AI generation → editable preview → bulk import into pool
  • AIService.php: NC TaskProcessing API (NC 30+) with TextProcessing fallback (NC 29) — runtime detection, no app-level API key management
  • AIController.php: 4 new endpoints — GET /api/ai/available, POST /api/ai/generate, GET /api/ai/status/{taskId}, POST /api/ai/import/{taskId}
  • AIGenerator.vue: Full wizard with textarea input, question count slider (5-30), language selector, polling progress, editable preview with select/deselect all, inline editing of questions and answers
  • At-Risk Early Warning: Instructors see which students are falling behind on the Course Progress tab. Rule-based risk scoring with 5 weighted signals (inactivity >7d, accuracy <50%, box-1 stall >60%, lost streak, <3 sessions in 14d)
  • At-Risk API: GET /api/courses/{courseId}/at-risk — returns students with risk_level (high/medium), risk_reasons array, last_active, accuracy
  • Remediation Queue: Focused practice on hardest questions (≥3 wrong answers, <30% accuracy, box ≤2). "Trouble Spots" button on Pool List with item count
  • Remediation API: GET /api/leitner/remediation (items), GET /api/leitner/remediation/count (lightweight count)
  • Daily Challenge: One random question per day from user's pools with +15 XP bonus for correct answers. Deterministic selection via crc32(userId + date) — same question per user per day
  • Daily Challenge API: GET /api/v1/daily-challenge, POST /api/v1/daily-challenge/answer
  • Migration V001600: Adds last_challenge_date (VARCHAR 10) and last_challenge_correct (BOOLEAN) to learning_user_stats

Changed

  • QuestionList.vue: "Generate with AI" button visible when AI provider is configured (checks /api/ai/available)
  • PoolList.vue: "Trouble Spots" button (orange, warning style) and inline Daily Challenge card with answer submission
  • SmartQueue.vue: New mode prop (queue | remediation) with conditional API endpoint, titles, and empty states
  • App.vue: Wires openRemediation event from PoolList to SmartQueue with mode="remediation", new smartQueueMode state
  • CourseDetail.vue: At-Risk section on Progress tab — collapsible card grid with risk badges and reason tags
  • routes.php: 9 new routes (ai: 4, leitner: 2, user_state: 2, course: 1) — 69 total

Security

  • AI Rate Limits: generate endpoint limited to 5/min, import limited to 10/min
  • AI Input Validation: Text length 50-50000 chars, word count capped at 3000 for LLM input
  • AI User Isolation: Task status checks verify userId matches task owner
  • At-Risk Access Control: Endpoint restricted to course instructors via validateInstructor()
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
Signaturedp2AlnFQwp1Cy8OCA/kE3gVqTvYhN9ORN/Oa86Lk0jjsYVLVFDHML+2ga4rlw5rjLTzojVtzB4BM1uJdyu/fRrdCUz9DhBBxIgNLNto8oIzu6HOYkE4TCB38quz5MGBbCVvZWnjmKb0ugYvzixvpy7ZPJnAWB5bwfj8C8AJqeEbbqqClkbjE4SAO9sxLfJbzDyWK7au4/It+H5gOO1yzXzUL6azX31M4acCwXZNI8AMRj6UHHqudtLsb9WgEC+cIHGEOfArbdIN9MDh1eDU3R17uuPjJw19g0KqZsc/NqGb/XuPUmHOHdcr8XzHDO4gYxp6FTEiMR8anCFogfEzpfrwGr/RAFzFBI0zfZ0+cbLHCNW3xrPVy/hOKGTlYXUHroalE6cvYdniSoXvQ09m6GlynsCauLZ8+hCb679ewlremqakW3E5RLtPL+xkP/ti0b8nev0Mdd9smil0YbrtPA6kJyk5JgllkPT3xhDDOtYrH+yrX2VNp5f4ypdWkPS8hM/SHId2W5q2D6K9XHVymde1aeA7AYPfa5/c62k7bvmwLbbNOWF4stKfq8MCA83RXASbfeHnAbdNbFltSPB9CT8oHBlBikwxk32iVKyoGEzuKZbAtZhC1x69ryyO0Uw5BAx6vexGDJUdgQb3PyeN5i2tV3Z2s3GCtHMjF+y0E8tY=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 1.6.0
Release Details
UpdatedFeb. 25, 2026, 7:30 p.m.
Changelog

Added

  • ConsistencyCheckJob: Daily background job that reconciles learning_user_stats against source-of-truth tables — self-healing for XP, level, sessions, mastered counts, and streaks
  • Composite Leitner indices: (user_id, box) and (user_id, next_review) on learning_leitner_items for faster aggregations and due-question queries (Migration Version001300)

Fixed

  • HIGH: LeitnerService::answerQuestion() now wraps box update, stats update, XP increment, and badge award in a single DB transaction — prevents partial writes on crashes
  • HIGH: Optimistic concurrency control on Leitner item update (WHERE box = :oldBox AND correct_count = :old AND incorrect_count = :old) — detects and rejects concurrent modifications including Box-5→5 lost updates
  • HIGH: Box-5 mastery bonus (+25 XP, +1 mastered, badge check) now only awarded on actual promotion (Box <5→5), not on repeated correct answers in Box 5 — prevents XP/stats inflation
  • HIGH: Badge notifications and Activity events now dispatched after transaction commit — prevents ghost notifications on rollback
  • MEDIUM: Demotion fallback (updateUserStats()) moved after Leitner item update — recalc now sees correct box value instead of overcounting
  • MEDIUM: syncLevel() deferred to after transaction commit — eliminates lock contention under concurrent reviews
  • MEDIUM: Cache invalidation moved after transaction commit (was inside write sequence, could serve stale data on rollback)
  • LOW: Multi-select answer validation uses batch IN query instead of N+1 per-answer queries

Performance

  • Leitner box aggregations (stats, mastery counts) use composite index instead of full table scan
  • Due-question queries benefit from (user_id, next_review) index — faster Leitner review loading
  • ConsistencyCheckJob processes max 500 users per run, oldest-updated first — all users eventually reconciled
  • ConsistencyCheckJob logs progress and catches per-user errors without aborting the batch
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureKQnhIvGaYFr9qdGYI0R0k4GLBar4u3swxmHkT+MfcE1phTVpyAm8O9s/s1TIz7qIDG3TA7CcjVDPTh57M2WysEi8/Yu8OZgE2pjJbsTOOssjRtFoGUqzyU4AR74azP5w3f/wdgk0jiIEQvOV+4aM3fENSOSktpfeGZzhch0xHUfON9kS2h4x8+8AqH9M/xkPJvS0dUIUoGNGYsug8qu3HkRcBxsH7n4hYzg3ycx+eL8vWpwfhFOhAV70cpcHOrK/oVz0ra4tl06LdPDNWeCB3AYCHU8hcehaPr+VsNJmgOdBoRf7JbesAu5YOB25qy340wJ+XlLonXe03NTq+xoG67Na0laU9cs+j56X856ik8G0UeT4vIywTObfh0iKmtqk/pUKzv0YopTYl/iSPtU/hTquoXnSYbEALoyPyh9aJpgpKXEn7d7qyoMo5/9Bx1owdXNxIi7gGtue1MMrFTkCIEm3/SMFWmA4XBXSRt2zP4sEUKaE1L8STzO57jFtpzt/WfC47ccCRktkLEkXDIIpwYwjHQYol7P/luO1OqUwJVefFnC52Fc4tJDrabMIbLqfOqwUPip0o18zcqsaNpTVyc6Mw+VLgO6MkP6lmdWfq0nvpBpKMu5e7cySJoT440xsvCBTWIIcfQyYcMJGxFscSondANcYYAg/ixhtChuTd5U=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 1.5.0
Release Details
UpdatedFeb. 25, 2026, 2:35 p.m.
Changelog

Added

  • Consolidated User State API: GET /api/v1/user/state — single endpoint replaces 4 separate calls (XP, streak, badges, progress)
  • Denormalized learning_user_stats table: O(1) reads for XP, level, streak, sessions, mastered counts (Migration Version001200)
  • Background Notification Job: NotificationJob (TimedJob every 4h) replaces widget-triggered notifications
  • Activity-App Integration: Badge unlock events appear in Nextcloud Activity stream with toggle in Activity settings
  • Timezone-aware badges: Night Owl and Early Bird badges respect user's Nextcloud timezone setting
  • XpService: Dedicated service for XP calculation, session XP increment, level computation
  • Response caching: User state endpoint cached for 30s per user via ICacheFactory
  • Composite index on learning_sessions(user_id, completed_at) for faster XP/streak queries
  • time_limit_seconds column on learning_sessions for Speed Demon badge support

Changed

  • BadgeService refactored from 430 to ~200 lines — XP/streak methods extracted to XpService
  • Dashboard Widget is now pure read-only (~140 lines) — no longer sends notifications as side-effect
  • AnalyticsDashboard.vue: 4 API calls consolidated to 1, with fallback to legacy endpoints for rolling deploys
  • countUp.js: Respects prefers-reduced-motion — immediately shows final value without animation
  • BadgeUnlock.vue: Added aria-live="polite" region for screenreader announcements
  • LeitnerService: Box-5 promotion updates denormalized total_mastered counter
  • TrainingService: Session completion updates denormalized stats via XpService

Fixed

  • HIGH: Leitner XP now synced to learning_user_stats — correct answers award 5 XP, Box-5 mastery awards 25 XP bonus
  • HIGH: Race condition in stats UPSERT — all INSERT paths wrapped in UniqueConstraintViolationException catch with UPDATE retry
  • HIGH: SQL injection in incrementSessionXp$currentStreak now uses createNamedParameter() instead of string concatenation
  • HIGH: NotificationJob memory exhaustion — fetchAll() replaced with streaming fetch() loop; N+1 due-count queries replaced with single batch query
  • HIGH: Level-race in XpService — stale getTotalXpFromStats() read eliminated; syncLevel() is monotonic (AND current_level < :newLevel) to prevent concurrent stale-level overwrites
  • HIGH: Stats INSERT fallback uses updateUserStats() full recalc — preserves historical XP, sessions, and mastered counts for first-write users
  • HIGH: total_mastered demotion — Box 5→1 transition now decrements total_mastered counter with updateUserStats() fallback for missing stats rows
  • MEDIUM: User state cache invalidated on every Leitner answer (not just correct), after share-badge awards, and at END of completeSession() (after all badge/streak writes)
  • MEDIUM: Migration backfill is per-step idempotent — each INSERT...SELECT skips existing users via NOT IN clause (safe for partial re-runs)
  • MEDIUM: Migration backfill includes Leitner-only users (no completed sessions but have reviewed cards)
  • MEDIUM: Frontend fallback triggers on any error (not just 404) for rolling-deploy resilience
  • LOW: Removed dead $totalMastered variable in LeitnerService (computed but never used)

Performance

  • Dashboard load: 4 XHR → 1 XHR for gamification data
  • XP calculation: O(n) SQL aggregate → O(1) stats table read
  • Notifications: synchronous widget side-effect → async background job
  • NotificationJob: filters to users active in last 30 days (skips dormant accounts on large instances)
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureOyK9vuzcblU3s5znaUXHm8WvkECMxcl4Jz5Xt1pNg4mTSvtO0R26bat9p9AMH75j70QPKj0FUJYI6jhObMU7X/lUu6b6+UhvO+RCtzO3/4OQ+gwULA4qSX4oWzmiG6obxmI51H0AnBOCwLb/JuVlbJJzDWuaSetL7fZX5oOEGoNuom7ZK3eoPovLG0d94fhldGhXBph8D6iUsySsmxuA1nU/nFE8kFTXAj89xHxPb1V6G4omNw+0K7mfjshDC++A44/zibOE/XvHYhLPmch/MvvHyPkJ7jMXzhOsSJYB+EAQMGEVMig4tOf6Cug9HFd3+adiHIPP+UpyI3R1lZP5YNSMsuvDviDHXI16P25mr87PZO6/XcOxbwRV+eG7aiRlRTtgvgbfCPQacIJfT+zzZzGytY2sa+htxiTis0sdQY2BdsdtlwD75NmlP37KEZFJuG6y+4TTV7kN6iTueYxfoYTcQ9irz82FrgNYTAgWAgNXJ6K9rnlHlBAc7ZU9+VT6tNzi39eJflwwLJKPjhPyBKiZ10ycIPwgJYLAtbTQdaYF7rmBDVM8xkS+KSjvyErD+vzV+lZRVy6G2zHZpiRhPSFHGc1ytWa3o180ukeo0fw2/fz29R/OcIxFupinMuAPeaoHE2yrGkHvg8yJSHq2Scen7Bp1AhNmiL8BIbSAHe4=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 1.4.0
Release Details
UpdatedFeb. 25, 2026, 10:28 a.m.
Changelog

Added

  • Achievements / Badges: 14 badges across 6 categories (sessions, performance, mastery, streak, social, fun)
  • XP & Levels: Experience points calculated from sessions, Leitner reviews, accuracy bonuses, and streak multiplier
  • Badge Unlock Overlay: Animated full-screen overlay with confetti when earning a badge
  • Analytics Dashboard: Achievements grid with earned/locked status, badge progress bars, XP level bar
  • Session Juice: Animated score count-up (countUp.js), Personal Best detection, improvement vs. average display
  • XP display: "+X XP" shown on all results screens (Training, Exam, Swipe, Leitner)
  • Nextcloud Notifications: Badge unlock notifications, streak-at-risk warnings, due card reminders
  • Badge progress tracking: API endpoint showing progress towards unearned badges
  • New DB table learning_user_badges (Migration Version001100)
  • 2 new API endpoints: GET /api/badges, GET /api/badges/progress

Changed

  • Training complete response now includes newly_earned_badges, xp_earned, is_personal_best, improvement, average_accuracy
  • Leitner answer response now includes newly_earned_badges when card reaches Box 5
  • Share creation now triggers badge check for "Sharing is Caring"
  • Streak endpoint now triggers streak badge checks
  • Dashboard widget sends streak warning and due reminder notifications
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureYuFGppj5TQhlB5nd+fXqJurxGQUn7l0FFIqbWhXJMf9xPEi/g3wKdx7qukdK2ttz1Rf5xEbSdoLsGj3q1F7V5DZ+4+4GmMewS+MlYE4GA9ESFIA6lHLYxThICgb3G2lEGtImmp57tmGv7dzAiPqIH4pEdC0KT/iO08+VGy5R5s1gS5r36nHSrytf5C7JUBSSmOg6rVpUFIccDaXv8zn1f9sWWAZw4pRptDx+X29foqY2Zt4S/Swuz/SOGWKyfhhPw/x6RHjB3vnJIxx64Oi4Rom8BNdrU911RtMUFXLcnxq4xsv7VO2wGMkjNHegpL2yNr68yJSEm0bOjmVih06XMpJDNC0KN4S0vwnUkDIm1t9Dk1zxSPK5ba/PlQrTFxMVwratZsc1Uz0b/VqUBaZTu9oEBMpBm4CTrSf8XK29CNQ5EQXAzMSB0UUz0TqPpL2rI9kkcejJl0cololPd8N5R5jJpQ5miguwm6UjfTrIJzaizm6MAtXg+wx/DFfTyaSS936v1JEaRGIy4XkeQ9ZAAnSANlx9o8HTyLnWc7v6EsdkSo/7q88h7FaFUrlgkb3Gv7CQLBIJZ2jLtYa/2jv5gHQrg3c9unmIPLK8njpwS5+KgMH1V8LsyvraUW9ejzfmGv/BuN+reNyvToEoP8JIFPLs7SP1areV9svmkEnjIT8=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 1.3.4
Release Details
UpdatedFeb. 19, 2026, 2:46 p.m.
Changelog

Security

  • CRITICAL: Close training-session oracle — startSession(exam) auto-completes open training sessions on same pool
  • CRITICAL: Defense-in-depth in submitAnswer/submitBatch — suppress correct_answer fields via cross-session check
  • HIGH: Strip explanation field from Question API during active exam to prevent indirect answer leakage
  • Rate-limits on ShareController and TranslationController write endpoints

Fixed

  • Leitner feedback shows hint when correct answers are suppressed during active exam
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureajCD73Wim+3CcebKFs72Co993wGojtfsPy8b+Gde+kx+EhPmDpzYEGdgbb54ZBqpDmJAroHIbaqZa0FfK8SwvFwC2JZ7WOp4xwOAjp+V7ruKvXu24MmzsH2wUp9U2ec+sO+EG9+ebsDELjaFEf2m6EMbRhw+/QUzsE51kaA10RaTwoNfTu29LLraGaEEFVWh9R5x5jbqNj9Wdvfq/vNNTp/XTm4SBLnAsD+7ymyMucfwHyn4ZYGspXdNd8v0HS6ZRe3JjtcOd+IjwEebZ4b2KPBCrnGs8sr+6zer7FItbLUOq2MxxdhaOml1yTQIPzeyuJPnFvmLJOw0FHJvsn/ZMMjCpByVSrf2MBua3yW4DcB/Z9m3yBwM3lQ98QUQDgmAfHwU1zG3P5ijvxFvaOz5XW3sFsCaktXfGtFfrMgUgbN8aee/7hZkA36Vi+zIUsbs+eExv5QvDn6bG21DrE8022vnfZ7gY9HFQESVMGsnZc9yqdeGJn9F09jScGcZvyinjtUUCe2/SRfjPHHa9JWvZ84pQuO+0OyAbvIEOlwz64r5qNatt47yoxAEzEUsu8oFQP2s+PX/Ni/yyEIWbH4LaK0qCPTulJKvujaq1fukSchT+9UMBVKxEebC672M1LtejtJnJfZVUp6WuAecz2QmBU4Va6WFDVLSkbAiz6ON/Jg=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0

Nextcloud 29

Learning 3.6.0
Release Details
UpdatedMarch 30, 2026, 4:56 a.m.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignaturejQ1Xdi636ODYsfoC8Sr3MU9s6K0a/PIOZvbo0ea4D/TpW/NiVKu49cZC8JLt8oFbyp2qVI27LVBXEplSF6V004H1NMqHdnC3zhqEbs/BzRH9CIKZW7Ouzs2Qj7obBiBiszYtamVpxRvxt3bfCiIfac9mn6yMJ2OvsqDohraIT5Mh84kyuW4ibPVun/8hX2/qndkvsQQvKnO+GL8UHRV1UhiSG/ezTdjZbinc0ZVU06oWXJFuP2YXpFPc+GHG8RMBP6N3KeqmK+rMZ6lKaZY5fl//pnr8AbASDKYK0MjWQFsqLrei9R/iQbsHqjlT3vT5o0Sssrw0m++5ysCJhTb0uEPgeLvg4DUOige/iCegy+NZFb+qgb7oezetZD8s/aWxZTR645y1MZS4va5kgdAVreT0rvHDDZvx9UuKr4smMvAxX1DEUKgzqP/AMellHcwb4BVE9pVwOENp5oKttpoJXKoH/Lnwu+o+1o5m4+JH/SHHGJBCmXYeehFscARZceC9lNYsBTHL+uKILOszxJXK0OkwrFCVCGTnXFfO0hn23gwjECPGP/zwB8OwlwedZXjaZkAMomIulAxghFIw5arSOoX85kv7bOlwerVJ7jfHs8GYIqBn3b+bWzVn5MQEumuUiKBi01WH7vbjn5Neuxi7YfSBkjJjeQFOFlGEmwFwcrs=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 3.4.0
Release Details
UpdatedMarch 28, 2026, 5:03 p.m.
Changelog

Changed — UX-Navigation Struktur

  • Instructor Tab Groups: 17 instructor tabs organized into 5 logical groups (Lernraum, Teilnehmer, Kommunikation, Wettbewerb, Verwaltung) with visual separators.
  • Abenteuer Standalone: Adventure mode promoted from Arena sub-mode to its own CourseDetail tab, independently gatable via mode_config.
  • Arena Submode Gating: Each Arena mode (Duel, Gameshow, Oldschool) individually hideable per course rules. Arena tab disappears when all sub-modes disabled.

Changed — Code-Hygiene & Settings

  • Settings Split: Instructors now see two sub-tabs in Settings: "Kurs-Verwaltung" (admin) and "Meine Einstellungen" (personal). Students see only personal settings.
  • Zeitreise Removed: Removed 1270+ lines of dead Zeitreise/HackThroughTime frontend code (component, characters, navigation, mode_config key).
  • German Labels: All UI-visible labels now go through t() translation. ModeIdentityBanner labels localized.

Added — Simulator-Praxis-Sessions

  • Practicum Engine: Pure-JS state machine for guided session management with localStorage persistence and browser-reload recovery.
  • 11 Practicum Sessions: Real-world IT scenarios across all 7 simulators (42 steps total). Firewall, DNS, and Routing get 2 sessions each.
  • PracticumRunner UI: New "Praxis" tab in every simulator with step-by-step instructions, context explanations, progress bar ("Schritt X von Y"), and score summary.

Added — Student Dashboard

  • Heute Screen: New default landing page for students with SmartQueue widget (due cards count + "Jetzt lernen"), Daily Challenge card, streak display, and daily progress.
  • Global Feed: Aggregates announcements from all enrolled courses chronologically with course-name badges and pagination.
  • Pools Navigation: Direct "Pools" tab in student main navigation — one click to PoolList.

Added — DevCloud Integration & Leitner

  • Talk Room Link: Instructors can set a Talk room token per course. Clickable link appears in course header, opens NC Talk in new tab.
  • Materials for Students: Students now see the Materialien tab (read-only) when a course has a material folder set.
  • Buddy Matching: New "Lernpartner" tab shows who can help with your topics and whom you can help, based on Telos help_offer/help_wanted data.
  • Course-Aware Tools: Werkzeuge tab filters simulators based on active course's enabled_tools. No course active = all tools visible.
  • Sprint Intervals: Instructors can activate sprint mode per course (4h/12h/1d/2d instead of 1d/3d/7d/14d Leitner intervals) for intensive courses.

Fixed

  • Badge Duplicate Crash: Session completion no longer fails with 400 when badge already exists. Fixed catch to use OCP\DB\Exception (NC 30 wraps Doctrine exceptions).
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
Signaturely5UiDEZdUJh6uSRREEijl3s87EIDnAeze3Y9KBfIECnaFvdafIwluTTl1XeyEvAaGshOHIXMmtfVvnYA9dMLyIj+jKvSeWlFKgbTsMS7hRvCiuqGcoFBPuOm8rDzIk6AXTGieQFgNIho9p68tRzQ2MF1mFJ/qnd3ayGiasJtT7W7rbUQYNAtzL3n4CpmxVZi4msMamM+K7c0O7e6/pmQJ3HCmtpjurPs8MJzAJQf5dyTQQuDa44T9aOSi4ucDAnS+aETU20UH0C8HWU15un+T0FeIP8//J8VxHFkP4g6BzrHF9mA52QKgUnUTkxYcH1qVhL7TcKjvfGScG3MjnSV92hvpVlEDZhMNAGkCwORAPMG22r4moEOmLse0r4/tMkSZ/4InV5kc3NYmZFzigT3yBnZGmsTxyvVb1PdAGi0uNhIvS2Ay8nq6tARMz1lFMv3iz8y9MmwSwIsyMGIUq5xWG49/Fj9rqB6HvEj7lmojVhuGm4eBEiJ6dnuyu91l1O5sML68xbiaHk1lv+Q4Qy6THYKX5MKFcCTbFxfs+4acZRgquRLpLFDGkXtpJMs4XMjSCygcdKQy2bk6TSnncyhPFUiMCDkhavR/QICmtQw/RBJatqdf9+f6LT87zhA4g2jO9XXq6EcoaSTn0k7aS3eghXGRHumpYSNCDMXxuPnjI=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 3.0.0
Release Details
UpdatedMarch 24, 2026, 6:55 a.m.
Changelog

Added — Story RPG "Abenteuer" Mode

  • Story Engine: Full campaign-based RPG learning mode with branching narratives, skill checks, and character classes (Architect, Security, SysAdmin, Helpdesk). 20 campaigns across CompTIA Network+, Security+, CySA+, Linux+, and A+.
  • KI-Erzähler: Gemini-powered dynamic narrator with freetext player actions, NPC dialog generation, and role-based prompts. Fallback to static text when AI unavailable.
  • Skill Checks: In-story quiz phases with 3 questions per check, batch submission, pass/fail branching to different scenes.
  • 20 Campaigns: Real-world IT incident scenarios — SolarWinds, WannaCry, Log4Shell, Colonial Pipeline, Equifax, plus 6 Security+ exam-oriented campaigns (Phishing, Zero Trust, Crypto, Compliance, IR, Cloud) and an AI Security campaign.
  • Coop Mode: Infrastructure for multiplayer campaign sessions (UI placeholder, backend ready).

Added — "Zeitreise" Hack Through Time

  • 7 Epoch Campaign System: Phone Phreaking (1960s), WarGames (1980s), The Worm (1990s), Bobby Tables (2000s), Shadow Brokers (2010s), Supply Chain (2020s), Quantum Dawn (Future).
  • Period-Accurate CSS Themes: Each epoch has its own visual theme (terminal-green, amber-on-black, retro-web, etc.).
  • CHRONOS Guide: AI narrator character that guides players through hacking history.
  • Museum Facts: Historical sidebars with real dates, events, and technical details.
  • Character Classes: Epoch-specific roles (Phreaker, Hacker, Script Kiddie, Analyst, etc.).

Added — Visual Identity System

  • Design Tokens: CSS custom property layer (--lnc-*) with dark/light scopes and motion utilities.
  • 13 Character Registry: SVG silhouette avatars with emotion states (idle, celebrate, alert) for all NPCs.
  • Campaign Intro Animation: Full-screen intro with title, difficulty badge, and character reveal.
  • Dialogue Stage: NPC dialog component with portrait, speech bubble, and emotion tags.
  • Paper & Circuits Narrative Skin: Dark theme for adventure mode with subtle circuit-board patterns.

Added — RAG & Document Intelligence (v4.1)

  • Document Upload & Extraction: Instructors can link Nextcloud folders as course material, scan for files, and extract text from PDF/Markdown.
  • Chunking Pipeline: Automatic text chunking with keyword extraction for semantic search.
  • Multi-Source RAG Context: VirtuProf answers now cite course materials with [Quelle: filename, Kap. X] format.
  • 4000-Token Budget: Smart context window management prioritizing relevant chunks.

Added — Oldschool Board Games (v5.0)

  • Lernwürfel: "Mensch ärgere dich nicht" inspired board game with dice rolls and question challenges.
  • Wissensturm: Trivial Pursuit tower game with category-based progression.

Added — Personal Learning Bot (v4.0)

  • GeminiService: 5-layer security stack (API key isolation, input sanitization, output filtering, rate limiting, audit logging).
  • VirtuProf Chat: AI-powered learning assistant with chat-first UI, language auto-detection, and chat memory.
  • Note Generator: Gemini-based topic summaries saved to Nextcloud Files.
  • Lernprofil: Passive user learning profile with weekly study plan generation.
  • Auto-Triggers: Exam auto-notes, wrong-answer threshold alerts, weekly plan background job.
  • Ticket Triage: AI-powered support ticket classification and draft FAQ responses.
  • AI Consent: Opt-in consent overlay before first AI interaction, GDPR-compliant.

Added — Tools

  • Subnet Calculator: Browser-based IPv4 subnet calculator with CIDR/mask input, binary display, and VLSM planner.
  • Subnetting Question Pool: 50+ subnet calculation practice questions.

Added — Quality & Testing

  • ESLint: Vue/JS linting with no-v-html error rule, 0 errors enforced.
  • Pre-Push Hook: 4-gate quality check (Security scan, ESLint, Vitest 67 tests, PHPStan Level 5).
  • Playwright Browser Tests: 67 automated checks covering navigation, campaigns, time travel, tools, VirtuProf, security. 52 PASS / 11 FAIL / 4 SKIP.
  • PHPUnit: 12 service-level unit tests (Training, Leitner, Analytics, Course).
  • Test Strategy: 4-gate pyramid documented in CLAUDE.md.

Fixed

  • Campaign skill-checks now always use pre-loaded questions from scene response (no separate API call).
  • Campaign start always creates fresh session (no stale resume from previous play).
  • Missing Abenteuer/Oldschool/Zeitreise toggles in course mode settings.
  • WannaCry campaign: corrected from email dropper to SMB worm narrative.
  • PBQ subtype auto-detection from config structure when pbq_subtype not set.
  • Empty skill-check pools handled gracefully (skip to next scene instead of crash).
  • Narrative garbage fallback when Gemini returns malformed text.
  • AI rate-limits on VirtuProf available()/status() endpoints.
  • ESLint: empty catch blocks, v-if with v-for separation, escaped quotes in templates.

Security

  • Gemini language mirroring prevention (no prompt echo).
  • Story mode injection guards on freetext actions.
  • Story mode rate-limits (10 starts/min, 60 scenes/min).
  • Pre-push security scan for hardcoded secrets.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureMWUO0JmVVcGH0NNuBs36k/SJ6luN5fkUQPaxu+CxY+5FdW/X4uAAD6NgGuM/jQsqSyKsns4V1UgbtV15xhOlHyO8/fOrnIeU1tifv52U+Sud8OdnMeCy9eQ8TmbbZwrsxT7er+1hmRgrJPC+b1++4bWDE57D6tJ85xAeJ4TeNMkSQDAy8PGI7PnhG1ae0Xx4DAXAjIm6+GZqeletoRknfiLPpLyUcF2EMOqOxdWjXhDVEGhXMLgPUcJnLPi6avTjN/CCEK1awEzVr4IhaUUI86Dub/68KQmeOFZRusIARkqmY5Bq0ER9xzcWKf26pyl10xr1GJUh2sQB+Utw3cszgq6VPS8KdsVJ3a15+uqdinFxo8QHhJz409tF9RdQnqye+0WJ2qa4d4PbndPeAiAcu3z27tlmVDmwouvxrYco4wDgUSIW3lzayLjR8IiONHylfIZ56idwu/EAYEU2u9/0oKVDeGi+Izt6z4/aX9iTjuV29T1uB1e2aasUIWyRttCFBZ01PIaJqMfubHMvRmDrcjb9U4OKUTqLg58u29eeQMimHB9O3ij0n6zQn2MJdxnnahO5seMg5tuLwRETHbcxQ0yNLskSLvSDgIa8vBr/leUgUtBPUCbIx4msuV3Tuy7HpA9Lg+3C7ZkqOIne6k0vakIc4KPjAPL/SLBwZusxfDI=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 2.6.0
Release Details
UpdatedMarch 17, 2026, 5:58 p.m.
Changelog

Added

  • Calendar Token: Per-user ICS subscription token for external calendar apps. GET /api/v1/user/calendar-token returns token + subscription URL. POST /api/v1/user/calendar-token/regenerate invalidates old token. Token stored in NC preferences (never expires until regenerated).
  • Public ICS Feed: GET /api/v1/calendar/{token}.ics — unauthenticated ICS endpoint for calendar subscriptions. Uses token-to-user reverse lookup via oc_preferences.
  • Calendar Sync in Personal Settings: ICS URL field with one-click copy and regenerate button.
  • ICS UID domain fix: UID fields now use actual NC hostname (parse_url(getBaseUrl(), PHP_URL_HOST)) instead of literal @nextcloud.
  • AI Explain button: POST /api/ai/explain schedules a text2text task explaining why an answer is correct/incorrect. "💡 Explain this" button appears after answering in LeitnerMode and TrainingMode (only shown when AI is available).
  • At-Risk CSV Export: GET /api/courses/{courseId}/at-risk/export/csv — downloads at-risk student list as CSV (Name, Risk Level, Risk Reasons, Accuracy, Last Active). Export button in course progress tab.
  • Batch Pool Assignment: Add-pool modal in CourseDetail now supports multi-select (checkboxes) — select multiple pools and add them all with one click.

Changed

  • ExportController: Replaced anonymous class with DataDownloadResponse for ICS response (cleaner code, no custom render() override needed). ICS body extracted to buildIcsBody() — shared by authenticated and token-based endpoints.
  • AIService::getTaskStatus() now includes output (raw text) in status response alongside questions array — needed for explain results.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignaturegpWcIhT4IeeSqVyKoOjXGch+flHYM9TICkDbyl7oRxuCOBH6sfYOwu5upyqwzGKl05TIRX2bqIrJiNj+ULif8rORhf3hvt03mhVuDCU1RuH9AbsD9VNvyw5Rf69FDXWD/44jH4JBjQHhD0E9MoY/Kud6Cog6W7SmIXEmGlHNz7mbopa2OoZZws6AA+SwjkDvK9BbvDrae3brEkSc2udTdi2HqSa8tbKPouwE3vdEdHWJWF3/j7P+4GM5cDXIT0B4g9eyL8r8Q1AKO0Xu/1pGPddNmeDz4gK4cQFGJF1KhhgAMEA7EM9/7wkMW6hrONfD57PJywCdeJhMTGVgGbjzLRreJ57GuI4jPhjqumOsiXRS3Evyn5LmO/q7FXn54hl1VBZBb7Kdj/t46wZzeV+vkKP/TFu2a/Amr99KFDWnNhKaF0eg/xYBAyGdNE162L7lHjXUlu5o6d1iO8i8y1NQoexyta7cqo019m4/BjhAr1QWAo5QsFJQ6hD7t8oA6Es50yFIi39Vzn2vFrkNuoUkrGtUNUH5mxEoDTCaHeLKBokStXztfaXsZzRBsi7Eem70Hqh65PQ4GAA7/BIKksrGR9XXRbbQG6ZBa1NN2iZaPDNF6t+zbq9EcfpITq7aLOthuU2OEkW4zm2Ds6wrxE+gFU+fxCePWR5H7g3OJuOcwjk=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 2.5.0
Release Details
UpdatedMarch 16, 2026, 8:57 a.m.
Changelog

Added

  • Daily missions: mission progress model plus claim endpoint (GET /api/v1/missions, POST /api/v1/missions/{missionKey}/claim).
  • Mission XP claims table: Migration Version002000 adds learning_user_mission_claims with one-claim-per-mission-per-day guarantee.
  • Streak freeze tokens: weekly reset token support in streak calculation (streak_freeze_tokens, last_freeze_reset_week in learning_user_stats).
  • Badge tiers: new bronze/silver/gold/platinum tiers for session count, mastery count, and streak milestones.
  • Analytics UI updates: Daily mission cards with claim action and freeze-token visibility.

Changed

  • Streak handling: streak computation can bridge one missed day when freeze token is available; token is consumed on activity-side calls.
  • App version: bumped to 2.5.0.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureBtgrr+hdTfM0f4h9yPsjjpUL18GMWeoMLCyfuSk+f0aj+R2D8WpUaWos8YBBAdFtoTYGKeykyLd+Ww/8ckGusCAhrB8BiV2IDSKhna3EreyedyjQ7tI9KXrif6dvkN/8FQB3JsWSXyLujapZYGX0lsvVxwf6rzmLIsOhC5gAGD+aCHwsZDxzi2bWVr3iyMaQq1rqd7HxGMUZq6E67lRr2bKCXTK46QEX1TnGw/jtv7gMg5Kq0pG39oRgOTtpjNc/0VJR/KUw4PujcVYMaOyLOlJlNjN0bZjgsgyijcACSi5L3gF8/M7yKvHFwZK/MKaWozRsTu1fJBtvrblhCBeJvoAGanAW+1gCE4SyNzClU/ToY/utQGJWUFNhARuMHjmqkAiFjfoev57XvvKIlC3mBF9U8oRIL9uQY+O6D1d1oynxvyVLvCmMOzw36xzHcEr7Hygu6PJUEOS79QkROIBiivsT91fAgRyFnStnbrM+0Az8Jiyis1mRU3lzOOSEIomZoapMevwMgngBQUwfUPDeQysmaz5DdpmDNW6oHbjV8WwIItNkK2sZm4VoDMud+PyGbLBIG/3HBjQVS1Hrhc4cjpoBgVLASsIVh6qIzQAsJnpagFsxxAm9azNMiNm1vgvcqRUnVStk0hi4B4pO3pr76/K/h3m7Y7MJDu0n736r4Ww=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 2.2.0
Release Details
UpdatedMarch 10, 2026, 11:40 a.m.
Changelog

Fixed

  • Course Pool Access: Course members and instructors can now access pools assigned to their courses. Previously only pool owners and explicitly shared users had access, causing "Pool not found" errors for enrolled students.

Changed

  • PoolService: Extracted findPoolRow() helper, added hasCoursePoolAccess() fallback in find() method
  • 5 Services updated: LeitnerService, PoolService, QuestionService, TrainingService, TranslationService — all hasPoolAccess() methods now check course membership as a third access path

Technical

  • 5 changed files, 165 insertions, 12 deletions
  • No database migration needed — uses existing learning_course_pools and learning_course_members tables
  • Course pool access grants read-only permission (permission: 'read')
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureFBngcENmOE/Ve20qo9FeQJkBZjOrpUJTFGqEhPB/hOp0PGIfvsZVFJylcJKnv59uVAjcElJIo3wtL5tG9b2sz0PtW60Fz24pb4NLxMewiUPNxKvBX7C7wcKNpf+H1nk3i/aGYPOiTZd6YTtMut1bDQ9zFdlXVxWjUCMAEZFJxMo0TG2IGD+bB+r2NGyh0okA2DN7+FVhCuRg/jF32BMFTtXD1X3qvmc2cQ6ls3F3hnDMrmpifXb2wzCAfAfBUyYoVCbwWyRL5Ig4iTZlk/TB5GmiPl2lncIGB3cMu8Ad0cJz26Ch+TMdbaSJdRtDCxQvCr9EwsL4mWR2BvsTqMUdybDA2C2aqPfRVjBg6oyP45C6z8KgE2XsMxzyzOI+E6leQ80nmmgBDx63+Yns4nXyAbFVegYan+8mQGm7PLDO3gtdossWxTiB3tptBTTljdSM3v+eHkncaTmIl/o1BOtMdznuhCHFUatKW1Bt+cDNBZg6gweghbJmBXfj9sFyqL/L+nZodDqXO5avLstGJoC0p7S5TmTM2L75kjKJxJe1IRMQUUldzH17NxDPeFP5bcPNZbPrujsFhjKNXFGzv2knPfZoV4oIGPbMQ+FNTWOn0jU6yik2o6sHsSMZfMMvr/MLwGdamYHOSbQba5FKE6FJh7LljZ1vaJqhwRAR08JFptE=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 2.1.0
Release Details
UpdatedFeb. 26, 2026, 3:56 p.m.
Changelog

Added

  • Free Text Questions: New open question type — users type free-text answers instead of selecting from choices. Fuzzy matching (case-insensitive, Levenshtein distance ≤2 for short answers, substring matching for long answers)
  • CSV/JSON Export: Download question pools as CSV or JSON files. Roundtrip-compatible with import — export then re-import produces identical questions
  • ExportController.php: New controller with exportCsv() and exportJson() endpoints, DataDownloadResponse for browser download
  • XP Streak Multipliers: Tier-based XP bonuses replace old linear formula — 1.5x at 3-day streak, 2x at 7-day, 3x at 30-day streak
  • XP Multiplier Badge: Visible multiplier indicator (1.5x / 2x / 3x) in Pool List when streak bonus is active
  • Open Question Import: CSV format question,model_answer,open and JSON "type": "open" with single model answer
  • Open Question in all modes: Training, Leitner, Smart Queue, Exam (textarea + batch submit), Daily Challenge — SwipeMode filters out open questions

Changed

  • XpService: getStreakMultiplier() and applyMultiplier() replace linear 1.0 + (streak * 0.01) formula
  • LeitnerService: All XP awards (correct answer, mastery bonus, daily goal) now use streak multiplier via XpService
  • UserStateController: state() response includes xp_multiplier field; answerChallenge() applies streak multiplier to challenge XP
  • QuestionForm.vue: New "Free text" answer type option with model answer textarea
  • QuestionList.vue: "Freitext" badge for open questions, model answer display, Export CSV/JSON dropdown
  • ImportDialog.vue: Help text updated with open-question format examples for both CSV and JSON
  • SwipeMode.vue: Filters out open questions (not compatible with swipe/tap interaction)
  • routes.php: 2 new export routes (71 total)

Technical

  • 1 new file (ExportController.php), 22 changed files
  • No database migration needed — question_type VARCHAR(20) already supports open, answer_ids TEXT stores JSON
  • QuestionService::isOpenAnswerCorrect() static helper used by TrainingService, LeitnerService, and UserStateController
  • Rate limit on export endpoints: 10 requests per 60 seconds
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureHyyUtHF7C32M+YZc15dn2kRI/DltaewXzt5Im3Zu3rPS12Q+ICmOK+AhT/TicLBFR3Zr21BjtyhcjcrFf5JmXIG9c65OEEyK2ApbXAa5HfFFhUbPIAjj+z2eG3F2+71DrFluPVg5imtKCJ1+zmZfNC3EFI+UFhUFPGor76KTJphQrT01qMaD21XuWlbr59lOI3PLuV+qENWBC2pvQMcBDTyfDEpanPR/NRZ9I31TqA5qj9d6su9UYxW0AO/21Dz6cTvUx6AeJksLyRjQsGEMZhvp5Lv3k3X4fiBp4q6j/VKtt/R89eCbNAjEcubZwYsAx6TA6gK1FtfOwO++7pU4EPzDlKFTBUpqoXJFvelF+SRg5h5oNJYU4zoJRCRV7IOIwliR//2G4Rh5bKenEELEhJ47l8lHfdw2vAkY1zMcOFRoTmda27VPD4W+uOBnd+7sXUSlPLCPRZYmZTMuFehgnPvLM8jN7e57ldBnzYw2AfSkS8vFmsIiT/TqhUknc7kFUAMD3Cz0PmofWWM+CbglCnD/HURBJW6FYX8dnA7fJhkyi7wSeC9nFc9TAU3jlVRiL/RA/wAmlxP2ZXJUk4JpuzxsdAwuBXkDRgnrmjnz31WdiqAI9f8HOPh9vc9ttbbMXP35llqMTa3T9NfnMZR0pkY0SKXcmSbAK3IHsv4dPI0=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 2.0.0
Release Details
UpdatedFeb. 26, 2026, 11:35 a.m.
Changelog

Added

  • Role-Based Navigation: Students start at Courses view (no Pools tab), instructors keep both tabs. App title simplified to "Lernen" for students
  • Onboarding Hint System: 7 dismissible info cards (localStorage-based) explaining Smart Queue, Leitner boxes, Daily Goal, Daily Challenge, and welcome messages for both roles
  • hintMixin.js: Reusable Vue mixin for localStorage-backed hint dismiss/check across all components
  • Mode Descriptions: One-line explanation shown below the active mode selector (Training, Leitner, Wahr/Falsch, Exam, Stats, Manage)
  • Pool-from-Course Navigation: "Back to Course" button when opening a pool from course context (instead of losing context by switching to Pools view)

Changed

  • App.vue: Mode selector filtered by role — students see only Train/Leitner/Wahr-Falsch/Exam (no Stats, no Manage)
  • PoolList.vue: Create Pool button, Share/Edit/Delete actions hidden for students. Better empty state text
  • CourseList.vue: Student empty state now explains that the instructor enrolls them
  • LeitnerMode.vue: Box labels improved — "Neu — taeglich wiederholen", "Lernphase — nach 1 Tag", "Bekannt — nach 3 Tagen", "Gut — nach 7 Tagen", "Gemeistert — nach 14 Tagen"
  • SmartQueue.vue: Better empty state ("Open a pool and start the Leitner system"), ready state shows priority sorting info
  • PoolList.vue: "Jetzt Lernen" → "Start learning", "Trouble Spots" → "Trouble spots" (consistency)
  • de.json: ~60 new German translation keys for all hints, mode descriptions, empty states, and v1.8/v1.9 UI strings
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureX22wHYsHapYtxGW+/4w3wuihpu0uy3Mi5x076ajJx5VbizQVWSF8uURw2bu+y/pQn4GZxinHK/JxHWqcCdU86MB3ThayzDX7ySTGx/z016eudjyAYAYGPx84KJ+ciGXFFiiS+QA7ebnPjnm/8O365ve4tVtv+7EqjHzOwntJnlT+GL9FAYiUS1z5UzFSuI02nNz3GXc3PG1NeWf3M1iAG9Q26zjv3n4q0mV1/GstjWvuJ5bAH/C8eNWtumTPjDq0/sBza15+DPzBtTuSDanieXSPi+EG2geKozRNe7fWBCWflVScnK38+9ke0vQsC+cgNMgsS+t9Qquv1IHQqbQLzEpFRq88LcWfar9VH0YFG9E1FaX2XrbF+59lZdM39NvwLrOCIfJFt7Qpnv/9Zkv4voezhaST8lKLI7FC/jCNhDcN6IpLPj3a8VuYsyMfu2vq3A1VDAyq7qb7T0l7T/FTRVQG2DlxZLnRMSMsQgFHmbiP2/5S553/N9JErAgrY85op8ucOCv83ysvUOYLVNtXHbPq9YyH+7GXDK0OsIvIfoK+gsaj/qcBt2x88FH1SlpY0VLDkZ7huBC21rvKTV0lT3sXyNo0H2HKPGR14Xm8DsN5GCIaljf0ErOJRfsxX9nUpDqU5aqWk8ABK+kyTldmwViOizIzc0uMMdeu0G7bUWE=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 1.9.0
Release Details
UpdatedFeb. 26, 2026, 9:25 a.m.
Changelog

Added

  • AI Question Generator: Paste text (lecture notes, textbook excerpts) and let AI generate multiple-choice questions. Three-step workflow: input → AI generation → editable preview → bulk import into pool
  • AIService.php: NC TaskProcessing API (NC 30+) with TextProcessing fallback (NC 29) — runtime detection, no app-level API key management
  • AIController.php: 4 new endpoints — GET /api/ai/available, POST /api/ai/generate, GET /api/ai/status/{taskId}, POST /api/ai/import/{taskId}
  • AIGenerator.vue: Full wizard with textarea input, question count slider (5-30), language selector, polling progress, editable preview with select/deselect all, inline editing of questions and answers
  • At-Risk Early Warning: Instructors see which students are falling behind on the Course Progress tab. Rule-based risk scoring with 5 weighted signals (inactivity >7d, accuracy <50%, box-1 stall >60%, lost streak, <3 sessions in 14d)
  • At-Risk API: GET /api/courses/{courseId}/at-risk — returns students with risk_level (high/medium), risk_reasons array, last_active, accuracy
  • Remediation Queue: Focused practice on hardest questions (≥3 wrong answers, <30% accuracy, box ≤2). "Trouble Spots" button on Pool List with item count
  • Remediation API: GET /api/leitner/remediation (items), GET /api/leitner/remediation/count (lightweight count)
  • Daily Challenge: One random question per day from user's pools with +15 XP bonus for correct answers. Deterministic selection via crc32(userId + date) — same question per user per day
  • Daily Challenge API: GET /api/v1/daily-challenge, POST /api/v1/daily-challenge/answer
  • Migration V001600: Adds last_challenge_date (VARCHAR 10) and last_challenge_correct (BOOLEAN) to learning_user_stats

Changed

  • QuestionList.vue: "Generate with AI" button visible when AI provider is configured (checks /api/ai/available)
  • PoolList.vue: "Trouble Spots" button (orange, warning style) and inline Daily Challenge card with answer submission
  • SmartQueue.vue: New mode prop (queue | remediation) with conditional API endpoint, titles, and empty states
  • App.vue: Wires openRemediation event from PoolList to SmartQueue with mode="remediation", new smartQueueMode state
  • CourseDetail.vue: At-Risk section on Progress tab — collapsible card grid with risk badges and reason tags
  • routes.php: 9 new routes (ai: 4, leitner: 2, user_state: 2, course: 1) — 69 total

Security

  • AI Rate Limits: generate endpoint limited to 5/min, import limited to 10/min
  • AI Input Validation: Text length 50-50000 chars, word count capped at 3000 for LLM input
  • AI User Isolation: Task status checks verify userId matches task owner
  • At-Risk Access Control: Endpoint restricted to course instructors via validateInstructor()
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
Signaturedp2AlnFQwp1Cy8OCA/kE3gVqTvYhN9ORN/Oa86Lk0jjsYVLVFDHML+2ga4rlw5rjLTzojVtzB4BM1uJdyu/fRrdCUz9DhBBxIgNLNto8oIzu6HOYkE4TCB38quz5MGBbCVvZWnjmKb0ugYvzixvpy7ZPJnAWB5bwfj8C8AJqeEbbqqClkbjE4SAO9sxLfJbzDyWK7au4/It+H5gOO1yzXzUL6azX31M4acCwXZNI8AMRj6UHHqudtLsb9WgEC+cIHGEOfArbdIN9MDh1eDU3R17uuPjJw19g0KqZsc/NqGb/XuPUmHOHdcr8XzHDO4gYxp6FTEiMR8anCFogfEzpfrwGr/RAFzFBI0zfZ0+cbLHCNW3xrPVy/hOKGTlYXUHroalE6cvYdniSoXvQ09m6GlynsCauLZ8+hCb679ewlremqakW3E5RLtPL+xkP/ti0b8nev0Mdd9smil0YbrtPA6kJyk5JgllkPT3xhDDOtYrH+yrX2VNp5f4ypdWkPS8hM/SHId2W5q2D6K9XHVymde1aeA7AYPfa5/c62k7bvmwLbbNOWF4stKfq8MCA83RXASbfeHnAbdNbFltSPB9CT8oHBlBikwxk32iVKyoGEzuKZbAtZhC1x69ryyO0Uw5BAx6vexGDJUdgQb3PyeN5i2tV3Z2s3GCtHMjF+y0E8tY=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 1.6.0
Release Details
UpdatedFeb. 25, 2026, 7:30 p.m.
Changelog

Added

  • ConsistencyCheckJob: Daily background job that reconciles learning_user_stats against source-of-truth tables — self-healing for XP, level, sessions, mastered counts, and streaks
  • Composite Leitner indices: (user_id, box) and (user_id, next_review) on learning_leitner_items for faster aggregations and due-question queries (Migration Version001300)

Fixed

  • HIGH: LeitnerService::answerQuestion() now wraps box update, stats update, XP increment, and badge award in a single DB transaction — prevents partial writes on crashes
  • HIGH: Optimistic concurrency control on Leitner item update (WHERE box = :oldBox AND correct_count = :old AND incorrect_count = :old) — detects and rejects concurrent modifications including Box-5→5 lost updates
  • HIGH: Box-5 mastery bonus (+25 XP, +1 mastered, badge check) now only awarded on actual promotion (Box <5→5), not on repeated correct answers in Box 5 — prevents XP/stats inflation
  • HIGH: Badge notifications and Activity events now dispatched after transaction commit — prevents ghost notifications on rollback
  • MEDIUM: Demotion fallback (updateUserStats()) moved after Leitner item update — recalc now sees correct box value instead of overcounting
  • MEDIUM: syncLevel() deferred to after transaction commit — eliminates lock contention under concurrent reviews
  • MEDIUM: Cache invalidation moved after transaction commit (was inside write sequence, could serve stale data on rollback)
  • LOW: Multi-select answer validation uses batch IN query instead of N+1 per-answer queries

Performance

  • Leitner box aggregations (stats, mastery counts) use composite index instead of full table scan
  • Due-question queries benefit from (user_id, next_review) index — faster Leitner review loading
  • ConsistencyCheckJob processes max 500 users per run, oldest-updated first — all users eventually reconciled
  • ConsistencyCheckJob logs progress and catches per-user errors without aborting the batch
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureKQnhIvGaYFr9qdGYI0R0k4GLBar4u3swxmHkT+MfcE1phTVpyAm8O9s/s1TIz7qIDG3TA7CcjVDPTh57M2WysEi8/Yu8OZgE2pjJbsTOOssjRtFoGUqzyU4AR74azP5w3f/wdgk0jiIEQvOV+4aM3fENSOSktpfeGZzhch0xHUfON9kS2h4x8+8AqH9M/xkPJvS0dUIUoGNGYsug8qu3HkRcBxsH7n4hYzg3ycx+eL8vWpwfhFOhAV70cpcHOrK/oVz0ra4tl06LdPDNWeCB3AYCHU8hcehaPr+VsNJmgOdBoRf7JbesAu5YOB25qy340wJ+XlLonXe03NTq+xoG67Na0laU9cs+j56X856ik8G0UeT4vIywTObfh0iKmtqk/pUKzv0YopTYl/iSPtU/hTquoXnSYbEALoyPyh9aJpgpKXEn7d7qyoMo5/9Bx1owdXNxIi7gGtue1MMrFTkCIEm3/SMFWmA4XBXSRt2zP4sEUKaE1L8STzO57jFtpzt/WfC47ccCRktkLEkXDIIpwYwjHQYol7P/luO1OqUwJVefFnC52Fc4tJDrabMIbLqfOqwUPip0o18zcqsaNpTVyc6Mw+VLgO6MkP6lmdWfq0nvpBpKMu5e7cySJoT440xsvCBTWIIcfQyYcMJGxFscSondANcYYAg/ixhtChuTd5U=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 1.5.0
Release Details
UpdatedFeb. 25, 2026, 2:35 p.m.
Changelog

Added

  • Consolidated User State API: GET /api/v1/user/state — single endpoint replaces 4 separate calls (XP, streak, badges, progress)
  • Denormalized learning_user_stats table: O(1) reads for XP, level, streak, sessions, mastered counts (Migration Version001200)
  • Background Notification Job: NotificationJob (TimedJob every 4h) replaces widget-triggered notifications
  • Activity-App Integration: Badge unlock events appear in Nextcloud Activity stream with toggle in Activity settings
  • Timezone-aware badges: Night Owl and Early Bird badges respect user's Nextcloud timezone setting
  • XpService: Dedicated service for XP calculation, session XP increment, level computation
  • Response caching: User state endpoint cached for 30s per user via ICacheFactory
  • Composite index on learning_sessions(user_id, completed_at) for faster XP/streak queries
  • time_limit_seconds column on learning_sessions for Speed Demon badge support

Changed

  • BadgeService refactored from 430 to ~200 lines — XP/streak methods extracted to XpService
  • Dashboard Widget is now pure read-only (~140 lines) — no longer sends notifications as side-effect
  • AnalyticsDashboard.vue: 4 API calls consolidated to 1, with fallback to legacy endpoints for rolling deploys
  • countUp.js: Respects prefers-reduced-motion — immediately shows final value without animation
  • BadgeUnlock.vue: Added aria-live="polite" region for screenreader announcements
  • LeitnerService: Box-5 promotion updates denormalized total_mastered counter
  • TrainingService: Session completion updates denormalized stats via XpService

Fixed

  • HIGH: Leitner XP now synced to learning_user_stats — correct answers award 5 XP, Box-5 mastery awards 25 XP bonus
  • HIGH: Race condition in stats UPSERT — all INSERT paths wrapped in UniqueConstraintViolationException catch with UPDATE retry
  • HIGH: SQL injection in incrementSessionXp$currentStreak now uses createNamedParameter() instead of string concatenation
  • HIGH: NotificationJob memory exhaustion — fetchAll() replaced with streaming fetch() loop; N+1 due-count queries replaced with single batch query
  • HIGH: Level-race in XpService — stale getTotalXpFromStats() read eliminated; syncLevel() is monotonic (AND current_level < :newLevel) to prevent concurrent stale-level overwrites
  • HIGH: Stats INSERT fallback uses updateUserStats() full recalc — preserves historical XP, sessions, and mastered counts for first-write users
  • HIGH: total_mastered demotion — Box 5→1 transition now decrements total_mastered counter with updateUserStats() fallback for missing stats rows
  • MEDIUM: User state cache invalidated on every Leitner answer (not just correct), after share-badge awards, and at END of completeSession() (after all badge/streak writes)
  • MEDIUM: Migration backfill is per-step idempotent — each INSERT...SELECT skips existing users via NOT IN clause (safe for partial re-runs)
  • MEDIUM: Migration backfill includes Leitner-only users (no completed sessions but have reviewed cards)
  • MEDIUM: Frontend fallback triggers on any error (not just 404) for rolling-deploy resilience
  • LOW: Removed dead $totalMastered variable in LeitnerService (computed but never used)

Performance

  • Dashboard load: 4 XHR → 1 XHR for gamification data
  • XP calculation: O(n) SQL aggregate → O(1) stats table read
  • Notifications: synchronous widget side-effect → async background job
  • NotificationJob: filters to users active in last 30 days (skips dormant accounts on large instances)
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureOyK9vuzcblU3s5znaUXHm8WvkECMxcl4Jz5Xt1pNg4mTSvtO0R26bat9p9AMH75j70QPKj0FUJYI6jhObMU7X/lUu6b6+UhvO+RCtzO3/4OQ+gwULA4qSX4oWzmiG6obxmI51H0AnBOCwLb/JuVlbJJzDWuaSetL7fZX5oOEGoNuom7ZK3eoPovLG0d94fhldGhXBph8D6iUsySsmxuA1nU/nFE8kFTXAj89xHxPb1V6G4omNw+0K7mfjshDC++A44/zibOE/XvHYhLPmch/MvvHyPkJ7jMXzhOsSJYB+EAQMGEVMig4tOf6Cug9HFd3+adiHIPP+UpyI3R1lZP5YNSMsuvDviDHXI16P25mr87PZO6/XcOxbwRV+eG7aiRlRTtgvgbfCPQacIJfT+zzZzGytY2sa+htxiTis0sdQY2BdsdtlwD75NmlP37KEZFJuG6y+4TTV7kN6iTueYxfoYTcQ9irz82FrgNYTAgWAgNXJ6K9rnlHlBAc7ZU9+VT6tNzi39eJflwwLJKPjhPyBKiZ10ycIPwgJYLAtbTQdaYF7rmBDVM8xkS+KSjvyErD+vzV+lZRVy6G2zHZpiRhPSFHGc1ytWa3o180ukeo0fw2/fz29R/OcIxFupinMuAPeaoHE2yrGkHvg8yJSHq2Scen7Bp1AhNmiL8BIbSAHe4=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 1.4.0
Release Details
UpdatedFeb. 25, 2026, 10:28 a.m.
Changelog

Added

  • Achievements / Badges: 14 badges across 6 categories (sessions, performance, mastery, streak, social, fun)
  • XP & Levels: Experience points calculated from sessions, Leitner reviews, accuracy bonuses, and streak multiplier
  • Badge Unlock Overlay: Animated full-screen overlay with confetti when earning a badge
  • Analytics Dashboard: Achievements grid with earned/locked status, badge progress bars, XP level bar
  • Session Juice: Animated score count-up (countUp.js), Personal Best detection, improvement vs. average display
  • XP display: "+X XP" shown on all results screens (Training, Exam, Swipe, Leitner)
  • Nextcloud Notifications: Badge unlock notifications, streak-at-risk warnings, due card reminders
  • Badge progress tracking: API endpoint showing progress towards unearned badges
  • New DB table learning_user_badges (Migration Version001100)
  • 2 new API endpoints: GET /api/badges, GET /api/badges/progress

Changed

  • Training complete response now includes newly_earned_badges, xp_earned, is_personal_best, improvement, average_accuracy
  • Leitner answer response now includes newly_earned_badges when card reaches Box 5
  • Share creation now triggers badge check for "Sharing is Caring"
  • Streak endpoint now triggers streak badge checks
  • Dashboard widget sends streak warning and due reminder notifications
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureYuFGppj5TQhlB5nd+fXqJurxGQUn7l0FFIqbWhXJMf9xPEi/g3wKdx7qukdK2ttz1Rf5xEbSdoLsGj3q1F7V5DZ+4+4GmMewS+MlYE4GA9ESFIA6lHLYxThICgb3G2lEGtImmp57tmGv7dzAiPqIH4pEdC0KT/iO08+VGy5R5s1gS5r36nHSrytf5C7JUBSSmOg6rVpUFIccDaXv8zn1f9sWWAZw4pRptDx+X29foqY2Zt4S/Swuz/SOGWKyfhhPw/x6RHjB3vnJIxx64Oi4Rom8BNdrU911RtMUFXLcnxq4xsv7VO2wGMkjNHegpL2yNr68yJSEm0bOjmVih06XMpJDNC0KN4S0vwnUkDIm1t9Dk1zxSPK5ba/PlQrTFxMVwratZsc1Uz0b/VqUBaZTu9oEBMpBm4CTrSf8XK29CNQ5EQXAzMSB0UUz0TqPpL2rI9kkcejJl0cololPd8N5R5jJpQ5miguwm6UjfTrIJzaizm6MAtXg+wx/DFfTyaSS936v1JEaRGIy4XkeQ9ZAAnSANlx9o8HTyLnWc7v6EsdkSo/7q88h7FaFUrlgkb3Gv7CQLBIJZ2jLtYa/2jv5gHQrg3c9unmIPLK8njpwS5+KgMH1V8LsyvraUW9ejzfmGv/BuN+reNyvToEoP8JIFPLs7SP1areV9svmkEnjIT8=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0
Learning 1.3.4
Release Details
UpdatedFeb. 19, 2026, 2:46 p.m.
Changelog

Security

  • CRITICAL: Close training-session oracle — startSession(exam) auto-completes open training sessions on same pool
  • CRITICAL: Defense-in-depth in submitAnswer/submitBatch — suppress correct_answer fields via cross-session check
  • HIGH: Strip explanation field from Question API during active exam to prevent indirect answer leakage
  • Rate-limits on ShareController and TranslationController write endpoints

Fixed

  • Leitner feedback shows hint when correct answers are suppressed during active exam
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEAzCCAusCAhL4MA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjYwMjE5MTIwNjM0WhcNMzYwNTI3MTIwNjM0WjATMREwDwYD
VQQDDAhsZWFybmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi7
IyOTssJkAP8hllbLrwWmuhi3R8D6GZVB4inBQfUKu4lcShFuqanFgEipA17sikdW
ktyrbqV2MhZi7UJSPFarnUP8zf7uBLh79mvSb8dMoqorR+lqZpPbAj3a1oKkU7hc
MLjkYNKuFJlKiJnyJDGASzff/eZCdTjnk1q6w3w8C4NGVKlrt4Cq44NKi4jSfEL2
WMaifKaAnpQRRHR59BIggtGfu5SbThTyy8dHeeYSQ+x/0svIBiaRA4jrvqn0kMx5
HoLXgS3wuAZgjC40sI7Mw331Glj8GkAJcJyDJyQE/H/ZU4rKrvcaQHL/3MlmGTR4
/cjPfDhCzUYt5E/j/Y+TF43GUjNatzXf86aGvlxz9ajC8nfdwTCaa2ty6xnGh6dj
N0BqWTeRWOVWTrKXN9Ajxbhq9/wVI3uknRdIMZHM3kd9Gl47ha5SGxJh0vpUtayq
3ZMFnQjpQDHWq9rHDGwAa0i9PqvBOPRXerezJhFBtaYuNNT7IYB9q5pG3aFAG8Uz
YFKrbuHP9+23s+6ccH2nDnkwKCIg+lImmTjZfhIqiAuxHYPBeQvT0ObCaWW7oH6d
XucjHsA09ql3lN+lsa6OlFNSJugeRaZo8SDmM0YZgaIEmK/g217A8NKA+2g1rSmF
hkRLTrYFCrP3XPY62eq+jB5kL0A5IzwAJdd4WlNrAgMBAAEwDQYJKoZIhvcNAQEL
BQADggEBABNbpoehsB5WXmkJgDYPpP+z/YksqVeVg0k+79iwAJzaIyISkfqSkt5l
DGKcfDPYOCw+nhrWZWyI8mS6noWvYVHK/AWbSI4uuBkaC8t8VgpBvBlRDyui1ewq
11fne57P9cQNHwk0PGkjvsAhykq/85AXks1iIKP9sjzrmrv0s61tvbE5LJtulWKY
SbkzDiFGlQFAAKIm9z6UUENNMty8QkBMFrLd/MxSEfY0x2YcOEx8ptB07AMNPzwW
t0k6ykD59OzU+t1SsSqWEih3wxP8FkO5XSxrFlXK/L5f55NpQeel3vh57a5fGQb6
UI4RLlKb/qz3o1Bj1qdKBp32qx6G6/Q=
-----END CERTIFICATE-----
SignatureajCD73Wim+3CcebKFs72Co993wGojtfsPy8b+Gde+kx+EhPmDpzYEGdgbb54ZBqpDmJAroHIbaqZa0FfK8SwvFwC2JZ7WOp4xwOAjp+V7ruKvXu24MmzsH2wUp9U2ec+sO+EG9+ebsDELjaFEf2m6EMbRhw+/QUzsE51kaA10RaTwoNfTu29LLraGaEEFVWh9R5x5jbqNj9Wdvfq/vNNTp/XTm4SBLnAsD+7ymyMucfwHyn4ZYGspXdNd8v0HS6ZRe3JjtcOd+IjwEebZ4b2KPBCrnGs8sr+6zer7FItbLUOq2MxxdhaOml1yTQIPzeyuJPnFvmLJOw0FHJvsn/ZMMjCpByVSrf2MBua3yW4DcB/Z9m3yBwM3lQ98QUQDgmAfHwU1zG3P5ijvxFvaOz5XW3sFsCaktXfGtFfrMgUgbN8aee/7hZkA36Vi+zIUsbs+eExv5QvDn6bG21DrE8022vnfZ7gY9HFQESVMGsnZc9yqdeGJn9F09jScGcZvyinjtUUCe2/SRfjPHHa9JWvZ84pQuO+0OyAbvIEOlwz64r5qNatt47yoxAEzEUsu8oFQP2s+PX/Ni/yyEIWbH4LaK0qCPTulJKvujaq1fukSchT+9UMBVKxEebC672M1LtejtJnJfZVUp6WuAecz2QmBU4Va6WFDVLSkbAiz6ON/Jg=
Signature digestsha512
Dependencies
Required Nextcloud versions >=29.0.0,<32.0.0
Minimum Integer bits32
PHP>=8.1.0