3.8 KiB
3.8 KiB
Travel Snapshot Persistence (DB-Primary + Extended Availability)
Scope
Persist travel payloads in DB and use them as primary local source, with enrichment from BusPro VERFUEGBARKEIT2 (internal naming: extended/ext).
Current Implementation Status
Completed
- Added snapshot persistence entity and repository:
src/Entity/TravelSnapshot.phpsrc/Repository/TravelSnapshotRepository.php
- Added snapshot application service:
src/Service/TravelSnapshotService.php- Uses Symfony Serializer JSON payloads for
Travel - Supports upsert/hash comparison, load, mapping, product lookup, refresh, purge
- Added extended availability integration:
ApiClient::TYPE_AVAILABILITY_EXTENDED = 'VERFUEGBARKEIT2'ApiClient::getAvailabilitiesExtended()- parser dispatch in
ApiResponseParser ExtendedAvailabilitiesParser- models
ExtendedAvailabilityandExtendedServiceAvailabilityResponse
- Added DB-primary read path in
TravelDataService:- tries snapshot first
- falls back to XML parse + enrichment + snapshot upsert
- snapshot mapping merged into
generateFilesMap() - product lookup includes snapshot metadata fallback
- Added refresh command:
app:travel:snapshot-refresh- supports batch processing, force mode, optional purge
- Added migration for snapshot table:
migrations/Version20260321120000.php
- Added serializer type metadata/docblocks in relevant model classes to support stable snapshot deserialization.
- Removed unified travel cache from
TravelDataService::getTravelData():- cache and snapshot-version-token logic removed; travel is now loaded directly from snapshot DB (fast indexed lookup) or XML fallback on every call
TravelSnapshotService::getCacheVersionToken()removed along with it
- Fixed hotel-specific lookup correctness:
- when
hotelIdis provided, snapshot lookup no longer falls back to another hotel of same date.
- when
Confirmed Behaviors
- Snapshot data survives XML deletion and remains loadable.
- Extended refresh updates service-level fields including
uhrzeit_von->Service::timeFrom. - Runtime availability overlay (
VERFUEGBARKEIT) remains in place.
Design Decisions (Final)
- Internal naming uses
extended/ext; external request type string staysVERFUEGBARKEIT2. - DB snapshots are the primary local source for travel loading.
- Serializer format is JSON via Symfony Serializer, not PHP
serialize(). - No application-level cache wraps
getTravelData(); snapshot DB is the fast path, XML is the fallback.
Operational Commands
- Refresh snapshots:
ddev php bin/console app:travel:snapshot-refresh
- Force refresh:
ddev php bin/console app:travel:snapshot-refresh --force
- Force refresh with limit:
ddev php bin/console app:travel:snapshot-refresh --force --limit=500
- Refresh + purge:
ddev php bin/console app:travel:snapshot-refresh --purge
Open TODOs
- Revisit DB indexes on
travel_snapshotand remove unused ones if desired (date_code,product_idcurrently appear non-critical for active query paths). - Added automated tests:
TravelSnapshotServiceTest— upsert, load, exists, generateMappingTravelDataServiceTest— DB-primary + XML fallback paths, insurance rehydration, exception propagation
- Add/expand automated tests:
- extended parser coverage
- snapshot refresh command behavior
- Define production cron schedule for refresh and cleanup cadence.
Notes
- If refreshed snapshot data is not visible immediately, ensure the request path is not serving an older in-memory/session DTO. There is no application-level cache on
getTravelData(); each call reads the snapshot DB directly, so data is current on the next request after a refresh.