Backup #128
| ID | 128 |
| Dateipfad | /var/www/dev.campus.systemische-tools.de/src/Infrastructure/Persistence/ContractRepository.php |
| Version | 3 |
| Typ |
modified |
| Größe | 8.8 KB |
| Hash | ed0dc76532fc2e5a194e0f764514c4d2c20743b17cfee7e0decd8fcc58fe60d6 |
| Datum | 2025-12-20 19:40:44 |
| Geändert von | claude-code-hook |
| Grund | Claude 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
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