Add AI parsing and graph parsing status; update related hooks and localization; modify microtime values in config and state files

This commit is contained in:
2026-03-27 10:47:30 +01:00
parent fa3c92379f
commit 412c25f184
14 changed files with 164 additions and 15 deletions

View File

@@ -29,9 +29,7 @@ class UpdateLastSyncFromDocuments implements BeforeSave
$pdo = $this->entityManager->getPDO();
$aktenId = $entity->getId();
// Einzelne Zeile mit aggregierten Worst-Case-Werten über alle Dokumente.
// CASE-Ausdrücke in MAX() vermeiden das GROUP-BY-Problem bei gemischten
// Aggregat- und Nicht-Aggregat-Spalten.
// Single aggregation row — CASE inside MAX() avoids the mixed-aggregate bug.
$stmt = $pdo->prepare(
"SELECT
MAX(last_sync_timestamp) AS maxAdvLastSync,
@@ -48,6 +46,12 @@ class UpdateLastSyncFromDocuments implements BeforeSave
OR ai_sync_status IS NULL OR ai_sync_status = '' THEN 1
ELSE 0
END) AS aiWorstLevel,
-- ai_sync_status = unclean triggers graphParsingStatus
SUM(CASE WHEN ai_sync_status = 'unclean' THEN 1 ELSE 0 END) AS aiUncleanCount,
-- aiParsingStatus buckets
SUM(CASE WHEN ai_parsing_status = 'parsing' THEN 1 ELSE 0 END) AS parseParsingCount,
SUM(CASE WHEN ai_parsing_status = 'complete' THEN 1 ELSE 0 END) AS parseCompleteCount,
SUM(CASE WHEN ai_parsing_status = 'failed' THEN 1 ELSE 0 END) AS parseFailedCount,
COUNT(*) AS docCount
FROM c_dokumente
WHERE c_akten_id = :aktenId AND deleted = 0"
@@ -58,10 +62,13 @@ class UpdateLastSyncFromDocuments implements BeforeSave
if (!$row || (int)$row['docCount'] === 0) {
$entity->set('syncStatus', 'unclean');
$entity->set('aiSyncStatus', 'unclean');
$entity->set('aiParsingStatus', 'unknown');
return;
}
// Timestamps setzen
$docCount = (int)$row['docCount'];
// ── Timestamps ─────────────────────────────────────────────────
if (!empty($row['maxAdvLastSync'])) {
$entity->set('lastSync', $row['maxAdvLastSync']);
}
@@ -69,7 +76,7 @@ class UpdateLastSyncFromDocuments implements BeforeSave
$entity->set('aiLastSync', $row['maxAiLastSync']);
}
// Advoware Status setzen (worst-case über alle Dokumente)
// ── Advoware Sync Status (worst-case) ──────────────────────────
$advLevel = (int)($row['advWorstLevel'] ?? 0);
if ($advLevel >= 2) {
$entity->set('syncStatus', 'failed');
@@ -79,7 +86,7 @@ class UpdateLastSyncFromDocuments implements BeforeSave
$entity->set('syncStatus', 'synced');
}
// AI Status setzen (worst-case über alle Dokumente)
// ── AI Sync Status (worst-case) ────────────────────────────────
$aiLevel = (int)($row['aiWorstLevel'] ?? 0);
if ($aiLevel >= 2) {
$entity->set('aiSyncStatus', 'failed');
@@ -89,6 +96,31 @@ class UpdateLastSyncFromDocuments implements BeforeSave
$entity->set('aiSyncStatus', 'synced');
}
// ── AI Parsing Status (aggregated across all documents) ─────────
// Priority: parsing > unknown > complete_with_failures > complete
$parseParsing = (int)($row['parseParsingCount'] ?? 0);
$parseComplete = (int)($row['parseCompleteCount'] ?? 0);
$parseFailed = (int)($row['parseFailedCount'] ?? 0);
$parseUnknown = $docCount - $parseParsing - $parseComplete - $parseFailed;
if ($parseParsing > 0) {
$entity->set('aiParsingStatus', 'parsing');
} elseif ($parseUnknown > 0) {
$entity->set('aiParsingStatus', 'unknown');
} elseif ($parseFailed > 0) {
// No unknown/parsing left, but some failures
$entity->set('aiParsingStatus', 'complete_with_failures');
} else {
$entity->set('aiParsingStatus', 'complete');
}
// ── Graph Parsing Status (only auto-set to unclean, never reset) ─
// If any document's AI sync status is currently unclean → graph is stale.
// Any other transition (back to complete, etc.) must be done manually.
if ((int)($row['aiUncleanCount'] ?? 0) > 0) {
$entity->set('graphParsingStatus', 'unclean');
}
} catch (\Exception $e) {
$GLOBALS['log']->error('CAkten UpdateLastSyncFromDocuments Hook Error: ' . $e->getMessage());
}