Skip to content

Changelog

Dokumentation aller wichtigen Änderungen am Appiyon-Projekt.

2025-10-24 - Admin-Modul & EasyAdmin Installation

✅ Neu implementiert

Infrastructure Layer - Admin-Modul

Entities (5):

  • Admin - System-Administrator Entity

    • Felder: id, name, email, password, email_verified_at, remember_token, deleted_at, timestamps
    • Soft Delete Support
    • Unique Email Constraint
  • AdminPasswordResetToken - Password Reset

    • Token-basiertes Reset-System
    • Expiration Support (60 Min)
  • AdminSession - Session Management

    • IP & User Agent Tracking
    • Last Activity Tracking
    • Auto-Expiration
  • AdminLoginAttempt - Security & Rate Limiting

    • Failed Login Tracking
    • IP-basierte Rate Limiting (Max 10 pro IP)
    • Email-basierte Rate Limiting (Max 5 pro Email)
    • Auto-Block nach Threshold (15 Min)
  • AdminAuditLog - Audit Trail

    • Alle Admin-Aktionen werden geloggt
    • Before/After Values
    • IP & User Agent
    • Beispiel-Actions: master_data.country.created, app.approved

ValueObjects (2):

  • AdminEmail - Email-Validierung

    • Format-Validierung
    • Max 255 Zeichen
    • Auto-Lowercase
  • AdminPassword - Password-Handling

    • Argon2ID Hashing (sicherster Algorithmus)
    • Strikte Anforderungen:
      • Min 8 Zeichen, Max 72
      • Mind. 1 Großbuchstabe
      • Mind. 1 Kleinbuchstabe
      • Mind. 1 Ziffer
    • Auto-Rehashing bei Algorithmus-Verbesserung

Repositories (3):

  • AdminRepository - CRUD für Admins
  • AdminAuditLogRepository - Audit-Logs
  • AdminLoginAttemptRepository - Login-Versuche mit Rate-Limiting-Queries

Use Cases (3):

  • CreateAdmin - Admin erstellen

    • Email-Eindeutigkeit prüfen
    • Password hashen
    • Validation
  • AuthenticateAdmin - Admin authentifizieren

    • Rate Limiting (5/Email, 10/IP in 15 Min)
    • Failed Attempt Tracking
    • Auto-Block bei Threshold
    • Password Rehashing
  • LogAdminAction - Admin-Aktionen loggen

    • Before/After Values
    • IP & User Agent
    • Admin-Zuordnung

Events (3):

  • AdminCreatedEvent - Admin wurde erstellt
  • AdminAuthenticatedEvent - Admin hat sich eingeloggt
  • AdminActionLoggedEvent - Admin-Aktion wurde geloggt

DTOs (1):

  • AdminDTO - API Response Format

Dev Layer

EasyAdmin Dashboard:

  • DashboardController - Haupt-Dashboard
    • Route: /admin
    • Navigation-Menu
    • Welcome-Screen

CRUD Controllers (3):

  • AdminCrudController - Admin-Verwaltung

    • Index, New, Edit, Detail
    • Delete deaktiviert (Soft Delete)
    • Password-Feld versteckt
  • AdminAuditLogCrudController - Audit-Trail

    • Read-Only (Immutable)
    • JSON-Editor für Old/New Values
    • Filterable
  • AdminLoginAttemptCrudController - Security-Monitoring

    • Read-Only
    • Filter: Successful, Date
    • Block-Status anzeigen

Event Subscribers (1):

  • AdminDomainRestrictionSubscriber
    • Beschränkt /admin auf appisym.go4family.net
    • Priority 31 (vor Security Layer)
    • 403 Forbidden bei falscher Domain

Console Commands (1):

  • admin:create - Admin erstellen via CLI
    • Interaktiver Modus (versteckte Passwort-Eingabe)
    • Non-interaktiver Modus (--name --email --password)
    • Umfassende Fehlerbehandlung
    • Hilfe-Texte

Shared Layer

Exception System erweitert:

  • Korrektur des ULID-Types in Doctrine-Config
    • Symfony\Component\Ulid\UlidTypeSymfony\Bridge\Doctrine\Types\UlidType

Event System:

  • DomainEventTrait Fehler behoben
    • parent::__construct() Problem gelöst
    • Events implementieren jetzt Interface direkt

Datenbank

Migration erstellt:

  • migrations/1_infrastructure/Version0001_admin.php
    • Namespace korrigiert: DoctrineMigrations\Infrastructure
    • 5 Tabellen erstellt (admins, admin_password_reset_tokens, admin_sessions, admin_login_attempts, admin_audit_logs)
    • Foreign Keys mit CASCADE/SET NULL
    • Indices für Performance

Migration ausgeführt:

  • ✅ Alle Admin-Tabellen erstellt
  • ✅ Constraints und Indices aktiv

Configuration

Environment Variables:

  • ADMIN_DOMAIN=appisym.go4family.net - Domain Restriction
  • APP_SECRET generiert
  • MESSENGER_TRANSPORT_DSN korrigiert (auto_setup entfernt)

Services:

  • Admin Domain Restriction Service registriert
  • Console Commands registriert
  • Event Subscribers konfiguriert

PHP-CS-Fixer:

  • Erweiterte Rules für Code-Style
  • Layer-spezifische Konfiguration
  • Argon2ID, Strict Types, PHPDoc Standards

PHPUnit:

  • Test-Struktur nach Layern
    • tests/Unit/Appi/Infrastructure/
    • tests/Integration/Appi/Infrastructure/
    • tests/Functional/Appi/Infrastructure/
  • 22 Test-Suites definiert
  • Layer- und Typ-spezifische Ausführung

Deployment

Dateien:

  • public/.htaccess - Apache Rewrite Rules
  • DEPLOYMENT.md - Deployment-Anleitung mit Troubleshooting

Dokumentation

Neue Dokumentation:

  • src/Appi/Infrastructure/Admin/README.md - Admin-Modul Dokumentation
  • src/Appi/Dev/Http/EventSubscriber/README.md - Event Subscribers
  • src/Appi/Dev/Console/Command/README.md - Console Commands
  • doku/docs/entwicklung/ - Entwickler-Dokumentation
    • index.md - Übersicht
    • troubleshooting-admin.md - Admin-Panel Troubleshooting
    • changelog.md - Dieses Dokument

🔧 Konfiguration

services.yaml:

  • Parameter: admin.allowed_domain
  • Console Commands Auto-Registration
  • Layer-spezifische Service-Excludes konsistent gemacht

doctrine.yaml:

  • Alle 6 Layer als Mappings registriert
  • ULID Type korrigiert

messenger.yaml:

  • AuditMessage auf async Transport

routes.yaml:

  • Controller-Pfad korrigiert: ../src/Appi/Dev/Http/Controller/

📦 Dependencies

Neu installiert:

  • easycorp/easyadmin-bundle v4.26.5
  • Symfony Form, Translation, Intl, UID
  • Symfony UX Twig Component
  • Twig HTML Extra

🗄️ Datenbank

Neue Tabellen (5):

admins (5 Spalten)
admin_password_reset_tokens (3 Spalten)
admin_sessions (6 Spalten)
admin_login_attempts (7 Spalten)
admin_audit_logs (10 Spalten)

Indices:

  • admins_email_unique auf admins.email
  • idx_admin_sessions_admin_id auf admin_sessions.admin_id
  • idx_admin_sessions_last_activity auf admin_sessions.last_activity
  • idx_admin_login_attempts_email auf admin_login_attempts.email
  • idx_admin_login_attempts_ip auf admin_login_attempts.ip_address
  • idx_admin_audit_logs_admin_id auf admin_audit_logs.admin_id
  • idx_admin_audit_logs_model auf admin_audit_logs(model_type, model_id)
  • idx_admin_audit_logs_action auf admin_audit_logs.action

🎯 Erster Admin erstellt

Credentials:

  • ID: 1
  • Name: Super Admin
  • Email: admin@appiyon.com
  • Password: SecureP@ss123 (Argon2ID Hash)
  • Created: 2025-10-24 20:26:35

Zugriff:

URL: https://appisym.go4family.net/admin
Email: admin@appiyon.com
Password: SecureP@ss123

🔒 Security Features

  • ✅ Domain Restriction auf appisym.go4family.net
  • ✅ Rate Limiting (5/Email, 10/IP)
  • ✅ Argon2ID Password Hashing
  • ✅ Session Tracking mit IP & User Agent
  • ✅ Failed Login Attempt Logging
  • ✅ Complete Audit Trail
  • ✅ Soft Deletes für Admins

📊 Statistik

  • 23 PHP-Dateien im Admin-Modul erstellt
  • 4 EasyAdmin-Controller erstellt
  • 1 Console Command erstellt
  • 1 Event Subscriber erstellt
  • 5 Database-Tabellen erstellt
  • 18 Test-Verzeichnisse erstellt

🐛 Behobene Bugs

  1. Event-Klassen: parent::__construct() Fehler in DomainEventTrait
  2. Doctrine ULID Type: Falscher Namespace
  3. Admin Entity: unique Parameter in ORM\Index nicht unterstützt
  4. Migration Namespace: DoctrineMigrations\Layer0SharedDoctrineMigrations\Infrastructure
  5. Services Excludes: Inkonsistente Patterns über Layer hinweg
  6. 404 bei /admin: .htaccess fehlte in public/
  7. MESSENGER_TRANSPORT_DSN: auto_setup=0 Inkonsistenz

📝 Offene Aufgaben

  • [ ] Security Bundle Integration für Admin-Login
  • [ ] Admin UserProvider implementieren
  • [ ] Login-Form erstellen
  • [ ] Remember Me Funktionalität
  • [ ] Password Reset Flow
  • [ ] Email Verification Flow
  • [ ] Two-Factor Authentication
  • [ ] Admin Permissions/Roles System
  • [ ] Test-Suite für Admin-Modul

🎓 Lessons Learned

  1. Traits mit Konstruktoren brauchen spezielle Behandlung - kein parent::__construct() möglich
  2. Doctrine Attributes haben spezifische Parameter - unique muss in UniqueConstraint statt Index
  3. Symfony Service Auto-Loading braucht konsistente Exclude-Patterns
  4. Document Root muss auf public/ zeigen für Symfony-Apps
  5. Domain Restriction sollte vor Security Layer laufen (Priority wichtig)
  6. Event Subscribers brauchen explizite Service-Registrierung wenn Parameter benötigt werden

Nächste Schritte

  1. Security-Integration für Admin-Login
  2. Weitere Infrastructure-Module
  3. Foundation-Layer aufbauen
  4. Core-Layer definieren
  5. Domain-Module implementieren

Total Lines of Code: ~3500+ (geschätzt) Total Files Created: 35+ Duration: ~2 Stunden Status: ✅ Production Ready (für Admin-Modul)

Built with VitePress