commit13
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Tenant;
|
||||
use App\Models\User;
|
||||
use App\Services\OrganizationAccess;
|
||||
use App\Services\WorkContext;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class SgcDeliveryCheck extends Command
|
||||
{
|
||||
protected $signature = 'sgc:delivery-check {tenant : ID da empresa}';
|
||||
|
||||
protected $description = 'Conferir configuração e ausência de dados de desenvolvimento antes da entrega; não altera dados';
|
||||
|
||||
public function handle(WorkContext $contexts): int
|
||||
{
|
||||
$tenant = Tenant::query()->find($this->argument('tenant'));
|
||||
if ($tenant === null || ! Schema::hasColumn('tenants', 'work_context_policy')) {
|
||||
$this->error('Empresa inexistente ou instalação do contexto pendente.');
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
$users = User::query()->where('tenant_id', $tenant->id)->get();
|
||||
$actor = $users->first();
|
||||
if ($actor === null || $contexts->policy($actor) === null || $contexts->purchased($actor) === [] || ! app(OrganizationAccess::class)->active($tenant->id)) {
|
||||
$this->error('Defina produto contratado, opções e administração da empresa antes da entrega.');
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
$administrators = 0;
|
||||
foreach ($users as $user) {
|
||||
$profiles = DB::table('organization_memberships as m')->join('organization_profiles as p', 'p.id', '=', 'm.profile_id')
|
||||
->where('m.tenant_id', $tenant->id)->where('p.tenant_id', $tenant->id)->where('m.user_id', $user->id)
|
||||
->where('m.maintenance', false)->whereNull('m.expires_at')->pluck('p.permissions');
|
||||
if ($profiles->contains(fn ($json) => in_array('admin', json_decode($json, true, 32, JSON_THROW_ON_ERROR), true))) {
|
||||
$administrators++;
|
||||
}
|
||||
}
|
||||
$clean = true;
|
||||
foreach (Schema::getTables() as $table) {
|
||||
$name = $table['name'];
|
||||
if (in_array($name, ['users', 'departments', 'cost_centers', 'organization_profiles', 'organization_memberships', 'organization_access', 'audit_logs'], true)) {
|
||||
continue;
|
||||
}
|
||||
if (Schema::hasColumn($name, 'tenant_id') && DB::table($name)->where('tenant_id', $tenant->id)->exists()) {
|
||||
$this->error('Existem registos a reconciliar antes da entrega: '.$name);
|
||||
$clean = false;
|
||||
}
|
||||
}
|
||||
$enabled = $contexts->policy($actor)['enabled'] ?? [];
|
||||
if ($administrators < 2 || $enabled === [] || array_diff($enabled, $contexts->purchased($actor)) !== []) {
|
||||
$this->error('Confira dois administradores permanentes e opções activadas dentro do produto contratado.');
|
||||
$clean = false;
|
||||
}
|
||||
foreach ($enabled as $key) {
|
||||
if (! (WorkContext::OPTIONS[$key]['operational'] ?? false)) {
|
||||
$this->error('Percurso operacional ainda pendente: '.$key);
|
||||
$clean = false;
|
||||
}
|
||||
if (! $users->contains(fn ($user) => in_array($key, $contexts->available($user), true))) {
|
||||
$this->error('Opção sem utilizador com perfil/contexto autorizado: '.$key);
|
||||
$clean = false;
|
||||
}
|
||||
}
|
||||
if ($clean) {
|
||||
$this->info('Conferência técnica aprovada. Não substitui aceitação funcional, revisão dos cadastros de configuração ou instalação de RH.');
|
||||
}
|
||||
|
||||
return $clean ? self::SUCCESS : self::FAILURE;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user