Files
portal/app/app/Console/Commands/ResetDeliveredTodayCommand.php
T
Дмитрий 9daa94d917 feat(commands): projects:reset-delivered-today (00:00 МСК cron)
Spec §6.1: ежедневный сброс projects.delivered_today=0 после midnight МСК.
delivered_in_month НЕ трогаем (это месячный счётчик, Plan 4 cron).

Реализация: Artisan-команда `projects:reset-delivered-today` (idempotent
UPDATE без транзакции/локов — отрабатывает за <1 сек), Schedule в
routes/console.php с dailyAt('00:00')->timezone('Europe/Moscow').

NB: `withoutOverlapping()` пропущен — требует таблицу cache_locks, которой
нет в schema.sql (Laravel-default-миграции удалены в фазе 1). Идемпотентность
UPDATE делает overlap-защиту избыточной.

Tests: 2/2 pass, phpstan 0 errors (1 baseline для $this->artisan, как у
прочих Pest-тестов с artisan-helper).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 19:58:47 +03:00

34 lines
1.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
/**
* Сброс projects.delivered_today=0 для всех tenant'ов.
*
* Spec: docs/superpowers/specs/2026-05-10-supplier-integration-design.md §6.1.
* Расписание: каждый день в 00:00 МСК (timezone Europe/Moscow).
*
* NB: tenant-scoped запрос без RLS — UPDATE сразу на все tenant'ы.
* dev=postgres BYPASSRLS / prod=elevated role при выполнении из Scheduler'а.
*/
class ResetDeliveredTodayCommand extends Command
{
protected $signature = 'projects:reset-delivered-today';
protected $description = 'Сброс projects.delivered_today=0 (00:00 МСК cron, spec §6.1)';
public function handle(): int
{
$affected = DB::update('UPDATE projects SET delivered_today = 0 WHERE delivered_today <> 0');
$this->info("Reset delivered_today on {$affected} project(s).");
return self::SUCCESS;
}
}