Backup #128

ID128
Dateipfad/var/www/dev.campus.systemische-tools.de/src/Infrastructure/Persistence/ContractRepository.php
Version3
Typ modified
Größe8.8 KB
Hashed0dc76532fc2e5a194e0f764514c4d2c20743b17cfee7e0decd8fcc58fe60d6
Datum2025-12-20 19:40:44
Geändert vonclaude-code-hook
GrundClaude Code Pre-Hook Backup vor Edit-Operation
Datei existiert Ja

Dateiinhalt

<?php

namespace Infrastructure\Persistence;

use PDO;

class ContractRepository
{
    private PDO $pdo;

    public function __construct()
    {
        // Contracts sind in ki_dev Datenbank
        $this->pdo = new PDO(
            'mysql:host=' . KI_DEV_DB_HOST . ';dbname=' . KI_DEV_DB_NAME . ';charset=utf8mb4',
            KI_DEV_DB_USER,
            KI_DEV_DB_PASS,
            [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            ]
        );
    }

    public function findAll(array $filters = [], int $limit = 50): array
    {
        $sql = 'SELECT * FROM contracts WHERE 1=1';
        $params = [];

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

        if (isset($filters['search']) && $filters['search'] !== '') {
            $sql .= ' AND (name LIKE :search OR scope_description LIKE :search2)';
            $params['search'] = '%' . $filters['search'] . '%';
            $params['search2'] = '%' . $filters['search'] . '%';
        }

        $sql .= ' ORDER BY name ASC, version DESC LIMIT :limit';

        $stmt = $this->pdo->prepare($sql);
        foreach ($params as $key => $value) {
            $stmt->bindValue(':' . $key, $value);
        }
        $stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
        $stmt->execute();

        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    public function findById(int $id): ?array
    {
        $stmt = $this->pdo->prepare('SELECT * FROM contracts WHERE id = :id');
        $stmt->execute(['id' => $id]);
        $result = $stmt->fetch(PDO::FETCH_ASSOC);

        return $result ?: null;
    }

    public function findByName(string $name, ?string $version = null): ?array
    {
        if ($version !== null) {
            $stmt = $this->pdo->prepare(
                'SELECT * FROM contracts WHERE name = :name AND version = :version'
            );
            $stmt->execute(['name' => $name, 'version' => $version]);
        } else {
            $stmt = $this->pdo->prepare(
                "SELECT * FROM contracts WHERE name = :name AND status = 'active' ORDER BY version DESC LIMIT 1"
            );
            $stmt->execute(['name' => $name]);
        }

        $result = $stmt->fetch(PDO::FETCH_ASSOC);

        return $result ?: null;
    }

    public function create(array $data): int
    {
        $stmt = $this->pdo->prepare('
            INSERT INTO contracts (uuid, name, version, status, yaml_content, scope_description, created_by)
            VALUES (UUID(), :name, :version, :status, :yaml_content, :scope_description, :created_by)
        ');

        $stmt->execute([
            'name' => $data['name'],
            'version' => $data['version'] ?? '1.0',
            'status' => $data['status'] ?? 'active',
            'yaml_content' => $data['yaml_content'],
            'scope_description' => $data['scope_description'] ?? null,
            'created_by' => $data['created_by'] ?? 'web',
        ]);

        return (int) $this->pdo->lastInsertId();
    }

    public function createNewVersion(int $id, string $yamlContent, string $newVersion, string $changeDescription): void
    {
        $contract = $this->findById($id);
        if ($contract === null) {
            throw new \RuntimeException("Contract {$id} not found");
        }

        $this->pdo->beginTransaction();

        try {
            // Historie speichern
            $stmt = $this->pdo->prepare('
                INSERT INTO contract_history (contract_id, previous_yaml, previous_version, change_description, changed_by)
                VALUES (:contract_id, :previous_yaml, :previous_version, :change_description, :changed_by)
            ');
            $stmt->execute([
                'contract_id' => $id,
                'previous_yaml' => $contract['yaml_content'],
                'previous_version' => $contract['version'],
                'change_description' => $changeDescription,
                'changed_by' => 'web',
            ]);

            // Contract aktualisieren
            $stmt = $this->pdo->prepare('
                UPDATE contracts SET yaml_content = :yaml_content, version = :version WHERE id = :id
            ');
            $stmt->execute([
                'yaml_content' => $yamlContent,
                'version' => $newVersion,
                'id' => $id,
            ]);

            $this->pdo->commit();
        } catch (\Exception $e) {
            $this->pdo->rollBack();

            throw $e;
        }
    }

    public function deprecate(int $id): void
    {
        $stmt = $this->pdo->prepare("UPDATE contracts SET status = 'deprecated' WHERE id = :id");
        $stmt->execute(['id' => $id]);
    }

    public function getHistory(int $contractId): array
    {
        $stmt = $this->pdo->prepare('
            SELECT * FROM contract_history
            WHERE contract_id = :contract_id
            ORDER BY changed_at DESC
        ');
        $stmt->execute(['contract_id' => $contractId]);

        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    public function getValidations(int $contractId, int $limit = 10): array
    {
        $stmt = $this->pdo->prepare('
            SELECT * FROM contract_validations
            WHERE contract_id = :contract_id
            ORDER BY validated_at DESC
            LIMIT :limit
        ');
        $stmt->bindValue('contract_id', $contractId, PDO::PARAM_INT);
        $stmt->bindValue('limit', $limit, PDO::PARAM_INT);
        $stmt->execute();

        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    public function runValidation(int $id): array
    {
        $contract = $this->findById($id);
        if ($contract === null) {
            return ['success' => false, 'error' => 'Contract not found'];
        }

        // Vereinfachte Validierung - prüft ob YAML gültig ist
        $startTime = microtime(true);

        try {
            $data = yaml_parse($contract['yaml_content']);
            $result = 'passed';
            $critical = 0;
            $major = 0;
            $minor = 0;
            $violations = [];

            // Basis-Prüfungen
            if (!isset($data['contract'])) {
                $major++;
                $violations[] = ['type' => 'major', 'message' => 'Missing contract root element'];
            }

            if (!isset($data['contract']['name'])) {
                $minor++;
                $violations[] = ['type' => 'minor', 'message' => 'Missing contract name'];
            }

            if ($critical > 0) {
                $result = 'failed';
            }
        } catch (\Exception $e) {
            $result = 'failed';
            $critical = 1;
            $major = 0;
            $minor = 0;
            $violations = [['type' => 'critical', 'message' => 'Invalid YAML: ' . $e->getMessage()]];
        }

        $durationMs = (int) ((microtime(true) - $startTime) * 1000);

        // Validierung speichern
        $stmt = $this->pdo->prepare("
            INSERT INTO contract_validations
            (contract_id, result, critical_count, major_count, minor_count, violations, triggered_by, duration_ms)
            VALUES (:contract_id, :result, :critical, :major, :minor, :violations, 'manual', :duration_ms)
        ");
        $stmt->execute([
            'contract_id' => $id,
            'result' => $result,
            'critical' => $critical,
            'major' => $major,
            'minor' => $minor,
            'violations' => json_encode($violations),
            'duration_ms' => $durationMs,
        ]);

        return [
            'success' => true,
            'result' => $result,
            'critical' => $critical,
            'major' => $major,
            'minor' => $minor,
            'violations' => $violations,
            'duration_ms' => $durationMs,
        ];
    }

    public function getStatistics(): array
    {
        $stats = [
            'total' => 0,
            'active' => 0,
            'draft' => 0,
            'deprecated' => 0,
            'validations_total' => 0,
            'validations_passed' => 0,
            'validations_failed' => 0,
        ];

        // Contracts nach Status
        $stmt = $this->pdo->query('SELECT status, COUNT(*) as cnt FROM contracts GROUP BY status');
        foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
            $stats[$row['status']] = (int) $row['cnt'];
            $stats['total'] += (int) $row['cnt'];
        }

        // Validierungen
        $stmt = $this->pdo->query('SELECT result, COUNT(*) as cnt FROM contract_validations GROUP BY result');
        foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
            $key = 'validations_' . $row['result'];
            $stats[$key] = (int) $row['cnt'];
            $stats['validations_total'] += (int) $row['cnt'];
        }

        return $stats;
    }
}

Vollständig herunterladen

Aktionen

Herunterladen

Andere Versionen dieser Datei

ID Version Typ Größe Datum
128 3 modified 8.8 KB 2025-12-20 19:40
127 2 modified 8.8 KB 2025-12-20 19:40
6 1 modified 8.8 KB 2025-12-20 16:09

← Zurück zur Übersicht