fix(балансы): свежий query-builder на итерацию джобы (PK violation на 2-м прогоне)
Переиспользование одного DB-билдера в цикле накапливало where-клаузы → updateOrInsert уходил в INSERT существующей строки → SQLSTATE 23505 на проде при повторном сборе. Билдер теперь создаётся внутри цикла. + тест на 2 прогона. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -51,6 +51,18 @@ it('пишет балансы трёх сервисов + считает све
|
||||
expect($rows['dadata']->ok)->toBeTruthy();
|
||||
});
|
||||
|
||||
it('повторный запуск обновляет строки, а не падает на PK (свежий builder/итерация)', function () {
|
||||
app()->instance(DadataBalanceProvider::class, fakeProvider('dadata', BalanceReading::ok('dadata', 4500, 'RUB', 100)));
|
||||
app()->instance(SupplierBalanceProvider::class, fakeProvider('supplier', BalanceReading::fail('supplier', 'таймаут')));
|
||||
app()->instance(YandexCloudBalanceProvider::class, fakeProvider('yandex_cloud', BalanceReading::ok('yandex_cloud', 42000, 'RUB', 600)));
|
||||
|
||||
(new RefreshExternalBalancesJob)->handle();
|
||||
(new RefreshExternalBalancesJob)->handle(); // второй прогон не должен бросить UniqueConstraint
|
||||
|
||||
$rows = DB::connection('pgsql_supplier')->table('external_service_balances')->get();
|
||||
expect($rows)->toHaveCount(3); // строк по-прежнему 3, без дублей
|
||||
});
|
||||
|
||||
it('упавший провайдер не роняет джобу и сохраняет ошибку, остальные пишутся', function () {
|
||||
app()->instance(DadataBalanceProvider::class, fakeProvider('dadata', BalanceReading::fail('dadata', 'HTTP 403')));
|
||||
app()->instance(SupplierBalanceProvider::class, fakeProvider('supplier', BalanceReading::ok('supplier', 50000, 'RUB', null)));
|
||||
|
||||
Reference in New Issue
Block a user