What's new
Changelog
All notable changes to this project are recorded here. Newest first.
Get updates in your inbox
New features, improvements, and fixes — delivered when they ship.
Cleaner URLs: /learn, /study, /account
Changed - The app's URLs are reorganized into three clear namespaces: the public catalog stays under
/learn, everything you do while signed in (lessons, practice, exams, challenges, scenarios, conversations, vocabulary) now lives under/study, and account management (profile, settings, billing, referrals) moves to/account. Search engines are told to index only the public catalog. - Catalog category URLs now use readable words instead of internal names:
/learn/german,/learn/exams,/learn/citizenship,/learn/life-in-germany,/learn/bureaucracy, and/learn/work(previously e.g./learn/german_curriculum). - The home dashboard and "My learning" merged into a single hub at
/study— one canonical signed-in landing page instead of two competing ones. - Starting an activity now opens the player at
/study/session/…with a stable identifier, instead of a long address borrowed from the catalog page you came from. The player still links back to the activity's public catalog page on exit, and can still be tried without an account. - Machine-generated activity addresses were cleaned up: format prefixes (
scenario-…,lesson-…) and trailing counts (…-300) no longer appear in new content's URLs, and existing catalog content was migrated to the cleaner form (3 items renamed after human review). Meaningful numbers — levels likeb1, ordinals likemock-test-01— are preserved.
- The app's URLs are reorganized into three clear namespaces: the public catalog stays under
Noun paradigm generation unblocked
Fixed - Generating a declension table for a noun (the paradigm shown on a word's lexicon entry) failed on every attempt: the schema handed to the AI model for structured output used a construct (
v.required(...)→non_optional) that the JSON-Schema converter in the LLM transport cannot translate, so noun requests errored before ever reaching the model and walked the retry backoff to permanently failed. The schema now expresses the same shape — case and number required on every cell, gender optional, no stray coordinate keys — in a convertible form. Verb conjugations and adjective endings were never affected.
- Generating a declension table for a noun (the paradigm shown on a word's lexicon entry) failed on every attempt: the schema handed to the AI model for structured output used a construct (
XP for in-session reviews
Added - Answering correctly during an in-experience session — lessons, scenarios, question banks, mock tests, guides, and flashcard review — now earns XP. Previously only the standalone vocabulary review screen awarded XP, so the very same correct answer was rewarded in one place and ignored in a session. A correct answer earns 10 XP, or 15 when you produce the answer from memory (typing/recall) rather than picking it; incorrect answers and too-fast repeat reviews earn nothing.
Changed - Session XP is capped at 200 per session for replayable activities (lessons, scenarios, question banks, mock tests, guides), so a single long session can't be farmed for unlimited points. Flashcard review — naturally paced by the spaced-repetition schedule — stays uncapped, matching the vocabulary review screen.
- The two flashcard review entry points (the vocabulary library's review and the in-session review) now run through one shared reward rule, so the same review can never pay out differently depending on where you start it.
Fixed - Reviewing a word on the vocabulary review screen now updates the same mastery record the rest of the app reads. Previously that screen tracked mastery under a mismatched user key, so its progress could be invisible to your vocabulary library and to in-session reviews.
Catalog expansion: persona-targeted programs
Added - 9 new learning programs spanning A1–B2, organized around the everyday-German learner plus eight specific audiences: care & nursing staff, hospitality staff, office/tech professionals, parents, university students, job seekers, trades & logistics workers, and patients at the doctor.
- 47 new published activities across these programs — a mix of lessons, conversation scenarios, a how-to guide (writing a German work email; preparing for an interview), and a bedside phrase sheet — each grounded in real situations for its audience (e.g. a shift handover, taking a restaurant order, a daily standup, a Kita registration, office hours, a salary negotiation, site-safety instructions, booking a doctor's appointment).
- Cover images for every new program, learning path, and activity.
Scenarios become live AI conversations
Added - Scenario practice is now a live, free-text conversation with an AI partner that stays in character and improvises — replacing the old "pick one of these replies" branching dialogues.
- Scenarios now carry ordered goals ("sub-objectives") such as greeting, making your request, and closing politely; the AI detects each one as the learner completes it and awards XP.
- The conversation runs inline on the scenario's own session page, so opening a scenario drops the learner straight into the chat.
- During a scenario, a new "Scenario" panel shows who you're talking to (the AI partner's name and role), the conversation's register (formal/informal), a glossary of key terms, and a short end-of-session reflection ("debrief").
- The AI partner now speaks in a male or female voice that matches its character, instead of always using the learner's default voice.
Changed - Scenario content generation now produces these AI conversations — the partner persona (name + gender), the partner's brief, the conversation register, opening suggestions, target vocabulary and grammar, success goals, the ordered sub-objectives, a glossary, and a debrief — instead of pre-scripted branching dialogue trees.
- A scenario is now a single piece of catalog content (the same conversation definition the AI reads at runtime), removing the old split between branching content and the live AI chat.
- Internal cleanup: the chat experience is now shared between the standalone conversation page and the in-lesson scenario, and a shared page-layout primitive was renamed for clarity.
- Platform: image checks for generated pictures (moderation, on-image text, visual quality, prompt match) now run through the shared AI gateway instead of calling OpenAI directly — one provider and key, with no separate OpenAI key needed.
- Platform: AI calls that time out now actually cancel the in-flight request rather than just stop waiting, and a timed-out content-validation call fails fast instead of retrying.
- Platform: citizenship-exam content now also goes through an automated pedagogy review.
Fixed - Existing scenarios that showed "This activity does not have session content available yet" now load — 25 scenarios still stored in the old branching format were regenerated into the current AI-conversation format, in place (keeping their slug and place in each track).
- When a scenario can't start (for example, not signed in or the chat limit is reached), the learner now sees the real reason and a Retry, instead of a misleading "the player will plug in next phase" placeholder.
Lesson content richness
Added - Richer lesson generation — lessons are now longer and use a wider variety of block types.
- Rich-text prose blocks, so lessons can include longer formatted explanations (headings, lists, tables, callouts).
- A "common mistakes" teaching block showing wrong-vs-correct examples.
- An opt-in "deepen lesson" pass that adds extra teaching content to an existing lesson without changing its exercises.
- A block registry that makes adding new lesson block types simpler and safer.
Fixed - Fixed lesson generation failing to produce output (the AI consistently returned nothing usable).
- Removed an unsafe way of displaying AI-written text that could allow harmful content; text now passes through a safety filter.
- Added missing editor support in the admin app for the new block types.
Discovery pages for lessons, tracks, and programs
Added - Lesson, track, and program pages now have a richer "before you start" experience instead of just a title and a Start button — an overview that helps a learner decide why something is worth doing, what they'll learn, and what's inside before they begin.
- Lesson pages show a real preview pulled from the actual lesson — a few key vocabulary words and a snippet of dialogue — plus where the lesson sits in its track (with previous / next links), an estimated time, and the skills it builds.
- Track pages now exist. A track previously had no page of its own (its breadcrumb link went nowhere); it now opens a page showing what the stage covers, the lessons inside it, where it sits in the program, and the skills it builds.
- Program pages can show an authored overview — who it's for, the shape of the journey — above the list of tracks.
- A set of overview "blocks" — a hero intro, free-form prose, a "what you'll learn" list, a fun fact, and info / tip / warning callouts — rendered consistently across all three levels. Free-form prose supports formatting (bold, lists, tables, links) and is safely sanitized before display.
- AI can generate this overview content for any lesson, track, or program, grounded in the real material: a lesson's overview is built from its actual vocabulary and dialogue, a track's from its lessons, and a program's from its tracks — so overviews reflect what's really there rather than a generic template, and each level only uses the kinds of blocks that make sense for it.
- A new admin panel to generate, review, approve, or clear overview content. Generated content lands as a pending draft and only goes live once an admin approves it — nothing AI-written is published unreviewed.
- Overview content is automatically flagged as stale when the underlying lesson or track changes, so it can be refreshed and doesn't drift from what it describes.