create(['frozen_by_balance_at' => null]); Project::factory()->for($tenant)->asCallSignal('79161234567')->create([ 'is_active' => true, 'delivery_days_mask' => 127, 'daily_limit_target' => 10, ]); $this->artisan('snapshot:rebuild', ['--date' => '2026-05-29'])->assertSuccessful(); expect( DB::table('project_routing_snapshots') ->where('snapshot_date', '2026-05-29') ->where('tenant_id', $tenant->id) ->count() )->toBe(1); Carbon::setTestNow(); }); it('replaces existing snapshot (NOT idempotent skip — full rebuild)', function (): void { Carbon::setTestNow('2026-05-29 09:00:00', 'Europe/Moscow'); $tenant = Tenant::factory()->create(['frozen_by_balance_at' => null]); $project = Project::factory()->for($tenant)->asCallSignal('79161234567')->create([ 'is_active' => true, 'delivery_days_mask' => 127, 'daily_limit_target' => 10, ]); // Уже есть snapshot за 2026-05-29 со stale daily_limit=3. DB::table('project_routing_snapshots')->insert([ 'snapshot_date' => '2026-05-29', 'project_id' => $project->id, 'tenant_id' => $tenant->id, 'daily_limit' => 3, // stale 'delivery_days_mask' => 127, 'regions' => '{}', 'signal_type' => 'call', 'signal_identifier' => '79161234567', 'expected_volume' => 3, 'delivered_count' => 0, 'created_at' => now(), ]); $this->artisan('snapshot:rebuild', ['--date' => '2026-05-29'])->assertSuccessful(); // После rebuild — daily_limit обновлён до live=10. $row = DB::table('project_routing_snapshots') ->where('snapshot_date', '2026-05-29') ->where('tenant_id', $tenant->id) ->first(); expect((int) $row->daily_limit)->toBe(10); Carbon::setTestNow(); });