## Summary - replace the legacy Tenant and TenantMembership core models with ManagedEnvironment and ManagedEnvironmentMembership - propagate the managed environment naming and key changes across Filament resources, pages, controllers, jobs, models, and supporting runtime paths - add feature 279 spec artifacts and focused managed-environment test coverage for model behavior, route binding, panel context, authorization, and legacy guardrails ## Validation - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ManagedEnvironment/LegacyTenantCoreGuardTest.php tests/Feature/ManagedEnvironment/ManagedEnvironmentAuthorizationTest.php tests/Feature/ManagedEnvironment/ManagedEnvironmentPanelContextTest.php tests/Feature/ManagedEnvironment/ManagedEnvironmentRouteBindingTest.php tests/Unit/ManagedEnvironment/ManagedEnvironmentContextResolverTest.php tests/Unit/ManagedEnvironment/ManagedEnvironmentModelTest.php` - `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` ## Notes - branch pushed from commit `1123b122` - browser smoke test file was added but not run in this pass Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #335
106 lines
3.6 KiB
PHP
106 lines
3.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Models\ManagedEnvironment;
|
|
use App\Services\Operations\OperationLifecycleReconciler;
|
|
use App\Support\Operations\OperationLifecyclePolicy;
|
|
use Illuminate\Console\Command;
|
|
|
|
class TenantpilotReconcileOperationRuns extends Command
|
|
{
|
|
protected $signature = 'tenantpilot:operation-runs:reconcile
|
|
{--type=* : Limit reconciliation to one or more covered operation types}
|
|
{--tenant=* : Limit reconciliation to managed_environment_id or tenant external_id}
|
|
{--workspace=* : Limit reconciliation to workspace ids}
|
|
{--limit=100 : Maximum number of active runs to inspect}
|
|
{--dry-run : Report the changes without writing them}';
|
|
|
|
protected $description = 'Reconcile stale covered operation runs back to deterministic terminal truth.';
|
|
|
|
public function handle(
|
|
OperationLifecycleReconciler $reconciler,
|
|
OperationLifecyclePolicy $policy,
|
|
): int {
|
|
$types = array_values(array_filter(
|
|
(array) $this->option('type'),
|
|
static fn (mixed $type): bool => is_string($type) && trim($type) !== '',
|
|
));
|
|
$workspaceIds = array_values(array_filter(
|
|
array_map(
|
|
static fn (mixed $workspaceId): int => is_numeric($workspaceId) ? (int) $workspaceId : 0,
|
|
(array) $this->option('workspace'),
|
|
),
|
|
static fn (int $workspaceId): bool => $workspaceId > 0,
|
|
));
|
|
$tenantIds = $this->resolveTenantIds(array_values(array_filter((array) $this->option('tenant'))));
|
|
$dryRun = (bool) $this->option('dry-run');
|
|
|
|
if ($types === []) {
|
|
$types = $policy->coveredTypeNames();
|
|
}
|
|
|
|
$result = $reconciler->reconcile([
|
|
'types' => $types,
|
|
'tenant_ids' => $tenantIds,
|
|
'workspace_ids' => $workspaceIds,
|
|
'limit' => max(1, (int) $this->option('limit')),
|
|
'dry_run' => $dryRun,
|
|
]);
|
|
|
|
$rows = collect($result['changes'] ?? [])
|
|
->map(static function (array $change): array {
|
|
return [
|
|
'Run' => (string) ($change['operation_run_id'] ?? '—'),
|
|
'Type' => (string) ($change['type'] ?? '—'),
|
|
'Reason' => (string) ($change['reason_code'] ?? '—'),
|
|
'Applied' => (($change['applied'] ?? false) === true) ? 'yes' : 'no',
|
|
];
|
|
})
|
|
->values()
|
|
->all();
|
|
|
|
if ($rows !== []) {
|
|
$this->table(['Run', 'Type', 'Reason', 'Applied'], $rows);
|
|
}
|
|
|
|
$this->info(sprintf(
|
|
'Inspected %d run(s); reconciled %d; skipped %d.',
|
|
(int) ($result['candidates'] ?? 0),
|
|
(int) ($result['reconciled'] ?? 0),
|
|
(int) ($result['skipped'] ?? 0),
|
|
));
|
|
|
|
if ($dryRun) {
|
|
$this->comment('Dry-run: no changes written.');
|
|
}
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @param array<int, string> $tenantIdentifiers
|
|
* @return array<int, int>
|
|
*/
|
|
private function resolveTenantIds(array $tenantIdentifiers): array
|
|
{
|
|
if ($tenantIdentifiers === []) {
|
|
return [];
|
|
}
|
|
|
|
$tenantIds = [];
|
|
|
|
foreach ($tenantIdentifiers as $identifier) {
|
|
$tenant = ManagedEnvironment::query()->forTenant($identifier)->first();
|
|
|
|
if ($tenant instanceof ManagedEnvironment) {
|
|
$tenantIds[] = (int) $tenant->getKey();
|
|
}
|
|
}
|
|
|
|
return array_values(array_unique($tenantIds));
|
|
}
|
|
}
|