Projekte
Raum-Buchungssystem — Symfony 7 + Nuxt 4
2026
Entkoppelte REST-API mit SPA-Frontend: race-condition-freie Konfliktprüfung, Genehmigungs-Workflows, iCalendar-Export und 42 PHPUnit-Tests.
- Symfony 7
- Doctrine
- JWT
- Nuxt 4
- TypeScript
- Docker
- PHPUnit
Die Aufgabe
Ein Meeting-Raum-Buchungssystem als Arbeitsprobe: Räume verwalten, Verfügbarkeiten prüfen, Buchungen anlegen und verschieben — mit Admin-Genehmigungen und sauberer API. Bewusst als entkoppeltes System gebaut: Symfony-7-REST-API und Nuxt-4-SPA, verbunden nur über HTTP.
Das interessanteste Problem: Doppelbuchungen
Zwei Nutzer buchen denselben Raum zur selben Zeit — klassische Race Condition. Die Lösung: eine Transaktion mit Overlap-Query vor dem INSERT.
SELECT * FROM booking
WHERE room_id = :room
AND cancelled_at IS NULL
AND start_at < :newEnd
AND end_at > :newStart
SQLite serialisiert Schreibvorgänge (ein Schreiber zur Zeit im WAL-Modus), damit ist der Check-then-Insert innerhalb der Transaktion race-condition-frei. Der Trade-off ist dokumentiert: Bei einem Wechsel auf PostgreSQL/MySQL braucht es SELECT FOR UPDATE auf Raumebene.
Weitere Entscheidungen
- Stateless JWT-Auth (RSA-256) — horizontal skalierbar, ohne Session-Storage; die Trade-offs (Token-Revocation, Cookie-Scope) sind im Entscheidungslog festgehalten.
- Soft Delete für Stornierungen —
cancelled_atstatt DELETE erhält die Historie für Auswertungen. - Genehmigungs-Workflows — Buchungen von Basisnutzern starten als
pending; Admins genehmigen Buchungen und Raum-Änderungsanträge. - iCalendar-Export (RFC 5545) — jede Buchung als
.icsdirekt in den Kalender. - Raumübergreifende Verfügbarkeitssuche — „welcher Raum ist am Dienstag 14–16 Uhr für 8 Personen frei?” als ein API-Call.
Qualität & Übergabe
42 PHPUnit-Tests (Repository, Controller, Services), Docker-Compose-Setup mit einem Befehl, und eine docs/ mit Mermaid-Architekturdiagrammen, API-Referenz und Anforderungsabgleich. So sieht bei mir Übergabe aus — auch bei kleinen Projekten.