feat(helpdesk): add handover revision history with timeline, diff, and restore

Every save creates an immutable revision snapshot. The aside shows a
commit-graph-style timeline (newest first) with vertical line, circle
nodes, version numbers, change type, user, and date. Clicking a past
revision renders it readonly with inline git-diff-style highlights
(changed/added/removed with tinted backgrounds). Compare mode allows
diffing any two arbitrary revisions. MANAGE users can restore old
versions, which creates a new revision preserving full history.

New: HandoverRevisionService, HandoverRevisionRepository,
migration 006, 14 PHPUnit tests, DE/EN translations.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-15 22:14:40 +02:00
parent 320f0a5a00
commit 03e15eaf08
13 changed files with 1240 additions and 96 deletions

View File

@@ -21,7 +21,9 @@ use MintyPHP\Module\Helpdesk\Service\SystemRecommendationEngine;
use MintyPHP\Module\Helpdesk\Service\TicketCommunicationService;
use MintyPHP\Module\Helpdesk\Handler\SoftwareProductSyncJobHandler;
use MintyPHP\Module\Helpdesk\Repository\HandoverRepository;
use MintyPHP\Module\Helpdesk\Repository\HandoverRevisionRepository;
use MintyPHP\Module\Helpdesk\Repository\SoftwareProductRepository;
use MintyPHP\Module\Helpdesk\Service\HandoverRevisionService;
use MintyPHP\Module\Helpdesk\Service\HandoverService;
use MintyPHP\Service\Access\PermissionService;
use MintyPHP\Service\Settings\SettingServicesFactory;
@@ -109,9 +111,17 @@ final class HelpdeskContainerRegistrar implements ContainerRegistrar
$container->set(HandoverRepository::class, static fn (): HandoverRepository => new HandoverRepository());
$container->set(HandoverRevisionRepository::class, static fn (): HandoverRevisionRepository => new HandoverRevisionRepository());
$container->set(HandoverRevisionService::class, static fn (AppContainer $c): HandoverRevisionService => new HandoverRevisionService(
$c->get(HandoverRevisionRepository::class),
$c->get(HandoverRepository::class)
));
$container->set(HandoverService::class, static fn (AppContainer $c): HandoverService => new HandoverService(
$c->get(HandoverRepository::class),
$c->get(SoftwareProductService::class)
$c->get(SoftwareProductService::class),
$c->get(HandoverRevisionService::class)
));
}
}