
Ein Nachhilfezentrum mit über 200 Schülern arbeitete mit Messenger-Apps, Tabellen und E-Mail — fragmentiert zwischen Lehrern, Schülern und Eltern. Lernmaterialien lagen in Chat-Verläufen. Testergebnisse wurden manuell erfasst. Stundenpläne änderten sich ständig. Die Schule brauchte eine zentrale Wahrheitsquelle — aber kein Standardsystem deckte die spezifischen Abläufe eines Nachhilfegeschäfts ab.
Eine Full-Stack-Plattform, vollständig selbst gebaut. Backend: Java 21 und Spring Boot 3.5, JWT-Authentifizierung, PostgreSQL 16 mit Flyway, S3-kompatibles RustFS für Dateien, jsoup zur Bereinigung jeglichen nutzergenerierten HTMLs. Frontend: React 18 mit Vite und Tailwind 4, TipTap als Editor, FullCalendar und Drag-and-drop für den Stundenplan. Läuft auf einem einzigen VPS hinter nginx — Docker Compose, TLS via certbot, Rate Limits, Security-Header, Prometheus als Monitoring und nächtliche Datenbank-Backups.
Codezeilen
Java-Backend, React-Frontend
Datenbanktabellen
20 Flyway-Migrationen
REST-Controller
Auth, Kurse, Tests, Chat
Im Produktivbetrieb
Auftragsarbeit, täglich genutzt

JWT mit Refresh-Token-Rotation, E-Mail-Verifikation und Passwort-Setup-Links, dazu drei Rollen — Schüler, Lehrer, Admin — durchgesetzt über 20 REST-Controller. Kein externer Identity-Provider.
Ein S3-kompatibles RustFS verwahrt Lernmaterialien, Testbilder, Chat-Anhänge, News-Medien und Programm-PDFs in vier getrennten Buckets. Es hat im Oktober 2026 MinIO abgelöst, ohne eine einzige Änderung am Backend-Code. Die Dateien verlassen den Server des Kunden nie, und es fallen keine Speicherkosten an.
Nach jedem Build fährt ein Playwright-Job jede öffentliche Route ab und legt einen statischen Schnappschuss ab, den nginx zuerst ausliefert — an alle, sodass Inhalt schon vor jedem JavaScript sichtbar ist. Suchbots bekommen zusätzlich direkt aus der Datenbank gerenderte Seiten, aufgeteilt per User-Agent in nginx.
Live in Produktion
Die Plattform läuft seit April 2026 auf cp-binom.ru und wird täglich von Schülern und Lehrkräften des Zentrums genutzt. Das Portal selbst liegt hinter einem Login; der öffentliche Teil steht allen offen.

Ich gehe gern die Entscheidungen dahinter durch — warum selbst gehosteter Speicher, warum zwei Render-Wege für denselben Inhalt und was ich beim nächsten Mal anders machen würde.