create([ 'tenant_id' => null, 'external_id' => 'platform', ]); }); it('hides triage actions for operators without platform.operations.manage', function () { $run = OperationRun::factory()->create([ 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Failed->value, 'type' => 'inventory_sync', ]); $viewOnlyUser = PlatformUser::factory()->create([ 'capabilities' => [ PlatformCapabilities::ACCESS_SYSTEM_PANEL, PlatformCapabilities::OPERATIONS_VIEW, ], 'is_active' => true, ]); $this->actingAs($viewOnlyUser, 'platform'); Livewire::test(Runs::class) ->assertTableActionHidden('retry', $run) ->assertTableActionHidden('cancel', $run) ->assertTableActionHidden('mark_investigated', $run); }); it('allows manage operators to run triage actions with audit logs and queued-run ux contract', function () { NotificationFacade::fake(); $failedRun = OperationRun::factory()->create([ 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Failed->value, 'type' => 'inventory_sync', ]); $manageUser = PlatformUser::factory()->create([ 'capabilities' => [ PlatformCapabilities::ACCESS_SYSTEM_PANEL, PlatformCapabilities::OPERATIONS_VIEW, PlatformCapabilities::OPERATIONS_MANAGE, ], 'is_active' => true, ]); $this->actingAs($manageUser, 'platform'); Livewire::test(Runs::class) ->callTableAction('retry', $failedRun) ->assertHasNoTableActionErrors() ->assertNotified('Inventory sync queued'); NotificationFacade::assertNothingSent(); expect(DatabaseNotification::query()->count())->toBe(0); $retriedRun = OperationRun::query() ->whereKeyNot((int) $failedRun->getKey()) ->latest('id') ->first(); expect($retriedRun)->not->toBeNull(); expect((string) $retriedRun?->status)->toBe(OperationRunStatus::Queued->value); expect((int) data_get($retriedRun?->context, 'triage.retry_of_run_id'))->toBe((int) $failedRun->getKey()); $this->get(SystemOperationRunLinks::view($retriedRun)) ->assertSuccessful() ->assertSee('Run #'.(int) $retriedRun?->getKey()); Livewire::test(Runs::class) ->callTableAction('mark_investigated', $failedRun, data: [ 'reason' => 'Checked by platform operations', ]) ->assertHasNoTableActionErrors(); expect(AuditLog::query()->where('action', 'platform.system_console.retry')->exists())->toBeTrue(); expect(AuditLog::query()->where('action', 'platform.system_console.mark_investigated')->exists())->toBeTrue(); });