Backup #344

ID344
Dateipfad/var/www/dev.campus.systemische-tools.de/src/Controller/ProtokollController.php
Version7
Typ modified
Größe5.1 KB
Hash8a41d43f2ba57ca83de686a477c2dae3b1b36351d56d6582a92a472e2486e4b3
Datum2025-12-22 08:12:13
Geändert vonclaude-code-hook
GrundClaude Code Pre-Hook Backup vor Edit-Operation
Datei existiert Ja

Dateiinhalt

<?php

namespace Controller;

use Domain\ValueObject\Pagination;
use Framework\Controller;
use Infrastructure\Config\DatabaseFactory;

/**
 * ProtokollController - KI-Protokoll Ansicht
 *
 * Zeigt KI-Interaktionen aus ki_dev.protokoll.
 * Nur Lesen, kein Erstellen/Bearbeiten.
 */
class ProtokollController extends Controller
{
    private \PDO $db;

    public function __construct()
    {
        $this->db = DatabaseFactory::dev();
    }

    /**
     * GET /protokoll
     * Liste aller Protokoll-Einträge
     */
    public function index(): void
    {
        // Statistiken
        $stats = $this->db->query(
            'SELECT
                COUNT(*) as total,
                SUM(CASE WHEN status = "completed" THEN 1 ELSE 0 END) as completed,
                SUM(CASE WHEN status = "error" THEN 1 ELSE 0 END) as errors,
                COALESCE(SUM(tokens_total), 0) as tokens_total,
                COALESCE(SUM(duration_ms), 0) as duration_total
             FROM protokoll'
        )->fetch();

        // Einträge mit Pagination
        $page = $this->getPage();
        $limit = 50;
        $offset = ($page - 1) * $limit;

        $search = $this->getString('search');
        $status = $this->getString('status');
        $model = $this->getString('model');

        $sql = 'SELECT id, timestamp, client_name, model_name, status, tokens_total, duration_ms,
                       LEFT(request, 200) as request_preview
                FROM protokoll WHERE 1=1';
        $countSql = 'SELECT COUNT(*) FROM protokoll WHERE 1=1';
        $params = [];

        if ($search !== '') {
            $sql .= ' AND (request LIKE :search OR response LIKE :search2 OR client_name LIKE :search3)';
            $countSql .= ' AND (request LIKE :search OR response LIKE :search2 OR client_name LIKE :search3)';
            $params['search'] = '%' . $search . '%';
            $params['search2'] = '%' . $search . '%';
            $params['search3'] = '%' . $search . '%';
        }

        if ($status !== '') {
            $sql .= ' AND status = :status';
            $countSql .= ' AND status = :status';
            $params['status'] = $status;
        }

        if ($model !== '') {
            $sql .= ' AND model_name = :model';
            $countSql .= ' AND model_name = :model';
            $params['model'] = $model;
        }

        // Total count
        $countStmt = $this->db->prepare($countSql);
        $countStmt->execute($params);
        $totalCount = (int) $countStmt->fetchColumn();

        // Fetch entries
        $sql .= ' ORDER BY timestamp DESC LIMIT :limit OFFSET :offset';
        $stmt = $this->db->prepare($sql);
        foreach ($params as $key => $value) {
            $stmt->bindValue(':' . $key, $value);
        }
        $stmt->bindValue(':limit', $limit, \PDO::PARAM_INT);
        $stmt->bindValue(':offset', $offset, \PDO::PARAM_INT);
        $stmt->execute();
        $entries = $stmt->fetchAll();

        // Modelle für Filter
        $models = $this->db->query(
            'SELECT DISTINCT model_name FROM protokoll WHERE model_name IS NOT NULL ORDER BY model_name'
        )->fetchAll(\PDO::FETCH_COLUMN);

        $this->view('protokoll.index', [
            'title' => 'KI-Protokoll',
            'stats' => $stats,
            'entries' => $entries,
            'models' => $models,
            'currentSearch' => $search,
            'currentStatus' => $status,
            'currentModel' => $model,
            'currentPage' => $page,
            'totalCount' => $totalCount,
            'totalPages' => ceil($totalCount / $limit),
        ]);
    }

    /**
     * GET /protokoll/{id}
     * Detail-Ansicht eines Eintrags
     */
    public function show(string $id): void
    {
        $stmt = $this->db->prepare('SELECT * FROM protokoll WHERE id = :id');
        $stmt->execute(['id' => (int) $id]);
        $entry = $stmt->fetch();

        if ($entry === false) {
            $this->notFound('Protokoll-Eintrag nicht gefunden');
        }

        // Request/Response als formatiertes JSON
        $entry['request_formatted'] = $this->formatJson($entry['request']);
        $entry['response_formatted'] = $this->formatJson($entry['response']);

        // Nachbar-Einträge für Navigation
        $stmt = $this->db->prepare('SELECT id FROM protokoll WHERE id < :id ORDER BY id DESC LIMIT 1');
        $stmt->execute(['id' => (int) $id]);
        $prevEntry = $stmt->fetch();

        $stmt = $this->db->prepare('SELECT id FROM protokoll WHERE id > :id ORDER BY id ASC LIMIT 1');
        $stmt->execute(['id' => (int) $id]);
        $nextEntry = $stmt->fetch();

        $this->view('protokoll.show', [
            'title' => 'Protokoll #' . $id,
            'entry' => $entry,
            'prevEntry' => $prevEntry,
            'nextEntry' => $nextEntry,
        ]);
    }

    /**
     * JSON formatieren für Anzeige
     */
    private function formatJson(?string $json): string
    {
        if ($json === null || $json === '') {
            return '-';
        }

        $decoded = json_decode($json, true);
        if ($decoded === null) {
            return htmlspecialchars($json);
        }

        return json_encode($decoded, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
    }
}

Vollständig herunterladen

Aktionen

Herunterladen

Andere Versionen dieser Datei

ID Version Typ Größe Datum
699 15 modified 2.1 KB 2025-12-23 07:53
643 14 modified 2.1 KB 2025-12-23 04:47
469 13 modified 2.1 KB 2025-12-22 10:32
468 12 modified 2.1 KB 2025-12-22 10:32
453 11 modified 2.9 KB 2025-12-22 10:27
448 10 modified 5.3 KB 2025-12-22 10:19
407 9 modified 5.2 KB 2025-12-22 08:55
345 8 modified 5.1 KB 2025-12-22 08:12
344 7 modified 5.1 KB 2025-12-22 08:12
343 6 modified 5.1 KB 2025-12-22 08:12
306 5 modified 5.1 KB 2025-12-22 08:05
246 4 modified 5.2 KB 2025-12-22 01:46
135 3 modified 4.9 KB 2025-12-20 19:56
34 2 modified 5.7 KB 2025-12-20 17:23
3 1 modified 5.7 KB 2025-12-20 16:08

← Zurück zur Übersicht