Independent engineering · Full-stack · Learning system

German Master

A German practice platform organized around lexemes and inflections rather than a fixed list of hand-coded exercises. Content, task generation, offline delivery, user history, enrichment, and synchronization are separate parts of the system.

ReactTypeScriptExpressPostgresDrizzlePWAIndexedDB

Lexemes before exercises

The core data model separates a word's lexical identity from its inflected forms and from the tasks generated around it. The current schema includes lexemes, inflections, task_specs, and practice_history, with part-of-speech-specific source data for verbs, nouns, adjectives, adverbs, prepositions, and other categories.

This avoids coupling the content store to one exercise type. A shared registry describes task types, while the client renders practice by taskType and the API serves POS-aware task descriptors.

Content-to-practice flow

Offline practice without a second application model

The web client is installable as a Progressive Web App. Recent task responses are cached for offline reuse, while practice attempts made without a usable network are stored in an IndexedDB queue through Dexie.

When connectivity returns, the sync hook flushes queued attempts to the normal submission endpoint. Each device carries a persistent device ID, so the same practice-history model is used whether an attempt was submitted immediately or replayed later.

Content provenance and enrichment

Language data is not treated as a one-off seed script. The enrichment pipeline can inspect incomplete entries, collect structured material from sources such as Wiktextract/Kaikki, OpenThesaurus, MyMemory and Tatoeba, optionally use an LLM for missing fields, and retain provider snapshots for later replay.

Updates are separated from collection: suggestions can be generated without mutating the canonical database, reviewed, backed up, and then applied. Attribution metadata is stored alongside generated task content where required.

Identity across clients

Supabase Auth is used so the web application and Android client can resolve the same user identity and preserve shared practice history. The web project also includes optional Microsoft OAuth support and server-side verification of web auth tokens.

Testable database and content pipelines

Tests do not require a shared development database. The test harness can run the real Drizzle migrations against an isolated in-memory Postgres implementation, seed controlled data, execute API tests, and tear the schema down again. A real Postgres instance can be substituted when needed.

Generated content also has its own checks: task-pack linting, type checking, unit/integration tests, environment validation, and build-time checks reduce the chance that content or schema changes silently produce invalid practice tasks.