refactor: scope postcode cache to place names, DB is authoritative for postcodes

This commit is contained in:
Ovidiu U
2026-04-22 12:23:50 +01:00
parent d460de1850
commit 5426722c71
2 changed files with 38 additions and 15 deletions

View File

@@ -26,7 +26,16 @@ class PostcodeService
public function resolve(string $query): ?LocationResult public function resolve(string $query): ?LocationResult
{ {
$query = trim($query); $query = trim($query);
$cacheKey = 'postcode:'.strtolower(preg_replace('/\s+/', '', $query));
if ($this->isFullPostcode($query)) {
return $this->lookupLocalPostcode($query) ?? $this->lookupPostcode($query);
}
if ($this->isOutcode($query)) {
return $this->lookupLocalOutcode($query) ?? $this->lookupOutcode($query);
}
$cacheKey = 'place:'.strtolower(preg_replace('/\s+/', '', $query));
$cached = Cache::get($cacheKey); $cached = Cache::get($cacheKey);
@@ -34,11 +43,7 @@ class PostcodeService
return $cached; return $cached;
} }
$result = match (true) { $result = $this->lookupPlace($query);
$this->isFullPostcode($query) => $this->lookupLocalPostcode($query) ?? $this->lookupPostcode($query),
$this->isOutcode($query) => $this->lookupLocalOutcode($query) ?? $this->lookupOutcode($query),
default => $this->lookupPlace($query),
};
if ($result !== null) { if ($result !== null) {
Cache::put($cacheKey, $result, self::CACHE_TTL); Cache::put($cacheKey, $result, self::CACHE_TTL);

View File

@@ -134,23 +134,41 @@ it('returns null when place name yields no results', function (): void {
// --- Caching --- // --- Caching ---
it('caches a successful resolution for 30 days', function (): void { it('caches a successful place resolution for 30 days', function (): void {
Http::fake([ Http::fake([
'*/outcodes/PE7' => Http::response([ '*/places*' => Http::response([
'status' => 200,
'result' => [[
'name_1' => 'Manchester',
'latitude' => 53.480957,
'longitude' => -2.237428,
]],
]),
]);
$this->service->resolve('Manchester');
$this->service->resolve('Manchester');
Http::assertSentCount(1);
expect(Cache::get('place:manchester'))->toBeInstanceOf(LocationResult::class);
});
it('does not cache postcode resolutions in the Cache store (DB is the cache)', function (): void {
Http::fake([
'*/postcodes/SW1A1AA' => Http::response([
'status' => 200, 'status' => 200,
'result' => [ 'result' => [
'outcode' => 'PE7', 'postcode' => 'SW1A 1AA',
'latitude' => 52.536397, 'latitude' => 51.501009,
'longitude' => -0.210181, 'longitude' => -0.141588,
], ],
]), ]),
]); ]);
$this->service->resolve('PE7'); $this->service->resolve('SW1A 1AA');
$this->service->resolve('PE7');
Http::assertSentCount(1); expect(Cache::get('postcode:sw1a1aa'))->toBeNull()
expect(Cache::get('postcode:pe7'))->toBeInstanceOf(LocationResult::class); ->and(Postcode::find('SW1A1AA'))->not->toBeNull();
}); });
it('does not cache failed lookups', function (): void { it('does not cache failed lookups', function (): void {