{
"tool_response": [
{
"type": "text",
"text": "{\n \"success\": true,\n \"task\": {\n \"id\": 438,\n \"uuid\": \"06f7aa5c-f26a-4e4d-9737-ea93726682cd\",\n \"title\": \"HTMX: tasks\/index.php - Inline Status-Änderung\",\n \"description\": \"# HTMX-Implementation: tasks\/index.php\\n\\n## Ziel\\nStatus-Badge klickbar machen für Inline-Status-Änderung ohne Page-Reload.\\n\\n---\\n\\n## Betroffene Datei\\n`\/var\/www\/dev.campus.systemische-tools.de\/src\/View\/tasks\/index.php`\\n\\n---\\n\\n## Aktuelle Implementierung (Zeile 64)\\n\\n```php\\n<td><span class=\\\"badge badge--<?= $task['status'] ?>\\\"><?= $task['status'] ?><\/span><\/td>\\n```\\n\\n**Problem:** Statisches Badge, Status-Änderung nur über Detail-Seite möglich.\\n\\n---\\n\\n## Ziel-Implementierung\\n\\n### Status-Badge als Dropdown mit HTMX\\n\\n```php\\n<td>\\n <select class=\\\"badge-select badge-select--<?= $task['status'] ?>\\\"\\n hx-patch=\\\"\/tasks\/<?= $task['id'] ?>\/status\\\"\\n hx-headers='{\\\"X-CSRF-TOKEN\\\": \\\"<?= $csrfToken ?>\\\"}'\\n hx-target=\\\"closest td\\\"\\n hx-swap=\\\"innerHTML\\\"\\n hx-indicator=\\\"closest td\\\">\\n <option value=\\\"pending\\\" <?= $task['status'] === 'pending' ? 'selected' : '' ?>>pending<\/option>\\n <option value=\\\"in_progress\\\" <?= $task['status'] === 'in_progress' ? 'selected' : '' ?>>in_progress<\/option>\\n <option value=\\\"completed\\\" <?= $task['status'] === 'completed' ? 'selected' : '' ?>>completed<\/option>\\n <option value=\\\"failed\\\" <?= $task['status'] === 'failed' ? 'selected' : '' ?>>failed<\/option>\\n <option value=\\\"cancelled\\\" <?= $task['status'] === 'cancelled' ? 'selected' : '' ?>>cancelled<\/option>\\n <\/select>\\n<\/td>\\n```\\n\\n### Alternativ: Badge mit Click-Cycle\\n\\n```php\\n<td>\\n <button class=\\\"badge badge--<?= $task['status'] ?>\\\"\\n hx-patch=\\\"\/tasks\/<?= $task['id'] ?>\/status-next\\\"\\n hx-headers='{\\\"X-CSRF-TOKEN\\\": \\\"<?= $csrfToken ?>\\\"}'\\n hx-target=\\\"closest td\\\"\\n hx-swap=\\\"innerHTML\\\"\\n title=\\\"Klicken für nächsten Status\\\">\\n <?= $task['status'] ?>\\n <\/button>\\n<\/td>\\n```\\n\\n---\\n\\n## Erforderliche Backend-Änderungen\\n\\n### Neuer Endpoint: TasksController::patchStatus()\\n\\n```php\\npublic function patchStatus(string $id): void\\n{\\n $this->requireCsrf();\\n \\n $newStatus = $_POST['status'] ?? $_GET['status'] ?? null;\\n \\n if (!$newStatus) {\\n http_response_code(400);\\n return;\\n }\\n \\n $result = $this->tasksUseCase->updateStatus((int) $id, $newStatus);\\n \\n if ($this->isHtmxRequest()) {\\n \/\/ Partial HTML zurückgeben (neues Badge\/Select)\\n $task = $this->tasksUseCase->getById((int) $id);\\n $this->partial('tasks.partials.status-cell', ['task' => $task->toArray()]);\\n return;\\n }\\n \\n $this->redirect('\/tasks\/' . $id);\\n}\\n```\\n\\n### Neues Partial: `tasks\/partials\/status-cell.php`\\n\\n```php\\n<select class=\\\"badge-select badge-select--<?= $task['status'] ?>\\\"\\n hx-patch=\\\"\/tasks\/<?= $task['id'] ?>\/status\\\"\\n hx-headers='{\\\"X-CSRF-TOKEN\\\": \\\"<?= $csrfToken ?>\\\"}'\\n hx-target=\\\"closest td\\\"\\n hx-swap=\\\"innerHTML\\\">\\n <!-- options -->\\n<\/select>\\n```\\n\\n### Route hinzufügen\\n\\n```php\\n$router->patch('\/tasks\/{id}\/status', [TasksController::class, 'patchStatus']);\\n```\\n\\n---\\n\\n## Contract-Compliance (htmx-patterns-contract v1.0)\\n\\n- ✅ `csrf-on-patch`: hx-headers mit X-CSRF-TOKEN\\n- ✅ `use-hx-indicator`: Loading-Feedback\\n- ⚠️ `no-fetch-for-simple-post`: Nicht relevant (kein fetch)\\n\\n---\\n\\n## CSS-Ergänzung\\n\\n```css\\n.badge-select {\\n appearance: none;\\n border: none;\\n padding: 0.25rem 0.5rem;\\n border-radius: 4px;\\n cursor: pointer;\\n font-size: 0.75rem;\\n}\\n.badge-select--pending { background: #fbbf24; }\\n.badge-select--in_progress { background: #3b82f6; color: white; }\\n.badge-select--completed { background: #10b981; color: white; }\\n.badge-select--failed { background: #ef4444; color: white; }\\n.badge-select--cancelled { background: #6b7280; color: white; }\\n```\\n\\n---\\n\\n## Testplan\\n\\n1. [ ] Status-Dropdown in Tabelle sichtbar\\n2. [ ] Status ändern → Inline-Update ohne Reload\\n3. [ ] Korrekter Status in DB gespeichert\\n4. [ ] Loading-Indicator während Request\\n5. [ ] CSRF-Fehler → 403\\n6. [ ] Contract validieren: `contracts_validate(\\\"htmx-patterns-contract\\\")`\\n\\n---\\n\\n## Aufwand\\n- View: ~15 Minuten\\n- Controller: ~15 Minuten\\n- Partial: ~5 Minuten\\n- CSS: ~5 Minuten\\n- **Gesamt: ~40 Minuten**\",\n \"type\": \"ai_task\",\n \"status\": \"pending\",\n \"created_by\": \"mcp-tasks\",\n \"created_by_type\": \"ai\",\n \"parent_task_id\": null,\n \"due_date\": null,\n \"created_at\": \"2025-12-27T11:34:07.850646\",\n \"updated_at\": \"2025-12-27T11:34:07.850649\",\n \"completed_at\": null,\n \"metadata\": {}\n },\n \"assignments\": [],\n \"results\": []\n}"
}
]
}