Viel neues

This commit is contained in:
Sven Steinert
2026-04-30 12:06:00 +02:00
parent 118809bfae
commit fce31ebcd7
1274 changed files with 181255 additions and 0 deletions

View File

@@ -0,0 +1,162 @@
<?php
declare(strict_types=1);
header('Content-Type: application/json; charset=utf-8');
require_once __DIR__ . '/../config/config.php';
try {
if (getenv('APP_DEBUG') === 'true') { ini_set('display_errors', '1'); error_reporting(E_ALL); }
if (!class_exists('PDO')) { throw new Exception('PDO extension not loaded'); }
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode(['ok'=>false, 'error'=>'Method not allowed']);
exit;
}
if (!isset($_POST['run'])) {
http_response_code(400);
echo json_encode(['ok'=>false, 'error'=>'Missing run']);
exit;
}
// Eingabe parsen
$run = json_decode($_POST['run'], true, 512, JSON_THROW_ON_ERROR);
// Optional: PDF speichern
$savedPdf = null;
if (isset($_FILES['pdf']) && $_FILES['pdf']['error'] === UPLOAD_ERR_OK) {
$ext = '.pdf';
$fname = sprintf(
'QA-%s-%s-%s-%s%s',
preg_replace('~[^a-zA-Z0-9_-]+~','_', $run['module'] ?? 'mod'),
preg_replace('~[^a-zA-Z0-9_-]+~','_', $run['module_version'] ?? 'v'),
preg_replace('~[^a-zA-Z0-9_-]+~','_', $run['pbx_version'] ?? 'pbx'),
date('Ymd_His'),
$ext
);
$destDir = rtrim($pdf_storage_dir ?? (__DIR__ . '/../storage/reports'), '/');
if (!is_dir($destDir)) { @mkdir($destDir, 0775, true); }
$dest = $destDir . '/' . $fname;
if (!@move_uploaded_file($_FILES['pdf']['tmp_name'], $dest)) {
$savedPdf = null; // PDF optional; DB-Export läuft trotzdem weiter
}
$savedPdf = $dest;
}
// DB verbinden
$dsn = "mysql:host={$db_host};port={$db_port};dbname={$db_name};charset=utf8mb4";
$pdo = new PDO($dsn, $db_user, $db_pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
]);
// Schema sicherstellen (idempotent)
$pdo->exec("
CREATE TABLE IF NOT EXISTS reports (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
module VARCHAR(255),
module_version VARCHAR(100),
pbx_version VARCHAR(100),
olm_nummer VARCHAR(100),
tester VARCHAR(255),
docbee_url TEXT,
summary VARCHAR(255),
pdf_path TEXT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS steps (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
report_id BIGINT NOT NULL,
step_index INT,
step_id VARCHAR(50),
title TEXT,
expected TEXT,
status ENUM('pass','fail','skip','na','') DEFAULT '',
comment TEXT,
evidence TEXT,
group_title VARCHAR(255),
group_index INT,
CONSTRAINT fk_steps_report FOREIGN KEY (report_id) REFERENCES reports(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
");
// Summary berechnen
$total=0;$pass=0;$fail=0;$skip=0;
foreach (($run['steps'] ?? []) as $s) {
if (($s['kind'] ?? 'step') === 'step') {
$total++;
$st = $s['status'] ?? '';
if ($st==='pass') $pass++;
elseif ($st==='fail') $fail++;
elseif ($st==='skip') $skip++;
}
}
$summary = sprintf('%d/%d pass, %d fail, %d skip', $pass, $total, $fail, $skip);
// Report speichern
$stmt = $pdo->prepare("INSERT INTO reports
(module, module_version, pbx_version, olm_nummer, tester, docbee_url, summary, pdf_path)
VALUES (:module, :module_version, :pbx_version, :olm_nummer, :tester, :docbee_url, :summary, :pdf_path)");
$stmt->execute([
':module' => $run['module'] ?? null,
':module_version' => $run['module_version'] ?? null,
':pbx_version' => $run['pbx_version'] ?? null,
':olm_nummer' => $run['olm_nummer'] ?? null,
':tester' => $run['tester'] ?? null,
':docbee_url' => $run['docbee_url'] ?? null,
':summary' => $summary,
':pdf_path' => $savedPdf
]);
$reportId = (int)$pdo->lastInsertId();
// Steps speichern
$idx = 0; $gidx = -1; $currentGroup = null;
$ins = $pdo->prepare("INSERT INTO steps
(report_id, step_index, step_id, title, expected, status, comment, evidence, group_title, group_index)
VALUES (:report_id,:step_index,:step_id,:title,:expected,:status,:comment,:evidence,:group_title,:group_index)");
foreach (($run['steps'] ?? []) as $s) {
if (($s['kind'] ?? 'step') === 'group') {
$currentGroup = $s['title'] ?? null;
$gidx++;
continue;
}
$idx++;
// status normalisieren → ENUM-kompatibel
$rawStatus = strtolower(trim((string)($s['status'] ?? '')));
$map = [
'ok'=>'pass','passed'=>'pass','success'=>'pass','true'=>'pass','yes'=>'pass','✔'=>'pass','✓'=>'pass',
'ko'=>'fail','failed'=>'fail','error'=>'fail','✗'=>'fail','x'=>'fail',
'skipped'=>'skip',
'n/a'=>'na','not applicable'=>'na',
'block'=>'blocked','blocked'=>'blocked','⛔'=>'blocked'
];
$st = $map[$rawStatus] ?? (in_array($rawStatus, ['pass','fail','skip','na','blocked',''], true) ? $rawStatus : '');
// und beim Insert:
// ':status' => $st,
$st = $map[$rawStatus] ?? (in_array($rawStatus, ['pass','fail','skip','na',''], true) ? $rawStatus : '');
try {
$ins->execute([
':report_id' => $reportId,
':step_index' => $idx,
':step_id' => $s['id'] ?? null,
':title' => $s['title'] ?? null,
':expected' => $s['expected'] ?? null,
':status' => $st,
':comment' => $s['comment'] ?? null,
':evidence' => $s['evidence'] ?? null,
':group_title' => $currentGroup,
':group_index' => $gidx >= 0 ? $gidx : null,
]);
} catch (PDOException $e) {
if ($e->getCode() !== '01000') { throw $e; } // ENUM-Truncation-Warning ignorieren
}
}
echo json_encode(['ok'=>true, 'report_id'=>$reportId, 'pdf_path'=>$savedPdf, 'summary'=>$summary]);
} catch (Throwable $e) {
http_response_code(500);
echo json_encode(['ok'=>false, 'error'=>$e->getMessage()]);
}