Files
awo-hamburg-intranet/module/tasks/cli/task_cert_sync_assignments.php
Moritz Weinmann 743476f64a Module tasks + knowledgecenter_update aus Kundenprojekt übernehmen (bereinigt)
Beide Module wurden aus einem anderen Kundenprojekt kopiert und bereinigt:

Knowledgecenter:
- Bild-Cache (1.985 Dateien) geleert, Ordnerstruktur mit .gitkeep behalten
- Files-Gallery-Lizenzschlüssel entfernt (config.php)
- Kundenspezifische Kategorien gelöscht: Teil I/II/III QM-Struktur,
  nummerierte QM-Kapitel, Gremien (Präsidium/Finanzausschuss/Landesausschuss),
  Sitzungsservice-Serie, Protokoll-Abteilungen, Testeinträge
- 56 generische Kategorien bleiben (Downloads, Onboarding, Personalthemen …)

Tasks:
- Alle Betriebsdaten gelöscht (114 Tasks, 914 Submissions, 579 Assignments)
- Task-Definitionen und Verlinkungen geleert
- Kategoriestruktur bleibt (Allgemein, IT, Personal, Buchhaltung …)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 09:20:02 +02:00

109 lines
3.4 KiB
PHP

<?php
declare(strict_types=1);
require_once __DIR__ . '/CronRuntime.php';
$usage = <<<TXT
Usage:
php cli/task_cert_sync_assignments.php [--apply|--dry-run] [--task_id=<id>] [--no-lock] [--json]
Options:
--apply Mutierender Lauf (Zuweisungen anlegen/entfernen)
--dry-run Nur Vorschau, keine DB-Änderungen
--task_id Optional: nur eine Aufgabe verarbeiten
--no-lock Locking deaktivieren (nur Debug)
--json JSON-Ausgabe zusätzlich auf stdout
--help Diese Hilfe anzeigen
TXT;
try {
$options = TaskCertCronRuntime::parseOptions($argv, true);
} catch (InvalidArgumentException $exception) {
TaskCertCronRuntime::printOptionError($exception->getMessage(), $usage);
exit(2);
}
if ((bool) ($options['help'] ?? false)) {
TaskCertCronRuntime::printUsage($usage);
exit(0);
}
$exitCode = TaskCertCronRuntime::runWithHandling(
'sync_assignments',
$options,
static function (array $context) use ($options): array {
require_once dirname(__DIR__) . '/bootstrap.php';
$services = task_cert_services();
$resolver = $services['assignmentResolverService'] ?? null;
if (!$resolver instanceof AssignmentResolverService) {
throw new RuntimeException('AssignmentResolverService nicht verfügbar.');
}
$apply = (bool) ($options['apply'] ?? false);
$taskId = (int) ($options['task_id'] ?? 0);
$auditContext = [
'changed_by' => 0,
'trigger' => 'cron_cli',
'job_run_id' => (string) ($context['job_run_id'] ?? ''),
];
if ($taskId > 0) {
$results = [$resolver->syncAssignmentsForTask($taskId, $apply, 'current_cycle', $auditContext)];
} else {
$results = $resolver->syncAssignmentsForAllActiveTasks($apply, 'current_cycle', $auditContext);
}
$totals = [
'task_count' => 0,
'target_count' => 0,
'existing_count' => 0,
'create_count' => 0,
'update_count' => 0,
'stale_count' => 0,
'protected_completed_count' => 0,
'protected_certificate_count' => 0,
'remove_count' => 0,
'remove_with_submissions_count' => 0,
];
foreach ($results as $result) {
if (!is_array($result)) {
continue;
}
$totals['task_count']++;
foreach ([
'target_count',
'existing_count',
'create_count',
'update_count',
'stale_count',
'protected_completed_count',
'protected_certificate_count',
'remove_count',
'remove_with_submissions_count',
] as $key) {
$totals[$key] += (int) ($result[$key] ?? 0);
}
}
if ($apply && $taskId <= 0) {
CronHeartbeat::record('sync_assignments', [
'task_count' => (int) ($totals['task_count'] ?? 0),
'create_count' => (int) ($totals['create_count'] ?? 0),
'remove_count' => (int) ($totals['remove_count'] ?? 0),
]);
}
return [
'job' => 'sync_assignments',
'mode' => $apply ? 'apply' : 'dry_run',
'scope' => 'current_cycle',
'task_id' => $taskId > 0 ? $taskId : null,
'totals' => $totals,
];
}
);
exit($exitCode);