c975e16a14
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
48 lines
1.4 KiB
PHP
48 lines
1.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Services\DaData;
|
|
|
|
use Illuminate\Support\Facades\Cache;
|
|
|
|
/**
|
|
* Дневной бюджет на платные вызовы DaData (spec §5.3 / §11).
|
|
*
|
|
* Расход копится в копейках под дневным ключом `phone_resolution:dadata:spent_kopecks:<YYYY-MM-DD>`.
|
|
* `Cache::increment` на redis-сторе атомарен (INCRBY) — корректно при параллельных
|
|
* RouteSupplierLeadJob. Дневной ключ сам обнуляется со сменой даты; TTL 2 дня чистит старые.
|
|
*
|
|
* При canSpend()=false LeadRegionResolver минует DaData и идёт сразу в Россвязь (spec §3.3).
|
|
*/
|
|
class DaDataBudgetGuard
|
|
{
|
|
public function canSpend(): bool
|
|
{
|
|
$capKopecks = ((int) config('services.dadata.daily_cap_rub', 10000)) * 100;
|
|
|
|
return $this->spentTodayKopecks() < $capKopecks;
|
|
}
|
|
|
|
public function recordSpend(int $kopecks): void
|
|
{
|
|
if ($kopecks <= 0) {
|
|
return;
|
|
}
|
|
|
|
$key = $this->dailyKey();
|
|
Cache::add($key, 0, now()->addDays(2));
|
|
Cache::increment($key, $kopecks);
|
|
}
|
|
|
|
public function spentTodayKopecks(): int
|
|
{
|
|
return (int) Cache::get($this->dailyKey(), 0);
|
|
}
|
|
|
|
private function dailyKey(): string
|
|
{
|
|
return 'phone_resolution:dadata:spent_kopecks:'.now()->format('Y-m-d');
|
|
}
|
|
}
|