Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
25
backups/docs-backup-20250731125004/ARCHITECURE.md
Normal file
25
backups/docs-backup-20250731125004/ARCHITECURE.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Architektur-Prinzipien
|
||||
|
||||
Dieses Dokument beschreibt die grundlegenden Architekturprinzipien unseres Frameworks.
|
||||
|
||||
## 1. Immutabilität und Unveränderlichkeit
|
||||
|
||||
Wo immer möglich, sollten Objekte unveränderlich (immutable) sein. Dies verbessert die Voraussagbarkeit und Testbarkeit.
|
||||
|
||||
## 2. Final by Default
|
||||
|
||||
Alle Klassen sollten standardmäßig als `final` deklariert werden, es sei denn, es gibt einen konkreten Grund für Vererbung.
|
||||
Begründung:
|
||||
- Vermeidet unbeabsichtigte Vererbungshierarchien
|
||||
- Verbessert die Kapselung
|
||||
- Ermöglicht interne Änderungen, ohne Kinderklassen zu beeinflussen
|
||||
|
||||
## 3. Explizite über Implizite
|
||||
|
||||
- Alle Abhängigkeiten sollten explizit injiziert werden
|
||||
- Keine globalen Zustände oder Singletons
|
||||
- Typen immer explizit deklarieren
|
||||
|
||||
## 4. Modularität
|
||||
|
||||
Jedes Modul sollte in sich geschlossen sein und minimale Abhängigkeiten nach außen haben.
|
||||
13
backups/docs-backup-20250731125004/Application/Controller.md
Normal file
13
backups/docs-backup-20250731125004/Application/Controller.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Controller
|
||||
|
||||
```PHP
|
||||
|
||||
final readonly class Controller
|
||||
{
|
||||
public function __invoke(): ActionResult
|
||||
{
|
||||
new ViewResult();
|
||||
}
|
||||
}
|
||||
|
||||
````
|
||||
76
backups/docs-backup-20250731125004/COMMITS.md
Normal file
76
backups/docs-backup-20250731125004/COMMITS.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# 📘 Commit-Konventionen – Conventional Commits
|
||||
|
||||
Dieses Projekt verwendet das [Conventional Commits](https://www.conventionalcommits.org)-Format für einheitliche und nachvollziehbare Commit-Nachrichten.
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Format
|
||||
|
||||
```
|
||||
<type>[optional scope]: <beschreibung>
|
||||
```
|
||||
|
||||
**Beispiel:**
|
||||
|
||||
```
|
||||
feat: add Ansible deploy playbook
|
||||
```
|
||||
|
||||
- **Englisch**
|
||||
- **Präsens** (z. B. „add“, nicht „added“)
|
||||
- **Keine abschließenden Punkte**
|
||||
- **Optionaler Body** bei größeren Änderungen
|
||||
|
||||
---
|
||||
|
||||
## 📦 Commit-Typen
|
||||
|
||||
| Typ | Beschreibung |
|
||||
|------------|--------------------------------------------------------|
|
||||
| `feat` | ✨ Neues Feature |
|
||||
| `fix` | 🐛 Fehlerbehebung |
|
||||
| `docs` | 📘 Nur Dokumentation (z. B. README, .env.example) |
|
||||
| `style` | 🎨 Formatierung, keine Änderung am Verhalten |
|
||||
| `refactor` | 🔁 Code-Umstrukturierung ohne neues Verhalten/Feature |
|
||||
| `test` | 🧪 Tests hinzufügen oder anpassen |
|
||||
| `chore` | 🔧 Projektpflege (z. B. `.gitignore`, `.mailmap`, Cleanup) |
|
||||
|
||||
---
|
||||
|
||||
## ✅ Gute Commit-Beispiele
|
||||
|
||||
```bash
|
||||
chore: initial commit with Docker + Ansible setup
|
||||
feat: add restart task to deploy role
|
||||
fix: correct Docker volume path
|
||||
docs: add .env.example as reference
|
||||
chore: add .mailmap to unify author identity
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🛑 Vermeide unklare Messages wie:
|
||||
|
||||
```bash
|
||||
"update"
|
||||
"bugfixes"
|
||||
"misc"
|
||||
"more changes"
|
||||
```
|
||||
|
||||
Diese helfen später weder dir noch Tools oder anderen.
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Tipps
|
||||
|
||||
- Nutze aussagekräftige, prägnante Beschreibungen
|
||||
- Schreibe deine Commits so, dass man daraus verstehen kann, **was passiert** – ohne Git-Diff zu lesen
|
||||
- Wenn du mehrere Dinge in einem Commit machst, überlege, ob es **mehrere Commits** sein sollten
|
||||
|
||||
---
|
||||
|
||||
## 📚 Weitere Infos
|
||||
|
||||
- [conventionalcommits.org](https://www.conventionalcommits.org)
|
||||
- [semantic-release](https://semantic-release.gitbook.io/semantic-release/) – für automatische Releases basierend auf Commit-Typen
|
||||
43
backups/docs-backup-20250731125004/DEPLOYMENT.md
Normal file
43
backups/docs-backup-20250731125004/DEPLOYMENT.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# 🚀 Deployment-Anleitung (Ansible-basiert)
|
||||
|
||||
Dieses Projekt verwendet Ansible zur automatisierten Bereitstellung.
|
||||
|
||||
---
|
||||
|
||||
## 🧱 Struktur
|
||||
|
||||
- `ansible/setup.yml` → Bereitet Zielserver vor (Docker, Git, Benutzer)
|
||||
- `ansible/deploy.yml` → Clont Projekt & startet Docker Compose
|
||||
|
||||
---
|
||||
|
||||
## 📂 Vorbereitung
|
||||
|
||||
1. Zielserver (Debian)
|
||||
2. SSH-Zugang (z. B. via `~/.ssh/id_rsa`)
|
||||
3. Eintrag in `ansible/inventory.ini`:
|
||||
|
||||
```ini
|
||||
[web]
|
||||
123.123.123.123 ansible_user=root
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ▶️ Ausführen
|
||||
|
||||
```bash
|
||||
# Setup ausführen (nur einmal)
|
||||
ansible-playbook -i ansible/inventory.ini ansible/setup.yml
|
||||
|
||||
# Projekt deployen (beliebig oft)
|
||||
ansible-playbook -i ansible/inventory.ini ansible/deploy.yml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Hinweis
|
||||
|
||||
- `.env` wird **nicht** automatisch übertragen
|
||||
- Serverpfade ggf. per `dest:` in `git:`-Modul anpassen
|
||||
|
||||
40
backups/docs-backup-20250731125004/ENV.md
Normal file
40
backups/docs-backup-20250731125004/ENV.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# 🔐 Umgebungsvariablen (.env)
|
||||
|
||||
Dieses Projekt verwendet `.env`-Dateien zur Konfiguration von Docker Compose und anderen Tools.
|
||||
|
||||
---
|
||||
|
||||
## 📄 Beispiel: .env
|
||||
|
||||
```env
|
||||
COMPOSE_PROJECT_NAME=michaelschiemer
|
||||
APP_PORT=8000
|
||||
PHP_VERSION=8.2
|
||||
```
|
||||
|
||||
> Diese Datei sollte **nicht** versioniert werden.
|
||||
|
||||
---
|
||||
|
||||
## 📄 Beispiel: .env.example
|
||||
|
||||
Diese Datei enthält Beispielwerte und wird mit dem Projekt mitgeliefert.
|
||||
|
||||
---
|
||||
|
||||
## 📌 Nutzung in docker-compose.yml
|
||||
|
||||
```yaml
|
||||
php:
|
||||
image: php:${PHP_VERSION}-fpm
|
||||
web:
|
||||
ports:
|
||||
- "${APP_PORT}:80"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📦 Empfehlung
|
||||
|
||||
- `.env` → lokal, nicht versioniert
|
||||
- `.env.example` → ins Git, immer aktuell halten
|
||||
61
backups/docs-backup-20250731125004/MARKDOWN.md
Normal file
61
backups/docs-backup-20250731125004/MARKDOWN.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# Heading 1
|
||||
## Heading 2
|
||||
### Heading 3
|
||||
#### Heading 4
|
||||
##### Heading 5
|
||||
###### Heading 6
|
||||
|
||||
*italics*
|
||||
|
||||
**bold**
|
||||
|
||||
***italics & bold***
|
||||
|
||||
~~crossed off~~
|
||||
|
||||
<mark>highlight</mark>
|
||||
|
||||
<sub>Test</sub>
|
||||
|
||||
`monospace`
|
||||
|
||||
```html
|
||||
|
||||
<html>
|
||||
<header></header>
|
||||
|
||||
<footer></footer>
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
[This is a link](https://localhost)
|
||||
|
||||

|
||||
|
||||
> This is a blockquote
|
||||
>> and it can be nested
|
||||
|
||||
***
|
||||
|
||||
---
|
||||
|
||||
___
|
||||
|
||||
1. Item 1
|
||||
2. Item 2
|
||||
3. Item 3
|
||||
|
||||
* Test
|
||||
* Test
|
||||
* Subitem
|
||||
* Subitem
|
||||
|
||||
| Column1 | Column 2 |
|
||||
| --- |-----|
|
||||
| Test | Test2 |
|
||||
|
||||
- [ ] Test
|
||||
- [x] Test 2
|
||||
77
backups/docs-backup-20250731125004/README.md
Normal file
77
backups/docs-backup-20250731125004/README.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# Projekt-Dokumentation
|
||||
|
||||
## Übersicht
|
||||
|
||||
Willkommen zur Dokumentation des Projekts. Diese Dokumentation dient als zentrale Informationsquelle für Entwickler, die am Projekt arbeiten.
|
||||
|
||||
## Inhaltsverzeichnis
|
||||
|
||||
### Standards und Guidelines
|
||||
|
||||
- [Coding Guidelines](/docs/standards/CODING-GUIDELINES.md) - Allgemeine Coding-Standards für das Projekt
|
||||
- [Sicherheitsrichtlinien](/docs/standards/SICHERHEITS-GUIDELINES.md) - Standards für sichere Softwareentwicklung
|
||||
|
||||
### Entwicklungsrichtlinien
|
||||
|
||||
- [Performance Guidelines](/docs/guidelines/PERFORMANCE-GUIDELINES.md) - Richtlinien zur Optimierung der Anwendungsleistung
|
||||
- [Testing Guidelines](/docs/guidelines/TESTING-GUIDELINES.md) - Standards und Best Practices für Tests
|
||||
|
||||
### KI-Assistent Konfiguration
|
||||
|
||||
- [Guidelines für KI-Assistenten](/docs/ai/GUIDELINES-FÜR-AI-ASSISTANT.md) - Spezifische Richtlinien für den KI-Assistenten
|
||||
- [PhpStorm Einrichtung](/docs/ai/EINRICHTUNG-PHPSTORM.md) - Anleitung zur Einrichtung des KI-Assistenten in PhpStorm
|
||||
|
||||
### Architektur und Struktur
|
||||
|
||||
- [Projektstruktur](/docs/architecture/STRUKTUR-DOKUMENTATION.md) - Überblick über die Struktur des Projekts
|
||||
|
||||
### Framework-Entwicklung
|
||||
|
||||
- [Modul-Checkliste](/docs/framework/MODUL-CHECKLISTE.md) - Leitfaden für die Erstellung neuer Module
|
||||
- [Erweiterungsmuster](/docs/framework/ERWEITERUNGSPATTERN.md) - Muster zur Erweiterung des Frameworks
|
||||
|
||||
### Framework-Module
|
||||
|
||||
- [Analytics-Modul](/docs/framework/analytics/README.md) - Tracking und Analyse von Anwendungsdaten
|
||||
- [Core-Modul](/docs/framework/core/README.md) - Kernkomponenten und Event-System
|
||||
- [DI-Modul](/docs/framework/di/README.md) - Dependency-Injection-Container
|
||||
- [HTTP-Modul](/docs/framework/http/README.md) - HTTP-Request und -Response-Handling
|
||||
|
||||
## Mitwirken
|
||||
|
||||
### Neue Module entwickeln
|
||||
|
||||
1. Folge der [Framework-Modul Checkliste](/docs/framework/MODUL-CHECKLISTE.md) für neue Module
|
||||
2. Stelle sicher, dass dein Code den [Coding Guidelines](/docs/standards/CODING-GUIDELINES.md) entspricht
|
||||
3. Schreibe Tests gemäß den [Testing Guidelines](/docs/guidelines/TESTING-GUIDELINES.md)
|
||||
4. Erstelle eine ausführliche Dokumentation für dein Modul
|
||||
|
||||
### Dokumentation verbessern
|
||||
|
||||
Wir begrüßen Beiträge zur Verbesserung der Dokumentation. Wenn du Fehler findest oder Vorschläge zur Verbesserung hast, erstelle bitte einen Pull Request mit deinen Änderungen.
|
||||
|
||||
## Erste Schritte
|
||||
|
||||
Neue Entwickler sollten mit folgenden Schritten beginnen:
|
||||
|
||||
1. Projekt lokal einrichten (siehe [Installation](#installation))
|
||||
2. Die [Projektstruktur](/docs/architecture/STRUKTUR-DOKUMENTATION.md) verstehen
|
||||
3. Die [Coding Guidelines](/docs/standards/CODING-GUIDELINES.md) lesen
|
||||
4. PhpStorm mit dem [KI-Assistenten einrichten](/docs/ai/EINRICHTUNG-PHPSTORM.md)
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
# Repository klonen
|
||||
git clone [repository-url]
|
||||
|
||||
# Abhängigkeiten installieren
|
||||
composer install
|
||||
|
||||
# Entwicklungsserver starten
|
||||
php -S localhost:8000 -t public/
|
||||
```
|
||||
|
||||
## Updates und Änderungen
|
||||
|
||||
Diese Dokumentation wird kontinuierlich aktualisiert. Prüfe regelmäßig auf Aktualisierungen, um über die neuesten Best Practices und Standards informiert zu bleiben.
|
||||
48
backups/docs-backup-20250731125004/SETUP.md
Normal file
48
backups/docs-backup-20250731125004/SETUP.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# ⚙️ Setup-Anleitung
|
||||
|
||||
Diese Datei beschreibt, wie du das Projekt lokal einrichtest und startest.
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Voraussetzungen
|
||||
|
||||
- Docker & Docker Compose
|
||||
- Python 3 (für Ansible, optional pipx)
|
||||
- Optional: Ansible (für Server-Setup)
|
||||
- Optional: PhpStorm oder VS Code
|
||||
|
||||
---
|
||||
|
||||
## 📦 Projektstruktur
|
||||
|
||||
```
|
||||
.
|
||||
├── app/ # PHP/NGINX-Anwendung
|
||||
├── ansible/ # Setup- und Deployment-Playbooks
|
||||
├── docker-compose.yml
|
||||
├── .env # Lokale Konfiguration (nicht versioniert)
|
||||
├── Makefile # Komfortbefehle
|
||||
└── docs/ # Dokumentation
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ▶️ Lokaler Start
|
||||
|
||||
```bash
|
||||
# Container starten
|
||||
docker compose up --build
|
||||
|
||||
# Alternativ mit Makefile
|
||||
make deploy
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Lokale Tests
|
||||
|
||||
- `http://localhost:8080` → NGINX + PHP
|
||||
- Logs anzeigen: `docker compose logs -f`
|
||||
|
||||
---
|
||||
|
||||
379
backups/docs-backup-20250731125004/UnitOfWork.md
Normal file
379
backups/docs-backup-20250731125004/UnitOfWork.md
Normal file
@@ -0,0 +1,379 @@
|
||||
# UnitOfWork Pattern - Enterprise Transaktionsmanagement
|
||||
|
||||
Das UnitOfWork Pattern bietet transaktionale Entity-Verwaltung mit automatischer Change Detection und Bulk Operations für optimale Performance.
|
||||
|
||||
## 🏗️ Architektur
|
||||
|
||||
### Core Components
|
||||
|
||||
```
|
||||
UnitOfWork
|
||||
├── ChangeTracker (WeakMap-basiert)
|
||||
│ ├── EntityState (Enum)
|
||||
│ ├── Entity State Tracking
|
||||
│ └── Change Detection
|
||||
├── BulkOperations
|
||||
│ ├── Bulk INSERT
|
||||
│ ├── Bulk UPDATE
|
||||
│ └── Bulk DELETE
|
||||
└── Transaction Management
|
||||
├── Auto-Commit Mode
|
||||
├── Explicit Transactions
|
||||
└── Rollback Safety
|
||||
```
|
||||
|
||||
### Entity States
|
||||
|
||||
```php
|
||||
enum EntityState: string
|
||||
{
|
||||
case NEW = 'new'; // Entity should be inserted
|
||||
case CLEAN = 'clean'; // Entity is unchanged
|
||||
case DIRTY = 'dirty'; // Entity should be updated
|
||||
case DELETED = 'deleted'; // Entity should be deleted
|
||||
case DETACHED = 'detached'; // Entity not tracked
|
||||
}
|
||||
```
|
||||
|
||||
## 🚀 Verwendung
|
||||
|
||||
### Grundlegende Operationen
|
||||
|
||||
```php
|
||||
// Zugriff über EntityManager
|
||||
$unitOfWork = $entityManager->unitOfWork;
|
||||
|
||||
// Entity für INSERT registrieren
|
||||
$user = new User('John', 'john@example.com');
|
||||
$unitOfWork->persist($user);
|
||||
|
||||
// Entity für UPDATE (automatische Change Detection)
|
||||
$existingUser->setName('Jane');
|
||||
$unitOfWork->merge($existingUser);
|
||||
|
||||
// Entity für DELETE registrieren
|
||||
$unitOfWork->remove($obsoleteUser);
|
||||
```
|
||||
|
||||
### Auto-Commit vs. Explicit Transactions
|
||||
|
||||
```php
|
||||
// Auto-Commit Mode (Standard) - Sofortige Persistierung
|
||||
$unitOfWork->persist($user); // ← Sofort committed
|
||||
$unitOfWork->remove($oldUser); // ← Sofort committed
|
||||
|
||||
// Explicit Transaction Mode
|
||||
$unitOfWork->setAutoCommit(false);
|
||||
$unitOfWork->persist($user1);
|
||||
$unitOfWork->persist($user2);
|
||||
$unitOfWork->remove($oldUser);
|
||||
$unitOfWork->commit(); // ← Alles in einer Transaktion
|
||||
```
|
||||
|
||||
### Transactional Callback Pattern
|
||||
|
||||
```php
|
||||
// Automatisches Transaction Management
|
||||
$entityManager->transactional(function($em) {
|
||||
$em->unitOfWork->persist($user1);
|
||||
$em->unitOfWork->persist($user2);
|
||||
$em->unitOfWork->remove($oldUser);
|
||||
|
||||
if ($someCondition) {
|
||||
throw new \Exception('Rollback!'); // ← Automatischer Rollback
|
||||
}
|
||||
// ← Automatischer Commit bei erfolgreichem Ende
|
||||
});
|
||||
```
|
||||
|
||||
## ⚡ Performance Features
|
||||
|
||||
### Bulk Operations (Automatisch)
|
||||
|
||||
```php
|
||||
// Automatische Bulk Operations bei >1 Entity desselben Typs
|
||||
$users = [new User('A'), new User('B'), new User('C')];
|
||||
|
||||
$unitOfWork->setAutoCommit(false);
|
||||
foreach ($users as $user) {
|
||||
$unitOfWork->persist($user); // Sammelt Entities
|
||||
}
|
||||
$unitOfWork->commit(); // ← Bulk INSERT in einem Query
|
||||
|
||||
// Ergebnis: INSERT INTO users (name) VALUES ('A'), ('B'), ('C')
|
||||
// Statt: 3x einzelne INSERT Statements
|
||||
```
|
||||
|
||||
### Smart Change Detection
|
||||
|
||||
```php
|
||||
// Automatische Dirty Detection
|
||||
$user = $entityManager->find(User::class, 1); // ← CLEAN state
|
||||
$user->setName('New Name'); // ← Noch CLEAN
|
||||
$unitOfWork->merge($user); // ← Automatisch DIRTY
|
||||
|
||||
// Oder explizit
|
||||
$unitOfWork->detectChanges(); // ← Prüft alle Entities
|
||||
```
|
||||
|
||||
## 🔧 Advanced Features
|
||||
|
||||
### Manual Entity State Management
|
||||
|
||||
```php
|
||||
// Entity State abfragen
|
||||
$state = $unitOfWork->getChangeTracker()->getEntityState($user);
|
||||
|
||||
// Entity detachen (nicht mehr verfolgen)
|
||||
$unitOfWork->detach($user);
|
||||
|
||||
// Prüfen ob Entity verwaltet wird
|
||||
$isManaged = $unitOfWork->contains($user);
|
||||
|
||||
// Alle Changes prüfen
|
||||
$hasChanges = $unitOfWork->getChangeTracker()->hasAnyChanges();
|
||||
```
|
||||
|
||||
### Flush ohne Commit
|
||||
|
||||
```php
|
||||
// Changes in DB schreiben, aber Transaktion offen lassen
|
||||
$unitOfWork->setAutoCommit(false);
|
||||
$unitOfWork->persist($user);
|
||||
$unitOfWork->flush(); // ← SQL ausgeführt, nicht committed
|
||||
|
||||
// Später...
|
||||
$unitOfWork->persist($anotherUser);
|
||||
$unitOfWork->commit(); // ← Beide Entities committed
|
||||
```
|
||||
|
||||
### Rollback Handling
|
||||
|
||||
```php
|
||||
try {
|
||||
$unitOfWork->setAutoCommit(false);
|
||||
$unitOfWork->persist($user);
|
||||
$unitOfWork->persist($problematicUser);
|
||||
$unitOfWork->commit();
|
||||
} catch (\Exception $e) {
|
||||
$unitOfWork->rollback(); // ← Automatisches Rollback
|
||||
// Entities kehren zu ursprünglichem State zurück
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 Monitoring & Debug
|
||||
|
||||
### Statistics
|
||||
|
||||
```php
|
||||
$stats = $unitOfWork->getStats();
|
||||
/*
|
||||
Array:
|
||||
├── change_tracker
|
||||
│ ├── total_tracked: 15
|
||||
│ ├── new_entities: 3
|
||||
│ ├── dirty_entities: 2
|
||||
│ ├── deleted_entities: 1
|
||||
│ └── has_changes: true
|
||||
├── in_transaction: false
|
||||
├── auto_commit: true
|
||||
└── identity_map
|
||||
├── total_entities: 42
|
||||
└── memory_usage: "2.1MB"
|
||||
*/
|
||||
|
||||
// ChangeTracker Details
|
||||
$changeStats = $unitOfWork->getChangeTracker()->getStats();
|
||||
|
||||
// Alle verwalteten Entities
|
||||
$trackedEntities = $unitOfWork->getChangeTracker()->getAllTrackedEntities();
|
||||
```
|
||||
|
||||
### Comprehensive EntityManager Stats
|
||||
|
||||
```php
|
||||
$stats = $entityManager->getComprehensiveStats();
|
||||
/*
|
||||
Array:
|
||||
├── identity_map: {...}
|
||||
├── unit_of_work: {...}
|
||||
├── lazy_loader: {...}
|
||||
└── connection_pool: {...}
|
||||
*/
|
||||
```
|
||||
|
||||
## 🎯 Performance Optimizations
|
||||
|
||||
### Bulk Operation Thresholds
|
||||
|
||||
Die UnitOfWork verwendet automatisch Bulk Operations:
|
||||
|
||||
- **Single Entity**: Normale INSERT/UPDATE/DELETE
|
||||
- **Multiple Entities**: Bulk Operations mit optimierten Queries
|
||||
|
||||
```sql
|
||||
-- Bulk INSERT (3 Users)
|
||||
INSERT INTO users (name, email) VALUES
|
||||
('User A', 'a@example.com'),
|
||||
('User B', 'b@example.com'),
|
||||
('User C', 'c@example.com');
|
||||
|
||||
-- Bulk UPDATE (5 Users)
|
||||
UPDATE users SET
|
||||
name = CASE id
|
||||
WHEN 1 THEN 'New Name A'
|
||||
WHEN 2 THEN 'New Name B'
|
||||
WHEN 3 THEN 'New Name C'
|
||||
END,
|
||||
email = CASE id
|
||||
WHEN 1 THEN 'new_a@example.com'
|
||||
WHEN 2 THEN 'new_b@example.com'
|
||||
WHEN 3 THEN 'new_c@example.com'
|
||||
END
|
||||
WHERE id IN (1, 2, 3);
|
||||
|
||||
-- Bulk DELETE (10 Users)
|
||||
DELETE FROM users WHERE id IN (1,2,3,4,5,6,7,8,9,10);
|
||||
```
|
||||
|
||||
### Memory Optimization
|
||||
|
||||
```php
|
||||
// WeakMaps für automatisches Cleanup
|
||||
$unitOfWork->getChangeTracker()->clear(); // Tracked entities löschen
|
||||
|
||||
// Komplettes UnitOfWork Reset
|
||||
$unitOfWork->clear(); // Alles zurücksetzen + Rollback
|
||||
```
|
||||
|
||||
## 🛡️ Best Practices
|
||||
|
||||
### Transaction Patterns
|
||||
|
||||
```php
|
||||
// ✅ Gutes Pattern - Kurze Transaktionen
|
||||
$entityManager->transactional(function($em) {
|
||||
$em->unitOfWork->persist($user);
|
||||
$em->unitOfWork->remove($oldUser);
|
||||
// Schnell und atomar
|
||||
});
|
||||
|
||||
// ❌ Schlechtes Pattern - Lange Transaktionen
|
||||
$unitOfWork->setAutoCommit(false);
|
||||
foreach ($thousands_of_users as $user) {
|
||||
$unitOfWork->persist($user);
|
||||
// Langsame externe API calls...
|
||||
processUser($user);
|
||||
}
|
||||
$unitOfWork->commit(); // Sehr lange Transaction!
|
||||
```
|
||||
|
||||
### Batch Processing
|
||||
|
||||
```php
|
||||
// ✅ Batch Processing mit Teilcommits
|
||||
$users = getAllUsers(); // 10,000 Users
|
||||
$batchSize = 100;
|
||||
|
||||
for ($i = 0; $i < count($users); $i += $batchSize) {
|
||||
$batch = array_slice($users, $i, $batchSize);
|
||||
|
||||
$entityManager->transactional(function($em) use ($batch) {
|
||||
foreach ($batch as $user) {
|
||||
$user->setProcessed(true);
|
||||
$em->unitOfWork->merge($user);
|
||||
}
|
||||
});
|
||||
|
||||
// Zwischencommit alle 100 Entities
|
||||
echo "Processed " . ($i + $batchSize) . " users\n";
|
||||
}
|
||||
```
|
||||
|
||||
### Error Handling
|
||||
|
||||
```php
|
||||
// ✅ Robustes Error Handling
|
||||
try {
|
||||
$entityManager->transactional(function($em) use ($users) {
|
||||
foreach ($users as $user) {
|
||||
$this->validateUser($user); // Kann Exception werfen
|
||||
$em->unitOfWork->persist($user);
|
||||
}
|
||||
});
|
||||
|
||||
$logger->info('Successfully processed ' . count($users) . ' users');
|
||||
|
||||
} catch (ValidationException $e) {
|
||||
$logger->error('Validation failed: ' . $e->getMessage());
|
||||
// UnitOfWork rollback automatisch durch transactional()
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$logger->error('Unexpected error: ' . $e->getMessage());
|
||||
throw $e; // Re-throw nach Logging
|
||||
}
|
||||
```
|
||||
|
||||
## 🔍 Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
```php
|
||||
// Entity nicht tracked?
|
||||
if (!$unitOfWork->contains($entity)) {
|
||||
$unitOfWork->merge($entity); // Entity als managed registrieren
|
||||
}
|
||||
|
||||
// Changes nicht erkannt?
|
||||
$unitOfWork->detectChanges(); // Manuelle Change Detection
|
||||
|
||||
// Memory Issues?
|
||||
$unitOfWork->clear(); // Alle Entities detachen
|
||||
|
||||
// Transaction Issues?
|
||||
$stats = $unitOfWork->getStats();
|
||||
if ($stats['in_transaction']) {
|
||||
$unitOfWork->rollback(); // Clean slate
|
||||
}
|
||||
```
|
||||
|
||||
### Debug Information
|
||||
|
||||
```php
|
||||
// Entity State Debug
|
||||
$state = $unitOfWork->getChangeTracker()->getEntityState($user);
|
||||
echo "User state: " . $state->value;
|
||||
|
||||
// Tracked Entities Overview
|
||||
foreach ($unitOfWork->getChangeTracker()->getAllTrackedEntities() as $item) {
|
||||
printf("Entity: %s, State: %s\n",
|
||||
$item['entity']::class,
|
||||
$item['state']->value);
|
||||
}
|
||||
|
||||
// Performance Monitoring
|
||||
$start = microtime(true);
|
||||
$unitOfWork->commit();
|
||||
$duration = microtime(true) - $start;
|
||||
echo "Commit took: " . ($duration * 1000) . "ms\n";
|
||||
```
|
||||
|
||||
## 📈 Performance Benchmarks
|
||||
|
||||
### Bulk vs. Individual Operations
|
||||
|
||||
| Operation | Individual | Bulk | Improvement |
|
||||
|-----------|------------|------|-------------|
|
||||
| 100 INSERTs | ~500ms | ~50ms | **90% faster** |
|
||||
| 50 UPDATEs | ~300ms | ~30ms | **90% faster** |
|
||||
| 200 DELETEs | ~800ms | ~20ms | **97% faster** |
|
||||
|
||||
### Memory Usage
|
||||
|
||||
| Entities | WeakMap Tracking | Array Tracking | Memory Savings |
|
||||
|----------|------------------|----------------|----------------|
|
||||
| 1,000 | 2.1MB | 8.5MB | **75% less** |
|
||||
| 10,000 | 18MB | 85MB | **79% less** |
|
||||
| 100,000 | 180MB | 850MB | **79% less** |
|
||||
|
||||
Das UnitOfWork Pattern bietet enterprise-grade Transaktionsmanagement mit optimaler Performance und Memory-Effizienz durch moderne PHP 8.4 Features wie WeakMaps und Enums.
|
||||
16
backups/docs-backup-20250731125004/WORKER.md
Normal file
16
backups/docs-backup-20250731125004/WORKER.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# Queue Worker - Docker Management
|
||||
|
||||
Dieses Dokument beschreibt alle Docker-spezifischen Befehle für die Verwaltung des Queue Workers.
|
||||
|
||||
## 📋 Inhaltsverzeichnis
|
||||
|
||||
- [Schnellstart](#schnellstart)
|
||||
- [Worker Management](#worker-management)
|
||||
- [Monitoring & Debugging](#monitoring--debugging)
|
||||
- [Konfiguration](#konfiguration)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [Wartung](#wartung)
|
||||
|
||||
## 🚀 Schnellstart
|
||||
|
||||
### Worker starten
|
||||
@@ -0,0 +1,53 @@
|
||||
# Einrichtung des KI-Assistenten in PhpStorm
|
||||
|
||||
## Übersicht
|
||||
|
||||
Diese Anleitung beschreibt, wie der KI-Assistent in PhpStorm eingerichtet wird, um automatisch die Projekt-Guidelines zu verwenden.
|
||||
|
||||
## Methode 1: Über die PhpStorm-Einstellungen
|
||||
|
||||
1. Öffne PhpStorm und gehe zu **Settings/Preferences**
|
||||
- Windows/Linux: File → Settings
|
||||
- macOS: PhpStorm → Preferences
|
||||
|
||||
2. Navigiere zu **Tools** → **AI Assistant** → **Custom Instructions**
|
||||
|
||||
3. Aktiviere die Option **Use custom instructions**
|
||||
|
||||
4. Füge in das Textfeld den Inhalt aus der Datei `/docs/ai/GUIDELINES-FÜR-AI-ASSISTANT.md` ein
|
||||
- Alternativ kannst du auf einen relativen Pfad verweisen
|
||||
|
||||
5. Aktiviere die Option **Apply project-specific instructions**, damit diese Einstellungen nur für dieses Projekt gelten
|
||||
|
||||
6. Klicke auf **Apply** und dann auf **OK**
|
||||
|
||||
## Methode 2: Über die Projektkonfiguration (empfohlen)
|
||||
|
||||
Die `.idea/aiAssistant.xml`-Datei ist bereits im Projekt enthalten und konfiguriert den KI-Assistenten automatisch mit den richtigen Einstellungen. Wenn du das Projekt öffnest, sollte der KI-Assistent bereits korrekt eingerichtet sein.
|
||||
|
||||
Um zu überprüfen, ob die Einstellungen korrekt übernommen wurden:
|
||||
|
||||
1. Öffne die PhpStorm-Einstellungen wie oben beschrieben
|
||||
2. Navigiere zu **Tools** → **AI Assistant** → **Custom Instructions**
|
||||
3. Überprüfe, ob **Use custom instructions** aktiviert ist und die Guidelines angezeigt werden
|
||||
|
||||
## Testen der Einrichtung
|
||||
|
||||
Um zu testen, ob der KI-Assistent die Guidelines korrekt anwendet:
|
||||
|
||||
1. Öffne eine PHP-Datei im Projekt
|
||||
2. Drücke `Alt+A` (Windows/Linux) oder `Option+A` (macOS) um den KI-Assistenten zu öffnen
|
||||
3. Bitte den Assistenten, eine neue Klasse zu erstellen
|
||||
4. Überprüfe, ob die generierte Klasse den Guidelines entspricht:
|
||||
- Sie sollte als `final` und wenn möglich `readonly` deklariert sein
|
||||
- Constructor Property Promotion sollte verwendet werden
|
||||
- Es sollten keine externen Abhängigkeiten importiert werden
|
||||
|
||||
## Fehlerbehebung
|
||||
|
||||
Falls die Guidelines nicht korrekt angewendet werden:
|
||||
|
||||
1. Stelle sicher, dass du die neueste Version von PhpStorm verwendest
|
||||
2. Überprüfe, ob die AI Assistant-Funktion aktiviert ist
|
||||
3. Versuche, das Projekt neu zu öffnen
|
||||
4. Führe einen Cache-Clear in PhpStorm durch: File → Invalidate Caches
|
||||
@@ -0,0 +1,174 @@
|
||||
# Guidelines für KI-Assistenten
|
||||
|
||||
## Übersicht
|
||||
|
||||
Diese Guidelines helfen dir, dem KI-Assistenten, konsistenten, modernen und qualitativ hochwertigen PHP-Code zu generieren, der den Projektstandards entspricht.
|
||||
|
||||
## Verwendung in PhpStorm
|
||||
|
||||
Diese Guidelines können in PhpStorm so eingerichtet werden, dass sie automatisch vom KI-Assistenten verwendet werden:
|
||||
|
||||
1. Gehe zu **Settings/Preferences** → **Tools** → **AI Assistant** → **Custom Instructions**
|
||||
2. Aktiviere **Use custom instructions**
|
||||
3. Füge im Textfeld den Inhalt dieser Datei ein oder verwende einen relativen Pfad zu dieser Datei
|
||||
4. Optional: Aktiviere **Apply project-specific instructions** für projektspezifische Einstellungen
|
||||
|
||||
Alternativ kann die Datei `.idea/aiAssistant.xml` angepasst werden, um diese Guidelines als Standardeinstellung für das Projekt zu verwenden.
|
||||
|
||||
## Kernprinzipien
|
||||
|
||||
### Abhängigkeitsvermeidung
|
||||
|
||||
- **Keine externen Abhängigkeiten** außer den explizit freigegebenen
|
||||
- Eigene Implementierungen gegenüber externen Bibliotheken bevorzugen
|
||||
- Bei Bedarf nach externen Funktionen zuerst prüfen, ob eine eigene Implementierung möglich ist
|
||||
- Erlaubte Abhängigkeiten sind auf die vorhandenen Composer-Pakete beschränkt
|
||||
|
||||
## Architekturprinzipien
|
||||
|
||||
Bei der Codeanalyse und -generierung sind folgende Architekturprinzipien zu beachten:
|
||||
|
||||
1. **Modularer Aufbau**: Das Projekt ist in Module unter `/src/Framework/` organisiert
|
||||
2. **Service-orientierte Architektur**: Funktionalitäten als unabhängige Services implementieren
|
||||
3. **Dependency Injection**: Abhängigkeiten werden per Constructor Injection bereitgestellt
|
||||
4. **Event-basierte Kommunikation**: Module kommunizieren über den EventDispatcher
|
||||
5. **Selbstständigkeit**: Module sollten möglichst unabhängig von externen Bibliotheken sein
|
||||
|
||||
## Coding-Standards
|
||||
|
||||
### Klassen
|
||||
|
||||
- **IMMER `final` verwenden**, außer bei zwingenden Gründen für Vererbung
|
||||
- **KEINE abstrakten Klassen** verwenden - stattdessen Interfaces und Kompositionen
|
||||
- Klassen und Properties wenn möglich als `readonly` deklarieren
|
||||
- Bevorzuge Interfaces für Vertragsgestaltung zwischen Komponenten
|
||||
|
||||
```php
|
||||
// RICHTIG
|
||||
final readonly class AnalyticsService implements AnalyticsInterface
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
// FALSCH
|
||||
abstract class BaseAnalytics
|
||||
{
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Properties und Methoden
|
||||
|
||||
- Private `readonly` Properties mit Typisierung
|
||||
- Return-Types immer angeben
|
||||
- Parameter-Types immer angeben
|
||||
- Union Types und Nullable Types nutzen
|
||||
|
||||
```php
|
||||
// RICHTIG
|
||||
private readonly LoggerInterface $logger;
|
||||
|
||||
public function process(?int $id): Result|null
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
// FALSCH
|
||||
public $logger;
|
||||
|
||||
public function process($id)
|
||||
{
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Moderne PHP-Features
|
||||
|
||||
Nutze aktiv die neuesten PHP-Features:
|
||||
|
||||
- Constructor Property Promotion
|
||||
- Match Expressions statt Switch
|
||||
- Named Arguments
|
||||
- Enums statt Konstanten
|
||||
- Nullsafe Operator (`?->`) wo sinnvoll
|
||||
- Typed Properties
|
||||
|
||||
## Klassenaufbau
|
||||
|
||||
Folgende Reihenfolge für Klassenelemente:
|
||||
|
||||
1. Konstanten
|
||||
2. Properties
|
||||
3. Constructor
|
||||
4. Öffentliche Methoden
|
||||
5. Private/Protected Methoden
|
||||
|
||||
## Service-Initialisierung
|
||||
|
||||
Services werden durch Initializer-Klassen registriert:
|
||||
|
||||
```php
|
||||
#[Initializer]
|
||||
final readonly class ServiceInitializer
|
||||
{
|
||||
public function __construct(
|
||||
private Configuration $config,
|
||||
private DependencyInterface $dependency
|
||||
) {}
|
||||
|
||||
public function __invoke(Container $container): ServiceInterface
|
||||
{
|
||||
return new Service(
|
||||
$this->config->get('service'),
|
||||
$this->dependency
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Fehlerbehandlung
|
||||
|
||||
- Spezifische Exception-Klassen werfen
|
||||
- Early Return Pattern bevorzugen
|
||||
- Defensive Programmierung mit Validierung
|
||||
|
||||
## Testing
|
||||
|
||||
Bei Test-Vorschlägen Pest-Framework nutzen:
|
||||
|
||||
```php
|
||||
test('method does something correctly', function () {
|
||||
// Arrangement
|
||||
$service = new Service($dependency);
|
||||
|
||||
// Action
|
||||
$result = $service->method();
|
||||
|
||||
// Assertion
|
||||
expect($result)->toBe('expected');
|
||||
});
|
||||
```
|
||||
|
||||
## Dokumentation
|
||||
|
||||
- PHPDoc für alle öffentlichen Methoden
|
||||
- Kurze, präzise Beschreibungen
|
||||
- Parameter und Return-Types in PHPDoc
|
||||
|
||||
## Zu vermeidende Praktiken
|
||||
|
||||
- Globale Zustände und statische Methoden
|
||||
- Tiefe Vererbungshierarchien
|
||||
- Lange, komplexe Methoden
|
||||
- Magische Methoden (`__call`, etc.) ohne triftigen Grund
|
||||
- Unnötige Abstraktionen
|
||||
|
||||
## Bei Codeanalyse und -vorschlägen
|
||||
|
||||
1. **Aktuellen Stil beibehalten**: Bei Vorschlägen den vorhandenen Codierungsstil beibehalten
|
||||
2. **Standards berücksichtigen**: Auf Einhaltung der hier definierten Guidelines achten
|
||||
3. **Modernisierung vorschlagen**: Auf Möglichkeiten zur Modernisierung hinweisen
|
||||
4. **Begründen**: Bei Empfehlungen die Gründe erläutern
|
||||
5. **Vollständigkeit**: Vollständige Lösungen anbieten, nicht nur Fragmente
|
||||
|
||||
Diese Guidelines sind als lebendiges Dokument zu betrachten, das mit der Evolution des Projekts und von PHP weiterentwickelt wird.
|
||||
54
backups/docs-backup-20250731125004/ai/index.md
Normal file
54
backups/docs-backup-20250731125004/ai/index.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# KI-Assistent Dokumentation
|
||||
|
||||
## Übersicht
|
||||
|
||||
Diese Dokumentation beschreibt die Einrichtung und Verwendung des KI-Assistenten im Projekt. Der KI-Assistent hilft bei der Entwicklung durch Code-Generierung, Refactoring-Vorschläge und mehr, während er die Projektstandards einhält.
|
||||
|
||||
## Inhalte
|
||||
|
||||
- [Guidelines für KI-Assistenten](/ai/GUIDELINES-FÜR-AI-ASSISTANT.md) - Richtlinien für den KI-Assistenten
|
||||
- [PhpStorm Einrichtung](/ai/EINRICHTUNG-PHPSTORM.md) - Anleitung zur Einrichtung in PhpStorm
|
||||
|
||||
## KI-Assistent Guidelines
|
||||
|
||||
Die [Guidelines für KI-Assistenten](/ai/GUIDELINES-FÜR-AI-ASSISTANT.md) stellen sicher, dass der KI-generierte Code den Projektstandards entspricht:
|
||||
|
||||
- Einhaltung der Coding-Standards
|
||||
- Vermeidung externer Abhängigkeiten
|
||||
- Verwendung moderner PHP-Features
|
||||
- Konsistente Klassenstruktur
|
||||
- Korrekte Fehlerbehandlung
|
||||
|
||||
## Einrichtung in PhpStorm
|
||||
|
||||
Die [PhpStorm Einrichtungsanleitung](/ai/EINRICHTUNG-PHPSTORM.md) führt Sie durch den Prozess der Integration des KI-Assistenten in Ihre IDE:
|
||||
|
||||
- Konfiguration der Custom Instructions
|
||||
- Verwendung der projektspezifischen Einstellungen
|
||||
- Testen der korrekten Einrichtung
|
||||
- Fehlerbehebung bei Problemen
|
||||
|
||||
## Effektive Nutzung des KI-Assistenten
|
||||
|
||||
### Best Practices
|
||||
|
||||
1. **Klare Anfragen stellen**: Je präziser die Anfrage, desto besser das Ergebnis
|
||||
2. **Kontext bereitstellen**: Dem Assistenten relevanten Kontext geben
|
||||
3. **Ergebnisse überprüfen**: Generierte Code immer prüfen und verstehen
|
||||
4. **Iterativ arbeiten**: Bei komplexen Aufgaben schrittweise vorgehen
|
||||
|
||||
### Häufige Anwendungsfälle
|
||||
|
||||
- Erstellung neuer Klassen und Interfaces
|
||||
- Implementierung von Tests
|
||||
- Refactoring bestehenden Codes
|
||||
- Dokumentation generieren
|
||||
- Code-Optimierung
|
||||
|
||||
## Datenschutz und Sicherheit
|
||||
|
||||
Beim Umgang mit dem KI-Assistenten sollten Sie folgende Punkte beachten:
|
||||
|
||||
- Keine sensiblen Daten oder Geschäftsgeheimnisse teilen
|
||||
- Keine Passwörter, API-Schlüssel oder Zugangsdaten teilen
|
||||
- Bei Unsicherheit den KI-Assistenten nicht verwenden
|
||||
134
backups/docs-backup-20250731125004/api.html
Normal file
134
backups/docs-backup-20250731125004/api.html
Normal file
@@ -0,0 +1,134 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>API Documentation</title>
|
||||
<style>body {
|
||||
font-family: 'Source Sans Pro', sans-serif;
|
||||
line-height: 1.6;
|
||||
color: #2c3e50;
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
background: #ecf0f1;
|
||||
}
|
||||
|
||||
.markdown-content {
|
||||
background: white;
|
||||
padding: 30px;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
h1, h2, h3 {
|
||||
color: #34495e;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.2em;
|
||||
color: #2980b9;
|
||||
border-bottom: 3px solid #3498db;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.6em;
|
||||
color: #27ae60;
|
||||
margin-top: 32px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.3em;
|
||||
color: #8e44ad;
|
||||
}
|
||||
|
||||
code {
|
||||
background: #f8f9fa;
|
||||
color: #e74c3c;
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 4px;
|
||||
padding: 2px 6px;
|
||||
font-family: 'Monaco', 'Menlo', monospace;
|
||||
}
|
||||
|
||||
pre {
|
||||
background: #2c3e50;
|
||||
color: #ecf0f1;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
border-left: 4px solid #3498db;
|
||||
}
|
||||
|
||||
pre code {
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.method {
|
||||
display: inline-block;
|
||||
padding: 4px 12px;
|
||||
border-radius: 20px;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
margin-right: 10px;
|
||||
font-size: 0.8em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.method.get { background: #27ae60; }
|
||||
.method.post { background: #f39c12; }
|
||||
.method.put { background: #e67e22; }
|
||||
.method.delete { background: #e74c3c; }
|
||||
|
||||
blockquote {
|
||||
border-left: 4px solid #3498db;
|
||||
background: #ebf3fd;
|
||||
margin: 20px 0;
|
||||
padding: 15px 20px;
|
||||
border-radius: 0 6px 6px 0;
|
||||
}</style>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism.min.css">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-php.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-javascript.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-json.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-bash.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="markdown-content">
|
||||
<h1>Michael Schiemer API</h1>
|
||||
<p>API documentation for Michael Schiemer's custom PHP framework</p>
|
||||
<p><strong>Version:</strong> 1.0.0</p>
|
||||
<h2>Endpoints</h2>
|
||||
<h3>GET /api/users</h3>
|
||||
<p>List all users</p>
|
||||
<p>Retrieve a paginated list of all users in the system</p>
|
||||
<p><strong>Parameters:</strong></p>
|
||||
<ul>
|
||||
<li><code>page</code> (query) - Page number for pagination (optional)</li>
|
||||
<li><code>limit</code> (query) - Number of items per page (optional)</li>
|
||||
<li><code>search</code> (query) - Search term to filter users (optional)</li>
|
||||
</ul>
|
||||
<p><strong>Responses:</strong></p>
|
||||
<ul>
|
||||
<li><code>200</code> - List of users retrieved successfully</li>
|
||||
<li><code>401</code> - Unauthorized - Invalid or missing authentication token</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h3>POST /kontakt</h3>
|
||||
<p>Submit contact form</p>
|
||||
<p>Submit a contact form message</p>
|
||||
<p><strong>Responses:</strong></p>
|
||||
<ul>
|
||||
<li><code>200</code> - Contact form submitted successfully</li>
|
||||
<li><code>400</code> - Validation error - Invalid form data</li>
|
||||
</ul>
|
||||
<hr>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
40
backups/docs-backup-20250731125004/api.md
Normal file
40
backups/docs-backup-20250731125004/api.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# Michael Schiemer API
|
||||
|
||||
API documentation for Michael Schiemer's custom PHP framework
|
||||
|
||||
**Version:** 1.0.0
|
||||
|
||||
## Endpoints
|
||||
|
||||
### GET /api/users
|
||||
|
||||
List all users
|
||||
|
||||
Retrieve a paginated list of all users in the system
|
||||
|
||||
**Parameters:**
|
||||
|
||||
- `page` (query) - Page number for pagination (optional)
|
||||
- `limit` (query) - Number of items per page (optional)
|
||||
- `search` (query) - Search term to filter users (optional)
|
||||
|
||||
**Responses:**
|
||||
|
||||
- `200` - List of users retrieved successfully
|
||||
- `401` - Unauthorized - Invalid or missing authentication token
|
||||
|
||||
---
|
||||
|
||||
### POST /kontakt
|
||||
|
||||
Submit contact form
|
||||
|
||||
Submit a contact form message
|
||||
|
||||
**Responses:**
|
||||
|
||||
- `200` - Contact form submitted successfully
|
||||
- `400` - Validation error - Invalid form data
|
||||
|
||||
---
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
# Projektstruktur-Dokumentation
|
||||
|
||||
## Übersicht
|
||||
|
||||
Diese Dokumentation bietet einen Überblick über die Architektur und Struktur des Projekts. Die Anwendung folgt einer modularen, serviceorientierten Architektur mit klarer Trennung von Verantwortlichkeiten.
|
||||
|
||||
## Hauptverzeichnisse
|
||||
|
||||
### `/src`
|
||||
|
||||
Das Hauptverzeichnis für den Anwendungscode, unterteilt in mehrere Unterverzeichnisse:
|
||||
|
||||
#### `/src/Framework`
|
||||
|
||||
Enthält das Framework mit grundlegenden Infrastrukturkomponenten:
|
||||
|
||||
- **Analytics**: System zur Erfassung und Analyse von Anwendungsdaten
|
||||
- **Attributes**: Attribute/Annotations für Metadaten
|
||||
- **Cache**: Caching-Mechanismen
|
||||
- **CommandBus**: Command-Handling-Komponenten
|
||||
- **Config**: Konfigurationsverwaltung
|
||||
- **Console**: Konsolenanwendung und -befehle
|
||||
- **Core**: Kernkomponenten und Events
|
||||
- **DI**: Dependency-Injection-Container
|
||||
- **ErrorHandling**: Fehlerbehandlungsmechanismen
|
||||
- **EventBus**: Event-Handling-System
|
||||
- **Exception**: Framework-Exceptions
|
||||
- **Filesystem**: Dateisystemoperationen
|
||||
- **Http**: HTTP-Request/Response-Handling
|
||||
- **HttpClient**: HTTP-Client für externe API-Aufrufe
|
||||
- **Logging**: Logging-Infrastruktur
|
||||
- **Performance**: Performance-Monitoring
|
||||
- **Queue**: Nachrichtenwarteschlangen
|
||||
- **Redis**: Redis-Integration
|
||||
- **Router**: URL-Routing
|
||||
- **StaticSite**: Statische Site-Generation
|
||||
- **Validation**: Datenvalidierung
|
||||
- **View**: Template-Rendering
|
||||
|
||||
#### `/src/Application`
|
||||
|
||||
Anwendungsspezifische Komponenten, die das Framework nutzen.
|
||||
|
||||
#### `/src/Domain`
|
||||
|
||||
Domain-Modelle, Entities und Business-Logik.
|
||||
|
||||
#### `/src/Infrastructure`
|
||||
|
||||
Infrastrukturkomponenten, die externe Systeme integrieren.
|
||||
|
||||
#### `/src/Config`
|
||||
|
||||
Konfigurationsdateien für verschiedene Module.
|
||||
|
||||
## Framework-Architektur
|
||||
|
||||
### Dependency Injection
|
||||
|
||||
Das System nutzt einen leistungsfähigen DI-Container zur Verwaltung von Services:
|
||||
|
||||
```php
|
||||
#[Initializer]
|
||||
class ServiceInitializer
|
||||
{
|
||||
public function __invoke(Container $container): Service
|
||||
{
|
||||
// Service erstellen und zurückgeben
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Event-System
|
||||
|
||||
Ein Event-System ermöglicht lose Kopplung zwischen Komponenten:
|
||||
|
||||
```php
|
||||
$eventDispatcher->addHandler(EventClass::class, function($event) {
|
||||
// Event verarbeiten
|
||||
});
|
||||
```
|
||||
|
||||
### HTTP-Pipeline
|
||||
|
||||
HTTP-Requests durchlaufen eine Middleware-Pipeline:
|
||||
|
||||
```php
|
||||
class CustomMiddleware implements Middleware
|
||||
{
|
||||
public function process(Request $request, callable $next): Response
|
||||
{
|
||||
// Request verarbeiten
|
||||
$response = $next($request);
|
||||
// Response verarbeiten
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Module und ihre Interaktionen
|
||||
|
||||
### Analytics-Modul
|
||||
|
||||
Das Analytics-Modul erfasst und analysiert Anwendungsdaten:
|
||||
|
||||
- **Events tracken**: `$analytics->track('event_name', $properties)`
|
||||
- **HTTP-Tracking**: Automatisch durch `AnalyticsMiddleware`
|
||||
- **Error-Tracking**: Integration mit dem Error-Handling-System
|
||||
- **Dashboard**: Admin-Interface zur Datenvisualisierung
|
||||
|
||||
### Konfigurationssystem
|
||||
|
||||
Konfigurationen werden zentral verwaltet und injiziert:
|
||||
|
||||
```php
|
||||
class Service
|
||||
{
|
||||
public function __construct(private Configuration $config)
|
||||
{
|
||||
$settings = $this->config->get('module_name', $defaults);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Erweiterbarkeit
|
||||
|
||||
### Neue Module hinzufügen
|
||||
|
||||
1. Erstellen Sie ein neues Verzeichnis unter `/src/Framework`
|
||||
2. Implementieren Sie eine Initializer-Klasse mit dem `#[Initializer]`-Attribut
|
||||
3. Erstellen Sie eine entsprechende Konfigurationsdatei unter `/src/Config`
|
||||
|
||||
### Middleware hinzufügen
|
||||
|
||||
```php
|
||||
// In Ihrer Anwendungsklasse
|
||||
public function bootstrap(): void
|
||||
{
|
||||
$this->addMiddleware(YourMiddleware::class);
|
||||
}
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- **Dependency Injection**: Verwenden Sie Constructor-Injection für Abhängigkeiten
|
||||
- **Interfaces**: Definieren Sie Interfaces für alle Services
|
||||
- **Events**: Nutzen Sie Events für lose Kopplung zwischen Modulen
|
||||
- **Konfiguration**: Externalisieren Sie Konfigurationen in dedizierte Dateien
|
||||
- **Typsicherheit**: Nutzen Sie strenge Typisierung und readonly-Properties
|
||||
70
backups/docs-backup-20250731125004/architecture/index.md
Normal file
70
backups/docs-backup-20250731125004/architecture/index.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# Architektur-Dokumentation
|
||||
|
||||
## Übersicht
|
||||
|
||||
Diese Dokumentation beschreibt die Architektur und Struktur des Projekts. Sie bietet einen Überblick über die wichtigsten Komponenten, deren Beziehungen und die zugrundeliegenden Architekturprinzipien.
|
||||
|
||||
## Inhalte
|
||||
|
||||
- [Projektstruktur](STRUKTUR-DOKUMENTATION.md) - Überblick über die Struktur des Projekts
|
||||
|
||||
## Architekturprinzipien
|
||||
|
||||
Das Projekt folgt diesen grundlegenden Architekturprinzipien:
|
||||
|
||||
1. **Modulare Architektur**: Klare Trennung von Verantwortlichkeiten in Modulen
|
||||
2. **Service-orientiertes Design**: Funktionalitäten als unabhängige Services
|
||||
3. **Dependency Injection**: Abhängigkeiten werden explizit injiziert
|
||||
4. **Event-basierte Kommunikation**: Lose Kopplung durch Events
|
||||
5. **Schichtenarchitektur**: Trennung von Präsentation, Anwendungslogik und Daten
|
||||
|
||||
## Hauptkomponenten
|
||||
|
||||
### Framework-Kern
|
||||
|
||||
Der Framework-Kern stellt grundlegende Infrastrukturkomponenten bereit:
|
||||
|
||||
- **DI-Container**: Verwaltung von Service-Abhängigkeiten
|
||||
- **Event-System**: Event-basierte Kommunikation
|
||||
- **HTTP-Komponenten**: Request/Response-Handling
|
||||
- **Routing**: URL-zu-Controller-Mapping
|
||||
|
||||
### Anwendungsschicht
|
||||
|
||||
Die Anwendungsschicht implementiert die Geschäftslogik:
|
||||
|
||||
- **Services**: Implementierung von Anwendungsfunktionen
|
||||
- **Commands/Queries**: Command-Query-Separation-Prinzip
|
||||
- **Controllers**: HTTP-Request-Handling
|
||||
|
||||
### Domainschicht
|
||||
|
||||
Die Domainschicht enthält die Kerngeschäftslogik:
|
||||
|
||||
- **Entities**: Geschäftsobjekte mit Identität
|
||||
- **Value Objects**: Unveränderliche Wertobjekte
|
||||
- **Domain Services**: Domänenspezifische Logik
|
||||
|
||||
### Infrastrukturschicht
|
||||
|
||||
Die Infrastrukturschicht bietet technische Funktionen:
|
||||
|
||||
- **Persistenz**: Datenbankzugriff und -verwaltung
|
||||
- **Messaging**: Externe Kommunikation
|
||||
- **Integration**: Anbindung an externe Systeme
|
||||
|
||||
## Datenfluss
|
||||
|
||||
Ein typischer Datenfluss im System:
|
||||
|
||||
1. HTTP-Request wird vom Router empfangen
|
||||
2. Middleware-Pipeline verarbeitet den Request
|
||||
3. Controller erhält den Request und delegiert an Services
|
||||
4. Services implementieren die Geschäftslogik
|
||||
5. Domain-Objekte repräsentieren den Geschäftszustand
|
||||
6. Repositories speichern/laden Daten
|
||||
7. Response wird erstellt und zurückgegeben
|
||||
|
||||
## Weitere Informationen
|
||||
|
||||
Für detailliertere Informationen zur Architektur siehe die [Projektstruktur-Dokumentation](STRUKTUR-DOKUMENTATION.md).
|
||||
145
backups/docs-backup-20250731125004/database/change-tracking.md
Normal file
145
backups/docs-backup-20250731125004/database/change-tracking.md
Normal file
@@ -0,0 +1,145 @@
|
||||
# EntityManager Change Tracking
|
||||
|
||||
Das EntityManager Change Tracking System bietet detaillierte Informationen über Änderungen an Entities und optimiert gleichzeitig die Performance durch Vermeidung unnötiger UPDATE-Queries.
|
||||
|
||||
## Features
|
||||
|
||||
### ✅ Automatische Änderungserkennung
|
||||
- Vergleicht automatisch alte vs. neue Werte für alle Entity-Properties
|
||||
- Ignoriert Relations und ID-Properties bei der Änderungserkennung
|
||||
- Behandelt `null`-Werte und Typ-sensitive Vergleiche korrekt
|
||||
|
||||
### ✅ Performance-Optimierung
|
||||
- **Keine unnötigen DB-Queries**: UPDATE wird nur ausgeführt wenn Änderungen erkannt werden
|
||||
- **Selective Updates**: Nur geänderte Felder werden in der SET-Clause verwendet
|
||||
- **IdentityMap Integration**: Nutzt bereits geladene Entities für Vergleiche
|
||||
|
||||
### ✅ Event-System Integration
|
||||
- Liefert detaillierte Informationen für `EntityUpdatedEvent`
|
||||
- Ermöglicht Audit-Logging und Change-History
|
||||
- Unterstützt Domain Events und Event-Sourcing
|
||||
|
||||
## Usage Example
|
||||
|
||||
```php
|
||||
// Original Entity in IdentityMap laden
|
||||
$user = $entityManager->find(User::class, 1);
|
||||
|
||||
// Entity modifizieren
|
||||
$user->name = 'New Name';
|
||||
$user->age = 25;
|
||||
|
||||
// Update mit automatischem Change Tracking
|
||||
$entityManager->update($user);
|
||||
|
||||
// Das EntityUpdatedEvent enthält:
|
||||
// - changes: ['name', 'age']
|
||||
// - oldValues: ['name' => 'Old Name', 'age' => 24]
|
||||
// - newValues: ['name' => 'New Name', 'age' => 25]
|
||||
```
|
||||
|
||||
## Event Data Structure
|
||||
|
||||
```php
|
||||
class EntityUpdatedEvent
|
||||
{
|
||||
public readonly array $changes; // Geänderte Property-Namen
|
||||
public readonly array $oldValues; // Alte Werte [property => value]
|
||||
public readonly array $newValues; // Neue Werte [property => value]
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
## Performance Benefits
|
||||
|
||||
### UPDATE Query Optimierung
|
||||
```sql
|
||||
-- Vorher: Alle Felder werden immer aktualisiert
|
||||
UPDATE users SET name = ?, email = ?, age = ?, status = ? WHERE id = ?
|
||||
|
||||
-- Nachher: Nur geänderte Felder werden aktualisiert
|
||||
UPDATE users SET name = ?, age = ? WHERE id = ?
|
||||
```
|
||||
|
||||
### Query-Vermeidung
|
||||
```php
|
||||
// Keine Änderungen erkannt → Kein UPDATE ausgeführt
|
||||
$user = $entityManager->find(User::class, 1);
|
||||
$identicalUser = new User(id: 1, name: $user->name, email: $user->email);
|
||||
$result = $entityManager->update($identicalUser); // Kein DB-Query!
|
||||
```
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### Change Detection Algorithm
|
||||
1. **IdentityMap Lookup**: Original Entity aus IdentityMap laden (falls vorhanden)
|
||||
2. **Property Comparison**: Reflection-basierter Vergleich aller Non-Relation Properties
|
||||
3. **Change Collection**: Sammlung von geänderten Feldern, alten und neuen Werten
|
||||
4. **Query Building**: SET-Clause nur für geänderte Properties
|
||||
5. **Event Dispatch**: EntityUpdatedEvent mit vollständigen Change-Informationen
|
||||
|
||||
### Edge Cases Handling
|
||||
- **Neue Entity ohne Original**: Alle Properties werden als "geändert" behandelt
|
||||
- **Keine Änderungen**: UPDATE wird komplett übersprungen
|
||||
- **Type-sensitive Vergleiche**: `0 !== '0'` wird korrekt erkannt
|
||||
- **Null-Werte**: `null` vs. Wert-Änderungen werden korrekt verarbeitet
|
||||
|
||||
## Testing
|
||||
|
||||
Das Change Tracking System ist durch umfassende Tests abgedeckt:
|
||||
|
||||
```bash
|
||||
# Change Tracking Logic Tests
|
||||
docker exec php ./vendor/bin/pest tests/Framework/Database/ChangeTrackingLogicTest.php
|
||||
```
|
||||
|
||||
## Use Cases
|
||||
|
||||
### Audit Logging
|
||||
```php
|
||||
// Event Listener für Audit Trail
|
||||
class AuditLogger
|
||||
{
|
||||
public function handle(EntityUpdatedEvent $event): void
|
||||
{
|
||||
foreach ($event->changes as $property) {
|
||||
$this->logChange([
|
||||
'entity' => $event->entityClass,
|
||||
'id' => $event->entityId,
|
||||
'property' => $property,
|
||||
'old_value' => $event->oldValues[$property],
|
||||
'new_value' => $event->newValues[$property],
|
||||
'timestamp' => $event->timestamp
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Change History
|
||||
```php
|
||||
// Automatische Versionierung
|
||||
class EntityVersioning
|
||||
{
|
||||
public function handle(EntityUpdatedEvent $event): void
|
||||
{
|
||||
if (!empty($event->changes)) {
|
||||
$this->createVersion([
|
||||
'entity_type' => $event->entityClass,
|
||||
'entity_id' => $event->entityId,
|
||||
'changes' => $event->changes,
|
||||
'data' => $event->newValues,
|
||||
'previous_data' => $event->oldValues
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Benefits
|
||||
|
||||
1. **Performance**: Bis zu 50% weniger DB-Queries durch intelligente Änderungserkennung
|
||||
2. **Audit-fähig**: Vollständige Change-History für Compliance und Debugging
|
||||
3. **Event-driven**: Ermöglicht reactive Programmierung und Domain Events
|
||||
4. **Type-safe**: Korrekte Behandlung aller PHP-Datentypen und Edge Cases
|
||||
5. **Zero-Config**: Funktioniert automatisch ohne zusätzliche Konfiguration
|
||||
243
backups/docs-backup-20250731125004/database/eager-loading.md
Normal file
243
backups/docs-backup-20250731125004/database/eager-loading.md
Normal file
@@ -0,0 +1,243 @@
|
||||
# Hydrator Eager Loading System
|
||||
|
||||
Das Eager Loading System löst das **N+1 Query Problem** durch intelligente Batch-Queries und bietet massive Performance-Verbesserungen für Relations-intensive Anwendungen.
|
||||
|
||||
## Problem: N+1 Query Problem
|
||||
|
||||
### Vorher (Lazy Loading)
|
||||
```php
|
||||
// 1 Query für Users
|
||||
$users = $repository->findAll(); // SELECT * FROM users
|
||||
|
||||
// N Queries für Relations (1 pro User)
|
||||
foreach($users as $user) {
|
||||
$user->posts; // SELECT * FROM posts WHERE user_id = ?
|
||||
$user->profile; // SELECT * FROM profiles WHERE user_id = ?
|
||||
}
|
||||
// Total: 1 + (N × 2) = 201 Queries für 100 Users!
|
||||
```
|
||||
|
||||
### Nachher (Eager Loading)
|
||||
```php
|
||||
// 3 Queries total durch Batch-Loading
|
||||
$users = $hydrator->hydrateManyWithRelations($metadata, $userData, ['posts', 'profile']);
|
||||
// 1. SELECT * FROM users
|
||||
// 2. SELECT * FROM posts WHERE user_id IN (1,2,3,...,100)
|
||||
// 3. SELECT * FROM profiles WHERE user_id IN (1,2,3,...,100)
|
||||
// Total: 3 Queries für 100 Users = 98.5% Reduktion!
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
### ✅ Selective Eager Loading
|
||||
```php
|
||||
// Lade nur spezifizierte Relations
|
||||
$user = $hydrator->hydrateWithRelations($metadata, $data, ['posts', 'comments']);
|
||||
|
||||
// Ohne Relations = normale Hydration
|
||||
$user = $hydrator->hydrateWithRelations($metadata, $data, []);
|
||||
```
|
||||
|
||||
### ✅ Batch Processing für Collections
|
||||
```php
|
||||
// N+1 Problem gelöst für Collections
|
||||
$users = $hydrator->hydrateManyWithRelations($metadata, $dataRows, ['posts', 'profile']);
|
||||
|
||||
// Intelligente Gruppierung nach Relation-Types
|
||||
// - belongsTo: IN-Queries für Foreign Keys
|
||||
// - hasMany: Gruppierung nach Local Keys
|
||||
// - one-to-one: Eindeutige Zuordnung
|
||||
```
|
||||
|
||||
### ✅ Relation-Type Support
|
||||
- **belongsTo**: Foreign Key Lookups mit IN-Queries
|
||||
- **hasMany**: Reverse Foreign Key Lookups mit Gruppierung
|
||||
- **one-to-one**: Eindeutige Relations-Zuordnung
|
||||
|
||||
## API Usage
|
||||
|
||||
### Single Entity mit Relations
|
||||
```php
|
||||
$user = $hydrator->hydrateWithRelations(
|
||||
$userMetadata,
|
||||
$userData,
|
||||
['posts', 'profile', 'roles']
|
||||
);
|
||||
|
||||
// Relations sind sofort verfügbar, keine zusätzlichen Queries
|
||||
echo count($user->posts); // Kein Query
|
||||
echo $user->profile->bio; // Kein Query
|
||||
```
|
||||
|
||||
### Multiple Entities (Batch Loading)
|
||||
```php
|
||||
$users = $hydrator->hydrateManyWithRelations(
|
||||
$userMetadata,
|
||||
$userDataRows,
|
||||
['posts', 'comments', 'profile']
|
||||
);
|
||||
|
||||
// Alle Relations wurden mit nur 4 Queries geladen:
|
||||
// 1x Users, 1x Posts, 1x Comments, 1x Profiles
|
||||
```
|
||||
|
||||
### Performance-kritische Scenarios
|
||||
```php
|
||||
// Blog-System: Posts mit Comments, Tags, Categories
|
||||
$posts = $hydrator->hydrateManyWithRelations(
|
||||
$postMetadata,
|
||||
$postDataRows,
|
||||
['comments', 'tags', 'category', 'author']
|
||||
);
|
||||
|
||||
// Ohne Eager Loading: 1 + (50 × 4) = 201 Queries
|
||||
// Mit Eager Loading: 5 Queries = 97.5% Reduktion
|
||||
```
|
||||
|
||||
## Performance Benchmarks
|
||||
|
||||
### Real-World Scenarios
|
||||
|
||||
| Scenario | Entities | Relations | Lazy Queries | Eager Queries | Reduction |
|
||||
|----------|----------|-----------|--------------|---------------|-----------|
|
||||
| User Dashboard | 50 users | posts, profile | 101 | 3 | **97.0%** |
|
||||
| Blog Listing | 20 posts | comments, tags, author | 81 | 4 | **95.1%** |
|
||||
| E-Commerce | 100 products | category, reviews, images | 301 | 4 | **98.7%** |
|
||||
| Social Feed | 30 posts | author, comments, likes | 91 | 4 | **95.6%** |
|
||||
|
||||
### Database Load Reduction
|
||||
```php
|
||||
// Blog System Beispiel (50 Posts)
|
||||
$lazyQueries = 1 + (50 × 3); // 151 Queries
|
||||
$eagerQueries = 4; // 4 Queries
|
||||
$loadReduction = 151 / 4; // 37.75x weniger DB-Load!
|
||||
```
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### Batch Loading Algorithm
|
||||
1. **Entity Creation**: Erstelle alle Entities ohne Relations
|
||||
2. **Key Collection**: Sammle alle IDs/Foreign Keys für Batch-Queries
|
||||
3. **Batch Queries**: Ein Query pro Relation-Type mit IN-Clauses
|
||||
4. **Grouping**: Gruppiere Related Entities nach Keys
|
||||
5. **Assignment**: Weise Relations den entsprechenden Entities zu
|
||||
|
||||
### BelongsTo Relations (Foreign Key Lookup)
|
||||
```php
|
||||
// Sammle alle Foreign Keys
|
||||
$foreignKeys = array_unique(array_column($dataRows, 'category_id'));
|
||||
|
||||
// Ein Batch-Query für alle Categories
|
||||
$categories = $entityLoader->findBy(Category::class, ['id' => $foreignKeys]);
|
||||
|
||||
// Gruppiere nach ID für schnelle Zuordnung
|
||||
$categoriesById = array_column($categories, null, 'id');
|
||||
```
|
||||
|
||||
### HasMany Relations (Reverse Lookup)
|
||||
```php
|
||||
// Sammle alle Entity IDs
|
||||
$userIds = array_column($userDataRows, 'id');
|
||||
|
||||
// Ein Batch-Query für alle Posts
|
||||
$posts = $entityLoader->findBy(Post::class, ['user_id' => $userIds]);
|
||||
|
||||
// Gruppiere Posts nach user_id
|
||||
$postsByUserId = [];
|
||||
foreach($posts as $post) {
|
||||
$postsByUserId[$post->user_id][] = $post;
|
||||
}
|
||||
```
|
||||
|
||||
### One-to-One Relations
|
||||
```php
|
||||
// Ähnlich wie hasMany, aber nur eine Relation pro Entity
|
||||
$profiles = $entityLoader->findBy(Profile::class, ['user_id' => $userIds]);
|
||||
$profileByUserId = array_column($profiles, null, 'user_id');
|
||||
```
|
||||
|
||||
## Error Handling & Edge Cases
|
||||
|
||||
### Missing Relations
|
||||
```php
|
||||
// Entities ohne Relations erhalten Default-Werte
|
||||
$userPosts = $postsByUserId[$userId] ?? []; // Empty array für hasMany
|
||||
$userProfile = $profilesByUserId[$userId] ?? null; // null für belongsTo/one-to-one
|
||||
```
|
||||
|
||||
### Empty Data Sets
|
||||
```php
|
||||
$result = $hydrator->hydrateManyWithRelations($metadata, [], ['posts']);
|
||||
// Returns: [] (empty array, keine Fehler)
|
||||
```
|
||||
|
||||
### Invalid Relations
|
||||
```php
|
||||
// Nicht-existierende oder Nicht-Relations werden übersprungen
|
||||
$user = $hydrator->hydrateWithRelations($metadata, $data, ['invalid_relation']);
|
||||
// Kein Fehler, Relation wird ignoriert
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Selective Loading
|
||||
```php
|
||||
// ✅ Gut: Nur benötigte Relations laden
|
||||
$posts = $hydrator->hydrateManyWithRelations($metadata, $data, ['author', 'comments']);
|
||||
|
||||
// ❌ Schlecht: Alle Relations laden
|
||||
$posts = $hydrator->hydrateManyWithRelations($metadata, $data, ['author', 'comments', 'tags', 'category', 'ratings']);
|
||||
```
|
||||
|
||||
### 2. Batch Processing priorisieren
|
||||
```php
|
||||
// ✅ Gut: Batch Loading für Collections
|
||||
$users = $hydrator->hydrateManyWithRelations($metadata, $dataRows, ['posts']);
|
||||
|
||||
// ❌ Schlecht: Einzelne Hydration in Loop
|
||||
foreach($dataRows as $data) {
|
||||
$users[] = $hydrator->hydrateWithRelations($metadata, $data, ['posts']);
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Relation Depth begrenzen
|
||||
```php
|
||||
// ✅ Gut: Direkte Relations
|
||||
$posts = $hydrator->hydrateManyWithRelations($metadata, $data, ['author', 'comments']);
|
||||
|
||||
// ⚠️ Consideration: Nested Relations
|
||||
// (Aktuell nicht unterstützt, würde zusätzliche Implementierung benötigen)
|
||||
$posts = $hydrator->hydrateManyWithRelations($metadata, $data, ['author.profile', 'comments.author']);
|
||||
```
|
||||
|
||||
## Benefits Summary
|
||||
|
||||
1. **Performance**: 95-98% Reduktion der Database-Queries
|
||||
2. **Scalability**: Lineare statt exponentieller Query-Wachstum
|
||||
3. **Resource Efficiency**: Drastisch reduzierte DB-Connection Usage
|
||||
4. **User Experience**: Faster page loads and API responses
|
||||
5. **Server Stability**: Reduzierter Memory- und CPU-Verbrauch
|
||||
6. **Database Health**: Weniger Lock-Contention und Connection-Pool-Pressure
|
||||
|
||||
## Migration Path
|
||||
|
||||
### Bestehende Code-Base
|
||||
```php
|
||||
// Vorher: Lazy Loading mit N+1 Problem
|
||||
$users = $repository->findAll();
|
||||
foreach($users as $user) {
|
||||
// Implicit queries triggered
|
||||
$user->posts;
|
||||
$user->profile;
|
||||
}
|
||||
|
||||
// Nachher: Explicit Eager Loading
|
||||
$userData = $repository->findAllAsData(); // Raw data query
|
||||
$users = $hydrator->hydrateManyWithRelations($metadata, $userData, ['posts', 'profile']);
|
||||
```
|
||||
|
||||
### Performance Monitoring
|
||||
- Monitor Query Count vor/nach Migration
|
||||
- Database Profiling für Query-Performance
|
||||
- Application Response Time Tracking
|
||||
- Memory Usage Monitoring bei Large Collections
|
||||
@@ -0,0 +1,204 @@
|
||||
# Master/Slave Router with Load Balancing
|
||||
|
||||
Der Master/Slave Router bietet fortgeschrittene Load Balancing und Monitoring Funktionen für optimale Database-Performance in High-Availability Setups.
|
||||
|
||||
## ✅ Implemented Features
|
||||
|
||||
### Weighted Selection Algorithm
|
||||
- **Dynamic Weight Adjustment**: Gewichte basierend auf aktueller Connection-Last und Response Time
|
||||
- **Load Factor**: Reduziert Gewichtung bei hoher Connection-Auslastung (min. 10% Gewichtung)
|
||||
- **Response Time Factor**: Bevorzugt schnelle Replicas basierend auf Moving Average
|
||||
- **Minimum Weight Protection**: Alle Replicas behalten mindestens 1% Gewichtung
|
||||
|
||||
### Connection Metrics & Monitoring
|
||||
- **Real-time Connection Counting**: Tracking aktiver Connections pro Replica
|
||||
- **Response Time History**: Moving Average der letzten 100 Response Times pro Replica
|
||||
- **Health Monitoring**: Automatische Health Checks mit konfigurierbaren Intervallen
|
||||
- **Comprehensive Statistics**: Detaillierte Routing-Statistiken für Monitoring
|
||||
|
||||
### Load Balancing Strategies
|
||||
- **WEIGHTED**: Intelligente gewichtete Auswahl mit Performance-Adjustierung
|
||||
- **LEAST_CONNECTIONS**: Auswahl der Replica mit wenigsten aktiven Connections
|
||||
- **RESPONSE_TIME**: Auswahl basierend auf bester durchschnittlicher Response Time
|
||||
- **ROUND_ROBIN**: Traditionelle zyklische Auswahl
|
||||
- **RANDOM**: Zufällige Auswahl für gleichmäßige Verteilung
|
||||
|
||||
## Configuration
|
||||
|
||||
### DriverConfig Extension
|
||||
```php
|
||||
public readonly class DriverConfig
|
||||
{
|
||||
public function __construct(
|
||||
// ... existing parameters ...
|
||||
public int $weight = 100, // Load balancing weight
|
||||
public int $maxConnections = 100 // Max concurrent connections
|
||||
) {}
|
||||
}
|
||||
```
|
||||
|
||||
### ReadWriteConfig Methods
|
||||
```php
|
||||
$config->getConnectionWeight($index); // Get weight for replica
|
||||
$config->getMaxConnections($index); // Get max connections for replica
|
||||
$config->getAllWeights(); // Get all weights indexed by position
|
||||
```
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Weighted Load Balancing Setup
|
||||
```php
|
||||
$readWriteConfig = new ReadWriteConfig(
|
||||
enabled: true,
|
||||
readConnections: [
|
||||
DriverConfig::fromArray([
|
||||
'host' => 'replica1.db.local',
|
||||
'weight' => 100, // Normal weight
|
||||
'max_connections' => 50
|
||||
]),
|
||||
DriverConfig::fromArray([
|
||||
'host' => 'replica2.db.local',
|
||||
'weight' => 200, // 2x higher capacity
|
||||
'max_connections' => 100
|
||||
]),
|
||||
DriverConfig::fromArray([
|
||||
'host' => 'replica3.db.local',
|
||||
'weight' => 50, // Lower capacity
|
||||
'max_connections' => 25
|
||||
])
|
||||
],
|
||||
loadBalancingStrategy: LoadBalancingStrategy::WEIGHTED
|
||||
);
|
||||
```
|
||||
|
||||
### Connection Tracking
|
||||
```php
|
||||
// Router tracks connections automatically
|
||||
$replica = $router->route($sql);
|
||||
|
||||
// Manual connection management (if needed)
|
||||
$router->incrementConnectionCount($replica);
|
||||
// ... use connection ...
|
||||
$router->decrementConnectionCount($replica);
|
||||
|
||||
// Track query performance
|
||||
$startTime = microtime(true);
|
||||
$result = $replica->query($sql);
|
||||
$responseTime = (microtime(true) - $startTime) * 1000;
|
||||
$router->recordResponseTime($replica, $responseTime);
|
||||
```
|
||||
|
||||
## Monitoring & Statistics
|
||||
|
||||
### Comprehensive Routing Statistics
|
||||
```php
|
||||
$stats = $router->getRoutingStatistics();
|
||||
// Returns:
|
||||
[
|
||||
'total_replicas' => 3,
|
||||
'healthy_replicas' => 2,
|
||||
'load_balancing_strategy' => 'WEIGHTED',
|
||||
'sticky_sessions' => false,
|
||||
'replica_details' => [
|
||||
0 => [
|
||||
'healthy' => true,
|
||||
'current_connections' => 15,
|
||||
'max_connections' => 50,
|
||||
'load_percentage' => 30.0,
|
||||
'config_weight' => 100,
|
||||
'adjusted_weight' => 85, // Reduced due to load
|
||||
'weight_adjustment_factor' => 0.85,
|
||||
'avg_response_time_ms' => 120.5,
|
||||
'total_queries' => 1540,
|
||||
'failed_queries' => 3,
|
||||
'success_rate' => 99.81,
|
||||
'recent_response_samples' => 100
|
||||
],
|
||||
// ... other replicas
|
||||
]
|
||||
]
|
||||
```
|
||||
|
||||
### Weight Distribution Analysis
|
||||
```php
|
||||
$distribution = $router->getWeightDistribution();
|
||||
// Returns current weight distribution for healthy replicas:
|
||||
[
|
||||
0 => [
|
||||
'config_weight' => 100,
|
||||
'adjusted_weight' => 85,
|
||||
'current_connections' => 15,
|
||||
'avg_response_time' => 120.5,
|
||||
'weight_percentage' => 35.2 // % of total weight
|
||||
],
|
||||
// ... other healthy replicas
|
||||
]
|
||||
```
|
||||
|
||||
## Performance Benefits
|
||||
|
||||
### Intelligent Load Distribution
|
||||
- **Load-based Adjustment**: Überlastete Replicas erhalten weniger Traffic
|
||||
- **Performance-based Routing**: Schnelle Replicas werden bevorzugt
|
||||
- **Connection Pool Optimization**: Verhindert Connection-Überlastung
|
||||
- **Failover Protection**: Automatischer Fallback bei Replica-Ausfallen
|
||||
|
||||
### Monitoring Integration
|
||||
- **Real-time Metrics**: Live-Statistiken für Performance-Monitoring
|
||||
- **Health Tracking**: Continuous Health Checks mit Response Time Tracking
|
||||
- **Success Rate Monitoring**: Tracking von Query Success/Failure Rates
|
||||
- **Load Analysis**: Detaillierte Load-Verteilung für Capacity Planning
|
||||
|
||||
## Weight Calculation Algorithm
|
||||
|
||||
```php
|
||||
// Dynamic weight adjustment based on current performance
|
||||
$loadFactor = max(0.1, 1 - ($currentConnections / $maxConnections));
|
||||
$responseFactor = max(0.1, min(1.0, 100 / $avgResponseTime));
|
||||
$adjustedWeight = max(1, round($baseWeight * $loadFactor * $responseFactor));
|
||||
```
|
||||
|
||||
**Factors:**
|
||||
- **Load Factor**: 10-100% basierend auf Connection-Auslastung
|
||||
- **Response Factor**: 10-100% basierend auf Response Time (100ms = Baseline)
|
||||
- **Minimum Protection**: Jede Replica behält mindestens 10% Gewichtung
|
||||
|
||||
## Testing
|
||||
|
||||
Comprehensive test suite covering:
|
||||
- ✅ Weighted selection distribution accuracy
|
||||
- ✅ Load factor calculation with edge cases
|
||||
- ✅ Response time factor adjustment
|
||||
- ✅ Connection counting accuracy
|
||||
- ✅ Response time history window management
|
||||
- ✅ Load balancing strategy logic
|
||||
- ✅ Routing statistics generation
|
||||
|
||||
All tests pass with 78 assertions validating the complete implementation.
|
||||
|
||||
## Migration from Simple Round Robin
|
||||
|
||||
```php
|
||||
// Vorher: Simple Round Robin
|
||||
$router = new MasterSlaveRouter(
|
||||
$master,
|
||||
$replicas,
|
||||
new ReadWriteConfig(
|
||||
enabled: true,
|
||||
loadBalancingStrategy: LoadBalancingStrategy::ROUND_ROBIN
|
||||
)
|
||||
);
|
||||
|
||||
// Nachher: Intelligent Weighted Balancing
|
||||
$router = new MasterSlaveRouter(
|
||||
$master,
|
||||
$replicas,
|
||||
new ReadWriteConfig(
|
||||
enabled: true,
|
||||
readConnections: $configsWithWeights,
|
||||
loadBalancingStrategy: LoadBalancingStrategy::WEIGHTED
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
Die Implementierung bietet vollständige Backward-Compatibility mit bestehenden Setups.
|
||||
@@ -0,0 +1,610 @@
|
||||
# Admin Design System
|
||||
|
||||
> Comprehensive design system for administrative interfaces with modern UI patterns, accessibility standards, and developer efficiency.
|
||||
|
||||
## 🎯 Design Principles
|
||||
|
||||
### User Experience
|
||||
- **Clarity First** - Information hierarchy and visual clarity over decoration
|
||||
- **Efficiency** - Minimize cognitive load and interaction friction
|
||||
- **Consistency** - Predictable patterns and behaviors across all interfaces
|
||||
- **Accessibility** - WCAG 2.1 AA compliance and inclusive design
|
||||
|
||||
### Technical Excellence
|
||||
- **Performance** - Fast load times and smooth interactions
|
||||
- **Maintainability** - Modular, reusable components
|
||||
- **Scalability** - Adaptable to growing feature requirements
|
||||
- **Developer Experience** - Clear documentation and easy implementation
|
||||
|
||||
## 🎨 Visual Language
|
||||
|
||||
### Color System
|
||||
|
||||
```css
|
||||
/* Primary Admin Palette */
|
||||
--admin-primary: #6366f1; /* Indigo - Primary actions */
|
||||
--admin-primary-hover: #5855eb; /* Hover states */
|
||||
--admin-primary-active: #4f46e5; /* Active states */
|
||||
--admin-primary-light: #a5b4fc; /* Backgrounds */
|
||||
|
||||
/* Semantic Colors */
|
||||
--admin-success: #10b981; /* Success states */
|
||||
--admin-warning: #f59e0b; /* Warning states */
|
||||
--admin-error: #ef4444; /* Error states */
|
||||
--admin-info: #3b82f6; /* Information */
|
||||
|
||||
/* Neutral System */
|
||||
--admin-gray-50: #f8fafc; /* Lightest backgrounds */
|
||||
--admin-gray-100: #f1f5f9; /* Light backgrounds */
|
||||
--admin-gray-200: #e2e8f0; /* Borders */
|
||||
--admin-gray-300: #cbd5e1; /* Disabled states */
|
||||
--admin-gray-400: #94a3b8; /* Placeholders */
|
||||
--admin-gray-500: #64748b; /* Secondary text */
|
||||
--admin-gray-600: #475569; /* Primary text */
|
||||
--admin-gray-700: #334155; /* Headings */
|
||||
--admin-gray-800: #1e293b; /* Dark text */
|
||||
--admin-gray-900: #0f172a; /* Darkest elements */
|
||||
|
||||
/* Dark Theme */
|
||||
--admin-dark-bg: #0f172a;
|
||||
--admin-dark-surface: #1e293b;
|
||||
--admin-dark-border: #334155;
|
||||
--admin-dark-text: #f1f5f9;
|
||||
```
|
||||
|
||||
### Typography
|
||||
|
||||
```css
|
||||
/* Font Stacks */
|
||||
--admin-font-sans: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
--admin-font-mono: 'SF Mono', 'Monaco', 'Cascadia Code', monospace;
|
||||
|
||||
/* Type Scale */
|
||||
--admin-text-xs: 0.75rem; /* 12px - Small labels */
|
||||
--admin-text-sm: 0.875rem; /* 14px - Body text */
|
||||
--admin-text-base: 1rem; /* 16px - Default */
|
||||
--admin-text-lg: 1.125rem; /* 18px - Large body */
|
||||
--admin-text-xl: 1.25rem; /* 20px - Small headings */
|
||||
--admin-text-2xl: 1.5rem; /* 24px - Section headings */
|
||||
--admin-text-3xl: 1.875rem; /* 30px - Page titles */
|
||||
--admin-text-4xl: 2.25rem; /* 36px - Large titles */
|
||||
|
||||
/* Font Weights */
|
||||
--admin-font-light: 300;
|
||||
--admin-font-normal: 400;
|
||||
--admin-font-medium: 500;
|
||||
--admin-font-semibold: 600;
|
||||
--admin-font-bold: 700;
|
||||
```
|
||||
|
||||
### Spacing System
|
||||
|
||||
```css
|
||||
/* 4px base unit scaling */
|
||||
--admin-space-0: 0;
|
||||
--admin-space-1: 0.25rem; /* 4px */
|
||||
--admin-space-2: 0.5rem; /* 8px */
|
||||
--admin-space-3: 0.75rem; /* 12px */
|
||||
--admin-space-4: 1rem; /* 16px */
|
||||
--admin-space-5: 1.25rem; /* 20px */
|
||||
--admin-space-6: 1.5rem; /* 24px */
|
||||
--admin-space-8: 2rem; /* 32px */
|
||||
--admin-space-10: 2.5rem; /* 40px */
|
||||
--admin-space-12: 3rem; /* 48px */
|
||||
--admin-space-16: 4rem; /* 64px */
|
||||
--admin-space-20: 5rem; /* 80px */
|
||||
--admin-space-24: 6rem; /* 96px */
|
||||
```
|
||||
|
||||
### Elevation & Shadows
|
||||
|
||||
```css
|
||||
/* Shadow System */
|
||||
--admin-shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
||||
--admin-shadow-base: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
||||
--admin-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
--admin-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
||||
--admin-shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
||||
|
||||
/* Border Radius */
|
||||
--admin-radius-none: 0;
|
||||
--admin-radius-sm: 0.125rem; /* 2px */
|
||||
--admin-radius-base: 0.25rem; /* 4px */
|
||||
--admin-radius-md: 0.375rem; /* 6px */
|
||||
--admin-radius-lg: 0.5rem; /* 8px */
|
||||
--admin-radius-xl: 0.75rem; /* 12px */
|
||||
--admin-radius-2xl: 1rem; /* 16px */
|
||||
--admin-radius-full: 9999px; /* Pill shape */
|
||||
```
|
||||
|
||||
## 🏗 Layout System
|
||||
|
||||
### Grid Foundation
|
||||
|
||||
```css
|
||||
/* Admin Layout Grid */
|
||||
.admin-layout {
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"header header"
|
||||
"nav main"
|
||||
"nav footer";
|
||||
grid-template-columns: 250px 1fr;
|
||||
grid-template-rows: auto 1fr auto;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.admin-header { grid-area: header; }
|
||||
.admin-nav { grid-area: nav; }
|
||||
.admin-main { grid-area: main; }
|
||||
.admin-footer { grid-area: footer; }
|
||||
|
||||
/* Responsive Adaptations */
|
||||
@media (max-width: 768px) {
|
||||
.admin-layout {
|
||||
grid-template-areas:
|
||||
"header"
|
||||
"main"
|
||||
"footer";
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.admin-nav {
|
||||
transform: translateX(-100%);
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.admin-nav.is-open {
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Content Layout
|
||||
|
||||
```css
|
||||
/* Page Structure */
|
||||
.page-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: var(--admin-space-6) 0;
|
||||
border-bottom: 1px solid var(--admin-gray-200);
|
||||
margin-bottom: var(--admin-space-6);
|
||||
}
|
||||
|
||||
.page-content {
|
||||
max-width: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Content Sections */
|
||||
.admin-section {
|
||||
background: var(--admin-surface);
|
||||
border: 1px solid var(--admin-border);
|
||||
border-radius: var(--admin-radius-lg);
|
||||
padding: var(--admin-space-6);
|
||||
margin-bottom: var(--admin-space-6);
|
||||
}
|
||||
|
||||
.admin-section + .admin-section {
|
||||
margin-top: var(--admin-space-8);
|
||||
}
|
||||
```
|
||||
|
||||
## 🧩 Component Architecture
|
||||
|
||||
### Base Component Classes
|
||||
|
||||
```css
|
||||
/* Button System */
|
||||
.admin-button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--admin-space-2);
|
||||
padding: var(--admin-space-2) var(--admin-space-4);
|
||||
border: 1px solid transparent;
|
||||
border-radius: var(--admin-radius-md);
|
||||
font-family: var(--admin-font-sans);
|
||||
font-size: var(--admin-text-sm);
|
||||
font-weight: var(--admin-font-medium);
|
||||
line-height: 1.5;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s ease;
|
||||
|
||||
&:focus {
|
||||
outline: 2px solid var(--admin-primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
/* Button Variants */
|
||||
.admin-button--primary {
|
||||
background: var(--admin-primary);
|
||||
color: white;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
background: var(--admin-primary-hover);
|
||||
}
|
||||
}
|
||||
|
||||
.admin-button--secondary {
|
||||
background: var(--admin-gray-100);
|
||||
color: var(--admin-gray-700);
|
||||
border-color: var(--admin-gray-200);
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
background: var(--admin-gray-200);
|
||||
}
|
||||
}
|
||||
|
||||
.admin-button--ghost {
|
||||
background: transparent;
|
||||
color: var(--admin-gray-600);
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
background: var(--admin-gray-100);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Form Components
|
||||
|
||||
```css
|
||||
/* Input System */
|
||||
.admin-input {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: var(--admin-space-3);
|
||||
border: 1px solid var(--admin-gray-300);
|
||||
border-radius: var(--admin-radius-md);
|
||||
font-family: var(--admin-font-sans);
|
||||
font-size: var(--admin-text-sm);
|
||||
line-height: 1.5;
|
||||
background: white;
|
||||
transition: all 0.15s ease;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
border-color: var(--admin-primary);
|
||||
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
background: var(--admin-gray-50);
|
||||
color: var(--admin-gray-400);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&.is-error {
|
||||
border-color: var(--admin-error);
|
||||
|
||||
&:focus {
|
||||
box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Form Groups */
|
||||
.admin-form-group {
|
||||
margin-bottom: var(--admin-space-4);
|
||||
}
|
||||
|
||||
.admin-label {
|
||||
display: block;
|
||||
margin-bottom: var(--admin-space-2);
|
||||
font-size: var(--admin-text-sm);
|
||||
font-weight: var(--admin-font-medium);
|
||||
color: var(--admin-gray-700);
|
||||
}
|
||||
|
||||
.admin-help-text {
|
||||
margin-top: var(--admin-space-1);
|
||||
font-size: var(--admin-text-xs);
|
||||
color: var(--admin-gray-500);
|
||||
}
|
||||
|
||||
.admin-error-text {
|
||||
margin-top: var(--admin-space-1);
|
||||
font-size: var(--admin-text-xs);
|
||||
color: var(--admin-error);
|
||||
}
|
||||
```
|
||||
|
||||
### Data Display Components
|
||||
|
||||
```css
|
||||
/* Stats Cards */
|
||||
.admin-stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
||||
gap: var(--admin-space-6);
|
||||
margin-bottom: var(--admin-space-8);
|
||||
}
|
||||
|
||||
.admin-stat-card {
|
||||
background: var(--admin-surface);
|
||||
border: 1px solid var(--admin-border);
|
||||
border-radius: var(--admin-radius-lg);
|
||||
padding: var(--admin-space-6);
|
||||
|
||||
&:hover {
|
||||
border-color: var(--admin-primary-light);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: var(--admin-shadow-md);
|
||||
}
|
||||
}
|
||||
|
||||
.admin-stat-label {
|
||||
display: block;
|
||||
font-size: var(--admin-text-sm);
|
||||
font-weight: var(--admin-font-medium);
|
||||
color: var(--admin-gray-600);
|
||||
margin-bottom: var(--admin-space-2);
|
||||
}
|
||||
|
||||
.admin-stat-value {
|
||||
font-size: var(--admin-text-3xl);
|
||||
font-weight: var(--admin-font-bold);
|
||||
color: var(--admin-gray-900);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.admin-stat-trend {
|
||||
margin-top: var(--admin-space-2);
|
||||
font-size: var(--admin-text-xs);
|
||||
|
||||
&.is-positive { color: var(--admin-success); }
|
||||
&.is-negative { color: var(--admin-error); }
|
||||
&.is-neutral { color: var(--admin-gray-500); }
|
||||
}
|
||||
```
|
||||
|
||||
### Tables
|
||||
|
||||
```css
|
||||
/* Admin Tables */
|
||||
.admin-table {
|
||||
width: 100%;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
background: var(--admin-surface);
|
||||
border: 1px solid var(--admin-border);
|
||||
border-radius: var(--admin-radius-lg);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.admin-table th {
|
||||
background: var(--admin-gray-50);
|
||||
padding: var(--admin-space-4);
|
||||
text-align: left;
|
||||
font-size: var(--admin-text-xs);
|
||||
font-weight: var(--admin-font-semibold);
|
||||
color: var(--admin-gray-600);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
border-bottom: 1px solid var(--admin-border);
|
||||
|
||||
&[data-sort] {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
|
||||
&:hover {
|
||||
background: var(--admin-gray-100);
|
||||
}
|
||||
|
||||
&.is-sorted-asc::after {
|
||||
content: " ↑";
|
||||
color: var(--admin-primary);
|
||||
}
|
||||
|
||||
&.is-sorted-desc::after {
|
||||
content: " ↓";
|
||||
color: var(--admin-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.admin-table td {
|
||||
padding: var(--admin-space-4);
|
||||
border-bottom: 1px solid var(--admin-gray-100);
|
||||
font-size: var(--admin-text-sm);
|
||||
color: var(--admin-gray-700);
|
||||
}
|
||||
|
||||
.admin-table tbody tr:hover {
|
||||
background: var(--admin-gray-50);
|
||||
}
|
||||
|
||||
.admin-table tbody tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
```
|
||||
|
||||
## 🌓 Dark Mode Support
|
||||
|
||||
```css
|
||||
/* Dark Theme Variables */
|
||||
[data-theme="dark"] {
|
||||
--admin-surface: var(--admin-dark-surface);
|
||||
--admin-border: var(--admin-dark-border);
|
||||
--admin-text: var(--admin-dark-text);
|
||||
--admin-bg: var(--admin-dark-bg);
|
||||
|
||||
/* Component Adaptations */
|
||||
--admin-gray-50: #334155;
|
||||
--admin-gray-100: #475569;
|
||||
--admin-gray-200: #64748b;
|
||||
--admin-gray-600: #cbd5e1;
|
||||
--admin-gray-700: #e2e8f0;
|
||||
--admin-gray-900: var(--admin-dark-text);
|
||||
}
|
||||
|
||||
/* Theme Toggle Component */
|
||||
.admin-theme-toggle {
|
||||
position: relative;
|
||||
width: 48px;
|
||||
height: 24px;
|
||||
background: var(--admin-gray-200);
|
||||
border: none;
|
||||
border-radius: var(--admin-radius-full);
|
||||
cursor: pointer;
|
||||
transition: background 0.2s ease;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: white;
|
||||
border-radius: 50%;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
&.is-dark {
|
||||
background: var(--admin-primary);
|
||||
|
||||
&::after {
|
||||
transform: translateX(24px);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## ♿ Accessibility Standards
|
||||
|
||||
### Focus Management
|
||||
|
||||
```css
|
||||
/* Focus Styles */
|
||||
.admin-focus-visible {
|
||||
outline: 2px solid var(--admin-primary);
|
||||
outline-offset: 2px;
|
||||
border-radius: var(--admin-radius-sm);
|
||||
}
|
||||
|
||||
/* Skip Links */
|
||||
.admin-skip-link {
|
||||
position: absolute;
|
||||
top: -40px;
|
||||
left: 6px;
|
||||
background: var(--admin-primary);
|
||||
color: white;
|
||||
padding: 8px;
|
||||
text-decoration: none;
|
||||
border-radius: var(--admin-radius-md);
|
||||
z-index: 1000;
|
||||
|
||||
&:focus {
|
||||
top: 6px;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### ARIA Support
|
||||
|
||||
```html
|
||||
<!-- Navigation with proper ARIA -->
|
||||
<nav class="admin-nav" role="navigation" aria-label="Main navigation">
|
||||
<ul role="menubar">
|
||||
<li role="none">
|
||||
<a href="/admin" role="menuitem" aria-current="page">Dashboard</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<!-- Data tables with proper headers -->
|
||||
<table class="admin-table" role="table" aria-label="User data">
|
||||
<thead>
|
||||
<tr role="row">
|
||||
<th role="columnheader" aria-sort="ascending">Name</th>
|
||||
<th role="columnheader">Email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody role="rowgroup">
|
||||
<tr role="row">
|
||||
<td role="gridcell">John Doe</td>
|
||||
<td role="gridcell">john@example.com</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
```
|
||||
|
||||
## 📱 Responsive Behavior
|
||||
|
||||
### Breakpoint System
|
||||
|
||||
```css
|
||||
/* Mobile First Breakpoints */
|
||||
.admin-responsive {
|
||||
/* Mobile (default) */
|
||||
padding: var(--admin-space-4);
|
||||
|
||||
/* Tablet */
|
||||
@media (min-width: 768px) {
|
||||
padding: var(--admin-space-6);
|
||||
}
|
||||
|
||||
/* Desktop */
|
||||
@media (min-width: 1024px) {
|
||||
padding: var(--admin-space-8);
|
||||
}
|
||||
|
||||
/* Large Desktop */
|
||||
@media (min-width: 1280px) {
|
||||
padding: var(--admin-space-12);
|
||||
}
|
||||
}
|
||||
|
||||
/* Navigation Adaptations */
|
||||
@media (max-width: 767px) {
|
||||
.admin-nav {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 280px;
|
||||
height: 100vh;
|
||||
background: var(--admin-surface);
|
||||
border-right: 1px solid var(--admin-border);
|
||||
transform: translateX(-100%);
|
||||
transition: transform 0.3s ease;
|
||||
z-index: 1000;
|
||||
|
||||
&.is-open {
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
.admin-nav-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: all 0.3s ease;
|
||||
z-index: 999;
|
||||
|
||||
&.is-active {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*For implementation examples, see [Admin Components](components.md)*
|
||||
*For JavaScript integration, see [JavaScript Modules](../javascript.md)*
|
||||
*For performance guidelines, see [CSS Architecture](../css-architecture.md)*
|
||||
471
backups/docs-backup-20250731125004/design-system/components.md
Normal file
471
backups/docs-backup-20250731125004/design-system/components.md
Normal file
@@ -0,0 +1,471 @@
|
||||
# UI Components
|
||||
|
||||
> Component library documentation and usage examples for the design system.
|
||||
|
||||
## 🧩 Component Architecture
|
||||
|
||||
All components follow a consistent structure with design tokens, accessibility standards, and responsive behavior.
|
||||
|
||||
### Base Component Pattern
|
||||
|
||||
```html
|
||||
<div class="component-name" data-component="name" role="[role]" aria-label="[description]">
|
||||
<div class="component-name__element">
|
||||
<!-- Component content -->
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Component CSS Structure
|
||||
|
||||
```css
|
||||
/* Block */
|
||||
.component-name {
|
||||
/* Base styles using design tokens */
|
||||
}
|
||||
|
||||
/* Element */
|
||||
.component-name__element {
|
||||
/* Element styles */
|
||||
}
|
||||
|
||||
/* Modifier */
|
||||
.component-name--variant {
|
||||
/* Variant styles */
|
||||
}
|
||||
|
||||
/* State */
|
||||
.component-name.is-active {
|
||||
/* State styles */
|
||||
}
|
||||
```
|
||||
|
||||
## 📋 Form Components
|
||||
|
||||
### Buttons
|
||||
|
||||
Basic button implementation with variants:
|
||||
|
||||
```html
|
||||
<!-- Primary Button -->
|
||||
<button class="btn btn--primary" type="button">
|
||||
Primary Action
|
||||
</button>
|
||||
|
||||
<!-- Secondary Button -->
|
||||
<button class="btn btn--secondary" type="button">
|
||||
Secondary Action
|
||||
</button>
|
||||
|
||||
<!-- Ghost Button -->
|
||||
<button class="btn btn--ghost" type="button">
|
||||
Ghost Action
|
||||
</button>
|
||||
```
|
||||
|
||||
**CSS Implementation:**
|
||||
```css
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
padding: var(--space-3) var(--space-4);
|
||||
border: 1px solid transparent;
|
||||
border-radius: var(--radius-md);
|
||||
font-family: var(--font-family-sans);
|
||||
font-size: var(--text-sm);
|
||||
font-weight: var(--font-medium);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
transition: all var(--duration-150) var(--ease-out);
|
||||
|
||||
&:focus-visible {
|
||||
outline: 2px solid var(--color-primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
.btn--primary {
|
||||
background: var(--color-primary);
|
||||
color: white;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
background: var(--color-primary-600);
|
||||
}
|
||||
}
|
||||
|
||||
.btn--secondary {
|
||||
background: var(--color-gray-100);
|
||||
color: var(--color-gray-700);
|
||||
border-color: var(--color-gray-200);
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
background: var(--color-gray-200);
|
||||
}
|
||||
}
|
||||
|
||||
.btn--ghost {
|
||||
background: transparent;
|
||||
color: var(--color-gray-600);
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
background: var(--color-gray-100);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Input Fields
|
||||
|
||||
Form input components with validation states:
|
||||
|
||||
```html
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="example-input">
|
||||
Field Label
|
||||
</label>
|
||||
<input
|
||||
class="form-input"
|
||||
type="text"
|
||||
id="example-input"
|
||||
placeholder="Enter text..."
|
||||
aria-describedby="example-help"
|
||||
/>
|
||||
<div class="form-help" id="example-help">
|
||||
Optional help text for this field
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Error State -->
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="error-input">
|
||||
Field with Error
|
||||
</label>
|
||||
<input
|
||||
class="form-input form-input--error"
|
||||
type="text"
|
||||
id="error-input"
|
||||
aria-invalid="true"
|
||||
aria-describedby="error-message"
|
||||
/>
|
||||
<div class="form-error" id="error-message">
|
||||
This field is required
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## 🎭 Layout Components
|
||||
|
||||
### Cards
|
||||
|
||||
Content containers with consistent styling:
|
||||
|
||||
```html
|
||||
<div class="card">
|
||||
<div class="card__header">
|
||||
<h3 class="card__title">Card Title</h3>
|
||||
<div class="card__actions">
|
||||
<button class="btn btn--ghost">Action</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card__body">
|
||||
<p>Card content goes here...</p>
|
||||
</div>
|
||||
<div class="card__footer">
|
||||
<small class="text-muted">Footer information</small>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Modals
|
||||
|
||||
Accessible modal dialogs:
|
||||
|
||||
```html
|
||||
<div class="modal" role="dialog" aria-modal="true" aria-labelledby="modal-title">
|
||||
<div class="modal__overlay" data-modal-close></div>
|
||||
<div class="modal__content">
|
||||
<div class="modal__header">
|
||||
<h2 class="modal__title" id="modal-title">Modal Title</h2>
|
||||
<button class="modal__close" data-modal-close aria-label="Close modal">
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal__body">
|
||||
<p>Modal content...</p>
|
||||
</div>
|
||||
<div class="modal__footer">
|
||||
<button class="btn btn--primary">Confirm</button>
|
||||
<button class="btn btn--secondary" data-modal-close>Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## 📊 Data Display
|
||||
|
||||
### Tables
|
||||
|
||||
Data tables with sorting and filtering:
|
||||
|
||||
```html
|
||||
<div class="table-container">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-sort="name" class="table__header--sortable">
|
||||
Name
|
||||
<span class="table__sort-indicator"></span>
|
||||
</th>
|
||||
<th data-sort="email" class="table__header--sortable">
|
||||
Email
|
||||
<span class="table__sort-indicator"></span>
|
||||
</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>John Doe</td>
|
||||
<td>john@example.com</td>
|
||||
<td>
|
||||
<div class="table__actions">
|
||||
<button class="btn btn--ghost btn--sm">Edit</button>
|
||||
<button class="btn btn--ghost btn--sm">Delete</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Stats Cards
|
||||
|
||||
Dashboard statistics display:
|
||||
|
||||
```html
|
||||
<div class="stats-grid">
|
||||
<div class="stat-card">
|
||||
<div class="stat-card__icon">
|
||||
📊
|
||||
</div>
|
||||
<div class="stat-card__content">
|
||||
<div class="stat-card__label">Total Users</div>
|
||||
<div class="stat-card__value">1,234</div>
|
||||
<div class="stat-card__trend stat-card__trend--positive">
|
||||
↗ +12% from last month
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## 🔔 Feedback Components
|
||||
|
||||
### Alerts
|
||||
|
||||
Status and notification messages:
|
||||
|
||||
```html
|
||||
<!-- Success Alert -->
|
||||
<div class="alert alert--success" role="alert">
|
||||
<div class="alert__icon">✅</div>
|
||||
<div class="alert__content">
|
||||
<div class="alert__title">Success</div>
|
||||
<div class="alert__message">Operation completed successfully!</div>
|
||||
</div>
|
||||
<button class="alert__close" aria-label="Close alert">×</button>
|
||||
</div>
|
||||
|
||||
<!-- Error Alert -->
|
||||
<div class="alert alert--error" role="alert">
|
||||
<div class="alert__icon">❌</div>
|
||||
<div class="alert__content">
|
||||
<div class="alert__title">Error</div>
|
||||
<div class="alert__message">Something went wrong. Please try again.</div>
|
||||
</div>
|
||||
<button class="alert__close" aria-label="Close alert">×</button>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Loading States
|
||||
|
||||
Progress indicators and skeleton screens:
|
||||
|
||||
```html
|
||||
<!-- Spinner -->
|
||||
<div class="spinner" role="status" aria-label="Loading">
|
||||
<div class="spinner__circle"></div>
|
||||
</div>
|
||||
|
||||
<!-- Progress Bar -->
|
||||
<div class="progress" role="progressbar" aria-valuenow="65" aria-valuemin="0" aria-valuemax="100">
|
||||
<div class="progress__bar" style="width: 65%"></div>
|
||||
<div class="progress__label">65% Complete</div>
|
||||
</div>
|
||||
|
||||
<!-- Skeleton Screen -->
|
||||
<div class="skeleton">
|
||||
<div class="skeleton__line skeleton__line--title"></div>
|
||||
<div class="skeleton__line skeleton__line--text"></div>
|
||||
<div class="skeleton__line skeleton__line--text skeleton__line--short"></div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## 🎯 Interactive Components
|
||||
|
||||
### Tabs
|
||||
|
||||
Content organization with tabbed interface:
|
||||
|
||||
```html
|
||||
<div class="tabs" role="tablist">
|
||||
<button class="tabs__tab tabs__tab--active" role="tab" aria-selected="true" aria-controls="panel-1">
|
||||
Tab 1
|
||||
</button>
|
||||
<button class="tabs__tab" role="tab" aria-selected="false" aria-controls="panel-2">
|
||||
Tab 2
|
||||
</button>
|
||||
<button class="tabs__tab" role="tab" aria-selected="false" aria-controls="panel-3">
|
||||
Tab 3
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="tabs__panels">
|
||||
<div class="tabs__panel tabs__panel--active" role="tabpanel" id="panel-1">
|
||||
Content for tab 1
|
||||
</div>
|
||||
<div class="tabs__panel" role="tabpanel" id="panel-2" hidden>
|
||||
Content for tab 2
|
||||
</div>
|
||||
<div class="tabs__panel" role="tabpanel" id="panel-3" hidden>
|
||||
Content for tab 3
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Dropdowns
|
||||
|
||||
Menu and selection dropdowns:
|
||||
|
||||
```html
|
||||
<div class="dropdown">
|
||||
<button class="dropdown__trigger" aria-haspopup="true" aria-expanded="false">
|
||||
Menu
|
||||
<span class="dropdown__arrow">▼</span>
|
||||
</button>
|
||||
<ul class="dropdown__menu" role="menu">
|
||||
<li role="none">
|
||||
<a class="dropdown__item" role="menuitem" href="#action1">Action 1</a>
|
||||
</li>
|
||||
<li role="none">
|
||||
<a class="dropdown__item" role="menuitem" href="#action2">Action 2</a>
|
||||
</li>
|
||||
<li class="dropdown__divider" role="separator"></li>
|
||||
<li role="none">
|
||||
<a class="dropdown__item dropdown__item--danger" role="menuitem" href="#delete">
|
||||
Delete Item
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
```
|
||||
|
||||
## ♿ Accessibility Guidelines
|
||||
|
||||
### ARIA Implementation
|
||||
|
||||
All components include proper ARIA attributes:
|
||||
|
||||
- `role` attributes for semantic meaning
|
||||
- `aria-label` for accessible names
|
||||
- `aria-describedby` for help text associations
|
||||
- `aria-expanded` for collapsible content
|
||||
- `aria-selected` for selectable items
|
||||
|
||||
### Keyboard Navigation
|
||||
|
||||
Components support keyboard interaction:
|
||||
|
||||
- **Tab**: Navigate between focusable elements
|
||||
- **Enter/Space**: Activate buttons and links
|
||||
- **Escape**: Close modals and dropdowns
|
||||
- **Arrow Keys**: Navigate within component groups
|
||||
|
||||
### Focus Management
|
||||
|
||||
Proper focus indicators and management:
|
||||
|
||||
```css
|
||||
.component:focus-visible {
|
||||
outline: 2px solid var(--color-primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* Skip focus ring on mouse interaction */
|
||||
.component:focus:not(:focus-visible) {
|
||||
outline: none;
|
||||
}
|
||||
```
|
||||
|
||||
## 🎨 Theming
|
||||
|
||||
All components automatically adapt to theme changes through CSS custom properties:
|
||||
|
||||
```css
|
||||
.component {
|
||||
background: var(--surface);
|
||||
color: var(--text-primary);
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
|
||||
/* Dark theme automatically applied */
|
||||
[data-theme="dark"] .component {
|
||||
/* Inherits dark theme tokens */
|
||||
}
|
||||
```
|
||||
|
||||
## 📚 Usage Examples
|
||||
|
||||
### JavaScript Integration
|
||||
|
||||
Components work with the framework's JavaScript module system:
|
||||
|
||||
```javascript
|
||||
// Auto-initialize components
|
||||
document.querySelectorAll('[data-component="modal"]').forEach(element => {
|
||||
new Modal(element);
|
||||
});
|
||||
|
||||
// Event-driven interactions
|
||||
events.delegate('click', '[data-action="show-alert"]', (event, element) => {
|
||||
const message = element.dataset.message;
|
||||
showAlert('success', message);
|
||||
});
|
||||
```
|
||||
|
||||
### PHP Template Integration
|
||||
|
||||
Components integrate with the View system:
|
||||
|
||||
```php
|
||||
<div class="card">
|
||||
<div class="card__header">
|
||||
<h3 class="card__title"><?= $title ?></h3>
|
||||
</div>
|
||||
<div class="card__body">
|
||||
<?= $content ?>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*For design tokens and foundations, see [Design Foundations](foundations.md)*
|
||||
*For CSS architecture details, see [CSS Architecture](css-architecture.md)*
|
||||
*For JavaScript integration, see [JavaScript Modules](javascript.md)*
|
||||
@@ -0,0 +1,252 @@
|
||||
# CSS Architecture
|
||||
|
||||
> ITCSS-based modular CSS architecture with component-driven development and utility-first approach.
|
||||
|
||||
## 📁 File Structure
|
||||
|
||||
```
|
||||
resources/css/
|
||||
├── styles.css # Main import file
|
||||
├── settings/
|
||||
│ ├── colors.css # Color definitions
|
||||
│ ├── typography.css # Font sizes, fonts
|
||||
│ ├── spacing.css # Spacing (margin, padding)
|
||||
│ └── variables.css # Duration, easing, radius, z-index etc.
|
||||
├── base/
|
||||
│ ├── reset.css # Reset/Normalize
|
||||
│ ├── global.css # Global styles for html, body, etc.
|
||||
│ ├── typography.css # h1, p, etc.
|
||||
│ ├── focus.css # Focus states
|
||||
│ ├── media.css # Media queries
|
||||
│ └── index.css # Base layer imports
|
||||
├── layout/
|
||||
│ ├── container.css # .page-container, max-widths, etc.
|
||||
│ └── grid.css # Custom grid system
|
||||
├── components/
|
||||
│ ├── header.css
|
||||
│ ├── nav.css
|
||||
│ ├── footer.css
|
||||
│ ├── buttons.css
|
||||
│ ├── card.css
|
||||
│ └── sidebar.css
|
||||
├── forms/
|
||||
│ └── inputs.css
|
||||
├── utilities/
|
||||
│ ├── animations.css # .fade-in, .shake, etc.
|
||||
│ ├── helpers.css # .skip-link, .hidden, .visually-hidden
|
||||
│ ├── scroll.css # scroll-behavior, scrollbar-style
|
||||
│ ├── transitions.css
|
||||
│ └── noise.css
|
||||
└── themes/
|
||||
└── dark.css # Dark mode color adjustments
|
||||
```
|
||||
|
||||
## 🏗 ITCSS Layer Hierarchy
|
||||
|
||||
1. **Settings** - Variables, colors, typography scales
|
||||
2. **Base** - Reset, normalize, global element styles
|
||||
3. **Layout** - Grid systems, containers, structural components
|
||||
4. **Components** - UI components and modules
|
||||
5. **Utilities** - Helper classes and overrides
|
||||
6. **Themes** - Color scheme variations
|
||||
|
||||
## 🎨 Design Tokens
|
||||
|
||||
### Colors
|
||||
```css
|
||||
/* Primary Palette */
|
||||
--color-primary: #007bff;
|
||||
--color-primary-dark: #0056b3;
|
||||
--color-primary-light: #66b3ff;
|
||||
|
||||
/* Semantic Colors */
|
||||
--color-success: #28a745;
|
||||
--color-warning: #ffc107;
|
||||
--color-error: #dc3545;
|
||||
--color-info: #17a2b8;
|
||||
|
||||
/* Neutral Palette */
|
||||
--color-gray-50: #f8f9fa;
|
||||
--color-gray-100: #e9ecef;
|
||||
--color-gray-900: #212529;
|
||||
```
|
||||
|
||||
### Typography
|
||||
```css
|
||||
/* Font Stacks */
|
||||
--font-family-sans: system-ui, -apple-system, sans-serif;
|
||||
--font-family-mono: 'SF Mono', Monaco, 'Cascadia Code', monospace;
|
||||
|
||||
/* Type Scale */
|
||||
--font-size-xs: 0.75rem; /* 12px */
|
||||
--font-size-sm: 0.875rem; /* 14px */
|
||||
--font-size-base: 1rem; /* 16px */
|
||||
--font-size-lg: 1.125rem; /* 18px */
|
||||
--font-size-xl: 1.25rem; /* 20px */
|
||||
--font-size-2xl: 1.5rem; /* 24px */
|
||||
--font-size-3xl: 1.875rem; /* 30px */
|
||||
--font-size-4xl: 2.25rem; /* 36px */
|
||||
```
|
||||
|
||||
### Spacing System
|
||||
```css
|
||||
/* 8pt Grid System */
|
||||
--space-1: 0.25rem; /* 4px */
|
||||
--space-2: 0.5rem; /* 8px */
|
||||
--space-3: 0.75rem; /* 12px */
|
||||
--space-4: 1rem; /* 16px */
|
||||
--space-5: 1.25rem; /* 20px */
|
||||
--space-6: 1.5rem; /* 24px */
|
||||
--space-8: 2rem; /* 32px */
|
||||
--space-10: 2.5rem; /* 40px */
|
||||
--space-12: 3rem; /* 48px */
|
||||
--space-16: 4rem; /* 64px */
|
||||
--space-20: 5rem; /* 80px */
|
||||
```
|
||||
|
||||
## 🧩 Component Patterns
|
||||
|
||||
### BEM Methodology
|
||||
```css
|
||||
/* Block */
|
||||
.card { }
|
||||
|
||||
/* Element */
|
||||
.card__header { }
|
||||
.card__body { }
|
||||
.card__footer { }
|
||||
|
||||
/* Modifier */
|
||||
.card--large { }
|
||||
.card--featured { }
|
||||
.card__header--centered { }
|
||||
```
|
||||
|
||||
### Component States
|
||||
```css
|
||||
.button {
|
||||
/* Base styles */
|
||||
|
||||
&:hover { }
|
||||
&:focus { }
|
||||
&:active { }
|
||||
&:disabled { }
|
||||
|
||||
&[aria-pressed="true"] { }
|
||||
&[aria-expanded="true"] { }
|
||||
}
|
||||
```
|
||||
|
||||
## 📱 Responsive Design
|
||||
|
||||
### Breakpoints
|
||||
```css
|
||||
/* Mobile First Approach */
|
||||
--breakpoint-sm: 640px;
|
||||
--breakpoint-md: 768px;
|
||||
--breakpoint-lg: 1024px;
|
||||
--breakpoint-xl: 1280px;
|
||||
--breakpoint-2xl: 1536px;
|
||||
```
|
||||
|
||||
### Media Query Mixins
|
||||
```css
|
||||
@media (min-width: 768px) {
|
||||
/* Tablet and up */
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
/* Desktop and up */
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
/* Reduced motion accessibility */
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
/* Dark mode preferences */
|
||||
}
|
||||
```
|
||||
|
||||
## 🎯 Admin-Specific Extensions
|
||||
|
||||
### Admin Color Palette
|
||||
```css
|
||||
/* Admin Theme Colors */
|
||||
--admin-primary: #6366f1;
|
||||
--admin-secondary: #8b5cf6;
|
||||
--admin-success: #10b981;
|
||||
--admin-warning: #f59e0b;
|
||||
--admin-error: #ef4444;
|
||||
|
||||
/* Admin Neutral Palette */
|
||||
--admin-bg: #f8fafc;
|
||||
--admin-surface: #ffffff;
|
||||
--admin-border: #e2e8f0;
|
||||
--admin-text: #1e293b;
|
||||
--admin-text-muted: #64748b;
|
||||
```
|
||||
|
||||
### Admin Components
|
||||
```css
|
||||
/* Admin Layout */
|
||||
.admin-layout { }
|
||||
.admin-header { }
|
||||
.admin-nav { }
|
||||
.admin-main { }
|
||||
.admin-sidebar { }
|
||||
|
||||
/* Admin UI Components */
|
||||
.admin-card { }
|
||||
.admin-table { }
|
||||
.admin-button { }
|
||||
.admin-form { }
|
||||
.admin-stats { }
|
||||
```
|
||||
|
||||
## 🔧 Build Process
|
||||
|
||||
### CSS Processing
|
||||
1. **PostCSS** for modern CSS features
|
||||
2. **Autoprefixer** for browser compatibility
|
||||
3. **CSS Nano** for minification
|
||||
4. **PurgeCSS** for unused style removal
|
||||
|
||||
### Development Workflow
|
||||
```bash
|
||||
# Development with hot reload
|
||||
npm run dev
|
||||
|
||||
# Production build
|
||||
npm run build
|
||||
|
||||
# Watch for changes
|
||||
npm run watch
|
||||
```
|
||||
|
||||
## 📋 Best Practices
|
||||
|
||||
### Performance
|
||||
- Use CSS custom properties for theme values
|
||||
- Minimize selector specificity
|
||||
- Leverage cascade and inheritance
|
||||
- Use `contain` property for layout optimization
|
||||
- Implement critical CSS loading
|
||||
|
||||
### Maintainability
|
||||
- Follow BEM naming conventions
|
||||
- Keep components isolated and reusable
|
||||
- Use meaningful class names
|
||||
- Document complex selectors
|
||||
- Regular architecture reviews
|
||||
|
||||
### Accessibility
|
||||
- Ensure sufficient color contrast ratios
|
||||
- Support reduced motion preferences
|
||||
- Use semantic markup structure
|
||||
- Implement focus management
|
||||
- Test with assistive technologies
|
||||
|
||||
---
|
||||
|
||||
*For component examples and live demos, visit [Admin Style Guide](/admin/docs)*
|
||||
365
backups/docs-backup-20250731125004/design-system/foundations.md
Normal file
365
backups/docs-backup-20250731125004/design-system/foundations.md
Normal file
@@ -0,0 +1,365 @@
|
||||
# Design System Foundations
|
||||
|
||||
> Core design principles, tokens, and guidelines for consistent visual language.
|
||||
|
||||
## 🎨 Color System
|
||||
|
||||
### Primary Palette
|
||||
```css
|
||||
--color-primary: #6366f1; /* Indigo - Main brand color */
|
||||
--color-primary-50: #eef2ff; /* Lightest tint */
|
||||
--color-primary-100: #e0e7ff;
|
||||
--color-primary-200: #c7d2fe;
|
||||
--color-primary-300: #a5b4fc;
|
||||
--color-primary-400: #818cf8;
|
||||
--color-primary-500: #6366f1; /* Base */
|
||||
--color-primary-600: #4f46e5;
|
||||
--color-primary-700: #4338ca;
|
||||
--color-primary-800: #3730a3;
|
||||
--color-primary-900: #312e81; /* Darkest shade */
|
||||
```
|
||||
|
||||
### Semantic Colors
|
||||
```css
|
||||
/* Success - Green */
|
||||
--color-success: #10b981;
|
||||
--color-success-light: #d1fae5;
|
||||
--color-success-dark: #047857;
|
||||
|
||||
/* Warning - Amber */
|
||||
--color-warning: #f59e0b;
|
||||
--color-warning-light: #fef3c7;
|
||||
--color-warning-dark: #d97706;
|
||||
|
||||
/* Error - Red */
|
||||
--color-error: #ef4444;
|
||||
--color-error-light: #fee2e2;
|
||||
--color-error-dark: #dc2626;
|
||||
|
||||
/* Info - Blue */
|
||||
--color-info: #3b82f6;
|
||||
--color-info-light: #dbeafe;
|
||||
--color-info-dark: #1d4ed8;
|
||||
```
|
||||
|
||||
### Neutral Palette
|
||||
```css
|
||||
--color-gray-50: #f8fafc;
|
||||
--color-gray-100: #f1f5f9;
|
||||
--color-gray-200: #e2e8f0;
|
||||
--color-gray-300: #cbd5e1;
|
||||
--color-gray-400: #94a3b8;
|
||||
--color-gray-500: #64748b;
|
||||
--color-gray-600: #475569;
|
||||
--color-gray-700: #334155;
|
||||
--color-gray-800: #1e293b;
|
||||
--color-gray-900: #0f172a;
|
||||
```
|
||||
|
||||
## 📝 Typography
|
||||
|
||||
### Font Stacks
|
||||
```css
|
||||
/* Sans Serif - Primary */
|
||||
--font-family-sans: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
|
||||
|
||||
/* Monospace - Code */
|
||||
--font-family-mono: 'SF Mono', 'Monaco', 'Cascadia Code', 'Fira Code', monospace;
|
||||
|
||||
/* Serif - Optional */
|
||||
--font-family-serif: 'Charter', 'Georgia', 'Times New Roman', serif;
|
||||
```
|
||||
|
||||
### Type Scale
|
||||
```css
|
||||
/* Font Sizes (16px base) */
|
||||
--text-xs: 0.75rem; /* 12px */
|
||||
--text-sm: 0.875rem; /* 14px */
|
||||
--text-base: 1rem; /* 16px */
|
||||
--text-lg: 1.125rem; /* 18px */
|
||||
--text-xl: 1.25rem; /* 20px */
|
||||
--text-2xl: 1.5rem; /* 24px */
|
||||
--text-3xl: 1.875rem; /* 30px */
|
||||
--text-4xl: 2.25rem; /* 36px */
|
||||
--text-5xl: 3rem; /* 48px */
|
||||
--text-6xl: 3.75rem; /* 60px */
|
||||
--text-7xl: 4.5rem; /* 72px */
|
||||
--text-8xl: 6rem; /* 96px */
|
||||
--text-9xl: 8rem; /* 128px */
|
||||
```
|
||||
|
||||
### Font Weights
|
||||
```css
|
||||
--font-thin: 100;
|
||||
--font-extralight: 200;
|
||||
--font-light: 300;
|
||||
--font-normal: 400;
|
||||
--font-medium: 500;
|
||||
--font-semibold: 600;
|
||||
--font-bold: 700;
|
||||
--font-extrabold: 800;
|
||||
--font-black: 900;
|
||||
```
|
||||
|
||||
### Line Heights
|
||||
```css
|
||||
--leading-none: 1;
|
||||
--leading-tight: 1.25;
|
||||
--leading-snug: 1.375;
|
||||
--leading-normal: 1.5;
|
||||
--leading-relaxed: 1.625;
|
||||
--leading-loose: 2;
|
||||
```
|
||||
|
||||
## 📏 Spacing System
|
||||
|
||||
### Base Unit: 4px
|
||||
```css
|
||||
--space-0: 0;
|
||||
--space-px: 1px;
|
||||
--space-0-5: 0.125rem; /* 2px */
|
||||
--space-1: 0.25rem; /* 4px */
|
||||
--space-1-5: 0.375rem; /* 6px */
|
||||
--space-2: 0.5rem; /* 8px */
|
||||
--space-2-5: 0.625rem; /* 10px */
|
||||
--space-3: 0.75rem; /* 12px */
|
||||
--space-3-5: 0.875rem; /* 14px */
|
||||
--space-4: 1rem; /* 16px */
|
||||
--space-5: 1.25rem; /* 20px */
|
||||
--space-6: 1.5rem; /* 24px */
|
||||
--space-7: 1.75rem; /* 28px */
|
||||
--space-8: 2rem; /* 32px */
|
||||
--space-9: 2.25rem; /* 36px */
|
||||
--space-10: 2.5rem; /* 40px */
|
||||
--space-11: 2.75rem; /* 44px */
|
||||
--space-12: 3rem; /* 48px */
|
||||
--space-14: 3.5rem; /* 56px */
|
||||
--space-16: 4rem; /* 64px */
|
||||
--space-20: 5rem; /* 80px */
|
||||
--space-24: 6rem; /* 96px */
|
||||
--space-28: 7rem; /* 112px */
|
||||
--space-32: 8rem; /* 128px */
|
||||
--space-36: 9rem; /* 144px */
|
||||
--space-40: 10rem; /* 160px */
|
||||
--space-44: 11rem; /* 176px */
|
||||
--space-48: 12rem; /* 192px */
|
||||
--space-52: 13rem; /* 208px */
|
||||
--space-56: 14rem; /* 224px */
|
||||
--space-60: 15rem; /* 240px */
|
||||
--space-64: 16rem; /* 256px */
|
||||
--space-72: 18rem; /* 288px */
|
||||
--space-80: 20rem; /* 320px */
|
||||
--space-96: 24rem; /* 384px */
|
||||
```
|
||||
|
||||
## 🔲 Border Radius
|
||||
|
||||
```css
|
||||
--radius-none: 0;
|
||||
--radius-sm: 0.125rem; /* 2px */
|
||||
--radius: 0.25rem; /* 4px */
|
||||
--radius-md: 0.375rem; /* 6px */
|
||||
--radius-lg: 0.5rem; /* 8px */
|
||||
--radius-xl: 0.75rem; /* 12px */
|
||||
--radius-2xl: 1rem; /* 16px */
|
||||
--radius-3xl: 1.5rem; /* 24px */
|
||||
--radius-full: 9999px; /* Pill shape */
|
||||
```
|
||||
|
||||
## 🌫 Shadows & Elevation
|
||||
|
||||
```css
|
||||
/* Box Shadows */
|
||||
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
||||
--shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
||||
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
||||
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
||||
--shadow-2xl: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
||||
--shadow-inner: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06);
|
||||
|
||||
/* Colored Shadows */
|
||||
--shadow-primary: 0 4px 14px 0 rgba(99, 102, 241, 0.15);
|
||||
--shadow-success: 0 4px 14px 0 rgba(16, 185, 129, 0.15);
|
||||
--shadow-warning: 0 4px 14px 0 rgba(245, 158, 11, 0.15);
|
||||
--shadow-error: 0 4px 14px 0 rgba(239, 68, 68, 0.15);
|
||||
```
|
||||
|
||||
## 📐 Layout & Grid
|
||||
|
||||
### Breakpoints
|
||||
```css
|
||||
--breakpoint-sm: 640px; /* Small tablets */
|
||||
--breakpoint-md: 768px; /* Large tablets */
|
||||
--breakpoint-lg: 1024px; /* Laptops */
|
||||
--breakpoint-xl: 1280px; /* Desktops */
|
||||
--breakpoint-2xl: 1536px; /* Large desktops */
|
||||
```
|
||||
|
||||
### Container Sizes
|
||||
```css
|
||||
--container-sm: 640px;
|
||||
--container-md: 768px;
|
||||
--container-lg: 1024px;
|
||||
--container-xl: 1280px;
|
||||
--container-2xl: 1536px;
|
||||
```
|
||||
|
||||
### Z-Index Scale
|
||||
```css
|
||||
--z-auto: auto;
|
||||
--z-0: 0;
|
||||
--z-10: 10;
|
||||
--z-20: 20;
|
||||
--z-30: 30;
|
||||
--z-40: 40;
|
||||
--z-50: 50;
|
||||
|
||||
/* Named layers */
|
||||
--z-dropdown: 1000;
|
||||
--z-sticky: 1020;
|
||||
--z-fixed: 1030;
|
||||
--z-modal-backdrop: 1040;
|
||||
--z-modal: 1050;
|
||||
--z-popover: 1060;
|
||||
--z-tooltip: 1070;
|
||||
--z-toast: 1080;
|
||||
```
|
||||
|
||||
## ⏱ Motion & Animation
|
||||
|
||||
### Duration
|
||||
```css
|
||||
--duration-75: 75ms;
|
||||
--duration-100: 100ms;
|
||||
--duration-150: 150ms;
|
||||
--duration-200: 200ms;
|
||||
--duration-300: 300ms;
|
||||
--duration-500: 500ms;
|
||||
--duration-700: 700ms;
|
||||
--duration-1000: 1000ms;
|
||||
```
|
||||
|
||||
### Easing Functions
|
||||
```css
|
||||
--ease-linear: linear;
|
||||
--ease-in: cubic-bezier(0.4, 0, 1, 1);
|
||||
--ease-out: cubic-bezier(0, 0, 0.2, 1);
|
||||
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
|
||||
/* Custom easing */
|
||||
--ease-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
||||
--ease-smooth: cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
```
|
||||
|
||||
## 🎭 Theme System
|
||||
|
||||
### Light Theme (Default)
|
||||
```css
|
||||
:root {
|
||||
--background: var(--color-gray-50);
|
||||
--surface: #ffffff;
|
||||
--surface-variant: var(--color-gray-100);
|
||||
--border: var(--color-gray-200);
|
||||
--text-primary: var(--color-gray-900);
|
||||
--text-secondary: var(--color-gray-600);
|
||||
--text-muted: var(--color-gray-500);
|
||||
--text-disabled: var(--color-gray-400);
|
||||
}
|
||||
```
|
||||
|
||||
### Dark Theme
|
||||
```css
|
||||
[data-theme="dark"] {
|
||||
--background: var(--color-gray-900);
|
||||
--surface: var(--color-gray-800);
|
||||
--surface-variant: var(--color-gray-700);
|
||||
--border: var(--color-gray-600);
|
||||
--text-primary: var(--color-gray-50);
|
||||
--text-secondary: var(--color-gray-300);
|
||||
--text-muted: var(--color-gray-400);
|
||||
--text-disabled: var(--color-gray-500);
|
||||
|
||||
/* Adjust shadows for dark mode */
|
||||
--shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.3), 0 1px 2px 0 rgba(0, 0, 0, 0.2);
|
||||
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.3), 0 2px 4px -1px rgba(0, 0, 0, 0.2);
|
||||
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.3), 0 4px 6px -2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 Usage Guidelines
|
||||
|
||||
### Semantic Token Usage
|
||||
|
||||
```css
|
||||
/* Use semantic tokens for meaning */
|
||||
.success-message {
|
||||
color: var(--color-success);
|
||||
background: var(--color-success-light);
|
||||
border-color: var(--color-success);
|
||||
}
|
||||
|
||||
/* Use scale tokens for consistency */
|
||||
.card {
|
||||
padding: var(--space-6);
|
||||
border-radius: var(--radius-lg);
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
|
||||
/* Use theme tokens for adaptability */
|
||||
.content {
|
||||
background: var(--surface);
|
||||
color: var(--text-primary);
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
```
|
||||
|
||||
### Responsive Design
|
||||
|
||||
```css
|
||||
/* Mobile first approach */
|
||||
.component {
|
||||
padding: var(--space-4);
|
||||
font-size: var(--text-sm);
|
||||
|
||||
@media (min-width: 768px) {
|
||||
padding: var(--space-6);
|
||||
font-size: var(--text-base);
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
padding: var(--space-8);
|
||||
font-size: var(--text-lg);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Accessibility Considerations
|
||||
|
||||
```css
|
||||
/* Ensure sufficient contrast */
|
||||
.text-on-primary {
|
||||
color: white; /* Passes WCAG AA on primary blue */
|
||||
}
|
||||
|
||||
/* Respect motion preferences */
|
||||
.animated-element {
|
||||
transition: transform var(--duration-300) var(--ease-out);
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Focus indicators */
|
||||
.interactive-element:focus-visible {
|
||||
outline: 2px solid var(--color-primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*For implementation examples, see [CSS Architecture](css-architecture.md)*
|
||||
*For component usage, see [UI Components](components.md)*
|
||||
*For admin-specific patterns, see [Admin Interface](admin/overview.md)*
|
||||
642
backups/docs-backup-20250731125004/design-system/javascript.md
Normal file
642
backups/docs-backup-20250731125004/design-system/javascript.md
Normal file
@@ -0,0 +1,642 @@
|
||||
# JavaScript Module System
|
||||
|
||||
> Modern ES6+ modular JavaScript architecture with performance monitoring, state management, and component-based UI interactions.
|
||||
|
||||
## 📁 Module Structure
|
||||
|
||||
```
|
||||
resources/js/
|
||||
├── main.js # Entry point
|
||||
├── core/ # Core framework modules
|
||||
│ ├── index.js # Core exports
|
||||
│ ├── init.js # Initialization
|
||||
│ ├── router.js # SPA routing
|
||||
│ ├── state.js # State management
|
||||
│ ├── EventManager.js # Event system
|
||||
│ ├── PerformanceMonitor.js # Performance tracking
|
||||
│ └── logger.js # Logging utilities
|
||||
├── modules/ # Feature modules
|
||||
│ ├── index.js # Module registry
|
||||
│ ├── ui/ # UI components
|
||||
│ │ ├── UIManager.js # UI coordinator
|
||||
│ │ └── components/ # Individual components
|
||||
│ ├── scroll-fx/ # Scroll animations
|
||||
│ ├── lightbox/ # Image lightbox
|
||||
│ └── parallax/ # Parallax effects
|
||||
├── utils/ # Utility functions
|
||||
└── docs/ # Module documentation
|
||||
```
|
||||
|
||||
## 🚀 Core System
|
||||
|
||||
### Application Initialization
|
||||
|
||||
```javascript
|
||||
// main.js - Application entry point
|
||||
import { init } from './core/init.js';
|
||||
import { ModuleRegistry } from './modules/index.js';
|
||||
|
||||
// Initialize core systems
|
||||
await init({
|
||||
performance: true,
|
||||
router: true,
|
||||
state: true,
|
||||
logging: 'development'
|
||||
});
|
||||
|
||||
// Register and load modules
|
||||
ModuleRegistry.register('ui', () => import('./modules/ui/index.js'));
|
||||
ModuleRegistry.register('scrollfx', () => import('./modules/scrollfx/index.js'));
|
||||
|
||||
// Auto-load modules based on DOM attributes
|
||||
ModuleRegistry.autoLoad();
|
||||
```
|
||||
|
||||
### Router System
|
||||
|
||||
```javascript
|
||||
// SPA routing with layout animations
|
||||
import { Router } from './core/router.js';
|
||||
|
||||
const router = new Router({
|
||||
mode: 'history',
|
||||
base: '/',
|
||||
transitions: true,
|
||||
prefetch: true
|
||||
});
|
||||
|
||||
// Route definitions
|
||||
router.addRoute('/admin/:page?', async (ctx) => {
|
||||
const { page = 'dashboard' } = ctx.params;
|
||||
|
||||
// Layout animation
|
||||
if (ctx.isLayoutChange) {
|
||||
await animateLayoutSwitch('admin');
|
||||
}
|
||||
|
||||
// Load page content
|
||||
return await loadAdminPage(page);
|
||||
});
|
||||
|
||||
// Meta data extraction from HTML
|
||||
router.onNavigate((ctx) => {
|
||||
// Extract and apply meta data
|
||||
const metaTitle = ctx.dom.querySelector('[data-meta-title]');
|
||||
if (metaTitle) {
|
||||
document.title = metaTitle.dataset.metaTitle;
|
||||
}
|
||||
|
||||
const metaTheme = ctx.dom.querySelector('[data-meta-theme]');
|
||||
if (metaTheme) {
|
||||
document.documentElement.style.setProperty('--theme-color', metaTheme.dataset.metaTheme);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### State Management
|
||||
|
||||
```javascript
|
||||
// Reactive state system
|
||||
import { State } from './core/state.js';
|
||||
|
||||
// Global state
|
||||
const appState = new State({
|
||||
user: null,
|
||||
theme: 'light',
|
||||
admin: {
|
||||
currentPage: 'dashboard',
|
||||
notifications: []
|
||||
}
|
||||
});
|
||||
|
||||
// Reactive updates
|
||||
appState.watch('theme', (newTheme, oldTheme) => {
|
||||
document.documentElement.dataset.theme = newTheme;
|
||||
localStorage.setItem('preferred-theme', newTheme);
|
||||
});
|
||||
|
||||
// Component state binding
|
||||
appState.bind('[data-user-name]', 'user.name');
|
||||
appState.bind('[data-notification-count]', 'admin.notifications.length');
|
||||
```
|
||||
|
||||
### Event System
|
||||
|
||||
```javascript
|
||||
// Centralized event management
|
||||
import { EventManager } from './core/EventManager.js';
|
||||
|
||||
const events = new EventManager();
|
||||
|
||||
// Global event delegation
|
||||
events.delegate('click', '[data-action]', (event, element) => {
|
||||
const action = element.dataset.action;
|
||||
const target = element.dataset.target;
|
||||
|
||||
switch (action) {
|
||||
case 'toggle-theme':
|
||||
appState.set('theme', appState.get('theme') === 'light' ? 'dark' : 'light');
|
||||
break;
|
||||
case 'show-modal':
|
||||
UIManager.showModal(target);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
// Custom events
|
||||
events.on('admin:page-change', (data) => {
|
||||
appState.set('admin.currentPage', data.page);
|
||||
PerformanceMonitor.mark(`admin-${data.page}-loaded`);
|
||||
});
|
||||
```
|
||||
|
||||
## 🧩 UI Component System
|
||||
|
||||
### Component Architecture
|
||||
|
||||
```javascript
|
||||
// Base component class
|
||||
class BaseComponent {
|
||||
constructor(element, options = {}) {
|
||||
this.element = element;
|
||||
this.options = { ...this.defaults, ...options };
|
||||
this.state = new State(this.initialState);
|
||||
|
||||
this.init();
|
||||
this.bindEvents();
|
||||
}
|
||||
|
||||
init() {
|
||||
// Override in subclasses
|
||||
}
|
||||
|
||||
bindEvents() {
|
||||
// Override in subclasses
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.state.destroy();
|
||||
this.element.removeEventListener();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Modal Component
|
||||
|
||||
```javascript
|
||||
// UI Modal component
|
||||
class Modal extends BaseComponent {
|
||||
defaults = {
|
||||
closeOnOverlay: true,
|
||||
closeOnEscape: true,
|
||||
animation: 'fade'
|
||||
};
|
||||
|
||||
initialState = {
|
||||
isOpen: false,
|
||||
content: null
|
||||
};
|
||||
|
||||
init() {
|
||||
this.overlay = this.element.querySelector('.modal-overlay');
|
||||
this.content = this.element.querySelector('.modal-content');
|
||||
this.closeBtn = this.element.querySelector('[data-modal-close]');
|
||||
|
||||
// State reactivity
|
||||
this.state.watch('isOpen', (isOpen) => {
|
||||
this.element.classList.toggle('is-open', isOpen);
|
||||
this.element.setAttribute('aria-hidden', !isOpen);
|
||||
|
||||
if (isOpen) {
|
||||
this.trapFocus();
|
||||
} else {
|
||||
this.releaseFocus();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bindEvents() {
|
||||
if (this.closeBtn) {
|
||||
this.closeBtn.addEventListener('click', () => this.close());
|
||||
}
|
||||
|
||||
if (this.options.closeOnOverlay) {
|
||||
this.overlay.addEventListener('click', () => this.close());
|
||||
}
|
||||
|
||||
if (this.options.closeOnEscape) {
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape' && this.state.get('isOpen')) {
|
||||
this.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
open(content = null) {
|
||||
if (content) {
|
||||
this.setContent(content);
|
||||
}
|
||||
this.state.set('isOpen', true);
|
||||
events.emit('modal:opened', { modal: this });
|
||||
}
|
||||
|
||||
close() {
|
||||
this.state.set('isOpen', false);
|
||||
events.emit('modal:closed', { modal: this });
|
||||
}
|
||||
|
||||
setContent(content) {
|
||||
if (typeof content === 'string') {
|
||||
this.content.innerHTML = content;
|
||||
} else if (content instanceof HTMLElement) {
|
||||
this.content.innerHTML = '';
|
||||
this.content.appendChild(content);
|
||||
}
|
||||
this.state.set('content', content);
|
||||
}
|
||||
}
|
||||
|
||||
// Auto-initialization
|
||||
document.querySelectorAll('[data-modal]').forEach(element => {
|
||||
new Modal(element);
|
||||
});
|
||||
```
|
||||
|
||||
### Admin-specific Components
|
||||
|
||||
```javascript
|
||||
// Admin Stats Card
|
||||
class AdminStatsCard extends BaseComponent {
|
||||
defaults = {
|
||||
updateInterval: 30000,
|
||||
animateChanges: true
|
||||
};
|
||||
|
||||
init() {
|
||||
this.valueElement = this.element.querySelector('.stat-value');
|
||||
this.labelElement = this.element.querySelector('.stat-label');
|
||||
this.trendElement = this.element.querySelector('.stat-trend');
|
||||
|
||||
if (this.options.updateInterval) {
|
||||
this.startPolling();
|
||||
}
|
||||
}
|
||||
|
||||
startPolling() {
|
||||
this.pollInterval = setInterval(() => {
|
||||
this.updateValue();
|
||||
}, this.options.updateInterval);
|
||||
}
|
||||
|
||||
async updateValue() {
|
||||
const endpoint = this.element.dataset.endpoint;
|
||||
if (!endpoint) return;
|
||||
|
||||
try {
|
||||
const response = await fetch(endpoint);
|
||||
const data = await response.json();
|
||||
|
||||
if (this.options.animateChanges) {
|
||||
this.animateValueChange(data.value);
|
||||
} else {
|
||||
this.setValue(data.value);
|
||||
}
|
||||
|
||||
if (data.trend) {
|
||||
this.setTrend(data.trend);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to update stat:', error);
|
||||
}
|
||||
}
|
||||
|
||||
animateValueChange(newValue) {
|
||||
const currentValue = parseInt(this.valueElement.textContent) || 0;
|
||||
const duration = 1000;
|
||||
const steps = 60;
|
||||
const increment = (newValue - currentValue) / steps;
|
||||
|
||||
let step = 0;
|
||||
const timer = setInterval(() => {
|
||||
step++;
|
||||
const value = Math.round(currentValue + (increment * step));
|
||||
this.valueElement.textContent = value.toLocaleString();
|
||||
|
||||
if (step >= steps) {
|
||||
clearInterval(timer);
|
||||
this.valueElement.textContent = newValue.toLocaleString();
|
||||
}
|
||||
}, duration / steps);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 Performance Monitoring
|
||||
|
||||
```javascript
|
||||
// Performance tracking
|
||||
import { PerformanceMonitor } from './core/PerformanceMonitor.js';
|
||||
|
||||
// Page load metrics
|
||||
PerformanceMonitor.mark('page-start');
|
||||
PerformanceMonitor.measure('page-load', 'page-start', 'page-end');
|
||||
|
||||
// Component performance
|
||||
class ComponentWithMetrics extends BaseComponent {
|
||||
init() {
|
||||
PerformanceMonitor.mark(`${this.constructor.name}-init-start`);
|
||||
|
||||
// Component initialization
|
||||
super.init();
|
||||
|
||||
PerformanceMonitor.mark(`${this.constructor.name}-init-end`);
|
||||
PerformanceMonitor.measure(
|
||||
`${this.constructor.name}-init`,
|
||||
`${this.constructor.name}-init-start`,
|
||||
`${this.constructor.name}-init-end`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Performance reporting
|
||||
PerformanceMonitor.report((metrics) => {
|
||||
// Send to analytics
|
||||
if (window.gtag) {
|
||||
gtag('event', 'performance_metric', {
|
||||
custom_map: { metric_name: 'custom_metric_name' },
|
||||
metric_name: metrics.name,
|
||||
value: metrics.duration
|
||||
});
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## 🎨 Admin Interface Integration
|
||||
|
||||
### Theme System
|
||||
|
||||
```javascript
|
||||
// Admin theme management
|
||||
class AdminThemeManager {
|
||||
constructor() {
|
||||
this.themes = ['light', 'dark', 'auto'];
|
||||
this.currentTheme = localStorage.getItem('admin-theme') || 'auto';
|
||||
this.mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
this.applyTheme(this.currentTheme);
|
||||
this.bindEvents();
|
||||
}
|
||||
|
||||
bindEvents() {
|
||||
// Theme toggle button
|
||||
document.addEventListener('click', (e) => {
|
||||
if (e.target.matches('[data-theme-toggle]')) {
|
||||
this.toggleTheme();
|
||||
}
|
||||
});
|
||||
|
||||
// System theme changes
|
||||
this.mediaQuery.addEventListener('change', () => {
|
||||
if (this.currentTheme === 'auto') {
|
||||
this.applyTheme('auto');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
applyTheme(theme) {
|
||||
let resolvedTheme = theme;
|
||||
|
||||
if (theme === 'auto') {
|
||||
resolvedTheme = this.mediaQuery.matches ? 'dark' : 'light';
|
||||
}
|
||||
|
||||
document.documentElement.dataset.theme = resolvedTheme;
|
||||
document.documentElement.style.setProperty('--theme-preference', theme);
|
||||
|
||||
// Update theme color meta tag
|
||||
const metaThemeColor = document.querySelector('meta[name="theme-color"]');
|
||||
if (metaThemeColor) {
|
||||
const color = resolvedTheme === 'dark' ? '#1e293b' : '#ffffff';
|
||||
metaThemeColor.setAttribute('content', color);
|
||||
}
|
||||
}
|
||||
|
||||
toggleTheme() {
|
||||
const currentIndex = this.themes.indexOf(this.currentTheme);
|
||||
const nextIndex = (currentIndex + 1) % this.themes.length;
|
||||
const nextTheme = this.themes[nextIndex];
|
||||
|
||||
this.setTheme(nextTheme);
|
||||
}
|
||||
|
||||
setTheme(theme) {
|
||||
this.currentTheme = theme;
|
||||
localStorage.setItem('admin-theme', theme);
|
||||
this.applyTheme(theme);
|
||||
|
||||
events.emit('theme:changed', { theme, resolvedTheme: this.getResolvedTheme() });
|
||||
}
|
||||
|
||||
getResolvedTheme() {
|
||||
if (this.currentTheme === 'auto') {
|
||||
return this.mediaQuery.matches ? 'dark' : 'light';
|
||||
}
|
||||
return this.currentTheme;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize admin theme
|
||||
new AdminThemeManager();
|
||||
```
|
||||
|
||||
### Data Tables
|
||||
|
||||
```javascript
|
||||
// Admin data table component
|
||||
class AdminDataTable extends BaseComponent {
|
||||
defaults = {
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
paginated: true,
|
||||
pageSize: 25
|
||||
};
|
||||
|
||||
init() {
|
||||
this.table = this.element.querySelector('table');
|
||||
this.tbody = this.table.querySelector('tbody');
|
||||
this.headers = [...this.table.querySelectorAll('th[data-sort]')];
|
||||
this.filterInput = this.element.querySelector('[data-table-filter]');
|
||||
|
||||
this.data = this.extractData();
|
||||
this.filteredData = [...this.data];
|
||||
this.currentSort = { column: null, direction: 'asc' };
|
||||
this.currentPage = 1;
|
||||
|
||||
this.bindEvents();
|
||||
this.render();
|
||||
}
|
||||
|
||||
bindEvents() {
|
||||
// Column sorting
|
||||
this.headers.forEach(header => {
|
||||
header.addEventListener('click', () => {
|
||||
const column = header.dataset.sort;
|
||||
this.sort(column);
|
||||
});
|
||||
});
|
||||
|
||||
// Filtering
|
||||
if (this.filterInput) {
|
||||
this.filterInput.addEventListener('input', debounce(() => {
|
||||
this.filter(this.filterInput.value);
|
||||
}, 300));
|
||||
}
|
||||
}
|
||||
|
||||
sort(column) {
|
||||
if (this.currentSort.column === column) {
|
||||
this.currentSort.direction = this.currentSort.direction === 'asc' ? 'desc' : 'asc';
|
||||
} else {
|
||||
this.currentSort.column = column;
|
||||
this.currentSort.direction = 'asc';
|
||||
}
|
||||
|
||||
this.filteredData.sort((a, b) => {
|
||||
const aVal = a[column];
|
||||
const bVal = b[column];
|
||||
const modifier = this.currentSort.direction === 'asc' ? 1 : -1;
|
||||
|
||||
if (aVal < bVal) return -1 * modifier;
|
||||
if (aVal > bVal) return 1 * modifier;
|
||||
return 0;
|
||||
});
|
||||
|
||||
this.currentPage = 1;
|
||||
this.render();
|
||||
}
|
||||
|
||||
filter(query) {
|
||||
if (!query) {
|
||||
this.filteredData = [...this.data];
|
||||
} else {
|
||||
const searchTerm = query.toLowerCase();
|
||||
this.filteredData = this.data.filter(row => {
|
||||
return Object.values(row).some(value =>
|
||||
String(value).toLowerCase().includes(searchTerm)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
this.currentPage = 1;
|
||||
this.render();
|
||||
}
|
||||
|
||||
render() {
|
||||
// Update table body
|
||||
this.renderTableBody();
|
||||
|
||||
// Update sort indicators
|
||||
this.updateSortIndicators();
|
||||
|
||||
// Update pagination
|
||||
if (this.options.paginated) {
|
||||
this.renderPagination();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔧 Utility Functions
|
||||
|
||||
```javascript
|
||||
// Common utility functions
|
||||
export const utils = {
|
||||
// Debounce function calls
|
||||
debounce(func, wait) {
|
||||
let timeout;
|
||||
return function executedFunction(...args) {
|
||||
const later = () => {
|
||||
clearTimeout(timeout);
|
||||
func(...args);
|
||||
};
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(later, wait);
|
||||
};
|
||||
},
|
||||
|
||||
// Throttle function calls
|
||||
throttle(func, limit) {
|
||||
let inThrottle;
|
||||
return function(...args) {
|
||||
if (!inThrottle) {
|
||||
func.apply(this, args);
|
||||
inThrottle = true;
|
||||
setTimeout(() => inThrottle = false, limit);
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
// DOM manipulation helpers
|
||||
dom: {
|
||||
ready(fn) {
|
||||
if (document.readyState !== 'loading') {
|
||||
fn();
|
||||
} else {
|
||||
document.addEventListener('DOMContentLoaded', fn);
|
||||
}
|
||||
},
|
||||
|
||||
create(tag, attributes = {}, children = []) {
|
||||
const element = document.createElement(tag);
|
||||
|
||||
Object.entries(attributes).forEach(([key, value]) => {
|
||||
if (key === 'className') {
|
||||
element.className = value;
|
||||
} else if (key.startsWith('data-')) {
|
||||
element.dataset[key.slice(5)] = value;
|
||||
} else {
|
||||
element.setAttribute(key, value);
|
||||
}
|
||||
});
|
||||
|
||||
children.forEach(child => {
|
||||
if (typeof child === 'string') {
|
||||
element.appendChild(document.createTextNode(child));
|
||||
} else {
|
||||
element.appendChild(child);
|
||||
}
|
||||
});
|
||||
|
||||
return element;
|
||||
}
|
||||
},
|
||||
|
||||
// Format utilities
|
||||
format: {
|
||||
bytes(bytes, decimals = 2) {
|
||||
if (bytes === 0) return '0 Bytes';
|
||||
const k = 1024;
|
||||
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(decimals)) + ' ' + sizes[i];
|
||||
},
|
||||
|
||||
duration(ms) {
|
||||
if (ms < 1000) return `${ms}ms`;
|
||||
if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
|
||||
return `${(ms / 60000).toFixed(1)}m`;
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*For specific module documentation, see individual files in `/resources/js/docs/`*
|
||||
*For performance optimization, see [Performance Guidelines](../development/performance.md)*
|
||||
*For component integration, see [UI Components](components.md)*
|
||||
260
backups/docs-backup-20250731125004/development/performance.md
Normal file
260
backups/docs-backup-20250731125004/development/performance.md
Normal file
@@ -0,0 +1,260 @@
|
||||
# Performance Guidelines
|
||||
|
||||
> Optimization strategies and best practices for frontend and backend performance.
|
||||
|
||||
## 🚀 Frontend Performance
|
||||
|
||||
### JavaScript Performance
|
||||
|
||||
#### Bundle Optimization
|
||||
- **Code Splitting**: Split code into smaller chunks
|
||||
- **Tree Shaking**: Remove unused code from bundles
|
||||
- **Module Loading**: Use dynamic imports for non-critical code
|
||||
|
||||
```javascript
|
||||
// Dynamic imports for better performance
|
||||
const LazyComponent = lazy(() => import('./LazyComponent.js'));
|
||||
|
||||
// Code splitting by route
|
||||
const AdminPanel = lazy(() => import('./admin/AdminPanel.js'));
|
||||
```
|
||||
|
||||
#### Runtime Performance
|
||||
- **Debouncing/Throttling**: Limit expensive operations
|
||||
- **Virtual Scrolling**: Handle large datasets efficiently
|
||||
- **Memory Management**: Prevent memory leaks
|
||||
|
||||
```javascript
|
||||
// Debounced search
|
||||
const debouncedSearch = debounce((query) => {
|
||||
performSearch(query);
|
||||
}, 300);
|
||||
|
||||
// Throttled scroll handler
|
||||
const throttledScroll = throttle(() => {
|
||||
updateScrollPosition();
|
||||
}, 16); // ~60fps
|
||||
```
|
||||
|
||||
### CSS Performance
|
||||
|
||||
#### Critical CSS
|
||||
- Inline critical CSS for above-the-fold content
|
||||
- Load non-critical CSS asynchronously
|
||||
- Use CSS containment for performance isolation
|
||||
|
||||
```css
|
||||
/* Critical CSS - inline in <head> */
|
||||
.hero-section {
|
||||
contain: layout style paint;
|
||||
/* Critical styles only */
|
||||
}
|
||||
|
||||
/* Non-critical CSS - load async */
|
||||
@import url('non-critical.css') (min-width: 768px);
|
||||
```
|
||||
|
||||
#### Efficient Selectors
|
||||
- Avoid complex selector chains
|
||||
- Use class selectors over tag selectors
|
||||
- Minimize reflows and repaints
|
||||
|
||||
```css
|
||||
/* Efficient */
|
||||
.card-title { color: var(--text-primary); }
|
||||
|
||||
/* Inefficient */
|
||||
.card .content .title h2 { color: var(--text-primary); }
|
||||
```
|
||||
|
||||
### Asset Optimization
|
||||
|
||||
#### Image Optimization
|
||||
- Use appropriate formats (WebP, AVIF)
|
||||
- Implement responsive images
|
||||
- Add loading="lazy" for below-fold images
|
||||
|
||||
```html
|
||||
<!-- Responsive images -->
|
||||
<picture>
|
||||
<source srcset="image.avif" type="image/avif">
|
||||
<source srcset="image.webp" type="image/webp">
|
||||
<img src="image.jpg" alt="Description" loading="lazy">
|
||||
</picture>
|
||||
```
|
||||
|
||||
#### Font Loading
|
||||
- Use font-display: swap
|
||||
- Preload critical fonts
|
||||
- Subset fonts to reduce file size
|
||||
|
||||
```css
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-display: swap;
|
||||
src: url('inter-subset.woff2') format('woff2');
|
||||
}
|
||||
```
|
||||
|
||||
## ⚡ Backend Performance
|
||||
|
||||
### Database Optimization
|
||||
|
||||
#### Query Optimization
|
||||
- Use indexes effectively
|
||||
- Avoid N+1 queries with eager loading
|
||||
- Implement connection pooling
|
||||
|
||||
```php
|
||||
// Eager loading to prevent N+1
|
||||
$users = $userRepository->findWithProfiles();
|
||||
|
||||
// Use database indexes
|
||||
$users = $userRepository->findByEmailIndex('user@example.com');
|
||||
```
|
||||
|
||||
#### Caching Strategies
|
||||
- Redis for session and cache storage
|
||||
- Database query result caching
|
||||
- Fragment caching for expensive operations
|
||||
|
||||
```php
|
||||
// Cache expensive operations
|
||||
$result = $cache->remember('expensive-calculation', 3600, function() {
|
||||
return performExpensiveCalculation();
|
||||
});
|
||||
```
|
||||
|
||||
### HTTP Performance
|
||||
|
||||
#### Response Optimization
|
||||
- Enable gzip/brotli compression
|
||||
- Set appropriate cache headers
|
||||
- Use CDN for static assets
|
||||
|
||||
```php
|
||||
// Set cache headers
|
||||
$response->headers->set('Cache-Control', 'public, max-age=3600');
|
||||
$response->headers->set('ETag', $etag);
|
||||
```
|
||||
|
||||
#### Connection Management
|
||||
- HTTP/2 server push for critical resources
|
||||
- Connection keep-alive
|
||||
- Reduce HTTP requests through bundling
|
||||
|
||||
## 📊 Performance Monitoring
|
||||
|
||||
### Metrics Collection
|
||||
|
||||
#### Core Web Vitals
|
||||
- **LCP**: Largest Contentful Paint < 2.5s
|
||||
- **FID**: First Input Delay < 100ms
|
||||
- **CLS**: Cumulative Layout Shift < 0.1
|
||||
|
||||
```javascript
|
||||
// Measure Core Web Vitals
|
||||
import { getCLS, getFID, getLCP } from 'web-vitals';
|
||||
|
||||
getCLS(console.log);
|
||||
getFID(console.log);
|
||||
getLCP(console.log);
|
||||
```
|
||||
|
||||
#### Custom Metrics
|
||||
- Time to Interactive (TTI)
|
||||
- First Contentful Paint (FCP)
|
||||
- Resource loading times
|
||||
|
||||
```javascript
|
||||
// Custom performance marks
|
||||
performance.mark('feature-start');
|
||||
// ... feature implementation
|
||||
performance.mark('feature-end');
|
||||
performance.measure('feature-load', 'feature-start', 'feature-end');
|
||||
```
|
||||
|
||||
### Performance Budget
|
||||
|
||||
#### Resource Budgets
|
||||
- JavaScript: < 170KB gzipped
|
||||
- CSS: < 50KB gzipped
|
||||
- Images: < 500KB per page
|
||||
- Total page weight: < 1MB
|
||||
|
||||
#### Timing Budgets
|
||||
- First Byte: < 600ms
|
||||
- First Contentful Paint: < 1.5s
|
||||
- Largest Contentful Paint: < 2.5s
|
||||
- Time to Interactive: < 3.8s
|
||||
|
||||
## 🔧 Tools & Testing
|
||||
|
||||
### Development Tools
|
||||
- **Lighthouse**: Automated performance auditing
|
||||
- **WebPageTest**: Real-world performance testing
|
||||
- **Chrome DevTools**: Performance profiling
|
||||
|
||||
### Continuous Monitoring
|
||||
- **Real User Monitoring (RUM)**: Actual user performance data
|
||||
- **Synthetic Monitoring**: Automated performance tests
|
||||
- **Performance Budgets**: CI/CD integration
|
||||
|
||||
```javascript
|
||||
// Performance budget in CI
|
||||
const budget = {
|
||||
resourceSizes: [
|
||||
{ resourceType: 'script', budget: 170 },
|
||||
{ resourceType: 'total', budget: 1000 }
|
||||
],
|
||||
resourceCounts: [
|
||||
{ resourceType: 'third-party', budget: 10 }
|
||||
]
|
||||
};
|
||||
```
|
||||
|
||||
## 🎯 Optimization Checklist
|
||||
|
||||
### Frontend Checklist
|
||||
- [ ] Critical CSS inlined
|
||||
- [ ] JavaScript code split and lazy loaded
|
||||
- [ ] Images optimized and responsive
|
||||
- [ ] Fonts preloaded and optimized
|
||||
- [ ] Service Worker implemented
|
||||
- [ ] Performance metrics tracked
|
||||
|
||||
### Backend Checklist
|
||||
- [ ] Database queries optimized
|
||||
- [ ] Caching strategy implemented
|
||||
- [ ] HTTP compression enabled
|
||||
- [ ] CDN configured for static assets
|
||||
- [ ] Database connections pooled
|
||||
- [ ] Server monitoring active
|
||||
|
||||
### Monitoring Checklist
|
||||
- [ ] Core Web Vitals tracked
|
||||
- [ ] Performance budgets defined
|
||||
- [ ] Real User Monitoring active
|
||||
- [ ] Automated performance tests in CI
|
||||
- [ ] Performance regression alerts set up
|
||||
|
||||
## 📈 Performance Patterns
|
||||
|
||||
### Progressive Enhancement
|
||||
Build for performance from the ground up:
|
||||
|
||||
1. **Content First**: HTML loads fast
|
||||
2. **Style Enhancement**: CSS loads progressively
|
||||
3. **Interaction Layer**: JavaScript enhances experience
|
||||
4. **Advanced Features**: Load only when needed
|
||||
|
||||
### Performance-First Architecture
|
||||
- Minimal initial bundle size
|
||||
- Lazy loading for secondary features
|
||||
- Service Worker for offline functionality
|
||||
- Resource prioritization for critical path
|
||||
|
||||
---
|
||||
|
||||
*For specific framework optimizations, see [Framework Performance](../framework/performance/README.md)*
|
||||
*For monitoring setup, see [Analytics System](../framework/analytics/README.md)*
|
||||
42
backups/docs-backup-20250731125004/features.md
Normal file
42
backups/docs-backup-20250731125004/features.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# Framework Features
|
||||
|
||||
## Core Features
|
||||
- [ ] Routing mit Unterstützung für PHP-Attribute
|
||||
- [ ] Dependency Injection Container
|
||||
- [ ] Request/Response Abstraktion
|
||||
- [ ] Template-Engine
|
||||
- [ ] Error/Exception Handling
|
||||
- [ ] Konfigurationssystem
|
||||
|
||||
## Database Features
|
||||
- [ ] PDO-Wrapper
|
||||
- [ ] Query Builder
|
||||
- [ ] Migrations-System
|
||||
- [ ] Schema Manager
|
||||
- [ ] Entity-Mapping (optional)
|
||||
|
||||
## Security Features
|
||||
- [ ] CSRF-Schutz
|
||||
- [ ] XSS-Filtierung
|
||||
- [ ] Input-Validierung
|
||||
- [ ] Authentifizierung
|
||||
- [ ] Autorisierung/Rechtemanagement
|
||||
|
||||
## Module: Music
|
||||
- [ ] Album-Verwaltung
|
||||
- [ ] Track-Management
|
||||
- [ ] Playlists
|
||||
- [ ] Integrationsmöglichkeit mit Spotify/SoundCloud
|
||||
|
||||
## Module: Content
|
||||
- [ ] Blog-System
|
||||
- [ ] Markdown-Support
|
||||
- [ ] Medienbibliothek
|
||||
- [ ] SEO-Optimierung
|
||||
- [ ] Kommentarsystem
|
||||
|
||||
## Admin Interface
|
||||
- [ ] Dashboard
|
||||
- [ ] Content-Editor
|
||||
- [ ] Benutzer-/Rechteverwaltung
|
||||
- [ ] Statistiken
|
||||
14
backups/docs-backup-20250731125004/framework/ANALYTICS.md
Normal file
14
backups/docs-backup-20250731125004/framework/ANALYTICS.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Analytics-Framework
|
||||
|
||||
> **Dokumentationshinweis:** Die vollständige Dokumentation für das Analytics-Framework finden Sie im Ordner [/docs/framework/analytics](/docs/framework/analytics/).
|
||||
|
||||
## Schnellzugriff
|
||||
|
||||
- [Übersicht und Einstieg](/docs/framework/analytics/index.md)
|
||||
- [Detaillierte Architektur](/docs/framework/analytics/architecture.md)
|
||||
- [Anwendungsbeispiele](/docs/framework/analytics/usage.md)
|
||||
- [Migrationsleitfaden](/docs/framework/analytics/migration.md)
|
||||
|
||||
## Implementierungsdetails
|
||||
|
||||
Die Code-Dokumentation befindet sich in der [README-Datei des Frameworks](/Framework/Analytics1/README.md).
|
||||
@@ -0,0 +1,200 @@
|
||||
# Erweiterungsmuster im Framework
|
||||
|
||||
## Übersicht
|
||||
|
||||
Dieses Dokument beschreibt die verschiedenen Muster und Techniken, um das Framework zu erweitern oder anzupassen, ohne den Kern-Code zu verändern.
|
||||
|
||||
## Event-basierte Erweiterungen
|
||||
|
||||
### Event-Listener
|
||||
|
||||
Die primäre Methode zur Erweiterung des Frameworks ist das Lauschen auf System-Events:
|
||||
|
||||
```php
|
||||
// Event-Listener registrieren
|
||||
public function __construct(private readonly EventDispatcher $eventDispatcher)
|
||||
{
|
||||
$this->eventDispatcher->addHandler(
|
||||
'App\Framework\Core\Events\ApplicationBooted',
|
||||
[$this, 'onApplicationBooted']
|
||||
);
|
||||
}
|
||||
|
||||
// Event-Handler-Methode
|
||||
public function onApplicationBooted(ApplicationBooted $event): void
|
||||
{
|
||||
// Erweiterungslogik implementieren
|
||||
}
|
||||
```
|
||||
|
||||
### Eigene Events
|
||||
|
||||
Benutzerdefinierte Events erstellen:
|
||||
|
||||
```php
|
||||
final readonly class UserRegistered
|
||||
{
|
||||
public function __construct(
|
||||
public string $userId,
|
||||
public string $email,
|
||||
public \DateTimeImmutable $timestamp
|
||||
) {}
|
||||
}
|
||||
|
||||
// Event auslösen
|
||||
$this->eventDispatcher->dispatch(new UserRegistered(
|
||||
$user->getId(),
|
||||
$user->getEmail(),
|
||||
new \DateTimeImmutable()
|
||||
));
|
||||
```
|
||||
|
||||
## Middleware
|
||||
|
||||
HTTP-Anfragen können durch Middleware-Klassen erweitert werden:
|
||||
|
||||
```php
|
||||
final readonly class CustomMiddleware implements Middleware
|
||||
{
|
||||
public function process(Request $request, callable $next): Response
|
||||
{
|
||||
// Vor der Anfrageverarbeitung
|
||||
$modifiedRequest = $this->modifyRequest($request);
|
||||
|
||||
// Anfrage weiterleiten
|
||||
$response = $next($modifiedRequest);
|
||||
|
||||
// Nach der Anfrageverarbeitung
|
||||
return $this->modifyResponse($response);
|
||||
}
|
||||
}
|
||||
|
||||
// Middleware registrieren
|
||||
$app->addMiddleware(CustomMiddleware::class);
|
||||
```
|
||||
|
||||
## Service-Erweiterungen
|
||||
|
||||
### Service-Ersetzen
|
||||
|
||||
Standardimplementierungen durch eigene ersetzen:
|
||||
|
||||
```php
|
||||
#[Initializer]
|
||||
final readonly class CustomStorageInitializer
|
||||
{
|
||||
public function __invoke(Container $container): StorageInterface
|
||||
{
|
||||
return new CustomStorage();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Service-Decorator
|
||||
|
||||
Bestehende Services erweitern ohne Änderung der Original-Implementierung:
|
||||
|
||||
```php
|
||||
#[Initializer]
|
||||
final readonly class LoggingAnalyticsInitializer
|
||||
{
|
||||
public function __construct(
|
||||
private readonly Configuration $config,
|
||||
private readonly LoggerInterface $logger
|
||||
) {}
|
||||
|
||||
public function __invoke(Container $container): Analytics
|
||||
{
|
||||
// Original-Analytics-Service erstellen
|
||||
$originalAnalytics = new Analytics(
|
||||
new AnalyticsManager($this->config->get('analytics'), new FileStorage($path)),
|
||||
$container->get(EventDispatcher::class)
|
||||
);
|
||||
|
||||
// Mit Logging-Decorator umhüllen
|
||||
return new LoggingAnalyticsDecorator($originalAnalytics, $this->logger);
|
||||
}
|
||||
}
|
||||
|
||||
// Decorator-Implementierung
|
||||
final readonly class LoggingAnalyticsDecorator implements AnalyticsInterface
|
||||
{
|
||||
public function __construct(
|
||||
private Analytics $analytics,
|
||||
private LoggerInterface $logger
|
||||
) {}
|
||||
|
||||
public function track(string $event, array $properties = [], ?string $userId = null): void
|
||||
{
|
||||
$this->logger->debug("Tracking event: {$event}", [
|
||||
'properties' => $properties,
|
||||
'user_id' => $userId
|
||||
]);
|
||||
|
||||
$this->analytics->track($event, $properties, $userId);
|
||||
}
|
||||
|
||||
// Andere Methoden implementieren
|
||||
}
|
||||
```
|
||||
|
||||
## Plugin-System
|
||||
|
||||
### Plugin-Interface
|
||||
|
||||
```php
|
||||
interface PluginInterface
|
||||
{
|
||||
public function register(Application $app): void;
|
||||
public function boot(Application $app): void;
|
||||
}
|
||||
|
||||
// Plugin-Implementierung
|
||||
final readonly class CustomPlugin implements PluginInterface
|
||||
{
|
||||
public function register(Application $app): void
|
||||
{
|
||||
// Services registrieren
|
||||
}
|
||||
|
||||
public function boot(Application $app): void
|
||||
{
|
||||
// Nach Initialisierung der Anwendung
|
||||
}
|
||||
}
|
||||
|
||||
// Plugin registrieren
|
||||
$app->registerPlugin(new CustomPlugin());
|
||||
```
|
||||
|
||||
## Konfigurationserweiterungen
|
||||
|
||||
### Konfigurationsquellen
|
||||
|
||||
Benutzerdefinierte Konfigurationsquellen implementieren:
|
||||
|
||||
```php
|
||||
final readonly class EnvironmentConfigSource implements ConfigSourceInterface
|
||||
{
|
||||
public function load(string $key, mixed $default = null): mixed
|
||||
{
|
||||
$envKey = strtoupper(str_replace('.', '_', $key));
|
||||
return $_ENV[$envKey] ?? $default;
|
||||
}
|
||||
}
|
||||
|
||||
// Konfigurationsquelle registrieren
|
||||
$config->addSource(new EnvironmentConfigSource());
|
||||
```
|
||||
|
||||
## Zusammenfassung
|
||||
|
||||
Die bevorzugten Erweiterungsmuster sind:
|
||||
|
||||
1. **Event-Listener** für reaktive Erweiterungen
|
||||
2. **Middleware** für HTTP-Anfrageverarbeitung
|
||||
3. **Service-Initializer** zum Ersetzen oder Dekorieren von Services
|
||||
4. **Plugins** für umfassendere Funktionalitätserweiterungen
|
||||
5. **Konfigurationsquellen** für benutzerdefinierte Konfigurationen
|
||||
|
||||
Diese Muster ermöglichen es, das Framework zu erweitern, ohne den Kern zu modifizieren, was zu einer besseren Wartbarkeit und einfacheren Updates führt.
|
||||
@@ -0,0 +1,73 @@
|
||||
# Framework-Modul Checkliste
|
||||
|
||||
## Übersicht
|
||||
|
||||
Diese Checkliste dient als Leitfaden für die Erstellung neuer Module im Framework. Sie hilft sicherzustellen, dass alle Module den Projektstandards entsprechen und konsistent implementiert werden.
|
||||
|
||||
## Strukturelle Anforderungen
|
||||
|
||||
- [ ] Modul in eigenem Verzeichnis unter `/src/Framework/`
|
||||
- [ ] Konsistente Namensgebung im PascalCase (z.B. `CacheManager` statt `Cache_manager`)
|
||||
- [ ] README.md mit Modul-Dokumentation
|
||||
- [ ] Interface(s) für öffentliche API
|
||||
- [ ] Implementierungsklassen als `final readonly`
|
||||
- [ ] Initializer-Klasse mit `#[Initializer]`-Attribut
|
||||
|
||||
## Abhängigkeiten
|
||||
|
||||
- [ ] Minimale externe Abhängigkeiten (idealerweise keine)
|
||||
- [ ] Klar definierte Abhängigkeiten zu anderen Framework-Modulen
|
||||
- [ ] Keine zirkulären Abhängigkeiten
|
||||
- [ ] Verwendung des DI-Containers für Abhängigkeiten
|
||||
|
||||
## Konfiguration
|
||||
|
||||
- [ ] Konfigurationsdatei unter `/src/Config/{modul-name}.php`
|
||||
- [ ] Standardkonfiguration in der Initializer-Klasse
|
||||
- [ ] Dokumentierte Konfigurationsoptionen
|
||||
|
||||
## Code-Qualität
|
||||
|
||||
- [ ] Vollständige Typisierung (Parameter, Rückgabewerte, Properties)
|
||||
- [ ] PHPDoc für öffentliche Methoden und Klassen
|
||||
- [ ] Keine abstrakten Klassen oder Vererbung (außer Interfaces)
|
||||
- [ ] Immutable Objekte wo möglich
|
||||
- [ ] Spezifische Exceptions für Fehlerbehandlung
|
||||
|
||||
## Tests
|
||||
|
||||
- [ ] Unit-Tests mit Pest für alle öffentlichen Methoden
|
||||
- [ ] Integrationstests für Modul-Interaktionen
|
||||
- [ ] Testabdeckung für Fehlerfälle
|
||||
|
||||
## Integration
|
||||
|
||||
- [ ] Event-Listener für relevante System-Events
|
||||
- [ ] Erweiterungspunkte für andere Module
|
||||
- [ ] Keine direkten Abhängigkeiten zu Domain-Klassen
|
||||
|
||||
## Dokumentation
|
||||
|
||||
- [ ] Beispiele für Verwendung
|
||||
- [ ] Architektur-Beschreibung
|
||||
- [ ] API-Dokumentation
|
||||
- [ ] Konfigurationsreferenz
|
||||
|
||||
## Performance
|
||||
|
||||
- [ ] Lazy-Loading für ressourcenintensive Operationen
|
||||
- [ ] Caching-Strategie (falls relevant)
|
||||
- [ ] Performancekritische Teile identifiziert und optimiert
|
||||
|
||||
## Sicherheit
|
||||
|
||||
- [ ] Validierung aller externen Eingaben
|
||||
- [ ] Keine sensiblen Daten in Logs
|
||||
- [ ] Schutz vor bekannten Sicherheitslücken
|
||||
|
||||
## Wartbarkeit
|
||||
|
||||
- [ ] Kleine, fokussierte Klassen
|
||||
- [ ] Klare Trennung von Verantwortlichkeiten
|
||||
- [ ] Konsistente Fehlerbehandlung
|
||||
- [ ] Logging an strategischen Stellen
|
||||
158
backups/docs-backup-20250731125004/framework/analytics/README.md
Normal file
158
backups/docs-backup-20250731125004/framework/analytics/README.md
Normal file
@@ -0,0 +1,158 @@
|
||||
# Analytics-Modul Dokumentation
|
||||
|
||||
## Übersicht
|
||||
|
||||
Das Analytics-Modul ist ein internes Tracking- und Analysesystem, das ohne externe Abhängigkeiten Benutzeraktivitäten, Systemereignisse und Leistungsdaten erfasst und analysiert.
|
||||
|
||||
## Kernkomponenten
|
||||
|
||||
### Analytics (Analytics.php)
|
||||
|
||||
Die Hauptklasse, die als zentraler Einstiegspunkt für das Tracking von Events dient.
|
||||
|
||||
**Hauptfunktionen:**
|
||||
- `track()`: Zeichnet ein generisches Event auf
|
||||
- `page()`: Spezifisch für Seitenaufrufe
|
||||
- `user()`: Verfolgt Benutzeridentifikation
|
||||
- `performance()`: Erfasst Leistungsmetriken
|
||||
- `error()`: Protokolliert Fehler und Ausnahmen
|
||||
|
||||
### AnalyticsManager (AnalyticsManager.php)
|
||||
|
||||
Verwaltet die Verarbeitung und Speicherung von Events.
|
||||
|
||||
**Hauptfunktionen:**
|
||||
- `track()`: Verarbeitet Events und wendet Middleware an
|
||||
- `addMiddleware()`: Fügt Verarbeitungsfunktionen hinzu
|
||||
- `flush()`: Schreibt gepufferte Events in den Speicher
|
||||
|
||||
### StorageInterface und FileStorage
|
||||
|
||||
Das Interface definiert die Speichermethoden, FileStorage implementiert die Speicherung in Dateien.
|
||||
|
||||
**Hauptoperationen:**
|
||||
- `store()`: Speichert Events
|
||||
- `retrieve()`: Ruft Events mit Filtern ab
|
||||
- `clear()`: Löscht alle gespeicherten Daten
|
||||
|
||||
### AnalyticsInitializer (AnalyticsInitializer.php)
|
||||
|
||||
Konfiguriert und initialisiert den Analytics-Service beim Anwendungsstart.
|
||||
|
||||
**Konfigurationsoptionen:**
|
||||
- Aktivierung/Deaktivierung
|
||||
- Auto-Flush und Batch-Größe
|
||||
- Storage-Typ und Pfad
|
||||
|
||||
### AnalyticsMiddleware (AnalyticsMiddleware.php)
|
||||
|
||||
HTTP-Middleware zum automatischen Tracking von Requests und Responses.
|
||||
|
||||
### AnalyticsDashboard (AnalyticsDashboard.php)
|
||||
|
||||
Stellt Methoden für Datenanalyse und -aggregation bereit:
|
||||
- `getEventStats()`: Ereignisstatistiken
|
||||
- `getTopPages()`: Meistbesuchte Seiten
|
||||
- `getUserStats()`: Benutzerstatistiken
|
||||
- `getErrorStats()`: Fehlerstatistiken
|
||||
- `getPerformanceStats()`: Leistungsmetriken
|
||||
|
||||
### Events
|
||||
|
||||
Vordefinierte Event-Typen:
|
||||
- `AnalyticsEvent`: Basis-Event-Klasse
|
||||
- `PageViewEvent`: Speziell für Seitenaufrufe
|
||||
|
||||
### Controllers
|
||||
|
||||
`AdminAnalyticsController`: Stellt das Admin-Dashboard bereit mit:
|
||||
- Übersichtsseite
|
||||
- Seitenstatistiken
|
||||
- Fehlerstatistiken
|
||||
- Leistungsstatistiken
|
||||
|
||||
### Console
|
||||
|
||||
`AnalyticsClearCommand`: Konsolenbefehl zum Löschen von Analytics-Daten.
|
||||
|
||||
## Konfiguration
|
||||
|
||||
Die Konfiguration erfolgt in `src/Config/analytics.php` mit folgenden Optionen:
|
||||
|
||||
```php
|
||||
return [
|
||||
'enabled' => true, // Aktiviert/deaktiviert das Tracking
|
||||
'auto_flush' => true, // Automatisches Speichern nach Batch-Größe
|
||||
'batch_size' => 50, // Anzahl Events pro Batch
|
||||
'storage' => 'file', // Storage-Backend
|
||||
'storage_path' => '...', // Speicherpfad
|
||||
'anonymize_ip' => true, // IP-Anonymisierung
|
||||
'track_events' => [...] // Zu trackende Events
|
||||
];
|
||||
```
|
||||
|
||||
## Verwendung
|
||||
|
||||
### Basis-Tracking
|
||||
|
||||
```php
|
||||
// Event tracken
|
||||
$analytics->track('button_click', ['button' => 'signup']);
|
||||
|
||||
// Seitenaufruf tracken
|
||||
$analytics->page('/dashboard', ['section' => 'analytics']);
|
||||
|
||||
// Benutzer identifizieren
|
||||
$analytics->user('user123', ['plan' => 'premium']);
|
||||
```
|
||||
|
||||
### Middleware einrichten
|
||||
|
||||
```php
|
||||
$this->addMiddleware(App\Framework\Analytics\AnalyticsMiddleware::class);
|
||||
```
|
||||
|
||||
### Eigene Middleware hinzufügen
|
||||
|
||||
```php
|
||||
$analyticsManager->addMiddleware(function(array $event) {
|
||||
// Daten verarbeiten oder filtern
|
||||
return $event;
|
||||
});
|
||||
```
|
||||
|
||||
## Datenschutz
|
||||
|
||||
Das System bietet integrierte Funktionen zur Anonymisierung personenbezogener Daten:
|
||||
- IP-Adressen-Anonymisierung (letztes Oktett wird entfernt)
|
||||
- Konfigurierbare Filterung sensibler Daten durch Middleware
|
||||
|
||||
## Erweiterbarkeit
|
||||
|
||||
### Eigene Storage-Provider
|
||||
|
||||
Implementieren Sie das `StorageInterface` für benutzerdefinierte Speicherlösungen:
|
||||
|
||||
```php
|
||||
class CustomStorage implements StorageInterface
|
||||
{
|
||||
public function store(array $events): void { /* ... */ }
|
||||
public function retrieve(array $filters = []): array { /* ... */ }
|
||||
public function clear(): void { /* ... */ }
|
||||
}
|
||||
```
|
||||
|
||||
### Event-Typen erweitern
|
||||
|
||||
Erstellen Sie benutzerdefinierte Event-Klassen, die von `AnalyticsEvent` erben:
|
||||
|
||||
```php
|
||||
class CustomEvent extends AnalyticsEvent
|
||||
{
|
||||
public function __construct(string $customData, array $additionalProps = [])
|
||||
{
|
||||
parent::__construct('custom_event',
|
||||
array_merge(['custom_data' => $customData], $additionalProps));
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,102 @@
|
||||
# Analytics-Framework: Architektur
|
||||
|
||||
## Überblick
|
||||
|
||||
Das Analytics-Framework verwendet eine Schichtenarchitektur mit klaren Verantwortlichkeiten:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ Öffentliche API │
|
||||
│ (Analytics) │
|
||||
└───────────────────────┬─────────────────────────────┘
|
||||
│
|
||||
┌───────────────────────▼─────────────────────────────┐
|
||||
│ Event-Verarbeitung │
|
||||
│ (AnalyticsManager) │
|
||||
└───────────────────────┬─────────────────────────────┘
|
||||
│
|
||||
┌──────────────┴──────────────┐
|
||||
│ │
|
||||
┌────────▼─────────┐ ┌─────────▼────────┐
|
||||
│ Middleware │ │ Storage-Layer │
|
||||
│ (Pipeline) │ │ (StorageInterface)│
|
||||
└──────────────────┘ └──────────────────┘
|
||||
```
|
||||
|
||||
## Komponenten im Detail
|
||||
|
||||
### Analytics (Frontend)
|
||||
|
||||
Bietet eine benutzerfreundliche API für Tracking-Operationen. Diese Klasse ist der primäre Einstiegspunkt für Anwendungscode und abstrahiert die Komplexität der Eventverarbeitung.
|
||||
|
||||
Verantwortlichkeiten:
|
||||
- Bereitstellung der öffentlichen API (`track`, `page`, `user`, `error`)
|
||||
- Integration mit dem Event-Dispatcher des Frameworks
|
||||
- Typ-Konvertierung zwischen benutzerdefinierten Ereignissen und dem internen Datenformat
|
||||
|
||||
### AnalyticsManager (Verarbeitung)
|
||||
|
||||
Der Manager ist das Herzstück des Systems und verantwortlich für:
|
||||
- Anwendung von Middleware-Transformationen auf Events
|
||||
- Eventpufferung für effiziente Speicherung
|
||||
- Verwaltung der Konfiguration
|
||||
- Steuerung des Storage-Layers
|
||||
|
||||
Der Manager implementiert einen Event-Buffer, der Daten sammelt und bei Erreichen einer konfigurierbaren Größe automatisch speichert.
|
||||
|
||||
### Middleware-System
|
||||
|
||||
Eine Kette von Verarbeitungsfunktionen, die auf jedes Event angewendet werden:
|
||||
- Datenfilterung und -transformation
|
||||
- Anonymisierung persönlicher Daten
|
||||
- Validierung und Anreicherung von Events
|
||||
|
||||
Jede Middleware kann Events modifizieren oder komplett verwerfen.
|
||||
|
||||
### Storage-Layer
|
||||
|
||||
Abstraktion für verschiedene Speichermethoden durch das `StorageInterface`:
|
||||
|
||||
```php
|
||||
interface StorageInterface
|
||||
{
|
||||
public function store(array $events): void;
|
||||
public function retrieve(array $filters = []): array;
|
||||
public function clear(): void;
|
||||
}
|
||||
```
|
||||
|
||||
Implementierungen:
|
||||
- `FileStorage`: Speichert Events in JSON-Dateien mit täglicher Rotation
|
||||
- Erweiterbar für andere Backends (Datenbank, Redis, etc.)
|
||||
|
||||
### HTTP-Integration
|
||||
|
||||
`AnalyticsMiddleware` integriert Analytics in den HTTP-Request-Lifecycle:
|
||||
- Tracking von eingehenden Requests
|
||||
- Erfassung von Antwortzeiten und Statuscodes
|
||||
- Fehlererfassung bei Exceptions
|
||||
|
||||
### Admin-Dashboard
|
||||
|
||||
`AnalyticsDashboard` und `AdminAnalyticsController` bieten:
|
||||
- Datenaggregation und -analyse
|
||||
- Visualisierung von Metriken
|
||||
- Filterung nach Zeiträumen
|
||||
- Verschiedene spezialisierte Ansichten (Seiten, Fehler, Performance)
|
||||
|
||||
## Datenfluss
|
||||
|
||||
1. Event wird durch `Analytics::track()` oder ähnliche Methoden erstellt
|
||||
2. `AnalyticsManager` wendet Middleware-Pipeline an
|
||||
3. Event wird zum Buffer hinzugefügt
|
||||
4. Bei Buffer-Füllung oder explizitem `flush()` werden Events an Storage übergeben
|
||||
5. Storage speichert Events im konfigurierten Backend
|
||||
6. `AnalyticsDashboard` ruft Daten bei Bedarf vom Storage ab und aggregiert sie
|
||||
|
||||
## Erweiterungspunkte
|
||||
|
||||
- **Storage-Provider**: Neue Implementierungen von `StorageInterface`
|
||||
- **Middleware**: Funktionen für Filterung/Transformation
|
||||
- **Event-Typen**: Spezialisierte Event-Klassen für typsicheres Tracking
|
||||
- **Dashboard-Views**: Zusätzliche Visualisierungen und Berichte
|
||||
114
backups/docs-backup-20250731125004/framework/analytics/index.md
Normal file
114
backups/docs-backup-20250731125004/framework/analytics/index.md
Normal file
@@ -0,0 +1,114 @@
|
||||
# Analytics-Framework
|
||||
|
||||
> **Dokumentationshinweis:** Diese Dokumentation ist vollständig aktualisiert und stellt die aktuelle Implementierung des Analytics-Frameworks korrekt dar.
|
||||
|
||||
## Übersicht
|
||||
|
||||
Das Analytics-Framework ist ein eigenständiges Tracking- und Analysesystem, das vollständig in die Anwendung integriert ist und ohne externe Dienste auskommt. Es ermöglicht die Erfassung, Speicherung und Analyse von:
|
||||
|
||||
- Benutzeraktivitäten (Seitenaufrufe, Interaktionen)
|
||||
- Systemereignissen (Anwendungsstart, Fehler)
|
||||
- Leistungsdaten (Speicherverbrauch, Ausführungszeit, Datenbankabfragen)
|
||||
|
||||
## Hauptkomponenten
|
||||
|
||||
### Analytics-Klasse
|
||||
|
||||
Die zentrale API für Tracking-Operationen:
|
||||
|
||||
```php
|
||||
// Klasse initialisieren
|
||||
$analytics = new Analytics($analyticsManager, $eventDispatcher);
|
||||
|
||||
// Event tracken
|
||||
$analytics->track('event_name', ['property' => 'value']);
|
||||
|
||||
// Seite tracken
|
||||
$analytics->page('/pfad/zur/seite', ['eigenschaft' => 'wert']);
|
||||
|
||||
// Benutzer identifizieren
|
||||
$analytics->user('user_id', ['eigenschaft' => 'wert']);
|
||||
|
||||
// Fehler tracken
|
||||
$analytics->error($exception);
|
||||
```
|
||||
|
||||
### AnalyticsManager
|
||||
|
||||
Verarbeitet und speichert Events:
|
||||
|
||||
- Wendet Middleware auf Events an
|
||||
- Puffert Events für effiziente Speicherung
|
||||
- Verwaltet die Konfiguration
|
||||
- Steuert die Speicherung in verschiedenen Backends
|
||||
|
||||
### Storage-System
|
||||
|
||||
Basierend auf dem `StorageInterface` mit verschiedenen Implementierungen:
|
||||
|
||||
- `FileStorage`: Speichert Events in Dateien
|
||||
- Erweiterbar für Datenbank, Redis oder andere Backends
|
||||
|
||||
### Middleware-System
|
||||
|
||||
```php
|
||||
$analyticsManager->addMiddleware(function(array $event) {
|
||||
// Event verarbeiten oder filtern
|
||||
return $event; // oder null um zu verwerfen
|
||||
});
|
||||
```
|
||||
|
||||
### HTTP-Middleware
|
||||
|
||||
Automatisches Tracking von HTTP-Requests und -Responses:
|
||||
|
||||
```php
|
||||
// In Bootstrap oder Application-Klasse
|
||||
$app->addMiddleware(AnalyticsMiddleware::class);
|
||||
```
|
||||
|
||||
### Dashboard und Berichterstattung
|
||||
|
||||
Das `AnalyticsDashboard` bietet Methoden zur Datenanalyse:
|
||||
|
||||
- `getEventStats()`: Statistiken zu Events
|
||||
- `getTopPages()`: Meistbesuchte Seiten
|
||||
- `getUserStats()`: Benutzerstatistiken
|
||||
- `getErrorStats()`: Fehlerstatistiken
|
||||
- `getPerformanceStats()`: Leistungsmetriken
|
||||
|
||||
Das Admin-Dashboard ist unter `/admin/analytics` verfügbar.
|
||||
|
||||
### Konsolen-Befehle
|
||||
|
||||
```bash
|
||||
# Analytics-Daten löschen
|
||||
php console analytics:clear [--force]
|
||||
```
|
||||
|
||||
## Integration
|
||||
|
||||
### Service-Container
|
||||
|
||||
Der Analytics-Service wird automatisch registriert und kann per Dependency Injection verwendet werden:
|
||||
|
||||
```php
|
||||
public function __construct(private readonly Analytics $analytics) {}
|
||||
```
|
||||
|
||||
### Event-Integration
|
||||
|
||||
Standardmäßig werden folgende Anwendungsereignisse getrackt:
|
||||
|
||||
- Anwendungsstart (`application_booted`)
|
||||
- Fehlerbehandlung (`error_occurred`)
|
||||
- Request-Verarbeitung (`request_started`, `request_completed`)
|
||||
|
||||
## Konfiguration
|
||||
|
||||
Detaillierte Konfigurationsoptionen finden Sie in der [Framework-README](/Framework/Analytics1/README.md).
|
||||
|
||||
## Weitere Informationen
|
||||
|
||||
- [Framework-Erweiterungsmuster](/docs/framework/ERWEITERUNGSPATTERN.md)
|
||||
- [Modul-Checkliste](/docs/framework/MODUL-CHECKLISTE.md)
|
||||
@@ -0,0 +1,160 @@
|
||||
# Analytics-Framework: Migrationsleitfaden
|
||||
|
||||
## Von Version 1.x zu 2.x
|
||||
|
||||
### Überblick der Änderungen
|
||||
|
||||
Die Version 2.x des Analytics-Frameworks führt mehrere wichtige Verbesserungen und Änderungen ein:
|
||||
|
||||
- **Typsicherheit**: Neue Event-Klassen statt Arrays
|
||||
- **Dependency Injection**: Verbesserte Integration mit dem Container
|
||||
- **Storage-Abstraktion**: Flexiblere Speichermethoden
|
||||
- **Fehlerbehandlung**: Robustere Exception-Handling
|
||||
- **Middleware-System**: Standardisierte Middleware-Pipeline
|
||||
|
||||
### Notwendige Migrationsschritte
|
||||
|
||||
#### 1. Konfiguration aktualisieren
|
||||
|
||||
**Alt (1.x):**
|
||||
```php
|
||||
return [
|
||||
'enabled' => true,
|
||||
'auto_flush' => true,
|
||||
'batch_size' => 50,
|
||||
'storage' => 'file',
|
||||
'storage_path' => '/pfad/zum/speicher',
|
||||
];
|
||||
```
|
||||
|
||||
**Neu (2.x):**
|
||||
```php
|
||||
return [
|
||||
'enabled' => true,
|
||||
'auto_flush' => true,
|
||||
'batch_size' => 50,
|
||||
'storage_driver' => 'file', // Umbenannt
|
||||
'storage_config' => [ // Neue Struktur
|
||||
'path' => '/pfad/zum/speicher',
|
||||
],
|
||||
'excluded_paths' => [], // Neue Option
|
||||
'excluded_user_agents' => [], // Neue Option
|
||||
'max_file_size' => 10 * 1024 * 1024, // Neue Option
|
||||
];
|
||||
```
|
||||
|
||||
#### 2. Event-Objekte (falls genutzt)
|
||||
|
||||
**Alt (1.x):**
|
||||
```php
|
||||
$analytics->track('custom_event', ['property' => 'value']);
|
||||
```
|
||||
|
||||
**Neu (2.x) - Option 1 (abwärtskompatibel):**
|
||||
```php
|
||||
// Weiterhin unterstützt
|
||||
$analytics->track('custom_event', ['property' => 'value']);
|
||||
```
|
||||
|
||||
**Neu (2.x) - Option 2 (typsicher):**
|
||||
```php
|
||||
use App\Framework\Analytics\Events\CustomEvent;
|
||||
|
||||
$event = new CustomEvent('wert', ['weitere' => 'daten']);
|
||||
$analytics->trackEvent($event);
|
||||
```
|
||||
|
||||
#### 3. Eigene Storage-Provider
|
||||
|
||||
**Alt (1.x):**
|
||||
```php
|
||||
class CustomStorage implements StorageInterface
|
||||
{
|
||||
public function store(array $events): void
|
||||
{
|
||||
// Implementation
|
||||
}
|
||||
|
||||
public function retrieve(array $filters = []): array
|
||||
{
|
||||
// Implementation
|
||||
}
|
||||
|
||||
public function clear(): void
|
||||
{
|
||||
// Implementation
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Neu (2.x):**
|
||||
```php
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class CustomStorage implements StorageInterface
|
||||
{
|
||||
public function __construct(
|
||||
private readonly array $config,
|
||||
private readonly LoggerInterface $logger
|
||||
) {}
|
||||
|
||||
public function store(array $events): void
|
||||
{
|
||||
try {
|
||||
// Implementation mit Fehlerbehandlung
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Storage error', ['exception' => $e]);
|
||||
throw new StorageException('Failed to store events', 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
// Andere Methoden analog
|
||||
}
|
||||
```
|
||||
|
||||
#### 4. Middleware anpassen
|
||||
|
||||
**Alt (1.x):**
|
||||
```php
|
||||
$analyticsManager->addMiddleware(function(array $event) {
|
||||
// Verarbeitung
|
||||
return $event;
|
||||
});
|
||||
```
|
||||
|
||||
**Neu (2.x) - Option 1 (abwärtskompatibel):**
|
||||
```php
|
||||
// Weiterhin unterstützt
|
||||
$analyticsManager->addMiddleware(function(array $event) {
|
||||
// Verarbeitung
|
||||
return $event;
|
||||
});
|
||||
```
|
||||
|
||||
**Neu (2.x) - Option 2 (typsicher):**
|
||||
```php
|
||||
use App\Framework\Analytics\Middleware\AnalyticsMiddleware;
|
||||
use App\Framework\Analytics\Events\AnalyticsEvent;
|
||||
|
||||
class CustomMiddleware implements AnalyticsMiddleware
|
||||
{
|
||||
public function process(AnalyticsEvent $event): ?AnalyticsEvent
|
||||
{
|
||||
// Verarbeitung
|
||||
return $event;
|
||||
}
|
||||
}
|
||||
|
||||
// Registrierung
|
||||
$analyticsManager->addMiddleware(new CustomMiddleware());
|
||||
```
|
||||
|
||||
### Automatisierte Tests
|
||||
|
||||
Führen Sie die folgenden Tests durch, um sicherzustellen, dass die Migration erfolgreich war:
|
||||
|
||||
```bash
|
||||
php console test:run --group=analytics
|
||||
```
|
||||
|
||||
Weitere Informationen zur Migration finden Sie in den Änderungsprotokollen im Quellcode-Repository.
|
||||
269
backups/docs-backup-20250731125004/framework/analytics/usage.md
Normal file
269
backups/docs-backup-20250731125004/framework/analytics/usage.md
Normal file
@@ -0,0 +1,269 @@
|
||||
# Analytics-Framework: Anwendungsbeispiele
|
||||
|
||||
## Grundlegende Verwendung
|
||||
|
||||
### Events tracken
|
||||
|
||||
```php
|
||||
// Über Dependency Injection
|
||||
public function __construct(private readonly Analytics $analytics) {}
|
||||
|
||||
// Einfaches Event tracken
|
||||
$this->analytics->track('login_attempt', [
|
||||
'success' => true,
|
||||
'user_type' => 'admin',
|
||||
'method' => 'password'
|
||||
]);
|
||||
|
||||
// Seitenaufruf tracken
|
||||
$this->analytics->page('/produkte/kategorie/elektronik', [
|
||||
'referrer' => 'homepage',
|
||||
'search_query' => 'smartphones'
|
||||
]);
|
||||
|
||||
// Benutzer identifizieren
|
||||
$this->analytics->user($user->getId(), [
|
||||
'email' => $user->getEmail(),
|
||||
'plan' => $user->getSubscriptionPlan(),
|
||||
'registered_since' => $user->getCreatedAt()->format('Y-m-d')
|
||||
]);
|
||||
```
|
||||
|
||||
### Fehler tracken
|
||||
|
||||
```php
|
||||
try {
|
||||
// Fehleranfälliger Code
|
||||
$result = $this->riskyOperation();
|
||||
return $result;
|
||||
} catch (\Exception $e) {
|
||||
// Fehler tracken
|
||||
$this->analytics->error($e);
|
||||
|
||||
// Fehler behandeln
|
||||
$this->logger->error($e->getMessage());
|
||||
return $this->fallbackOperation();
|
||||
}
|
||||
```
|
||||
|
||||
### Performance tracken
|
||||
|
||||
```php
|
||||
// Manuelles Performance-Tracking
|
||||
$startTime = microtime(true);
|
||||
$startMemory = memory_get_usage();
|
||||
|
||||
// Operation durchführen
|
||||
$result = $this->heavyOperation();
|
||||
|
||||
// Performance-Metriken tracken
|
||||
$this->analytics->performance([
|
||||
'operation' => 'heavy_operation',
|
||||
'execution_time' => microtime(true) - $startTime,
|
||||
'memory_used' => memory_get_usage() - $startMemory,
|
||||
'result_size' => is_countable($result) ? count($result) : 0
|
||||
]);
|
||||
```
|
||||
|
||||
## Erweiterte Anwendungsfälle
|
||||
|
||||
### Benutzerdefinierte Middleware
|
||||
|
||||
```php
|
||||
// In einem Service Provider oder Initializer
|
||||
public function initialize(AnalyticsManager $manager): void
|
||||
{
|
||||
// DSGVO-Middleware zur Anonymisierung personenbezogener Daten
|
||||
$manager->addMiddleware(function(array $event) {
|
||||
// E-Mail-Adressen anonymisieren
|
||||
if (isset($event['properties']['email'])) {
|
||||
$parts = explode('@', $event['properties']['email']);
|
||||
if (count($parts) === 2) {
|
||||
$event['properties']['email'] = substr($parts[0], 0, 1) .
|
||||
'***@' . $parts[1];
|
||||
}
|
||||
}
|
||||
|
||||
// Passwörter und Tokens entfernen
|
||||
foreach (['password', 'token', 'api_key', 'secret'] as $key) {
|
||||
if (isset($event['properties'][$key])) {
|
||||
$event['properties'][$key] = '[redacted]';
|
||||
}
|
||||
}
|
||||
|
||||
return $event;
|
||||
});
|
||||
|
||||
// Spam-Filter
|
||||
$manager->addMiddleware(function(array $event) {
|
||||
// Zu viele Events von einem Benutzer filtern
|
||||
static $userCounts = [];
|
||||
$userId = $event['user_id'] ?? $event['session_id'] ?? null;
|
||||
|
||||
if ($userId) {
|
||||
$userCounts[$userId] = ($userCounts[$userId] ?? 0) + 1;
|
||||
|
||||
// Mehr als 100 Events pro Session ist verdächtig
|
||||
if ($userCounts[$userId] > 100) {
|
||||
return null; // Event verwerfen
|
||||
}
|
||||
}
|
||||
|
||||
return $event;
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### Integration mit dem Domain-Layer
|
||||
|
||||
```php
|
||||
// In einem Domain-Service
|
||||
namespace App\Domain\Shop\Services;
|
||||
|
||||
use App\Framework\Analytics\Analytics;
|
||||
|
||||
class ProductService
|
||||
{
|
||||
public function __construct(private readonly Analytics $analytics) {}
|
||||
|
||||
public function viewProduct(string $productId, ?string $userId): Product
|
||||
{
|
||||
$product = $this->productRepository->find($productId);
|
||||
|
||||
if (!$product) {
|
||||
throw new ProductNotFoundException($productId);
|
||||
}
|
||||
|
||||
// Produktansicht tracken
|
||||
$this->analytics->track('product_view', [
|
||||
'product_id' => $product->getId(),
|
||||
'product_name' => $product->getName(),
|
||||
'product_price' => $product->getPrice(),
|
||||
'product_category' => $product->getCategory()->getName(),
|
||||
'in_stock' => $product->isInStock()
|
||||
], $userId);
|
||||
|
||||
return $product;
|
||||
}
|
||||
|
||||
public function addToCart(string $productId, int $quantity, ?string $userId): Cart
|
||||
{
|
||||
// Implementation...
|
||||
|
||||
// Event tracken
|
||||
$this->analytics->track('add_to_cart', [
|
||||
'product_id' => $productId,
|
||||
'quantity' => $quantity,
|
||||
'cart_value' => $cart->getTotalValue()
|
||||
], $userId);
|
||||
|
||||
return $cart;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Verwendung im Controller
|
||||
|
||||
```php
|
||||
namespace App\Application\Controllers;
|
||||
|
||||
use App\Framework\Analytics\Analytics;
|
||||
use App\Framework\Http\Request;
|
||||
use App\Framework\Http\Response;
|
||||
use App\Framework\Attributes\Route;
|
||||
|
||||
class CheckoutController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly Analytics $analytics,
|
||||
private readonly CheckoutService $checkoutService
|
||||
) {}
|
||||
|
||||
#[Route('/checkout/complete', method: 'POST')]
|
||||
public function completeCheckout(Request $request): Response
|
||||
{
|
||||
$userId = $request->getSession()->get('user_id');
|
||||
$cartId = $request->getSession()->get('cart_id');
|
||||
|
||||
try {
|
||||
$order = $this->checkoutService->completeCheckout($cartId, $userId);
|
||||
|
||||
// Erfolgreichen Checkout tracken
|
||||
$this->analytics->track('checkout_complete', [
|
||||
'order_id' => $order->getId(),
|
||||
'order_value' => $order->getTotalValue(),
|
||||
'items_count' => count($order->getItems()),
|
||||
'payment_method' => $order->getPaymentMethod(),
|
||||
'shipping_method' => $order->getShippingMethod()
|
||||
], $userId);
|
||||
|
||||
return new Response([
|
||||
'success' => true,
|
||||
'order_id' => $order->getId()
|
||||
], 200);
|
||||
} catch (\Exception $e) {
|
||||
// Fehler beim Checkout tracken
|
||||
$this->analytics->track('checkout_error', [
|
||||
'error' => $e->getMessage(),
|
||||
'cart_id' => $cartId
|
||||
], $userId);
|
||||
|
||||
// Auch den Exception-Stack tracken
|
||||
$this->analytics->error($e);
|
||||
|
||||
return new Response([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
], 400);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Analyse der Daten
|
||||
|
||||
### Dashboard-Controller
|
||||
|
||||
```php
|
||||
namespace App\Application\Controllers;
|
||||
|
||||
use App\Framework\Analytics\AnalyticsDashboard;
|
||||
use App\Framework\Http\Request;
|
||||
use App\Framework\Http\Response;
|
||||
use App\Framework\View\ViewRenderer;
|
||||
use App\Framework\Attributes\Route;
|
||||
|
||||
class AnalyticsDashboardController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly AnalyticsDashboard $dashboard,
|
||||
private readonly ViewRenderer $viewRenderer
|
||||
) {}
|
||||
|
||||
#[Route('/admin/analytics/conversion')]
|
||||
public function conversionReport(Request $request): Response
|
||||
{
|
||||
$from = $request->getQueryParam('from');
|
||||
$to = $request->getQueryParam('to');
|
||||
|
||||
// Benutzerdefinierte Analyse für Conversion-Funnel
|
||||
$pageViews = $this->dashboard->getEventCountByType('page_view', $from, $to);
|
||||
$productViews = $this->dashboard->getEventCountByType('product_view', $from, $to);
|
||||
$addToCarts = $this->dashboard->getEventCountByType('add_to_cart', $from, $to);
|
||||
$checkouts = $this->dashboard->getEventCountByType('checkout_complete', $from, $to);
|
||||
|
||||
// Conversion-Raten berechnen
|
||||
$data = [
|
||||
'total_visitors' => $pageViews,
|
||||
'product_view_rate' => $pageViews > 0 ? $productViews / $pageViews : 0,
|
||||
'add_to_cart_rate' => $productViews > 0 ? $addToCarts / $productViews : 0,
|
||||
'checkout_rate' => $addToCarts > 0 ? $checkouts / $addToCarts : 0,
|
||||
'overall_conversion' => $pageViews > 0 ? $checkouts / $pageViews : 0,
|
||||
'from_date' => $from,
|
||||
'to_date' => $to
|
||||
];
|
||||
|
||||
return $this->viewRenderer->render('admin/analytics/conversion', $data);
|
||||
}
|
||||
}
|
||||
```
|
||||
45
backups/docs-backup-20250731125004/framework/core/README.md
Normal file
45
backups/docs-backup-20250731125004/framework/core/README.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# Core-Modul Dokumentation
|
||||
|
||||
## Übersicht
|
||||
|
||||
Das Core-Modul bildet das Herzstück des Frameworks und stellt grundlegende Funktionalitäten bereit, die von anderen Modulen genutzt werden.
|
||||
|
||||
## Hauptkomponenten
|
||||
|
||||
### Events und EventDispatcher
|
||||
|
||||
Das Event-System ermöglicht die Kommunikation zwischen Komponenten über einen zentralen Event-Bus.
|
||||
|
||||
**Kernklassen:**
|
||||
- `EventDispatcher`: Zentraler Service zum Registrieren und Auslösen von Events
|
||||
- Bekannte Events:
|
||||
- `ApplicationBooted`
|
||||
- `ErrorOccurred`
|
||||
- `BeforeHandleRequest`
|
||||
- `AfterHandleRequest`
|
||||
|
||||
**Beispielverwendung:**
|
||||
```php
|
||||
// Event-Handler registrieren
|
||||
$eventDispatcher->addHandler('App\Framework\Core\Events\ApplicationBooted', function($event) {
|
||||
// Event verarbeiten
|
||||
});
|
||||
```
|
||||
|
||||
### PathProvider
|
||||
|
||||
Stellt Pfadinformationen für verschiedene Bereiche der Anwendung bereit.
|
||||
|
||||
**Hauptfunktionen:**
|
||||
- `getDataPath()`: Liefert Pfade zu Datenverzeichnissen
|
||||
|
||||
## Integration mit anderen Modulen
|
||||
|
||||
Das Core-Modul wird von vielen anderen Modulen verwendet, wie z.B.:
|
||||
|
||||
- **Analytics-Modul**: Nutzt den EventDispatcher zum Tracking von Systemereignissen
|
||||
- **DI-Container**: Nutzt Core-Komponenten für die Initialisierung von Services
|
||||
|
||||
## Architektur
|
||||
|
||||
Das Core-Modul folgt einer ereignisgesteuerten Architektur, bei der Komponenten über Events miteinander kommunizieren können, anstatt direkte Abhängigkeiten zu haben.
|
||||
89
backups/docs-backup-20250731125004/framework/di/README.md
Normal file
89
backups/docs-backup-20250731125004/framework/di/README.md
Normal file
@@ -0,0 +1,89 @@
|
||||
# Dependency Injection Modul
|
||||
|
||||
## Übersicht
|
||||
|
||||
Das DI-Modul implementiert ein Dependency-Injection-Container-System, das die automatische Auflösung und Verwaltung von Abhängigkeiten ermöglicht.
|
||||
|
||||
## Hauptkomponenten
|
||||
|
||||
### Container
|
||||
|
||||
Der zentrale Service-Container, der Instanzen erstellt und verwaltet.
|
||||
|
||||
**Hauptfunktionen:**
|
||||
- Service-Erstellung und -Auflösung
|
||||
- Singleton-Verwaltung
|
||||
- Rekursive Abhängigkeitsauflösung
|
||||
|
||||
### Initializer-Attribut
|
||||
|
||||
Das `#[Initializer]`-Attribut kennzeichnet Klassen, die Services im Container registrieren können.
|
||||
|
||||
**Beispiel:**
|
||||
```php
|
||||
#[Initializer]
|
||||
readonly class AnalyticsInitializer
|
||||
{
|
||||
public function __invoke(Container $container): Analytics
|
||||
{
|
||||
// Service erstellen und konfigurieren
|
||||
return $analytics;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Verwendung
|
||||
|
||||
### Service definieren
|
||||
|
||||
```php
|
||||
// Service-Interface
|
||||
interface MyServiceInterface
|
||||
{
|
||||
public function doSomething(): void;
|
||||
}
|
||||
|
||||
// Konkrete Implementierung
|
||||
class MyService implements MyServiceInterface
|
||||
{
|
||||
public function doSomething(): void
|
||||
{
|
||||
// Implementierung
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Service registrieren
|
||||
|
||||
```php
|
||||
#[Initializer]
|
||||
class MyServiceInitializer
|
||||
{
|
||||
public function __invoke(Container $container): MyServiceInterface
|
||||
{
|
||||
return new MyService();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Service verwenden
|
||||
|
||||
```php
|
||||
class MyController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly MyServiceInterface $myService
|
||||
) {}
|
||||
|
||||
public function action(): void
|
||||
{
|
||||
$this->myService->doSomething();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Prinzipien
|
||||
|
||||
- **Automatische Auflösung**: Abhängigkeiten werden anhand von Typ-Hints automatisch aufgelöst
|
||||
- **Lazy Loading**: Services werden erst erstellt, wenn sie benötigt werden
|
||||
- **Singleton-Modus**: Standardmäßig werden Services als Singletons verwaltet
|
||||
439
backups/docs-backup-20250731125004/framework/error-boundaries.md
Normal file
439
backups/docs-backup-20250731125004/framework/error-boundaries.md
Normal file
@@ -0,0 +1,439 @@
|
||||
# Error Boundaries
|
||||
|
||||
Error Boundaries provide graceful degradation and prevent cascading failures in the application. They act as a safety net that catches errors and provides fallback functionality instead of letting the entire system fail.
|
||||
|
||||
## Overview
|
||||
|
||||
The Error Boundary system implements multiple patterns for resilient error handling:
|
||||
|
||||
- **Fallback Mechanisms** - Provide alternative functionality when operations fail
|
||||
- **Retry Strategies** - Automatically retry failed operations with configurable strategies
|
||||
- **Circuit Breaker Pattern** - Prevent repeated calls to failing services
|
||||
- **Bulk Operations** - Handle partial failures in batch processing
|
||||
- **Timeout Protection** - Prevent long-running operations from blocking the system
|
||||
|
||||
## Basic Usage
|
||||
|
||||
### Simple Error Boundary
|
||||
|
||||
```php
|
||||
use App\Framework\ErrorBoundaries\ErrorBoundary;
|
||||
use App\Framework\ErrorBoundaries\BoundaryConfig;
|
||||
|
||||
$boundary = new ErrorBoundary('user_service', BoundaryConfig::externalService());
|
||||
|
||||
$result = $boundary->execute(
|
||||
operation: fn() => $userService->getUser($id),
|
||||
fallback: fn() => $this->getCachedUser($id)
|
||||
);
|
||||
```
|
||||
|
||||
### Factory Pattern
|
||||
|
||||
```php
|
||||
use App\Framework\ErrorBoundaries\ErrorBoundaryFactory;
|
||||
|
||||
$factory = $container->get(ErrorBoundaryFactory::class);
|
||||
|
||||
// Create boundary for different contexts
|
||||
$dbBoundary = $factory->createForDatabase('user_queries');
|
||||
$apiBoundary = $factory->createForExternalService('payment_api');
|
||||
$uiBoundary = $factory->createForUI('user_dashboard');
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Predefined Configurations
|
||||
|
||||
```php
|
||||
// Critical operations - maximum resilience
|
||||
BoundaryConfig::critical()
|
||||
|
||||
// External services - network-aware retries
|
||||
BoundaryConfig::externalService()
|
||||
|
||||
// Database operations - transaction-safe retries
|
||||
BoundaryConfig::database()
|
||||
|
||||
// UI components - fast failure for user experience
|
||||
BoundaryConfig::ui()
|
||||
|
||||
// Background jobs - long retry cycles
|
||||
BoundaryConfig::backgroundJob()
|
||||
|
||||
// Development - permissive for debugging
|
||||
BoundaryConfig::development()
|
||||
|
||||
// Fail fast - no retries
|
||||
BoundaryConfig::failFast()
|
||||
```
|
||||
|
||||
### Custom Configuration
|
||||
|
||||
```php
|
||||
$config = new BoundaryConfig(
|
||||
maxRetries: 3,
|
||||
retryStrategy: RetryStrategy::EXPONENTIAL_JITTER,
|
||||
baseDelay: Duration::fromMilliseconds(100),
|
||||
maxDelay: Duration::fromSeconds(5),
|
||||
circuitBreakerEnabled: true,
|
||||
circuitBreakerThreshold: 5,
|
||||
circuitBreakerTimeout: Duration::fromMinutes(1),
|
||||
maxBulkErrorRate: 0.3,
|
||||
enableMetrics: true,
|
||||
enableTracing: false
|
||||
);
|
||||
```
|
||||
|
||||
## Execution Strategies
|
||||
|
||||
### Standard Execution with Fallback
|
||||
|
||||
```php
|
||||
$result = $boundary->execute(
|
||||
operation: fn() => $service->riskyOperation(),
|
||||
fallback: fn() => $service->safeAlternative()
|
||||
);
|
||||
```
|
||||
|
||||
### Optional Execution (Returns null on failure)
|
||||
|
||||
```php
|
||||
$result = $boundary->executeOptional(
|
||||
operation: fn() => $service->optionalOperation(),
|
||||
fallback: fn() => $service->defaultValue() // Optional fallback
|
||||
);
|
||||
```
|
||||
|
||||
### Default Value on Failure
|
||||
|
||||
```php
|
||||
$result = $boundary->executeWithDefault(
|
||||
operation: fn() => $service->getValue(),
|
||||
defaultValue: 'default_value'
|
||||
);
|
||||
```
|
||||
|
||||
### Result Wrapper
|
||||
|
||||
```php
|
||||
$result = $boundary->executeForResult(
|
||||
operation: fn() => $service->operation()
|
||||
);
|
||||
|
||||
if ($result->isSuccess()) {
|
||||
$value = $result->getValue();
|
||||
} else {
|
||||
$error = $result->getError();
|
||||
}
|
||||
```
|
||||
|
||||
## Retry Strategies
|
||||
|
||||
### Fixed Delay
|
||||
|
||||
```php
|
||||
RetryStrategy::FIXED // Same delay between retries
|
||||
```
|
||||
|
||||
### Linear Backoff
|
||||
|
||||
```php
|
||||
RetryStrategy::LINEAR // Linearly increasing delay
|
||||
```
|
||||
|
||||
### Exponential Backoff
|
||||
|
||||
```php
|
||||
RetryStrategy::EXPONENTIAL // Exponentially increasing delay
|
||||
```
|
||||
|
||||
### Exponential with Jitter
|
||||
|
||||
```php
|
||||
RetryStrategy::EXPONENTIAL_JITTER // Exponential + random jitter
|
||||
```
|
||||
|
||||
## Circuit Breaker Pattern
|
||||
|
||||
```php
|
||||
$config = new BoundaryConfig(
|
||||
circuitBreakerEnabled: true,
|
||||
circuitBreakerThreshold: 5, // Open after 5 failures
|
||||
circuitBreakerTimeout: Duration::fromMinutes(2) // Try again after 2 minutes
|
||||
);
|
||||
|
||||
$result = $boundary->executeWithCircuitBreaker(
|
||||
operation: fn() => $externalService->call(),
|
||||
fallback: fn() => $this->getCachedResponse()
|
||||
);
|
||||
```
|
||||
|
||||
## Bulk Operations
|
||||
|
||||
Handle batch processing with partial failure tolerance:
|
||||
|
||||
```php
|
||||
$items = [1, 2, 3, 4, 5];
|
||||
|
||||
$result = $boundary->executeBulk($items, function($item) {
|
||||
if ($item % 2 === 0) {
|
||||
throw new Exception("Even numbers fail");
|
||||
}
|
||||
return $item * 2;
|
||||
});
|
||||
|
||||
echo "Processed: {$result->getProcessedCount()}/{$result->getTotalCount()}\n";
|
||||
echo "Success rate: {$result->getSuccessRate()}%\n";
|
||||
|
||||
foreach ($result->getResults() as $key => $value) {
|
||||
echo "Item {$key}: {$value}\n";
|
||||
}
|
||||
|
||||
foreach ($result->getErrors() as $key => $error) {
|
||||
echo "Error {$key}: {$error->getMessage()}\n";
|
||||
}
|
||||
```
|
||||
|
||||
## Timeout Protection
|
||||
|
||||
```php
|
||||
$result = $boundary->executeWithTimeout(
|
||||
operation: fn() => $longRunningService->process(),
|
||||
fallback: fn() => 'Operation timed out',
|
||||
timeoutSeconds: 30
|
||||
);
|
||||
```
|
||||
|
||||
## Parallel Operations
|
||||
|
||||
Execute multiple operations with individual boundaries:
|
||||
|
||||
```php
|
||||
$operations = [
|
||||
'user_data' => fn() => $userService->getData(),
|
||||
'preferences' => fn() => $prefsService->getPreferences(),
|
||||
'notifications' => fn() => $notificationService->getCount()
|
||||
];
|
||||
|
||||
$results = $boundary->executeParallel($operations);
|
||||
|
||||
foreach ($results as $name => $result) {
|
||||
if ($result->isSuccess()) {
|
||||
$data[$name] = $result->getValue();
|
||||
} else {
|
||||
$data[$name] = null; // Or default value
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## HTTP Middleware Integration
|
||||
|
||||
Automatic error boundary protection for HTTP requests:
|
||||
|
||||
```php
|
||||
// In middleware registration
|
||||
$app->addMiddleware(ErrorBoundaryMiddleware::class);
|
||||
```
|
||||
|
||||
The middleware automatically:
|
||||
- Creates boundaries based on route patterns
|
||||
- Provides JSON fallback responses for API routes
|
||||
- Provides HTML error pages for web routes
|
||||
- Logs failures for monitoring
|
||||
|
||||
## Environment Configuration
|
||||
|
||||
Configure boundaries via environment variables:
|
||||
|
||||
```env
|
||||
# Global settings
|
||||
ERROR_BOUNDARY_ENABLED=true
|
||||
|
||||
# Route-specific configuration
|
||||
ERROR_BOUNDARY_ROUTE_API_USER_MAX_RETRIES=5
|
||||
ERROR_BOUNDARY_ROUTE_API_USER_CIRCUIT_BREAKER_ENABLED=true
|
||||
ERROR_BOUNDARY_ROUTE_API_USER_BASE_DELAY_MS=200
|
||||
```
|
||||
|
||||
## Console Commands
|
||||
|
||||
### Test Error Boundaries
|
||||
|
||||
```bash
|
||||
# Test basic functionality
|
||||
php console.php boundary:test basic
|
||||
|
||||
# Test retry strategies
|
||||
php console.php boundary:test retry
|
||||
|
||||
# Test circuit breaker
|
||||
php console.php boundary:test circuit
|
||||
|
||||
# Test bulk operations
|
||||
php console.php boundary:test bulk
|
||||
```
|
||||
|
||||
### Monitor Circuit Breakers
|
||||
|
||||
```bash
|
||||
# Show circuit breaker statistics
|
||||
php console.php boundary:stats
|
||||
|
||||
# Reset specific circuit breaker
|
||||
php console.php boundary:reset user_service
|
||||
|
||||
# Reset all circuit breakers
|
||||
php console.php boundary:reset
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Choose Appropriate Configurations
|
||||
|
||||
```php
|
||||
// API endpoints - use external service config
|
||||
$apiBoundary = $factory->createForExternalService('payment_api');
|
||||
|
||||
// Database queries - use database config
|
||||
$dbBoundary = $factory->createForDatabase('user_queries');
|
||||
|
||||
// UI components - use UI config for fast failures
|
||||
$uiBoundary = $factory->createForUI('dashboard_widget');
|
||||
```
|
||||
|
||||
### 2. Meaningful Fallbacks
|
||||
|
||||
```php
|
||||
// Good - provides useful fallback
|
||||
$boundary->execute(
|
||||
operation: fn() => $service->getLiveData(),
|
||||
fallback: fn() => $service->getCachedData()
|
||||
);
|
||||
|
||||
// Avoid - fallback provides no value
|
||||
$boundary->execute(
|
||||
operation: fn() => $service->getData(),
|
||||
fallback: fn() => null
|
||||
);
|
||||
```
|
||||
|
||||
### 3. Monitor Circuit Breakers
|
||||
|
||||
```php
|
||||
// Set up alerting for circuit breaker state changes
|
||||
$boundary->executeWithCircuitBreaker(
|
||||
operation: fn() => $service->call(),
|
||||
fallback: function() {
|
||||
$this->logger->warning('Circuit breaker activated for service');
|
||||
return $this->getFallbackData();
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
### 4. Handle Bulk Operations Appropriately
|
||||
|
||||
```php
|
||||
$result = $boundary->executeBulk($items, $processor);
|
||||
|
||||
// Check if too many failures occurred
|
||||
if ($result->getErrorRate() > 50) {
|
||||
$this->logger->error('High error rate in bulk operation');
|
||||
// Consider stopping or alerting
|
||||
}
|
||||
```
|
||||
|
||||
## Integration Examples
|
||||
|
||||
### With Repositories
|
||||
|
||||
```php
|
||||
class UserRepository
|
||||
{
|
||||
public function __construct(
|
||||
private ErrorBoundaryFactory $boundaryFactory,
|
||||
private DatabaseConnection $db
|
||||
) {}
|
||||
|
||||
public function findById(int $id): ?User
|
||||
{
|
||||
$boundary = $this->boundaryFactory->createForDatabase('user_find');
|
||||
|
||||
return $boundary->executeOptional(
|
||||
operation: fn() => $this->db->query('SELECT * FROM users WHERE id = ?', [$id]),
|
||||
fallback: fn() => $this->getCachedUser($id)
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### With External APIs
|
||||
|
||||
```php
|
||||
class PaymentService
|
||||
{
|
||||
public function processPayment(Payment $payment): PaymentResult
|
||||
{
|
||||
$boundary = $this->boundaryFactory->createForExternalService('payment_gateway');
|
||||
|
||||
return $boundary->execute(
|
||||
operation: fn() => $this->gateway->process($payment),
|
||||
fallback: fn() => $this->queueForLaterProcessing($payment)
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### With Background Jobs
|
||||
|
||||
```php
|
||||
class EmailJob
|
||||
{
|
||||
public function handle(): void
|
||||
{
|
||||
$boundary = $this->boundaryFactory->createForBackgroundJob('email_sending');
|
||||
|
||||
$boundary->executeBulk($this->emails, function($email) {
|
||||
$this->mailer->send($email);
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
Error boundaries can throw specific exceptions:
|
||||
|
||||
- `BoundaryFailedException` - When both operation and fallback fail
|
||||
- `BoundaryTimeoutException` - When operations exceed timeout limits
|
||||
|
||||
```php
|
||||
try {
|
||||
$result = $boundary->execute($operation, $fallback);
|
||||
} catch (BoundaryFailedException $e) {
|
||||
$this->logger->error('Boundary failed completely', [
|
||||
'boundary' => $e->getBoundaryName(),
|
||||
'original_error' => $e->getOriginalException()?->getMessage(),
|
||||
'fallback_error' => $e->getFallbackException()?->getMessage(),
|
||||
]);
|
||||
} catch (BoundaryTimeoutException $e) {
|
||||
$this->logger->warning('Operation timed out', [
|
||||
'boundary' => $e->getBoundaryName(),
|
||||
'execution_time' => $e->getExecutionTime(),
|
||||
'timeout_limit' => $e->getTimeoutLimit(),
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
1. **Circuit Breakers** - Use file-based storage for simplicity, consider Redis for high-traffic applications
|
||||
2. **Retry Delays** - Use jitter to avoid thundering herd problems
|
||||
3. **Bulk Operations** - Set appropriate error rate thresholds to prevent resource exhaustion
|
||||
4. **Timeouts** - PHP's synchronous nature limits true timeout implementation
|
||||
|
||||
## Security Considerations
|
||||
|
||||
1. **Information Disclosure** - Ensure fallbacks don't leak sensitive information
|
||||
2. **Resource Exhaustion** - Configure appropriate timeouts and retry limits
|
||||
3. **Circuit Breaker State** - Protect circuit breaker state files from unauthorized access
|
||||
521
backups/docs-backup-20250731125004/framework/error-reporting.md
Normal file
521
backups/docs-backup-20250731125004/framework/error-reporting.md
Normal file
@@ -0,0 +1,521 @@
|
||||
# Error Reporting & Analytics
|
||||
|
||||
Das Error Reporting System bietet strukturierte Fehlerberichterstattung und erweiterte Analytics für das Framework. Es erfasst, analysiert und visualisiert Fehler mit umfassendem Kontext für bessere Debugging- und Monitoring-Möglichkeiten.
|
||||
|
||||
## Überblick
|
||||
|
||||
Das System implementiert folgende Funktionen:
|
||||
|
||||
- **Strukturierte Fehlerberichte** - Umfassende Kontext-Erfassung
|
||||
- **Analytics Engine** - Trend-Analyse und Anomalie-Erkennung
|
||||
- **Predictive Insights** - Vorhersagen und Empfehlungen
|
||||
- **Context Processors** - Automatische Anreicherung mit Request/User-Kontext
|
||||
- **Storage Interface** - Flexible Speicher-Implementierungen
|
||||
- **Console Commands** - Management und Monitoring Tools
|
||||
|
||||
## Basic Usage
|
||||
|
||||
### Error Reporter
|
||||
|
||||
```php
|
||||
use App\Framework\ErrorReporting\ErrorReporter;
|
||||
|
||||
$reporter = $container->get(ErrorReporter::class);
|
||||
|
||||
// Report an exception
|
||||
$reportId = $reporter->reportThrowable($exception);
|
||||
|
||||
// Report manual error
|
||||
$reportId = $reporter->reportError('error', 'Something went wrong', [
|
||||
'user_action' => 'delete_file',
|
||||
'file_id' => 123
|
||||
]);
|
||||
```
|
||||
|
||||
### Mit Request Context
|
||||
|
||||
```php
|
||||
$contextualReporter = $reporter->withRequestContext(
|
||||
method: 'POST',
|
||||
route: '/api/users',
|
||||
requestId: $requestId,
|
||||
userAgent: $userAgent,
|
||||
ipAddress: $clientIp
|
||||
);
|
||||
|
||||
$reportId = $contextualReporter->reportThrowable($exception);
|
||||
```
|
||||
|
||||
### Mit User Context
|
||||
|
||||
```php
|
||||
$userReporter = $reporter->withUserContext(
|
||||
userId: $user->getId(),
|
||||
sessionId: $session->getId()
|
||||
);
|
||||
|
||||
$reportId = $userReporter->reportError('warning', 'User action failed');
|
||||
```
|
||||
|
||||
## Error Report Structure
|
||||
|
||||
```php
|
||||
$report = ErrorReport::fromThrowable($exception)
|
||||
->withUser($userId, $sessionId)
|
||||
->withRequest($method, $route, $requestId, $userAgent, $ipAddress)
|
||||
->withPerformance($executionTime, $memoryUsage)
|
||||
->withTags(['api', 'payment'])
|
||||
->withBreadcrumbs($breadcrumbs)
|
||||
->withCustomData(['order_id' => 12345]);
|
||||
```
|
||||
|
||||
### Report Properties
|
||||
|
||||
- **Basic Info**: ID, timestamp, level, message, exception class
|
||||
- **Location**: File, line, stack trace
|
||||
- **User Context**: User ID, session ID
|
||||
- **Request Context**: Route, method, IP, user agent, request data
|
||||
- **Performance**: Execution time, memory usage
|
||||
- **Metadata**: Tags, breadcrumbs, custom data, environment info
|
||||
- **Analytics**: Fingerprint, severity level
|
||||
|
||||
## Analytics Engine
|
||||
|
||||
### Anomalie-Erkennung
|
||||
|
||||
```php
|
||||
use App\Framework\ErrorReporting\Analytics\ErrorAnalyticsEngine;
|
||||
|
||||
$analytics = $container->get(ErrorAnalyticsEngine::class);
|
||||
|
||||
$from = new DateTimeImmutable('-24 hours');
|
||||
$to = new DateTimeImmutable();
|
||||
|
||||
// Detect anomalies and spikes
|
||||
$anomalies = $analytics->detectAnomalies($from, $to);
|
||||
|
||||
foreach ($anomalies as $anomaly) {
|
||||
echo "Anomaly detected: {$anomaly['type']} at {$anomaly['period']}\n";
|
||||
echo "Count: {$anomaly['count']} (expected: {$anomaly['expected']})\n";
|
||||
echo "Z-Score: {$anomaly['z_score']}\n";
|
||||
}
|
||||
```
|
||||
|
||||
### Error Velocity
|
||||
|
||||
```php
|
||||
// Calculate rate of change
|
||||
$velocity = $analytics->calculateErrorVelocity($from, $to);
|
||||
|
||||
$latest = end($velocity);
|
||||
echo "Latest trend: {$latest['direction']} ({$latest['velocity_percent']}%)\n";
|
||||
```
|
||||
|
||||
### Pattern Analysis
|
||||
|
||||
```php
|
||||
$patterns = $analytics->identifyPatterns($from, $to);
|
||||
|
||||
// Route correlations
|
||||
foreach ($patterns['route_correlations'] as $correlation) {
|
||||
echo "Route {$correlation['route']}: {$correlation['total_errors']} errors\n";
|
||||
echo "Clustered periods: {$correlation['clustered_periods']}\n";
|
||||
}
|
||||
|
||||
// Time patterns
|
||||
$timePatterns = $patterns['time_patterns'];
|
||||
echo "Peak hour: {$timePatterns['peak_hour']}\n";
|
||||
echo "Peak day: {$timePatterns['peak_day']}\n";
|
||||
```
|
||||
|
||||
### Predictive Insights
|
||||
|
||||
```php
|
||||
$predictions = $analytics->generatePredictiveInsights($from, $to);
|
||||
|
||||
$trend = $predictions['trend_prediction'];
|
||||
echo "Trend: {$trend['trend']} (slope: {$trend['slope']})\n";
|
||||
|
||||
foreach ($trend['predictions'] as $prediction) {
|
||||
echo "Period +{$prediction['period']}: ~{$prediction['predicted_count']} errors\n";
|
||||
}
|
||||
|
||||
$risk = $predictions['risk_assessment'];
|
||||
echo "Risk level: {$risk['level']} (factor: {$risk['risk_factor']})\n";
|
||||
```
|
||||
|
||||
### Health Report
|
||||
|
||||
```php
|
||||
$healthReport = $analytics->generateHealthReport($from, $to);
|
||||
|
||||
echo "Health Score: {$healthReport['health_score']}/100\n";
|
||||
|
||||
// Impact analysis
|
||||
$impact = $healthReport['impact'];
|
||||
echo "Affected users: {$impact['user_impact']['affected_users']}\n";
|
||||
echo "Critical errors: {$impact['business_impact']['critical_errors']}\n";
|
||||
|
||||
// Recommendations
|
||||
foreach ($healthReport['predictions']['recommendations'] as $rec) {
|
||||
echo "[{$rec['priority']}] {$rec['message']}\n";
|
||||
}
|
||||
```
|
||||
|
||||
## Search & Filtering
|
||||
|
||||
```php
|
||||
use App\Framework\ErrorReporting\ErrorReportCriteria;
|
||||
|
||||
// Recent critical errors
|
||||
$criteria = ErrorReportCriteria::critical();
|
||||
$reports = $reporter->findReports($criteria);
|
||||
|
||||
// Errors by user
|
||||
$criteria = ErrorReportCriteria::byUser('user123');
|
||||
$reports = $reporter->findReports($criteria);
|
||||
|
||||
// Complex search
|
||||
$criteria = ErrorReportCriteria::recent(48) // Last 48 hours
|
||||
->withLevels(['error', 'critical'])
|
||||
->withEnvironment('production')
|
||||
->withPagination(50, 0);
|
||||
|
||||
$reports = $reporter->findReports($criteria);
|
||||
```
|
||||
|
||||
### Search Criteria Options
|
||||
|
||||
```php
|
||||
$criteria = new ErrorReportCriteria(
|
||||
from: $fromDate,
|
||||
to: $toDate,
|
||||
levels: ['error', 'critical'],
|
||||
exceptions: ['DatabaseException', 'PaymentException'],
|
||||
routes: ['/api/payment', '/api/orders'],
|
||||
methods: ['POST', 'PUT'],
|
||||
userId: 'user123',
|
||||
environment: 'production',
|
||||
tags: ['payment', 'critical'],
|
||||
search: 'connection timeout',
|
||||
fingerprint: 'abc123',
|
||||
minSeverity: 2,
|
||||
maxSeverity: 4,
|
||||
limit: 100,
|
||||
offset: 0,
|
||||
orderBy: 'timestamp',
|
||||
orderDir: 'DESC'
|
||||
);
|
||||
```
|
||||
|
||||
## Context Processors
|
||||
|
||||
### Request Context Processor
|
||||
|
||||
Automatische Anreicherung mit HTTP Request Informationen:
|
||||
|
||||
- Method, Route, User-Agent, IP-Adresse
|
||||
- Request Data (GET, POST, JSON) - sanitized
|
||||
- Execution Time, Memory Usage
|
||||
- Tags (API, AJAX, Method)
|
||||
|
||||
### User Context Processor
|
||||
|
||||
Automatische Anreicherung mit User Informationen:
|
||||
|
||||
- User ID aus Session
|
||||
- Session ID
|
||||
- User Breadcrumbs
|
||||
- Tags (authenticated/anonymous)
|
||||
|
||||
```php
|
||||
use App\Framework\ErrorReporting\Processors\UserContextProcessor;
|
||||
|
||||
// Add breadcrumb from application code
|
||||
UserContextProcessor::addBreadcrumb(
|
||||
message: 'User clicked delete button',
|
||||
category: 'user_action',
|
||||
level: 'info',
|
||||
data: ['file_id' => 123]
|
||||
);
|
||||
```
|
||||
|
||||
## HTTP Middleware
|
||||
|
||||
Automatische Fehlerberichterstattung für HTTP Requests:
|
||||
|
||||
```php
|
||||
// Automatically registered via initializer
|
||||
$app->addMiddleware(ErrorReportingMiddleware::class);
|
||||
```
|
||||
|
||||
Das Middleware:
|
||||
- Fängt alle ungefangenen Exceptions ab
|
||||
- Fügt Request-Kontext automatisch hinzu
|
||||
- Sanitized Request-Daten
|
||||
- Bestimmt Client IP korrekt (X-Forwarded-For, etc.)
|
||||
|
||||
## Console Commands
|
||||
|
||||
### Statistiken anzeigen
|
||||
|
||||
```bash
|
||||
# Last 24 hours (default)
|
||||
php console.php errors:stats
|
||||
|
||||
# Last 48 hours
|
||||
php console.php errors:stats 48
|
||||
```
|
||||
|
||||
Zeigt:
|
||||
- Total/Unique Errors
|
||||
- Critical Error Count
|
||||
- Error Rate & Health Score
|
||||
- Errors by Level
|
||||
- Top Exceptions & Routes
|
||||
- Insights & Recommendations
|
||||
|
||||
### Advanced Analytics
|
||||
|
||||
```bash
|
||||
# Advanced analytics report
|
||||
php console.php errors:analytics 24
|
||||
```
|
||||
|
||||
Zeigt:
|
||||
- Anomaly Detection
|
||||
- Error Velocity
|
||||
- Pattern Analysis
|
||||
- Predictive Insights
|
||||
|
||||
### Health Report
|
||||
|
||||
```bash
|
||||
# Comprehensive health report
|
||||
php console.php errors:health 24
|
||||
```
|
||||
|
||||
Zeigt:
|
||||
- Overall Health Score
|
||||
- Key Metrics
|
||||
- Impact Analysis
|
||||
- Recommendations
|
||||
|
||||
### Search Errors
|
||||
|
||||
```bash
|
||||
# Search by term
|
||||
php console.php errors:search "database connection"
|
||||
```
|
||||
|
||||
### Show Error Details
|
||||
|
||||
```bash
|
||||
# Show detailed error report
|
||||
php console.php errors:show <report-id>
|
||||
```
|
||||
|
||||
### Cleanup
|
||||
|
||||
```bash
|
||||
# Delete errors older than 30 days (default)
|
||||
php console.php errors:cleanup
|
||||
|
||||
# Delete errors older than 7 days
|
||||
php console.php errors:cleanup 7
|
||||
```
|
||||
|
||||
## Environment Configuration
|
||||
|
||||
```env
|
||||
# Enable/disable error reporting
|
||||
ERROR_REPORTING_ENABLED=true
|
||||
|
||||
# Enable async processing via queue
|
||||
ERROR_REPORTING_ASYNC=true
|
||||
|
||||
# Filter levels (comma-separated)
|
||||
ERROR_REPORTING_FILTER_LEVELS=error,critical,alert,emergency
|
||||
```
|
||||
|
||||
## Database Schema
|
||||
|
||||
Das System benötigt die `error_reports` Tabelle:
|
||||
|
||||
```bash
|
||||
php console.php db:migrate
|
||||
```
|
||||
|
||||
Die Migration erstellt eine optimierte Tabelle mit:
|
||||
- Primary Key: String ID (32 chars)
|
||||
- Indexes für häufige Queries
|
||||
- JSON Felder für flexible Daten
|
||||
- Analytics-Felder (fingerprint, severity_level)
|
||||
|
||||
## Storage Interface
|
||||
|
||||
Custom Storage Implementierungen möglich:
|
||||
|
||||
```php
|
||||
use App\Framework\ErrorReporting\Storage\ErrorReportStorageInterface;
|
||||
|
||||
class RedisErrorReportStorage implements ErrorReportStorageInterface
|
||||
{
|
||||
public function store(ErrorReport $report): void
|
||||
{
|
||||
// Custom implementation
|
||||
}
|
||||
|
||||
// ... other methods
|
||||
}
|
||||
|
||||
// In initializer
|
||||
$container->bind(ErrorReportStorageInterface::class, RedisErrorReportStorage::class);
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Structured Error Messages
|
||||
|
||||
```php
|
||||
// Good - structured context
|
||||
$reporter->reportError('error', 'Payment processing failed', [
|
||||
'payment_id' => $paymentId,
|
||||
'amount' => $amount,
|
||||
'currency' => $currency,
|
||||
'gateway_response' => $gatewayResponse
|
||||
]);
|
||||
|
||||
// Avoid - unstructured message
|
||||
$reporter->reportError('error', "Payment $paymentId failed for $amount $currency");
|
||||
```
|
||||
|
||||
### 2. Appropriate Log Levels
|
||||
|
||||
```php
|
||||
// Critical system failures
|
||||
$reporter->reportThrowable($exception, 'critical');
|
||||
|
||||
// Business logic errors
|
||||
$reporter->reportThrowable($exception, 'error');
|
||||
|
||||
// Recoverable issues
|
||||
$reporter->reportError('warning', 'Deprecated API used');
|
||||
|
||||
// Development info
|
||||
$reporter->reportError('info', 'Cache miss occurred');
|
||||
```
|
||||
|
||||
### 3. Sensitive Data Handling
|
||||
|
||||
```php
|
||||
// Data is automatically sanitized by processors
|
||||
// But be explicit about sensitive data
|
||||
$reporter->reportError('error', 'Authentication failed', [
|
||||
'username' => $username,
|
||||
'ip_address' => $ip,
|
||||
// Don't include: password, tokens, etc.
|
||||
]);
|
||||
```
|
||||
|
||||
### 4. Custom Tags for Filtering
|
||||
|
||||
```php
|
||||
$report = ErrorReport::fromThrowable($exception)
|
||||
->withTags(['payment', 'external_api', 'critical']);
|
||||
```
|
||||
|
||||
### 5. Breadcrumbs for Context
|
||||
|
||||
```php
|
||||
// Add breadcrumbs throughout user journey
|
||||
UserContextProcessor::addBreadcrumb('User logged in');
|
||||
UserContextProcessor::addBreadcrumb('Started checkout process');
|
||||
UserContextProcessor::addBreadcrumb('Selected payment method', 'action', 'info', [
|
||||
'method' => 'credit_card'
|
||||
]);
|
||||
|
||||
// Error report will include full journey
|
||||
```
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
1. **Async Processing** - Enable für Production (`ERROR_REPORTING_ASYNC=true`)
|
||||
2. **Data Sanitization** - Automatic für Request Data
|
||||
3. **Storage Optimization** - Indexes für häufige Queries
|
||||
4. **Cleanup Strategy** - Regular cleanup alter Reports
|
||||
5. **Memory Usage** - Limited Context Data Size
|
||||
|
||||
## Security Considerations
|
||||
|
||||
1. **Data Sanitization** - Sensitive Data wird automatisch entfernt
|
||||
2. **Access Control** - Console Commands benötigen entsprechende Rechte
|
||||
3. **Storage Security** - Database Access Controls
|
||||
4. **IP Address Handling** - Respects Privacy Regulations
|
||||
5. **Session Security** - Nur Session IDs, keine Session Daten
|
||||
|
||||
## Integration Examples
|
||||
|
||||
### Mit Custom Exception Handler
|
||||
|
||||
```php
|
||||
class CustomExceptionHandler
|
||||
{
|
||||
public function __construct(
|
||||
private ErrorReporter $reporter
|
||||
) {}
|
||||
|
||||
public function handle(Throwable $exception): void
|
||||
{
|
||||
// Report the error
|
||||
$this->reporter->reportThrowable($exception);
|
||||
|
||||
// Continue with normal error handling
|
||||
$this->originalHandler->handle($exception);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Mit Business Logic
|
||||
|
||||
```php
|
||||
class PaymentService
|
||||
{
|
||||
public function processPayment(Payment $payment): PaymentResult
|
||||
{
|
||||
try {
|
||||
return $this->gateway->process($payment);
|
||||
} catch (PaymentException $e) {
|
||||
// Report with business context
|
||||
$this->reporter->reportThrowable($e, 'error', [
|
||||
'payment_id' => $payment->getId(),
|
||||
'amount' => $payment->getAmount(),
|
||||
'gateway' => $this->gateway->getName(),
|
||||
]);
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Mit Background Jobs
|
||||
|
||||
```php
|
||||
class EmailJob
|
||||
{
|
||||
public function handle(): void
|
||||
{
|
||||
try {
|
||||
$this->sendEmails();
|
||||
} catch (Throwable $e) {
|
||||
$this->reporter->reportThrowable($e, 'error', [
|
||||
'job' => 'email_sending',
|
||||
'batch_size' => count($this->emails),
|
||||
]);
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
92
backups/docs-backup-20250731125004/framework/http/README.md
Normal file
92
backups/docs-backup-20250731125004/framework/http/README.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# HTTP-Modul Dokumentation
|
||||
|
||||
## Übersicht
|
||||
|
||||
Das HTTP-Modul stellt Komponenten für die Verarbeitung von HTTP-Anfragen und -Antworten bereit.
|
||||
|
||||
## Hauptkomponenten
|
||||
|
||||
### Request
|
||||
|
||||
Repräsentiert eine HTTP-Anfrage mit Methoden zum Zugriff auf:
|
||||
- HTTP-Methode (`getMethod()`)
|
||||
- Pfad (`getPath()`)
|
||||
- Query-Parameter (`getQueryParams()`)
|
||||
- Request-Body
|
||||
- Headers
|
||||
|
||||
### Response
|
||||
|
||||
Repräsentiert eine HTTP-Antwort mit:
|
||||
- Status-Code (`getStatusCode()`)
|
||||
- Headers
|
||||
- Body
|
||||
|
||||
### Middleware
|
||||
|
||||
Ein Interface für HTTP-Middleware-Komponenten, die die Request-Verarbeitung verändern können:
|
||||
|
||||
```php
|
||||
interface Middleware
|
||||
{
|
||||
public function process(Request $request, callable $next): Response;
|
||||
}
|
||||
```
|
||||
|
||||
**Beispiel-Middleware:**
|
||||
```php
|
||||
class AnalyticsMiddleware implements Middleware
|
||||
{
|
||||
public function __construct(
|
||||
private readonly Analytics $analytics
|
||||
) {}
|
||||
|
||||
public function process(Request $request, callable $next): Response
|
||||
{
|
||||
// Request tracken
|
||||
$this->analytics->track('http_request', [
|
||||
'method' => $request->getMethod(),
|
||||
'path' => $request->getPath(),
|
||||
]);
|
||||
|
||||
// Request weiterleiten
|
||||
$response = $next($request);
|
||||
|
||||
// Response tracken
|
||||
$this->analytics->track('http_response', [
|
||||
'status_code' => $response->getStatusCode(),
|
||||
]);
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Integration mit anderen Modulen
|
||||
|
||||
- **Router**: Routing von HTTP-Requests zu Controllers
|
||||
- **Analytics**: Tracking von HTTP-Requests und -Responses
|
||||
- **Validation**: Validierung von Request-Daten
|
||||
|
||||
## Middlewares registrieren
|
||||
|
||||
In der Anwendungsklasse:
|
||||
|
||||
```php
|
||||
$this->addMiddleware(LoggingMiddleware::class);
|
||||
$this->addMiddleware(AnalyticsMiddleware::class);
|
||||
$this->addMiddleware(AuthenticationMiddleware::class);
|
||||
```
|
||||
|
||||
## Responses erzeugen
|
||||
|
||||
```php
|
||||
// JSON-Response
|
||||
return new JsonResponse(['success' => true]);
|
||||
|
||||
// HTML-Response
|
||||
return new HtmlResponse('<html><body>Hello World</body></html>');
|
||||
|
||||
// Redirect
|
||||
return new RedirectResponse('/dashboard');
|
||||
```
|
||||
42
backups/docs-backup-20250731125004/framework/index.md
Normal file
42
backups/docs-backup-20250731125004/framework/index.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# Framework-Dokumentation
|
||||
|
||||
## Übersicht
|
||||
|
||||
Diese Dokumentation beschreibt die Architektur, Komponenten und Verwendung des Framework-Kerns des Projekts.
|
||||
|
||||
## Hauptmodule
|
||||
|
||||
- [Analytics](/framework/analytics/README.md) - System zur Erfassung und Analyse von Anwendungsdaten
|
||||
- [Core](/framework/core/README.md) - Kernkomponenten und Event-System
|
||||
- [DI (Dependency Injection)](/framework/di/README.md) - Container und Service-Management
|
||||
- [HTTP](/framework/http/README.md) - HTTP-Request/Response-Handling
|
||||
|
||||
## Richtlinien und Muster
|
||||
|
||||
- [Modul-Checkliste](/framework/MODUL-CHECKLISTE.md) - Leitfaden für die Erstellung neuer Module
|
||||
- [Erweiterungsmuster](/framework/ERWEITERUNGSPATTERN.md) - Muster zur Erweiterung des Frameworks
|
||||
|
||||
## Modulare Architektur
|
||||
|
||||
Das Framework ist modular aufgebaut, mit klaren Verantwortlichkeiten für jedes Modul. Module kommunizieren über klar definierte Interfaces und den Event-Dispatcher.
|
||||
|
||||
### Neues Modul erstellen
|
||||
|
||||
Um ein neues Modul zu erstellen, folgen Sie der [Modul-Checkliste](/framework/MODUL-CHECKLISTE.md) und beachten Sie die folgenden Kernprinzipien:
|
||||
|
||||
1. Klare Verantwortlichkeiten definieren
|
||||
2. Dependency Injection verwenden
|
||||
3. Interface-basiertes Design umsetzen
|
||||
4. Event-basierte Kommunikation nutzen
|
||||
5. Externe Abhängigkeiten minimieren
|
||||
|
||||
### Framework erweitern
|
||||
|
||||
Es gibt verschiedene Möglichkeiten, das Framework zu erweitern:
|
||||
|
||||
1. **Middleware**: HTTP-Request-Pipeline erweitern
|
||||
2. **Event-Listener**: Auf System-Events reagieren
|
||||
3. **Service-Provider**: Eigene Services registrieren
|
||||
4. **Plugin-System**: Umfangreichere Erweiterungen implementieren
|
||||
|
||||
Weitere Details finden Sie im Dokument [Erweiterungsmuster](/framework/ERWEITERUNGSPATTERN.md).
|
||||
@@ -0,0 +1,350 @@
|
||||
# Framework Performance
|
||||
|
||||
> Performance optimization features and monitoring built into the PHP framework.
|
||||
|
||||
## 🔧 Built-in Performance Features
|
||||
|
||||
### Connection Pooling
|
||||
|
||||
The framework includes advanced database connection pooling with health monitoring:
|
||||
|
||||
```php
|
||||
// Automatic connection pooling
|
||||
$pool = new ConnectionPool([
|
||||
'min_connections' => 5,
|
||||
'max_connections' => 20,
|
||||
'idle_timeout' => 300,
|
||||
'health_check_interval' => 60
|
||||
]);
|
||||
|
||||
// Health monitoring
|
||||
$healthChecker = new ConnectionHealthChecker($pool);
|
||||
$healthStatus = $healthChecker->checkHealth();
|
||||
```
|
||||
|
||||
### Query Optimization
|
||||
|
||||
#### N+1 Query Prevention
|
||||
The framework automatically detects and eliminates N+1 queries:
|
||||
|
||||
```php
|
||||
// Automatic eager loading detection
|
||||
$users = $userRepository->findWithRelations(['posts', 'comments']);
|
||||
|
||||
// Batch loading for performance
|
||||
$posts = $postRepository->loadBatch($userIds);
|
||||
```
|
||||
|
||||
#### Query Caching
|
||||
Built-in query result caching with intelligent invalidation:
|
||||
|
||||
```php
|
||||
// Cache configuration
|
||||
$cacheConfig = [
|
||||
'default_ttl' => 3600,
|
||||
'strategy' => 'write-through',
|
||||
'invalidation' => 'tag-based'
|
||||
];
|
||||
|
||||
// Automatic query caching
|
||||
$result = $repository->findCached('user-posts-' . $userId);
|
||||
```
|
||||
|
||||
### View System Performance
|
||||
|
||||
#### Template Compilation
|
||||
PHP templates are compiled and cached for optimal performance:
|
||||
|
||||
```php
|
||||
// Template compilation
|
||||
$viewProcessor = new ViewProcessor([
|
||||
'cache_path' => '/var/cache/views',
|
||||
'auto_reload' => false, // Production setting
|
||||
'optimize' => true
|
||||
]);
|
||||
```
|
||||
|
||||
#### Fragment Caching
|
||||
Cache expensive template fragments:
|
||||
|
||||
```html
|
||||
<!-- Fragment caching in templates -->
|
||||
<cache key="user-stats-<?= $userId ?>" ttl="3600">
|
||||
<?php foreach($stats as $stat): ?>
|
||||
<div class="stat"><?= $stat->render() ?></div>
|
||||
<?php endforeach; ?>
|
||||
</cache>
|
||||
```
|
||||
|
||||
## 📊 Performance Monitoring
|
||||
|
||||
### Analytics Integration
|
||||
|
||||
The framework includes comprehensive performance analytics:
|
||||
|
||||
```php
|
||||
// Performance monitoring
|
||||
class PerformanceMiddleware implements HttpMiddleware
|
||||
{
|
||||
public function handle(Request $request, Next $next): Response
|
||||
{
|
||||
$startTime = microtime(true);
|
||||
$startMemory = memory_get_usage();
|
||||
|
||||
$response = $next($request);
|
||||
|
||||
$this->recordMetrics([
|
||||
'duration' => microtime(true) - $startTime,
|
||||
'memory' => memory_get_usage() - $startMemory,
|
||||
'route' => $request->getRoute(),
|
||||
'status' => $response->getStatusCode()
|
||||
]);
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Database Performance Tracking
|
||||
|
||||
Monitor database query performance automatically:
|
||||
|
||||
```php
|
||||
// Query performance logging
|
||||
class QueryLogger implements QueryMiddleware
|
||||
{
|
||||
public function beforeQuery(string $sql, array $params): void
|
||||
{
|
||||
$this->startTime = microtime(true);
|
||||
}
|
||||
|
||||
public function afterQuery(string $sql, array $params): void
|
||||
{
|
||||
$duration = microtime(true) - $this->startTime;
|
||||
|
||||
if ($duration > 0.1) { // Log slow queries
|
||||
$this->logger->warning('Slow query detected', [
|
||||
'sql' => $sql,
|
||||
'duration' => $duration,
|
||||
'params' => $params
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🚀 Optimization Strategies
|
||||
|
||||
### HTTP Layer Optimizations
|
||||
|
||||
#### Response Compression
|
||||
Automatic response compression based on content type:
|
||||
|
||||
```php
|
||||
// Compression middleware
|
||||
class CompressionMiddleware implements HttpMiddleware
|
||||
{
|
||||
public function handle(Request $request, Next $next): Response
|
||||
{
|
||||
$response = $next($request);
|
||||
|
||||
if ($this->shouldCompress($response)) {
|
||||
return $this->compress($response);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### HTTP Caching
|
||||
Intelligent HTTP caching with ETag support:
|
||||
|
||||
```php
|
||||
// Cache headers
|
||||
$response->headers->set('Cache-Control', 'public, max-age=3600');
|
||||
$response->headers->set('ETag', hash('sha256', $content));
|
||||
|
||||
// Conditional requests
|
||||
if ($request->headers->get('If-None-Match') === $etag) {
|
||||
return new Response('', 304);
|
||||
}
|
||||
```
|
||||
|
||||
### Asset Optimization
|
||||
|
||||
#### Static File Serving
|
||||
Optimized static file serving with proper headers:
|
||||
|
||||
```nginx
|
||||
# Nginx configuration for static assets
|
||||
location /assets/ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
add_header Vary "Accept-Encoding";
|
||||
|
||||
gzip_static on;
|
||||
brotli_static on;
|
||||
}
|
||||
```
|
||||
|
||||
#### Asset Bundling
|
||||
Framework integration with Vite for optimal asset bundling:
|
||||
|
||||
```php
|
||||
// Asset helper
|
||||
class AssetHelper
|
||||
{
|
||||
public function getAssetUrl(string $asset): string
|
||||
{
|
||||
$manifest = $this->loadManifest();
|
||||
return $manifest[$asset]['url'] ?? $asset;
|
||||
}
|
||||
|
||||
public function getCriticalCss(): string
|
||||
{
|
||||
return $this->inlineAsset('critical.css');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔍 Performance Profiling
|
||||
|
||||
### Built-in Profiler
|
||||
|
||||
Enable the framework profiler for detailed performance analysis:
|
||||
|
||||
```php
|
||||
// Profiler configuration
|
||||
$profiler = new FrameworkProfiler([
|
||||
'enabled' => $this->isDebugMode(),
|
||||
'storage' => 'file', // or 'redis'
|
||||
'threshold' => 100, // ms
|
||||
'collect' => [
|
||||
'queries',
|
||||
'views',
|
||||
'cache',
|
||||
'events'
|
||||
]
|
||||
]);
|
||||
```
|
||||
|
||||
### Memory Usage Tracking
|
||||
|
||||
Monitor memory usage throughout the request lifecycle:
|
||||
|
||||
```php
|
||||
// Memory tracking
|
||||
class MemoryTracker
|
||||
{
|
||||
public function trackOperation(string $operation, callable $callback)
|
||||
{
|
||||
$beforeMemory = memory_get_usage(true);
|
||||
$beforePeak = memory_get_peak_usage(true);
|
||||
|
||||
$result = $callback();
|
||||
|
||||
$afterMemory = memory_get_usage(true);
|
||||
$afterPeak = memory_get_peak_usage(true);
|
||||
|
||||
$this->recordMemoryUsage([
|
||||
'operation' => $operation,
|
||||
'memory_used' => $afterMemory - $beforeMemory,
|
||||
'peak_increase' => $afterPeak - $beforePeak
|
||||
]);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## ⚡ Performance Best Practices
|
||||
|
||||
### Database Best Practices
|
||||
|
||||
1. **Use Indexes**: Ensure proper database indexing
|
||||
2. **Lazy Loading**: Load data only when needed
|
||||
3. **Batch Operations**: Group database operations
|
||||
4. **Connection Reuse**: Leverage connection pooling
|
||||
|
||||
```php
|
||||
// Efficient database operations
|
||||
class UserService
|
||||
{
|
||||
public function getUsersWithPosts(array $userIds): array
|
||||
{
|
||||
// Single query with join instead of N+1
|
||||
return $this->repository->findUsersWithPosts($userIds);
|
||||
}
|
||||
|
||||
public function batchUpdateUsers(array $updates): void
|
||||
{
|
||||
// Batch update instead of individual queries
|
||||
$this->repository->batchUpdate($updates);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### View Optimization
|
||||
|
||||
1. **Template Caching**: Cache compiled templates
|
||||
2. **Fragment Caching**: Cache expensive view fragments
|
||||
3. **Lazy Loading**: Load view components on demand
|
||||
4. **Asset Optimization**: Minify and compress assets
|
||||
|
||||
```php
|
||||
// Optimized view rendering
|
||||
class OptimizedViewController
|
||||
{
|
||||
public function render(string $template, array $data): Response
|
||||
{
|
||||
// Use cached template if available
|
||||
$compiled = $this->templateCache->get($template);
|
||||
|
||||
if (!$compiled) {
|
||||
$compiled = $this->compiler->compile($template);
|
||||
$this->templateCache->set($template, $compiled);
|
||||
}
|
||||
|
||||
return $this->renderCompiled($compiled, $data);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📈 Monitoring & Alerts
|
||||
|
||||
### Performance Metrics Collection
|
||||
|
||||
Collect and analyze key performance metrics:
|
||||
|
||||
```php
|
||||
// Metrics collection
|
||||
$metrics = [
|
||||
'response_time' => $responseTime,
|
||||
'memory_usage' => memory_get_peak_usage(true),
|
||||
'database_queries' => $queryCount,
|
||||
'cache_hits' => $cacheHits,
|
||||
'cache_misses' => $cacheMisses
|
||||
];
|
||||
|
||||
$this->metricsCollector->record($metrics);
|
||||
```
|
||||
|
||||
### Alert Configuration
|
||||
|
||||
Set up alerts for performance degradation:
|
||||
|
||||
```php
|
||||
// Performance alerts
|
||||
$alertConfig = [
|
||||
'response_time_threshold' => 1000, // ms
|
||||
'memory_threshold' => 128 * 1024 * 1024, // 128MB
|
||||
'query_count_threshold' => 50,
|
||||
'error_rate_threshold' => 0.01 // 1%
|
||||
];
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*For general performance guidelines, see [Performance Guidelines](../../development/performance.md)*
|
||||
*For analytics configuration, see [Analytics System](../analytics/README.md)*
|
||||
359
backups/docs-backup-20250731125004/framework/views/overview.md
Normal file
359
backups/docs-backup-20250731125004/framework/views/overview.md
Normal file
@@ -0,0 +1,359 @@
|
||||
# View System Overview
|
||||
|
||||
> Advanced template processing system with DOM manipulation, component architecture, and intelligent caching.
|
||||
|
||||
## 🏗 Architecture
|
||||
|
||||
The view system is built around **DOM-based processing** using PHP 8.4's native HTML5 parser, enabling sophisticated template manipulation while maintaining performance through intelligent caching.
|
||||
|
||||
### Core Components
|
||||
|
||||
```
|
||||
src/Framework/View/
|
||||
├── Engine.php # Main template engine
|
||||
├── TemplateRenderer.php # Rendering coordinator
|
||||
├── DomProcessor.php # DOM manipulation interface
|
||||
├── RenderContext.php # Template context data
|
||||
├── ComponentRenderer.php # Component system
|
||||
├── Processors/ # Template processors
|
||||
├── Caching/ # Multi-level caching
|
||||
└── Loading/ # Template resolution
|
||||
```
|
||||
|
||||
## 📝 Basic Usage
|
||||
|
||||
### Simple Template Rendering
|
||||
|
||||
```php
|
||||
// Controller
|
||||
class HomeController
|
||||
{
|
||||
public function index(TemplateRenderer $renderer): ViewResult
|
||||
{
|
||||
return new ViewResult('home', [
|
||||
'title' => 'Welcome',
|
||||
'user' => $user,
|
||||
'stats' => $this->getStats()
|
||||
]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Template Structure
|
||||
|
||||
```html
|
||||
<!-- templates/home.view.php -->
|
||||
<layout name="main">
|
||||
<slot name="title">{title}</slot>
|
||||
<slot name="content">
|
||||
<div class="welcome">
|
||||
<h1>Hello, {user.name}!</h1>
|
||||
<div class="stats">
|
||||
<for data="stats" as="stat">
|
||||
<div class="stat-item">
|
||||
<span class="value">{stat.value}</span>
|
||||
<span class="label">{stat.label}</span>
|
||||
</div>
|
||||
</for>
|
||||
</div>
|
||||
</div>
|
||||
</slot>
|
||||
</layout>
|
||||
```
|
||||
|
||||
## 🧩 Component System
|
||||
|
||||
### Component Definition
|
||||
|
||||
```html
|
||||
<!-- components/card.view.php -->
|
||||
<div class="card {classes}">
|
||||
<if condition="title">
|
||||
<header class="card-header">
|
||||
<h3>{title}</h3>
|
||||
</header>
|
||||
</if>
|
||||
|
||||
<div class="card-body">
|
||||
<slot name="content">{content}</slot>
|
||||
</div>
|
||||
|
||||
<if condition="actions">
|
||||
<footer class="card-footer">
|
||||
<slot name="actions"></slot>
|
||||
</footer>
|
||||
</if>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Component Usage
|
||||
|
||||
```html
|
||||
<component name="card" title="User Profile" classes="profile-card">
|
||||
<slot name="content">
|
||||
<p>User: {user.name}</p>
|
||||
<p>Email: {user.email}</p>
|
||||
</slot>
|
||||
|
||||
<slot name="actions">
|
||||
<button>Edit Profile</button>
|
||||
<button>View History</button>
|
||||
</slot>
|
||||
</component>
|
||||
```
|
||||
|
||||
## 🔄 Template Processors
|
||||
|
||||
### Available Processors
|
||||
|
||||
| Processor | Purpose | Documentation |
|
||||
|-----------|---------|---------------|
|
||||
| **LayoutTagProcessor** | Layout system implementation | [Details](processors.md#layout) |
|
||||
| **ComponentProcessor** | Reusable UI components | [Details](processors.md#components) |
|
||||
| **SlotProcessor** | Content injection system | [Details](processors.md#slots) |
|
||||
| **IfProcessor** | Conditional rendering | [Details](processors.md#conditionals) |
|
||||
| **ForProcessor** | Loop iteration | [Details](processors.md#loops) |
|
||||
| **PlaceholderReplacer** | Variable substitution | [Details](processors.md#placeholders) |
|
||||
| **AssetInjector** | JS/CSS asset injection | [Details](processors.md#assets) |
|
||||
| **MetaManipulator** | Meta tag extraction | [Details](processors.md#meta) |
|
||||
|
||||
### Processing Pipeline
|
||||
|
||||
```
|
||||
1. Structure Processors
|
||||
├── LayoutTagProcessor # Apply layouts
|
||||
└── IncludeProcessor # Include external files
|
||||
|
||||
2. Component Processors
|
||||
├── ComponentProcessor # Process components
|
||||
└── SlotProcessor # Handle slots
|
||||
|
||||
3. Logic Processors
|
||||
├── IfProcessor # Conditional logic
|
||||
├── ForProcessor # Loops
|
||||
└── SwitchCaseProcessor # Switch statements
|
||||
|
||||
4. Content Processors
|
||||
├── PlaceholderReplacer # Variable substitution
|
||||
├── DateFormatProcessor # Date formatting
|
||||
└── MetaManipulator # Meta extraction
|
||||
|
||||
5. Asset Processors
|
||||
└── AssetInjector # CSS/JS injection
|
||||
|
||||
6. Optimization Processors
|
||||
├── CommentStripProcessor # Remove comments
|
||||
├── RemoveEmptyLinesProcessor
|
||||
└── VoidElementsSelfClosingProcessor
|
||||
```
|
||||
|
||||
## 🎯 Advanced Features
|
||||
|
||||
### Conditional Rendering
|
||||
|
||||
```html
|
||||
<!-- Simple conditions -->
|
||||
<if condition="user.isAdmin">
|
||||
<admin-panel></admin-panel>
|
||||
</if>
|
||||
|
||||
<!-- Complex conditions -->
|
||||
<if condition="user.role === 'admin' && features.adminPanel">
|
||||
<component name="admin-dashboard"></component>
|
||||
</if>
|
||||
|
||||
<!-- If-else chains -->
|
||||
<if condition="user.isAdmin">
|
||||
<admin-view></admin-view>
|
||||
<else-if condition="user.isModerator">
|
||||
<moderator-view></moderator-view>
|
||||
<else>
|
||||
<user-view></user-view>
|
||||
</if>
|
||||
```
|
||||
|
||||
### Loop Iteration
|
||||
|
||||
```html
|
||||
<!-- Simple loops -->
|
||||
<for data="users" as="user">
|
||||
<div class="user-card">
|
||||
<h3>{user.name}</h3>
|
||||
<p>{user.email}</p>
|
||||
</div>
|
||||
</for>
|
||||
|
||||
<!-- Loops with keys -->
|
||||
<for data="categories" as="category" key="categoryId">
|
||||
<section data-category="{categoryId}">
|
||||
<h2>{category.name}</h2>
|
||||
<for data="category.items" as="item">
|
||||
<article>{item.title}</article>
|
||||
</for>
|
||||
</section>
|
||||
</for>
|
||||
|
||||
<!-- Loops with index -->
|
||||
<for data="items" as="item" index="i">
|
||||
<div class="item-{i}">
|
||||
Position: {i + 1} - {item.name}
|
||||
</div>
|
||||
</for>
|
||||
```
|
||||
|
||||
### Layout System
|
||||
|
||||
```html
|
||||
<!-- Layout definition: layouts/main.view.php -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title><slot name="title">Default Title</slot></title>
|
||||
<meta name="description" content="<slot name="description"></slot>">
|
||||
<slot name="head"></slot>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<nav><!-- Navigation --></nav>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<slot name="content"></slot>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<slot name="footer">© 2024 Framework</slot>
|
||||
</footer>
|
||||
|
||||
<slot name="scripts"></slot>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
## 💾 Caching System
|
||||
|
||||
### Cache Strategies
|
||||
|
||||
```php
|
||||
// Automatic caching based on template analysis
|
||||
$cacheStrategy = $analyzer->determineCacheStrategy($template);
|
||||
|
||||
// Manual cache control
|
||||
$context = new RenderContext($data);
|
||||
$context->setCacheStrategy(CacheStrategy::FULL_PAGE);
|
||||
$context->setCacheTags(['user:123', 'posts']);
|
||||
$context->setCacheTtl(3600);
|
||||
```
|
||||
|
||||
### Cache Invalidation
|
||||
|
||||
```php
|
||||
// Tag-based invalidation
|
||||
$cache->invalidateByTags(['user:123']);
|
||||
|
||||
// Template-based invalidation
|
||||
$cache->invalidateTemplate('user-profile');
|
||||
|
||||
// Smart invalidation on data changes
|
||||
$user->save(); // Automatically invalidates user-related caches
|
||||
```
|
||||
|
||||
## 🔧 Template Functions
|
||||
|
||||
### Built-in Functions
|
||||
|
||||
```html
|
||||
<!-- URL generation -->
|
||||
<a href="{url('user.profile', {id: user.id})}">Profile</a>
|
||||
|
||||
<!-- Image slots with responsive images -->
|
||||
<img src="{imageSlot('hero', 'medium')}"
|
||||
srcset="{imageSlot('hero', 'small')} 480w,
|
||||
{imageSlot('hero', 'medium')} 768w,
|
||||
{imageSlot('hero', 'large')} 1200w">
|
||||
|
||||
<!-- Date formatting -->
|
||||
<time datetime="{user.createdAt|iso8601}">
|
||||
{user.createdAt|date('d.m.Y H:i')}
|
||||
</time>
|
||||
|
||||
<!-- Asset URLs -->
|
||||
<link rel="stylesheet" href="{asset('css/app.css')}">
|
||||
<script src="{asset('js/app.js')}" defer></script>
|
||||
```
|
||||
|
||||
### Custom Functions
|
||||
|
||||
```php
|
||||
// Register custom function
|
||||
$templateEngine->registerFunction('currency', function ($amount, $currency = 'EUR') {
|
||||
return number_format($amount, 2, ',', '.') . ' ' . $currency;
|
||||
});
|
||||
```
|
||||
|
||||
```html
|
||||
<!-- Use custom function -->
|
||||
<span class="price">{product.price|currency('USD')}</span>
|
||||
```
|
||||
|
||||
## 🎨 Integration with CSS/JS
|
||||
|
||||
### Asset Management
|
||||
|
||||
```html
|
||||
<!-- Vite asset injection -->
|
||||
<head>
|
||||
{vite('resources/css/app.css')}
|
||||
{vite('resources/js/app.js')}
|
||||
</head>
|
||||
|
||||
<!-- Conditional assets -->
|
||||
<if condition="isDevelopment">
|
||||
<script src="http://localhost:3000/@vite/client" type="module"></script>
|
||||
</if>
|
||||
```
|
||||
|
||||
### Component-specific Assets
|
||||
|
||||
```html
|
||||
<!-- components/chart.view.php -->
|
||||
<div class="chart-container" data-chart="{chartData}">
|
||||
<slot name="head">
|
||||
<link rel="stylesheet" href="{asset('css/charts.css')}">
|
||||
</slot>
|
||||
|
||||
<slot name="scripts">
|
||||
<script src="{asset('js/charts.js')}" defer></script>
|
||||
</slot>
|
||||
</div>
|
||||
```
|
||||
|
||||
## 🔍 Debugging & Development
|
||||
|
||||
### Template Debugging
|
||||
|
||||
```html
|
||||
<!-- Debug mode shows processing steps -->
|
||||
<debug>
|
||||
Template: {template.name}
|
||||
Context: {context.data|json}
|
||||
Cache: {cache.status}
|
||||
</debug>
|
||||
```
|
||||
|
||||
### Performance Analysis
|
||||
|
||||
```php
|
||||
// Template performance metrics
|
||||
$metrics = $templateEngine->getMetrics();
|
||||
echo "Render time: {$metrics->renderTime}ms\n";
|
||||
echo "Cache hits: {$metrics->cacheHits}\n";
|
||||
echo "Processors: {$metrics->processorsRun}\n";
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*For detailed processor documentation, see [Template Processors](processors.md)*
|
||||
*For component examples, see [Component Library](../design-system/components.md)*
|
||||
*For caching strategies, see [View Caching](caching.md)*
|
||||
@@ -0,0 +1,169 @@
|
||||
# Performance-Richtlinien
|
||||
|
||||
## Übersicht
|
||||
|
||||
Diese Richtlinien beschreiben Best Practices für die Optimierung der Anwendungsleistung im Framework.
|
||||
|
||||
## Grundprinzipien
|
||||
|
||||
### 1. Frühe Optimierung vermeiden
|
||||
|
||||
- Code zuerst korrekt und lesbar schreiben
|
||||
- Optimierungen auf Basis von Messungen durchführen
|
||||
- Performance-Engpässe mit dem Profiler identifizieren
|
||||
|
||||
### 2. Caching strategisch einsetzen
|
||||
|
||||
- Ergebnisse teurer Operationen cachen
|
||||
- Geeignete Cache-Invalidierungsstrategien implementieren
|
||||
- Cache-Hierarchie nutzen (Memory → Filesystem → Datenbank)
|
||||
|
||||
```php
|
||||
// Beispiel: Strategisches Caching
|
||||
public function getExpensiveData(string $key): array
|
||||
{
|
||||
$cacheKey = "data_{$key}";
|
||||
|
||||
// Prüfen, ob Daten im Cache sind
|
||||
if ($this->cache->has($cacheKey)) {
|
||||
return $this->cache->get($cacheKey);
|
||||
}
|
||||
|
||||
// Teure Operation durchführen
|
||||
$result = $this->performExpensiveOperation($key);
|
||||
|
||||
// Ergebnis cachen mit angemessener TTL
|
||||
$this->cache->set($cacheKey, $result, 3600);
|
||||
|
||||
return $result;
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Lazy Loading
|
||||
|
||||
- Ressourcen erst bei Bedarf laden
|
||||
- Schwere Abhängigkeiten verzögert initialisieren
|
||||
|
||||
```php
|
||||
// Beispiel: Lazy Loading
|
||||
private ?ExpensiveService $expensiveService = null;
|
||||
|
||||
private function getExpensiveService(): ExpensiveService
|
||||
{
|
||||
if ($this->expensiveService === null) {
|
||||
$this->expensiveService = new ExpensiveService($this->config);
|
||||
}
|
||||
|
||||
return $this->expensiveService;
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Datenstrukturen optimieren
|
||||
|
||||
- Passende Datenstrukturen für den Anwendungsfall wählen
|
||||
- Große Arrays vermeiden, wenn möglich Iteratoren oder Generatoren nutzen
|
||||
- Bei großen Datenmengen paginieren
|
||||
|
||||
```php
|
||||
// Beispiel: Generator statt Array
|
||||
public function processLargeDataset(): Generator
|
||||
{
|
||||
$handle = fopen($this->largeFile, 'r');
|
||||
|
||||
while (($line = fgets($handle)) !== false) {
|
||||
yield $this->processLine($line);
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
}
|
||||
```
|
||||
|
||||
## Spezifische Optimierungen
|
||||
|
||||
### Datenbankzugriffe
|
||||
|
||||
- Anzahl der Datenbankabfragen minimieren
|
||||
- Indizes für häufige Abfragen
|
||||
- N+1 Problem vermeiden durch Eager Loading
|
||||
- Datenbankverbindungen poolen
|
||||
|
||||
### HTTP-Anfragen
|
||||
|
||||
- Statische Assets komprimieren und cachen
|
||||
- HTTP/2 nutzen, wenn möglich
|
||||
- Content-Kompression aktivieren
|
||||
- Browser-Caching durch geeignete Header
|
||||
|
||||
### Speichernutzung
|
||||
|
||||
- Große Objekte nach Gebrauch freigeben (`unset()`)
|
||||
- Zirkuläre Referenzen vermeiden
|
||||
- Bei Dateiberarbeitung auf Streaming-Ansätze setzen
|
||||
|
||||
### Autoloading
|
||||
|
||||
- Composer-Autoloader in Produktionsumgebung optimieren
|
||||
- Preloading für häufig verwendete Klassen nutzen
|
||||
|
||||
```php
|
||||
// preload.php Beispiel
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
// Häufig verwendete Klassen vorladen
|
||||
require_once __DIR__ . '/Framework/Core/Application.php';
|
||||
require_once __DIR__ . '/Framework/DI/Container.php';
|
||||
require_once __DIR__ . '/Framework/Http/Request.php';
|
||||
require_once __DIR__ . '/Framework/Http/Response.php';
|
||||
```
|
||||
|
||||
## Monitoring und Profiling
|
||||
|
||||
### Performance messen
|
||||
|
||||
- Kritische Code-Pfade instrumentieren
|
||||
- End-to-End Zeitmessungen durchführen
|
||||
|
||||
```php
|
||||
// Beispiel: Performance-Messung
|
||||
$startTime = microtime(true);
|
||||
|
||||
// Operation durchführen
|
||||
$result = $this->performOperation();
|
||||
|
||||
$duration = microtime(true) - $startTime;
|
||||
$this->logger->debug("Operation ausgeführt in {$duration}s");
|
||||
```
|
||||
|
||||
### Automatisiertes Monitoring
|
||||
|
||||
- Performance-Regressions automatisch erkennen
|
||||
- Regelmäßige Lasttests durchführen
|
||||
- Kritische Pfade überwachen
|
||||
|
||||
## Umgebungsspezifische Optimierungen
|
||||
|
||||
### Entwicklung
|
||||
|
||||
- Debug-Tools aktivieren
|
||||
- Performance-Optimierungen deaktivieren, die Debugging erschweren
|
||||
|
||||
### Produktion
|
||||
|
||||
- Opcache aktivieren und optimieren
|
||||
- Fehlerbehandlung optimieren (keine Stack Traces)
|
||||
- Logging auf nötige Informationen beschränken
|
||||
|
||||
```php
|
||||
// Umgebungsspezifische Einstellungen
|
||||
if ($environment === 'production') {
|
||||
ini_set('opcache.validate_timestamps', 0);
|
||||
ini_set('display_errors', 0);
|
||||
error_reporting(E_ERROR | E_WARNING | E_PARSE);
|
||||
} else {
|
||||
ini_set('opcache.validate_timestamps', 1);
|
||||
ini_set('display_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,181 @@
|
||||
# Testing-Richtlinien
|
||||
|
||||
## Übersicht
|
||||
|
||||
Diese Richtlinien beschreiben die Standards und Best Practices für Tests im Framework.
|
||||
|
||||
## Grundprinzipien
|
||||
|
||||
### 1. Testarten
|
||||
|
||||
- **Unit Tests**: Testen einzelner Komponenten isoliert
|
||||
- **Integrationstests**: Testen des Zusammenspiels mehrerer Komponenten
|
||||
- **Funktionstests**: Testen ganzer Funktionalitäten aus Benutzersicht
|
||||
|
||||
### 2. Pest-Framework
|
||||
|
||||
Alle Tests werden mit dem Pest-Framework geschrieben:
|
||||
|
||||
```php
|
||||
test('Analytics::track zeichnet Events korrekt auf', function () {
|
||||
// Arrange
|
||||
$manager = new AnalyticsManager(['enabled' => true], new InMemoryStorage());
|
||||
$analytics = new Analytics($manager, new EventDispatcher());
|
||||
|
||||
// Act
|
||||
$analytics->track('test_event', ['key' => 'value']);
|
||||
|
||||
// Assert
|
||||
expect($manager->getStorage()->retrieve())->toHaveCount(1);
|
||||
expect($manager->getStorage()->retrieve()[0]['event'])->toBe('test_event');
|
||||
});
|
||||
```
|
||||
|
||||
### 3. Teststruktur
|
||||
|
||||
- Jeder Test folgt dem AAA-Prinzip: Arrange, Act, Assert
|
||||
- Tests sollten unabhängig voneinander sein
|
||||
- Tests sollten deterministisch sein (keine zufälligen Ergebnisse)
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Testabdeckung
|
||||
|
||||
- Jede öffentliche Methode sollte getestet werden
|
||||
- Edge Cases und Fehlersituationen explizit testen
|
||||
- Fokus auf Business-Logik und kritische Pfade
|
||||
|
||||
### 2. Mocking
|
||||
|
||||
- Externe Abhängigkeiten mocken
|
||||
- Eigene Test-Implementierungen für Interfaces erstellen
|
||||
- Mock-Objekte nur für die spezifischen Testfälle konfigurieren
|
||||
|
||||
```php
|
||||
// Beispiel: Test mit Mock
|
||||
test('Fehlerbehandlung bei Storage-Ausfall', function () {
|
||||
// Arrange
|
||||
$storage = new class implements StorageInterface {
|
||||
public function store(array $events): void
|
||||
{
|
||||
throw new \RuntimeException('Storage-Fehler');
|
||||
}
|
||||
|
||||
public function retrieve(array $filters = []): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function clear(): void
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
$manager = new AnalyticsManager(['enabled' => true], $storage);
|
||||
|
||||
// Act & Assert
|
||||
expect(fn() => $manager->flush())->toThrow(\RuntimeException::class);
|
||||
});
|
||||
```
|
||||
|
||||
### 3. Fixtures und Factories
|
||||
|
||||
- Testdaten mit Factories erstellen
|
||||
- Komplexe Objekte über Helpers aufbauen
|
||||
- Wiederverwendbare Fixtures für ähnliche Tests
|
||||
|
||||
```php
|
||||
// Beispiel: Test-Factory
|
||||
function createAnalyticsManager(array $config = []): AnalyticsManager
|
||||
{
|
||||
$defaultConfig = ['enabled' => true, 'auto_flush' => false];
|
||||
return new AnalyticsManager(
|
||||
array_merge($defaultConfig, $config),
|
||||
new InMemoryStorage()
|
||||
);
|
||||
}
|
||||
|
||||
test('Auto-Flush funktioniert korrekt', function () {
|
||||
// Arrange
|
||||
$manager = createAnalyticsManager(['auto_flush' => true, 'batch_size' => 2]);
|
||||
|
||||
// Act
|
||||
$manager->track('event1', []);
|
||||
$manager->track('event2', []);
|
||||
|
||||
// Assert
|
||||
expect($manager->getStorage()->retrieve())->toHaveCount(2);
|
||||
});
|
||||
```
|
||||
|
||||
### 4. Datenbankzugriffe
|
||||
|
||||
- In Unit-Tests Datenbankzugriffe vermeiden oder mocken
|
||||
- In Integrationstests separate Testdatenbank verwenden
|
||||
- Testdatenbank nach Tests zurücksetzen
|
||||
|
||||
### 5. Asynchrone Tests
|
||||
|
||||
- Timeouts für asynchrone Tests setzen
|
||||
- Auf Async-Events warten, statt feste Wartezeiten
|
||||
|
||||
## Testorganisation
|
||||
|
||||
### 1. Dateistruktur
|
||||
|
||||
- Tests in `/tests`-Verzeichnis mit gleicher Struktur wie `/src`
|
||||
- Dateinamen mit `Test`-Suffix
|
||||
|
||||
### 2. Testgruppen
|
||||
|
||||
- Tests mit Attributen in Gruppen einteilen
|
||||
- Langsame Tests markieren
|
||||
|
||||
```php
|
||||
#[Group('analytics')]
|
||||
#[Group('slow')]
|
||||
test('große Datenmenge verarbeiten', function () {
|
||||
// Test mit vielen Daten
|
||||
});
|
||||
```
|
||||
|
||||
## CI/CD-Integration
|
||||
|
||||
- Tests in CI-Pipeline automatisiert ausführen
|
||||
- Testabdeckung messen und überwachen
|
||||
- Pull Requests nur mit erfolgreichen Tests mergen
|
||||
|
||||
## Fehlersuche
|
||||
|
||||
### 1. Debugging-Techniken
|
||||
|
||||
- Pest-Debugging aktivieren mit `->dump()`
|
||||
- PHPUnit-Assertions für detaillierte Fehlermeldungen
|
||||
|
||||
```php
|
||||
test('komplexes Objekt validieren', function () {
|
||||
$result = processData();
|
||||
|
||||
// Bei Fehlern Kontext ausgeben
|
||||
if (!expect($result->isValid())->toBeTrue()->isSuccess()) {
|
||||
dump($result->getErrors());
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### 2. Problematische Tests
|
||||
|
||||
- Flaky Tests identifizieren und beheben
|
||||
- Tests isolieren mit `only` oder `skip`
|
||||
|
||||
```php
|
||||
test('problematischer Test', function () {
|
||||
// Test-Code
|
||||
})->skip('Wird untersucht');
|
||||
```
|
||||
|
||||
## Zusammenfassung
|
||||
|
||||
- Tests sind ein integraler Bestandteil der Codebase
|
||||
- Qualität und Wartbarkeit der Tests sind genauso wichtig wie die des Produktionscodes
|
||||
- Tests dienen als lebende Dokumentation der Funktionalität
|
||||
43
backups/docs-backup-20250731125004/guidelines/index.md
Normal file
43
backups/docs-backup-20250731125004/guidelines/index.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Entwicklungsrichtlinien
|
||||
|
||||
## Übersicht
|
||||
|
||||
Diese Richtlinien bieten Best Practices und Standards für die Entwicklung innerhalb des Projekts. Sie helfen, qualitativ hochwertigen, wartbaren und leistungsfähigen Code zu schreiben.
|
||||
|
||||
## Verfügbare Richtlinien
|
||||
|
||||
- [Performance-Richtlinien](/guidelines/PERFORMANCE-GUIDELINES.md) - Optimierung der Anwendungsleistung
|
||||
- [Testing-Richtlinien](/guidelines/TESTING-GUIDELINES.md) - Standards und Best Practices für Tests
|
||||
|
||||
## Performance-Optimierung
|
||||
|
||||
Leistungsoptimierung ist ein wichtiger Aspekt der Anwendungsentwicklung. Die [Performance-Richtlinien](/guidelines/PERFORMANCE-GUIDELINES.md) bieten Einblicke in:
|
||||
|
||||
- Strategisches Caching
|
||||
- Lazy Loading
|
||||
- Optimierung von Datenbankabfragen
|
||||
- Effiziente Datenstrukturen
|
||||
- Speichernutzung
|
||||
|
||||
## Teststrategien
|
||||
|
||||
Testen ist ein integraler Bestandteil des Entwicklungsprozesses. Die [Testing-Richtlinien](/guidelines/TESTING-GUIDELINES.md) decken folgende Themen ab:
|
||||
|
||||
- Unit Tests mit Pest-Framework
|
||||
- Integrationstests
|
||||
- Test-Fixtures und Factories
|
||||
- Mocking-Strategien
|
||||
- Testorganisation und -struktur
|
||||
|
||||
## Anwendung der Richtlinien
|
||||
|
||||
Diese Richtlinien sollten in allen Phasen der Entwicklung berücksichtigt werden:
|
||||
|
||||
1. **Planungsphase**: Frühzeitige Berücksichtigung von Performance und Testbarkeit
|
||||
2. **Implementierungsphase**: Anwendung der Best Practices während der Entwicklung
|
||||
3. **Review-Phase**: Überprüfung des Codes anhand der Richtlinien
|
||||
4. **Refactoring**: Verbesserung bestehenden Codes gemäß den Richtlinien
|
||||
|
||||
## Continuous Improvement
|
||||
|
||||
Diese Richtlinien werden kontinuierlich verbessert und aktualisiert. Wenn Sie Vorschläge zur Verbesserung haben, zögern Sie nicht, diese einzubringen.
|
||||
80
backups/docs-backup-20250731125004/index.md
Normal file
80
backups/docs-backup-20250731125004/index.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# Framework Documentation
|
||||
|
||||
> Comprehensive documentation for the custom PHP framework with modern architecture patterns, advanced caching, and powerful view system.
|
||||
|
||||
## 📚 Documentation Overview
|
||||
|
||||
### Framework Core
|
||||
- **[Framework Overview](framework/index.md)** - Core framework concepts and patterns
|
||||
- **[HTTP Layer](framework/http/README.md)** - Request/response handling and middleware
|
||||
- **[Database & ORM](database/eager-loading.md)** - EntityManager, N+1 elimination, change tracking
|
||||
- **[View System](framework/views/overview.md)** - Template processing and component system
|
||||
- **[Dependency Injection](framework/di/README.md)** - Container and service management
|
||||
- **[Analytics System](framework/analytics/README.md)** - Performance monitoring and metrics
|
||||
- **[Core Components](framework/core/README.md)** - Discovery, routing, and bootstrapping
|
||||
|
||||
### Design System
|
||||
- **[Design Foundations](design-system/foundations.md)** - Colors, typography, spacing, and design tokens
|
||||
- **[CSS Architecture](design-system/css-architecture.md)** - ITCSS structure and methodology
|
||||
- **[JavaScript Modules](design-system/javascript.md)** - ES6 component system
|
||||
- **[Admin Interface](design-system/admin/overview.md)** - Admin-specific design patterns
|
||||
|
||||
### Development & Standards
|
||||
- **[Setup Guide](SETUP.md)** - Development environment setup
|
||||
- **[Coding Guidelines](standards/CODING-GUIDELINES.md)** - Code standards and best practices
|
||||
- **[Security Guidelines](standards/SICHERHEITS-GUIDELINES.md)** - Security standards
|
||||
- **[Testing Guidelines](guidelines/TESTING-GUIDELINES.md)** - Testing strategies and patterns
|
||||
- **[Performance Guidelines](guidelines/PERFORMANCE-GUIDELINES.md)** - Optimization techniques
|
||||
- **[Deployment Guide](DEPLOYMENT.md)** - Production deployment strategies
|
||||
|
||||
### Database & Advanced Features
|
||||
- **[Database Master/Slave Router](database/master-slave-router.md)** - Connection management and load balancing
|
||||
- **[Database Change Tracking](database/change-tracking.md)** - Entity change tracking and audit logs
|
||||
- **[Database Eager Loading](database/eager-loading.md)** - N+1 query elimination and performance optimization
|
||||
- **[Phone Number Validation](validation/phone-number.md)** - Phone number handling and validation
|
||||
- **[Unit of Work Pattern](UnitOfWork.md)** - Database transaction management
|
||||
- **[Worker System](WORKER.md)** - Background job processing and queues
|
||||
|
||||
### Architecture & Patterns
|
||||
- **[System Architecture](architecture/STRUKTUR-DOKUMENTATION.md)** - Overall system structure
|
||||
- **[Module System](framework/MODUL-CHECKLISTE.md)** - Module development checklist
|
||||
- **[Extension Patterns](framework/ERWEITERUNGSPATTERN.md)** - Framework extension patterns
|
||||
|
||||
### Development Tools & AI
|
||||
- **[AI Assistant Setup](ai/EINRICHTUNG-PHPSTORM.md)** - PhpStorm AI integration
|
||||
- **[AI Guidelines](ai/GUIDELINES-FÜR-AI-ASSISTANT.md)** - Best practices for AI assistance
|
||||
- **[API Documentation](api.md)** - API reference and examples
|
||||
- **[Environment Setup](ENV.md)** - Environment configuration
|
||||
- **[Git Workflows](COMMITS.md)** - Commit standards and workflows
|
||||
|
||||
## 🚀 Quick Start Guide
|
||||
|
||||
### For New Developers
|
||||
1. **[Setup Guide](SETUP.md)** - Get your development environment running
|
||||
2. **[System Architecture](architecture/STRUKTUR-DOKUMENTATION.md)** - Understand the system structure
|
||||
3. **[Coding Guidelines](standards/CODING-GUIDELINES.md)** - Learn the coding standards
|
||||
4. **[Module Checklist](framework/MODUL-CHECKLISTE.md)** - Framework module development
|
||||
|
||||
### For Designers
|
||||
1. **[CSS Architecture](design-system/css-architecture.md)** - Understand the CSS structure
|
||||
2. **[Admin Interface](design-system/admin/overview.md)** - Admin design patterns
|
||||
3. **[JavaScript Modules](design-system/javascript.md)** - Frontend component system
|
||||
|
||||
### For DevOps
|
||||
1. **[Deployment Guide](DEPLOYMENT.md)** - Production deployment
|
||||
2. **[Performance Guidelines](guidelines/PERFORMANCE-GUIDELINES.md)** - Optimization techniques
|
||||
3. **[Security Guidelines](standards/SICHERHEITS-GUIDELINES.md)** - Security best practices
|
||||
|
||||
## 📊 Framework Features
|
||||
|
||||
- **Modern PHP 8.4** - Latest language features and performance
|
||||
- **Attribute-based Architecture** - Clean, discoverable component system
|
||||
- **Advanced ORM** - N+1 elimination, change tracking, master/slave routing
|
||||
- **DOM-based Templates** - Powerful view processing with component system
|
||||
- **Multi-level Caching** - Intelligent caching with automatic invalidation
|
||||
- **AI Integration** - MCP protocol for AI development tools
|
||||
- **Performance Monitoring** - Built-in analytics and optimization tools
|
||||
|
||||
---
|
||||
|
||||
*This documentation is continuously updated. For contributions, see our [contribution guidelines](standards/CODING-GUIDELINES.md).*
|
||||
221
backups/docs-backup-20250731125004/next-steps.md
Normal file
221
backups/docs-backup-20250731125004/next-steps.md
Normal file
@@ -0,0 +1,221 @@
|
||||
# Nächste Schritte zur Projektverbesserung
|
||||
|
||||
Basierend auf der Analyse des aktuellen Projektstatus und dem Verbesserungsplan (plan.md) wurden die folgenden konkreten nächsten Schritte identifiziert. Diese Schritte berücksichtigen, dass viele der vorgeschlagenen Verbesserungen bereits implementiert wurden, aber noch nicht in der Dokumentation reflektiert sind.
|
||||
|
||||
## 1. Dokumentation aktualisieren
|
||||
|
||||
### 1.1 Tracking-Dokumente aktualisieren
|
||||
|
||||
**Aktuelle Situation**: Die Tracking-Dokumente (features.md und tasks.md) spiegeln nicht den tatsächlichen Implementierungsstatus wider. Viele Features und Tasks sind als nicht implementiert markiert, obwohl sie bereits umgesetzt wurden.
|
||||
|
||||
**Nächste Schritte**:
|
||||
1. Features.md durchgehen und den tatsächlichen Implementierungsstatus für jedes Feature aktualisieren
|
||||
2. Tasks.md aktualisieren, um abgeschlossene Aufgaben zu markieren
|
||||
3. Einen automatisierten Prozess implementieren, um diese Dokumente aktuell zu halten (z.B. durch CI/CD-Integration)
|
||||
|
||||
**Erfolgsmetriken**:
|
||||
- Dokumentation spiegelt den tatsächlichen Implementierungsstatus wider
|
||||
- Entwickler können schnell erkennen, welche Features und Tasks noch ausstehen
|
||||
|
||||
### 1.2 Technische Dokumentation vervollständigen
|
||||
|
||||
**Aktuelle Situation**: Die technische Dokumentation für implementierte Komponenten ist unvollständig oder fehlt ganz.
|
||||
|
||||
**Nächste Schritte**:
|
||||
1. API-Dokumentation für alle öffentlichen Schnittstellen erstellen
|
||||
2. Architektur-Diagramme aktualisieren, um die tatsächliche Implementierung widerzuspiegeln
|
||||
3. Entwickler-Anleitungen für die Nutzung der implementierten Komponenten erstellen
|
||||
|
||||
**Erfolgsmetriken**:
|
||||
- Vollständige API-Dokumentation für alle Framework-Komponenten
|
||||
- Aktuelle Architektur-Diagramme
|
||||
- Entwickler können neue Komponenten ohne externe Hilfe nutzen
|
||||
|
||||
## 2. Sicherheitsverbesserungen
|
||||
|
||||
### 2.1 WAF-Feedback-System implementieren
|
||||
|
||||
**Aktuelle Situation**: Das WAF mit Machine Learning ist implementiert, aber es fehlt ein Feedback-System für falsch positive/negative Ergebnisse.
|
||||
|
||||
**Nächste Schritte**:
|
||||
1. Ein Admin-Interface für die Überprüfung von WAF-Entscheidungen implementieren
|
||||
2. Einen Feedback-Mechanismus entwickeln, der ML-Modelle basierend auf Admin-Feedback aktualisiert
|
||||
3. Ein Dashboard für Sicherheitsanomalien mit Visualisierungen erstellen
|
||||
|
||||
**Technische Spezifikation**:
|
||||
- Implementierung in `src/Framework/Waf/Feedback/`
|
||||
- Integration mit bestehenden ML-Komponenten in `src/Framework/Waf/MachineLearning/`
|
||||
- Speicherung von Feedback-Daten für kontinuierliches Training
|
||||
|
||||
**Erfolgsmetriken**:
|
||||
- Reduzierung falsch positiver Ergebnisse um 50%
|
||||
- Verbesserung der Erkennungsgenauigkeit um 20%
|
||||
- Positives Feedback von Administratoren zur Benutzerfreundlichkeit
|
||||
|
||||
### 2.2 Security Headers vervollständigen
|
||||
|
||||
**Aktuelle Situation**: Grundlegende Sicherheitsmaßnahmen sind implementiert, aber moderne Security Headers könnten konsistenter angewendet werden.
|
||||
|
||||
**Nächste Schritte**:
|
||||
1. Content Security Policy (CSP) mit angemessenen Direktiven implementieren
|
||||
2. Strict-Transport-Security, X-Content-Type-Options und andere Security Headers hinzufügen
|
||||
3. Ein Security-Header-Audit-Tool für kontinuierliche Überwachung erstellen
|
||||
|
||||
**Technische Spezifikation**:
|
||||
- Implementierung in `src/Framework/Security/Headers/`
|
||||
- Integration mit dem bestehenden Middleware-System
|
||||
- Konfigurierbare Header-Richtlinien pro Route oder Controller
|
||||
|
||||
**Erfolgsmetriken**:
|
||||
- A+ Rating bei Security-Header-Scans
|
||||
- Keine CSP-Verletzungen in der Produktion
|
||||
- Erfolgreiche Abwehr von XSS- und Clickjacking-Angriffen
|
||||
|
||||
## 3. Performance-Optimierungen
|
||||
|
||||
### 3.1 Lazy Loading für nicht-kritische Services
|
||||
|
||||
**Aktuelle Situation**: Der DI-Container initialisiert viele Services beim Start, was die Bootstrap-Zeit beeinträchtigen kann.
|
||||
|
||||
**Nächste Schritte**:
|
||||
1. Service-Initialisierung profilieren, um Bottlenecks zu identifizieren
|
||||
2. Lazy Loading für nicht-kritische Services implementieren
|
||||
3. Service-Gruppen mit priorisierter Initialisierung erstellen
|
||||
|
||||
**Technische Spezifikation**:
|
||||
- Erweiterung des DI-Containers in `src/Framework/DI/`
|
||||
- Implementierung eines Proxy-Patterns für Lazy-Loading
|
||||
- Konfigurationssystem für Service-Prioritäten
|
||||
|
||||
**Erfolgsmetriken**:
|
||||
- Reduzierung der Bootstrap-Zeit um mindestens 30%
|
||||
- Reduzierung des Speicherverbrauchs bei nicht genutzten Services
|
||||
- Keine Beeinträchtigung der Antwortzeit für kritische Pfade
|
||||
|
||||
### 3.2 Cache-Warming-Strategien
|
||||
|
||||
**Aktuelle Situation**: Ein umfassendes Caching-System ist implementiert, aber es fehlen automatisierte Cache-Warming-Strategien.
|
||||
|
||||
**Nächste Schritte**:
|
||||
1. Automatisches Cache-Warming für häufig abgerufene Daten implementieren
|
||||
2. Cache-Invalidierungsmuster für verschiedene Datentypen erstellen
|
||||
3. Cache-Analyse-Tools implementieren, um Caching-Möglichkeiten zu identifizieren
|
||||
|
||||
**Technische Spezifikation**:
|
||||
- Implementierung in `src/Framework/Cache/Warming/`
|
||||
- Integration mit dem Deployment-Prozess
|
||||
- Konfigurierbare Warming-Strategien für verschiedene Cache-Typen
|
||||
|
||||
**Erfolgsmetriken**:
|
||||
- Reduzierung der Cache-Miss-Rate um 40%
|
||||
- Verbesserte Antwortzeiten nach Deployments
|
||||
- Gleichmäßigere Leistung unter Last
|
||||
|
||||
## 4. Entwicklererfahrung
|
||||
|
||||
### 4.1 Test-Abdeckung erhöhen
|
||||
|
||||
**Aktuelle Situation**: Die Testabdeckung ist für viele Komponenten unvollständig.
|
||||
|
||||
**Nächste Schritte**:
|
||||
1. Unit-Tests für Komponenten ohne Testabdeckung hinzufügen
|
||||
2. Integrationstests für kritische Workflows implementieren
|
||||
3. End-to-End-Tests für wichtige Benutzer-Journeys hinzufügen
|
||||
|
||||
**Technische Spezifikation**:
|
||||
- Fokus auf Komponenten in `src/Framework/` ohne Tests
|
||||
- Verwendung von PHPUnit für Unit- und Integrationstests
|
||||
- Implementierung von Cypress oder ähnlichen Tools für E2E-Tests
|
||||
|
||||
**Erfolgsmetriken**:
|
||||
- Testabdeckung von mindestens 80% für alle Kernkomponenten
|
||||
- Reduzierung der Regressionen bei neuen Releases um 50%
|
||||
- Schnelleres Feedback für Entwickler bei Code-Änderungen
|
||||
|
||||
### 4.2 Entwicklungs-Workflow optimieren
|
||||
|
||||
**Aktuelle Situation**: Grundlegende Entwicklungstools sind vorhanden, aber der Workflow könnte optimiert werden.
|
||||
|
||||
**Nächste Schritte**:
|
||||
1. Standardisierte Entwicklungsumgebungen mit Containern implementieren
|
||||
2. Automatisierte Code-Qualitätsprüfungen mit sofortigem Feedback einrichten
|
||||
3. Feature-Flag-System für sicherere Deployments implementieren
|
||||
|
||||
**Technische Spezifikation**:
|
||||
- Docker-Compose-Setup für lokale Entwicklung verbessern
|
||||
- Integration von PHP-CS-Fixer, PHPStan und anderen Tools in den Entwicklungsprozess
|
||||
- Implementierung eines Feature-Flag-Systems in `src/Framework/FeatureFlags/`
|
||||
|
||||
**Erfolgsmetriken**:
|
||||
- Reduzierung der Zeit für die Einrichtung neuer Entwicklungsumgebungen um 70%
|
||||
- Konsistente Code-Qualität über alle Pull Requests
|
||||
- Sicherere und häufigere Deployments
|
||||
|
||||
## 5. Skalierbarkeit und Zuverlässigkeit
|
||||
|
||||
### 5.1 Horizontale Skalierung unterstützen
|
||||
|
||||
**Aktuelle Situation**: Die Anwendungsarchitektur unterstützt möglicherweise nicht vollständig die horizontale Skalierung.
|
||||
|
||||
**Nächste Schritte**:
|
||||
1. Zustandslose Service-Design-Patterns implementieren
|
||||
2. Verteiltes Session-Management hinzufügen
|
||||
3. Service-Discovery für dynamische Skalierung implementieren
|
||||
|
||||
**Technische Spezifikation**:
|
||||
- Implementierung in `src/Framework/Scaling/`
|
||||
- Integration mit Redis oder anderen verteilten Speichersystemen
|
||||
- Unterstützung für Container-Orchestrierung (Kubernetes)
|
||||
|
||||
**Erfolgsmetriken**:
|
||||
- Erfolgreiche Tests mit mehreren Anwendungsinstanzen
|
||||
- Lineare Skalierung der Leistung mit zusätzlichen Instanzen
|
||||
- Keine Single Points of Failure
|
||||
|
||||
### 5.2 Resilience-Patterns
|
||||
|
||||
**Aktuelle Situation**: Grundlegende Fehlerbehandlung ist vorhanden, aber umfassende Resilience-Patterns sind nicht vollständig implementiert.
|
||||
|
||||
**Nächste Schritte**:
|
||||
1. Circuit-Breaker-Patterns für externe Service-Aufrufe implementieren
|
||||
2. Retry-Mechanismen mit exponentiellen Backoff hinzufügen
|
||||
3. Fallback-Strategien für kritische Services erstellen
|
||||
|
||||
**Technische Spezifikation**:
|
||||
- Implementierung in `src/Framework/Resilience/`
|
||||
- Integration mit dem bestehenden HttpClient
|
||||
- Konfigurierbare Resilience-Strategien pro Service
|
||||
|
||||
**Erfolgsmetriken**:
|
||||
- Verbesserte Systemstabilität während Ausfällen externer Dienste
|
||||
- Reduzierung von Kaskadierenden Fehlern um 90%
|
||||
- Verbesserte Benutzererfahrung während Teilausfällen
|
||||
|
||||
## 6. Implementierungs-Roadmap
|
||||
|
||||
### 6.1 Kurzfristige Prioritäten (1-2 Monate)
|
||||
|
||||
1. Dokumentation aktualisieren, um den tatsächlichen Implementierungsstatus widerzuspiegeln
|
||||
2. WAF-Feedback-System implementieren
|
||||
3. Security Headers vervollständigen
|
||||
4. Test-Abdeckung für kritische Komponenten erhöhen
|
||||
|
||||
### 6.2 Mittelfristige Ziele (2-4 Monate)
|
||||
|
||||
1. Lazy Loading für nicht-kritische Services implementieren
|
||||
2. Cache-Warming-Strategien entwickeln
|
||||
3. Entwicklungs-Workflow optimieren
|
||||
4. Resilience-Patterns für verbesserte Stabilität implementieren
|
||||
|
||||
### 6.3 Langfristige Vision (4-6 Monate)
|
||||
|
||||
1. Horizontale Skalierung unterstützen
|
||||
2. Umfassendes Monitoring und Observability implementieren
|
||||
3. Alle geplanten Module und Features vervollständigen
|
||||
4. Für Performance im großen Maßstab optimieren
|
||||
|
||||
## Fazit
|
||||
|
||||
Diese nächsten Schritte bauen auf den bereits implementierten Verbesserungen auf und adressieren die verbleibenden Bereiche mit dem höchsten Wirkungspotenzial. Durch die Priorisierung von Dokumentation, Sicherheit, Performance und Entwicklererfahrung wird das Projekt weiter verbessert und für zukünftiges Wachstum vorbereitet.
|
||||
|
||||
Die Umsetzung dieser Schritte sollte iterativ erfolgen, mit regelmäßigen Überprüfungen und Anpassungen basierend auf Feedback und sich ändernden Anforderungen.
|
||||
242
backups/docs-backup-20250731125004/plan.md
Normal file
242
backups/docs-backup-20250731125004/plan.md
Normal file
@@ -0,0 +1,242 @@
|
||||
# Project Improvement Plan
|
||||
|
||||
This document outlines a comprehensive improvement plan for the project based on analysis of the current codebase, architecture, and requirements. The plan is organized by key areas of the system, with each section providing specific recommendations and their rationale.
|
||||
|
||||
## 1. Architecture Improvements
|
||||
|
||||
### 1.1 Modular Architecture Refinement
|
||||
|
||||
**Current State**: The project has a modular structure with clear separation between Framework, Application, Domain, and Infrastructure layers. However, there are opportunities to improve module isolation and reduce coupling.
|
||||
|
||||
**Proposed Changes**:
|
||||
- Implement a formal module boundary system with explicit public APIs for each module
|
||||
- Create interface contracts for all module interactions
|
||||
- Establish a dependency graph visualization tool to monitor architectural health
|
||||
|
||||
**Rationale**: Enhancing module boundaries will improve maintainability, make the system more testable, and reduce the risk of unintended side effects when making changes. Clear interfaces will make it easier for new developers to understand the system.
|
||||
|
||||
### 1.2 Configuration System Consolidation
|
||||
|
||||
**Current State**: Multiple configuration approaches exist across the system (env files, JSON configs, code-based configs).
|
||||
|
||||
**Proposed Changes**:
|
||||
- Create a unified configuration system with a consistent API
|
||||
- Implement hierarchical configuration with environment-specific overrides
|
||||
- Add validation for configuration values with strong typing
|
||||
|
||||
**Rationale**: A unified configuration system will reduce complexity, prevent configuration-related errors, and make the system easier to deploy across different environments.
|
||||
|
||||
### 1.3 Service Initialization Optimization
|
||||
|
||||
**Current State**: The dependency injection container initializes many services at startup, potentially impacting bootstrap time.
|
||||
|
||||
**Proposed Changes**:
|
||||
- Implement lazy loading for non-critical services
|
||||
- Add service initialization profiling to identify bottlenecks
|
||||
- Create service groups with prioritized initialization
|
||||
|
||||
**Rationale**: Optimizing service initialization will improve application startup time, reduce resource usage, and enhance the developer experience during local development.
|
||||
|
||||
## 2. Security Enhancements
|
||||
|
||||
### 2.1 WAF and Machine Learning Improvements
|
||||
|
||||
**Current State**: The system includes a sophisticated Web Application Firewall with machine learning capabilities for anomaly detection.
|
||||
|
||||
**Proposed Changes**:
|
||||
- Enhance the feature extraction pipeline with more behavioral indicators
|
||||
- Implement ensemble learning to combine multiple detector results
|
||||
- Add real-time visualization of security anomalies for administrators
|
||||
- Create a feedback loop system for false positive/negative reporting
|
||||
|
||||
**Rationale**: These improvements will enhance threat detection accuracy, reduce false positives, and provide better visibility into security events.
|
||||
|
||||
### 2.2 Comprehensive Security Headers
|
||||
|
||||
**Current State**: Basic security measures are in place, but modern security headers could be more consistently applied.
|
||||
|
||||
**Proposed Changes**:
|
||||
- Implement Content Security Policy (CSP) with appropriate directives
|
||||
- Add Strict-Transport-Security, X-Content-Type-Options, and other security headers
|
||||
- Create a security header audit tool for continuous monitoring
|
||||
|
||||
**Rationale**: Modern security headers provide an additional layer of defense against common web vulnerabilities like XSS, clickjacking, and MIME type confusion.
|
||||
|
||||
### 2.3 Authentication and Authorization Hardening
|
||||
|
||||
**Current State**: Authentication and authorization systems exist but could benefit from additional security measures.
|
||||
|
||||
**Proposed Changes**:
|
||||
- Implement multi-factor authentication support
|
||||
- Add role-based access control with fine-grained permissions
|
||||
- Create comprehensive audit logging for security-sensitive operations
|
||||
|
||||
**Rationale**: Enhanced authentication and authorization will protect sensitive operations and data, while audit logging will improve incident response capabilities.
|
||||
|
||||
## 3. Performance Optimization
|
||||
|
||||
### 3.1 Caching Strategy
|
||||
|
||||
**Current State**: Some caching mechanisms exist, but a comprehensive caching strategy is not fully implemented.
|
||||
|
||||
**Proposed Changes**:
|
||||
- Implement a multi-level caching strategy (memory, local, distributed)
|
||||
- Add cache warming for frequently accessed data
|
||||
- Create cache invalidation patterns for different data types
|
||||
- Implement automatic cache analysis to identify caching opportunities
|
||||
|
||||
**Rationale**: A well-designed caching strategy will significantly improve application performance, reduce database load, and enhance user experience.
|
||||
|
||||
### 3.2 Database Optimization
|
||||
|
||||
**Current State**: Basic database operations are implemented, but there's room for optimization.
|
||||
|
||||
**Proposed Changes**:
|
||||
- Add query analysis and optimization tools
|
||||
- Implement database connection pooling
|
||||
- Create index optimization based on query patterns
|
||||
- Add database sharding support for horizontal scaling
|
||||
|
||||
**Rationale**: Database optimizations will improve response times for data-intensive operations and support scaling as the application grows.
|
||||
|
||||
### 3.3 Asynchronous Processing
|
||||
|
||||
**Current State**: Most operations are synchronous, potentially blocking the main execution thread.
|
||||
|
||||
**Proposed Changes**:
|
||||
- Implement a robust asynchronous processing system for non-critical operations
|
||||
- Add support for background jobs with retry mechanisms
|
||||
- Create a monitoring dashboard for async job status
|
||||
|
||||
**Rationale**: Asynchronous processing will improve responsiveness, allow for better resource utilization, and enhance the system's ability to handle peak loads.
|
||||
|
||||
## 4. Developer Experience
|
||||
|
||||
### 4.1 Testing Infrastructure
|
||||
|
||||
**Current State**: Testing coverage is incomplete across many components.
|
||||
|
||||
**Proposed Changes**:
|
||||
- Implement a comprehensive testing strategy covering unit, integration, and end-to-end tests
|
||||
- Add automated test generation tools for common patterns
|
||||
- Create visual test coverage reports integrated with CI/CD
|
||||
- Implement contract testing for service interfaces
|
||||
|
||||
**Rationale**: Improved testing infrastructure will enhance code quality, reduce regressions, and give developers confidence when making changes.
|
||||
|
||||
### 4.2 Documentation System
|
||||
|
||||
**Current State**: Documentation exists but is scattered and incomplete in some areas.
|
||||
|
||||
**Proposed Changes**:
|
||||
- Create an integrated documentation system with code-level and architectural documentation
|
||||
- Implement automatic API documentation generation
|
||||
- Add interactive examples and tutorials for key components
|
||||
- Create a centralized knowledge base for development practices
|
||||
|
||||
**Rationale**: Comprehensive documentation will improve developer onboarding, reduce knowledge silos, and promote consistent development practices.
|
||||
|
||||
### 4.3 Development Workflow Optimization
|
||||
|
||||
**Current State**: Basic development tools are in place, but the workflow could be streamlined.
|
||||
|
||||
**Proposed Changes**:
|
||||
- Implement standardized development environments using containers
|
||||
- Create automated code quality checks with immediate feedback
|
||||
- Add interactive debugging tools for complex components
|
||||
- Implement feature flag system for safer deployments
|
||||
|
||||
**Rationale**: Optimized development workflows will increase developer productivity, improve code quality, and reduce the time from idea to implementation.
|
||||
|
||||
## 5. Scalability and Reliability
|
||||
|
||||
### 5.1 Horizontal Scaling Support
|
||||
|
||||
**Current State**: The application architecture may not fully support horizontal scaling.
|
||||
|
||||
**Proposed Changes**:
|
||||
- Implement stateless service design patterns
|
||||
- Add distributed session management
|
||||
- Create load balancing strategies for different service types
|
||||
- Implement service discovery for dynamic scaling
|
||||
|
||||
**Rationale**: Supporting horizontal scaling will allow the application to handle increased load by adding more instances rather than requiring larger servers.
|
||||
|
||||
### 5.2 Resilience Patterns
|
||||
|
||||
**Current State**: Basic error handling exists, but comprehensive resilience patterns are not fully implemented.
|
||||
|
||||
**Proposed Changes**:
|
||||
- Implement circuit breaker patterns for external service calls
|
||||
- Add retry mechanisms with exponential backoff
|
||||
- Create fallback strategies for critical services
|
||||
- Implement bulkhead patterns to isolate failures
|
||||
|
||||
**Rationale**: Resilience patterns will improve system stability, prevent cascading failures, and enhance the user experience during partial outages.
|
||||
|
||||
### 5.3 Monitoring and Observability
|
||||
|
||||
**Current State**: Basic logging is implemented, but comprehensive monitoring is limited.
|
||||
|
||||
**Proposed Changes**:
|
||||
- Implement distributed tracing across all services
|
||||
- Add real-time metrics collection and visualization
|
||||
- Create anomaly detection for system metrics
|
||||
- Implement health check APIs with detailed status reporting
|
||||
|
||||
**Rationale**: Enhanced monitoring and observability will improve incident response, help identify performance bottlenecks, and provide insights for optimization.
|
||||
|
||||
## 6. Feature Completion
|
||||
|
||||
### 6.1 Core Framework Features
|
||||
|
||||
**Current State**: Many core features are planned but not fully implemented.
|
||||
|
||||
**Proposed Changes**:
|
||||
- Complete routing system with PHP attribute support
|
||||
- Enhance the template engine with caching and optimization
|
||||
- Implement a comprehensive error handling system
|
||||
- Complete the configuration system implementation
|
||||
|
||||
**Rationale**: Completing core framework features will provide a solid foundation for application development and ensure consistency across the system.
|
||||
|
||||
### 6.2 Module Completion
|
||||
|
||||
**Current State**: Several modules are partially implemented or planned.
|
||||
|
||||
**Proposed Changes**:
|
||||
- Complete the database module with migration system and query builder
|
||||
- Implement the security module with all planned features
|
||||
- Develop the content module with Markdown support and media library
|
||||
- Complete the admin interface with dashboard and user management
|
||||
|
||||
**Rationale**: Completing planned modules will provide a comprehensive set of tools for application development and reduce the need for external dependencies.
|
||||
|
||||
## 7. Implementation Roadmap
|
||||
|
||||
### 7.1 Short-term Priorities (1-3 months)
|
||||
|
||||
1. Complete core framework features
|
||||
2. Implement comprehensive testing infrastructure
|
||||
3. Enhance security with WAF improvements and security headers
|
||||
4. Optimize service initialization and bootstrap process
|
||||
|
||||
### 7.2 Medium-term Goals (3-6 months)
|
||||
|
||||
1. Implement caching strategy and database optimizations
|
||||
2. Complete module implementation for key features
|
||||
3. Enhance developer experience with documentation and workflow improvements
|
||||
4. Implement resilience patterns for improved stability
|
||||
|
||||
### 7.3 Long-term Vision (6-12 months)
|
||||
|
||||
1. Implement horizontal scaling support
|
||||
2. Develop comprehensive monitoring and observability
|
||||
3. Complete all planned modules and features
|
||||
4. Optimize for performance at scale
|
||||
|
||||
## Conclusion
|
||||
|
||||
This improvement plan addresses key areas of the project including architecture, security, performance, developer experience, scalability, and feature completion. By implementing these recommendations in a phased approach, the project will achieve improved stability, security, performance, and developer productivity.
|
||||
|
||||
The plan aligns with the project's modular architecture and builds upon the existing strengths while addressing areas that need improvement. Regular review and adjustment of this plan is recommended as the project evolves and new requirements emerge.
|
||||
@@ -0,0 +1,234 @@
|
||||
# Coding Guidelines
|
||||
|
||||
## Allgemeine Prinzipien
|
||||
|
||||
Diese Guidelines definieren die Standards für die Entwicklung und Wartung des Projekts. Sie sorgen für Konsistenz, Lesbarkeit und Wartbarkeit des Codes.
|
||||
|
||||
## PHP-Version
|
||||
|
||||
- **PHP 8.4**: Die Codebase nutzt stets die neueste stabile PHP-Version (aktuell PHP 8.4)
|
||||
- Alle neuen PHP-Sprachfeatures sollten, wo sinnvoll, genutzt werden
|
||||
|
||||
## Abhängigkeiten
|
||||
|
||||
- **Externe Abhängigkeiten vermeiden**: Das Projekt soll möglichst ohne externe Bibliotheken auskommen
|
||||
- **Eigene Implementierungen bevorzugen**: Anstatt externe Pakete einzubinden, sollten eigene Lösungen entwickelt werden
|
||||
- **Erlaubte Abhängigkeiten**: Nur die bereits in composer.json definierten Pakete dürfen verwendet werden
|
||||
- **Neue Abhängigkeiten**: Müssen explizit genehmigt werden und sollten nur in Ausnahmefällen hinzugefügt werden
|
||||
|
||||
## Klassenstruktur
|
||||
|
||||
### Klassen
|
||||
|
||||
- **Alle Klassen müssen `final` sein**, es sei denn, es gibt einen zwingenden Grund für Vererbung
|
||||
- **Keine abstrakten Klassen** - bevorzuge Interfaces und Kompositionen
|
||||
- **Klassen sollten `readonly` sein**, wann immer möglich
|
||||
- Interfaces verwenden, um Verträge zwischen Komponenten zu definieren
|
||||
|
||||
```php
|
||||
// Gut
|
||||
final readonly class AnalyticsManager
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
// Vermeiden
|
||||
abstract class BaseManager
|
||||
{
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Properties
|
||||
|
||||
- **Properties sollten `readonly` sein**, wann immer möglich
|
||||
- Private Visibility für alle Properties, es sei denn, es gibt einen zwingenden Grund
|
||||
- Typisierung ist obligatorisch für alle Properties
|
||||
|
||||
```php
|
||||
// Gut
|
||||
private readonly StorageInterface $storage;
|
||||
|
||||
// Vermeiden
|
||||
public array $config;
|
||||
```
|
||||
|
||||
## Methoden und Funktionen
|
||||
|
||||
- Typisierung ist obligatorisch für alle Parameter und Rückgabewerte
|
||||
- Methoden sollten klein und fokussiert sein (Single Responsibility)
|
||||
- Verwende named arguments für bessere Lesbarkeit
|
||||
|
||||
```php
|
||||
// Gut
|
||||
public function track(string $event, array $properties = [], ?string $userId = null): void
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
// Vermeiden
|
||||
public function process($data)
|
||||
{
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
## Dependency Injection
|
||||
|
||||
- Constructor Injection für alle Abhängigkeiten
|
||||
- Keine Service Locator oder globale Zustände
|
||||
- Verwende das `#[Initializer]`-Attribut für Service-Registrierung
|
||||
|
||||
```php
|
||||
// Gut
|
||||
public function __construct(
|
||||
private readonly Configuration $config,
|
||||
private readonly StorageInterface $storage
|
||||
) {}
|
||||
|
||||
// Vermeiden
|
||||
public function __construct()
|
||||
{
|
||||
$this->config = Container::get(Configuration::class);
|
||||
}
|
||||
```
|
||||
|
||||
## Moderne PHP-Features
|
||||
|
||||
### Nullable Types und Union Types
|
||||
|
||||
```php
|
||||
public function findUser(?int $id): ?User
|
||||
public function process(int|string $identifier): void
|
||||
```
|
||||
|
||||
### Match Expression statt Switch
|
||||
|
||||
```php
|
||||
// Gut
|
||||
return match($storageType) {
|
||||
'file' => new FileStorage($path),
|
||||
'redis' => new RedisStorage($connection),
|
||||
default => throw new \InvalidArgumentException("Nicht unterstützter Storage-Typ: {$storageType}")
|
||||
};
|
||||
|
||||
// Vermeiden
|
||||
switch ($storageType) {
|
||||
case 'file':
|
||||
return new FileStorage($path);
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Named Arguments
|
||||
|
||||
```php
|
||||
$this->createUser(
|
||||
email: 'user@example.com',
|
||||
role: 'admin',
|
||||
sendWelcomeEmail: true
|
||||
);
|
||||
```
|
||||
|
||||
### Constructor Property Promotion
|
||||
|
||||
```php
|
||||
public function __construct(
|
||||
private readonly Configuration $config,
|
||||
private readonly PathProvider $pathProvider
|
||||
) {}
|
||||
```
|
||||
|
||||
## Fehlerbehandlung
|
||||
|
||||
- Spezifische Exceptions werfen
|
||||
- Typed Exceptions verwenden
|
||||
- Early Return Pattern bevorzugen
|
||||
|
||||
```php
|
||||
// Gut
|
||||
if (!$this->isValid()) {
|
||||
throw new ValidationException('Ungültige Daten');
|
||||
}
|
||||
|
||||
// Vermeiden
|
||||
if ($this->isValid()) {
|
||||
// Lange Verarbeitung...
|
||||
} else {
|
||||
throw new Exception('Fehler');
|
||||
}
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
- Tests mit Pest-Framework schreiben
|
||||
- Für jede öffentliche Methode sollte mindestens ein Test existieren
|
||||
- Mocking nur für externe Abhängigkeiten verwenden
|
||||
|
||||
```php
|
||||
test('track method records events correctly', function () {
|
||||
$analytics = new Analytics($manager, $dispatcher);
|
||||
$analytics->track('test_event', ['key' => 'value']);
|
||||
|
||||
expect($manager->getEvents())->toHaveCount(1);
|
||||
});
|
||||
```
|
||||
|
||||
## Dokumentation
|
||||
|
||||
- PHPDoc für alle öffentlichen Methoden und Klassen
|
||||
- Typen in PHPDoc sollten den tatsächlichen Typen entsprechen
|
||||
- Klare, beschreibende Kommentare für komplexe Logik
|
||||
|
||||
```php
|
||||
/**
|
||||
* Zeichnet ein Event auf und wendet Middleware an
|
||||
*
|
||||
* @param string $event Event-Name
|
||||
* @param array $properties Event-Eigenschaften
|
||||
* @param string|null $userId Benutzer-ID (optional)
|
||||
*/
|
||||
public function track(string $event, array $properties = [], ?string $userId = null): void
|
||||
```
|
||||
|
||||
## Namenskonventionen
|
||||
|
||||
- **Klassen**: PascalCase (`AnalyticsManager`)
|
||||
- **Methoden/Funktionen**: camelCase (`getEventStats()`)
|
||||
- **Variablen**: camelCase (`$eventData`)
|
||||
- **Konstanten**: SNAKE_CASE (`MAX_BATCH_SIZE`)
|
||||
- **Dateien**: Klassenname.php (`AnalyticsManager.php`)
|
||||
|
||||
## Architektur
|
||||
|
||||
- Dependency Inversion Principle befolgen
|
||||
- Interfaces für alle externen Abhängigkeiten
|
||||
- Vermeide zirkuläre Abhängigkeiten zwischen Modulen
|
||||
- Services sollten eine klare, fokussierte Verantwortung haben
|
||||
|
||||
## Performance
|
||||
|
||||
- Lazy Loading für ressourcenintensive Operationen
|
||||
- Caching wo sinnvoll
|
||||
- Datenstrukturen sorgfältig auswählen
|
||||
|
||||
## Security
|
||||
|
||||
- Alle Benutzereingaben validieren und bereinigen
|
||||
- Prepared Statements für Datenbankabfragen
|
||||
- Vermeidung von `eval()` und ähnlichen unsicheren Funktionen
|
||||
- Sensible Daten niemals in Logs schreiben
|
||||
|
||||
## Best Practices
|
||||
|
||||
- **Immutability**: Bevorzuge unveränderliche Objekte
|
||||
- **Pure Functions**: Bevorzuge reine Funktionen ohne Seiteneffekte
|
||||
- **Enums**: Verwende Enums statt String-Konstanten für feste Optionssätze
|
||||
- **DTOs**: Verwende Data Transfer Objects für Datentransport
|
||||
- **Value Objects**: Verwende Value Objects für semantisch reiche Datentypen
|
||||
|
||||
## Refactoring
|
||||
|
||||
- Code, der diese Guidelines nicht erfüllt, sollte beim Bearbeiten aktualisiert werden
|
||||
- Tests müssen vor und nach dem Refactoring bestehen
|
||||
- Große Refactorings sollten in kleinen, separaten Commits erfolgen
|
||||
@@ -0,0 +1,187 @@
|
||||
# Sicherheitsrichtlinien
|
||||
|
||||
## Übersicht
|
||||
|
||||
Diese Richtlinien definieren Standards und Best Practices für sichere Softwareentwicklung im Projekt.
|
||||
|
||||
## Grundprinzipien
|
||||
|
||||
### 1. Defense in Depth
|
||||
|
||||
- Mehrere Sicherheitsschichten implementieren
|
||||
- Nicht auf eine einzelne Sicherheitsmaßnahme vertrauen
|
||||
- Fail-Safe-Mechanismen einbauen
|
||||
|
||||
### 2. Least Privilege
|
||||
|
||||
- Minimale Berechtigungen für Funktionen und Benutzer
|
||||
- Ressourcenzugriff nur bei Bedarf gewähren
|
||||
- Temporäre Berechtigungen nach Gebrauch entziehen
|
||||
|
||||
### 3. Input-Validierung
|
||||
|
||||
- Alle Benutzereingaben validieren und bereinigen
|
||||
- Whitelist-Ansatz bevorzugen (erlaubte Eingaben definieren)
|
||||
- Typprüfung und Formatvalidierung durchführen
|
||||
|
||||
```php
|
||||
// Beispiel: Sichere Input-Validierung
|
||||
public function processUserInput(string $input): string
|
||||
{
|
||||
// Länge prüfen
|
||||
if (strlen($input) > 100) {
|
||||
throw new ValidationException('Input zu lang (max 100 Zeichen)');
|
||||
}
|
||||
|
||||
// Inhalt validieren (Whitelist-Ansatz)
|
||||
if (!preg_match('/^[a-zA-Z0-9\s\-_]+$/', $input)) {
|
||||
throw new ValidationException('Input enthält ungültige Zeichen');
|
||||
}
|
||||
|
||||
// Bereinigung
|
||||
return htmlspecialchars($input, ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
```
|
||||
|
||||
## Spezifische Sicherheitsmaßnahmen
|
||||
|
||||
### 1. SQL-Injection-Prävention
|
||||
|
||||
- Prepared Statements für alle Datenbankabfragen
|
||||
- Keine dynamischen SQL-Queries
|
||||
- ORM-Framework bevorzugen
|
||||
|
||||
```php
|
||||
// Sicher
|
||||
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?");
|
||||
$stmt->execute([$email]);
|
||||
|
||||
// Unsicher - NIEMALS SO MACHEN
|
||||
$query = "SELECT * FROM users WHERE email = '{$email}'";
|
||||
```
|
||||
|
||||
### 2. Cross-Site Scripting (XSS) Prävention
|
||||
|
||||
- Output-Escaping für alle benutzergenerierten Inhalte
|
||||
- Content-Security-Policy (CSP) implementieren
|
||||
- HttpOnly und Secure Flags für Cookies
|
||||
|
||||
```php
|
||||
// Ausgabe in HTML
|
||||
echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');
|
||||
|
||||
// Ausgabe in JavaScript
|
||||
echo json_encode($userInput, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP);
|
||||
```
|
||||
|
||||
### 3. Cross-Site Request Forgery (CSRF) Schutz
|
||||
|
||||
- CSRF-Token für alle ändernden Anfragen
|
||||
- SameSite-Attribut für Cookies
|
||||
|
||||
```php
|
||||
// CSRF-Token generieren
|
||||
public function generateCsrfToken(): string
|
||||
{
|
||||
$token = bin2hex(random_bytes(32));
|
||||
$_SESSION['csrf_token'] = $token;
|
||||
return $token;
|
||||
}
|
||||
|
||||
// CSRF-Token validieren
|
||||
public function validateCsrfToken(string $token): bool
|
||||
{
|
||||
return hash_equals($_SESSION['csrf_token'] ?? '', $token);
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Sichere Authentifizierung
|
||||
|
||||
- Passwörter mit starken Algorithmen hashen (Argon2id)
|
||||
- Multi-Faktor-Authentifizierung anbieten
|
||||
- Ratelimiting für Login-Versuche
|
||||
|
||||
```php
|
||||
// Passwort hashen
|
||||
public function hashPassword(string $password): string
|
||||
{
|
||||
return password_hash($password, PASSWORD_ARGON2ID);
|
||||
}
|
||||
|
||||
// Passwort verifizieren
|
||||
public function verifyPassword(string $password, string $hash): bool
|
||||
{
|
||||
return password_verify($password, $hash);
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Sichere Datenspeicherung
|
||||
|
||||
- Sensible Daten verschlüsseln
|
||||
- Separate Schlüssel für unterschiedliche Daten
|
||||
- Schlüsselrotation implementieren
|
||||
|
||||
```php
|
||||
// Daten verschlüsseln
|
||||
public function encrypt(string $data, string $purpose): string
|
||||
{
|
||||
$key = $this->getEncryptionKey($purpose);
|
||||
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
|
||||
|
||||
$cipher = sodium_crypto_secretbox(
|
||||
$data,
|
||||
$nonce,
|
||||
$key
|
||||
);
|
||||
|
||||
return base64_encode($nonce . $cipher);
|
||||
}
|
||||
|
||||
// Daten entschlüsseln
|
||||
public function decrypt(string $encrypted, string $purpose): string
|
||||
{
|
||||
$key = $this->getEncryptionKey($purpose);
|
||||
$decoded = base64_decode($encrypted);
|
||||
|
||||
$nonce = mb_substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
|
||||
$cipher = mb_substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
|
||||
|
||||
return sodium_crypto_secretbox_open(
|
||||
$cipher,
|
||||
$nonce,
|
||||
$key
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Sicherheitstests
|
||||
|
||||
### 1. Automatisierte Sicherheitstests
|
||||
|
||||
- Static Application Security Testing (SAST)
|
||||
- Dynamic Application Security Testing (DAST)
|
||||
- Dependency-Scanning für bekannte Schwachstellen
|
||||
|
||||
### 2. Penetrationstests
|
||||
|
||||
- Regelmäßige Sicherheitsaudits
|
||||
- Manuelle Penetrationstests
|
||||
- Bug-Bounty-Programme
|
||||
|
||||
## Sicherheitskultur
|
||||
|
||||
### 1. Entwicklerschulungen
|
||||
|
||||
- Regelmäßige Sicherheitsschulungen
|
||||
- Code-Reviews mit Sicherheitsfokus
|
||||
- Sicherheits-Champions im Team
|
||||
|
||||
### 2. Incident Response
|
||||
|
||||
- Sicherheitsvorfälle dokumentieren
|
||||
- Prozess für Sicherheitsmeldungen
|
||||
- Notfallpläne für Sicherheitsvorfälle
|
||||
|
||||
## Zusammenfassung
|
||||
|
||||
Sicherheit ist ein kontinuierlicher Prozess, keine einmalige Aufgabe. Diese Richtlinien sollten regelmäßig überprüft und aktualisiert werden, um neuen Bedrohungen zu begegnen.
|
||||
50
backups/docs-backup-20250731125004/standards/index.md
Normal file
50
backups/docs-backup-20250731125004/standards/index.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# Coding-Standards und Richtlinien
|
||||
|
||||
## Übersicht
|
||||
|
||||
Diese Standards und Richtlinien definieren die grundlegenden Prinzipien für die Codierung und Sicherheit im Projekt. Sie gewährleisten Konsistenz, Wartbarkeit und Sicherheit des Codes.
|
||||
|
||||
## Verfügbare Standards
|
||||
|
||||
- [Coding Guidelines](/standards/CODING-GUIDELINES.md) - Allgemeine Coding-Standards für das Projekt
|
||||
- [Sicherheitsrichtlinien](/standards/SICHERHEITS-GUIDELINES.md) - Standards für sichere Softwareentwicklung
|
||||
|
||||
## Coding Guidelines
|
||||
|
||||
Die [Coding Guidelines](/standards/CODING-GUIDELINES.md) definieren die technischen Standards für die Codeentwicklung, einschließlich:
|
||||
|
||||
- Klassenstruktur und -design
|
||||
- Property- und Methodendefinitionen
|
||||
- Nutzung moderner PHP-Features
|
||||
- Fehlerbehandlung
|
||||
- Dokumentation
|
||||
- Namenskonventionen
|
||||
|
||||
## Sicherheitsrichtlinien
|
||||
|
||||
Die [Sicherheitsrichtlinien](/standards/SICHERHEITS-GUIDELINES.md) bieten umfassende Anleitungen zur sicheren Softwareentwicklung:
|
||||
|
||||
- Input-Validierung
|
||||
- SQL-Injection-Prävention
|
||||
- XSS-Schutz
|
||||
- CSRF-Schutz
|
||||
- Sichere Authentifizierung
|
||||
- Sichere Datenspeicherung
|
||||
- Session-Management
|
||||
|
||||
## Anwendung der Standards
|
||||
|
||||
Alle Teammitglieder sind verpflichtet, diese Standards in ihrer Arbeit anzuwenden. Sie dienen als Grundlage für Code-Reviews und Qualitätssicherung.
|
||||
|
||||
## Abweichungen von Standards
|
||||
|
||||
In Ausnahmefällen können Abweichungen von diesen Standards erforderlich sein. Solche Abweichungen sollten:
|
||||
|
||||
1. Dokumentiert werden
|
||||
2. Begründet werden
|
||||
3. Im Team besprochen werden
|
||||
4. Auf ein Minimum beschränkt werden
|
||||
|
||||
## Aktualisierungen
|
||||
|
||||
Diese Standards werden regelmäßig überprüft und aktualisiert, um sicherzustellen, dass sie den neuesten Best Practices und Technologien entsprechen.
|
||||
138
backups/docs-backup-20250731125004/tasks.md
Normal file
138
backups/docs-backup-20250731125004/tasks.md
Normal file
@@ -0,0 +1,138 @@
|
||||
# Improvement Tasks
|
||||
|
||||
This document contains a comprehensive list of actionable improvement tasks for the project. Each task is specific, actionable, and can be checked off when completed.
|
||||
|
||||
## Architecture
|
||||
|
||||
1. [ ] Evaluate and optimize the dependency graph in the DI container to reduce initialization time
|
||||
2. [ ] Implement a service locator pattern for non-critical services to reduce container complexity
|
||||
3. [ ] Create a unified configuration system that consolidates the various config approaches (env files, JSON configs, code-based configs)
|
||||
4. [ ] Refactor the bootstrapping process to support lazy-loading of non-essential services
|
||||
5. [ ] Implement a module system to better organize and encapsulate related components
|
||||
6. [ ] Standardize error handling across all framework components
|
||||
7. [ ] Create a comprehensive application lifecycle documentation with sequence diagrams
|
||||
8. [ ] Implement a plugin architecture to allow for easier extension of core functionality
|
||||
|
||||
## Code Quality
|
||||
|
||||
9. [ ] Complete all TODO items in the codebase:
|
||||
- [ ] Implement migration logic in `MigrationGenerator.php`
|
||||
- [ ] Implement rollback in `MigrationGenerator.php`
|
||||
- [ ] Return proper responses in various handlers
|
||||
- [ ] Implement actual login logic in `LoginUserHandler.php`
|
||||
- [ ] Use Clock instead of date() in `ShowImageUpload.php`
|
||||
- [ ] Implement Size for ImageVariant in `ImageVariant.php`
|
||||
- [ ] Remove TTL in RedisCache
|
||||
- [ ] Get RequestData from Request Object in Container
|
||||
- [ ] Integrate McpInitializer with the discovery system
|
||||
10. [ ] Implement consistent error handling and logging across all components
|
||||
11. [ ] Add comprehensive PHPDoc comments to all public methods and classes
|
||||
12. [ ] Standardize naming conventions across the codebase
|
||||
13. [ ] Refactor large classes (>200 lines) into smaller, more focused components
|
||||
14. [ ] Implement strict type checking across all files
|
||||
15. [ ] Remove commented-out code and unused imports
|
||||
16. [ ] Apply consistent code formatting using PHP-CS-Fixer or similar tool
|
||||
|
||||
## Performance
|
||||
|
||||
17. [ ] Implement caching for frequently accessed data and expensive operations
|
||||
18. [ ] Optimize database queries by adding appropriate indexes and query analysis
|
||||
19. [ ] Implement lazy loading for non-critical components
|
||||
20. [ ] Add performance benchmarks for critical paths in the application
|
||||
21. [ ] Optimize the discovery service to reduce bootstrap time
|
||||
22. [ ] Implement resource pooling for database connections and other expensive resources
|
||||
23. [ ] Add memory usage optimization for large data processing
|
||||
24. [ ] Implement asynchronous processing for non-blocking operations
|
||||
25. [ ] Optimize the dependency injection container initialization
|
||||
26. [ ] Add performance monitoring for production environments
|
||||
|
||||
## Security
|
||||
|
||||
27. [ ] Implement comprehensive input validation for all user inputs
|
||||
28. [ ] Add Content Security Policy (CSP) headers
|
||||
29. [ ] Implement rate limiting for all public endpoints
|
||||
30. [ ] Add security headers (X-Content-Type-Options, X-Frame-Options, etc.)
|
||||
31. [ ] Implement proper password hashing and storage
|
||||
32. [ ] Add CSRF protection to all forms
|
||||
33. [ ] Implement proper session management with secure cookies
|
||||
34. [ ] Add security scanning in the CI/CD pipeline
|
||||
35. [ ] Implement proper error handling that doesn't expose sensitive information
|
||||
36. [ ] Add security audit logging for sensitive operations
|
||||
|
||||
## Testing
|
||||
|
||||
37. [ ] Add unit tests for components without test coverage:
|
||||
- [ ] Analytics
|
||||
- [ ] Api
|
||||
- [ ] Attributes
|
||||
- [ ] Auth
|
||||
- [ ] CircuitBreaker
|
||||
- [ ] Config
|
||||
- [ ] Console
|
||||
- [ ] Context
|
||||
- [ ] Debug
|
||||
- [ ] Encryption
|
||||
- [ ] ErrorAggregation
|
||||
- [ ] ErrorBoundaries
|
||||
- [ ] ErrorHandling
|
||||
- [ ] ErrorReporting
|
||||
- [ ] EventBus
|
||||
- [ ] Exception
|
||||
- [ ] Firewall
|
||||
- [ ] Health
|
||||
- [ ] HttpClient
|
||||
- [ ] Logging
|
||||
- [ ] Markdown
|
||||
- [ ] Meta
|
||||
- [ ] OpenApi
|
||||
- [ ] Performance
|
||||
- [ ] Quality
|
||||
- [ ] QueryBus
|
||||
- [ ] Queue
|
||||
- [ ] Random
|
||||
- [ ] RateLimit
|
||||
- [ ] Redis
|
||||
- [ ] Reflection
|
||||
- [ ] Sitemap
|
||||
- [ ] Smartlinks
|
||||
- [ ] SyntaxHighlighter
|
||||
- [ ] Tracing
|
||||
- [ ] Ulid
|
||||
- [ ] UserAgent
|
||||
- [ ] Waf
|
||||
- [ ] Worker
|
||||
38. [ ] Implement integration tests for critical workflows
|
||||
39. [ ] Add end-to-end tests for key user journeys
|
||||
40. [ ] Implement performance tests for critical paths
|
||||
41. [ ] Add security tests for authentication and authorization
|
||||
42. [ ] Implement mutation testing to verify test quality
|
||||
43. [ ] Add code coverage reporting to CI/CD pipeline
|
||||
44. [ ] Implement contract tests for API endpoints
|
||||
45. [ ] Add load testing for high-traffic endpoints
|
||||
46. [ ] Implement snapshot testing for UI components
|
||||
|
||||
## Documentation
|
||||
|
||||
47. [ ] Create comprehensive API documentation
|
||||
48. [ ] Add inline code documentation for complex algorithms
|
||||
49. [ ] Create user guides for key features
|
||||
50. [ ] Document the architecture and design decisions
|
||||
51. [ ] Add setup and installation instructions
|
||||
52. [ ] Create troubleshooting guides
|
||||
53. [ ] Document performance optimization strategies
|
||||
54. [ ] Add security best practices documentation
|
||||
55. [ ] Create developer onboarding documentation
|
||||
56. [ ] Document testing strategies and approaches
|
||||
|
||||
## DevOps
|
||||
|
||||
57. [ ] Implement automated deployment pipelines
|
||||
58. [ ] Add infrastructure as code for all environments
|
||||
59. [ ] Implement comprehensive monitoring and alerting
|
||||
60. [ ] Add automated database migrations
|
||||
61. [ ] Implement blue-green deployments
|
||||
62. [ ] Add canary releases for critical features
|
||||
63. [ ] Implement feature flags for gradual rollouts
|
||||
64. [ ] Add automated rollback mechanisms
|
||||
65. [ ] Implement comprehensive logging and log aggregation
|
||||
66. [ ] Add performance monitoring and profiling in production
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ULID Validation Rule - Verwendungsbeispiele
|
||||
*
|
||||
* Die ULID Validation Rule verwendet den bestehenden UlidValidator
|
||||
* für konsistente ULID-Validierung nach dem offiziellen Standard.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Framework\Validation\Rules\Ulid;
|
||||
|
||||
// Basis ULID-Validierung
|
||||
class EntityRequest
|
||||
{
|
||||
public function __construct(
|
||||
#[Ulid]
|
||||
public readonly string $id,
|
||||
|
||||
#[Ulid]
|
||||
public readonly string $parentId,
|
||||
|
||||
#[Ulid(message: 'Die Benutzer-ID muss eine gültige ULID sein.')]
|
||||
public readonly string $userId,
|
||||
) {}
|
||||
}
|
||||
|
||||
// Verwendungsbeispiele:
|
||||
|
||||
// ✅ Gültige ULIDs
|
||||
$validExamples = [
|
||||
'id' => '01ARZ3NDEKTSV4RRFFQ69G5FAV',
|
||||
'parentId' => '01BX5ZZKBKACTAV9WEVGEMMVRY',
|
||||
'userId' => '01CA2ZZKBKACTAV9WEVGEMMVRY',
|
||||
];
|
||||
|
||||
// ❌ Ungültige ULIDs
|
||||
$invalidExamples = [
|
||||
'id' => '01ARZ3NDEKTSV4RRFFQ69G5F', // Zu kurz (25 statt 26 Zeichen)
|
||||
'parentId' => '01ARZ3NDEKTSV4RRFFQ69G5FAVX', // Zu lang (27 Zeichen)
|
||||
'userId' => '01ARZ3NDEKTSV4RRFFQ69G5FIV', // Enthält 'I' (nicht erlaubt)
|
||||
];
|
||||
|
||||
/**
|
||||
* ULID (Universally Unique Lexicographically Sortable Identifier) Standard:
|
||||
*
|
||||
* Format: 26 Zeichen in Crockford Base32 Encoding
|
||||
* - Erste 10 Zeichen: Zeitstempel (48-bit Unix-Zeit in Millisekunden)
|
||||
* - Letzte 16 Zeichen: Zufälliger Teil (80-bit Entropie)
|
||||
*
|
||||
* Erlaubte Zeichen (Crockford Base32):
|
||||
* 0123456789ABCDEFGHJKMNPQRSTVWXYZ
|
||||
*
|
||||
* Nicht erlaubte Zeichen (um Verwechslungen zu vermeiden):
|
||||
* - I (sieht wie 1 aus)
|
||||
* - L (sieht wie 1 aus)
|
||||
* - O (sieht wie 0 aus)
|
||||
* - U (kann wie V aussehen)
|
||||
*
|
||||
* Eigenschaften von ULIDs:
|
||||
* ✅ Lexikographisch sortierbar (chronologische Ordnung)
|
||||
* ✅ URL-sicher (keine Sonderzeichen)
|
||||
* ✅ Case-insensitive (obwohl üblicherweise Großbuchstaben verwendet werden)
|
||||
* ✅ Monotonisch (innerhalb derselben Millisekunde aufsteigend)
|
||||
* ✅ Kompakt (26 Zeichen vs. 36 für UUID mit Bindestrichen)
|
||||
*
|
||||
* Validierungsregeln:
|
||||
* - Exakt 26 Zeichen
|
||||
* - Nur Crockford Base32 Zeichen
|
||||
* - Keine Leer- oder Sonderzeichen
|
||||
* - Case-sensitive (üblicherweise Großbuchstaben)
|
||||
*
|
||||
* Beispiele für gültige ULIDs:
|
||||
* - 01ARZ3NDEKTSV4RRFFQ69G5FAV (Standard-Format)
|
||||
* - 00000000000000000000000000 (Minimum ULID)
|
||||
* - 7ZZZZZZZZZZZZZZZZZZZZZZZZZ (Maximum timestamp)
|
||||
* - GGGGGGGGGGGGGGGGGGGGGGGGGG (Alle G's - technisch gültig)
|
||||
*/
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* URL Validation Rule - Verwendungsbeispiele
|
||||
*
|
||||
* Die URL Validation Rule verwendet das bestehende Url Value Object
|
||||
* für konsistente und umfassende URL-Validierung.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Framework\Validation\Rules\Url;
|
||||
|
||||
// Basis URL-Validierung
|
||||
class UserProfileRequest
|
||||
{
|
||||
public function __construct(
|
||||
#[Url]
|
||||
public readonly string $website,
|
||||
|
||||
#[Url(requireSecure: true)]
|
||||
public readonly string $secureUrl,
|
||||
|
||||
#[Url(allowLocal: false)]
|
||||
public readonly string $publicUrl,
|
||||
|
||||
#[Url(autoAddProtocol: true)]
|
||||
public readonly string $flexibleUrl,
|
||||
|
||||
#[Url(
|
||||
requireSecure: true,
|
||||
allowLocal: false,
|
||||
message: 'Bitte geben Sie eine gültige HTTPS-URL ein, die öffentlich erreichbar ist.'
|
||||
)]
|
||||
public readonly string $strictUrl,
|
||||
) {}
|
||||
}
|
||||
|
||||
// Verwendungsbeispiele:
|
||||
|
||||
// ✅ Gültige URLs
|
||||
$validExamples = [
|
||||
'website' => 'https://example.com',
|
||||
'secureUrl' => 'https://secure.example.com',
|
||||
'publicUrl' => 'https://public.example.com',
|
||||
'flexibleUrl' => 'example.com', // Wird zu https://example.com
|
||||
'strictUrl' => 'https://production.example.com',
|
||||
];
|
||||
|
||||
// ❌ Ungültige URLs
|
||||
$invalidExamples = [
|
||||
'website' => 'not-a-url', // Kein gültiges URL-Format
|
||||
'secureUrl' => 'http://insecure.com', // Nicht HTTPS
|
||||
'publicUrl' => 'https://localhost', // Lokale URL nicht erlaubt
|
||||
'flexibleUrl' => 'ftp://files.com', // FTP nicht HTTP/HTTPS
|
||||
'strictUrl' => 'http://localhost', // Nicht sicher UND lokal
|
||||
];
|
||||
|
||||
/**
|
||||
* Die URL Validation Rule unterstützt verschiedene Konfigurationen:
|
||||
*
|
||||
* @param bool $requireSecure - Nur HTTPS URLs erlauben
|
||||
* @param bool $allowLocal - Lokale URLs (localhost, 192.168.x.x) erlauben
|
||||
* @param bool $autoAddProtocol - Automatisch https:// hinzufügen wenn fehlt
|
||||
* @param string|null $message - Benutzerdefinierte Fehlermeldung
|
||||
*
|
||||
* Validierungsregeln des Url Value Objects:
|
||||
* - Gültiges URL-Format (parse_url() erfolgreich)
|
||||
* - Scheme und Host erforderlich
|
||||
* - Unterstützte Schemes: http, https, ftp, ftps, ssh, file, data
|
||||
* - Host max. 253 Zeichen
|
||||
* - Keine ungültigen Zeichen im Host: Leerzeichen, <, >, ", '
|
||||
* - Keine aufeinanderfolgenden Punkte im Host
|
||||
* - Host darf nicht mit Punkt oder Bindestrich beginnen/enden
|
||||
* - IP-Adressen werden validiert (filter_var FILTER_VALIDATE_IP)
|
||||
* - Ports müssen zwischen 1-65535 liegen
|
||||
* - Keine Leer-URLs (nur Schema ohne Host)
|
||||
* - Keine führenden/nachgestellten Leerzeichen
|
||||
* - Max. 2048 Zeichen Gesamtlänge
|
||||
*/
|
||||
276
backups/docs-backup-20250731125004/validation/phone-number.md
Normal file
276
backups/docs-backup-20250731125004/validation/phone-number.md
Normal file
@@ -0,0 +1,276 @@
|
||||
# PhoneNumber Value Object & Validation
|
||||
|
||||
Complete phone number handling system with Value Object pattern, validation rule, and database integration.
|
||||
|
||||
## ✅ Features Implemented
|
||||
|
||||
### PhoneNumber Value Object
|
||||
- **Type-safe Phone Numbers**: Immutable readonly class with comprehensive validation
|
||||
- **Multiple Input Formats**: Supports international, national, and formatted inputs
|
||||
- **Smart Normalization**: Automatic cleaning and formatting of phone number strings
|
||||
- **Country Code Detection**: Automatic extraction of country codes from international numbers
|
||||
- **Mobile Detection**: Heuristic detection of mobile vs. landline numbers
|
||||
- **Multiple Output Formats**: E.164, International, and National formatting
|
||||
|
||||
### Phone Validation Rule
|
||||
- **Attribute-based Validation**: `#[Phone]` attribute for automatic validation
|
||||
- **Framework Integration**: Works with existing validation system
|
||||
- **Flexible Validation**: Allows empty values (use with `#[Required]` if needed)
|
||||
- **Custom Messages**: Customizable error messages
|
||||
- **Type Safety**: Validates input types and formats
|
||||
|
||||
### Database Integration
|
||||
- **TypeCaster Support**: Automatic conversion between database strings and PhoneNumber objects
|
||||
- **Null Handling**: Proper handling of null and empty values
|
||||
- **Round-trip Conversion**: Preserves formatting through database operations
|
||||
- **Type Safety**: Ensures only valid PhoneNumber instances are stored
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Basic Value Object Usage
|
||||
```php
|
||||
use App\Domain\Common\ValueObject\PhoneNumber;
|
||||
|
||||
// Create from various formats
|
||||
$phone1 = PhoneNumber::from('+49 123 456789');
|
||||
$phone2 = PhoneNumber::parse('+49-123-456-789'); // Normalizes formatting
|
||||
$phone3 = PhoneNumber::from('0123 456789'); // National format
|
||||
|
||||
// Validation
|
||||
$isValid = PhoneNumber::isValid('+49 123 456789'); // true
|
||||
$isValid = PhoneNumber::isValid('abc'); // false
|
||||
|
||||
// Information extraction
|
||||
$countryCode = $phone1->getCountryCode(); // '49'
|
||||
$national = $phone1->getNationalNumber(); // ' 123 456789'
|
||||
$isMobile = $phone1->isMobile(); // false (German landline)
|
||||
|
||||
// Formatting
|
||||
$e164 = $phone1->toE164(); // '+49123456789'
|
||||
$international = $phone1->toInternational(); // '+49 123 456 789'
|
||||
$national = $phone1->toNational(); // '0123 456 789'
|
||||
|
||||
// Comparison
|
||||
$phone4 = PhoneNumber::from('+49-123-456-789');
|
||||
$isEqual = $phone1->equals($phone4); // true (same number)
|
||||
$sameCountry = $phone1->isSameCountry($phone4); // true
|
||||
```
|
||||
|
||||
### Validation Rule Usage
|
||||
```php
|
||||
use App\Framework\Validation\Rules\Phone;
|
||||
use App\Framework\Validation\Rules\Required;
|
||||
|
||||
class CustomerRequest
|
||||
{
|
||||
#[Required]
|
||||
#[Phone('Please enter a valid phone number.')]
|
||||
public ?string $phone = null;
|
||||
|
||||
#[Phone] // Optional phone field
|
||||
public ?string $mobile = null;
|
||||
}
|
||||
|
||||
// Usage in validation
|
||||
$validator = new Validator();
|
||||
$request = new CustomerRequest();
|
||||
$request->phone = '+49 123 456789'; // Valid
|
||||
$request->mobile = 'invalid'; // Invalid
|
||||
|
||||
$errors = $validator->validate($request);
|
||||
// Returns validation errors for invalid phone numbers
|
||||
```
|
||||
|
||||
### Database Integration
|
||||
```php
|
||||
use App\Framework\Database\Attributes\Column;
|
||||
use App\Domain\Common\ValueObject\PhoneNumber;
|
||||
|
||||
class Customer
|
||||
{
|
||||
#[Column(type: PhoneNumber::class)]
|
||||
public ?PhoneNumber $phone = null;
|
||||
}
|
||||
|
||||
// Entity usage
|
||||
$customer = new Customer();
|
||||
$customer->phone = PhoneNumber::from('+49 123 456789');
|
||||
|
||||
// EntityManager automatically handles conversion
|
||||
$entityManager->save($customer); // Stores as string: "+49 123 456789"
|
||||
$loaded = $entityManager->find(Customer::class, $id);
|
||||
// $loaded->phone is automatically converted back to PhoneNumber object
|
||||
```
|
||||
|
||||
## Supported Phone Number Formats
|
||||
|
||||
### International Formats
|
||||
```php
|
||||
PhoneNumber::from('+49 123 456789'); // German
|
||||
PhoneNumber::from('+1 (555) 123-4567'); // US with formatting
|
||||
PhoneNumber::from('+33 1 23 45 67 89'); // French
|
||||
PhoneNumber::from('+44 20 7946 0958'); // UK London
|
||||
```
|
||||
|
||||
### National Formats
|
||||
```php
|
||||
PhoneNumber::from('0123 456789'); // German national
|
||||
PhoneNumber::from('(555) 123-4567'); // US national
|
||||
PhoneNumber::from('030 12345678'); // German Berlin
|
||||
```
|
||||
|
||||
### Flexible Input Processing
|
||||
```php
|
||||
// All of these create equivalent PhoneNumber objects:
|
||||
$formats = [
|
||||
'+49 123 456789',
|
||||
'+49-123-456-789',
|
||||
'+49.123.456.789',
|
||||
'+49 (123) 456-789',
|
||||
'+49 123 456 789', // Multiple spaces
|
||||
];
|
||||
|
||||
foreach ($formats as $format) {
|
||||
$phone = PhoneNumber::parse($format);
|
||||
echo $phone->toE164(); // Always: '+49123456789'
|
||||
}
|
||||
```
|
||||
|
||||
## Country-Specific Features
|
||||
|
||||
### German Phone Numbers
|
||||
```php
|
||||
$landline = PhoneNumber::from('+49 30 12345678'); // Berlin landline
|
||||
$mobile = PhoneNumber::from('+49 151 12345678'); // Mobile (15x prefix)
|
||||
|
||||
echo $landline->isMobile(); // false
|
||||
echo $mobile->isMobile(); // true
|
||||
|
||||
echo $landline->toNational(); // '030 123 456 78'
|
||||
echo $mobile->toNational(); // '0151 123 456 78'
|
||||
```
|
||||
|
||||
### US Phone Numbers
|
||||
```php
|
||||
$usPhone = PhoneNumber::from('+1 555 123 4567');
|
||||
|
||||
echo $usPhone->getCountryCode(); // '1'
|
||||
echo $usPhone->isMobile(); // true (heuristic: 10 digits)
|
||||
echo $usPhone->toInternational(); // '+1 (555) 123-4567'
|
||||
echo $usPhone->toNational(); // '(555) 123-4567'
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Validation Errors
|
||||
```php
|
||||
try {
|
||||
$phone = PhoneNumber::from('');
|
||||
} catch (InvalidArgumentException $e) {
|
||||
echo $e->getMessage(); // "Phone number cannot be empty."
|
||||
}
|
||||
|
||||
try {
|
||||
$phone = PhoneNumber::from('123');
|
||||
} catch (InvalidArgumentException $e) {
|
||||
echo $e->getMessage(); // "Phone number too short: 123"
|
||||
}
|
||||
|
||||
try {
|
||||
$phone = PhoneNumber::from('not-a-phone');
|
||||
} catch (InvalidArgumentException $e) {
|
||||
echo $e->getMessage(); // "Phone number must contain digits: not-a-phone"
|
||||
}
|
||||
```
|
||||
|
||||
### Safe Validation
|
||||
```php
|
||||
// Non-throwing validation
|
||||
$isValid = PhoneNumber::isValid('+49 123 456789'); // true
|
||||
$isValid = PhoneNumber::isValid('invalid'); // false
|
||||
|
||||
// Use in validation logic
|
||||
if (PhoneNumber::isValid($userInput)) {
|
||||
$phone = PhoneNumber::from($userInput);
|
||||
// Process valid phone number
|
||||
} else {
|
||||
// Handle invalid input
|
||||
}
|
||||
```
|
||||
|
||||
## Testing Coverage
|
||||
|
||||
### Comprehensive Test Suite
|
||||
- **19 test cases** covering all PhoneNumber functionality
|
||||
- **10 test cases** for TypeCaster database integration
|
||||
- **8 test cases** for Phone validation rule
|
||||
- **Edge cases**: Empty values, format variations, error conditions
|
||||
- **Real-world scenarios**: International numbers, mobile detection, formatting
|
||||
|
||||
### Test Examples
|
||||
```php
|
||||
// All tests pass with comprehensive assertions
|
||||
describe('PhoneNumber Value Object', function () {
|
||||
it('handles various input formats', function () {
|
||||
$formats = [
|
||||
'+49 123 456789',
|
||||
'+49-123-456-789',
|
||||
'+49.123.456.789',
|
||||
'0123 456789',
|
||||
];
|
||||
|
||||
foreach ($formats as $format) {
|
||||
$phone = PhoneNumber::parse($format);
|
||||
expect($phone)->toBeInstanceOf(PhoneNumber::class);
|
||||
}
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Integration with Existing Systems
|
||||
|
||||
### Migration from String Phone Fields
|
||||
```php
|
||||
// Before: Simple string validation
|
||||
class CustomerRequest {
|
||||
public ?string $phone = null;
|
||||
}
|
||||
|
||||
// After: Type-safe PhoneNumber with comprehensive validation
|
||||
class CustomerRequest {
|
||||
#[Phone]
|
||||
public ?string $phone = null; // Still string for form input
|
||||
}
|
||||
|
||||
// Entity level: Convert to Value Object
|
||||
class Customer {
|
||||
#[Column(type: PhoneNumber::class)]
|
||||
public ?PhoneNumber $phone = null; // Type-safe storage
|
||||
}
|
||||
```
|
||||
|
||||
### Backward Compatibility
|
||||
```php
|
||||
// Existing code continues to work
|
||||
$phoneString = '+49 123 456789';
|
||||
|
||||
// New type-safe approach
|
||||
$phoneObject = PhoneNumber::from($phoneString);
|
||||
$backToString = (string) $phoneObject; // '+49 123 456789'
|
||||
```
|
||||
|
||||
## Performance & Best Practices
|
||||
|
||||
### Efficient Usage
|
||||
- **Normalization**: Parse method handles formatting variations efficiently
|
||||
- **Validation**: Use `isValid()` for non-throwing validation in user input
|
||||
- **Comparison**: Use `equals()` method for accurate phone number comparison
|
||||
- **Formatting**: Choose appropriate format method for display context
|
||||
|
||||
### Framework Integration
|
||||
- **Validation**: Combine with `#[Required]` for mandatory fields
|
||||
- **Database**: TypeCaster handles conversion automatically
|
||||
- **Forms**: Accept string input, validate with `#[Phone]`, convert to object in entity
|
||||
- **APIs**: Format output with appropriate method (`toE164()` for APIs, `toInternational()` for display)
|
||||
|
||||
The PhoneNumber implementation provides a complete solution for phone number handling in the framework, ensuring type safety, validation, and proper formatting throughout the application.
|
||||
Reference in New Issue
Block a user