chore: remove Findings lifecycle backfill operational surface (controls slice)
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 1m38s
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 1m38s
This commit is contained in:
parent
dcf70b6df8
commit
c23383f889
@ -77,9 +77,6 @@ public function getHeader(): ?View
|
|||||||
protected function getHeaderActions(): array
|
protected function getHeaderActions(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
$this->pauseFindingsLifecycleBackfillAction(),
|
|
||||||
$this->resumeFindingsLifecycleBackfillAction(),
|
|
||||||
$this->viewHistoryFindingsLifecycleBackfillAction(),
|
|
||||||
$this->pauseRestoreExecuteAction(),
|
$this->pauseRestoreExecuteAction(),
|
||||||
$this->resumeRestoreExecuteAction(),
|
$this->resumeRestoreExecuteAction(),
|
||||||
$this->viewHistoryRestoreExecuteAction(),
|
$this->viewHistoryRestoreExecuteAction(),
|
||||||
@ -187,21 +184,6 @@ public function scopeImpactPreview(string $controlKey, string $scopeType, ?int $
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function pauseFindingsLifecycleBackfillAction(): Action
|
|
||||||
{
|
|
||||||
return $this->pauseActionFor('findings.lifecycle.backfill');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function resumeFindingsLifecycleBackfillAction(): Action
|
|
||||||
{
|
|
||||||
return $this->resumeActionFor('findings.lifecycle.backfill');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function viewHistoryFindingsLifecycleBackfillAction(): Action
|
|
||||||
{
|
|
||||||
return $this->historyActionFor('findings.lifecycle.backfill');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function pauseRestoreExecuteAction(): Action
|
public function pauseRestoreExecuteAction(): Action
|
||||||
{
|
{
|
||||||
return $this->pauseActionFor('restore.execute');
|
return $this->pauseActionFor('restore.execute');
|
||||||
|
|||||||
@ -10,13 +10,6 @@ final class OperationalControlCatalog
|
|||||||
* @var array<string, array{key: string, label: string, supported_scopes: array<int, string>, operation_types: array<int, string>, affected_surfaces: array<int, string>}>
|
* @var array<string, array{key: string, label: string, supported_scopes: array<int, string>, operation_types: array<int, string>, affected_surfaces: array<int, string>}>
|
||||||
*/
|
*/
|
||||||
private const DEFINITIONS = [
|
private const DEFINITIONS = [
|
||||||
'findings.lifecycle.backfill' => [
|
|
||||||
'key' => 'findings.lifecycle.backfill',
|
|
||||||
'label' => 'Findings lifecycle backfill',
|
|
||||||
'supported_scopes' => ['global', 'workspace'],
|
|
||||||
'operation_types' => ['findings.lifecycle.backfill'],
|
|
||||||
'affected_surfaces' => ['system.ops.runbooks', 'tenant.findings.list'],
|
|
||||||
],
|
|
||||||
'restore.execute' => [
|
'restore.execute' => [
|
||||||
'key' => 'restore.execute',
|
'key' => 'restore.execute',
|
||||||
'label' => 'Restore execution',
|
'label' => 'Restore execution',
|
||||||
|
|||||||
@ -50,27 +50,27 @@ function makeControlsManager(): PlatformUser
|
|||||||
|
|
||||||
$this->get(Controls::getUrl(panel: 'system'))
|
$this->get(Controls::getUrl(panel: 'system'))
|
||||||
->assertSuccessful()
|
->assertSuccessful()
|
||||||
->assertSee("mountAction('pause_findings_lifecycle_backfill')", escape: false)
|
|
||||||
->assertSee("mountAction('view_history_findings_lifecycle_backfill')", escape: false)
|
|
||||||
->assertSee("mountAction('pause_restore_execute')", escape: false)
|
->assertSee("mountAction('pause_restore_execute')", escape: false)
|
||||||
->assertDontSee('Pause Findings lifecycle backfill')
|
->assertDontSee('Findings lifecycle backfill')
|
||||||
->assertDontSee('Resume Findings lifecycle backfill')
|
->assertDontSee("mountAction('pause_findings_lifecycle_backfill')", escape: false)
|
||||||
|
->assertDontSee("mountAction('resume_findings_lifecycle_backfill')", escape: false)
|
||||||
|
->assertDontSee("mountAction('view_history_findings_lifecycle_backfill')", escape: false)
|
||||||
->assertDontSee('Pause Restore execution')
|
->assertDontSee('Pause Restore execution')
|
||||||
->assertDontSee('Resume Restore execution');
|
->assertDontSee('Resume Restore execution');
|
||||||
|
|
||||||
OperationalControlActivation::factory()->forGlobalScope()->create([
|
OperationalControlActivation::factory()->forGlobalScope()->create([
|
||||||
'control_key' => 'findings.lifecycle.backfill',
|
'control_key' => 'restore.execute',
|
||||||
'reason_text' => 'Paused for compact action rendering coverage.',
|
'reason_text' => 'Paused for compact action rendering coverage.',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->get(Controls::getUrl(panel: 'system'))
|
$this->get(Controls::getUrl(panel: 'system'))
|
||||||
->assertSuccessful()
|
->assertSuccessful()
|
||||||
->assertSee("mountAction('resume_findings_lifecycle_backfill')", escape: false)
|
->assertSee("mountAction('resume_restore_execute')", escape: false)
|
||||||
->assertDontSee("mountAction('pause_findings_lifecycle_backfill')", escape: false)
|
->assertDontSee("mountAction('pause_restore_execute')", escape: false)
|
||||||
->assertSee("mountAction('pause_restore_execute')", escape: false);
|
->assertDontSee('Findings lifecycle backfill');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('previews, pauses, updates, resumes, and exposes on-demand history for a global control', function (): void {
|
it('previews, pauses, updates, resumes, and exposes on-demand history for restore execution', function (): void {
|
||||||
$workspaceA = Workspace::factory()->create(['name' => 'Acme']);
|
$workspaceA = Workspace::factory()->create(['name' => 'Acme']);
|
||||||
$workspaceB = Workspace::factory()->create(['name' => 'Bravo']);
|
$workspaceB = Workspace::factory()->create(['name' => 'Bravo']);
|
||||||
|
|
||||||
@ -81,11 +81,11 @@ function makeControlsManager(): PlatformUser
|
|||||||
$this->actingAs($user, 'platform');
|
$this->actingAs($user, 'platform');
|
||||||
|
|
||||||
$component = Livewire::test(Controls::class)
|
$component = Livewire::test(Controls::class)
|
||||||
->assertActionExists('pause_findings_lifecycle_backfill', fn (Action $action): bool => $action->isConfirmationRequired())
|
->assertActionExists('pause_restore_execute', fn (Action $action): bool => $action->isConfirmationRequired())
|
||||||
->assertActionExists('resume_findings_lifecycle_backfill', fn (Action $action): bool => $action->isConfirmationRequired())
|
->assertActionExists('resume_restore_execute', fn (Action $action): bool => $action->isConfirmationRequired())
|
||||||
->assertActionExists('view_history_findings_lifecycle_backfill', fn (Action $action): bool => $action->getLabel() === 'View Findings lifecycle backfill history');
|
->assertActionExists('view_history_restore_execute', fn (Action $action): bool => $action->getLabel() === 'View Restore execution history');
|
||||||
|
|
||||||
$preview = $component->instance()->scopeImpactPreview('findings.lifecycle.backfill', 'global', null);
|
$preview = $component->instance()->scopeImpactPreview('restore.execute', 'global', null);
|
||||||
|
|
||||||
expect($preview['workspace_count'])->toBe(2)
|
expect($preview['workspace_count'])->toBe(2)
|
||||||
->and($preview['tenant_count'])->toBe(3)
|
->and($preview['tenant_count'])->toBe(3)
|
||||||
@ -93,45 +93,45 @@ function makeControlsManager(): PlatformUser
|
|||||||
->and($preview['summary'])->toContain('3 tenants');
|
->and($preview['summary'])->toContain('3 tenants');
|
||||||
|
|
||||||
$component
|
$component
|
||||||
->callAction('pause_findings_lifecycle_backfill', data: [
|
->callAction('pause_restore_execute', data: [
|
||||||
'scope_type' => 'global',
|
'scope_type' => 'global',
|
||||||
'reason_text' => 'Paused for incident review.',
|
'reason_text' => 'Paused for incident review.',
|
||||||
'expires_at' => now()->addDay()->toDateTimeString(),
|
'expires_at' => now()->addDay()->toDateTimeString(),
|
||||||
])
|
])
|
||||||
->assertNotified('Findings lifecycle backfill paused');
|
->assertNotified('Restore execution paused');
|
||||||
|
|
||||||
$activation = OperationalControlActivation::query()
|
$activation = OperationalControlActivation::query()
|
||||||
->forControl('findings.lifecycle.backfill')
|
->forControl('restore.execute')
|
||||||
->forGlobalScope()
|
->forGlobalScope()
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
expect($activation)->not->toBeNull()
|
expect($activation)->not->toBeNull()
|
||||||
->and($activation?->reason_text)->toBe('Paused for incident review.');
|
->and($activation?->reason_text)->toBe('Paused for incident review.');
|
||||||
|
|
||||||
$summary = $component->instance()->controlSummary('findings.lifecycle.backfill');
|
$summary = $component->instance()->controlSummary('restore.execute');
|
||||||
|
|
||||||
expect($summary['effective_state'])->toBe('paused')
|
expect($summary['effective_state'])->toBe('paused')
|
||||||
->and($summary['active_activations'])->toHaveCount(1)
|
->and($summary['active_activations'])->toHaveCount(1)
|
||||||
->and($summary['active_activations'][0]['owner_name'])->toBe($user->name);
|
->and($summary['active_activations'][0]['owner_name'])->toBe($user->name);
|
||||||
|
|
||||||
$component
|
$component
|
||||||
->callAction('pause_findings_lifecycle_backfill', data: [
|
->callAction('pause_restore_execute', data: [
|
||||||
'scope_type' => 'global',
|
'scope_type' => 'global',
|
||||||
'reason_text' => 'Updated incident review scope.',
|
'reason_text' => 'Updated incident review scope.',
|
||||||
'expires_at' => now()->addDays(2)->toDateTimeString(),
|
'expires_at' => now()->addDays(2)->toDateTimeString(),
|
||||||
])
|
])
|
||||||
->assertNotified('Findings lifecycle backfill updated');
|
->assertNotified('Restore execution updated');
|
||||||
|
|
||||||
expect($activation?->fresh()?->reason_text)->toBe('Updated incident review scope.');
|
expect($activation?->fresh()?->reason_text)->toBe('Updated incident review scope.');
|
||||||
|
|
||||||
$component
|
$component
|
||||||
->callAction('resume_findings_lifecycle_backfill', data: [
|
->callAction('resume_restore_execute', data: [
|
||||||
'scope_type' => 'global',
|
'scope_type' => 'global',
|
||||||
])
|
])
|
||||||
->assertNotified('Findings lifecycle backfill resumed');
|
->assertNotified('Restore execution resumed');
|
||||||
|
|
||||||
expect(OperationalControlActivation::query()
|
expect(OperationalControlActivation::query()
|
||||||
->forControl('findings.lifecycle.backfill')
|
->forControl('restore.execute')
|
||||||
->forGlobalScope()
|
->forGlobalScope()
|
||||||
->count())->toBe(0);
|
->count())->toBe(0);
|
||||||
|
|
||||||
@ -141,7 +141,7 @@ function makeControlsManager(): PlatformUser
|
|||||||
AuditActionId::OperationalControlUpdated->value,
|
AuditActionId::OperationalControlUpdated->value,
|
||||||
AuditActionId::OperationalControlResumed->value,
|
AuditActionId::OperationalControlResumed->value,
|
||||||
])
|
])
|
||||||
->where('metadata->control_key', 'findings.lifecycle.backfill')
|
->where('metadata->control_key', 'restore.execute')
|
||||||
->orderBy('id')
|
->orderBy('id')
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
@ -153,8 +153,8 @@ function makeControlsManager(): PlatformUser
|
|||||||
->and($audits[2]->action)->toBe(AuditActionId::OperationalControlResumed->value);
|
->and($audits[2]->action)->toBe(AuditActionId::OperationalControlResumed->value);
|
||||||
|
|
||||||
$component
|
$component
|
||||||
->mountAction('view_history_findings_lifecycle_backfill')
|
->mountAction('view_history_restore_execute')
|
||||||
->assertActionMounted('view_history_findings_lifecycle_backfill');
|
->assertActionMounted('view_history_restore_execute');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('supports workspace-scoped pauses and removes expired conflicting activations before replacement writes', function (): void {
|
it('supports workspace-scoped pauses and removes expired conflicting activations before replacement writes', function (): void {
|
||||||
|
|||||||
@ -4,20 +4,11 @@
|
|||||||
|
|
||||||
use App\Support\OperationalControls\OperationalControlCatalog;
|
use App\Support\OperationalControls\OperationalControlCatalog;
|
||||||
|
|
||||||
it('exposes the bounded first-slice control catalog', function (): void {
|
it('exposes only active runtime controls in the bounded control catalog', function (): void {
|
||||||
$catalog = app(OperationalControlCatalog::class);
|
$catalog = app(OperationalControlCatalog::class);
|
||||||
|
|
||||||
expect($catalog->keys())->toBe([
|
expect($catalog->keys())->toBe(['restore.execute'])
|
||||||
'findings.lifecycle.backfill',
|
->and($catalog->definition('restore.execute'))->toMatchArray([
|
||||||
'restore.execute',
|
|
||||||
]);
|
|
||||||
|
|
||||||
expect($catalog->definition('findings.lifecycle.backfill'))->toMatchArray([
|
|
||||||
'key' => 'findings.lifecycle.backfill',
|
|
||||||
'label' => 'Findings lifecycle backfill',
|
|
||||||
'supported_scopes' => ['global', 'workspace'],
|
|
||||||
'operation_types' => ['findings.lifecycle.backfill'],
|
|
||||||
])->and($catalog->definition('restore.execute'))->toMatchArray([
|
|
||||||
'key' => 'restore.execute',
|
'key' => 'restore.execute',
|
||||||
'label' => 'Restore execution',
|
'label' => 'Restore execution',
|
||||||
'supported_scopes' => ['global', 'workspace'],
|
'supported_scopes' => ['global', 'workspace'],
|
||||||
@ -25,9 +16,11 @@
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('rejects unknown control keys', function (): void {
|
it('rejects removed or unknown control keys', function (): void {
|
||||||
$catalog = app(OperationalControlCatalog::class);
|
$catalog = app(OperationalControlCatalog::class);
|
||||||
|
|
||||||
expect(fn (): array => $catalog->definition('tenant.review.compose'))
|
expect(fn (): array => $catalog->definition('findings.lifecycle.backfill'))
|
||||||
|
->toThrow(\InvalidArgumentException::class)
|
||||||
|
->and(fn (): array => $catalog->definition('tenant.review.compose'))
|
||||||
->toThrow(\InvalidArgumentException::class);
|
->toThrow(\InvalidArgumentException::class);
|
||||||
});
|
});
|
||||||
@ -13,17 +13,17 @@
|
|||||||
$workspace = Workspace::factory()->create();
|
$workspace = Workspace::factory()->create();
|
||||||
|
|
||||||
OperationalControlActivation::factory()->workspaceScoped()->create([
|
OperationalControlActivation::factory()->workspaceScoped()->create([
|
||||||
'control_key' => 'findings.lifecycle.backfill',
|
'control_key' => 'restore.execute',
|
||||||
'workspace_id' => (int) $workspace->getKey(),
|
'workspace_id' => (int) $workspace->getKey(),
|
||||||
'reason_text' => 'Workspace pause.',
|
'reason_text' => 'Workspace pause.',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$globalActivation = OperationalControlActivation::factory()->forGlobalScope()->create([
|
$globalActivation = OperationalControlActivation::factory()->forGlobalScope()->create([
|
||||||
'control_key' => 'findings.lifecycle.backfill',
|
'control_key' => 'restore.execute',
|
||||||
'reason_text' => 'Global incident pause.',
|
'reason_text' => 'Global incident pause.',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$decision = app(OperationalControlEvaluator::class)->evaluate('findings.lifecycle.backfill', $workspace);
|
$decision = app(OperationalControlEvaluator::class)->evaluate('restore.execute', $workspace);
|
||||||
|
|
||||||
expect($decision->isPaused())->toBeTrue()
|
expect($decision->isPaused())->toBeTrue()
|
||||||
->and($decision->matchedScopeType)->toBe('global')
|
->and($decision->matchedScopeType)->toBe('global')
|
||||||
@ -36,18 +36,18 @@
|
|||||||
$workspace = Workspace::factory()->create();
|
$workspace = Workspace::factory()->create();
|
||||||
|
|
||||||
OperationalControlActivation::factory()->forGlobalScope()->create([
|
OperationalControlActivation::factory()->forGlobalScope()->create([
|
||||||
'control_key' => 'findings.lifecycle.backfill',
|
'control_key' => 'restore.execute',
|
||||||
'reason_text' => 'Expired global pause.',
|
'reason_text' => 'Expired global pause.',
|
||||||
'expires_at' => now()->subMinute(),
|
'expires_at' => now()->subMinute(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$workspaceActivation = OperationalControlActivation::factory()->workspaceScoped()->create([
|
$workspaceActivation = OperationalControlActivation::factory()->workspaceScoped()->create([
|
||||||
'control_key' => 'findings.lifecycle.backfill',
|
'control_key' => 'restore.execute',
|
||||||
'workspace_id' => (int) $workspace->getKey(),
|
'workspace_id' => (int) $workspace->getKey(),
|
||||||
'reason_text' => 'Active workspace pause.',
|
'reason_text' => 'Active workspace pause.',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$decision = app(OperationalControlEvaluator::class)->evaluate('findings.lifecycle.backfill', $workspace);
|
$decision = app(OperationalControlEvaluator::class)->evaluate('restore.execute', $workspace);
|
||||||
|
|
||||||
expect($decision->isPaused())->toBeTrue()
|
expect($decision->isPaused())->toBeTrue()
|
||||||
->and($decision->matchedScopeType)->toBe('workspace')
|
->and($decision->matchedScopeType)->toBe('workspace')
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user