53 lines
4.5 KiB
PHP
53 lines
4.5 KiB
PHP
<?php
|
|
|
|
// Reproduce the existing membership scope in QA only; discard all fixtures afterwards.
|
|
ini_set('zend.exception_ignore_args', '1');
|
|
$root = dirname(__DIR__);
|
|
$private = $root.'/storage/app/private/investmoz-v2/portal-audit';
|
|
$plan = json_decode(file_get_contents($private.'/onboarding-governance-plan.json'),true,512,JSON_THROW_ON_ERROR);
|
|
$stage = realpath($plan['source']);
|
|
if (!($stage && str_starts_with(strtolower($stage),strtolower(realpath($private).DIRECTORY_SEPARATOR)) && $plan['target']['port']===55441)) {
|
|
throw new RuntimeException('Separate QA source required.');
|
|
}
|
|
require $stage.'/qa-autoload.php';
|
|
$app = require $stage.'/bootstrap/app.php';
|
|
(new Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables)->bootstrap($app);
|
|
(new Illuminate\Foundation\Bootstrap\LoadConfiguration)->bootstrap($app);
|
|
$c=config('database.connections.'.config('database.default'));
|
|
throw_unless(config('app.env')==='testing' && $c['driver']==='pgsql' && empty($c['url']) && (int)$c['port']===55441 && $c['database']===$plan['target']['database'] && str_ends_with($c['database'],'_test') && config('mail.default')==='array',RuntimeException::class,'QA environment refused.');
|
|
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
|
|
throw_unless(str_starts_with((new ReflectionClass(App\Services\PortalProfileAccess::class))->getFileName(),$stage),RuntimeException::class,'Active classes refused.');
|
|
$identity=DB::selectOne('SELECT current_database() AS database,inet_server_port() AS port');
|
|
throw_unless((int)$identity->port===55441 && $identity->database===$plan['target']['database'],RuntimeException::class,'QA database refused.');
|
|
DB::beginTransaction();
|
|
try {
|
|
$before=[];foreach(['users','organizations','memberships'] as $t)$before[$t]=DB::table($t)->count();
|
|
$actor=App\Models\User::factory()->create();
|
|
$organization=(string)Illuminate\Support\Str::uuid();
|
|
DB::table('organizations')->insert(['id'=>$organization,'name'=>'Synthetic portal business scope QA','organization_type'=>'private']);
|
|
$membership=(string)Illuminate\Support\Str::uuid();
|
|
DB::table('memberships')->insert(['id'=>$membership,'user_id'=>$actor->id,'organization_id'=>$organization,'role'=>'officer']);
|
|
$access=app(App\Services\PortalProfileAccess::class);
|
|
$country=app(App\Services\OrganizationCountry::class);
|
|
$desk=app(App\Services\VirtualDesk::class);
|
|
$proof=['at'=>gmdate('c'),'target'=>$identity,'QA_only'=>true,'source'=>'User clarification: Aurora acts within portal business, not company management',
|
|
'requested_scope'=>'promoter_portal_business_only','synthetic_fixtures'=>true,'active_writes'=>0,'real_organization_or_accounts_created'=>false];
|
|
foreach(['officer','viewer'] as $role){
|
|
DB::table('memberships')->where('id',$membership)->update(['role'=>$role]);
|
|
$allowed=true;
|
|
try{$country->authorize($actor,$organization,true);}catch(Symfony\Component\HttpKernel\Exception\HttpException $e){throw_unless($e->getStatusCode()===403,RuntimeException::class);$allowed=false;}
|
|
$proof['existing_roles'][$role]=['promoter_representation_allowed'=>$access->represents($actor,$organization),
|
|
'master_country_write_authorized'=>$allowed,'organizational_desk_write_authorized'=>$desk->represents($actor,$organization,true),
|
|
'opportunity_operational_flag'=>(bool)config('portal.profile_access_enabled')];
|
|
}
|
|
throw_unless($proof['existing_roles']['officer']['promoter_representation_allowed'] && $proof['existing_roles']['officer']['master_country_write_authorized']
|
|
&& $proof['existing_roles']['officer']['organizational_desk_write_authorized'] && !$proof['existing_roles']['viewer']['promoter_representation_allowed'],RuntimeException::class,'Existing behavior differs; review required.');
|
|
DB::rollBack();
|
|
foreach($before as $t=>$n)throw_unless(DB::table($t)->count()===$n,RuntimeException::class,'QA fixture not rolled back.');
|
|
$proof['QA_fixtures_rolled_back']=true;
|
|
$proof['result']='existing_scope_coupling_demonstrated_not_corrected';
|
|
$proof['correction_required']='Distinguish portal-business representation and employment from company master/general dossier write; do not assign officer/manager/admin as a shortcut.';
|
|
file_put_contents($private.'/tempo-scope-diagnosis-qa.json',json_encode($proof,JSON_PRETTY_PRINT|JSON_THROW_ON_ERROR));
|
|
echo json_encode($proof,JSON_THROW_ON_ERROR).PHP_EOL;
|
|
} catch(Throwable $e){if(DB::transactionLevel()>0)DB::rollBack();fwrite(STDERR,'QA diagnosis incomplete; no active writes; '.$e::class);exit(1);}
|