dadfdcaa7e
Месячный cron-сброс tenants.delivered_in_month + projects.delivered_in_month 1-го числа каждого месяца в 00:00 МСК. Идёт через pgsql_supplier BYPASSRLS connection (паттерн ResetDeliveredTodayCommand). Идемпотентный (WHERE delivered_in_month <> 0 → повторный запуск 0 affected rows). 4 теста: reset multi-tenant + idempotency + Schedule registration + BYPASSRLS without SET LOCAL. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
43 lines
1.9 KiB
PHP
43 lines
1.9 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace App\Console\Commands;
|
||
|
||
use Illuminate\Console\Command;
|
||
use Illuminate\Support\Facades\DB;
|
||
|
||
/**
|
||
* Сброс tenants.delivered_in_month + projects.delivered_in_month = 0.
|
||
*
|
||
* Spec: docs/superpowers/specs/2026-05-11-plan4-billing-csv-admin-design.md §4.1
|
||
* Расписание: 1-го числа каждого месяца в 00:00 Europe/Moscow.
|
||
*
|
||
* Идёт через connection `pgsql_supplier` (BYPASSRLS-роль crm_supplier_worker) —
|
||
* паттерн ResetDeliveredTodayCommand. Один statement на таблицу, без SET LOCAL.
|
||
*/
|
||
class ResetMonthlyCountersCommand extends Command
|
||
{
|
||
protected $signature = 'projects:reset-monthly';
|
||
|
||
protected $description = 'Сброс tenants.delivered_in_month + projects.delivered_in_month = 0 (1-го числа в 00:00 МСК, Plan 4)';
|
||
|
||
public function handle(): int
|
||
{
|
||
// Без оборачивающего DB::transaction: два UPDATE'а независимо идемпотентны
|
||
// (WHERE delivered_in_month <> 0). Если один упадёт, следующий cron-запуск
|
||
// довершит сброс. Атомарность не требуется. Дополнительно — оборачивание
|
||
// ломает тесты с shared PDO (SharesSupplierPdo trait): PostgreSQL не
|
||
// допускает nested transactions без savepoints, см. precedent
|
||
// ResetDeliveredTodayCommand (тоже без обёртки).
|
||
$tenants = DB::connection('pgsql_supplier')
|
||
->update('UPDATE tenants SET delivered_in_month = 0 WHERE delivered_in_month <> 0');
|
||
$projects = DB::connection('pgsql_supplier')
|
||
->update('UPDATE projects SET delivered_in_month = 0 WHERE delivered_in_month <> 0');
|
||
|
||
$this->info("Monthly reset: {$tenants} tenants, {$projects} projects.");
|
||
|
||
return self::SUCCESS;
|
||
}
|
||
}
|