From 7eb1cbdabd213ad73d9e17ab71b05c7b9166621c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Fromme?= Date: Fri, 3 Apr 2026 15:20:37 +0200 Subject: [PATCH] fix: remove redundant insurance hydration, cache snapshots and files map --- src/Service/TravelDataService.php | 45 +++++++------------------ tests/Service/TravelDataServiceTest.php | 12 +++---- 2 files changed, 18 insertions(+), 39 deletions(-) diff --git a/src/Service/TravelDataService.php b/src/Service/TravelDataService.php index fd91dbf..ca54430 100644 --- a/src/Service/TravelDataService.php +++ b/src/Service/TravelDataService.php @@ -7,7 +7,6 @@ namespace App\Service; use App\BusProNet\ApiClient; use App\BusProNet\Exception\ApiClientException; use App\BusProNet\Model\BaseData; -use App\BusProNet\Model\Insurance; use App\BusProNet\Model\Notification; use App\BusProNet\Model\ServiceAvailabilityResponse; use App\BusProNet\Model\Travel; @@ -38,6 +37,9 @@ class TravelDataService private const int AVAILABILITY_CACHE_TTL = 600; private const int MUTABILITY_CACHE_TTL = 300; + /** @var array>|null */ + private ?array $filesMapCache = null; + public function __construct( private readonly TravelLoader $travelLoader, private readonly HotelLoader $hotelLoader, @@ -147,7 +149,6 @@ class TravelDataService if (null !== $travel) { $this->patchInsuranceData($travel); - $this->hydrateInsurancePackageRelationships($travel->insurances); } return $travel; @@ -275,6 +276,9 @@ class TravelDataService 'travelId' => $result->id, ]); + $this->patchInsuranceData($result); + $this->travelSnapshotService->upsertFromTravel($result); + return $result; } catch (ApiClientException $e) { $this->logger->error('Failed to load travel data from API', [ @@ -508,6 +512,10 @@ class TravelDataService */ public function generateFilesMap(): array { + if (null !== $this->filesMapCache) { + return $this->filesMapCache; + } + $mapping = []; try { @@ -537,6 +545,8 @@ class TravelDataService 'count' => count($mapping), ]); + $this->filesMapCache = $mapping; + return $mapping; } @@ -792,35 +802,4 @@ class TravelDataService } } - /** - * Reconstructs containedInsurances arrays for insurance packages. - * - * Insurance packages reference other insurances via containedInsuranceIds. - * After deserialization, the containedInsurances array is empty due to - * circular reference prevention. This method rebuilds those relationships. - * - * @param array $insurances All insurances including packages - */ - private function hydrateInsurancePackageRelationships(array $insurances): void - { - // Build lookup map of all insurances by ID (includes complementary insurances) - $insuranceById = []; - foreach ($insurances as $insurance) { - $insuranceById[$insurance->id] = $insurance; - } - - // Reconstruct containedInsurances for each package - foreach ($insurances as $insurance) { - if (!$insurance->package || empty($insurance->containedInsuranceIds)) { - continue; - } - - $insurance->containedInsurances = []; - foreach ($insurance->containedInsuranceIds as $containedId) { - if (isset($insuranceById[$containedId])) { - $insurance->containedInsurances[] = $insuranceById[$containedId]; - } - } - } - } } diff --git a/tests/Service/TravelDataServiceTest.php b/tests/Service/TravelDataServiceTest.php index 05b3762..80a3389 100644 --- a/tests/Service/TravelDataServiceTest.php +++ b/tests/Service/TravelDataServiceTest.php @@ -313,7 +313,7 @@ class TravelDataServiceTest extends TestCase $this->assertSame($travel, $result); } - public function testGetTravelDataFromLocalHydratesInsurancePackagesFromLoaderAfterSnapshotLoad(): void + public function testGetTravelDataFromLocalReplacesSnapshotInsurancesWithLoaderData(): void { $dateId = 12345; $hotelId = 67890; @@ -335,7 +335,8 @@ class TravelDataServiceTest extends TestCase $package->id = '20'; $package->package = true; $package->containedInsuranceIds = ['10']; - $package->containedInsurances = []; + // InsuranceParser populates containedInsurances at parse time; loadAll() returns hydrated data. + $package->containedInsurances = [$individual]; $this->travelSnapshotService ->expects($this->once()) @@ -396,13 +397,11 @@ class TravelDataServiceTest extends TestCase $this->assertSame($travel, $result); } - public function testGetTravelDataFromLocalRehydratesInsurancePackagesFromXmlFallback(): void + public function testGetTravelDataFromLocalAttachesLoaderInsurancesFromXmlFallback(): void { $dateId = 12345; $hotelId = 67890; - // InsuranceLoader supplies the canonical insurance list for local reads; the package's - // containedInsurances starts empty and is rebuilt after hydration. $individual = new Insurance(); $individual->id = '10'; $individual->package = false; @@ -411,7 +410,8 @@ class TravelDataServiceTest extends TestCase $package->id = '20'; $package->package = true; $package->containedInsuranceIds = ['10']; - $package->containedInsurances = []; + // InsuranceParser populates containedInsurances at parse time; loadAll() returns hydrated data. + $package->containedInsurances = [$individual]; $travel = new Travel(); $travel->id = $dateId;