Table of Contents
- Backend-Dokumentation
- Übersicht
- Verzeichnisstruktur
- Models
- Repositories
- Services
- Web-Endpoints
- Öffentliche Endpoints
- /anmeldung/ (static/anmeldung/index.php → public/anmeldung/index.php)
- /registration/ (static/registration/index.php → public/registration/index.php)
- Admin-Endpoints
- Datenbank-Schema
- Sicherheit
- Erweiterungen
Backend-Dokumentation
Übersicht
Das PHP-Backend verwaltet Anmeldungen für die Zwergen-Börse. Es verwendet eine klare Architektur mit Models, Repositories und Services.
Für ein zusammenhängendes Gesamtbild (inkl. Build-/Laufzeit-Pfade):
→ Projekt-Landkarte (Code-getrieben)
Verzeichnisstruktur
zgb-backend/
├── Model/ # Domain-Models (Value Objects)
├── Repository/ # Datenzugriff
│ └── Schema/ # SQL-Dateien
├── Service/ # Business-Logik
└── web/ # Controller/Endpoints
Models
Registration
Immutable Value Object für Anmeldungen:
final class Registration
{
public function __construct(
public readonly string $salutation,
public readonly string $firstName,
public readonly string $lastName,
public readonly string $street,
public readonly string $postcode,
public readonly string $city,
public readonly string $email,
public readonly string $phone,
public readonly string $transfer,
public readonly ?string $teamMember,
public readonly int $number,
public readonly string $createdAt
) {}
}
Felder:
salutation: Anrede (Herr, Frau, Divers)firstName,lastName: Namestreet,postcode,city: Adresseemail,phone: Kontakttransfer: Übergabeart (Post, Abholung, Team)teamMember: Name des Teammitglieds (optional)number: Vergebene AnmeldenummercreatedAt: Zeitstempel
Config
Konfiguration für das System:
final class Config
{
public function __construct(
public readonly string $startDate,
public readonly string $endDate,
public readonly int $startNumber,
public readonly int $maxNumber,
public readonly string $operatorEmail,
public readonly string $eventDate,
public readonly string $adminPasswordHash = ''
) {}
}
Felder:
startDate: Startdatum Anmeldung (ISO-Format:Y-m-d)endDate: Enddatum Anmeldung (ISO-Format:Y-m-d)startNumber: Erste vergebene NummermaxNumber: Maximale Anzahl AnmeldungenoperatorEmail: E-Mail des OrganisatorseventDate: Datum der Zwergenbörse (ISO-Format:Y-m-d)adminPasswordHash: Gehashtes Admin-Passwort (optional)
Repositories
RegistrationRepository
Verwaltet Anmeldungen in der Datenbank.
Methoden:
saveRegistration(Registration $registration): Speichert AnmeldungloadRegistration(int $id): Lädt Anmeldung nach IDgetAllRegistrations(): Alle AnmeldungenclearAllRegistrations(): Löscht alle AnmeldungenexistsDuplicateRegistration(array $data): Prüft auf Duplikate
SQL-Schema: Repository/Schema/Registration/
ConfigRepository
Verwaltet System-Konfiguration als Key-Value-Paare.
Methoden:
loadConfig(): Lädt aktuelle Konfiguration als Config-ObjektsaveConfig(Config $config): Speichert Konfiguration (alle Werte)getConfig(string $key): Lädt einzelnen KonfigurationswertsetConfig(string $key, string $value): Setzt einzelnen Konfigurationswert
SQL-Schema: Repository/Schema/Config/
Hinweis: Die Konfiguration wird als Key-Value-Paare in der Datenbank gespeichert. loadConfig() und saveConfig() arbeiten mit dem Config-Objekt, während getConfig() und setConfig() einzelne Werte verwalten.
Repository (Basis-Klasse)
Abstrakte Basis-Klasse für alle Repositories:
abstract class Repository
{
public static function CreatePDO(string $dbPath): PDO
// Erstellt PDO-Verbindung zur SQLite-Datenbank
protected function getSQL(string $fname): string
// Lädt SQL-Datei aus Schema-Verzeichnis
}
Services
AuthService
Authentifizierung und Rate-Limiting.
Methoden:
isAdmin(): Prüft Admin-StatusrequireAdmin(): Erzwingt Admin-Loginlogin(): Setzt Admin-Sessionlogout(): Beendet SessioncheckRateLimit(): Prüft Rate-LimitfailRateLimit(): Erhöht FehlversucheresetRateLimit(): Setzt Rate-Limit zurück
Rate-Limiting:
- Max. 5 Fehlversuche
- Block: 10 Minuten
CSRFService
CSRF-Token-Verwaltung.
Methoden:
getToken(): Generiert/erhält TokencheckToken(?string $token): Validiert TokenrotateToken(): Rotiert Token
Implementierung:
- Token in Session gespeichert
- 32 Bytes zufällige Hex-String
- Prüfung bei allen POST-Requests
MailService
E-Mail-Versand mit Templates.
Methoden:
sendUserMail(Registration $registration, Config $config): Bestätigung an UsersendOrganizerMail(Registration $registration, Config $config): Benachrichtigung an Organisator
Templates:
MailTemplates/user_mail.txt: User-BestätigungMailTemplates/organizer_mail.txt: Organisator-Benachrichtigung
Template-Syntax:
{{variable}}: Platzhalter{{#if teamMember}}...{{/if}}: Bedingte Blöcke
Für den asynchronen Versand (Queue, Rate-Limit, Cron):
→ Mail-Queue
SessionService
Zentrales, sicheres Session-Setup.
Methoden:
start(): Startet Session mit sicheren Default-Flags
Features:
- Automatische Cookie-Flag-Konfiguration (HttpOnly, Secure, SameSite)
- Strict Mode aktiviert
- Nur Cookie-basierte Sessions
- CLI-kompatibel (keine Cookies im CLI-Modus)
Verwendung:
SessionService::start();
// Danach kann $_SESSION verwendet werden
RateLimitService
File-basiertes Rate-Limiting für spezifische Aktionen.
Methoden:
allowWithCooldown(string $filePath, string $actionKey, int $cooldownSeconds): Prüft, ob Aktion erlaubt ist
Features:
- File-basiertes Locking (flock)
- Action-spezifische Cooldowns
- Fail-open bei Dateisystem-Problemen
Verwendung:
if (!RateLimitService::allowWithCooldown($rateLimitFile, 'admin_password_reset', 600)) {
// Aktion noch in Cooldown (10 Minuten)
}
Einsatz:
- Passwort-Reset-Limiting (10 Minuten Cooldown)
- Weitere Rate-Limits nach Bedarf
LogService
Strukturiertes Logging für Fehler und Events.
Methoden:
error(string $message, array $context = [], ?\Throwable $exception = null): Loggt Fehlerwarning(string $message, array $context = []): Loggt Warnunginfo(string $message, array $context = []): Loggt Infodebug(string $message, array $context = []): Loggt Debug-Info
Features:
- Strukturiertes JSON-Logging
- Kontext-Informationen
- Exception-Stack-Traces
- Log-Level (ERROR, WARNING, INFO, DEBUG)
Verwendung:
LogService::error('Fehler beim Speichern', [
'file' => __FILE__,
'line' => __LINE__,
'registration_number' => $number
], $exception);
MailQueueWorker
Asynchroner E-Mail-Versand mit Queue-System.
Methoden:
run(string $dbPath, string $logPath): Startet Worker (CLI-only)
Features:
- Token-Bucket Rate-Limiting
- Retry-Mechanismus mit Backoff
- Lock/Lease-System für Concurrency
- Automatische Cleanup von "waisen" Jobs
Siehe auch: Mail-Queue
Web-Endpoints
Öffentliche Endpoints
/anmeldung/ (static/anmeldung/index.php → public/anmeldung/index.php)
Zeigt Anmeldeformular:
- Prüft Anmeldezeitraum
- Findet freie Nummer
- Zeigt Formular oder Fehlermeldung
/registration/ (static/registration/index.php → public/registration/index.php)
Verarbeitet Formular-Submission:
- Validierung
- Duplikat-Prüfung
- Speicherung
- E-Mail-Versand
- Weiterleitung
Hinweis: Die konkreten Build-/Laufzeit-Pfade und der vollständige Flow sind in der Projekt-Landkarte (Code-getrieben) dokumentiert.
Admin-Endpoints
/backend/web/admin_login.php
Login-Seite:
- Passwort-Eingabe
- Rate-Limiting
- Session-Management
/backend/web/admin.php
Haupt-Admin-Seite:
- Konfiguration bearbeiten
- Export-Funktion
- Logout
- Passwort ändern
- Anmeldungen löschen
Zugriffsschutz: Nur für eingeloggte Admins
/backend/web/admin_password.php
Passwort ändern:
- Altes Passwort prüfen
- Neues Passwort setzen
- Hash in Datenbank speichern
/backend/web/admin_logout.php
Logout:
- Session beenden
- Weiterleitung zu Login
/backend/web/export_registrations.php
CSV-Export:
- Alle Anmeldungen als CSV
- Download-Datei
/backend/web/clear_registrations.php
Anmeldungen löschen:
- Nur außerhalb Anmeldezeitraum
- Unwiderruflich
/backend/web/counter.php
Zählt Anmeldungen:
- Aktuelle Anzahl
- JSON-Response
Datenbank-Schema
Quelle der Wahrheit
Das Schema wird automatisch initialisiert und liegt als SQL-Dateien unter:
zgb-backend/Repository/Schema/Registration/*zgb-backend/Repository/Schema/Config/*zgb-backend/Repository/Schema/MailQueue/*
Eine lesbare Zusammenfassung ist in Datenbank.
Für “Warum ist das so?” siehe Entscheidungen & Historie.
Für Performance-Aspekte (SQLite, Caches, Indizes, etc.):
→ Performance & Optimierungen
Sicherheit
Implementierte Maßnahmen
- CSRF-Schutz: Token bei allen POST-Requests
- SQL-Injection-Schutz: Prepared Statements
- Rate-Limiting: Schutz vor Brute-Force
- Session-Sicherheit: Regenerierung nach Login
- Input-Validierung: Server-seitig
- HTTP-Security-Headers: X-Frame-Options, CSP, etc.
Best Practices
- Passwörter: Bcrypt-Hashing (über
password_hash()) - Sessions: Sichere Cookie-Flags
- Fehlerbehandlung: Keine sensiblen Daten in Fehlermeldungen
- Logging: Admin-Aktionen protokollieren
Erweiterungen
Neue Funktion hinzufügen
-
Model erstellen (falls nötig):
// zgb-backend/Model/NewModel.php -
Repository erstellen:
// zgb-backend/Repository/NewRepository.php // SQL in Repository/Schema/NewModel/ -
Service erstellen (falls nötig):
// zgb-backend/Service/NewService.php -
Controller erstellen:
// zgb-backend/web/new_endpoint.php
Validierung erweitern
Validierung erfolgt in den Controllern. Beispiel:
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
exit('Ungültige E-Mail-Adresse');
}
E-Mail-Templates anpassen
Templates in Service/MailTemplates/ bearbeiten:
- Platzhalter:
{{variable}} - Bedingte Blöcke:
{{#if condition}}...{{/if}}
Einstieg
Architektur
- Architektur-Übersicht
- Frontend-Build
- Backend
- Datenbank
- Mail-Queue
- Performance & Optimierungen
- Entscheidungen & Historie
Betrieb
Projektarbeit
- Code:
ssh://forgejo@home.schumbi.de/ralf/zgb_www.git - Wiki:
ssh://forgejo@home.schumbi.de/ralf/zgb_www.wiki.git