Files
michaelschiemer/docs/livecomponents/livecomponents-implementation-plan.md
Michael Schiemer 36ef2a1e2c
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
fix: Gitea Traefik routing and connection pool optimization
- Remove middleware reference from Gitea Traefik labels (caused routing issues)
- Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s)
- Add explicit service reference in Traefik labels
- Fix intermittent 504 timeouts by improving PostgreSQL connection handling

Fixes Gitea unreachability via git.michaelschiemer.de
2025-11-09 14:46:15 +01:00

700 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# LiveComponents Implementation Plan
**Datum**: 2025-10-07
**Status**: Draft für Review
## Executive Summary
Dieser Plan strukturiert die vorgeschlagenen Verbesserungen für das LiveComponents-Modul in umsetzbare Phasen mit klaren Prioritäten basierend auf Impact, Aufwand und Framework-Compliance.
---
## Priorisierungs-Matrix
### Scoring-System
- **Impact**: 1-5 (1=niedrig, 5=kritisch)
- **Effort**: 1-5 (1=wenige Stunden, 5=mehrere Wochen)
- **Framework Compliance**: 1-5 (1=neutral, 5=essentiell für Framework-Patterns)
- **Priority Score**: (Impact × 2 + Framework Compliance - Effort) / 3
---
## Phase 1: Critical Foundation (P0 - MUST HAVE)
### 1.1 State-Validierung & Serialization
**Impact**: 5 | **Effort**: 2 | **Framework Compliance**: 5 | **Priority**: 6.0
**Problem**:
- Kein Schema/Validierung für State
- Serialization-Fehler bei komplexen Objekten
- Sicherheitsrisiken durch unvalidierte State-Änderungen
**Lösung**:
```php
// State Schema Interface
interface StateSchema
{
public function validate(array $state): ValidationResult;
public function sanitize(array $state): array;
public function getSerializableFields(): array;
}
// Component mit Schema
final readonly class TodoListComponent implements LiveComponentContract
{
public function getStateSchema(): StateSchema
{
return new TodoListStateSchema([
'todos' => 'array<TodoItem>',
'filter' => 'enum:all|active|completed',
'page' => 'int:min=1'
]);
}
}
```
**Files to Create**:
- `src/Framework/LiveComponents/Contracts/StateSchema.php`
- `src/Framework/LiveComponents/StateValidation/StateValidator.php`
- `src/Framework/LiveComponents/StateValidation/ValidationResult.php`
- `src/Framework/LiveComponents/StateValidation/Sanitizer.php`
**Framework Pattern**: Value Objects für State, Validation mit expliziten Contracts
---
### 1.2 CSRF-Integration
**Impact**: 5 | **Effort**: 1 | **Framework Compliance**: 4 | **Priority**: 5.7
**Problem**:
- Keine CSRF-Protection für Component-Actions
- Security Gap
**Lösung**:
```php
// In LiveComponentHandler
public function handle(
LiveComponentContract $component,
string $method,
ActionParameters $params
): ComponentUpdate {
// CSRF-Check vor Action-Ausführung
if (!$this->csrfValidator->validate($params->getCsrfToken())) {
throw new CsrfTokenMismatchException();
}
// ... existing code
}
```
**Files to Modify**:
- `src/Framework/LiveComponents/LiveComponentHandler.php` (add CSRF check)
- `src/Framework/LiveComponents/ValueObjects/ActionParameters.php` (add csrfToken field)
- `resources/js/modules/livecomponent/index.js` (auto-include CSRF token)
**Framework Pattern**: Integration mit bestehendem CsrfMiddleware
---
### 1.3 Action Guards & Permissions
**Impact**: 5 | **Effort**: 2 | **Framework Compliance**: 4 | **Priority**: 5.3
**Problem**:
- Keine Permission-Checks auf Actions
- Jeder kann jede Action aufrufen
**Lösung**:
```php
#[Attribute(Attribute::TARGET_METHOD)]
final readonly class RequiresPermission
{
public function __construct(
public string $permission
) {}
}
// Usage
#[RequiresPermission('posts.delete')]
public function deletePost(string $postId): ComponentData
{
// Only executed if user has permission
}
```
**Files to Create**:
- `src/Framework/LiveComponents/Attributes/RequiresPermission.php`
- `src/Framework/LiveComponents/Security/ActionAuthorizationChecker.php`
**Framework Pattern**: Attribute-basierte Authorization wie bei Routes
---
### 1.4 Starke Fehlermeldungen
**Impact**: 4 | **Effort**: 2 | **Framework Compliance**: 4 | **Priority**: 4.0
**Problem**:
- Generische Fehlermeldungen
- Schwer zu debuggen
**Lösung**:
```php
// Custom Exceptions mit Context
final class ComponentActionNotFoundException extends FrameworkException
{
public static function forAction(string $componentName, string $action): self
{
return self::create(
ErrorCode::LIVECOMPONENT_ACTION_NOT_FOUND,
"Action '{$action}' not found on component '{$componentName}'"
)->withData([
'component' => $componentName,
'action' => $action,
'available_actions' => self::getAvailableActions($componentName),
'suggestion' => self::suggestSimilarAction($componentName, $action)
]);
}
}
```
**Files to Create**:
- `src/Framework/LiveComponents/Exceptions/ComponentActionNotFoundException.php`
- `src/Framework/LiveComponents/Exceptions/InvalidStateException.php`
- `src/Framework/LiveComponents/Exceptions/ComponentNotFoundException.php`
**Framework Pattern**: FrameworkException mit ErrorCode, ExceptionContext
---
## Phase 2: Architektur-Verbesserungen (P1 - SHOULD HAVE)
### 2.1 Lifecycle Hooks
**Impact**: 4 | **Effort**: 3 | **Framework Compliance**: 4 | **Priority**: 3.7
**Problem**:
- Keine standardisierten Lifecycle-Events
- Schwer, Initialization/Cleanup zu machen
**Lösung**:
```php
interface ComponentLifecycle
{
public function beforeMount(ComponentData $initialState): ComponentData;
public function mount(): void;
public function hydrate(ComponentData $state): ComponentData;
public function dehydrate(ComponentData $state): array;
public function beforeUpdate(ComponentData $oldState, ComponentData $newState): ComponentData;
public function updated(ComponentData $state): void;
public function beforeDestroy(): void;
}
// Trait mit Default-Implementations
trait ComponentLifecycleTrait
{
public function beforeMount(ComponentData $initialState): ComponentData
{
return $initialState;
}
// ... all hooks with empty defaults
}
```
**Files to Create**:
- `src/Framework/LiveComponents/Contracts/ComponentLifecycle.php`
- `src/Framework/LiveComponents/Traits/ComponentLifecycleTrait.php`
**Files to Modify**:
- `src/Framework/LiveComponents/LiveComponentHandler.php` (call hooks)
- `src/Framework/LiveComponents/ComponentRegistry.php` (call mount hook)
**Framework Pattern**: Contract + Trait für optionale Hooks
---
### 2.2 Middleware-Pipeline
**Impact**: 4 | **Effort**: 3 | **Framework Compliance**: 5 | **Priority**: 4.0
**Problem**:
- Cross-Cutting Concerns (Logging, Rate-Limiting) fest im Handler
- Nicht erweiterbar
**Lösung**:
```php
interface ComponentMiddleware
{
public function before(
LiveComponentContract $component,
string $method,
ActionParameters $params
): void;
public function after(
LiveComponentContract $component,
ComponentUpdate $update
): ComponentUpdate;
}
// Built-in Middlewares
final readonly class RateLimitMiddleware implements ComponentMiddleware {}
final readonly class LoggingMiddleware implements ComponentMiddleware {}
final readonly class ValidationMiddleware implements ComponentMiddleware {}
final readonly class CsrfMiddleware implements ComponentMiddleware {}
```
**Files to Create**:
- `src/Framework/LiveComponents/Middleware/ComponentMiddleware.php`
- `src/Framework/LiveComponents/Middleware/MiddlewarePipeline.php`
- `src/Framework/LiveComponents/Middleware/RateLimitMiddleware.php`
- `src/Framework/LiveComponents/Middleware/LoggingMiddleware.php`
- `src/Framework/LiveComponents/Middleware/ValidationMiddleware.php`
- `src/Framework/LiveComponents/Middleware/CsrfMiddleware.php`
**Files to Modify**:
- `src/Framework/LiveComponents/LiveComponentHandler.php` (integrate pipeline)
**Framework Pattern**: Middleware-Pattern wie bei HTTP-Requests
---
### 2.3 Partial Rendering & DOM-Diffing
**Impact**: 5 | **Effort**: 4 | **Framework Compliance**: 3 | **Priority**: 3.5
**Problem**:
- Ganzer Component wird re-rendert
- Ineffizient bei großen Components
**Lösung**:
```php
// Server-Side: Fragments
interface SupportsFragments
{
public function getFragments(): array;
public function renderFragment(string $name, ComponentData $data): string;
}
// Client-Side: DOM-Diffing
class DomPatcher {
patch(element, newHtml) {
// morphdom-ähnlicher Algorithmus
this.diffAndPatch(element, newHtml);
}
}
```
**Files to Create**:
- `src/Framework/LiveComponents/Contracts/SupportsFragments.php`
- `src/Framework/LiveComponents/Rendering/FragmentRenderer.php`
- `public/js/modules/livecomponent/dom-patcher.js`
**Files to Modify**:
- `src/Framework/View/LiveComponentRenderer.php` (fragment support)
- `resources/js/modules/livecomponent/index.js` (DOM diffing)
**Framework Pattern**: Contract für Fragment-Support
---
### 2.4 Rate-Limiting auf Action-Level
**Impact**: 4 | **Effort**: 2 | **Framework Compliance**: 4 | **Priority**: 4.0
**Problem**:
- Keine Rate-Limits auf Actions
- Potentielle DOS-Attacken
**Lösung**:
```php
#[Attribute(Attribute::TARGET_METHOD)]
final readonly class RateLimit
{
public function __construct(
public int $maxAttempts = 60,
public int $decayMinutes = 1
) {}
}
// Usage
#[RateLimit(maxAttempts: 5, decayMinutes: 1)]
public function sendMessage(string $message): ComponentData
{
// Max 5 calls per minute
}
```
**Files to Create**:
- `src/Framework/LiveComponents/Attributes/RateLimit.php`
**Files to Modify**:
- `src/Framework/LiveComponents/Middleware/RateLimitMiddleware.php` (check attribute)
**Framework Pattern**: Attribute-basierte Konfiguration wie bei Routes
---
## Phase 3: Developer Experience (P2 - NICE TO HAVE)
### 3.1 CLI-Generator
**Impact**: 3 | **Effort**: 2 | **Framework Compliance**: 3 | **Priority**: 2.7
**Problem**:
- Boilerplate-Code für neue Components
- Inkonsistente Struktur
**Lösung**:
```bash
php console.php make:livecomponent TodoList \
--pollable \
--cacheable \
--with-test \
--with-template
```
**Files to Create**:
- `src/Framework/Console/Commands/MakeLiveComponentCommand.php`
- `resources/stubs/livecomponent.stub`
- `resources/stubs/livecomponent-template.stub`
- `resources/stubs/livecomponent-test.stub`
**Framework Pattern**: ConsoleCommand mit Stub-Templates
---
### 3.2 Test-Harness
**Impact**: 3 | **Effort**: 2 | **Framework Compliance**: 4 | **Priority**: 3.0
**Problem**:
- Boilerplate für Component-Tests
- Inkonsistente Test-Setups
**Lösung**:
```php
it('increments counter', function () {
$component = $this->mountComponent(CounterComponent::class, ['count' => 5]);
$update = $this->callAction($component, 'increment');
$this->assertComponentState($update, ['count' => 6]);
$this->assertEventDispatched($update, 'counter:changed');
});
```
**Files to Create**:
- `tests/Framework/LiveComponentTestCase.php`
- `tests/Framework/Traits/LiveComponentTestHelpers.php`
**Framework Pattern**: Pest Test Helpers
---
### 3.3 Autodiscovery-Optimierung
**Impact**: 3 | **Effort**: 2 | **Framework Compliance**: 5 | **Priority**: 3.3
**Problem**:
- Discovery funktioniert, aber könnte klarer sein
- Keine Kollisionswarnungen
**Lösung**:
```php
// Fallback auf Class-Name → kebab-case wenn kein Attribute
final class TodoListComponent implements LiveComponentContract {}
// → Auto-Name: "todo-list"
// Collision Detection
if (isset($map[$name])) {
throw new ComponentNameCollisionException(
"Component name '{$name}' already registered by {$map[$name]}"
);
}
```
**Files to Modify**:
- `src/Framework/LiveComponents/ComponentRegistry.php` (fallback + collision check)
**Framework Pattern**: Convention over Configuration
---
### 3.4 Template-Konventionen dokumentieren
**Impact**: 2 | **Effort**: 1 | **Framework Compliance**: 3 | **Priority**: 2.0
**Problem**:
- Keine klaren Template-Patterns
- Inkonsistente Component-Markup
**Lösung**:
```html
<!-- Standard Component Template Structure -->
<div data-lc="component-name" data-key="{id}" class="lc-component">
<!-- Component-specific markup -->
<!-- Slot system for extensibility -->
<slot name="header"></slot>
<slot name="content">Default content</slot>
<slot name="footer"></slot>
</div>
```
**Files to Create/Modify**:
- `docs/claude/livecomponent-template-conventions.md`
- Update existing templates to follow conventions
**Framework Pattern**: Template-System Integration
---
## Phase 4: Performance & Polish (P3 - FUTURE)
### 4.1 Request-Cache/Memoization
**Impact**: 3 | **Effort**: 3 | **Framework Compliance**: 4 | **Priority**: 2.7
**Lösung**:
```php
interface Cacheable
{
public function getCacheTtl(): Duration;
public function getCacheKey(): CacheKey;
public function getCacheTags(): array;
public function varyBy(): array; // ['state.userId', 'state.filter']
}
```
**Framework Pattern**: SmartCache mit varyBy-Support
---
### 4.2 Polling-Coalescing
**Impact**: 2 | **Effort**: 3 | **Framework Compliance**: 2 | **Priority**: 1.3
**Lösung**:
```javascript
// Batch multiple poll requests
class PollCoalescer {
batchRequest(components) {
return fetch('/live-component/poll-batch', {
body: JSON.stringify({
components: components.map(c => c.id)
})
});
}
}
```
---
### 4.3 Debounce/Throttle im Protokoll
**Impact**: 3 | **Effort**: 2 | **Framework Compliance**: 2 | **Priority**: 2.3
**Lösung**:
```html
<input
data-live-action="search"
data-debounce="300"
data-throttle="1000"
/>
```
---
### 4.4 SSE Streaming
**Impact**: 3 | **Effort**: 4 | **Framework Compliance**: 3 | **Priority**: 2.0
**Lösung**:
```php
interface StreamableComponent
{
public function streamUpdates(): Generator;
}
```
---
### 4.5 Optimistic UI
**Impact**: 2 | **Effort**: 4 | **Framework Compliance**: 2 | **Priority**: 1.0
**Lösung**:
```javascript
// Client setzt State vorläufig, Server bestätigt oder rollt zurück
await component.callAction('deleteItem', { id: 123 }, { optimistic: true });
```
---
### 4.6 Background Actions
**Impact**: 2 | **Effort**: 3 | **Framework Compliance**: 3 | **Priority**: 1.7
**Lösung**:
```php
#[Attribute(Attribute::TARGET_METHOD)]
final readonly class Background
{
public function __construct(
public bool $queueable = true,
public ?string $queue = null
) {}
}
```
---
### 4.7 Accessibility Hooks
**Impact**: 2 | **Effort**: 2 | **Framework Compliance**: 2 | **Priority**: 1.3
**Lösung**:
```html
<div
data-lc="component"
data-lc-keep-focus
data-lc-announce-updates
role="region"
aria-live="polite"
>
```
---
### 4.8 DevTools Overlay
**Impact**: 2 | **Effort**: 4 | **Framework Compliance**: 1 | **Priority**: 0.7
**Lösung**:
```javascript
// Dev-Modus Overlay mit Component-Inspector
if (ENV === 'development') {
new LiveComponentDevTools().init();
}
```
---
## Quick Wins (Immediate Implementation)
### Top 5 Quick Wins (High Impact / Low Effort)
1. **CSRF-Integration** (Impact: 5, Effort: 1, Priority: 5.7)
- 2-4 Stunden
- Sofortiger Security-Benefit
2. **Starke Fehlermeldungen** (Impact: 4, Effort: 2, Priority: 4.0)
- 1 Tag
- Massiv verbesserte DX
3. **CLI-Generator** (Impact: 3, Effort: 2, Priority: 2.7)
- 1 Tag
- Accelerates development
4. **Test-Harness** (Impact: 3, Effort: 2, Priority: 3.0)
- 1 Tag
- Better test coverage
5. **Template-Konventionen** (Impact: 2, Effort: 1, Priority: 2.0)
- 4 Stunden
- Consistency across components
---
## Implementation Roadmap
### Sprint 1 (Week 1-2): Security Foundation
- ✅ CSRF-Integration
- ✅ Action Guards & Permissions
- ✅ State-Validierung
**Deliverables**: Secure LiveComponents-System
---
### Sprint 2 (Week 3-4): Architecture Improvements
- ✅ Middleware-Pipeline
- ✅ Lifecycle Hooks
- ✅ Starke Fehlermeldungen
**Deliverables**: Extensible, Developer-Friendly System
---
### Sprint 3 (Week 5-6): Performance & DX
- ✅ Partial Rendering
- ✅ Rate-Limiting
- ✅ CLI-Generator
- ✅ Test-Harness
**Deliverables**: Production-Ready System with Developer Tools
---
### Sprint 4+ (Future): Polish & Advanced Features
- ☐ Request-Cache/Memoization
- ☐ Polling-Coalescing
- ☐ SSE Streaming
- ☐ Optimistic UI
- ☐ Background Actions
- ☐ DevTools Overlay
**Deliverables**: Enterprise-Grade LiveComponents
---
## Success Metrics
### Security
- ✅ 100% CSRF-Protection on all Actions
- ✅ Permission-Checks auf allen kritischen Actions
- ✅ State-Validierung für alle Components
### Performance
- ✅ < 50ms Action-Latency (P95)
- ✅ < 100ms Render-Time (P95)
- ✅ 80%+ Cache-Hit-Rate
### Developer Experience
- ✅ < 5 Minuten neue Component erstellen
- ✅ < 10 Minuten Component-Test schreiben
- ✅ Klare Fehlermeldungen mit Lösungsvorschlägen
### Quality
- ✅ 90%+ Test-Coverage
- ✅ 100% Framework-Pattern-Compliance
- ✅ Zero breaking changes to existing components
---
## Risk Assessment
### High Risk
- **Middleware-Pipeline**: Breaking Changes möglich
- **Mitigation**: Optional in v1, Mandatory in v2
- **Lifecycle Hooks**: Performance Impact
- **Mitigation**: Profiling, Optional Hooks
### Medium Risk
- **Partial Rendering**: Client-Side Complexity
- **Mitigation**: Progressive Enhancement, Fallback zu Full-Render
- **State-Validierung**: Performance bei großen States
- **Mitigation**: Lazy Validation, Schema-Caching
### Low Risk
- **CSRF, Permissions, CLI-Generator**: Isolierte Änderungen
---
## Next Steps
1. **Review & Approval**: Stakeholder-Review dieses Plans
2. **Prototype**: CSRF-Integration als Proof-of-Concept
3. **Sprint Planning**: Detaillierte Sprint-1-Tasks
4. **Implementation**: Start mit Quick Wins
---
## Appendix: Framework-Compliance Checklist
Alle Implementations müssen folgen:
- ✅ Readonly Classes wo möglich
- ✅ Value Objects statt Primitives
- ✅ Composition over Inheritance
- ✅ Attribute-basierte Discovery
- ✅ Explicit Dependency Injection
- ✅ FrameworkException für Fehler
- ✅ Contracts statt Abstraction
- ✅ Pest Tests