rafiqohfitriani.com → Deutsch Diary

Building my own spaced-repetition engine instead of trusting a generic app with my B1 deadline

A self-hosted German learning platform I designed, built, and deployed — SRS algorithm, Goethe-format testing, and a progress model built entirely around my own real vocabulary state.

Solo build · architect + engineer
PHP 8.3 · SQLite · Hostinger
Aug 2026 → ongoing

The problem

I'm learning German toward a hard deadline — A1 by the end of August 2026, B1 by the end of the year — while job-hunting for Program Manager and automation-enablement roles in the EU. Generic apps didn't fit that constraint in three specific ways:

So I scoped, built, and deployed a purpose-built tool instead of adapting my study plan to someone else's product.

What I built

A single-user web app tracking exactly where I stand on 732 tagged A1 vocabulary items (396 already known, 336 in active review), with:

Technical stack

Backend
PHP 8.3 + PDO
Database
SQLite (file-based)
Frontend
Alpine.js + Chart.js
Audio
Web Speech API (TTS + STT)
Hosting
Hostinger shared, deployed over SSH
Writing grading
Manual LLM copy-paste bridge

Product decisions worth explaining

The interesting part of this build wasn't the code — it was the tradeoffs. A few I'd defend in an interview:

SQLite over MySQL

This is a single-user tool. MySQL would have meant generating and safeguarding a second set of database credentials for zero real concurrency benefit. SQLite is one file, stored outside the web root so it's never directly downloadable, and it backs up by just copying that file.

Recognition quizzes, not translation flashcards

My source word lists had no English glosses. Rather than spend a build cycle hand-translating 732 words, I redesigned the core quiz around recognition — hear or read the word, pick it out of same-category distractors. It turned a data gap into arguably better pedagogy: it tests active recall under a real constraint, not passive translation lookup.

Free by default on the one feature with a real cost

Schreiben grading against Goethe rubrics needs an LLM. Rather than wire a paid API key in by default, the editor formats a grading prompt I copy into Claude's free chat and paste the feedback back in. One-click paid grading stays an opt-in toggle, not the default state of a personal project.

Public read access, write access still gated

This page is meant to be seen by whoever's evaluating me, not locked behind a password. But the practice tools write to the same database I use for real study — so viewing and even trying the quizzes is open to everyone, while only my own login can actually update the progress numbers you're looking at.

Where it stands

Live: vocabulary engine, SRS review, dashboard, timeline, Lesen/Hören/Schreiben/Sprechen quiz modes
Target: A1 mastery by 31 Aug 2026
Target: B1 by end of 2026, with the professional-German track weighted toward interview readiness