Protokoll #16877

ID16877
Zeitstempel2025-12-25 20:12:40.306772
Clientroot
IP145.224.72.140
Modellclaude-sonnet-4-20250514
Statuscompleted
Tokens1,959 (Input: 39, Output: 1,920)
Dauer101 ms
Request-Zeit2025-12-25 20:12:40.306772
Response-Zeit2025-12-25 20:12:40.407508

Request

{
    "event": "PreToolUse",
    "tool_name": "Read",
    "tool_input": {
        "file_path": "\/var\/www\/dev.campus.systemische-tools.de\/src\/Infrastructure\/Audit\/AuditService.php"
    }
}

Response

{
    "tool_response": {
        "type": "text",
        "file": {
            "filePath": "\/var\/www\/dev.campus.systemische-tools.de\/src\/Infrastructure\/Audit\/AuditService.php",
            "content": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Infrastructure\\Audit;\n\n\/\/ @responsibility: Zentrales Audit-Logging für kritische Operationen\n\nuse PDO;\n\n\/**\n * Audit service for logging critical operations.\n *\n * Logs to ki_dev.audit_log table with structured data for:\n * - Ontology\/Taxonomy changes\n * - Entity merges\n * - DSGVO deletions\n * - Schema migrations\n * - Pipeline configuration changes\n *\/\nfinal class AuditService\n{\n    private const TABLE = 'ki_dev.audit_log';\n\n    \/**\n     * @param PDO $pdo Database connection to ki_dev\n     *\/\n    public function __construct(private PDO $pdo)\n    {\n    }\n\n    \/**\n     * Log an audit event.\n     *\n     * @param string               $event       Event name (e.g., 'entity.merge', 'ontology.update')\n     * @param string               $targetTable Target table name (e.g., 'entities', 'ontology_classes')\n     * @param int|null             $targetId    Target entity\/record ID\n     * @param array<string, mixed> $oldValue    Previous state (will be JSON encoded)\n     * @param array<string, mixed> $newValue    New state (will be JSON encoded)\n     * @param string|null          $reason      Optional reason for the change\n     * @param string               $actor       Who performed the action (username or 'system')\n     * @param string               $actorType   Actor type: 'user', 'system', 'pipeline'\n     * @param string               $level       Log level: 'debug', 'info', 'warning', 'error'\n     *\/\n    public function log(\n        string $event,\n        string $targetTable,\n        ?int $targetId = null,\n        array $oldValue = [],\n        array $newValue = [],\n        ?string $reason = null,\n        string $actor = 'system',\n        string $actorType = 'system',\n        string $level = 'info'\n    ): void {\n        $correlationId = $this->getCorrelationId();\n\n        $stmt = $this->pdo->prepare(\n            'INSERT INTO ' . self::TABLE . '\n            (correlation_id, event, entity_type, entity_id, context, level,\n             actor, actor_type, target_table, target_id, old_value, new_value, reason,\n             ip_address, created_at)\n            VALUES\n            (:correlation_id, :event, :entity_type, :entity_id, :context, :level,\n             :actor, :actor_type, :target_table, :target_id, :old_value, :new_value, :reason,\n             :ip_address, NOW())'\n        );\n\n        $stmt->execute([\n            'correlation_id' => $correlationId,\n            'event' => $event,\n            'entity_type' => $targetTable,\n            'entity_id' => $targetId,\n            'context' => json_encode(['target_table' => $targetTable, 'target_id' => $targetId]),\n            'level' => $level,\n            'actor' => $actor,\n            'actor_type' => $actorType,\n            'target_table' => $targetTable,\n            'target_id' => $targetId,\n            'old_value' => $oldValue !== [] ? json_encode($oldValue) : null,\n            'new_value' => $newValue !== [] ? json_encode($newValue) : null,\n            'reason' => $reason,\n            'ip_address' => $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1',\n        ]);\n    }\n\n    \/**\n     * Log an entity creation.\n     *\n     * @param string               $table    Table name\n     * @param int                  $id       Created entity ID\n     * @param array<string, mixed> $data     Created data\n     * @param string               $actor    Who created it\n     * @param string               $actorType Actor type\n     *\/\n    public function logCreate(\n        string $table,\n        int $id,\n        array $data,\n        string $actor = 'system',\n        string $actorType = 'system'\n    ): void {\n        $this->log(\n            event: $table . '.create',\n            targetTable: $table,\n            targetId: $id,\n            newValue: $data,\n            actor: $actor,\n            actorType: $actorType\n        );\n    }\n\n    \/**\n     * Log an entity update.\n     *\n     * @param string               $table    Table name\n     * @param int                  $id       Updated entity ID\n     * @param array<string, mixed> $oldData  Previous state\n     * @param array<string, mixed> $newData  New state\n     * @param string               $actor    Who updated it\n     * @param string               $actorType Actor type\n     *\/\n    public function logUpdate(\n        string $table,\n        int $id,\n        array $oldData,\n        array $newData,\n        string $actor = 'system',\n        string $actorType = 'system'\n    ): void {\n        $this->log(\n            event: $table . '.update',\n            targetTable: $table,\n            targetId: $id,\n            oldValue: $oldData,\n            newValue: $newData,\n            actor: $actor,\n            actorType: $actorType\n        );\n    }\n\n    \/**\n     * Log an entity deletion.\n     *\n     * @param string               $table    Table name\n     * @param int                  $id       Deleted entity ID\n     * @param array<string, mixed> $data     Deleted data (for recovery)\n     * @param string|null          $reason   Reason for deletion (e.g., 'DSGVO request')\n     * @param string               $actor    Who deleted it\n     * @param string               $actorType Actor type\n     *\/\n    public function logDelete(\n        string $table,\n        int $id,\n        array $data,\n        ?string $reason = null,\n        string $actor = 'system',\n        string $actorType = 'system'\n    ): void {\n        $this->log(\n            event: $table . '.delete',\n            targetTable: $table,\n            targetId: $id,\n            oldValue: $data,\n            reason: $reason,\n            actor: $actor,\n            actorType: $actorType,\n            level: 'warning'\n        );\n    }\n\n    \/**\n     * Log an entity merge operation.\n     *\n     * @param int                  $sourceId   Source entity ID (merged into target)\n     * @param int                  $targetId   Target entity ID (kept)\n     * @param array<string, mixed> $sourceData Source entity data\n     * @param array<string, mixed> $targetData Target entity data after merge\n     * @param string               $actor      Who performed the merge\n     *\/\n    public function logMerge(\n        int $sourceId,\n        int $targetId,\n        array $sourceData,\n        array $targetData,\n        string $actor = 'system'\n    ): void {\n        $this->log(\n            event: 'entity.merge',\n            targetTable: 'entities',\n            targetId: $targetId,\n            oldValue: ['source_id' => $sourceId, 'source_data' => $sourceData],\n            newValue: ['target_id' => $targetId, 'merged_data' => $targetData],\n            reason: \"Merged entity #{$sourceId} into #{$targetId}\",\n            actor: $actor,\n            actorType: 'user',\n            level: 'warning'\n        );\n    }\n\n    \/**\n     * Get or generate correlation ID for request tracing.\n     *\/\n    private function getCorrelationId(): string\n    {\n        \/\/ Check for existing correlation ID from middleware\n        if (isset($_SERVER['HTTP_X_CORRELATION_ID'])) {\n            return $_SERVER['HTTP_X_CORRELATION_ID'];\n        }\n\n        \/\/ Check session\n        if (isset($_SESSION['correlation_id'])) {\n            return $_SESSION['correlation_id'];\n        }\n\n        \/\/ Generate new one\n        return bin2hex(random_bytes(16));\n    }\n}\n",
            "numLines": 220,
            "startLine": 1,
            "totalLines": 220
        }
    }
}
← Vorheriger Zur Liste Nächster →