projects.ls
Was ich so baue
What I build
Fünf Maschinen. Ein Cluster. Kein Tutorial, das einem das Denken abnimmt.
Ich habe von Grund auf einen eigenen Proxmox-Cluster aufgebaut –
mit verteiltem Ceph-Storage, Live-Migration, High Availability
und allem, was dazugehört. Nicht weil ich musste, sondern weil ich verstehen wollte,
wie das alles wirklich funktioniert – unter der Haube, ohne Abstraktion.
Darauf läuft unter anderem Home Assistant,
mit dem ich unser Zuhause Stück für Stück smarter mache.
Jedes neue Gerät, jede neue Automatisierung – ein weiteres kleines Experiment.
Five machines. One cluster. No tutorial doing the thinking for you.
I built my own Proxmox cluster from scratch –
with distributed Ceph storage, live migration, high availability
and everything that comes with it. Not because I had to, but because I wanted to understand
how it all really works – under the hood, without abstraction.
Among other things, Home Assistant runs on it,
with which I'm making our home smarter piece by piece.
Every new device, every new automation – another small experiment.
Spieleranalyse-Plattform für Fußballtrainer im Amateurbereich — als installierbare Web-PWA plus Android-App. Trainer erfassen Beobachtungen und Übungsergebnisse als Freitext, ein lokal gehostetes LLM wandelt sie in strukturierte Bewertungen über acht Kategorien um (Technik, Taktik, Zweikampf, Kondition u.a.), die als gewichteter Verlauf ins Radar-Profil jedes Spielers einfließen. Dazu: Formations-Planer nach WFV/DFB-Spielformaten (3v3 bis 11v11) mit KI-Aufstellungsvorschlag und Auswechselbank-Logik, ein Übungskatalog mit 210 Übungen über sieben Altersklassen inklusive Stoppuhr/Zähler-Erfassung, sowie Mehrtrainer-Teams mit Einladungslinks und Abstimmung über Aufstellungen.
Technisch: Node.js/Express mit SQLite, Vanilla-JS-Frontend als PWA mit Service Worker, Android-WebView-Wrapper. Alle KI-Aufrufe laufen über meinen eigenen AI-Gateway gegen lokale Modelle — bewusst ohne Cloud-Anbieter, kein fremder Dienst bekommt Beobachtungen über Kinder zu sehen. Antworten werden als striktes JSON erzwungen; serverseitige Validierung fängt typische LLM-Fehler ab (z.B. doppelt zugewiesene Spieler im Aufstellungsvorschlag). Das Modell ist pro Trainer, Team oder global wählbar, Reasoning-Modelle bekommen automatisch ein höheres Token-Budget. Deployment als Docker-Container mit zentralem Fehler-Reporting.
Player-analysis platform for amateur football coaches — an installable web PWA plus an Android app. Coaches enter observations and drill results as free text, and a locally hosted LLM turns them into structured ratings across eight categories (technique, tactics, duels, fitness and more), which feed a weighted history into each player's radar profile. On top of that: a formation planner covering official youth match formats (3v3 up to 11v11) with AI lineup suggestions and substitute-bench logic, a drill catalogue of 210 exercises across seven age groups with built-in stopwatch/counter capture, and multi-coach teams with invitation links and lineup voting.
Under the hood: Node.js/Express with SQLite, a vanilla-JS frontend shipped as a PWA with a service worker, and an Android WebView wrapper. All AI calls go through my own AI gateway to local models — deliberately no cloud provider, so no outside service ever sees an observation about a child. Responses are forced into strict JSON, and server-side validation catches typical LLM mistakes (e.g. the same player assigned twice in a suggested lineup). The model is selectable per coach, per team or globally, and reasoning models automatically get a larger token budget. Deployed as a Docker container with centralized error reporting.
Legacy — laenger nichts dran gemacht Legacy — untouched for a while
Fertig, abgelöst oder ruhend. Manches läuft weiter, weitergebaut wird daran nicht. Finished, superseded or dormant. Some of it still runs, none of it is still being built.
Hardware trifft Software trifft Sport.
Ich habe 10 ESP32-Module gebaut –
akkubetrieben, drahtlos, jedes mit farbigen LEDs bestückt.
Das Ergebnis: ein physisches Reaktionsspiel, bei dem Spieler blitzschnell
reagieren müssen, sobald ihre Farbe aufleuchtet. Nicht am Bildschirm –
auf dem Platz. Mit dem ganzen Körper.
Dazu gehört eine Android-App,
die die Module steuert, Spielmodi verwaltet und Ergebnisse auswertet –
sechs Spielmodi sind umgesetzt.
Zwei Beispiele:
Im Team-Modus liefern sich zwei Teams
einen Wettlauf – wer trifft in der vorgegebenen Zeit öfter seine Farbe?
Im Reaktions-Modus zählt jede Millisekunde:
10 zufällige Aufleuchten, die Gesamtreaktionszeit entscheidet.
Hardware meets software meets sport.
I built 10 ESP32 modules –
battery-powered, wireless, each fitted with coloured LEDs.
The result: a physical reaction game where players must react lightning-fast
when their colour lights up. Not on a screen –
on the field. With the whole body.
A companion Android app controls
the modules, manages game modes and evaluates results –
six game modes are implemented.
Two examples:
In team mode, two teams race against each other –
who hits their colour more often in the given time?
In reaction mode, every millisecond counts:
10 random flashes, total reaction time decides.
Ein Problem, das eigentlich jeder kennt – aber niemand löst.
Kommunikation zwischen Eltern und Lehrern
ist heute noch oft Zettelwirtschaft, veraltete Apps mit Datenweitergabe
oder schlicht WhatsApp-Gruppen ohne jede Struktur.
Ich habe eine Alternative gebaut – mit einem klaren Grundsatz:
der Server speichert nichts.
Nachrichten, Dokumente, Bilder – alles wird nur weitergeleitet, nie gespeichert.
Lehrer können eine eigene E-Mail-Weiterleitung
in der App hinterlegen – eingehende Nachrichten landen direkt im Postfach.
Eltern können Nachrichten an Lehrer senden –
aber nicht untereinander. Die Registrierung läuft über einen
QR-Code – einscannen, fertig, drin.
A problem everyone knows – but nobody solves.
Communication between parents and teachers
is still often paper-based, outdated apps with data sharing,
or simply WhatsApp groups with no structure.
I built an alternative – with one clear principle:
the server stores nothing.
Messages, documents, images – everything is only forwarded, never stored.
Teachers can store their own email forwarding
in the app – incoming messages land directly in their inbox.
Parents can send messages to teachers –
but not to each other. Registration works via a
QR code – scan, done, in.
Selbst gehostete Foto-Bibliothek für rund 200.000 Familienbilder — komplett lokal, keine Cloud. Ein Scanner crawlt konfigurierte Quellverzeichnisse, die Pipeline optimiert jedes Bild per libvips, erzeugt Thumbnails, liest EXIF- und GPS-Daten aus und taggt es automatisch über ein lokales Vision-LLM; Gesichter erkennt InsightFace direkt im GPU-Worker und gruppiert sie per Embedding zu Personen, die sich benennen und durchsuchen lassen.
Backend ist FastAPI mit PostgreSQL + pgvector, die Verarbeitung läuft asynchron über Celery/Redis mit GPU-Unterstützung. Personen-Clustering per Cosine-Similarity auf Gesichts-Embeddings direkt in der Datenbank, Duplikat-Erkennung über perzeptuelle Hashes (pHash), dazu Reprocess-Endpoints für Tags und Gesichter. Das Vision-Tagging geht über meinen lokalen AI-Gateway (OpenAI-kompatible API) und ist zur Laufzeit ohne Worker-Restart umkonfigurierbar. Frontend: schlankes Vanilla-JS mit Galerie, Personen-Suche, Bilddetail-Modal und GPS-Weltkarte (Leaflet/OSM); deployt als vier Docker-Container.
Self-hosted photo library for around 200,000 family pictures — fully local, no cloud. A scanner crawls configured source directories, the pipeline optimizes each image with libvips, generates thumbnails, extracts EXIF and GPS data, and auto-tags it via a local vision LLM; faces are detected by InsightFace right in the GPU worker and grouped into persons via embeddings, which can then be named and searched.
The backend is FastAPI with PostgreSQL + pgvector; processing runs asynchronously on Celery/Redis with GPU support. Person clustering uses cosine similarity on face embeddings directly in the database, duplicate detection relies on perceptual hashes (pHash), plus reprocess endpoints for tags and faces. Vision tagging goes through my local AI gateway (OpenAI-compatible API) and can be reconfigured at runtime without restarting workers. The frontend is lightweight vanilla JS with a gallery, person search, image detail modal, and a GPS world map (Leaflet/OSM); deployed as four Docker containers.
zuletzt bearbeitet 04.08.2026 last touched 2026-08-04
Sammlungs-App für die Pokémon-Karten meines Sohnes (~1000 Karten) — komplett selbstgehostet. Karten kommen per Dokumentenscanner (eSCL/AirScan) oder Foto-Upload herein; ein lokal laufendes Vision-LLM identifiziert Name, Set, Nummer und Sprache, extrahiert den kompletten Kartentext und übersetzt ihn ins Deutsche. Marktpreise (Cardmarket, Fallback TCGPlayer mit Währungsumrechnung) liefert die offizielle Pokémon-TCG-API, inklusive Append-only-Preishistorie mit Verlaufs-Charts pro Karte.
Technisch: React/Vite-PWA hinter Nginx, Fastify-Backend mit SQLite (WAL-Modus) und sharp für die Bildverarbeitung. Die Multi-Karten-Erkennung im Scan läuft zuerst über Pixelprojektion (ganz ohne KI), mit Vision-LLM und gleichmäßigem Grid als Fallback-Kette; die Identifizierung streamt ihren Fortschritt per SSE ins Frontend und überlebt dank React-Context auch Seitenwechsel. Alle KI-Calls (qwen3-vl für Vision/OCR, translategemma für Übersetzung) gehen über meinen zentralen AI-Gateway auf lokale GPUs — es verlässt kein Kartenbild das Haus.
Collection manager for my son's Pokémon cards (~1000 of them) — fully self-hosted. Cards come in via a document scanner (eSCL/AirScan) or photo upload; a locally running vision LLM identifies name, set, number and language, extracts the full card text and translates it into German. Market prices (Cardmarket, with TCGPlayer plus currency conversion as fallback) come from the official Pokémon TCG API, including an append-only price history with per-card trend charts.
Under the hood: a React/Vite PWA behind Nginx, a Fastify backend with SQLite (WAL mode) and sharp for image processing. Multi-card detection on a scan starts with plain pixel projection (no AI at all), falling back to the vision LLM and finally an even grid; identification streams its progress to the frontend via SSE and survives page navigation thanks to a React context. All AI calls (qwen3-vl for vision/OCR, translategemma for translation) route through my central AI gateway onto local GPUs — no card image ever leaves the house.
zuletzt bearbeitet 04.08.2026 last touched 2026-08-04
Text-to-CAD für den 3D-Drucker: Ein Bauteil per Chat in natürlicher Sprache beschreiben („Adapter, Innendurchmesser 38 mm, Wandstärke 2 mm, seitlicher Schlitz 80×15 mm") — die KI schreibt parametrischen CadQuery-Code, ein Sandbox-Worker baut daraus ein echtes BREP-Solid (OpenCASCADE) und liefert eine STEP-Datei für den Slicer plus Live-3D-Vorschau im Browser. Hauptweg ist ein Galerie-Trichter: Text-Intent → Form-Richtung → kuratierte parametrische Vorlagen, die garantiert baubar sind; Freihand-KI-Generierung mit Self-Correction-Loop dient als Fallback für alles, was keine Vorlage abdeckt.
Dahinter steckt eine Lern-Schicht auf Postgres + pgvector: jede Generierung wird mit Embedding gespeichert, ein Daumen-hoch macht daraus eine gelernte Galerie-Kachel und ein Few-Shot-Beispiel für künftige Generierungen. Der interaktive Editor kann Live-Schieberegler mit Neu-Build beim Ziehen, Sprach-Änderungen („Wand 1 mm dicker"), Klick-auf-Fläche-Editing per Raycast, Schnitt-Ansicht für hohle Teile, Druckbarkeits- und Gewichts-Check (Volumen × Material) sowie Gegenstück-Generierung (Negativ/Gussform). KI-generierter Code läuft isoliert in einem eigenen Subprozess mit CPU- und Zeit-Limit, non-root im Container.
Text-to-CAD for 3D printing: describe a part in plain language in a chat ("adapter, inner diameter 38 mm, wall thickness 2 mm, side slot 80×15 mm") — the AI writes parametric CadQuery code, a sandboxed worker builds a true BREP solid (OpenCASCADE) and delivers a STEP file for the slicer plus a live 3D preview in the browser. The main path is a gallery funnel: text intent → shape direction → curated parametric templates that are guaranteed to build; free-form AI generation with a self-correction loop serves as the fallback for anything no template covers.
Underneath sits a learning layer on Postgres + pgvector: every generation is stored with an embedding, a thumbs-up turns it into a learned gallery tile and a few-shot example for future generations. The interactive editor offers live sliders that rebuild the part while dragging, natural-language tweaks ("wall 1 mm thicker"), click-on-face editing via raycasting, a section view for hollow parts, printability and weight checks (volume × material), and counterpart generation (negative/mold). AI-generated code runs isolated in its own subprocess with CPU and wall-clock limits, non-root inside the container.
zuletzt bearbeitet 04.08.2026 last touched 2026-08-04
Komplette Vereinsverwaltung als Progressive Web App — mehrvereinsfähig mit rollenbasierten Berechtigungen, gebaut für den echten Vereinsalltag statt für Feature-Listen: Mitglieder mit Familien-Gruppen, Mannschaften inklusive Spielgemeinschaften, Veranstaltungen mit strukturierten Protokollen und Abstimmungen, Arbeitspläne mit Schicht-Self-Signup und Konfliktprüfung, Trainings-Anwesenheit, Finanzbuchhaltung mit Approval-Workflow sowie Turnier-Autogenerator (Gruppen + KO, Rotations-Modus) mit öffentlichem Live-View. Läuft produktiv unter ourclubpro.solidio.de.
Django 5 mit PostgreSQL 17, Bootstrap 5 und Alpine.js, als installierbare PWA mit Service-Worker und Web-Push (VAPID). Besonderheiten: SEPA-Lastschrift-Export (pain.008) für die Beitragsverwaltung, druckbare Zuwendungsbestätigungen nach §10b EStG, Datenauskunft-Export pro Mitglied (Art. 15 DSGVO), passwortloses Sponsor-Portal über Token-Links, iCal-Export pro Verein und Team plus QR-Code-Check-in. Öffentliche Helfer- und Sachspenden-Anmeldung ist datenschutzfreundlich gebaut — nach außen sichtbar sind nur Zähler, keine Namen.
Complete club management as a progressive web app — multi-club capable with role-based permissions, built for real club life rather than feature lists: members with family groups, teams including joint squads across clubs, events with structured minutes and votes, work schedules with shift self-signup and conflict checking, training attendance, finance accounting with an approval workflow, and a tournament auto-generator (groups + knockout, rotation mode) with a public live view. Running in production at ourclubpro.solidio.de.
Django 5 with PostgreSQL 17, Bootstrap 5 and Alpine.js, shipped as an installable PWA with a service worker and web push (VAPID). Highlights: SEPA direct-debit export (pain.008) for membership fees, printable donation receipts compliant with German tax law (§10b EStG), per-member data-subject export (GDPR Art. 15), a passwordless sponsor portal via token links, iCal export per club and team, and QR-code check-in. The public volunteer and in-kind-donation signup is privacy-friendly by design — only counters are visible externally, never names.
zuletzt bearbeitet 04.08.2026 last touched 2026-08-04
Kindgerechter Gaming-Server: Steam-Spiele laufen auf einer Ubuntu-VM mit GPU-Passthrough und werden per Sunshine an einen Raspberry Pi am Wohnzimmer-TV gestreamt — Moonlight direkt im Framebuffer, kein Desktop, kein Window-Manager. Die Kinder landen in einem gamepad-bedienbaren Chromium-Kiosk mit großen Spiel-Covern; bewusst ist der Kiosk das einzige Moonlight-Tile, damit Spielzeit-Limit und PIN-Gate nicht über Direkt-Kacheln umgangen werden können.
Die Bibliothek ist deklarativ: App-IDs in eine Config-Datei, Git-Push, und ein Webhook lässt steamcmd installieren/deinstallieren, cached Cover und regeneriert die Sunshine-Tiles. Das Flask-Backend (Vanilla-JS-Frontend) erzwingt tägliche Spielzeit-Limits und ein PIN-Gate für Erwachsenen-Titel, erkennt Steam-Logouts und loggt sich automatisch neu ein (Bestätigung per Handy-Push). Lockfiles plus Watchdog koordinieren Streams, laufende Installationen und Cleanup — dieselbe GPU dient zwischen den Gaming-Sessions als KI-Inferenz-Host und wird über eine Gaming-Mode-API automatisch reserviert und 15 Minuten nach Disconnect wieder freigegeben. Im selben Grid: Mediathek-Tiles (ARD/ZDF/KiKA via Kodi).
Kid-friendly gaming server: Steam games run on an Ubuntu VM with GPU passthrough and are streamed via Sunshine to a Raspberry Pi at the living-room TV — Moonlight straight in the framebuffer, no desktop, no window manager. The kids land in a gamepad-navigable Chromium kiosk with big game covers; deliberately, the kiosk is the only Moonlight tile, so playtime limits and the PIN gate can't be bypassed via direct game tiles.
The library is declarative: app IDs in a config file, git push, and a webhook has steamcmd install/uninstall games, caches cover art, and regenerates the Sunshine tiles. The Flask backend (vanilla-JS frontend) enforces daily playtime limits and a PIN gate for adult titles, detects Steam logouts and re-logs in automatically (confirmed via phone push). Lockfiles plus a watchdog coordinate streams, in-flight installs, and cleanup — between gaming sessions the same GPU serves as an AI inference host, automatically reserved and released via a gaming-mode API 15 minutes after disconnect. In the same grid: public-broadcaster media tiles (ARD/ZDF/KiKA via Kodi).
zuletzt bearbeitet 02.08.2026 last touched 2026-08-02
Selbstgebautes LAN-Monitoring plus Infrastruktur-Inventar für meine gesamte Server-Landschaft — bewusst ohne Grafana, Prometheus oder fremde Container-Images. Agents auf jedem Host pushen alle 30 Sekunden Host- und Container-Metriken (CPU, RAM, Load, Disks, pro Container CPU%, RAM, Restart-Count) an einen zentralen Hub; der Hub pollt zusätzlich die Proxmox-API und kennt so alle LXC-Container und VMs im Cluster inklusive Drift-Erkennung gegen den Soll-Zustand.
Der Hub ist eine FastAPI-App mit Postgres (Alembic-Migrationen) und Chart.js, die Agents ein einziges Python-Script mit psutil und Docker-Engine-API über den UNIX-Socket. Dazu Hardware-Inventar pro Host (CPU/RAM/Disks/GPUs, GPU-Live-Telemetrie via nvidia-smi), Aggregation in drei Tiers (30 s / 1 min / 5 min mit gestaffelter Retention), Bearer-Token-Auth mit Trust-on-First-Use-Registrierung, IP-Whitelist und Schwellwert-Alerts in die zentrale Bug-Inbox. Inzwischen abgelöst durch MyWorldControl, das den Monitoring-Hub zur aktiven Steuerzentrale weiterentwickelt hat.
A self-built LAN monitoring stack plus infrastructure inventory for my entire server landscape — deliberately without Grafana, Prometheus, or third-party container images. Agents on every host push host and container metrics (CPU, RAM, load, disks, per-container CPU%, RAM, restart count) to a central hub every 30 seconds; the hub additionally polls the Proxmox API, giving it a full view of all LXC containers and VMs in the cluster, including drift detection against the intended state.
The hub is a FastAPI app with Postgres (Alembic migrations) and Chart.js; the agents are a single Python script using psutil and the Docker Engine API over the UNIX socket. On top of that: per-host hardware inventory (CPU/RAM/disks/GPUs, live GPU telemetry via nvidia-smi), three-tier aggregation (30 s / 1 min / 5 min with staggered retention), bearer-token auth with trust-on-first-use registration, an IP whitelist, and threshold alerts pushed to a central bug inbox. Since superseded by MyWorldControl, which evolved the monitoring hub into an active control center.
zuletzt bearbeitet 02.08.2026 last touched 2026-08-02
Update-Orchestrator für meinen Proxmox-Cluster: Der Dienst entdeckt über die Proxmox-API automatisch alle Nodes, LXC-Container und VMs, erkennt per SSH das Betriebssystem und den Paketmanager und hält die gesamte Flotte aktuell — Update-Check, Installation und Reboot pro Host, gesteuert über ein schlankes Web-Dashboard mit Live-Status, Update-Zählern und Reboot-Pending-Anzeige.
Technisch ein FastAPI-Service mit asyncio-Hintergrund-Loops (Discovery alle 30 Minuten, Update-Check alle 6 Stunden) und asyncssh mit Concurrency-Limit. IP-Erkennung funktioniert auch bei DHCP — über das LXC-Interfaces-API bzw. den QEMU-Guest-Agent, mit Fallback auf die statische Netz-Config. SQLite im WAL-Modus dient als Inventar-, Config- und Log-Store; erwartbar unerreichbare Hosts werden von echten Fehlern unterschieden, damit sie das zentrale Fehler-Monitoring nicht mit Fehlalarmen fluten. Läuft als Docker-Container im Cluster.
Update orchestrator for my Proxmox cluster: the service auto-discovers all nodes, LXC containers and VMs via the Proxmox API, detects each host's OS and package manager over SSH, and keeps the whole fleet current — update check, installation and reboot per host, driven from a lean web dashboard with live status, update counts and reboot-pending indicators.
Technically a FastAPI service with asyncio background loops (discovery every 30 minutes, update check every 6 hours) and asyncssh with a concurrency limit. IP detection works even with DHCP — via the LXC interfaces API or the QEMU guest agent, falling back to the static network config. SQLite in WAL mode serves as inventory, config and log store; expectedly unreachable hosts are distinguished from real failures so they don't flood the central error monitoring with false alarms. Runs as a Docker container inside the cluster.
zuletzt bearbeitet 02.08.2026 last touched 2026-08-02
Persönliches Börsen-Dashboard mit Multi-Modell-KI-Analyse — komplett lokal, ohne externen KI-Dienst und ohne Broker-Anbindung. Jeder Lauf zieht Kurs- und Fundamentaldaten, Analysten-Konsens und News aus Yahoo Finance und RSS-Feeds, lässt bis zu zehn lokale LLMs mit unterschiedlichen Stärken (Finanz-Spezialist, Reasoning, Sentiment) dieselben Aktien bewerten und stellt die Einschätzungen als Vergleichstabelle mit gewichtetem Konsens gegenüber. Kein Trading — nur strukturiertes Wissen fürs eigene Depot inklusive Stop-Überwachung und Portfolio-Simulationen.
React/Vite-Frontend vor einem FastAPI-Backend mit PostgreSQL als Single Source of Truth: alle Tabellen sind append-only, jeder Analyse-Lauf bleibt historisch reproduzierbar. Eine systemd-Timer-Pipeline screent pro Lauf über 1.000 Ticker aus Yahoo-Screenern, filtert nach Liquidität und Momentum und reicht die Top-Kandidaten mit RSI, MACD, Bollinger-Bändern und Earnings-Daten an die Modelle weiter. Ein Feedback-Loop bewertet jede Modell-Vorhersage nach 6, 24 und 120 Stunden nach und lernt so Trefferquoten pro Modell und Ticker; die LLM-Calls laufen gebündelt über den lokalen KI-Gateway in Niedriglast-Fenstern.
Personal stock market dashboard with multi-model AI analysis — fully local, no external AI service and no broker connection. Each run pulls price and fundamental data, analyst consensus and news from Yahoo Finance and RSS feeds, has up to ten local LLMs with different strengths (finance specialist, reasoning, sentiment) rate the same stocks, and presents their assessments as a comparison table with a weighted consensus. No trading — just structured knowledge about my own portfolio, including stop monitoring and portfolio simulations.
React/Vite frontend in front of a FastAPI backend with PostgreSQL as the single source of truth: all tables are append-only, so every analysis run stays historically reproducible. A systemd timer pipeline screens over 1,000 tickers from Yahoo screeners per run, filters by liquidity and momentum, and hands the top candidates — enriched with RSI, MACD, Bollinger bands and earnings data — to the models. A feedback loop re-scores every model prediction after 6, 24 and 120 hours, learning hit rates per model and ticker; all LLM calls are funneled through the local AI gateway during low-load windows.
zuletzt bearbeitet 02.08.2026 last touched 2026-08-02
KI-Aufgabengenerator für Lehrkräfte in Baden-Württemberg. Ein Crawler holt die offiziellen BW-Lehrpläne (~700 Curricula), lokale LLMs generieren daraus Einzelaufgaben und komplette Klausuren. Drei Module: Materialien (PDF-/DOCX-Upload mit Text-Extraktion), Aufgabenpool (Versionierung, Tags, Volltextsuche) und Zusammenstellungen — inklusive KI-Vorschlägen aus dem Pool, druckfertigem PDF-Export via Puppeteer und simulierter Schülerleistung auf drei Niveaus.
Node.js/Express mit PostgreSQL, React-Frontend mit Tailwind v4. Alle LLM-Calls laufen über das eigene AI-Gateway; Generierung asynchron per Job-Queue mit Batch-Worker, dreistufigem JSON-Parser (strict → Repair → jsonrepair) und Partial-Recovery bei abgeschnittenen Antworten. Besonderheit: ein permanentes Self-Audit-System lässt Aufgaben von einem anderen Modell als dem Ersteller nach fünf Kriterien nachbewerten (Cross-Model-Grading) und meldet die Scores als Quality-Feedback ans Gateway zurück — künftige Auto-Modellwahl bevorzugt so die Modelle mit den besten Audits.
AI exercise generator for teachers in Baden-Württemberg. A crawler fetches the official state curricula (~700 documents), and local LLMs generate individual exercises and complete exams from them. Three modules: materials (PDF/DOCX upload with text extraction), exercise pool (versioning, tags, full-text search), and worksheets — including AI suggestions from the pool, print-ready PDF export via Puppeteer, and simulated student performance at three ability levels.
Node.js/Express with PostgreSQL, React frontend with Tailwind v4. All LLM calls go through the in-house AI gateway; generation runs asynchronously via a job queue with batch workers, a three-stage JSON parser (strict → repair → jsonrepair), and partial recovery for truncated responses. Its standout feature: a continuous self-audit system has each exercise re-graded by a different model than its creator across five criteria (cross-model grading) and reports the scores back to the gateway as quality feedback — future auto model selection then favors the models with the best audit history.
zuletzt bearbeitet 02.08.2026 last touched 2026-08-02
Selbstgehostete Lernplattform für Schüler der Klassen 1–13, ausgerichtet am Bildungsplan Baden-Württemberg — läuft komplett im Heimnetz, ohne Cloud-Abhängigkeiten zur Laufzeit. Ein KI-Tutor erklärt Themen nach der sokratischen Methode (hinführen statt vorsagen), generiert Übungsaufgaben in sieben Aufgabentypen, gibt sofortiges Feedback und bietet einen Prüfungsmodus mit Notensimulation. Dazu kommen acht Lernspiele, ein XP-/Badge-Belohnungssystem, On-Demand-PDF-Aufgabenblätter und ein „Was brauche ich im Leben"-Bereich jenseits des Lehrplans.
Technisch ein bewusst schlankes Python-Backend (stdlib http.server) mit PostgreSQL und Vanilla-JS-Frontend. Alle LLM-Aufrufe laufen über meinen lokalen AI-Gateway mit aufgabenspezifischem Modell-Routing: Reasoning-Modell für Mathematik, Chat-Modell fürs Tutoring, schnelles kleines Modell für Spiele. Lernmaterial-Bilder erzeugt eine eigene ComfyUI-Pipeline (Flux.1) auf lokaler GPU; ein Vision-Modell prüft jedes generierte Bild automatisch gegen die Anforderung, bevor es im Admin-Review-Workflow freigegeben wird.
Self-hosted learning platform for students in grades 1–13, aligned with the Baden-Württemberg state curriculum — running entirely on the home network with no cloud dependencies at runtime. An AI tutor explains topics using the Socratic method (guiding instead of giving answers), generates exercises across seven question types, provides instant feedback, and offers an exam mode with grade simulation. On top of that: eight learning games, an XP/badge reward system, on-demand PDF worksheets, and a "life skills" section beyond the school curriculum.
Under the hood it is a deliberately lean Python backend (stdlib http.server) with PostgreSQL and a vanilla-JS frontend. All LLM calls go through my local AI gateway with task-specific model routing: a reasoning model for math, a chat model for tutoring, a fast small model for games. Learning-material images come from a dedicated ComfyUI pipeline (Flux.1) on a local GPU; a vision model automatically checks every generated image against the requirements before it enters the admin review workflow.
zuletzt bearbeitet 02.08.2026 last touched 2026-08-02
Zentrale Error- und Audit-Event-Sammelstelle für alle eigenen Dienste — bewusst kein Sentry: kein APM, kein Log-Tailing, kein Dashboard, sondern eine kuratierte Bug-Queue, die ein KI-Agent am Session-Start per API abarbeitet und Bugs mit Fix-Commit-Referenz schließt. Ein self-hosted Sentry-Stack (4–8 GB RAM, ~20 Container) wäre für unter 100 Events/Tag Overkill; der Eigenbau läuft komplett im eigenen Netz mit rund 1 GB RAM.
FastAPI + PostgreSQL, Backend als Single-File (~400 Zeilen). Dedup per Fingerprint (ein Fehler, der 1000× feuert, ist eine Row mit occurrence_count 1000), Status-Workflow open → investigating → fixed/wontfix/ignored mit Auto-Reopen, wenn ein behobener Bug erneut auftritt. Die Python- und Node-Clients sind fire-and-forget mit non-blocking Queue-Dispatcher: ein einziges install_log_handler() genügt, und alle logger.error/warning landen automatisch in der Inbox — Framework-Rauschen wird gefiltert. In 14+ eigenen Projekten integriert.
Central error and audit event collector for all in-house services — deliberately not Sentry: no APM, no log tailing, no dashboard, just a curated bug queue that an AI agent works through via the API at the start of each session, closing bugs with a fix-commit reference. A self-hosted Sentry stack (4–8 GB RAM, ~20 containers) would be overkill for under 100 events per day; this homegrown version runs entirely on my own network in about 1 GB of RAM.
FastAPI + PostgreSQL, single-file backend (~400 lines). Deduplication via fingerprint (an error firing 1000 times is one row with occurrence_count 1000), status workflow open → investigating → fixed/wontfix/ignored with auto-reopen when a fixed bug recurs. The Python and Node clients are fire-and-forget with a non-blocking queue dispatcher: a single install_log_handler() call routes every logger.error/warning into the inbox automatically, with framework noise filtered out. Integrated into 14+ of my projects.
zuletzt bearbeitet 02.08.2026 last touched 2026-08-02