@@ -53,6 +53,7 @@ class InterestRequestController extends Controller
|
||||
'phone' => $validated['phone'] ?? null,
|
||||
'investor_type' => $validated['investorType'],
|
||||
'country' => $validated['country'],
|
||||
'metadata' => ['declared_origin_country_code' => $validated['declared_origin_country_code'] ?? null],
|
||||
'sector_interest' => $validated['sectorInterest'],
|
||||
'opportunity_reference' => $validated['opportunityReference'] ?? null,
|
||||
'investment_range' => $validated['investmentRange'] ?? null,
|
||||
|
||||
@@ -3,19 +3,25 @@
|
||||
namespace App\Http\Controllers\Api\V1;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Services\CountryCatalogue;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class ReferenceCatalogController extends Controller
|
||||
{
|
||||
private const CATALOGS = ['authorities', 'jurisdictions', 'economic-activities'];
|
||||
private const CATALOGS = ['authorities', 'jurisdictions', 'economic-activities', 'countries'];
|
||||
|
||||
public function index(Request $request, string $catalog): JsonResponse
|
||||
{
|
||||
$catalog = $this->validatedCatalog($catalog);
|
||||
if ($catalog === 'countries') {
|
||||
return $this->countries($request);
|
||||
}
|
||||
|
||||
$rules = [
|
||||
'q' => ['nullable', 'string', 'max:100'],
|
||||
@@ -89,6 +95,21 @@ class ReferenceCatalogController extends Controller
|
||||
->header('ETag', 'W/"catalog-'.substr(hash('sha256', $catalog.'|'.$version->version_no.'|'.json_encode($data, JSON_THROW_ON_ERROR)), 0, 32).'"');
|
||||
}
|
||||
|
||||
private function countries(Request $request): JsonResponse
|
||||
{
|
||||
$data = $request->validate(['q' => 'nullable|string|max:100', 'page' => 'nullable|integer|min:1', 'per_page' => 'nullable|integer|min:1|max:100', 'parent_id' => 'prohibited', 'version' => 'prohibited']);
|
||||
$term = strtolower(Str::ascii(trim($data['q'] ?? '')));
|
||||
$items = collect(app(CountryCatalogue::class)->all())
|
||||
->filter(fn (array $country) => $term === '' || str_contains(strtolower(Str::ascii(implode(' ', $country))), $term))
|
||||
->values()->map(fn (array $country) => ['id' => $country['code'], 'value' => $country['code'], 'code' => $country['code'], 'name' => $country['name'], 'label' => $country['name']]);
|
||||
$page = (int) ($data['page'] ?? 1);
|
||||
$perPage = (int) ($data['per_page'] ?? 50);
|
||||
$result = new LengthAwarePaginator($items->forPage($page, $perPage)->values(), $items->count(), $perPage, $page, ['path' => $request->url(), 'query' => $request->query()]);
|
||||
|
||||
return response()->json([...$result->toArray(), 'meta' => ['catalog' => 'countries', 'source' => 'Local ISO 3166 catalogue', 'sha256' => hash_file('sha256', resource_path('data/iso3166.tab'))]])
|
||||
->header('Cache-Control', 'public, max-age=300');
|
||||
}
|
||||
|
||||
/** @param array<string,mixed> $data */
|
||||
private function authorities(string $versionId, array $data): Builder
|
||||
{
|
||||
@@ -171,7 +192,7 @@ class ReferenceCatalogController extends Controller
|
||||
});
|
||||
}
|
||||
|
||||
/** @return 'authorities'|'jurisdictions'|'economic-activities' */
|
||||
/** @return 'authorities'|'jurisdictions'|'economic-activities'|'countries' */
|
||||
private function validatedCatalog(string $catalog): string
|
||||
{
|
||||
abort_unless(in_array($catalog, self::CATALOGS, true), 404);
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Http\Controllers;
|
||||
use App\Models\InterestRequest;
|
||||
use App\Models\Opportunity;
|
||||
use App\Models\Sector;
|
||||
use App\Services\InvestorPath;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
@@ -14,7 +15,16 @@ class DashboardController extends Controller
|
||||
public function __invoke(Request $request): Response
|
||||
{
|
||||
if (! $request->user()->can('manage-portal')) {
|
||||
return Inertia::render('dashboard', ['summary' => null]);
|
||||
$path = app(InvestorPath::class);
|
||||
$contexts = $path->contexts($request->user());
|
||||
$current = $contexts ? $path->view($request->user(), $contexts[0]['id']) : null;
|
||||
|
||||
return Inertia::render('dashboard', ['summary' => null, 'investorPath' => $path->available() ? [
|
||||
'contexts' => $contexts,
|
||||
'current' => $current ? ['id' => $current['case']['id'], 'next' => $current['next'],
|
||||
'pending' => count(array_filter($current['steps'], fn ($step) => ! in_array($step['state'], ['completed', 'approved', 'dispensed'], true))),
|
||||
'documents' => count($current['documents']), 'results' => count($current['results']), 'tasks' => count($current['tasks'])] : null,
|
||||
] : null]);
|
||||
}
|
||||
|
||||
$counts = InterestRequest::query()->selectRaw('status, count(*) as total')
|
||||
|
||||
@@ -6,6 +6,7 @@ use App\Models\ExistingBusiness;
|
||||
use App\Models\ExistingBusinessObject;
|
||||
use App\Models\Sector;
|
||||
use App\Services\BusinessFormSchema;
|
||||
use App\Services\CountryCatalogue;
|
||||
use App\Services\ExistingBusinessDrafts;
|
||||
use App\Services\ExistingBusinessIntake;
|
||||
use App\Services\ExistingBusinessObjects;
|
||||
@@ -15,9 +16,11 @@ use App\Services\Mne\BusinessRepository;
|
||||
use App\Services\Mne\CompatibilityShadow;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
@@ -35,7 +38,23 @@ class ExistingBusinessController extends Controller
|
||||
} else {
|
||||
$query->where('owner_user_id', $request->user()->id);
|
||||
}
|
||||
$props = ['records' => $query->orderByDesc('updated_at')->paginate(20)->through(fn ($row) => $this->record($row)),
|
||||
$filters = $request->validate(['country' => ['nullable', app(CountryCatalogue::class)->rule()], 'origin' => ['nullable', Rule::in([...array_column(app(CountryCatalogue::class)->all(), 'code'), 'unknown'])], 'page' => ['nullable', 'integer', 'min:1']]);
|
||||
$query->orderByDesc('updated_at');
|
||||
if (! empty($filters['country']) || ! empty($filters['origin'])) {
|
||||
// The private payload is encrypted: filter only the already-authorized collection.
|
||||
$matches = $query->get()->filter(function ($business) use ($filters) {
|
||||
$payload = $business->payload;
|
||||
$origin = $payload['declared_origin_country_code'] ?? null;
|
||||
$validOrigin = in_array($origin, array_column(app(CountryCatalogue::class)->all(), 'code'), true) ? $origin : 'unknown';
|
||||
|
||||
return (empty($filters['country']) || ($payload['country'] ?? null) === $filters['country']) && (empty($filters['origin']) || $validOrigin === $filters['origin']);
|
||||
})->values();
|
||||
$page = (int) ($filters['page'] ?? 1);
|
||||
$records = new LengthAwarePaginator($matches->forPage($page, 20)->values(), $matches->count(), 20, $page, ['path' => $request->url(), 'query' => $request->query()]);
|
||||
} else {
|
||||
$records = $query->paginate(20)->withQueryString();
|
||||
}
|
||||
$props = ['records' => $records->through(fn ($row) => $this->record($row)), 'filters' => $filters, 'countries' => app(CountryCatalogue::class)->all(),
|
||||
'management' => $management, 'modalities' => ExistingBusinessDrafts::MODALITIES];
|
||||
|
||||
return $request->expectsJson() ? response()->json($props) : Inertia::render('investment/businesses', $props);
|
||||
@@ -46,7 +65,7 @@ class ExistingBusinessController extends Controller
|
||||
$business = app(BusinessRepository::class)->find($id);
|
||||
Gate::authorize('view', $business);
|
||||
app(CompatibilityShadow::class)->schedule($id);
|
||||
$props = ['sectors' => Sector::where('is_active', true)->orderBy('name')->get(['id', 'name']), 'formSchema' => BusinessFormSchema::fields(), 'record' => $this->record($business), 'canEdit' => $request->user()->can('update', $business),
|
||||
$props = ['countries' => app(CountryCatalogue::class)->all(), 'sectors' => Sector::where('is_active', true)->orderBy('name')->get(['id', 'name']), 'formSchema' => BusinessFormSchema::fields(), 'record' => $this->record($business), 'canEdit' => $request->user()->can('update', $business),
|
||||
'owner' => $request->user()->can('owns', $business), 'canReview' => $request->user()->can('review', $business),
|
||||
'canTriage' => $request->user()->can('triage', $business),
|
||||
'canApproveLevelOne' => $request->user()->can('approveLevelOne', $business),
|
||||
|
||||
@@ -10,6 +10,7 @@ use App\Services\InvestmentZones;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
@@ -130,7 +131,7 @@ class InvestmentDiscoveryController extends Controller
|
||||
{
|
||||
$filters = $catalogue->filters($request);
|
||||
$context = $this->territorial($filters)->map(fn ($d) => ['id' => 'dossier:'.$d->id, 'title' => $d->title, 'kind' => $d->cluster_id ? 'Cluster' : ($d->corridor_id ? 'Corredor' : 'Projeto âncora'), 'url' => '/carteira/'.$d->id]);
|
||||
$opportunityOnlyFilters = array_filter(\Illuminate\Support\Arr::only($filters, ['education', 'sector', 'facets', 'project_id', 'cluster_id', 'corridor_id', 'min_amount', 'max_amount', 'currency', 'before', 'maturity_level']), fn ($value) => $value !== null && $value !== '' && $value !== false && $value !== []);
|
||||
$opportunityOnlyFilters = array_filter(Arr::only($filters, ['education', 'sector', 'facets', 'project_id', 'cluster_id', 'corridor_id', 'min_amount', 'max_amount', 'currency', 'before', 'maturity_level']), fn ($value) => $value !== null && $value !== '' && $value !== false && $value !== []);
|
||||
if ($opportunityOnlyFilters === [] && ! in_array($filters['dimension'] ?? null, ['cluster', 'corridor'], true)) {
|
||||
$zoneFilters = $filters;
|
||||
if (in_array($filters['dimension'] ?? null, ['zee', 'zfi'], true)) {
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Models\InterestRequest;
|
||||
use App\Models\InvestmentSpecificNeed;
|
||||
use App\Models\InvestmentSubmission;
|
||||
use App\Models\Opportunity;
|
||||
use App\Services\CountryCatalogue;
|
||||
use App\Services\InterestSubmission;
|
||||
use App\Services\InvestmentCatalogue;
|
||||
use App\Services\InvestmentWorkspace;
|
||||
@@ -111,7 +112,7 @@ class InvestmentSubmissionController extends Controller
|
||||
$target = $row->opportunity_id ? Opportunity::published()->find($row->opportunity_id) : null;
|
||||
$dossier = $row->dossier_id ? InvestmentPortfolioController::visible()->find($row->dossier_id) : null;
|
||||
$zoneOrigin = DB::table('investment_submission_zones')->where('submission_id', $id)->first(['zone_id', 'zone_version', 'intent']);
|
||||
$data = ['countries' => app(\App\Services\CountryCatalogue::class)->all(), 'submission' => $row->only(['id', 'payload', 'version', 'status', 'opportunity_id', 'dossier_id']), 'zone_origin' => $zoneOrigin,
|
||||
$data = ['countries' => app(CountryCatalogue::class)->all(), 'submission' => $row->only(['id', 'payload', 'version', 'status', 'opportunity_id', 'dossier_id']), 'zone_origin' => $zoneOrigin,
|
||||
'target' => ($target ? $target->title : null) ?? ($dossier ? $dossier->title : null), 'references' => [
|
||||
...$catalogue->references(), 'options' => DB::table('investment_reference_options')->orderBy('label')->get()],
|
||||
'needs' => InvestmentSpecificNeed::where('submission_id', $id)->get(),
|
||||
@@ -145,9 +146,9 @@ class InvestmentSubmissionController extends Controller
|
||||
$required = $submitting ? 'required' : 'nullable';
|
||||
$data = $request->validate(['version' => ['required', 'integer', 'min:1'],
|
||||
'payload' => ['required', 'array:full_name,email,phone,country,residence_country_code,incorporation_country_code,declared_origin_country_code,organisation,representative_role,experience,investment_capacity,profile_id,sector,objective,participation_id,partnership_id,estimated_amount,currency,horizon,location,cluster_ids,corridor_ids,project_ids,contact_consent,other_details'],
|
||||
'payload.residence_country_code' => ['nullable', 'string', app(\App\Services\CountryCatalogue::class)->rule()],
|
||||
'payload.incorporation_country_code' => ['nullable', 'string', app(\App\Services\CountryCatalogue::class)->rule()],
|
||||
'payload.declared_origin_country_code' => ['nullable', 'string', app(\App\Services\CountryCatalogue::class)->rule()],
|
||||
'payload.residence_country_code' => ['nullable', 'string', app(CountryCatalogue::class)->rule()],
|
||||
'payload.incorporation_country_code' => ['nullable', 'string', app(CountryCatalogue::class)->rule()],
|
||||
'payload.declared_origin_country_code' => ['nullable', 'string', app(CountryCatalogue::class)->rule()],
|
||||
'payload.other_details' => ['nullable', 'string', 'max:5000'],
|
||||
'payload.full_name' => [$required, 'string', ...($submitting ? ['min:3'] : []), 'max:150'], 'payload.email' => [$required, $submitting ? 'email:rfc' : 'string', 'max:150'],
|
||||
'payload.phone' => ['nullable', 'string', 'max:30'], 'payload.country' => [$submitting ? 'required_without:payload.declared_origin_country_code' : 'nullable', 'nullable', 'string', 'max:100'],
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Services\InvestmentZones;
|
||||
use App\Services\TerritoryGeometry;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@@ -10,6 +11,17 @@ use Illuminate\Validation\ValidationException;
|
||||
|
||||
class InvestmentTerritoryController extends Controller
|
||||
{
|
||||
public function geometries(Request $request): JsonResponse
|
||||
{
|
||||
$data = $request->validate(['territory_id' => ['required', 'uuid']]);
|
||||
$management = $request->is('management/*');
|
||||
if ($management) {
|
||||
abort_unless($request->user()?->can('manage-portal'), 403);
|
||||
}
|
||||
|
||||
return response()->json(app(TerritoryGeometry::class)->context($data['territory_id'], $management));
|
||||
}
|
||||
|
||||
private const TABLES = ['opportunities' => 'opportunities', 'projects' => 'projects', 'clusters' => 'economic_clusters', 'corridors' => 'development_corridors', 'zones' => 'investment_zones'];
|
||||
|
||||
public function subjects(Request $request): JsonResponse
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\InvestmentSubmission;
|
||||
use App\Models\User;
|
||||
use App\Services\CountryCatalogue;
|
||||
use App\Services\InvestmentWorkspace;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
@@ -18,7 +19,7 @@ class InvestmentWorkspaceController extends Controller
|
||||
{
|
||||
public function profile(Request $request, InvestmentWorkspace $workspace): Response|JsonResponse
|
||||
{
|
||||
$data = ['countries' => app(\App\Services\CountryCatalogue::class)->all(), 'account' => $workspace->account($request->user()->id), 'companies' => DB::table('investment_company_declarations')
|
||||
$data = ['countries' => app(CountryCatalogue::class)->all(), 'account' => $workspace->account($request->user()->id), 'companies' => DB::table('investment_company_declarations')
|
||||
->where('user_id', $request->user()->id)->orderByDesc('created_at')->get(['id', 'version', 'payload'])->map(function ($company) {
|
||||
$company->payload = json_decode(Crypt::decryptString($company->payload), true, 512, JSON_THROW_ON_ERROR);
|
||||
|
||||
@@ -32,7 +33,7 @@ class InvestmentWorkspaceController extends Controller
|
||||
{
|
||||
$data = $request->validate(['version' => ['required', 'integer', 'min:0'],
|
||||
'payload' => ['required', 'array:phone,country,residence_country_code,sector,experience,investment_capacity'],
|
||||
'payload.residence_country_code' => ['nullable', 'string', app(\App\Services\CountryCatalogue::class)->rule()],
|
||||
'payload.residence_country_code' => ['nullable', 'string', app(CountryCatalogue::class)->rule()],
|
||||
'payload.phone' => ['nullable', 'string', 'max:30'], 'payload.country' => ['nullable', 'string', 'max:100'],
|
||||
'payload.sector' => ['nullable', 'string', 'max:150'], 'payload.experience' => ['nullable', 'string', 'max:2000'],
|
||||
'payload.investment_capacity' => ['nullable', 'string', 'max:1000']]);
|
||||
@@ -55,7 +56,7 @@ class InvestmentWorkspaceController extends Controller
|
||||
{
|
||||
$data = $request->validate(['version' => ['required', 'integer', 'min:0'],
|
||||
'payload' => ['required', 'array:name,country,incorporation_country_code,registration,sector,role,description'],
|
||||
'payload.incorporation_country_code' => ['nullable', 'string', app(\App\Services\CountryCatalogue::class)->rule()],
|
||||
'payload.incorporation_country_code' => ['nullable', 'string', app(CountryCatalogue::class)->rule()],
|
||||
'payload.name' => ['required', 'string', 'min:2', 'max:200'], 'payload.country' => ['required_without:payload.incorporation_country_code', 'nullable', 'string', 'max:100'],
|
||||
'payload.registration' => ['nullable', 'string', 'max:100'], 'payload.sector' => ['nullable', 'string', 'max:150'],
|
||||
'payload.role' => ['required', 'string', 'max:150'], 'payload.description' => ['nullable', 'string', 'max:2000']]);
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Services\Ai\EvidenceRepository;
|
||||
use App\Services\Ai\InvestorGuidance;
|
||||
use App\Services\InvestorPath;
|
||||
use App\Services\VirtualDesk;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
@@ -18,7 +19,10 @@ class InvestorGuidanceController extends Controller
|
||||
$actor = $request->user();
|
||||
$organizations = DB::table('memberships')->where('user_id', $actor->id)->whereNull('deleted_at')->pluck('organization_id');
|
||||
$cases = DB::table('desk_cases')->whereNull('closed_at')->where(fn ($q) => $q->where(fn ($p) => $p->where('user_id', $actor->id)->whereNull('organization_id'))->orWhereIn('organization_id', $organizations))
|
||||
->orderByDesc('updated_at')->get(['id', 'title']);
|
||||
->orderByDesc('updated_at')->get(['id', 'title', 'journey_id'])->map(function ($case) {
|
||||
return ['id' => $case->id, 'title' => $case->title, 'path_supported' => app(InvestorPath::class)->available()
|
||||
&& $case->journey_id && DB::table('investor_journeys')->where('id', $case->journey_id)->whereNotNull('path_definition_id')->exists()];
|
||||
});
|
||||
|
||||
return response()->json(['cases' => $cases]);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Services\InvestorPath;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
class InvestorPathController extends Controller
|
||||
{
|
||||
public function index(Request $request, InvestorPath $path): JsonResponse|Response
|
||||
{
|
||||
abort_unless($path->available(), 404);
|
||||
$data = ['contexts' => $path->contexts($request->user())];
|
||||
|
||||
return $request->expectsJson() ? response()->json($data) : Inertia::render('investor-path/index', $data);
|
||||
}
|
||||
|
||||
public function create(Request $request, InvestorPath $path): JsonResponse|RedirectResponse
|
||||
{
|
||||
$id = $path->create($request->user(), $request->all());
|
||||
|
||||
return $request->expectsJson() ? response()->json(['id' => $id], 201) : redirect('/investimentos/'.$id)->with('success', 'Investimento guardado no seu dossier.');
|
||||
}
|
||||
|
||||
public function show(Request $request, string $id, InvestorPath $path): JsonResponse|Response
|
||||
{
|
||||
$data = $path->view($request->user(), $id);
|
||||
|
||||
return $request->expectsJson() ? response()->json($data) : Inertia::render('investor-path/show', $data);
|
||||
}
|
||||
|
||||
public function facts(Request $request, string $id, InvestorPath $path): JsonResponse|RedirectResponse
|
||||
{
|
||||
abort_unless($path->available(), 404);
|
||||
$path->facts($request->user(), $id, $request->all());
|
||||
|
||||
return $this->saved($request, 'Aplicabilidade registada; o histórico foi preservado.');
|
||||
}
|
||||
|
||||
public function stage(Request $request, string $id, string $code, InvestorPath $path): JsonResponse|RedirectResponse
|
||||
{
|
||||
abort_unless($path->available(), 404);
|
||||
$path->stage($request->user(), $id, $code, $request->all());
|
||||
|
||||
return $this->saved($request, 'Etapa e fundamento registados.');
|
||||
}
|
||||
|
||||
public function tool(Request $request, string $id, InvestorPath $path): JsonResponse
|
||||
{
|
||||
abort_unless($path->available(), 404);
|
||||
|
||||
return response()->json(['result' => $path->returnTool($request, $id, $request->all())]);
|
||||
}
|
||||
|
||||
public function task(Request $request, string $id, InvestorPath $path): JsonResponse|RedirectResponse
|
||||
{
|
||||
abort_unless($path->available(), 404);
|
||||
$task = $path->task($request->user(), $id, $request->all());
|
||||
|
||||
return $request->expectsJson() ? response()->json(['id' => $task], 201) : back()->with('success', 'Tarefa assumida no acompanhamento interno.');
|
||||
}
|
||||
|
||||
private function saved(Request $request, string $message): JsonResponse|RedirectResponse
|
||||
{
|
||||
return $request->expectsJson() ? response()->json(['message' => $message]) : back()->with('success', $message);
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ namespace App\Http\Controllers;
|
||||
use App\Models\InterestRequest;
|
||||
use App\Models\Investor;
|
||||
use App\Models\InvestorJourney;
|
||||
use App\Services\CountryCatalogue;
|
||||
use App\Services\InterestSubmission;
|
||||
use App\Services\PortalAudit;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
@@ -23,10 +24,12 @@ class InvestorWorkspaceController extends Controller
|
||||
$interest = $journey->interest_request_id ? InterestRequest::find($journey->interest_request_id) : null;
|
||||
|
||||
return ['id' => $journey->id, 'dossier_id' => $dossier?->id, 'title' => $dossier->title ?? 'Ficha temporariamente indisponível',
|
||||
'status' => $journey->status, 'reference' => $interest?->reference, 'request_status' => $interest?->status];
|
||||
'status' => $journey->status, 'reference' => $interest?->reference, 'request_status' => $interest?->status,
|
||||
'country' => $interest?->country,
|
||||
'declared_origin' => app(CountryCatalogue::class)->describe($interest?->metadata['declared_origin_country_code'] ?? null)];
|
||||
});
|
||||
|
||||
return Inertia::render('portfolio/workspace', ['journeys' => $journeys]);
|
||||
return Inertia::render('portfolio/workspace', ['journeys' => $journeys, 'countries' => app(CountryCatalogue::class)->all()]);
|
||||
}
|
||||
|
||||
public function start(Request $request, string $id): RedirectResponse
|
||||
@@ -57,7 +60,8 @@ class InvestorWorkspaceController extends Controller
|
||||
|
||||
public function submit(Request $request, string $id, InterestSubmission $submission): RedirectResponse
|
||||
{
|
||||
$data = $request->validate(['message' => ['required', 'string', 'min:20', 'max:5000'], 'country' => ['required', 'string', 'max:100'],
|
||||
$data = $request->validate(['message' => ['required', 'string', 'min:20', 'max:5000'], 'country' => ['required', 'string', 'max:100', app(CountryCatalogue::class)->legacyCountryRule()],
|
||||
'declared_origin_country_code' => ['nullable', app(CountryCatalogue::class)->rule()],
|
||||
'privacy_consent' => ['accepted'], 'role' => ['required', 'in:investir,financiar,fornecer,operar,parceria'],
|
||||
'horizon' => ['required', 'string', 'max:100']]);
|
||||
DB::transaction(function () use ($request, $id, $data, $submission) {
|
||||
@@ -74,6 +78,7 @@ class InvestorWorkspaceController extends Controller
|
||||
'sector_interest' => Str::limit($dossier->content['sector'] ?? $dossier->title, 150, ''), 'message' => $data['message'],
|
||||
'privacy_consent' => true, 'consented_at' => now(), 'status' => 'received', 'source_page' => '/carteira/'.$dossier->id,
|
||||
'metadata' => ['journey_id' => $journey->id, 'dossier_id' => $dossier->id, 'origin_dossier_id' => $journey->origin_dossier_id,
|
||||
'declared_origin_country_code' => $data['declared_origin_country_code'] ?? null,
|
||||
'project_id' => $dossier->project_id ?? $origin?->project_id,
|
||||
'cluster_id' => $dossier->cluster_id ?? $origin?->cluster_id, 'corridor_id' => $dossier->corridor_id ?? $origin?->corridor_id,
|
||||
'role' => $data['role'], 'horizon' => $data['horizon'], 'purpose' => 'Acompanhamento da manifestação de interesse'],
|
||||
|
||||
@@ -8,7 +8,9 @@ use App\Http\Requests\StoreLandAssistanceCaseRequest;
|
||||
use App\Jobs\ScanDocumentForMalware;
|
||||
use App\Models\InterestRequest;
|
||||
use App\Models\LandAssistanceCase;
|
||||
use App\Services\CountryCatalogue;
|
||||
use App\Services\InterestSubmission;
|
||||
use App\Services\InvestmentGeography;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -57,6 +59,7 @@ class LandAssistanceController extends Controller
|
||||
'user' => ['name' => $request->user()->name, 'email' => $request->user()->email],
|
||||
'disclaimer' => self::DISCLAIMER,
|
||||
'modelVersion' => 'land-assistance-v1',
|
||||
'countries' => app(CountryCatalogue::class)->all(),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -70,6 +73,7 @@ class LandAssistanceController extends Controller
|
||||
'user' => ['name' => $request->user()->name, 'email' => $request->user()->email],
|
||||
'disclaimer' => self::DISCLAIMER,
|
||||
'modelVersion' => 'land-assistance-v1',
|
||||
'countries' => app(CountryCatalogue::class)->all(),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -102,6 +106,7 @@ class LandAssistanceController extends Controller
|
||||
{
|
||||
$case = $this->owned($request, $id);
|
||||
$data = [
|
||||
...$this->presentation($case),
|
||||
'case' => $case->only(['id', 'reference', 'status', 'version', 'payload', 'updated_at']),
|
||||
'documents' => DB::table('land_assistance_documents as link')->join('documents as document', 'document.id', '=', 'link.document_id')
|
||||
->where('link.case_id', $id)->whereIn('document.status', ['active', 'quarantined'])->whereNull('document.deleted_at')
|
||||
@@ -162,6 +167,7 @@ class LandAssistanceController extends Controller
|
||||
'sectorInterest' => 'Terra e DUAT', 'message' => mb_substr($message, 0, 2000),
|
||||
'privacyConsent' => true, 'portal_user_id' => $request->user()->id,
|
||||
'land_case_id' => $case->id, 'land_case_reference' => $case->reference,
|
||||
'declared_origin_country_code' => $payload['declared_origin_country_code'] ?? null,
|
||||
], $case->crm_submission_key, fn () => InterestRequest::create([
|
||||
'reference' => 'AP-'.now()->year.'-'.Str::ulid(), 'full_name' => $payload['full_name'],
|
||||
'email' => $payload['email'], 'phone' => $payload['phone'] ?? null,
|
||||
@@ -169,7 +175,8 @@ class LandAssistanceController extends Controller
|
||||
'sector_interest' => 'Terra e DUAT', 'message' => mb_substr($message, 0, 2000),
|
||||
'privacy_consent' => true, 'consented_at' => now(), 'status' => 'received', 'source_page' => '/terra-duat',
|
||||
'metadata' => ['kind' => 'support', 'portal_user_id' => $request->user()->id,
|
||||
'land_case_id' => $case->id, 'land_case_reference' => $case->reference],
|
||||
'land_case_id' => $case->id, 'land_case_reference' => $case->reference,
|
||||
'declared_origin_country_code' => $payload['declared_origin_country_code'] ?? null],
|
||||
]));
|
||||
$case->forceFill([
|
||||
'payload' => $payload,
|
||||
@@ -304,6 +311,22 @@ class LandAssistanceController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
/** @return array<string,mixed> */
|
||||
private function presentation(LandAssistanceCase $case, bool $management = false): array
|
||||
{
|
||||
$payload = $case->payload;
|
||||
$countries = app(CountryCatalogue::class);
|
||||
$country = $countries->describe($payload['country'] ?? null);
|
||||
$paths = [];
|
||||
foreach ($payload['parcels'] ?? [] as $parcel) {
|
||||
$id = $parcel['locality_id'] ?? $parcel['admin_post_id'] ?? $parcel['district_id'] ?? $parcel['province_id'] ?? null;
|
||||
$paths[] = app(InvestmentGeography::class)->path($id ?: null, $management);
|
||||
}
|
||||
|
||||
return ['countryName' => $country['code'] !== null ? $country['name'] : ($payload['country'] ?? 'Não informado'),
|
||||
'declaredOrigin' => $countries->describe($payload['declared_origin_country_code'] ?? null), 'territoryPaths' => $paths];
|
||||
}
|
||||
|
||||
public function manage(Request $request): Response
|
||||
{
|
||||
$cases = LandAssistanceCase::query()->latest('updated_at')->paginate(30)->through(fn (LandAssistanceCase $case): array => [
|
||||
@@ -321,6 +344,7 @@ class LandAssistanceController extends Controller
|
||||
$events = DB::table('land_assistance_events')->where('case_id', $id)->orderBy('created_at')->get(['action', 'version', 'metadata', 'created_at']);
|
||||
|
||||
return Inertia::render('land-assistance/case', [
|
||||
...$this->presentation($case, true),
|
||||
'case' => $case->only(['id', 'reference', 'status', 'version', 'payload', 'updated_at']),
|
||||
'documents' => DB::table('land_assistance_documents as link')->join('documents as document', 'document.id', '=', 'link.document_id')
|
||||
->where('link.case_id', $id)->whereIn('document.status', ['active', 'quarantined'])->whereNull('document.deleted_at')->get(['link.id', 'link.category', 'document.file_name', 'document.status']),
|
||||
|
||||
@@ -8,6 +8,7 @@ use App\Models\Sector;
|
||||
use App\Services\InvestmentGeography;
|
||||
use App\Services\OpportunityManagement;
|
||||
use App\Services\OpportunityManagementInstallation;
|
||||
use App\Services\OpportunityMaturity;
|
||||
use App\Services\OpportunityResources;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
@@ -67,10 +68,11 @@ class OpportunityManagementController extends Controller
|
||||
return app(PortalManagementController::class)->edit('opportunities', $id);
|
||||
}
|
||||
$record = $id ? Opportunity::withTrashed()->findOrFail($id) : null;
|
||||
$values = $record ? ($record->management_draft ? json_decode($record->management_draft, true) : $record->only(OpportunityManagement::FIELDS)) : [];
|
||||
$values = $record ? $service->values($record) : [];
|
||||
$classification = $id ? DB::table('audit_events')->where('source_system', 'opportunity-origin-review')->where('after_data->opportunity_id', $id)->orderByDesc('occurred_at')->orderByDesc('id')->value('after_data') : null;
|
||||
|
||||
return Inertia::render('management/opportunity-draft', ['resourcesInstalled' => app(OpportunityResources::class)->installed(), 'record' => $record, 'values' => $values, 'etag' => $record ? $service->etag($record) : null, 'readOnly' => str_ends_with($request->path(), '/view'), 'closedVersion' => $record ? $service->closed($record) : false, 'classification' => $classification ? json_decode($classification, true)['classification'] : 'undetermined', 'sectors' => Sector::where('is_active', true)->orderBy('name')->get(['id', 'name']), 'categories' => OpportunityManagement::CATEGORIES,
|
||||
'maturityCatalogue' => ['version' => OpportunityMaturity::VERSION, 'stages' => OpportunityMaturity::STAGES, 'legacyVersion' => OpportunityMaturity::LEGACY, 'legacyLabels' => OpportunityMaturity::LEGACY_LABELS],
|
||||
'territoryPath' => app(InvestmentGeography::class)->path($values['primary_territory_id'] ?? null, true),
|
||||
'history' => $id ? DB::table('audit_events')->where('source_system', 'opportunity-management')->where('after_data->record_id', $id)->orderByDesc('occurred_at')->get(['id', 'action', 'actor_user_id', 'occurred_at']) : []]);
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ class OpportunityResourceController extends Controller
|
||||
$image->derivativePreviews = [];
|
||||
foreach ($image->payload['derivatives'] ?? [] as $derived) {
|
||||
if (DB::table('documents')->where('id', $derived['document_id'])->where('status', 'active')->where('malware_scan_status', 'clean')->whereColumn('sha256', 'malware_scanned_sha256')->exists()) {
|
||||
$image->derivativePreviews[] = [...$derived, 'url' => URL::temporarySignedRoute('opportunity-image-preview', now()->addMinutes(10), ['id' => $id, 'resourceId' => $image->id, 'documentId' => $derived['document_id']])];
|
||||
$image->derivativePreviews[] = [...$derived, 'url' => URL::temporarySignedRoute('management.opportunity-image-preview', now()->addMinutes(10), ['id' => $id, 'resourceId' => $image->id, 'documentId' => $derived['document_id']])];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ use App\Models\InvestmentSubmission;
|
||||
use App\Models\Opportunity;
|
||||
use App\Models\Sector;
|
||||
use App\Models\User;
|
||||
use App\Services\CountryCatalogue;
|
||||
use App\Services\DeclaredOriginStatistics;
|
||||
use App\Services\InterestWorkflow;
|
||||
use App\Services\InvestmentGeography;
|
||||
use App\Services\InvestmentWorkspace;
|
||||
@@ -56,10 +58,22 @@ class PortalManagementController extends Controller
|
||||
'q' => ['nullable', 'string', 'max:150'],
|
||||
'status' => ['nullable', Rule::in(self::STATES)],
|
||||
'follow_up' => ['nullable', Rule::in(['overdue', 'upcoming', 'unassigned'])],
|
||||
'country' => ['nullable', app(CountryCatalogue::class)->rule()],
|
||||
'origin' => ['nullable', Rule::in([...array_column(app(CountryCatalogue::class)->all(), 'code'), 'unknown'])],
|
||||
]);
|
||||
$query = InterestRequest::query()->with('assignee:id,name')->select([
|
||||
'id', 'reference', 'full_name', 'email', 'sector_interest', 'existing_business_id', 'modality', 'status', 'assigned_to', 'next_action', 'next_action_due_at', 'created_at',
|
||||
'id', 'reference', 'full_name', 'email', 'country', 'metadata', 'sector_interest', 'existing_business_id', 'modality', 'status', 'assigned_to', 'next_action', 'next_action_due_at', 'created_at',
|
||||
]);
|
||||
if ($country = $filters['country'] ?? null) {
|
||||
$query->where('country', $country);
|
||||
}
|
||||
if ($origin = $filters['origin'] ?? null) {
|
||||
if ($origin === 'unknown') {
|
||||
$query->where(fn ($q) => $q->whereNull('metadata->declared_origin_country_code')->orWhereNotIn('metadata->declared_origin_country_code', array_column(app(CountryCatalogue::class)->all(), 'code')));
|
||||
} else {
|
||||
$query->where('metadata->declared_origin_country_code', $origin);
|
||||
}
|
||||
}
|
||||
if ($term = $filters['q'] ?? null) {
|
||||
$query->where(fn ($q) => $q->whereLike('reference', "%{$term}%")
|
||||
->orWhereLike('full_name', "%{$term}%")->orWhereLike('email', "%{$term}%"));
|
||||
@@ -78,8 +92,18 @@ class PortalManagementController extends Controller
|
||||
}
|
||||
|
||||
return Inertia::render('management/interests', [
|
||||
'requests' => $query->orderByDesc('id')->paginate(20)->withQueryString(),
|
||||
'requests' => $query->orderByDesc('id')->paginate(20)->withQueryString()->through(function ($row) {
|
||||
$result = $row->toArray();
|
||||
$result['declaredOrigin'] = app(CountryCatalogue::class)->describe($row->metadata['declared_origin_country_code'] ?? null);
|
||||
$country = app(CountryCatalogue::class)->describe($row->country);
|
||||
$result['countryName'] = $country['code'] !== null ? $country['name'] : $row->country;
|
||||
unset($result['metadata']);
|
||||
|
||||
return $result;
|
||||
}),
|
||||
'filters' => $filters,
|
||||
'countries' => app(CountryCatalogue::class)->all(),
|
||||
'originStatistics' => app(DeclaredOriginStatistics::class)->forManager($request->user(), $filters['origin'] ?? null),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -97,6 +121,7 @@ class PortalManagementController extends Controller
|
||||
->orderBy('created_at')->get(['purpose', 'policy_version', 'status', 'granted_at', 'withdrawn_at']);
|
||||
|
||||
return Inertia::render('management/interest', [
|
||||
'declaredOrigin' => app(CountryCatalogue::class)->describe($interest->metadata['declared_origin_country_code'] ?? null),
|
||||
'interest' => $interest->only([
|
||||
'id', 'reference', 'full_name', 'email', 'phone', 'investor_type', 'country',
|
||||
'sector_interest', 'opportunity_reference', 'investment_range', 'message',
|
||||
|
||||
@@ -5,9 +5,11 @@ namespace App\Http\Controllers;
|
||||
use App\Jobs\ScanDocumentForMalware;
|
||||
use App\Models\InterestRequest;
|
||||
use App\Models\Sector;
|
||||
use App\Services\CountryCatalogue;
|
||||
use App\Services\IdempotencyConflict;
|
||||
use App\Services\InterestSubmission;
|
||||
use App\Services\Malware\MalwareScanner;
|
||||
use App\Services\VerifiedDocumentBinary;
|
||||
use App\Services\VirtualDesk;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Illuminate\Database\QueryException;
|
||||
@@ -37,7 +39,7 @@ class PortalServicesController extends Controller
|
||||
$essentialResources = collect();
|
||||
}
|
||||
|
||||
return Inertia::render('PortalInvestidor', ['essentialResources' => $essentialResources]);
|
||||
return Inertia::render('PortalInvestidor', ['essentialResources' => $essentialResources, 'countries' => app(CountryCatalogue::class)->all()]);
|
||||
}
|
||||
|
||||
private function resources(): Builder
|
||||
@@ -64,7 +66,7 @@ class PortalServicesController extends Controller
|
||||
'stage' => ['nullable', 'array', 'max:10'], 'stage.*' => ['string', 'max:80'],
|
||||
'module' => ['nullable', 'array', 'max:10'], 'module.*' => ['string', 'max:80'],
|
||||
]);
|
||||
$props = ['section' => $page, 'filters' => $filters];
|
||||
$props = ['section' => $page, 'filters' => $filters, 'countries' => app(CountryCatalogue::class)->all()];
|
||||
if ($page === 'sectors') {
|
||||
$props['sectors'] = Sector::where('is_active', true)->withCount(['opportunities' => fn ($q) => $q->published()])->orderBy('sort_order')->get(['id', 'name', 'slug', 'short_description']);
|
||||
}
|
||||
@@ -222,7 +224,8 @@ class PortalServicesController extends Controller
|
||||
$data = $request->validate([
|
||||
'kind' => ['required', 'in:support,investor,company,partnership'],
|
||||
'fullName' => ['required', 'string', 'min:3', 'max:150'], 'email' => ['required', 'email:rfc', 'max:150'],
|
||||
'phone' => ['nullable', 'string', 'max:30'], 'country' => ['required', 'string', 'max:100'],
|
||||
'phone' => ['nullable', 'string', 'max:30'], 'country' => ['required', 'string', 'max:100', app(CountryCatalogue::class)->legacyCountryRule()],
|
||||
'declared_origin_country_code' => ['nullable', app(CountryCatalogue::class)->rule()],
|
||||
'company' => ['nullable', 'required_if:kind,company', 'string', 'max:150'],
|
||||
'sectorInterest' => ['required', 'string', 'max:150'], 'message' => ['required', 'string', 'min:20', 'max:2000'],
|
||||
'privacyConsent' => ['required', 'accepted'], 'submission_key' => ['required', 'uuid'],
|
||||
@@ -240,7 +243,8 @@ class PortalServicesController extends Controller
|
||||
'sector_interest' => $data['sectorInterest'], 'message' => $data['message'],
|
||||
'privacy_consent' => true, 'consented_at' => now(), 'status' => 'received', 'source_page' => '/apoio',
|
||||
'metadata' => ['kind' => $data['kind'], 'company' => $data['company'] ?? null,
|
||||
'portal_user_id' => $data['portal_user_id'], 'partnership_id' => $data['partnership_id'] ?? null],
|
||||
'portal_user_id' => $data['portal_user_id'], 'partnership_id' => $data['partnership_id'] ?? null,
|
||||
'declared_origin_country_code' => $data['declared_origin_country_code'] ?? null],
|
||||
]));
|
||||
} catch (IdempotencyConflict) {
|
||||
abort(409, 'Este envio já foi usado com dados diferentes. Recarregue o formulário.');
|
||||
@@ -260,17 +264,12 @@ class PortalServicesController extends Controller
|
||||
return back()->with('success', 'Proposta recebida para publicação. Acompanhe no Balcão Virtual.');
|
||||
}
|
||||
|
||||
public function download(int $id): BinaryFileResponse
|
||||
public function download(int $id): BinaryFileResponse|\Illuminate\Http\Response
|
||||
{
|
||||
$resource = $this->resources()->where('r.id', $id)->first(['d.storage_key', 'd.file_name', 'd.sha256']);
|
||||
$resource = $this->resources()->where('r.id', $id)->first(['d.*']);
|
||||
abort_unless($resource !== null, 404);
|
||||
$root = realpath(Storage::disk('local')->path(''));
|
||||
$path = realpath(Storage::disk('local')->path($resource->storage_key));
|
||||
abort_unless($root && $path && str_starts_with(strtolower($path), strtolower($root.DIRECTORY_SEPARATOR)) && is_file($path), 404);
|
||||
$checksum = hash_file('sha256', $path);
|
||||
abort_unless($checksum !== false && hash_equals($resource->sha256, $checksum), 404);
|
||||
|
||||
return response()->download($path, basename($resource->file_name), ['X-Content-Type-Options' => 'nosniff', 'Cache-Control' => 'private, no-store']);
|
||||
return app(VerifiedDocumentBinary::class)->respond($resource);
|
||||
}
|
||||
|
||||
public function showDocument(Request $request, int $id): Response
|
||||
@@ -306,42 +305,21 @@ class PortalServicesController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
public function viewDocument(int $id): BinaryFileResponse
|
||||
public function viewDocument(int $id): BinaryFileResponse|\Illuminate\Http\Response
|
||||
{
|
||||
$document = $this->resources()->where('r.id', $id)->first([
|
||||
'd.storage_key', 'd.file_name', 'd.sha256', 'd.media_type',
|
||||
]);
|
||||
$document = $this->resources()->where('r.id', $id)->first(['d.*']);
|
||||
abort_unless($document && in_array($document->media_type, ['application/pdf', 'image/jpeg', 'image/png', 'image/webp'], true), 404);
|
||||
$root = realpath(Storage::disk('local')->path(''));
|
||||
$path = realpath(Storage::disk('local')->path($document->storage_key));
|
||||
abort_unless($root && $path && str_starts_with(strtolower($path), strtolower($root.DIRECTORY_SEPARATOR)) && is_file($path), 404);
|
||||
$checksum = hash_file('sha256', $path);
|
||||
abort_unless($checksum !== false && hash_equals($document->sha256, $checksum), 404);
|
||||
|
||||
return response()->file($path, [
|
||||
'Content-Type' => $document->media_type,
|
||||
'X-Content-Type-Options' => 'nosniff',
|
||||
'Content-Security-Policy' => "sandbox; default-src 'none'; style-src 'unsafe-inline'",
|
||||
'Cache-Control' => 'private, no-store',
|
||||
])->setContentDisposition('inline', basename($document->file_name));
|
||||
return app(VerifiedDocumentBinary::class)->respond($document, true);
|
||||
}
|
||||
|
||||
public function downloadForManager(string $id): BinaryFileResponse
|
||||
public function downloadForManager(string $id): BinaryFileResponse|\Illuminate\Http\Response
|
||||
{
|
||||
$document = DB::table('documents')->where('id', $id)->whereNull('deleted_at')->first([
|
||||
'storage_key', 'file_name', 'sha256', 'status', 'malware_scan_status', 'malware_scanned_sha256',
|
||||
]);
|
||||
$document = DB::table('documents')->where('id', $id)->whereNull('deleted_at')->first();
|
||||
abort_unless($document && $document->status === 'active' && $document->malware_scan_status === 'clean'
|
||||
&& hash_equals(trim($document->sha256), trim((string) $document->malware_scanned_sha256)), 404);
|
||||
$root = realpath(Storage::disk('local')->path(''));
|
||||
$path = realpath(Storage::disk('local')->path($document->storage_key));
|
||||
abort_unless($root && $path && str_starts_with(strtolower($path), strtolower($root.DIRECTORY_SEPARATOR)) && is_file($path), 404);
|
||||
$checksum = hash_file('sha256', $path);
|
||||
abort_unless($checksum !== false && hash_equals($document->sha256, $checksum), 404);
|
||||
|
||||
return response()->download($path, basename($document->file_name), [
|
||||
'X-Content-Type-Options' => 'nosniff', 'Cache-Control' => 'private, no-store',
|
||||
]);
|
||||
return app(VerifiedDocumentBinary::class)->respond($document);
|
||||
}
|
||||
|
||||
public function manage(MalwareScanner $scanner): Response
|
||||
@@ -437,8 +415,8 @@ class PortalServicesController extends Controller
|
||||
$id = DB::table('portal_resources')->insertGetId([...$fields, 'approved_by' => null, 'published' => false, 'created_at' => now(), 'updated_at' => now()]);
|
||||
$this->syncResourceLinks($id, $data['associations'] ?? []);
|
||||
$this->recordResourceRevision($id, 'created', $request->user()->id, 1);
|
||||
DB::table('documents')->where('id', $document->id)->update(['issuer' => $data['issuer'] ?: $document->issuer,
|
||||
'issued_on' => $data['document_date'] ?: $document->issued_on, 'rights_status' => $data['rights_status'],
|
||||
DB::table('documents')->where('id', $document->id)->update(['issuer' => ($data['issuer'] ?? null) ?: $document->issuer,
|
||||
'issued_on' => ($data['document_date'] ?? null) ?: $document->issued_on, 'rights_status' => $data['rights_status'],
|
||||
'data_classification' => $data['data_classification'] ?? $document->data_classification, 'updated_at' => now()]);
|
||||
$this->audit($request, $duplicate ? 'resource_registered_possible_duplicate' : 'resource_registered', 'portal_resources', $id);
|
||||
|
||||
@@ -475,8 +453,8 @@ class PortalServicesController extends Controller
|
||||
DB::table('portal_resource_links')->where('resource_id', $id)->delete();
|
||||
$this->syncResourceLinks($id, $data['associations'] ?? []);
|
||||
$this->recordResourceRevision($id, 'metadata_updated', $request->user()->id, $expectedVersion + 1);
|
||||
DB::table('documents')->where('id', $document->id)->update(['issuer' => $data['issuer'] ?: $document->issuer,
|
||||
'issued_on' => $data['document_date'] ?: $document->issued_on, 'rights_status' => $data['rights_status'],
|
||||
DB::table('documents')->where('id', $document->id)->update(['issuer' => ($data['issuer'] ?? null) ?: $document->issuer,
|
||||
'issued_on' => ($data['document_date'] ?? null) ?: $document->issued_on, 'rights_status' => $data['rights_status'],
|
||||
'data_classification' => $data['data_classification'] ?? $document->data_classification, 'updated_at' => now()]);
|
||||
$this->audit($request, 'resource_metadata_updated', 'portal_resources', $id);
|
||||
});
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Resources\PublicBusinessOpportunityResource;
|
||||
use App\Models\ExistingBusiness;
|
||||
use App\Services\CountryCatalogue;
|
||||
use App\Services\ExistingBusinessDrafts;
|
||||
use App\Services\InvestmentGeography;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
@@ -84,6 +85,7 @@ class PublicBusinessOpportunityController extends Controller
|
||||
return Inertia::render('investment/business-interest', [
|
||||
'record' => (new PublicBusinessOpportunityResource($record))->resolve($request),
|
||||
'modalities' => ExistingBusinessDrafts::MODALITIES,
|
||||
'countries' => app(CountryCatalogue::class)->all(),
|
||||
'returnUrl' => $returnFilters === [] ? '/negocios' : '/negocios?'.http_build_query($returnFilters),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Opportunity;
|
||||
use App\Models\Sector;
|
||||
use App\Services\CountryCatalogue;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
@@ -32,13 +33,13 @@ class PublicPortalController extends Controller
|
||||
|
||||
public function interest(?string $slug = null): Response
|
||||
{
|
||||
return $slug ? $this->detail($slug, 'interest') : Inertia::render('PortalInvestidor', ['initialView' => 'interest']);
|
||||
return $slug ? $this->detail($slug, 'interest') : Inertia::render('PortalInvestidor', ['initialView' => 'interest', 'countries' => app(CountryCatalogue::class)->all()]);
|
||||
}
|
||||
|
||||
private function detail(string $slug, string $view): Response
|
||||
{
|
||||
$opportunity = Opportunity::with('sector:id,name,slug')->published()->where('slug', $slug)->firstOrFail();
|
||||
|
||||
return Inertia::render('PortalInvestidor', ['initialView' => $view, 'initialOpportunity' => $opportunity]);
|
||||
return Inertia::render('PortalInvestidor', ['initialView' => $view, 'initialOpportunity' => $opportunity, 'countries' => app(CountryCatalogue::class)->all()]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Services\TerritoryGeometryImport;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class TerritoryGeometryImportController extends Controller
|
||||
{
|
||||
public function preview(Request $request, TerritoryGeometryImport $service)
|
||||
{
|
||||
$data = $request->validate(['level' => 'nullable|integer|in:1,2,3']);
|
||||
$plan = $service->preview($request->user(), (int) ($data['level'] ?? 1));
|
||||
|
||||
return $request->expectsJson() ? response()->json($plan) : Inertia::render('management/territory-geometry-import', ['plan' => $plan]);
|
||||
}
|
||||
|
||||
public function apply(Request $request, TerritoryGeometryImport $service)
|
||||
{
|
||||
return response()->json($service->apply($request->user(), $request->all()));
|
||||
}
|
||||
|
||||
public function reverse(Request $request, string $batch, TerritoryGeometryImport $service)
|
||||
{
|
||||
return response()->json($service->reverse($request->user(), $batch, $request->all()));
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,13 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Jobs\ScanDocumentForMalware;
|
||||
use App\Models\InvestmentSubmission;
|
||||
use App\Models\User;
|
||||
use App\Services\Ai\InvestorGuidance;
|
||||
use App\Services\CountryCatalogue;
|
||||
use App\Services\InstitutionalLinkMonitor;
|
||||
use App\Services\InvestmentGeography;
|
||||
use App\Services\VerifiedDocumentBinary;
|
||||
use App\Services\VirtualDesk;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
@@ -48,7 +51,7 @@ class VirtualDeskController extends Controller
|
||||
$data = ['cases' => $cases, 'queue' => $queue, 'notifications' => DB::table('desk_notifications')->where('user_id', $actor->id)->orderByDesc('id')->limit(100)->get(),
|
||||
'legacyRequests' => DB::table('interest_requests')->where('metadata->portal_user_id', $actor->id)->whereNull('deleted_at')->orderByDesc('created_at')->get(['id', 'reference', 'status', 'created_at']),
|
||||
'companies' => DB::table('investment_company_declarations')->where('user_id', $actor->id)->get(['id', 'payload'])->map(fn ($c) => ['id' => $c->id, 'name' => $desk->decode($c->payload)['name'] ?? 'Declaração empresarial']),
|
||||
'submissions' => \App\Models\InvestmentSubmission::where('user_id', $actor->id)->get()->map(fn ($s) => ['id' => $s->id, 'status' => $s->status, 'name' => ($s->opportunity_id ? DB::table('opportunities')->where('id', $s->opportunity_id)->value('title') : null) ?? ($s->dossier_id ? DB::table('investment_dossiers')->where('id', $s->dossier_id)->value('title') : null) ?? ($s->payload['organisation'] ?? null)]),
|
||||
'submissions' => InvestmentSubmission::where('user_id', $actor->id)->get()->map(fn ($s) => ['id' => $s->id, 'status' => $s->status, 'name' => ($s->opportunity_id ? DB::table('opportunities')->where('id', $s->opportunity_id)->value('title') : null) ?? ($s->dossier_id ? DB::table('investment_dossiers')->where('id', $s->dossier_id)->value('title') : null) ?? ($s->payload['organisation'] ?? null)]),
|
||||
'journeys' => DB::table('investor_journeys as j')->leftJoin('investment_dossiers as d', 'd.id', '=', 'j.dossier_id')->where('j.user_id', $actor->id)->whereNull('j.deleted_at')->get(['j.id', 'j.dossier_id', 'j.status', 'd.title as name']),
|
||||
'simulationDrafts' => DB::table('simulation_form_drafts')->where('owner_user_id', $actor->id)->whereNull('deleted_at')->where(fn ($q) => $q->whereNull('expires_at')->orWhere('expires_at', '>', now()))->get(['id', 'version_no']),
|
||||
'guidanceTasks' => app(InvestorGuidance::class)->installed() ? DB::table('tasks as t')->join('desk_cases as c', 'c.id', '=', 't.desk_case_id')
|
||||
@@ -72,7 +75,11 @@ class VirtualDeskController extends Controller
|
||||
$case = $desk->case($request->user(), $id);
|
||||
$owner = $desk->owns($request->user(), $case, false);
|
||||
$this->auditRead($request, 'desk_cases', $id);
|
||||
$data = ['case' => [...(array) $case, 'payload' => Arr::except($desk->decode($case->payload), $owner ? ['_creation_hash'] : ['_creation_hash', 'profile', 'company', 'investment', 'name', 'email']), 'workflow' => json_decode($case->workflow, true)],
|
||||
$hidden = $owner ? ['_creation_hash'] : ['_creation_hash', 'profile', 'company', 'investment', 'name', 'email'];
|
||||
if ((int) $case->user_id !== $request->user()->id) {
|
||||
$hidden[] = 'investor_path';
|
||||
}
|
||||
$data = ['case' => [...(array) $case, 'payload' => Arr::except($desk->decode($case->payload), $hidden), 'workflow' => json_decode($case->workflow, true)],
|
||||
'legacyRequest' => ($case->interest_request_id ?? null) ? DB::table('interest_requests as r')->leftJoin('users as u', 'u.id', '=', 'r.assigned_to')->where('r.id', $case->interest_request_id)->whereNull('r.deleted_at')
|
||||
->when(! $request->user()->can('manage-portal'), fn ($q) => $q->where('r.metadata->portal_user_id', $request->user()->id))
|
||||
->first(['r.id', 'r.reference', 'r.status', 'r.next_action', 'r.next_action_due_at', 'u.name as responsible_name']) : null,
|
||||
@@ -122,6 +129,13 @@ class VirtualDeskController extends Controller
|
||||
$row = $desk->request($request->user(), $id);
|
||||
$case = $desk->case($request->user(), $row->case_id);
|
||||
$payload = $desk->decode($row->payload);
|
||||
$definition = $desk->definition($row);
|
||||
$territoryPaths = [];
|
||||
foreach ($definition['fields'] as $key => $field) {
|
||||
if ($field['type'] === 'territory') {
|
||||
$territoryPaths[$key] = app(InvestmentGeography::class)->path($payload[$key] ?? null);
|
||||
}
|
||||
}
|
||||
$messageKinds = [];
|
||||
foreach (DB::table('desk_events')->where('request_id', $id)->where('action', 'message_added')->get() as $event) {
|
||||
$original = $desk->decode($event->payload);
|
||||
@@ -130,8 +144,8 @@ class VirtualDeskController extends Controller
|
||||
}
|
||||
}
|
||||
$this->auditRead($request, 'desk_requests', $id);
|
||||
$data = ['countries' => app(\App\Services\CountryCatalogue::class)->all(), 'request' => [...(array) $row, 'payload' => $payload, 'submitted_snapshot' => $desk->decode($row->submitted_snapshot), 'editable_fields' => json_decode($row->editable_fields ?? '[]', true)],
|
||||
'case' => ['id' => $case->id, 'title' => $case->title], 'caseVersion' => $case->version, 'definition' => $desk->definition($row),
|
||||
$data = ['countries' => app(CountryCatalogue::class)->all(), 'request' => [...(array) $row, 'payload' => $payload, 'submitted_snapshot' => $desk->decode($row->submitted_snapshot), 'editable_fields' => json_decode($row->editable_fields ?? '[]', true)],
|
||||
'case' => ['id' => $case->id, 'title' => $case->title], 'caseVersion' => $case->version, 'definition' => $definition, 'territoryPaths' => $territoryPaths,
|
||||
'serviceSource' => json_decode(DB::table('desk_service_versions')->where('id', $row->service_version_id)->value('source'), true),
|
||||
'owner' => $desk->owns($request->user(), $case), 'manager' => $request->user()->can('manage-portal'), 'analyst' => (int) $row->analyst_id === $request->user()->id,
|
||||
'fieldsEditable' => in_array($row->status, ['draft', 'returned'], true), 'states' => config('virtual-desk.request_states'), 'transitions' => config('virtual-desk.transitions.'.$row->status, []),
|
||||
@@ -274,7 +288,7 @@ class VirtualDeskController extends Controller
|
||||
return $request->expectsJson() ? response()->json(['ok' => true]) : back()->with('success', 'Documento privado associado; consulte o estado da análise.');
|
||||
}
|
||||
|
||||
public function download(Request $request, string $id, string $document, VirtualDesk $desk): BinaryFileResponse
|
||||
public function download(Request $request, string $id, string $document, VirtualDesk $desk): BinaryFileResponse|\Illuminate\Http\Response
|
||||
{
|
||||
$desk->case($request->user(), $id);
|
||||
$doc = DB::table('desk_documents as l')->join('documents as d', 'd.id', '=', 'l.document_id')->where('l.case_id', $id)->where('l.id', $document)->whereNull('d.deleted_at')->first(['d.*', 'l.request_id']);
|
||||
@@ -282,12 +296,10 @@ class VirtualDeskController extends Controller
|
||||
$desk->request($request->user(), $doc->request_id);
|
||||
}
|
||||
abort_unless($doc && $doc->status === 'active' && $doc->malware_scan_status === 'clean' && trim($doc->sha256) === $doc->malware_scanned_sha256, 404);
|
||||
$path = realpath(Storage::disk('local')->path($doc->storage_key));
|
||||
$root = realpath(Storage::disk('local')->path(''));
|
||||
abort_unless($path && $root && str_starts_with($path, $root.DIRECTORY_SEPARATOR) && is_file($path) && is_string($actualHash = hash_file('sha256', $path)) && hash_equals(trim($doc->sha256), $actualHash), 404);
|
||||
$response = app(VerifiedDocumentBinary::class)->respond($doc);
|
||||
$this->auditRead($request, 'documents', $doc->id, 'document_downloaded');
|
||||
|
||||
return response()->download($path, $doc->file_name, ['Cache-Control' => 'private, no-store']);
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function notification(Request $request, int $id): RedirectResponse
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Services\InvestorPath;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Middleware;
|
||||
|
||||
@@ -42,6 +43,7 @@ class HandleInertiaRequests extends Middleware
|
||||
'educationEnabled' => (bool) config('education.enabled', false),
|
||||
'aiEnabled' => (bool) config('investmoz_ai.enabled', false),
|
||||
'existingBusinessEnabled' => (bool) config('existing-business.enabled', false),
|
||||
'investorPathEnabled' => app(InvestorPath::class)->available(),
|
||||
'flash' => ['success' => fn () => $request->session()->get('success'), 'warning' => fn () => $request->session()->get('warning')],
|
||||
'auth' => [
|
||||
'user' => $request->user(),
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Services\CountryCatalogue;
|
||||
use App\Services\ExistingBusinessDrafts;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@@ -30,7 +31,8 @@ class StoreInterestRequestRequest extends FormRequest
|
||||
'investorType' => ['required', 'string', Rule::in([
|
||||
'individual', 'empresa', 'fundo', 'entidade_publica', 'outro',
|
||||
])],
|
||||
'country' => ['required', 'string', 'max:100'],
|
||||
'country' => ['required', 'string', 'max:100', ...($knownKey ? [] : [app(CountryCatalogue::class)->legacyCountryRule()])],
|
||||
'declared_origin_country_code' => ['nullable', app(CountryCatalogue::class)->rule()],
|
||||
'sectorInterest' => ['required', 'string', 'max:150'],
|
||||
// A known receipt can replay after withdrawal; the service verifies the payload hash.
|
||||
'opportunityReference' => ['nullable', 'string', 'max:80', ...($knownKey ? [] : [
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Services\CountryCatalogue;
|
||||
use App\Services\InvestmentGeography;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Validator;
|
||||
@@ -28,7 +29,7 @@ class StoreLandAssistanceCaseRequest extends FormRequest
|
||||
{
|
||||
return [
|
||||
'version' => [$this->isMethod('post') && ! $this->routeIs('land-assistance.support') ? 'nullable' : 'required', 'integer', 'min:1'],
|
||||
'payload' => ['required', 'array:support_kind,request_description,project_reference,applicant_category,full_name,contact_person,email,phone,preferred_contact,country,nationality,representative_name,representative_role,representation_basis,nuit,constitution_or_residency_note,area_status,parcels,purpose,activity,known_occupants,occupant_description,known_improvements,improvements_description,prior_right_status,prior_right_description,conflict_status,conflict_description,official_process,attachments_to_follow,exploration_plan,consultation,additional_information,truth_declaration,contact_consent'],
|
||||
'payload' => ['required', 'array:support_kind,request_description,project_reference,applicant_category,full_name,contact_person,email,phone,preferred_contact,country,declared_origin_country_code,nationality,representative_name,representative_role,representation_basis,nuit,constitution_or_residency_note,area_status,parcels,purpose,activity,known_occupants,occupant_description,known_improvements,improvements_description,prior_right_status,prior_right_description,conflict_status,conflict_description,official_process,attachments_to_follow,exploration_plan,consultation,additional_information,truth_declaration,contact_consent'],
|
||||
'payload.support_kind' => ['nullable', 'in:investment,home,family_exploitation,recognition,regularization,delimitation,change_of_use,transfer,existing_process,conflict_guidance,other'],
|
||||
'payload.request_description' => ['nullable', 'string', 'max:4000'],
|
||||
'payload.project_reference' => ['nullable', 'string', 'max:160'],
|
||||
@@ -38,7 +39,8 @@ class StoreLandAssistanceCaseRequest extends FormRequest
|
||||
'payload.email' => ['nullable', 'email:rfc', 'max:150'],
|
||||
'payload.phone' => ['nullable', 'string', 'max:30'],
|
||||
'payload.preferred_contact' => ['nullable', 'in:email,phone,any'],
|
||||
'payload.country' => ['nullable', 'string', 'max:100'],
|
||||
'payload.country' => ['nullable', 'string', 'max:100', app(CountryCatalogue::class)->legacyCountryRule()],
|
||||
'payload.declared_origin_country_code' => ['nullable', 'string', app(CountryCatalogue::class)->rule()],
|
||||
'payload.nationality' => ['nullable', 'string', 'max:120'],
|
||||
'payload.representative_name' => ['nullable', 'string', 'max:200'],
|
||||
'payload.representative_role' => ['nullable', 'string', 'max:120'],
|
||||
@@ -132,7 +134,9 @@ class StoreLandAssistanceCaseRequest extends FormRequest
|
||||
continue;
|
||||
}
|
||||
$record = $geography->publicReferences()->where('id', $id)->first(['id', 'parent_id', 'location_type']);
|
||||
if ($gap || ! $record || $record->location_type !== $expectedType || ($expectedType === 'province' ? $record->parent_id !== null : (string) $record->parent_id !== $parent)) {
|
||||
// The populated workbook hierarchy has country -> province. The public
|
||||
// selector deliberately starts at province; it is not a root in storage.
|
||||
if ($gap || ! $record || $record->location_type !== $expectedType || ($expectedType !== 'province' && (string) $record->parent_id !== $parent)) {
|
||||
$validator->errors()->add("payload.parcels.$index.$field", 'A hierarquia territorial declarada é incoerente ou não está publicada.');
|
||||
$gap = true;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Services\CountryCatalogue;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Validation\Validator;
|
||||
@@ -62,6 +63,7 @@ class StoreSimulationFormDraftRequest extends FormRequest
|
||||
$rules = [
|
||||
// Anonymous clients must send an empty snapshot; `required` rejects
|
||||
// an empty array before the privacy policy can enforce that shape.
|
||||
'context' => ['nullable', 'uuid'],
|
||||
'personal_snapshot' => ['present', 'array:'.implode(',', $personal)],
|
||||
'economic_snapshot' => ['required', 'array:'.implode(',', $economic)],
|
||||
'economic_snapshot.purpose' => ['required', 'in:simulate_only,own_investment,seek_investor,seek_partner,present_opportunity,request_facilitation'],
|
||||
@@ -169,6 +171,10 @@ class StoreSimulationFormDraftRequest extends FormRequest
|
||||
'contact_province', 'contact_district', 'preferred_channel'] as $field) {
|
||||
$rules['personal_snapshot.'.$field] = ['nullable', 'string', 'max:3000'];
|
||||
}
|
||||
foreach (['tax_residency_country', 'fiscal_residency_country', 'contact_country'] as $field) {
|
||||
$rules['personal_snapshot.'.$field][] = app(CountryCatalogue::class)->legacyCountryRule();
|
||||
}
|
||||
$rules['economic_snapshot.funds_origin_countries.*'][] = app(CountryCatalogue::class)->legacyCountryRule();
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
@@ -132,9 +132,11 @@ class InvestorGuidance
|
||||
$actions = ['opportunities' => '/oportunidades', 'locations' => '/oportunidades?view=map', 'partners' => '/parcerias',
|
||||
'documents' => '/documentos', 'plan' => $case->submission_id && (int) $case->user_id === $actor->id ? '/investidor/manifestacoes/'.$case->submission_id : '/balcao-virtual/dossiers/'.$id,
|
||||
'simulator' => '/simulador-fiscal', 'support' => '/balcao-virtual/dossiers/'.$id];
|
||||
// The simulator recovers its current owner-scoped draft; do not pass private payload in URLs.
|
||||
// Pin the linked owner-scoped draft instead of opening another project's current draft.
|
||||
// The receiving API still enforces ownership; no private payload is carried in the URL.
|
||||
if ($case->simulation_id && $context['financial_draft'] !== null) {
|
||||
$actions['plan'] = '/simulador-fiscal';
|
||||
$actions['simulator'] = '/simulador-fiscal?draft='.rawurlencode($case->simulation_id);
|
||||
$actions['plan'] = $actions['simulator'];
|
||||
}
|
||||
$phases = $this->rules->evaluate($context['facts'], $context['evidence']);
|
||||
foreach ($phases as &$phase) {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Services;
|
||||
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rules\In;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
final class BusinessFormSchema
|
||||
@@ -13,7 +14,8 @@ final class BusinessFormSchema
|
||||
return [
|
||||
'proponent_type' => ['step' => 1, 'pt' => 'Quem apresenta a oportunidade?', 'en' => 'Who is presenting the opportunity?', 'type' => 'select', 'max' => 30, 'options' => ['organization' => 'Empresa ou organização / Company or organization', 'sole_trader' => 'Empresário em nome individual / Sole trader', 'person' => 'Pessoa singular / Individual', 'public_entity' => 'Entidade pública / Public entity']],
|
||||
'proponent_name' => ['step' => 1, 'pt' => 'Nome ou denominação', 'en' => 'Name', 'type' => 'text', 'max' => 200],
|
||||
'country' => ['step' => 1, 'pt' => 'País de origem ou constituição (código ISO de duas letras)', 'en' => 'Country of origin or incorporation (two-letter ISO code)', 'type' => 'text', 'max' => 2],
|
||||
'country' => ['step' => 1, 'pt' => 'País de origem ou constituição', 'en' => 'Country of origin or incorporation', 'type' => 'country', 'max' => 100],
|
||||
'declared_origin_country_code' => ['step' => 1, 'pt' => 'País de origem declarado desta solicitação (opcional)', 'en' => 'Declared country of origin of this request (optional)', 'type' => 'country', 'max' => 2],
|
||||
'tax_identifier' => ['step' => 1, 'pt' => 'NUIT ou identificador (interno, quando aplicável)', 'en' => 'NUIT or identifier (internal, when applicable)', 'type' => 'text', 'max' => 50],
|
||||
'contact_name' => ['step' => 1, 'pt' => 'Nome da pessoa de contacto', 'en' => 'Contact person name', 'type' => 'text', 'max' => 200],
|
||||
'contact_email' => ['step' => 1, 'pt' => 'Correio electrónico (indique email ou telefone)', 'en' => 'Email (provide email or phone)', 'type' => 'email', 'max' => 254],
|
||||
@@ -77,7 +79,7 @@ final class BusinessFormSchema
|
||||
];
|
||||
}
|
||||
|
||||
/** @return array<string, array<int,string>> */
|
||||
/** @return array<string, list<string|\Closure|In>> */
|
||||
public static function rules(): array
|
||||
{
|
||||
$rules = [];
|
||||
@@ -89,7 +91,8 @@ final class BusinessFormSchema
|
||||
}
|
||||
$rules['payload.contact_email'][] = 'nullable';
|
||||
$rules['payload.contact_email'][] = 'email';
|
||||
$rules['payload.country'][] = 'regex:/^[A-Z]{2}$/';
|
||||
$rules['payload.country'][] = app(CountryCatalogue::class)->legacyCountryRule();
|
||||
$rules['payload.declared_origin_country_code'][] = app(CountryCatalogue::class)->rule();
|
||||
$rules['payload.currency'][] = 'regex:/^[A-Z]{3}$/';
|
||||
$rules['payload.asking_value'][] = 'regex:/^\d{1,15}(\.\d{1,4})?$/';
|
||||
$rules['payload.amount_secured'][] = 'regex:/^\d{1,15}(\.\d{1,4})?$/';
|
||||
@@ -122,6 +125,8 @@ final class BusinessFormSchema
|
||||
$rules[$field] = ['required'];
|
||||
}
|
||||
$rules['sector_id'] = ['required'];
|
||||
$rules['country'] = ['required', 'string', app(CountryCatalogue::class)->rule()];
|
||||
$rules['declared_origin_country_code'] = ['nullable', 'string', app(CountryCatalogue::class)->rule()];
|
||||
$rules['contact_email'] = ['required_without:contact_phone', 'nullable', 'email'];
|
||||
$rules['contact_phone'] = ['required_without:contact_email', 'nullable', 'string', 'regex:/^[+0-9() .-]{7,40}$/'];
|
||||
$rules['legitimacy_declaration'] = ['required', 'in:yes'];
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Services;
|
||||
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\Rules\In;
|
||||
|
||||
/** Shared ISO identifiers; independent of administrative territories and IP data. */
|
||||
final class CountryCatalogue
|
||||
@@ -28,8 +29,28 @@ final class CountryCatalogue
|
||||
return $countries;
|
||||
}
|
||||
|
||||
public function rule(): \Illuminate\Validation\Rules\In
|
||||
public function rule(): In
|
||||
{
|
||||
return Rule::in(array_column($this->all(), 'code'));
|
||||
}
|
||||
|
||||
/** Accept existing free-text integrations; validate ISO-shaped values without rewriting them. */
|
||||
public function legacyCountryRule(): \Closure
|
||||
{
|
||||
$codes = array_column($this->all(), 'code');
|
||||
|
||||
return static function (string $attribute, mixed $value, \Closure $fail) use ($codes): void {
|
||||
if (is_string($value) && preg_match('/^[a-zA-Z]{2}$/D', $value) && ! in_array($value, $codes, true)) {
|
||||
$fail('Seleccione um código ISO de país válido.');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** @return array{code:string|null,name:string} */
|
||||
public function describe(?string $code): array
|
||||
{
|
||||
$names = array_column($this->all(), 'name', 'code');
|
||||
|
||||
return isset($names[$code ?? '']) ? ['code' => $code, 'name' => $names[$code]] : ['code' => null, 'name' => 'Não informado'];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Services\Mne\BusinessRepository;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
@@ -28,14 +29,23 @@ final class DeclaredOriginStatistics
|
||||
$desk[$key] = ($desk[$key] ?? 0) + 1;
|
||||
}
|
||||
}
|
||||
$businesses = [];
|
||||
if (Schema::hasTable('existing_businesses')) {
|
||||
foreach (app(BusinessRepository::class)->query()->whereNotIn('status', ['draft', 'cancelled'])->cursor() as $business) {
|
||||
$code = $business->payload['declared_origin_country_code'] ?? null;
|
||||
$key = is_string($code) && isset($names[$code]) ? $code : '';
|
||||
$businesses[$key] = ($businesses[$key] ?? 0) + 1;
|
||||
}
|
||||
}
|
||||
// Distinct request collections; summing them could count the same investor twice.
|
||||
if ($origin !== null && $origin !== '') {
|
||||
$key = $origin === 'unknown' ? '' : $origin;
|
||||
$groups = array_intersect_key($groups, [$key => true]);
|
||||
$desk = array_intersect_key($desk, [$key => true]);
|
||||
$businesses = array_intersect_key($businesses, [$key => true]);
|
||||
}
|
||||
|
||||
return ['interests' => $this->format($groups, $names), 'desk' => $this->format($desk, $names)];
|
||||
return ['interests' => $this->format($groups, $names), 'desk' => $this->format($desk, $names), 'businesses' => $this->format($businesses, $names)];
|
||||
}
|
||||
|
||||
/** @param array<string, int> $counts
|
||||
|
||||
@@ -81,7 +81,8 @@ final class ExistingBusinessIntake
|
||||
} elseif (($business->payload['wizard_version'] ?? null) === '1') {
|
||||
Validator::make($business->payload, [
|
||||
'proponent_type' => ['required'], 'proponent_name' => ['required'], 'tax_identifier' => ['required'],
|
||||
'contact_email' => ['required', 'email'], 'country' => ['required', 'regex:/^[A-Z]{2}$/'],
|
||||
'contact_email' => ['required', 'email'], 'country' => ['required', app(CountryCatalogue::class)->rule()],
|
||||
'declared_origin_country_code' => ['nullable', app(CountryCatalogue::class)->rule()],
|
||||
'acting_capacity' => ['required'], 'declared_holder' => ['required'], 'location_notes' => ['required'],
|
||||
'legitimacy_declaration' => ['required', 'in:yes'],
|
||||
'mandate_reference' => ['required_if:acting_capacity,representative'],
|
||||
|
||||
@@ -0,0 +1,334 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\CrmTask;
|
||||
use App\Models\SimulationFormDraft;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
final class InvestorPath
|
||||
{
|
||||
public function __construct(private readonly VirtualDesk $desk) {}
|
||||
|
||||
public function available(): bool
|
||||
{
|
||||
return (bool) config('investor-path.enabled') && $this->desk->installed()
|
||||
&& Schema::hasColumn('investor_journeys', 'path_definition_id') && Schema::hasColumn('journey_steps', 'path_detail');
|
||||
}
|
||||
|
||||
/** @param array<string,mixed> $input */
|
||||
public function create(User $actor, array $input): string
|
||||
{
|
||||
abort_unless($this->available(), 404);
|
||||
|
||||
return DB::transaction(function () use ($actor, $input): string {
|
||||
$case = $this->desk->createCase($actor, $input);
|
||||
$this->initialize($actor, $case->id);
|
||||
|
||||
return $case->id;
|
||||
});
|
||||
}
|
||||
|
||||
public function initialize(User $actor, string $id): void
|
||||
{
|
||||
abort_unless($this->available(), 404);
|
||||
DB::transaction(function () use ($actor, $id): void {
|
||||
$case = $this->desk->case($actor, $id, true, true);
|
||||
abort_if($case->closed_at, 409);
|
||||
if ($case->journey_id) {
|
||||
$existing = DB::table('investor_journeys')->where('id', $case->journey_id)->firstOrFail();
|
||||
// Never convert or renumber a saved portfolio/legacy journey implicitly.
|
||||
abort_unless($existing->path_definition_id !== null, 409, 'O percurso existente foi preservado; a conversão exige uma correspondência explícita.');
|
||||
|
||||
return;
|
||||
}
|
||||
$version = DB::table('questionnaire_versions')->where('id', config('investor-path.definition_id'))
|
||||
->where('code', 'investor-path-19')->where('status', 'published')->firstOrFail();
|
||||
$definition = json_decode($version->schema_snapshot, true, 512, JSON_THROW_ON_ERROR);
|
||||
InvestorPathDefinition::validate($definition);
|
||||
$journey = (string) Str::uuid();
|
||||
DB::table('investor_journeys')->insert(['id' => $journey, 'investor_id' => $case->investor_id, 'user_id' => $actor->id,
|
||||
'status' => 'started', 'path_definition_id' => $version->id, 'source_system' => 'investor-path', 'data_classification' => 'confidential']);
|
||||
foreach ($definition['steps'] as $step) {
|
||||
DB::table('journey_steps')->insert(['id' => (string) Str::uuid(), 'journey_id' => $journey, 'step_code' => $step['code'],
|
||||
'sequence_no' => $step['sequence'], 'status' => 'pending', 'source_system' => 'investor-path', 'data_classification' => 'confidential',
|
||||
'path_detail' => $this->desk->encode(['state' => 'not_started'])]);
|
||||
}
|
||||
DB::table('desk_cases')->where('id', $id)->update(['journey_id' => $journey, 'version' => $case->version + 1, 'updated_at' => now()]);
|
||||
$this->desk->event($this->desk->case($actor, $id), $actor, 'investor_path_started', ['journey_id' => $journey, 'definition_id' => $version->id, 'source_sha256' => $definition['source_sha256']]);
|
||||
});
|
||||
}
|
||||
|
||||
/** @return array<string,mixed> */
|
||||
public function view(User $actor, string $id): array
|
||||
{
|
||||
abort_unless($this->available(), 404);
|
||||
$case = $this->desk->case($actor, $id);
|
||||
$journey = DB::table('investor_journeys')->where('id', $case->journey_id)->whereNull('deleted_at')->firstOrFail();
|
||||
abort_unless($journey->path_definition_id !== null, 409, 'Este dossier conserva o seu roteiro original.');
|
||||
$version = DB::table('questionnaire_versions')->where('id', $journey->path_definition_id)->firstOrFail();
|
||||
$definition = json_decode($version->schema_snapshot, true, 512, JSON_THROW_ON_ERROR);
|
||||
$payload = $this->desk->decode($case->payload);
|
||||
$path = $payload['investor_path'] ?? [];
|
||||
$facts = $path['facts'] ?? ['land_needed' => 'unknown', 'external_funding' => 'unknown', 'viability' => 'unknown'];
|
||||
$records = DB::table('journey_steps')->where('journey_id', $journey->id)->whereNull('deleted_at')->get()->keyBy('step_code');
|
||||
$steps = [];
|
||||
foreach ($definition['steps'] as $step) {
|
||||
$row = $records->get($step['code']);
|
||||
abort_unless($row !== null, 409, 'Etapa em falta; reparar a instalação sem reconstruir o histórico.');
|
||||
$detail = $this->desk->decode($row->path_detail);
|
||||
$value = $step['branch'] ? ($facts[$step['branch']] ?? 'unknown') : 'yes';
|
||||
$applicable = $value === 'unknown' ? 'undetermined' : ($value === 'no' ? 'not_needed_for_preparation' : 'applicable');
|
||||
$state = $value === 'no' ? 'dispensed' : $detail['state'];
|
||||
$steps[] = [...$step, 'id' => $row->id, 'version' => $row->version_no, 'state' => $state, 'saved_state' => $detail['state'],
|
||||
'applicability' => $applicable, 'reason' => $value === 'no' ? ($path['fact_reasons'][$step['branch']] ?? '') : ($detail['reason'] ?? ''),
|
||||
'detail' => $detail, 'preparation_allowed' => $value !== 'no',
|
||||
'action_gaps' => []];
|
||||
}
|
||||
$byCode = collect($steps)->keyBy('code');
|
||||
foreach ($steps as &$step) {
|
||||
foreach ($step['dependencies'] as $action => $dependencies) {
|
||||
$step['action_gaps'][$action] = array_values(array_filter($dependencies, function ($code) use ($byCode) {
|
||||
$dependency = $byCode->get($code);
|
||||
|
||||
// Branch dispensation is not evidence of any legal permission.
|
||||
return ! in_array($dependency['state'], ['completed', 'approved'], true);
|
||||
}));
|
||||
}
|
||||
}
|
||||
unset($step);
|
||||
foreach ($steps as &$step) {
|
||||
if (in_array($step['state'], ['completed', 'submitted'], true)
|
||||
&& count(array_filter($step['action_gaps'])) > 0) {
|
||||
$step['state'] = 'correction_required';
|
||||
$step['reason'] = 'Uma dependência desta acção foi reaberta; reveja o avanço. O registo original foi preservado.';
|
||||
}
|
||||
}
|
||||
unset($step);
|
||||
$owner = $this->desk->owns($actor, $case);
|
||||
$manager = $actor->can('manage-portal');
|
||||
$requests = DB::table('desk_requests')->where('case_id', $id)
|
||||
->when(! $owner && ! $manager, fn ($q) => $q->where('analyst_id', $actor->id))
|
||||
->orderByDesc('updated_at')->get(['id', 'status', 'protocol', 'version']);
|
||||
$documents = DB::table('desk_documents as l')->join('documents as d', 'd.id', '=', 'l.document_id')
|
||||
->where('l.case_id', $id)->whereNull('d.deleted_at')
|
||||
->when(! $owner && ! $manager, fn ($q) => $q->where(fn ($p) => $p->whereNull('l.request_id')->orWhereIn('l.request_id', $requests->pluck('id'))))
|
||||
->get(['l.id', 'l.document_id', 'd.file_name', 'd.status', 'd.malware_scan_status']);
|
||||
// Only the private draft owner can receive the financial snapshot/result. Dossier access alone is insufficient.
|
||||
$results = (int) $case->user_id === $actor->id ? ($path['results'] ?? []) : [];
|
||||
$next = collect($steps)->first(fn ($step) => $step['preparation_allowed'] && ! in_array($step['state'], ['completed', 'approved', 'waiting_external', 'submitted', 'reviewing'], true));
|
||||
|
||||
return ['case' => ['id' => $id, 'title' => $case->title, 'version' => $case->version, 'closed' => $case->closed_at !== null],
|
||||
'journey_id' => $journey->id, 'definition_id' => $version->id, 'definition_version' => $version->version_no, 'source_sha256' => $definition['source_sha256'],
|
||||
'phases' => $definition['phases'], 'steps' => $steps, 'facts' => $facts, 'fact_reasons' => $path['fact_reasons'] ?? [],
|
||||
'canWrite' => $owner && ! $case->closed_at, 'canReview' => $manager && (int) $case->user_id !== $actor->id && ! $case->closed_at,
|
||||
'next' => $next ? ['code' => $next['code'], 'title' => $next['title'], 'action' => 'Preparar', 'href' => '#'.$next['code']] : null,
|
||||
'results' => $results, 'requests' => $requests, 'documents' => $documents,
|
||||
'tasks' => DB::table('tasks')->where('desk_case_id', $id)
|
||||
->whereNull('deleted_at')
|
||||
->when(! $owner && ! $manager, fn ($q) => $q->where('assignee_user_id', $actor->id))
|
||||
->get(['id', 'title', 'status', 'version_no', 'due_at', 'assignee_user_id']),
|
||||
'services' => DB::table('desk_service_versions')->where('status', 'published')->orderByDesc('version')->get(['id', 'code', 'definition'])
|
||||
->unique('code')->values()->map(fn ($s) => ['id' => $s->id, 'title' => json_decode($s->definition, true)['title']]),
|
||||
'tools' => ['simulator' => (int) $case->user_id === $actor->id ? '/simulador-fiscal?context='.$id.($case->simulation_id ? '&draft='.$case->simulation_id : '') : null,
|
||||
'desk' => '/balcao-virtual/dossiers/'.$id, 'guidance' => '/balcao-virtual/dossiers/'.$id.'/orientacao',
|
||||
'library' => '/documentos?context='.$id, 'opportunities' => '/oportunidades?context='.$id, 'territory' => '/zonas?context='.$id, 'partners' => '/parcerias/painel?context='.$id]];
|
||||
}
|
||||
|
||||
/** @param array<string,mixed> $input */
|
||||
public function facts(User $actor, string $id, array $input): void
|
||||
{
|
||||
$data = Validator::make($input, ['version' => 'required|integer|min:1',
|
||||
'land_needed' => ['required', Rule::in(['yes', 'no', 'unknown'])], 'external_funding' => ['required', Rule::in(['yes', 'no', 'unknown'])],
|
||||
'viability' => ['required', Rule::in(['unknown', 'proceed', 'reformulate', 'archive'])],
|
||||
'reason' => 'required|string|min:3|max:3000'])->validate();
|
||||
DB::transaction(function () use ($actor, $id, $data): void {
|
||||
$case = $this->writable($actor, $id, $data['version']);
|
||||
$payload = $this->desk->decode($case->payload);
|
||||
foreach (['land_needed', 'external_funding', 'viability'] as $key) {
|
||||
$payload['investor_path']['facts'][$key] = $data[$key];
|
||||
$payload['investor_path']['fact_reasons'][$key] = $data['reason'];
|
||||
}
|
||||
$this->savePayload($case, $payload);
|
||||
$this->desk->event($this->desk->case($actor, $id), $actor, 'path_applicability_declared', $data);
|
||||
});
|
||||
}
|
||||
|
||||
/** @param array<string,mixed> $input */
|
||||
public function stage(User $actor, string $id, string $code, array $input): void
|
||||
{
|
||||
$data = Validator::make($input, ['version' => 'required|integer|min:1', 'state' => ['required', Rule::in(array_diff(InvestorPathDefinition::STATES, ['dispensed']))],
|
||||
'reason' => 'required|string|min:3|max:3000', 'action' => ['required', Rule::in(['prepare', 'submit', 'execute', 'operate', 'review', 'record_external'])],
|
||||
'document_id' => 'nullable|uuid', 'authority' => 'nullable|string|max:200', 'reference' => 'nullable|string|max:300',
|
||||
'decision_date' => 'nullable|date_format:Y-m-d|before_or_equal:today'])->validate();
|
||||
DB::transaction(function () use ($actor, $id, $code, $data): void {
|
||||
$case = $this->desk->case($actor, $id, false, true);
|
||||
abort_if($case->closed_at, 409);
|
||||
abort_unless((int) $case->version === $data['version'], 409, 'O dossier mudou; recupere a versão actual.');
|
||||
$view = $this->view($actor, $id);
|
||||
$step = $this->findStep($view, $code);
|
||||
abort_unless($step !== null && $step['preparation_allowed'], 422, 'Etapa dispensada de preparação; altere os pressupostos com fundamento.');
|
||||
$state = $data['state'];
|
||||
$internal = in_array($state, ['reviewing', 'correction_required'], true);
|
||||
$external = in_array($state, ['approved', 'rejected', 'expired'], true);
|
||||
$scope = 'investor_preparation';
|
||||
if ($internal || $external) {
|
||||
abort_unless($view['canReview'], 403, 'A conferência interna exige um responsável distinto do promotor.');
|
||||
abort_unless($data['action'] === ($external ? 'record_external' : 'review'), 422);
|
||||
$scope = $external ? 'external_document_recorded' : 'internal_validation';
|
||||
} else {
|
||||
abort_unless($view['canWrite'], 403);
|
||||
abort_unless(! in_array($data['action'], ['review', 'record_external'], true), 422);
|
||||
if ($state === 'submitted') {
|
||||
abort_unless($data['action'] === 'submit' && ! empty($data['reference']), 422, 'Registe a referência da submissão; guardar não equivale a submeter.');
|
||||
}
|
||||
}
|
||||
if ($external || $data['action'] !== 'prepare') {
|
||||
abort_unless(empty($step['action_gaps'][$data['action']] ?? []), 422,
|
||||
'Dependências reais da acção: '.implode(', ', $step['action_gaps'][$data['action']] ?? []));
|
||||
}
|
||||
if ($external) {
|
||||
abort_unless(! empty($data['document_id']) && ! empty($data['authority']) && ! empty($data['reference']) && ! empty($data['decision_date']), 422, 'Registe documento, entidade, referência e data do acto externo.');
|
||||
$doc = DB::table('desk_documents as l')->join('documents as d', 'd.id', '=', 'l.document_id')->where('l.case_id', $id)
|
||||
->where('d.id', $data['document_id'])->whereNull('d.deleted_at')->first(['d.status', 'd.malware_scan_status', 'd.sha256', 'd.malware_scanned_sha256']);
|
||||
abort_unless($doc && $doc->status === 'active' && $doc->malware_scan_status === 'clean' && trim($doc->sha256) === $doc->malware_scanned_sha256, 422, 'Documento de decisão ainda não consultável.');
|
||||
}
|
||||
// Completion of a legal/finance/operation action requires the corresponding evidence; preparation can proceed independently.
|
||||
if ($state === 'completed' && in_array($code, ['S07', 'S08', 'S10', 'S11', 'S14', 'S15', 'S17', 'S18'], true)) {
|
||||
abort_unless(($step['saved_state'] ?? '') === 'approved' && in_array($data['action'], ['execute', 'operate'], true), 422, 'Conclusão operacional exige acto externo documentado; use preparação enquanto aguarda.');
|
||||
}
|
||||
$detail = [...$data, 'scope' => $scope, 'actor_id' => $actor->id, 'recorded_at' => now()->toIso8601String()];
|
||||
DB::table('journey_steps')->where('id', $step['id'])->update(['path_detail' => $this->desk->encode($detail),
|
||||
'status' => in_array($state, ['completed', 'approved'], true) ? 'completed' : ($state === 'not_started' ? 'pending' : 'active'),
|
||||
'version_no' => $step['version'] + 1, 'updated_at' => now()]);
|
||||
DB::table('desk_cases')->where('id', $id)->update(['version' => $case->version + 1, 'updated_at' => now()]);
|
||||
$this->desk->event($this->desk->case($actor, $id), $actor, 'path_stage_recorded', ['code' => $code, ...$detail]);
|
||||
});
|
||||
}
|
||||
|
||||
/** @param array<string,mixed> $input
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function returnTool(Request $request, string $id, array $input): array
|
||||
{
|
||||
$data = Validator::make($input, ['version' => 'required|integer|min:1', 'draft_id' => 'required|uuid', 'draft_version' => 'required|integer|min:1'])->validate();
|
||||
|
||||
return DB::transaction(function () use ($request, $id, $data): array {
|
||||
$actor = $request->user();
|
||||
$case = $this->desk->case($actor, $id, true, true);
|
||||
abort_if($case->closed_at, 409);
|
||||
abort_unless($case->simulation_id === $data['draft_id'] && (int) $case->user_id === $actor->id, 403, 'Ferramenta pertencente a outro contexto.');
|
||||
$draft = app(SimulationFormDrafts::class)->find($data['draft_id'], $request);
|
||||
abort_unless($draft->version_no === $data['draft_version'], 409, 'O rascunho mudou; aguarde a gravação e volte a recuperar o resultado.');
|
||||
$economic = SimulationFormDraft::decryptSnapshot($draft->economic_snapshot);
|
||||
$snapshot = $economic['financial_tools_snapshot'] ?? null;
|
||||
abort_unless(is_string($snapshot) && strlen($snapshot) <= 30000, 422, 'Guarde primeiro as entradas da ferramenta financeira.');
|
||||
$parsed = json_decode($snapshot, true);
|
||||
abort_unless(is_array($parsed) && ($parsed['version'] ?? null) === 1 && is_array($parsed['data'] ?? null), 422, 'Snapshot financeiro incompatível.');
|
||||
$payload = $this->desk->decode($case->payload);
|
||||
$resultKey = hash('sha256', $draft->id.':'.$draft->version_no.':'.$snapshot);
|
||||
foreach ($payload['investor_path']['results'] ?? [] as $result) {
|
||||
if ($result['source_key'] === $resultKey) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
abort_unless((int) $case->version === $data['version'], 409, 'Recupere a versão actual do dossier.');
|
||||
$result = ['id' => (string) Str::uuid(), 'source_key' => $resultKey, 'draft_id' => $draft->id, 'draft_version' => $draft->version_no,
|
||||
'snapshot_sha256' => $draft->snapshot_sha256, 'financial_snapshot' => $snapshot,
|
||||
'currency' => $economic['currency'] ?? null, 'engine' => 'financial-calculators:v1',
|
||||
'kind' => 'local_calculation_inputs', 'recorded_at' => now()->toIso8601String()];
|
||||
$payload['investor_path']['results'][] = $result;
|
||||
abort_unless(count($payload['investor_path']['results']) <= 100, 422, 'Limite de evidências financeiras deste dossier atingido.');
|
||||
$this->savePayload($case, $payload);
|
||||
$this->desk->event($this->desk->case($actor, $id), $actor, 'tool_evidence_returned', array_diff_key($result, ['financial_snapshot' => true]));
|
||||
|
||||
return $result;
|
||||
});
|
||||
}
|
||||
|
||||
/** @return list<array<string,mixed>> */
|
||||
public function contexts(User $actor): array
|
||||
{
|
||||
if (! $this->available()) {
|
||||
return [];
|
||||
}
|
||||
$organizations = DB::table('memberships')->where('user_id', $actor->id)->whereNull('deleted_at')->pluck('organization_id');
|
||||
|
||||
$contexts = DB::table('desk_cases as c')->join('investor_journeys as j', 'j.id', '=', 'c.journey_id')->whereNotNull('j.path_definition_id')
|
||||
->whereNull('j.deleted_at')->whereNull('c.closed_at')->where(fn ($q) => $q->where(fn ($p) => $p->where('c.user_id', $actor->id)->whereNull('c.organization_id'))->orWhereIn('c.organization_id', $organizations))
|
||||
->orderByDesc('c.updated_at')->get(['c.id', 'c.title', 'c.version', 'c.updated_at'])
|
||||
->map(fn ($row) => ['id' => $row->id, 'title' => $row->title, 'version' => $row->version, 'updated_at' => $row->updated_at])->all();
|
||||
|
||||
return array_values($contexts);
|
||||
}
|
||||
|
||||
/** @param array<string,mixed> $input */
|
||||
public function task(User $actor, string $id, array $input): string
|
||||
{
|
||||
$data = Validator::make($input, ['version' => 'required|integer|min:1', 'code' => ['required', Rule::in(array_map(fn ($n) => sprintf('S%02d', $n), range(1, 19)))],
|
||||
'title' => 'required|string|min:3|max:200', 'due_at' => 'required|date|after:now', 'consent' => 'accepted'])->validate();
|
||||
|
||||
return DB::transaction(function () use ($actor, $id, $data): string {
|
||||
$case = $this->desk->case($actor, $id, true, true);
|
||||
abort_if($case->closed_at, 409);
|
||||
$key = 'path:'.$data['code'];
|
||||
$existing = DB::table('tasks')->where('desk_case_id', $id)->where('guidance_key', $key)->first();
|
||||
if ($existing) {
|
||||
abort_unless($existing->title === $data['title'] && (int) $existing->accepted_by === $actor->id
|
||||
&& Carbon::parse($existing->due_at)->equalTo(Carbon::parse($data['due_at'])), 409, 'A tarefa desta etapa já existe com outros dados.');
|
||||
|
||||
return $existing->id;
|
||||
}
|
||||
$this->writable($actor, $id, $data['version']);
|
||||
$step = $this->findStep($this->view($actor, $id), $data['code']);
|
||||
abort_unless($step !== null && $step['preparation_allowed'], 422);
|
||||
$task = CrmTask::create(['desk_case_id' => $id, 'guidance_key' => $key, 'title' => $data['title'], 'due_at' => $data['due_at'],
|
||||
'status' => 'open', 'assignee_user_id' => $actor->id, 'accepted_by' => $actor->id, 'accepted_at' => now(),
|
||||
'external_sync_status' => 'pending_authorization', 'data_classification' => 'confidential', 'source_system' => 'investor-path']);
|
||||
$this->desk->event($case, $actor, 'path_task_accepted', ['task_id' => $task->id, 'code' => $data['code'], 'scope' => 'internal_crm']);
|
||||
|
||||
return $task->id;
|
||||
});
|
||||
}
|
||||
|
||||
private function writable(User $actor, string $id, int $version): \stdClass
|
||||
{
|
||||
abort_unless($this->available(), 404);
|
||||
$case = $this->desk->case($actor, $id, true, true);
|
||||
abort_if($case->closed_at, 409);
|
||||
abort_unless((int) $case->version === $version, 409, 'Recupere a versão actual do dossier.');
|
||||
$this->view($actor, $id);
|
||||
|
||||
return $case;
|
||||
}
|
||||
|
||||
/** @param array<string,mixed> $view
|
||||
* @return array<string,mixed>|null
|
||||
*/
|
||||
private function findStep(array $view, string $code): ?array
|
||||
{
|
||||
if (! is_array($view['steps'] ?? null)) {
|
||||
return null;
|
||||
}
|
||||
foreach ($view['steps'] as $step) {
|
||||
if (is_array($step) && ($step['code'] ?? null) === $code) {
|
||||
return $step;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @param array<string,mixed> $payload */
|
||||
private function savePayload(\stdClass $case, array $payload): void
|
||||
{
|
||||
DB::table('desk_cases')->where('id', $case->id)->update(['payload' => $this->desk->encode($payload), 'version' => $case->version + 1, 'updated_at' => now()]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
final class InvestorPathDefinition
|
||||
{
|
||||
public const STATES = ['not_started', 'preparing', 'ready_to_submit', 'submitted', 'reviewing', 'correction_required', 'waiting_external', 'approved', 'rejected', 'dispensed', 'completed', 'expired'];
|
||||
|
||||
/** @return array<string,mixed> */
|
||||
public static function snapshot(): array
|
||||
{
|
||||
$titles = ['Sistematizar a ideia', 'Análise preliminar', 'Decisão sobre a viabilidade', 'Estruturar o investimento',
|
||||
'Constituição e registo', 'Preparar o dossier', 'Submeter quando aplicável', 'Licenciamento prévio',
|
||||
'Necessidade de terra', 'Regularização da terra', 'Confirmar regularização aplicável',
|
||||
'Necessidade e estrutura de financiamento', 'Diligência e negociação financeira', 'Decisão do financiador',
|
||||
'Fecho e desembolso', 'Implementação', 'Inspecções, testes e licença de operação', 'Início de operação', 'Acompanhamento recorrente'];
|
||||
$steps = [];
|
||||
foreach ($titles as $index => $title) {
|
||||
$n = $index + 1;
|
||||
$steps[] = ['code' => sprintf('S%02d', $n), 'sequence' => $n, 'title' => $title,
|
||||
'phase' => $n <= 4 ? 1 : ($n <= 7 ? 2 : ($n <= 11 ? 3 : ($n <= 15 ? 4 : 5))),
|
||||
'source_paragraph' => 21 + $n,
|
||||
'branch' => $n === 10 ? 'land_needed' : (in_array($n, [13, 14, 15], true) ? 'external_funding' : null),
|
||||
// Preparation has no dependencies. These only constrain the named consequential action.
|
||||
'dependencies' => match ($n) {
|
||||
7 => ['submit' => ['S06']],
|
||||
15 => ['execute' => ['S14']],
|
||||
18 => ['operate' => ['S17']],
|
||||
default => [],
|
||||
}];
|
||||
}
|
||||
|
||||
return ['kind' => 'investor-path', 'version' => 1,
|
||||
'source_sha256' => 'aa13c53138ec15cd808de43d9dc2fc6808da86943d09d3352c9dd0944bdae364',
|
||||
'phases' => [1 => 'Ideia e viabilidade', 2 => 'Formalização e dossier', 3 => 'Licenciamento e terra', 4 => 'Financiamento', 5 => 'Execução e acompanhamento'],
|
||||
'states' => self::STATES, 'steps' => $steps,
|
||||
'legacy_roadmaps' => ['virtual-desk:E0-E11', 'investor-guidance:7-phases', 'investment-roadmap:14-activities']];
|
||||
}
|
||||
|
||||
/** @param array<string,mixed> $definition */
|
||||
public static function validate(array $definition): void
|
||||
{
|
||||
$steps = $definition['steps'] ?? [];
|
||||
$expected = array_map(fn ($n) => sprintf('S%02d', $n), range(1, 19));
|
||||
if (count($definition['phases'] ?? []) !== 5 || array_column($steps, 'code') !== $expected
|
||||
|| array_column($steps, 'sequence') !== range(1, 19)) {
|
||||
throw new \LogicException('The five phases and nineteen source stages must remain traceable.');
|
||||
}
|
||||
$edges = [];
|
||||
foreach ($steps as $step) {
|
||||
if (! in_array($step['phase'], range(1, 5), true)
|
||||
|| ! in_array($step['branch'], [null, 'land_needed', 'external_funding'], true)) {
|
||||
throw new \LogicException('Unknown phase or applicability field.');
|
||||
}
|
||||
$edges[$step['code']] = [];
|
||||
foreach ($step['dependencies'] as $action => $dependencies) {
|
||||
if (! in_array($action, ['submit', 'execute', 'operate'], true)
|
||||
|| array_diff($dependencies, $expected)) {
|
||||
throw new \LogicException('Unknown action/dependency; preparation cannot be blocked.');
|
||||
}
|
||||
$edges[$step['code']] = array_merge($edges[$step['code']], $dependencies);
|
||||
}
|
||||
}
|
||||
$visit = function (string $code, array $trail) use (&$visit, $edges): void {
|
||||
if (in_array($code, $trail, true)) {
|
||||
throw new \LogicException('Cyclic action dependencies.');
|
||||
}
|
||||
foreach ($edges[$code] as $next) {
|
||||
$visit($next, [...$trail, $code]);
|
||||
}
|
||||
};
|
||||
foreach ($expected as $code) {
|
||||
$visit($code, []);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,17 @@ class OpportunityManagement
|
||||
|
||||
public const FIELDS = ['title', 'summary', 'description', 'sector_id', 'promoter_name', 'promoter_type', 'maturity_level', 'maturity_label', 'financing_modality', 'expected_impact', 'estimated_investment_amount', 'estimated_investment_currency', 'opportunity_category', 'primary_territory_id', 'province', 'district', 'geography_scope'];
|
||||
|
||||
public const MATURITY_FIELDS = ['maturity_level', 'maturity_label', 'maturity_stage', 'maturity_catalogue_version'];
|
||||
|
||||
/** @return array<string,mixed> */
|
||||
public function values(Opportunity $record): array
|
||||
{
|
||||
$base = $record->only(self::FIELDS);
|
||||
$draft = $record->management_draft ? json_decode($record->management_draft, true, 512, JSON_THROW_ON_ERROR) : [];
|
||||
|
||||
return [...$base, ...($this->closed($record) ? $draft : array_intersect_key($draft, array_flip(self::MATURITY_FIELDS)))];
|
||||
}
|
||||
|
||||
public function installed(): bool
|
||||
{
|
||||
return Schema::hasColumn('opportunities', 'management_version');
|
||||
@@ -44,7 +55,9 @@ class OpportunityManagement
|
||||
'title' => ['nullable', 'string', 'max:150'], 'summary' => ['nullable', 'string', 'max:500'],
|
||||
'description' => ['nullable', 'string', 'max:50000'], 'promoter_name' => ['nullable', 'string', 'max:200'],
|
||||
'promoter_type' => ['nullable', Rule::in(['public', 'private', 'ppp', 'cooperative', 'association', 'community', 'other', $id ? Opportunity::withTrashed()->findOrFail($id)->promoter_type : null])],
|
||||
'maturity_level' => ['nullable', 'integer', 'between:1,6'],
|
||||
'maturity_level' => ['nullable', 'integer', 'between:1,8'],
|
||||
'maturity_stage' => ['nullable', Rule::in(array_keys(OpportunityMaturity::STAGES))],
|
||||
'maturity_catalogue_version' => ['nullable', Rule::in([OpportunityMaturity::VERSION, OpportunityMaturity::LEGACY])],
|
||||
'financing_modality' => ['nullable', 'string', 'max:120'],
|
||||
'expected_impact' => ['nullable', 'string', 'max:10000'],
|
||||
'sector_id' => ['nullable', 'integer', Rule::exists('sectors', 'id')->whereNull('deleted_at')->where('is_active', true)],
|
||||
@@ -54,12 +67,13 @@ class OpportunityManagement
|
||||
'reason' => ['required', 'string', 'min:20', 'max:1000'],
|
||||
'province_id' => ['nullable', 'uuid'], 'district_id' => ['nullable', 'uuid'], 'admin_post_id' => ['nullable', 'uuid'], 'locality_id' => ['nullable', 'uuid'],
|
||||
])->validate();
|
||||
$data = app(OpportunityMaturity::class)->normalize($data);
|
||||
|
||||
return DB::transaction(function () use ($actor, $data, $id) {
|
||||
DB::select('SELECT pg_advisory_xact_lock(91026, 100000)');
|
||||
if (! $id && ($existing = Opportunity::withTrashed()->where('management_creation_key', $data['creation_key'])->first())) {
|
||||
$snapshot = $existing->management_draft ? json_decode($existing->management_draft, true) : $existing->only(self::FIELDS);
|
||||
foreach (array_intersect_key($data, array_flip(self::FIELDS)) as $key => $value) {
|
||||
$snapshot = $this->values($existing);
|
||||
foreach (array_intersect_key($data, array_flip([...self::FIELDS, ...self::MATURITY_FIELDS])) as $key => $value) {
|
||||
if (($snapshot[$key] ?? null) != $value) {
|
||||
throw ValidationException::withMessages(['creation_key' => 'Esta chave já foi utilizada com dados diferentes.']);
|
||||
}
|
||||
@@ -73,11 +87,7 @@ class OpportunityManagement
|
||||
abort_if($record->trashed() || $record->status === 'archived', 409, 'Restaure antes de editar.');
|
||||
}
|
||||
$before = $record->getAttributes();
|
||||
$changes = array_intersect_key($data, array_flip(self::FIELDS));
|
||||
if (array_key_exists('maturity_level', $changes)) {
|
||||
$labels = [1 => 'Ideia identificada', 'Pré-estudo disponível', 'Estudo de viabilidade em curso', 'Projecto estruturado', 'Pronto para investimento', 'Em negociação ou implementação'];
|
||||
$changes['maturity_label'] = $labels[$changes['maturity_level'] ?? 0] ?? null;
|
||||
}
|
||||
$changes = array_intersect_key($data, array_flip([...self::FIELDS, ...self::MATURITY_FIELDS]));
|
||||
if (array_intersect_key($data, InvestmentGeography::FIELDS) !== []) {
|
||||
$path = app(InvestmentGeography::class)->selection($data, true);
|
||||
$changes['primary_territory_id'] = $path === [] ? null : $path[array_key_last($path)]->id;
|
||||
@@ -101,8 +111,16 @@ class OpportunityManagement
|
||||
$record->management_draft = json_encode([...$previous, ...$changes], JSON_THROW_ON_ERROR);
|
||||
} else {
|
||||
foreach ($changes as $key => $value) {
|
||||
if (in_array($key, ['maturity_stage', 'maturity_catalogue_version'], true) || (($changes['maturity_catalogue_version'] ?? null) === OpportunityMaturity::VERSION && in_array($key, ['maturity_level', 'maturity_label'], true))) {
|
||||
continue;
|
||||
}
|
||||
$record->{$key} = $value;
|
||||
}
|
||||
if (isset($changes['maturity_catalogue_version'])) {
|
||||
// The existing draft JSON holds the versioned catalogue; legacy columns stay intact.
|
||||
$previous = $record->management_draft ? json_decode($record->management_draft, true, 512, JSON_THROW_ON_ERROR) : [];
|
||||
$record->management_draft = json_encode([...$previous, ...array_intersect_key($changes, array_flip(self::MATURITY_FIELDS))], JSON_THROW_ON_ERROR);
|
||||
}
|
||||
}
|
||||
$record->save();
|
||||
$this->audit($record, $actor, $before, $id ? 'draft_updated' : 'draft_created', $data['reason']);
|
||||
|
||||
@@ -14,6 +14,8 @@ class OpportunityManagementInstallation
|
||||
{
|
||||
$files = [__FILE__, app_path('Models/Opportunity.php'), app_path('Services/OpportunityManagement.php'), app_path('Http/Controllers/OpportunityManagementController.php'), app_path('Http/Controllers/PortalManagementController.php'), database_path('migrations/'.self::MIGRATION.'.php'), base_path('routes/web.php'), resource_path('js/pages/management/opportunity-draft.tsx'), resource_path('js/pages/management/opportunities.tsx')];
|
||||
|
||||
$files[] = app_path('Services/OpportunityMaturity.php');
|
||||
|
||||
return hash('sha256', json_encode(array_map(fn ($file) => hash_file('sha256', $file), $files), JSON_THROW_ON_ERROR));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
/** Catalogue versions are not interchangeable: historical positions keep their meaning. */
|
||||
final class OpportunityMaturity
|
||||
{
|
||||
public const VERSION = 'spec-v2';
|
||||
|
||||
public const LEGACY = 'legacy-v1';
|
||||
|
||||
public const STAGES = [
|
||||
'idea' => 'Ideia',
|
||||
'concept' => 'Conceito',
|
||||
'prefeasibility' => 'Pré-viabilidade',
|
||||
'feasibility' => 'Viabilidade',
|
||||
'structured' => 'Estruturado',
|
||||
'investment_ready' => 'Pronto para investimento',
|
||||
'implementation' => 'Implementação',
|
||||
'operational' => 'Operacional',
|
||||
];
|
||||
|
||||
public const LEGACY_LABELS = [1 => 'Ideia identificada', 'Pré-estudo disponível', 'Estudo de viabilidade em curso', 'Projecto estruturado', 'Pronto para investimento', 'Em negociação ou implementação'];
|
||||
|
||||
/** @param array<string,mixed> $data
|
||||
* @return array<string,mixed> */
|
||||
public function normalize(array $data): array
|
||||
{
|
||||
if (! array_key_exists('maturity_level', $data) && ! array_key_exists('maturity_stage', $data)) {
|
||||
if (isset($data['maturity_catalogue_version'])) {
|
||||
throw ValidationException::withMessages(['maturity_catalogue_version' => 'Seleccione também a etapa; mudar só a versão não converte o valor histórico.']);
|
||||
}
|
||||
unset($data['maturity_catalogue_version']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
$level = isset($data['maturity_level']) ? (int) $data['maturity_level'] : null;
|
||||
$version = $data['maturity_catalogue_version'] ?? ((isset($data['maturity_stage']) || ($level ?? 0) > 6) ? self::VERSION : self::LEGACY);
|
||||
if ($version === self::LEGACY) {
|
||||
if (($level ?? 0) > 6 || isset($data['maturity_stage'])) {
|
||||
throw ValidationException::withMessages(['maturity_level' => 'O catálogo histórico tem seis níveis; seleccione explicitamente o catálogo de oito etapas.']);
|
||||
}
|
||||
|
||||
return [...$data, 'maturity_catalogue_version' => self::LEGACY, 'maturity_stage' => null, 'maturity_label' => self::LEGACY_LABELS[$level ?? 0] ?? null];
|
||||
}
|
||||
$codes = array_keys(self::STAGES);
|
||||
$stage = $data['maturity_stage'] ?? ($level !== null ? $codes[$level - 1] : null);
|
||||
if ($stage !== null && $level !== null && $codes[$level - 1] !== $stage) {
|
||||
throw ValidationException::withMessages(['maturity_stage' => 'O código da etapa e a posição no catálogo não correspondem.']);
|
||||
}
|
||||
|
||||
return [...$data, 'maturity_catalogue_version' => self::VERSION, 'maturity_stage' => $stage,
|
||||
'maturity_level' => $stage !== null ? array_search($stage, $codes, true) + 1 : null,
|
||||
'maturity_label' => $stage !== null ? self::STAGES[$stage] : null];
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,20 @@ class OpportunityResourceInstallation
|
||||
|
||||
$files = [...$files, app_path('Services/CountryCatalogue.php'), app_path('Services/DeclaredOriginStatistics.php'), app_path('Services/VirtualDesk.php'), app_path('Http/Controllers/CrmController.php'), app_path('Http/Controllers/InvestmentWorkspaceController.php'), app_path('Http/Controllers/InvestmentSubmissionController.php'), app_path('Http/Controllers/InvestmentDiscoveryController.php'), app_path('Http/Controllers/VirtualDeskController.php'), resource_path('data/iso3166.tab'), resource_path('js/components/country-select.tsx'), resource_path('js/components/investment-territory.tsx'), resource_path('js/pages/investment/profile.tsx'), resource_path('js/pages/investment/submission.tsx'), resource_path('js/pages/investment/catalogue.tsx'), resource_path('js/pages/desk/request.tsx'), resource_path('js/pages/desk/panel.tsx'), resource_path('js/pages/crm/leads.tsx')];
|
||||
|
||||
$files = [...$files, app_path('Http/Controllers/PortalServicesController.php'), app_path('Http/Controllers/PublicPortalController.php'), app_path('Http/Controllers/InvestorWorkspaceController.php'), app_path('Http/Controllers/PublicBusinessOpportunityController.php'), app_path('Http/Controllers/Api/V1/InterestRequestController.php'), app_path('Http/Requests/StoreInterestRequestRequest.php'), resource_path('js/pages/portal/services.tsx'), resource_path('js/pages/PortalInvestidor.tsx'), resource_path('js/pages/portfolio/workspace.tsx'), resource_path('js/pages/investment/business-interest.tsx'), resource_path('js/lib/portal-api.ts')];
|
||||
|
||||
$files = [...$files, app_path('Http/Controllers/PortalManagementController.php'), resource_path('js/pages/management/interest.tsx')];
|
||||
$files = [...$files, app_path('Http/Controllers/Api/V1/ReferenceCatalogController.php'), base_path('routes/api.php'), resource_path('js/components/simulation-form.tsx')];
|
||||
$files[] = app_path('Http/Requests/StoreSimulationFormDraftRequest.php');
|
||||
$files = [...$files, app_path('Services/TerritoryGeometry.php'), app_path('Http/Controllers/InvestmentTerritoryController.php'), resource_path('js/components/territory-geometry-preview.tsx'), resource_path('js/components/interactive-investment-map.tsx'), resource_path('js/components/investment-map-panel.tsx')];
|
||||
$files = [...$files, app_path('Services/OpportunityManagement.php'), app_path('Services/OpportunityMaturity.php'), app_path('Services/BusinessFormSchema.php'), app_path('Http/Controllers/ExistingBusinessController.php'), app_path('Http/Controllers/LandAssistanceController.php'), app_path('Http/Requests/StoreLandAssistanceCaseRequest.php'), resource_path('js/pages/investment/business-wizard.tsx'), resource_path('js/pages/investment/businesses.tsx'), resource_path('js/pages/investment/business.tsx'), resource_path('js/pages/land-assistance/form.tsx'), resource_path('js/pages/management/interests.tsx')];
|
||||
$files = [...$files, app_path('Services/ExistingBusinessIntake.php'), resource_path('js/pages/land-assistance/case.tsx')];
|
||||
$files = [...$files, resource_path('js/pages/investment/detail.tsx'), resource_path('js/pages/partnerships/catalogue.tsx')];
|
||||
|
||||
$files = [...$files, app_path('Services/VerifiedDocumentBinary.php'), app_path('Services/TerritoryGeometryImport.php'), app_path('Http/Controllers/TerritoryGeometryImportController.php'), config_path('geometry-import.php'), resource_path('js/pages/management/territory-geometry-import.tsx'),
|
||||
base_path('bootstrap/app.php'), app_path('Providers/FortifyServiceProvider.php'), config_path('fortify.php'),
|
||||
resource_path('js/pages/auth/login.tsx'), resource_path('js/pages/auth/two-factor-challenge.tsx')];
|
||||
|
||||
return hash('sha256', json_encode(array_map(fn ($file) => hash_file('sha256', $file), $files), JSON_THROW_ON_ERROR));
|
||||
}
|
||||
|
||||
@@ -29,7 +43,7 @@ class OpportunityResourceInstallation
|
||||
$ready = ($proof['restore_verified'] ?? false) && ($proof['compatibility_verified'] ?? false) && ($proof['reversal_verified'] ?? false) && ($proof['qa_passed'] ?? false) && ($proof['code_hash'] ?? '') === $code && ($proof['target']['database'] ?? '') === $identity->database && (int) ($proof['target']['port'] ?? 0) === (int) $identity->port && strtotime($proof['verified_at'] ?? '') >= time() - 86400 && is_file($proof['dump_path'] ?? '') && hash_file('sha256', $proof['dump_path']) === ($proof['sha256'] ?? null);
|
||||
$installed = app(OpportunityResources::class)->installed();
|
||||
|
||||
return ['installed' => $installed, 'ready' => $ready, 'target' => $identity, 'code_hash' => $code, 'hash' => hash('sha256', json_encode([$identity, $code, $ready, $installed], JSON_THROW_ON_ERROR)), 'migration' => self::MIGRATION, 'backupDate' => $proof['verified_at'] ?? null, 'changes' => ['Recursos privados de preparação ligados às oportunidades existentes, documents e geo_locations; nenhum dado existente alterado.', 'Originais cifrados; scan pendente bloqueia acesso aos binários, não preparação de metadados/localizações.', 'Versões, exclusão lógica e restauro com auditoria; nenhuma publicação automática.', 'Pendentes: ClamD real, derivadas seguras/revisão/publicação e compatibilidade com limites oficiais onde ausentes.'], 'rollback' => 'Reversão apenas com tabelas vazias e sem documentos cifrados; após utilização, preservar e reconciliar versões antes de uma ação autorizada.'];
|
||||
return ['installed' => $installed, 'ready' => $ready, 'target' => $identity, 'code_hash' => $code, 'hash' => hash('sha256', json_encode([$identity, $code, $ready, $installed], JSON_THROW_ON_ERROR)), 'migration' => self::MIGRATION, 'backupDate' => $proof['verified_at'] ?? null, 'changes' => ['Recursos privados de preparação ligados às oportunidades existentes, documents e geo_locations; nenhum dado existente alterado.', 'Originais cifrados; scan pendente bloqueia acesso aos binários, não preparação de metadados/localizações.', 'Versões, exclusão lógica e restauro com auditoria; nenhuma publicação automática.', 'Scan de cada original/derivada, disponibilidade GD/WebP, revisão de divulgação e compatibilidade territorial têm critérios independentes; a instalação não os confirma. Consultar os estados por ficheiro e as evidências QA da revisão.'], 'rollback' => 'Reversão apenas com tabelas vazias e sem documentos cifrados; após utilização, preservar e reconciliar versões antes de uma ação autorizada.'];
|
||||
}
|
||||
|
||||
public function apply(User $actor, string $hash): void
|
||||
|
||||
@@ -23,13 +23,18 @@ final class SimulationFormDrafts
|
||||
public function create(array $data, Request $request, string $key): array
|
||||
{
|
||||
[$actorId, $tokenHash] = $this->context($request);
|
||||
$caseId = $request->input('context');
|
||||
if ($caseId !== null) {
|
||||
abort_unless(config('investor-path.enabled') && is_string($caseId) && Str::isUuid($caseId), 422, 'Contexto de investimento indisponível.');
|
||||
abort_unless($request->user()?->hasVerifiedEmail(), 403);
|
||||
}
|
||||
$data = SimulationFormDraftPrivacyPolicy::apply($data, $actorId !== null);
|
||||
$scope = $actorId === null ? 'anonymous:'.$tokenHash : 'user:'.$actorId;
|
||||
$scope = ($actorId === null ? 'anonymous:'.$tokenHash : 'user:'.$actorId).($caseId ? ':case:'.$caseId : '');
|
||||
$keyHash = hash_hmac('sha256', strtolower($key), (string) config('app.key'));
|
||||
$canonicalPayload = json_encode($this->canonical($data), JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE);
|
||||
$payloadHash = hash('sha256', $canonicalPayload);
|
||||
|
||||
return DB::transaction(function () use ($actorId, $tokenHash, $scope, $keyHash, $payloadHash, $data): array {
|
||||
return DB::transaction(function () use ($actorId, $tokenHash, $scope, $keyHash, $payloadHash, $data, $caseId, $request): array {
|
||||
$this->setContext($actorId, $tokenHash);
|
||||
DB::select('select pg_advisory_xact_lock(261010, hashtext(?))', [$scope]);
|
||||
|
||||
@@ -39,7 +44,13 @@ final class SimulationFormDrafts
|
||||
->update(['deleted_at' => now()]);
|
||||
}
|
||||
|
||||
$draft = $this->ownedQuery($actorId, $tokenHash)->lockForUpdate()->first();
|
||||
$case = $caseId ? app(VirtualDesk::class)->case($request->user(), $caseId, true, true) : null;
|
||||
// Shared case access never grants ownership of a private simulator snapshot.
|
||||
abort_if($case && ((int) $case->user_id !== $actorId || $case->closed_at), 403);
|
||||
$query = $this->ownedQuery($actorId, $tokenHash);
|
||||
$draft = $case
|
||||
? ($case->simulation_id ? $query->whereKey($case->simulation_id)->lockForUpdate()->firstOrFail() : null)
|
||||
: $this->unscoped($query, $actorId)->lockForUpdate()->first();
|
||||
if ($draft) {
|
||||
if (hash_equals($draft->create_key_hash, $keyHash)) {
|
||||
abort_unless(hash_equals($draft->create_payload_hash, $payloadHash), 409, 'Idempotency-Key já foi utilizada com outros dados.');
|
||||
@@ -57,6 +68,11 @@ final class SimulationFormDrafts
|
||||
'expires_at' => $actorId === null ? now()->addDays(30) : null,
|
||||
]);
|
||||
|
||||
if ($case) {
|
||||
DB::table('desk_cases')->where('id', $case->id)->update(['simulation_id' => $draft->id, 'version' => $case->version + 1, 'updated_at' => now()]);
|
||||
app(VirtualDesk::class)->event(app(VirtualDesk::class)->case($request->user(), $case->id), $request->user(), 'context_draft_created', ['draft_id' => $draft->id]);
|
||||
}
|
||||
|
||||
return ['draft' => $draft, 'replayed' => false];
|
||||
}, 3);
|
||||
}
|
||||
@@ -70,6 +86,7 @@ final class SimulationFormDrafts
|
||||
return DB::transaction(function () use ($id, $data, $request, $actorId, $tokenHash): SimulationFormDraft {
|
||||
$this->setContext($actorId, $tokenHash);
|
||||
$draft = $this->ownedQuery($actorId, $tokenHash)->lockForUpdate()->findOrFail($id);
|
||||
$this->checkContext($request, $draft);
|
||||
$this->requireMatch($request, $draft);
|
||||
$previousEconomic = SimulationFormDraft::decryptSnapshot($draft->economic_snapshot);
|
||||
if (($data['economic_snapshot']['reuse_simulation'] ?? null) === 'no') {
|
||||
@@ -162,10 +179,19 @@ final class SimulationFormDrafts
|
||||
{
|
||||
[$actorId, $tokenHash] = $this->context($request);
|
||||
|
||||
return DB::transaction(function () use ($actorId, $tokenHash): ?SimulationFormDraft {
|
||||
return DB::transaction(function () use ($actorId, $tokenHash, $request): ?SimulationFormDraft {
|
||||
$this->setContext($actorId, $tokenHash);
|
||||
$query = $this->ownedQuery($actorId, $tokenHash);
|
||||
if ($request->query('context') !== null) {
|
||||
$id = $request->query('context');
|
||||
abort_unless(config('investor-path.enabled') && $request->user()?->hasVerifiedEmail() && is_string($id) && Str::isUuid($id), 403);
|
||||
$case = app(VirtualDesk::class)->case($request->user(), $id, true);
|
||||
abort_unless((int) $case->user_id === $actorId, 403);
|
||||
|
||||
return $this->ownedQuery($actorId, $tokenHash)->orderByDesc('updated_at')->first();
|
||||
return $case->simulation_id ? $query->whereKey($case->simulation_id)->firstOrFail() : null;
|
||||
}
|
||||
|
||||
return $this->unscoped($query, $actorId)->orderByDesc('updated_at')->first();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -327,10 +353,12 @@ final class SimulationFormDrafts
|
||||
{
|
||||
[$actorId, $tokenHash] = $this->context($request);
|
||||
|
||||
return DB::transaction(function () use ($id, $actorId, $tokenHash): SimulationFormDraft {
|
||||
return DB::transaction(function () use ($id, $actorId, $tokenHash, $request): SimulationFormDraft {
|
||||
$this->setContext($actorId, $tokenHash);
|
||||
$draft = $this->ownedQuery($actorId, $tokenHash)->findOrFail($id);
|
||||
$this->checkContext($request, $draft);
|
||||
|
||||
return $this->ownedQuery($actorId, $tokenHash)->findOrFail($id);
|
||||
return $draft;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -414,6 +442,31 @@ final class SimulationFormDrafts
|
||||
: $query->where('owner_user_id', $actorId)->whereNull('anonymous_token_hash');
|
||||
}
|
||||
|
||||
/** @param Builder<SimulationFormDraft> $query
|
||||
* @return Builder<SimulationFormDraft>
|
||||
*/
|
||||
private function unscoped(Builder $query, ?int $actorId): Builder
|
||||
{
|
||||
if ($actorId !== null && config('investor-path.enabled') && app(VirtualDesk::class)->installed()) {
|
||||
// The direct tool has its own current draft; context drafts are opened explicitly by ID/context.
|
||||
$query->whereNotExists(fn ($q) => $q->selectRaw('1')->from('desk_cases')
|
||||
->whereColumn('desk_cases.simulation_id', 'simulation_form_drafts.id'));
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
private function checkContext(Request $request, SimulationFormDraft $draft): void
|
||||
{
|
||||
$context = $request->input('context');
|
||||
if ($context === null) {
|
||||
return;
|
||||
}
|
||||
abort_unless(config('investor-path.enabled') && $request->user()?->hasVerifiedEmail() && is_string($context) && Str::isUuid($context), 403);
|
||||
$case = app(VirtualDesk::class)->case($request->user(), $context, true);
|
||||
abort_unless((int) $case->user_id === $request->user()->id && $case->simulation_id === $draft->id, 403, 'Rascunho pertencente a outro contexto.');
|
||||
}
|
||||
|
||||
/** @return array{id:string,title:string,updated_at:string|null,expires_at:string|null,version_no:int} */
|
||||
private function summary(SimulationFormDraft $draft): array
|
||||
{
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/** Administrative context is never an investment site or a zone perimeter. */
|
||||
final class TerritoryGeometry
|
||||
{
|
||||
/** @return array<string,mixed> */
|
||||
public function context(string $id, bool $management = false): array
|
||||
{
|
||||
$geography = app(InvestmentGeography::class);
|
||||
abort_unless($geography->references($management)->where('id', $id)->exists(), 404);
|
||||
$path = $geography->path($id, $management);
|
||||
$ids = array_map(fn ($node) => $node->id, $path);
|
||||
$rows = DB::table('geo_geometries as g')->join('geo_locations as l', 'l.id', '=', 'g.geo_location_id')
|
||||
->whereIn('g.geo_location_id', $ids)->whereNull('g.deleted_at')->whereNull('l.deleted_at')
|
||||
->whereIn('g.data_classification', $management ? ['internal', 'public'] : ['public'])
|
||||
->whereRaw("g.properties->>'purpose' = 'administrative_boundary'")
|
||||
->whereIn('g.geometry_type', ['polygon', 'multipolygon'])
|
||||
->whereRaw('ST_IsValid(g.geom) AND NOT ST_IsEmpty(g.geom) AND ST_SRID(g.geom)=4326')
|
||||
->orderBy('g.geo_location_id')->orderBy('g.id')->limit(101)
|
||||
->get(['g.id', 'g.geo_location_id', 'l.name', 'l.location_type', 'g.properties', 'g.data_classification',
|
||||
DB::raw('ST_AsGeoJSON(ST_SimplifyPreserveTopology(g.geom,0.0001),6) as geometry')]);
|
||||
$areas = $rows->take(100)->map(function ($row) use ($id) {
|
||||
$source = json_decode($row->properties, true, 512, JSON_THROW_ON_ERROR);
|
||||
|
||||
return ['id' => $row->id, 'territory_id' => $row->geo_location_id, 'location_type' => $row->location_type,
|
||||
'selected_territory' => $row->geo_location_id === $id, 'geometry' => json_decode($row->geometry, true, 512, JSON_THROW_ON_ERROR),
|
||||
'title' => 'Limite administrativo: '.$row->name, 'purpose' => 'administrative_boundary',
|
||||
'source_reference' => $source['authority'] ?? null, 'source_date' => $source['source_version'] ?? null,
|
||||
'source_url' => $source['source_url'] ?? null, 'source_sha256' => $source['source_sha256'] ?? null,
|
||||
'data_classification' => $row->data_classification, 'legal_currentness' => $source['legal_currentness'] ?? 'not_determined', 'url' => ''];
|
||||
})->all();
|
||||
|
||||
return ['territory_id' => $id, 'territory_registered' => true,
|
||||
'selected_geometry_available' => $rows->contains('geo_location_id', $id), 'context_geometry_count' => count($areas),
|
||||
'areas' => $areas, 'truncated' => $rows->count() > 100, 'investment_site' => false];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Services\Malware\MalwareScanner;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/** Imports only the retained, accepted INE edition. Publication is a separate action. */
|
||||
class TerritoryGeometryImport
|
||||
{
|
||||
public function fingerprint(): string
|
||||
{
|
||||
return hash('sha256', implode('', array_map(fn ($f) => hash_file('sha256', $f), [__FILE__, config_path('geometry-import.php'), app_path('Http/Controllers/TerritoryGeometryImportController.php'), base_path('routes/web.php'), resource_path('js/pages/management/territory-geometry-import.tsx'),
|
||||
base_path('bootstrap/app.php'), app_path('Providers/FortifyServiceProvider.php'), config_path('fortify.php'),
|
||||
resource_path('js/pages/auth/login.tsx'), resource_path('js/pages/auth/two-factor-challenge.tsx')])));
|
||||
}
|
||||
|
||||
private function guard(User $actor, bool $write = false): void
|
||||
{
|
||||
abort_unless($actor->can('manage-portal'), 403);
|
||||
abort_unless(config('geometry-import.enabled'), 503, 'Importação cartográfica não disponibilizada.');
|
||||
if (! $write) {
|
||||
return;
|
||||
}
|
||||
abort_unless($actor->two_factor_confirmed_at && $actor->two_factor_secret, 403, 'Confirme a autenticação de dois factores para aplicar ou reverter cartografia.');
|
||||
$target = DB::selectOne('SELECT current_database() AS database,inet_server_port() AS port');
|
||||
$qa = app()->environment('testing') && str_ends_with($target->database, '_test') && (int) $target->port === 55441 && config('database.connections.pgsql.host') === '127.0.0.1';
|
||||
if ($qa) {
|
||||
return;
|
||||
}
|
||||
$file = storage_path('app/private/investmoz-v2/geometry-import-activation-proof.json');
|
||||
$p = is_file($file) ? json_decode(file_get_contents($file), true) : [];
|
||||
abort_unless(($p['restore_verified'] ?? false) && ($p['qa_passed'] ?? false) && ($p['ui_passed'] ?? false)
|
||||
&& ($p['code_hash'] ?? '') === $this->fingerprint() && ($p['target']['database'] ?? '') === $target->database
|
||||
&& (int) ($p['target']['port'] ?? 0) === (int) $target->port && strtotime($p['verified_at'] ?? '') >= time() - 86400
|
||||
&& is_file($p['dump_path'] ?? '') && hash_file('sha256', $p['dump_path']) === ($p['sha256'] ?? null)
|
||||
&& ($p['files_verified'] ?? false) && is_file($p['files_path'] ?? '') && hash_file('sha256', $p['files_path']) === ($p['files_sha256'] ?? null), 422, 'Backup/restauro e provas desta revisão e alvo necessários; preparação não autoriza ativação.');
|
||||
}
|
||||
|
||||
public function preview(User $actor, int $level): array
|
||||
{
|
||||
$this->guard($actor);
|
||||
abort_unless(in_array($level, [1, 2, 3], true), 422);
|
||||
$directory = config('geometry-import.directory');
|
||||
$file = $directory.'/moz-adm'.$level.'-ine-20190607.geojson';
|
||||
$metadata = $directory.'/moz-adm'.$level.'-ine-metadata.html';
|
||||
abort_unless(is_file($file) && is_file($metadata), 422, 'Exemplar privado indisponível.');
|
||||
$text = file_get_contents($metadata);
|
||||
abort_unless(str_contains($text, 'Mozambique INE - Instituto Nacional de Estatistica') && str_contains($text, '2019-06-07'), 422, 'Metadados do exemplar divergentes.');
|
||||
$sourceHash = hash_file('sha256', $file);
|
||||
$source = json_decode(file_get_contents($file), true, 512, JSON_THROW_ON_ERROR);
|
||||
abort_unless(($source['type'] ?? '') === 'FeatureCollection' && count($source['features'] ?? []) === [1 => 11, 2 => 159, 3 => 411][$level] && ! ($source['exceededTransferLimit'] ?? false), 422, 'Exemplar incompleto.');
|
||||
$locations = DB::table('geo_locations')->where('location_type', [1 => 'province', 2 => 'district', 3 => 'admin_post'][$level])->whereNull('deleted_at')->get(['id', 'name', 'parent_id']);
|
||||
$normalize = fn ($n) => strtolower(trim(Str::ascii($n)));
|
||||
$countryNames = array_map($normalize, [$source['features'][0]['properties']['ADM0_PT'], $source['features'][0]['properties']['ADM0_EN']]);
|
||||
$countries = DB::table('geo_locations')->where('location_type', 'country')->whereNull('deleted_at')->get(['id', 'name'])->filter(fn ($c) => in_array($normalize($c->name), $countryNames, true))->values();
|
||||
$countryId = count($countries) === 1 ? $countries[0]->id : null;
|
||||
$parentSourceHash = $level > 1 ? hash_file('sha256', $directory.'/moz-adm'.($level - 1).'-ine-20190607.geojson') : null;
|
||||
$rows = [];
|
||||
foreach ($source['features'] as $feature) {
|
||||
$p = $feature['properties'];
|
||||
abort_unless(($p['ADM0_PCODE'] ?? '') === 'MZ', 422, 'Âmbito territorial do exemplar divergente.');
|
||||
$external = '2019-06-07:adm'.$level.':'.$p['ADM'.$level.'_PCODE'];
|
||||
$parent = $level > 1 ? DB::table('geo_geometries')->where('source_system', 'ine-cod-ab')->where('external_id', '2019-06-07:adm'.($level - 1).':'.$p['ADM'.($level - 1).'_PCODE'])->where('properties->source_sha256', $parentSourceHash)->whereNull('deleted_at')->value('geo_location_id') : $countryId;
|
||||
$matches = $locations->filter(fn ($l) => $normalize($l->name) === $normalize($p['ADM'.$level.'_PT']) && $parent && $l->parent_id === $parent)->values();
|
||||
$row = ['external_id' => $external, 'name' => $p['ADM'.$level.'_PT'], 'parent_name' => $level > 1 ? $p['ADM'.($level - 1).'_PT'] : null,
|
||||
'parent_code' => $level > 1 ? $p['ADM'.($level - 1).'_PCODE'] : null, 'candidates' => $matches->all(), 'location_id' => count($matches) === 1 ? $matches[0]->id : null,
|
||||
'status' => count($matches) === 1 ? 'insert' : (! $parent ? 'parent_unresolved' : 'name_unresolved')];
|
||||
if ($row['location_id']) {
|
||||
$geometry = json_encode($feature['geometry'], JSON_THROW_ON_ERROR);
|
||||
$valid = DB::selectOne('SELECT ST_IsValid(g) AND NOT ST_IsEmpty(g) AND ST_NDims(g)=2 AND GeometryType(g) IN (\'POLYGON\',\'MULTIPOLYGON\') AND ST_XMin(Box3D(g))>=-180 AND ST_XMax(Box3D(g))<=180 AND ST_YMin(Box3D(g))>=-90 AND ST_YMax(Box3D(g))<=90 AS valid FROM (SELECT ST_SetSRID(ST_GeomFromGeoJSON(?),4326) g) q', [$geometry]);
|
||||
if (! $valid->valid) {
|
||||
$row['status'] = 'invalid_geometry';
|
||||
} else {
|
||||
$existing = DB::table('geo_geometries')->where('source_system', 'ine-cod-ab')->where('external_id', $external)->first();
|
||||
if ($existing) {
|
||||
$props = json_decode($existing->properties, true);
|
||||
$same = DB::selectOne('SELECT ST_Equals(geom,ST_SetSRID(ST_GeomFromGeoJSON(?),4326)) AS same FROM geo_geometries WHERE id=?', [$geometry, $existing->id])->same;
|
||||
$row['status'] = $same && $existing->geo_location_id === $row['location_id'] && ($props['source_sha256'] ?? null) === $sourceHash && ! $existing->deleted_at ? 'reuse' : 'identity_conflict';
|
||||
$row['geometry_id'] = $existing->id;
|
||||
$row['version'] = $existing->version_no;
|
||||
$row['classification'] = $existing->data_classification;
|
||||
} elseif (DB::table('geo_geometries')->where('geo_location_id', $row['location_id'])->where('geometry_type', strtolower($feature['geometry']['type']))->whereNull('deleted_at')->exists()) {
|
||||
$row['status'] = 'territory_geometry_conflict';
|
||||
}
|
||||
}
|
||||
}
|
||||
$rows[] = $row;
|
||||
}
|
||||
$scanFile = $directory.'/geometry-source-scans.json';
|
||||
$scans = is_file($scanFile) ? json_decode(file_get_contents($scanFile), true) : [];
|
||||
$scan = null;
|
||||
foreach ($scans['files'] ?? [] as $s) {
|
||||
if ($s['file'] === basename($file) && $s['sha256'] === $sourceHash) {
|
||||
$scan = ($s['scan']['result'] ?? '') === 'clean' ? $s['scan'] : ($s['gis_scan'] ?? null);
|
||||
}
|
||||
}
|
||||
$scanReady = ($scan['result'] ?? '') === 'clean' && ($scan['engine'] ?? '') === 'ClamAV' && strtotime($scans['captured_at'] ?? '') >= time() - config('geometry-import.scan_max_age_seconds');
|
||||
$target = DB::selectOne('SELECT current_database() AS database,inet_server_port() AS port');
|
||||
$plan = ['level' => $level, 'target' => $target, 'edition' => '2019-06-07', 'source_sha256' => $sourceHash, 'metadata_sha256' => hash_file('sha256', $metadata), 'code_hash' => $this->fingerprint(),
|
||||
'expected' => count($rows), 'resolved' => count(array_filter($rows, fn ($r) => in_array($r['status'], ['insert', 'reuse'], true))), 'rows' => $rows, 'scan_ready' => $scanReady, 'scan' => $scan, 'scan_at' => $scans['captured_at'] ?? null, 'published' => false];
|
||||
$plan['pending'] = $plan['expected'] - $plan['resolved'];
|
||||
$plan['hash'] = hash_hmac('sha256', json_encode([$actor->id, $plan], JSON_THROW_ON_ERROR), config('app.key'));
|
||||
|
||||
return $plan;
|
||||
}
|
||||
|
||||
public function apply(User $actor, array $input): array
|
||||
{
|
||||
$this->guard($actor, true);
|
||||
$data = Validator::make($input, ['level' => 'required|integer|in:1,2,3', 'hash' => 'required|string|size:64', 'idempotency_key' => 'required|uuid', 'reason' => 'required|string|min:20|max:1000', 'confirm' => 'required|accepted'])->validate();
|
||||
|
||||
return $this->receipt($actor, 'geometry-import-apply', $data, function () use ($actor, $data) {
|
||||
$plan = $this->preview($actor, (int) $data['level']);
|
||||
abort_unless(hash_equals($plan['hash'], $data['hash']), 409, 'Correspondências, fonte ou estado alterados; repita a pré-visualização.');
|
||||
abort_unless($plan['scan_ready'], 423, 'Scan limpo atual ligado ao original necessário.');
|
||||
abort_if(count(array_filter($plan['rows'], fn ($r) => str_contains($r['status'], 'conflict') || $r['status'] === 'invalid_geometry')) > 0, 409, 'Conflito de identidade/geometria: nenhuma escrita aplicada.');
|
||||
$bytes = file_get_contents(config('geometry-import.directory').'/moz-adm'.$data['level'].'-ine-20190607.geojson');
|
||||
abort_unless(hash('sha256', $bytes) === $plan['source_sha256'], 409);
|
||||
$source = json_decode($bytes, true, 512, JSON_THROW_ON_ERROR);
|
||||
$metadata = config('geometry-import.directory').'/moz-adm'.$data['level'].'-ine-metadata.html';
|
||||
$metadataScan = app(MalwareScanner::class)->scan($metadata, filesize($metadata), storage_path('app/private'));
|
||||
abort_unless(($metadataScan['result'] ?? '') === 'clean', 423, 'Scan dos metadados do exemplar pendente ou inconclusivo.');
|
||||
abort_unless(hash_file('sha256', $metadata) === $plan['metadata_sha256'], 409, 'Metadados alterados durante o scan.');
|
||||
$metadataScan['signatures_at'] = $metadataScan['signatures_at']?->format(DATE_ATOM);
|
||||
$batch = (string) Str::uuid();
|
||||
$created = [];
|
||||
$reused = [];
|
||||
foreach ($plan['rows'] as $i => $row) {
|
||||
if ($row['status'] === 'reuse') {
|
||||
$reused[] = $row['geometry_id'];
|
||||
}
|
||||
if ($row['status'] !== 'insert') {
|
||||
continue;
|
||||
}
|
||||
$feature = $source['features'][$i];
|
||||
$id = (string) Str::uuid();
|
||||
$trace = ['authority' => 'Mozambique INE - Instituto Nacional de Estatistica', 'provider' => 'UNOCHA; exemplar hosted by World Bank', 'source_version' => $plan['edition'], 'source_sha256' => $plan['source_sha256'], 'metadata_sha256' => $plan['metadata_sha256'], 'source_url' => 'https://services.arcgis.com/iQ1dY19aHwbSDYIF/arcgis/rest/services/Mozambique/FeatureServer/'.($data['level'] + 2), 'source_properties' => $feature['properties'], 'source_scan' => $plan['scan'], 'batch_id' => $batch, 'purpose' => 'administrative_boundary', 'investment_site' => false, 'legal_currentness' => 'not_determined', 'match_basis' => 'unique_exact_name_and_matched_parent_after_case_and_diacritics'];
|
||||
DB::insert('INSERT INTO geo_geometries(id,source_system,external_id,geo_location_id,geometry_type,geom,properties,data_classification) VALUES (?,?,?,?,?,ST_SetSRID(ST_GeomFromGeoJSON(?),4326),?::jsonb,?)', [$id, 'ine-cod-ab', $row['external_id'], $row['location_id'], strtolower($feature['geometry']['type']), json_encode($feature['geometry'], JSON_THROW_ON_ERROR), json_encode($trace, JSON_THROW_ON_ERROR), 'internal']);
|
||||
$created[] = ['id' => $id, 'checksum' => $this->snapshotHash($id)];
|
||||
}
|
||||
$result = ['batch_id' => $batch, 'level' => $data['level'], 'preview_hash' => $plan['hash'], 'expected' => $plan['expected'], 'resolved' => $plan['resolved'], 'created' => $created, 'inserted' => count($created), 'reused' => count($reused), 'reused_ids' => $reused, 'pending' => $plan['pending'], 'source_sha256' => $plan['source_sha256'], 'metadata_sha256' => $plan['metadata_sha256'], 'metadata_scan' => $metadataScan, 'published' => false, 'reason' => $data['reason']];
|
||||
$this->audit($actor, $batch, 'geometry_import_applied', $result);
|
||||
|
||||
return $result;
|
||||
});
|
||||
}
|
||||
|
||||
public function reverse(User $actor, string $batch, array $input): array
|
||||
{
|
||||
$this->guard($actor, true);
|
||||
$data = Validator::make([...$input, 'batch_id' => $batch], ['batch_id' => 'required|uuid', 'idempotency_key' => 'required|uuid', 'reason' => 'required|string|min:20|max:1000', 'confirm' => 'required|accepted'])->validate();
|
||||
|
||||
return $this->receipt($actor, 'geometry-import-reverse', $data, function () use ($actor, $data, $batch) {
|
||||
$event = DB::table('audit_events')->where('source_system', 'geometry-import')->where('entity_id', $batch)->where('action', 'geometry_import_applied')->first();
|
||||
abort_unless($event, 404);
|
||||
$old = DB::table('audit_events')->where('source_system', 'geometry-import')->where('entity_id', $batch)->where('action', 'geometry_import_reversed')->first();
|
||||
if ($old) {
|
||||
return json_decode($old->after_data, true);
|
||||
}
|
||||
$manifest = json_decode($event->after_data, true);
|
||||
foreach ($manifest['created'] as $row) {
|
||||
DB::table('geo_geometries')->where('id', $row['id'])->lockForUpdate()->first();
|
||||
abort_unless($this->snapshotHash($row['id']) === $row['checksum'], 409, 'Geometria alterada ou publicada; reversão recusada.');
|
||||
// Enumerate all real FKs, rather than assuming one consumer table.
|
||||
$references = DB::select("SELECT n.nspname AS schema,t.relname AS table_name,a.attname AS column_name FROM pg_constraint c JOIN pg_class t ON t.oid=c.conrelid JOIN pg_namespace n ON n.oid=t.relnamespace JOIN pg_attribute a ON a.attrelid=c.conrelid AND a.attnum=c.conkey[1] WHERE c.contype='f' AND c.confrelid='geo_geometries'::regclass");
|
||||
foreach ($references as $ref) {
|
||||
abort_if(DB::table($ref->schema.'.'.$ref->table_name)->where($ref->column_name, $row['id'])->exists(), 409, 'Geometria associada a um consumidor; preserve a relação.');
|
||||
}
|
||||
}
|
||||
foreach ($manifest['created'] as $row) {
|
||||
DB::table('geo_geometries')->where('id', $row['id'])->update(['deleted_at' => now(), 'updated_at' => now(), 'version_no' => DB::raw('version_no+1')]);
|
||||
}
|
||||
$result = ['batch_id' => $batch, 'reversed' => count($manifest['created']), 'reused_preserved' => $manifest['reused'], 'published' => false, 'reason' => $data['reason']];
|
||||
$this->audit($actor, $batch, 'geometry_import_reversed', $result);
|
||||
|
||||
return $result;
|
||||
});
|
||||
}
|
||||
|
||||
private function snapshotHash(string $id): string
|
||||
{
|
||||
$r = DB::selectOne('SELECT row_to_json(q)::text AS value FROM (SELECT *,encode(ST_AsEWKB(geom),\'hex\') AS binary_geometry FROM geo_geometries WHERE id=?) q', [$id]);
|
||||
|
||||
return hash('sha256', $r->value ?? 'missing');
|
||||
}
|
||||
|
||||
private function receipt(User $actor, string $scope, array $data, callable $operation): array
|
||||
{
|
||||
return DB::transaction(function () use ($actor, $scope, $data, $operation) {
|
||||
DB::select('SELECT pg_advisory_xact_lock(91026,20190607)');
|
||||
DB::select('SELECT pg_advisory_xact_lock(280926,150000)');
|
||||
$hash = hash('sha256', json_encode($data, JSON_THROW_ON_ERROR));
|
||||
$receipt = DB::table('geo_write_receipts')->where('actor_id', $actor->id)->where('scope', $scope)->where('idempotency_key', $data['idempotency_key'])->first();
|
||||
if ($receipt) {
|
||||
abort_unless(hash_equals(trim($receipt->request_hash), $hash), 409, 'Chave reutilizada com outro pedido.');
|
||||
|
||||
return json_decode($receipt->response, true);
|
||||
}
|
||||
$result = $operation();
|
||||
DB::table('geo_write_receipts')->insert(['id' => (string) Str::uuid(), 'actor_id' => $actor->id, 'scope' => $scope, 'idempotency_key' => $data['idempotency_key'], 'request_hash' => $hash, 'response' => json_encode($result, JSON_THROW_ON_ERROR), 'http_status' => 200]);
|
||||
|
||||
return $result;
|
||||
});
|
||||
}
|
||||
|
||||
private function audit(User $actor, string $batch, string $action, array $data): void
|
||||
{
|
||||
DB::table('audit_events')->insert(['source_system' => 'geometry-import', 'entity_type' => 'geo_geometries', 'entity_id' => $batch, 'correlation_id' => $batch, 'actor_user_id' => $actor->id, 'action' => $action, 'after_data' => json_encode($data, JSON_THROW_ON_ERROR), 'data_classification' => 'internal']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use Illuminate\Contracts\Encryption\DecryptException;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
use Symfony\Component\HttpFoundation\HeaderUtils;
|
||||
|
||||
/** Authorization/publication stays with the consumer; originals share integrity and cipher handling. */
|
||||
class VerifiedDocumentBinary
|
||||
{
|
||||
public function respond(object $document, bool $inline = false): Response|BinaryFileResponse
|
||||
{
|
||||
abort_unless($document->status === 'active' && $document->malware_scan_status === 'clean'
|
||||
&& ($document->deleted_at ?? null) === null && hash_equals(trim($document->sha256), trim((string) $document->malware_scanned_sha256)), 404);
|
||||
$disk = Storage::disk('local');
|
||||
$root = realpath($disk->path(''));
|
||||
$path = realpath($disk->path($document->storage_key));
|
||||
abort_unless($root && $path && str_starts_with(strtolower($path), strtolower($root.DIRECTORY_SEPARATOR)) && is_file($path), 404);
|
||||
$headers = ['X-Content-Type-Options' => 'nosniff', 'Cache-Control' => 'private, no-store'];
|
||||
if ($inline) {
|
||||
$headers['Content-Type'] = $document->media_type;
|
||||
$headers['Content-Security-Policy'] = "sandbox; default-src 'none'; style-src 'unsafe-inline'";
|
||||
}
|
||||
if (($document->storage_encryption ?? null) === 'laravel') {
|
||||
try {
|
||||
$bytes = Crypt::decryptString($disk->get($document->storage_key));
|
||||
} catch (DecryptException) {
|
||||
abort(404);
|
||||
}
|
||||
abort_unless(hash_equals(trim($document->sha256), hash('sha256', $bytes)), 404);
|
||||
$headers['Content-Type'] = $document->media_type;
|
||||
$headers['Content-Disposition'] = HeaderUtils::makeDisposition($inline ? 'inline' : 'attachment', basename($document->file_name), 'document');
|
||||
|
||||
return response($bytes, 200, $headers);
|
||||
}
|
||||
abort_unless(($document->storage_encryption ?? null) === null, 404);
|
||||
$checksum = hash_file('sha256', $path);
|
||||
abort_unless(is_string($checksum) && hash_equals(trim($document->sha256), $checksum), 404);
|
||||
|
||||
return $inline ? response()->file($path, $headers)->setContentDisposition('inline', basename($document->file_name)) : response()->download($path, basename($document->file_name), $headers);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,9 @@ namespace App\Services;
|
||||
use App\Models\InvestmentSubmission;
|
||||
use App\Models\Investor;
|
||||
use App\Models\InvestorJourney;
|
||||
use App\Models\SimulationFormDraft;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@@ -186,6 +188,14 @@ class VirtualDesk
|
||||
$id = (string) Str::uuid();
|
||||
$base = $this->decode($case->payload);
|
||||
$payload = ['title' => $case->title, 'description' => $base['investment']['objective'] ?? '', 'regime' => 'unknown'];
|
||||
if (config('investor-path.enabled') && $case->simulation_id && (int) $case->user_id === $actor->id) {
|
||||
$draftRequest = Request::create('/');
|
||||
$draftRequest->setUserResolver(fn () => $actor);
|
||||
$draft = app(SimulationFormDrafts::class)->find($case->simulation_id, $draftRequest);
|
||||
$economic = SimulationFormDraft::decryptSnapshot($draft->economic_snapshot);
|
||||
$payload['description'] = $economic['project_summary'] ?? $payload['description'];
|
||||
$this->event($case, $actor, 'request_prefill_prepared', ['draft_id' => $draft->id, 'draft_version' => $draft->version_no, 'snapshot_sha256' => $draft->snapshot_sha256, 'fields' => ['title', 'description']]);
|
||||
}
|
||||
DB::table('desk_requests')->insert(['id' => $id, 'case_id' => $caseId, 'service_version_id' => $serviceId, 'client_key' => $clientKey, 'payload' => $this->encode($payload), 'created_at' => now(), 'updated_at' => now()]);
|
||||
$request = DB::table('desk_requests')->where('id', $id)->firstOrFail();
|
||||
$this->event($case, $actor, 'draft_created', [], $request);
|
||||
@@ -205,7 +215,8 @@ class VirtualDesk
|
||||
* @return array<string,mixed> */
|
||||
public function validateFields(array $payload, array $definition, bool $submitting): array
|
||||
{
|
||||
$rules = ['payload' => ['required', 'array:'.implode(',', [...array_keys($definition['fields']), 'declared_origin_country_code'])],
|
||||
$rules = ['payload' => ['required', 'array:'.implode(',', [...array_keys($definition['fields']), 'country', 'declared_origin_country_code'])],
|
||||
'payload.country' => ['nullable', 'string', 'max:100', app(CountryCatalogue::class)->legacyCountryRule()],
|
||||
'payload.declared_origin_country_code' => ['nullable', 'string', app(CountryCatalogue::class)->rule()]];
|
||||
foreach ($definition['fields'] as $key => $field) {
|
||||
$active = ! isset($field['when']) || ($payload[$field['when']['field']] ?? null) === $field['when']['equals'];
|
||||
@@ -219,8 +230,14 @@ class VirtualDesk
|
||||
$rules['payload.'.$key] = $rule;
|
||||
}
|
||||
$validated = Validator::make(['payload' => $payload], $rules)->validate()['payload'];
|
||||
foreach ($definition['fields'] as $key => $field) {
|
||||
if ($field['type'] === 'territory' && ! empty($validated[$key])) {
|
||||
if (! app(InvestmentGeography::class)->publicReferences()->where('id', $validated[$key])->exists()) {
|
||||
throw ValidationException::withMessages(['payload.'.$key => 'Seleccione uma localização disponível no cadastro territorial.']);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($validated['territory_id'] ?? null) {
|
||||
abort_unless(app(InvestmentGeography::class)->publicReferences()->where('id', $validated['territory_id'])->exists(), 422, 'Localização indisponível.');
|
||||
if ($submitting && trim($validated['location_source'] ?? '') === '') {
|
||||
throw ValidationException::withMessages(['payload.location_source' => 'Indique a fonte da localização.']);
|
||||
}
|
||||
@@ -320,7 +337,7 @@ class VirtualDesk
|
||||
}
|
||||
$editable = $data['editable_fields'] ?? [];
|
||||
abort_if($data['status'] === 'returned' && ! $editable, 422, 'Indique os campos autorizados para correção.');
|
||||
abort_if(array_diff($editable, array_keys($this->definition($request)['fields'])) !== [], 422);
|
||||
abort_if(array_diff($editable, [...array_keys($this->definition($request)['fields']), 'country', 'declared_origin_country_code']) !== [], 422);
|
||||
DB::table('desk_requests')->where('id', $id)->update(['status' => $data['status'], 'version' => $request->version + 1, 'editable_fields' => json_encode($editable), 'closed_at' => in_array($data['status'], ['closed', 'cancelled'], true) ? now() : null, 'updated_at' => now()]);
|
||||
$request = DB::table('desk_requests')->where('id', $id)->firstOrFail();
|
||||
$this->event($case, $actor, 'request_'.$data['status'], ['reason' => $data['reason'], 'editable_fields' => $editable], $request);
|
||||
|
||||
@@ -9,7 +9,7 @@ use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class VirtualDeskInstallation
|
||||
{
|
||||
public const MIGRATIONS = ['2026_10_07_190000_create_internal_virtual_desk', '2026_10_08_120000_extend_desk_investor_guidance'];
|
||||
public const MIGRATIONS = ['2026_10_07_190000_create_internal_virtual_desk', '2026_10_08_120000_extend_desk_investor_guidance', '2026_10_09_190000_prepare_investor_path'];
|
||||
|
||||
public function fingerprint(): string
|
||||
{
|
||||
@@ -20,6 +20,17 @@ class VirtualDeskInstallation
|
||||
resource_path('js/lib/business-financial-plan.ts'), resource_path('js/lib/financial-calculators.ts'), resource_path('js/lib/project-dossier.ts'),
|
||||
...array_map(fn ($name) => database_path('migrations/'.$name.'.php'), self::MIGRATIONS),
|
||||
...(glob(resource_path('js/pages/desk/*.tsx')) ?: []), resource_path('js/components/investor-guidance.tsx'), resource_path('js/components/journey-companion.tsx'), resource_path('js/components/desk-internal-operations.tsx'), resource_path('js/layouts/portal-navigation.tsx'), resource_path('js/layouts/app/app-sidebar-layout.tsx'), resource_path('js/pages/investment/shared.tsx'), resource_path('js/lib/investor-guidance-finance.ts')];
|
||||
$files = [...$files, app_path('Services/InvestorPath.php'), app_path('Services/InvestorPathDefinition.php'),
|
||||
app_path('Services/SimulationFormDrafts.php'), app_path('Http/Requests/StoreSimulationFormDraftRequest.php'),
|
||||
app_path('Http/Controllers/InvestorPathController.php'), app_path('Http/Controllers/DashboardController.php'),
|
||||
base_path('routes/investor-path.php'), base_path('routes/web.php'), config_path('investor-path.php'),
|
||||
resource_path('js/pages/dashboard.tsx'), resource_path('js/components/simulation-form.tsx'), resource_path('js/lib/investor-path.ts'),
|
||||
database_path('migrations/2026_10_01_000200_create_simulation_execution_core.php'),
|
||||
resource_path('js/components/investment-map-panel.tsx'), resource_path('js/pages/investment/detail.tsx'), resource_path('js/pages/partnerships/catalogue.tsx'),
|
||||
...(glob(resource_path('js/pages/investor-path/*.tsx')) ?: [])];
|
||||
$files = [...$files, app_path('Services/VerifiedDocumentBinary.php'), app_path('Services/TerritoryGeometryImport.php'), app_path('Http/Controllers/TerritoryGeometryImportController.php'), config_path('geometry-import.php'), resource_path('js/pages/management/territory-geometry-import.tsx'),
|
||||
base_path('bootstrap/app.php'), app_path('Providers/FortifyServiceProvider.php'), config_path('fortify.php'),
|
||||
resource_path('js/pages/auth/login.tsx'), resource_path('js/pages/auth/two-factor-challenge.tsx')];
|
||||
sort($files);
|
||||
|
||||
return hash('sha256', json_encode(array_map(fn ($file) => hash_file('sha256', $file), $files), JSON_THROW_ON_ERROR));
|
||||
@@ -57,20 +68,29 @@ class VirtualDeskInstallation
|
||||
foreach (['desk_cases', 'desk_requests', 'desk_documents', 'desk_messages', 'tasks', 'investor_accounts', 'investment_submissions'] as $table) {
|
||||
$counts[$table] = Schema::hasTable($table) ? DB::table($table)->count() : null;
|
||||
}
|
||||
$installed = app(VirtualDesk::class)->installed();
|
||||
$pathInstalled = Schema::hasColumn('investor_journeys', 'path_definition_id') && Schema::hasColumn('journey_steps', 'path_detail');
|
||||
$installed = app(VirtualDesk::class)->installed() && $pathInstalled
|
||||
&& DB::table('migrations')->where('migration', '2026_10_09_190000_prepare_investor_path')->exists();
|
||||
$pathQa = $read('investor-path-qa-evidence.json');
|
||||
$pathQaVerified = ($pathQa['code_hash'] ?? null) === $code && ($pathQa['api_persistence_passed'] ?? false)
|
||||
&& ($pathQa['integrated_ui_ab_passed'] ?? false) && str_ends_with($pathQa['database'] ?? '', '_test') && (int) ($pathQa['port'] ?? 0) === 55441;
|
||||
$privileges = DB::selectOne("select has_schema_privilege(current_user, 'public', 'CREATE') as can_create,
|
||||
pg_has_role(current_user, (select tableowner from pg_tables where schemaname='public' and tablename='tasks'), 'USAGE') as can_alter_tasks");
|
||||
$databaseReady = (bool) ($privileges->can_create && $privileges->can_alter_tasks);
|
||||
|
||||
return ['hash' => hash('sha256', json_encode([$identity, $code, $counts, $backupVerified, $qaVerified, $compatibilityVerified, $databaseReady], JSON_THROW_ON_ERROR)), 'code_hash' => $code,
|
||||
'installed' => $installed, 'target' => $identity, 'counts' => $counts, 'backupVerified' => $backupVerified, 'qaVerified' => $qaVerified,
|
||||
return ['hash' => hash('sha256', json_encode([$identity, $code, $counts, $backupVerified, $qaVerified, $compatibilityVerified, $databaseReady, $pathQaVerified, $pathInstalled, (bool) config('investor-path.enabled')], JSON_THROW_ON_ERROR)), 'code_hash' => $code,
|
||||
'installed' => $installed, 'baseDeskInstalled' => app(VirtualDesk::class)->installed(), 'pathInstalled' => $pathInstalled,
|
||||
'pathEnabled' => (bool) config('investor-path.enabled'), 'pathQaVerified' => $pathQaVerified,
|
||||
'target' => $identity, 'counts' => $counts, 'backupVerified' => $backupVerified, 'qaVerified' => $qaVerified,
|
||||
'compatibilityVerified' => $compatibilityVerified, 'backupDate' => $backup['verified_at'] ?? null,
|
||||
'databaseReady' => $databaseReady,
|
||||
'scanner' => app(MalwareScanner::class)->health(),
|
||||
'pendingMigrations' => array_values(array_filter(self::MIGRATIONS, fn ($name) => ! DB::table('migrations')->where('migration', $name)->exists())),
|
||||
'rollback' => 'Reversão vazia ensaiada em cópia isolada. Com dados novos, preservar/exportar pedidos e tarefas; o down recusa eliminar dados. Restauro integral só numa janela autorizada, após reconciliar alterações posteriores ao backup.',
|
||||
'changes' => ['Completar o Balcão Virtual existente, preservando pedidos anteriores.', 'Acrescentar associações opcionais ao investidor, projecto e percurso existentes.',
|
||||
'Reutilizar tasks do CRM para acções expressamente assumidas; sem envio externo.', 'Nenhuma publicação de serviço, documento ou candidatura automática.']];
|
||||
'Reutilizar tasks do CRM para acções expressamente assumidas; sem envio externo.', 'Nenhuma publicação de serviço, documento ou candidatura automática.',
|
||||
'Preparar duas colunas nas entidades existentes e uma versão publicada do percurso de 19 etapas. Não converter dossiers existentes.',
|
||||
'Não habilitar a navegação por instalação: configuração INVESTOR_PATH_ENABLED permanece uma acção separada.']];
|
||||
}
|
||||
|
||||
public function apply(string $hash, User $actor): void
|
||||
@@ -84,7 +104,9 @@ class VirtualDeskInstallation
|
||||
return;
|
||||
}
|
||||
abort_unless($preview['backupVerified'] && $preview['qaVerified'] && $preview['compatibilityVerified'] && $preview['databaseReady'], 422, 'Backup/restauro atualizado, compatibilidade/reversão, permissões da base e QA desta versão continuam necessários.');
|
||||
abort_unless($preview['pathQaVerified'], 422, 'Demonstração A/B na interface e evidência API/persistência desta versão ainda necessárias.');
|
||||
config(['virtual-desk.installation_authorized' => true]);
|
||||
config(['investor-path.authenticated_installation' => true]);
|
||||
try {
|
||||
foreach (self::MIGRATIONS as $name) {
|
||||
if (! DB::table('migrations')->where('migration', $name)->exists()) {
|
||||
@@ -94,6 +116,7 @@ class VirtualDeskInstallation
|
||||
}
|
||||
} finally {
|
||||
config(['virtual-desk.installation_authorized' => false]);
|
||||
config(['investor-path.authenticated_installation' => false]);
|
||||
}
|
||||
DB::table('audit_events')->insert(['source_system' => 'virtual-desk', 'entity_type' => 'desk_cases', 'actor_user_id' => $actor->id,
|
||||
'action' => 'desk_installed', 'after_data' => json_encode(['preview_hash' => $hash, 'code_hash' => $preview['code_hash'], 'prior_counts' => $preview['counts']])]);
|
||||
|
||||
@@ -4,12 +4,14 @@ use App\Http\Middleware\EnsureSimulationRecoveryCookie;
|
||||
use App\Http\Middleware\HandleAppearance;
|
||||
use App\Http\Middleware\HandleInertiaRequests;
|
||||
use App\Http\Middleware\PreserveFormFeedback;
|
||||
use Illuminate\Contracts\Encryption\DecryptException;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Foundation\Configuration\Exceptions;
|
||||
use Illuminate\Foundation\Configuration\Middleware;
|
||||
use Illuminate\Http\Middleware\AddLinkHeadersForPreloadedAssets;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Str;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
@@ -31,6 +33,28 @@ return Application::configure(basePath: dirname(__DIR__))
|
||||
]);
|
||||
})
|
||||
->withExceptions(function (Exceptions $exceptions): void {
|
||||
$exceptions->dontReportWhen(fn (Throwable $exception) => $exception instanceof DecryptException
|
||||
&& request()->isMethod('POST') && request()->is('two-factor-challenge'));
|
||||
$exceptions->render(function (DecryptException $exception, Request $request) {
|
||||
if (! $request->isMethod('POST') || ! $request->is('two-factor-challenge')) {
|
||||
return null;
|
||||
}
|
||||
$reference = (string) Str::uuid();
|
||||
Log::warning('Two-factor credential could not be decrypted; authentication refused.', [
|
||||
'reference' => $reference, 'pending_user_id' => $request->session()->get('login.id'),
|
||||
]);
|
||||
$request->session()->invalidate();
|
||||
$request->session()->regenerateToken();
|
||||
$message = 'Não foi possível verificar a autenticação desta conta. Inicie sessão novamente ou contacte o suporte.';
|
||||
if ($request->expectsJson()) {
|
||||
$field = $request->filled('recovery_code') ? 'recovery_code' : 'code';
|
||||
|
||||
return response()->json(['message' => $message, 'errors' => [$field => [$message]], 'reference' => $reference], 422)
|
||||
->header('Cache-Control', 'no-store');
|
||||
}
|
||||
|
||||
return redirect()->route('login')->withErrors(['email' => $message])->header('Cache-Control', 'no-store');
|
||||
});
|
||||
$exceptions->shouldRenderJsonWhen(
|
||||
fn (Request $request) => $request->is('api/*') || $request->expectsJson(),
|
||||
);
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
// Preparation does not enable imports on an active target.
|
||||
'enabled' => (bool) env('TERRITORY_GEOMETRY_IMPORT_ENABLED', false),
|
||||
'directory' => storage_path('app/private/investmoz-v2/portal-audit'),
|
||||
'scan_max_age_seconds' => 86400,
|
||||
];
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
// Explicit opt-in after authenticated installation; never infer activation from schema/ready.
|
||||
'enabled' => env('INVESTOR_PATH_ENABLED', false),
|
||||
'definition_id' => '61000919-0000-4000-8000-000000000001',
|
||||
];
|
||||
@@ -201,7 +201,6 @@ SQL);
|
||||
}
|
||||
foreach (self::TABLES as $table) {
|
||||
if (Schema::hasTable($table)) {
|
||||
DB::statement("ALTER TABLE public.{$table} DISABLE ROW LEVEL SECURITY");
|
||||
$query = DB::table($table);
|
||||
if ($table === 'questionnaire_versions') {
|
||||
$query->where('id', '<>', '61000100-0000-4000-8000-000000000001');
|
||||
@@ -212,6 +211,9 @@ SQL);
|
||||
}
|
||||
}
|
||||
foreach (self::TABLES as $table) {
|
||||
if (Schema::hasTable($table)) {
|
||||
DB::statement("ALTER TABLE public.{$table} DISABLE ROW LEVEL SECURITY");
|
||||
}
|
||||
Schema::dropIfExists($table);
|
||||
}
|
||||
DB::statement('DROP FUNCTION IF EXISTS public.investmoz_reject_simulation_audit_change() RESTRICT');
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
use App\Services\InvestorPathDefinition;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
if (! app()->environment('testing') && ! config('investor-path.authenticated_installation')) {
|
||||
throw new RuntimeException('Investor path installation requires an authenticated, verified activation plan.');
|
||||
}
|
||||
if (DB::connection()->getDriverName() !== 'pgsql') {
|
||||
throw new RuntimeException('Investor path requires PostgreSQL.');
|
||||
}
|
||||
DB::statement('ALTER TABLE investor_journeys ADD COLUMN path_definition_id uuid REFERENCES questionnaire_versions(id) ON DELETE RESTRICT');
|
||||
DB::statement('ALTER TABLE journey_steps ADD COLUMN path_detail text');
|
||||
$definition = InvestorPathDefinition::snapshot();
|
||||
InvestorPathDefinition::validate($definition);
|
||||
$existing = DB::table('questionnaire_versions')->where('id', config('investor-path.definition_id'))->first();
|
||||
if ($existing) {
|
||||
$stored = json_decode($existing->schema_snapshot, true, 512, JSON_THROW_ON_ERROR);
|
||||
if (! is_array($stored) || Arr::sortRecursive($stored) !== Arr::sortRecursive($definition) || $existing->code !== 'investor-path-19' || $existing->status !== 'published') {
|
||||
throw new RuntimeException('Published definition differs: create a new version rather than overwrite it.');
|
||||
}
|
||||
} else {
|
||||
DB::table('questionnaire_versions')->insert([
|
||||
'id' => config('investor-path.definition_id'), 'code' => 'investor-path-19', 'version_no' => 1,
|
||||
'locale' => 'pt-MZ', 'schema_snapshot' => json_encode($definition, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE),
|
||||
'status' => 'published', 'valid_from' => '2026-10-09',
|
||||
]);
|
||||
}
|
||||
// Definition availability does not enable the feature or reinterpret existing journeys.
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
if (DB::table('investor_journeys')->whereNotNull('path_definition_id')->exists()
|
||||
|| DB::table('journey_steps')->whereNotNull('path_detail')->exists()) {
|
||||
throw new RuntimeException('Preserve investor path history: disable feature or restore a verified backup instead of dropping used columns.');
|
||||
}
|
||||
DB::statement('ALTER TABLE journey_steps DROP COLUMN path_detail');
|
||||
DB::statement('ALTER TABLE investor_journeys DROP COLUMN path_definition_id');
|
||||
// Published questionnaire versions are immutable; retain the unused definition and its provenance.
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,54 @@
|
||||
Classe,Percurso/caso automatizado,Asserções,Resultado QA,UI observada,Disponibilidade ativa demonstrada
|
||||
Tests\Feature\CrmIntakeTest,test_conversion_is_idempotent_and_preserves_source_with_owner_and_future_task,13,passou,não,não
|
||||
Tests\Feature\CrmIntakeTest,test_existing_contact_requires_explicit_investor_selection_and_is_not_duplicated,8,passou,não,não
|
||||
Tests\Feature\CrmIntakeTest,test_conversion_rechecks_the_canonical_contact_consent_record,9,passou,não,não
|
||||
Tests\Feature\CrmIntakeTest,test_unauthorised_users_cannot_convert_and_input_requires_owner_and_future_action,4,passou,não,não
|
||||
Tests\Feature\CrmIntakeTest,test_active_lead_keeps_a_next_action_and_qualification_is_audited,8,passou,não,não
|
||||
Tests\Feature\CrmIntakeTest,test_investor_edit_and_contact_duplicate_protection_are_scoped,8,passou,não,não
|
||||
Tests\Feature\InvestmentTerritoryTest,test_confirmed_coordinates_create_a_marker_without_hiding_missing_records,60,passou,não,não
|
||||
Tests\Feature\InvestmentTerritoryTest,test_public_cascade_filters_saved_locations_and_hides_unapproved_references,25,passou,não,não
|
||||
Tests\Feature\InvestmentTerritoryTest,test_opportunities_match_hierarchical_and_multiple_public_locations_without_expanding,33,passou,não,não
|
||||
Tests\Feature\InvestmentTerritoryTest,test_opportunity_cluster_and_corridor_filters_use_their_public_opportunity_relations,17,passou,não,não
|
||||
Tests\Feature\InvestmentTerritoryTest,test_cluster_territory_uses_only_public_validated_project_links_and_project_locations,1,passou,não,não
|
||||
Tests\Feature\InvestmentTerritoryTest,test_opportunity_pagination_retains_the_selected_territory,20,passou,não,não
|
||||
Tests\Feature\InvestmentTerritoryTest,test_cascade_assignment_persists_and_rejects_mismatched_parent_and_stale_write,17,passou,não,não
|
||||
Tests\Feature\InvestmentTerritoryTest,test_non_managers_cannot_read_internal_options,1,passou,não,não
|
||||
Tests\Feature\InvestmentTerritoryTest,test_opportunity_edit_saves_the_geographic_fields_with_the_record,13,passou,não,não
|
||||
Tests\Feature\InvestmentTerritoryTest,test_database_rejects_a_cycle_wrong_parent_and_duplicate_source_code,4,passou,não,não
|
||||
Tests\Feature\InvestmentTerritoryTest,test_integrity_migration_reverses_without_data_and_preserves_imported_codes,2,passou,não,não
|
||||
Tests\Feature\InvestmentTerritoryTest,test_background_options_do_not_consume_form_validation_feedback,12,passou,não,não
|
||||
Tests\Feature\InvestmentTerritoryTest,test_investment_areas_are_idempotent_and_preserve_legacy_sectors,4,passou,não,não
|
||||
Tests\Feature\LandAssistanceTest,test_public_guide_and_blank_form_are_available_without_claiming_official_status,16,passou,não,não
|
||||
Tests\Feature\LandAssistanceTest,test_private_draft_and_support_are_versioned_and_create_one_crm_receipt,16,passou,não,não
|
||||
Tests\Feature\LandAssistanceTest,test_phone_only_support_still_requires_contact_consent,5,passou,não,não
|
||||
Tests\Feature\LandAssistanceTest,test_phone_only_support_is_saved_without_a_synthetic_email,5,passou,não,não
|
||||
Tests\Feature\LandAssistanceTest,test_email_nullable_migration_can_be_reversed_when_no_email_is_missing,2,passou,não,não
|
||||
Tests\Feature\LandAssistanceTest,test_email_nullable_migration_refuses_rollback_with_phone_only_requests,2,passou,não,não
|
||||
Tests\Feature\OpportunityResourcesTest,test_encrypted_original_scan_pending_recovery_replacement_and_logical_lifecycle,23,passou,não,não
|
||||
Tests\Feature\OpportunityResourcesTest,test_multiple_locations_without_coordinates_and_invalid_hierarchy_and_geometry,14,passou,não,não
|
||||
Tests\Feature\OpportunityResourcesTest,test_invalid_upload_and_cross_opportunity_links_do_not_create_resources,7,passou,não,não
|
||||
Tests\Feature\OpportunityResourcesTest,test_image_processing_is_explicit_and_every_derivative_requires_its_own_scan,4,passou,não,não
|
||||
Tests\Feature\PartnershipExchangeTest,test_complete_local_flow_from_personal_draft_to_agreement_and_completed_milestone,16,passou,não,não
|
||||
Tests\Feature\PartnershipExchangeTest,test_preserves_legacy_proposal_and_rejects_self_moderation_and_concurrent_updates,4,passou,não,não
|
||||
Tests\Feature\PartnershipExchangeTest,test_draft_recovery_and_idempotency_do_not_require_organization_or_documents,7,passou,não,não
|
||||
Tests\Feature\PartnershipExchangeTest,test_competing_candidates_and_moderator_cannot_enter_private_room_or_read_other_interests,10,passou,não,não
|
||||
Tests\Feature\PartnershipExchangeTest,test_matching_keeps_unknown_information_separate_from_proven_failure_and_desirable_criteria,6,passou,não,não
|
||||
Tests\Feature\PartnershipExchangeTest,test_document_sharing_reuses_private_repository_and_scan_controls,8,passou,não,não
|
||||
Tests\Feature\PartnershipExchangeTest,test_organization_representation_blocks_viewer_writes_and_revoked_authors,6,passou,não,não
|
||||
Tests\Feature\PartnershipExchangeTest,test_hierarchical_filters_and_source_links_use_only_explicit_documented_relations,18,passou,não,não
|
||||
Tests\Feature\PartnershipExchangeTest,test_authenticated_installation_preserves_legacy_rows_and_is_repeatable_in_qa,5,passou,não,não
|
||||
Tests\Feature\PortalAuditConsumerLotTest,test_private_official_context_is_authorized_and_does_not_become_a_public_investment_site,20,passou,não,não
|
||||
Tests\Feature\PortalAuditConsumerLotTest,test_all_three_desk_forms_save_recover_countries_and_support_authorized_corrections,104,passou,não,não
|
||||
Tests\Feature\PortalAuditContinuationTest,test_public_country_and_origin_survive_api_storage_management_recovery_and_statistics,84,passou,não,não
|
||||
Tests\Feature\PortalAuditContinuationTest,test_support_kinds_keep_iso_country_separate_and_legacy_text_unchanged,24,passou,não,não
|
||||
Tests\Feature\PortalAuditContinuationTest,test_iso_catalogue_does_not_depend_on_geo_publication_and_is_searchable_and_pageable,21,passou,não,não
|
||||
Tests\Feature\PortalAuditContinuationTest,test_simulator_recovers_iso_countries_in_private_draft_without_reinterpreting_legacy_values,16,passou,não,não
|
||||
Tests\Feature\PortalAuditContinuationTest,test_desk_territory_cascade_is_saved_recovered_and_presented_with_origin_without_cross_account_access,58,passou,não,não
|
||||
Tests\Feature\PortalAuditNextLotTest,test_eight_maturity_stages_recover_versioned_without_reinterpreting_legacy_or_publishing,179,passou,não,não
|
||||
Tests\Feature\PortalAuditNextLotTest,test_business_country_origin_save_recover_filters_submission_statistics_and_actor_isolation,51,passou,não,não
|
||||
Tests\Feature\PortalAuditNextLotTest,test_land_country_origin_and_four_territory_levels_recover_in_support_filters_statistics,68,passou,não,não
|
||||
Tests\Feature\TerritorialRegistryTest,test_writes_require_idempotency_and_replays_recheck_current_permissions,10,passou,não,não
|
||||
Tests\Feature\TerritorialRegistryTest,test_drafts_are_private_and_hierarchy_duplicates_and_stale_versions_are_rejected,15,passou,não,não
|
||||
Tests\Feature\TerritorialRegistryTest,test_revoking_ancestor_source_hides_descendants_and_filters_are_scoped,6,passou,não,não
|
||||
Tests\Feature\TerritorialRegistryTest,test_authentication_mfa_and_empty_rollback,4,passou,não,não
|
||||
Tests\Feature\TerritorialRegistryTest,test_editor_reviewer_publisher_workflow_and_source_revocation,9,passou,não,não
|
||||
|
File diff suppressed because one or more lines are too long
@@ -0,0 +1,285 @@
|
||||
# InvesteMoz — backlog do lote 3
|
||||
|
||||
## C37 — causa confirmada; seleção de conta QA corrigida — P0, visual pendente
|
||||
|
||||
O pedido de reabertura referia a conta esperada18. A captura manual21:22–21:24UTC demonstra que foi selecionada a conta13 restaurada. O MFA foi alcançado, mas a autenticação nunca se completou. Causa concreta: credenciais MFA da conta13 cifradas pela chave de origem, incompatíveis com a chave estávelQA; a conta18 sintética não foi desafiada nessa tentativa. Nenhuma chave, MFA ou conta13 foi alterada para contornar o problema.
|
||||
|
||||
| UTC09/10 | Pedido | Resultado observado |
|
||||
|---|---|---|
|
||||
|21:22:10|GET/investimentos|302/login; sessão convidada guardada, destino pretendido /investimentos.|
|
||||
|21:22:11|GET/login|200; mesmo cookie/sessão, sem autenticação.|
|
||||
|21:22:44|POST/login|302/two-factor-challenge; login.id=13, não18.|
|
||||
|21:22:44|GET/two-factor-challenge|200; desafio13 recuperado da mesma sessão; ecrã confirmado pelo utilizador.|
|
||||
|21:23:04|POST/two-factor-challenge|Falha de desencriptação; warning correlacionado conta13;302/login, invalidação intencional e nova sessão convidada.|
|
||||
|21:23:04|GET/login|200; cookie aceite corresponde à sessão regenerada; sem utilizador autenticado.|
|
||||
|
||||
Primeiro desvio do ensaio: POST/login desafia13. Primeira falha técnica: POST/two-factor-challenge às21:23:04 (trace ec68d040a3291cb8, referência26e15b04-07b8-4211-a2a0-7f70509e03f6). Não se tratou de código MFA rejeitado pelo verificador nem de perda após autenticação. Os dois campos cifrados (secret/recovery) são incompatíveis; como nenhum corpo foi retido, não se afirma qual modalidade de entrada foi usada nesta tentativa. Não foram observados conflitos de cookies, mudança de chave/guard ou redirecionamento para outra origem.
|
||||
|
||||
CorreçãoQA, após guarda real desk_restore_20261009_174726_test:55441: login identifica/preenche o email não secreto da conta18; o ecrã MFA identifica a conta realmente desafiada. PortalQaAccountSelection, carregado exclusivamente pelo routerQA, recusa endereços não sintéticos antes do desafio e cancela desafios antigos de contas restauradas, com erro controlado. Os perfis sintéticosQA mantêm o login Fortify normal e respetivo MFA. Contas restauradas e dados ativos preservados. A conta13 continua cifrada como no original; não foi reencryptada nem usa chave ativa como fallback.
|
||||
|
||||
Lacuna de feedback encontrada no código: o Form recém-criado no login começa com erros locais vazios e não lia o errors.email devolvido pela página após redirecionamento do MFA. Login agora apresenta também esse erro da página. A mensagem de falha de desencriptação continua controlada e não autentica; sua apresentação visual ainda exige confirmação.
|
||||
|
||||
Evidência atual2026-10-09T21:37:04.282708+00:00 em c37-auth-redirect-qa.json, pelo servidor18097 e protocolo Inertia/HTML com redirects reais: seletor13 recusado antes do MFA; desafio18 identificado; código inválido mantém desafio sem autenticar; MFA válido regenera/grava18 e redireciona /investimentos; GET e reload mantêm18; logout revoga acesso; novo cookie jar+login+MFA recupera o mesmo dossier413ba1f6-bdf6-402a-a561-c4e2d4098d1a; outra conta403. Negativo sintético19 demonstra falha de desencriptação→login com mensagem, sem autenticação. Nenhuma criação extra de dossier. Estes são resultados de resposta/persistência, não um ensaio visual bem-sucedido.
|
||||
|
||||
Evidências: c37-manual-2122-2124-qa.json conserva os seis pedidos e warning sanitizados; auth-session-trace-qa.jsonl mantém histórico append-only e pseudónimos HMAC; c37-qa-account-auth.xml verifica políticaQA, preservação, MFA válido/inválido e falhas secret/recovery; c37-installation-auth-fingerprint.xml verifica guardas/importação/reversão. TypeScript e build passaram. mfa-persistence-qa.json reconfirma conta13 e .env byte a byte, MFA18 confirmado/oito códigos, chave não gerada/rodada e zero escritas ativas. Cookies, passwords, OTP e corpos não são exportados.
|
||||
|
||||
Estado: causa identificada, preparaçãoQA corrigida e protocolo/persistência demonstrados; C37 permanece aberto para /investimentos visível→reload→logout→novo login da conta18 no navegador. A captura manual demonstrou apenas o MFA da conta13 e retorno ao login; não certifica o percursoA/B nem o feedback atualizado. Próximo teste deve confirmar que o ecrã diz contaQA18 antes de usar o autenticador dessa conta. URL exato http://127.0.0.1:18097/investimentos. Credenciais/segredo permanecem somente no ficheiro privado local investor-mfa-qa-private.json, sem exportação. Workflow/contratos especializados continuam no backlog, sem jornadas educativas novas.
|
||||
|
||||
Ativação não autorizada e revisão candidata não fixada. Fingerprints agora incluem também login.tsx e two-factor-challenge.tsx: percursob402e851b49bfb640f26417f1ff783320210271cd7d84e80dea0db264c89ec28; cartografia95610d2660956a9bb10e6ac9443c24ededf4f3d97f996047c92a5d5c37ff3c6c; recursos4aa6946228b5ebb99bb29e3166e9ce53abdba776b3298a9ccbe437784d8cfa02. Ready/provas de versões anteriores não demonstram esta revisão. Política/seletor/rastreioQA não integram instalação ativa. Após aceitação visualA/B e correções, renovar backup/restauro/compatibilidade e manter a ordem já documentada de recursos→percurso→flag→importação cartográfica→publicação separada, sem repetir o que estiver instalado. ReversãoQA: retirar registo/configuração de PortalQaAccountSelection e overrides Fortify do router; retirar os registos de rastreio; preservar provas. A correção do feedback é código compatível sem migration, alteração de chave ou modificação de dados.
|
||||
|
||||
## Próximo passo após C37 — retomar A com MFA
|
||||
|
||||
1. Retomar A primeiro na interface18097 com o investidor sintético MFA; iniciar janela privada nova. Preservar o500 reportado como falha bloqueante histórica; conta13 restaurada não deve servir de conta sintéticaQA. Nova criação manual continua exigida, não apenas abrir o dossier HTTP.
|
||||
2. Registar login/desafio/mensagem/recuperação, depois ferramenta→resultado→Balcão→acompanhamento e negativas; omitir Cookie/X-XSRF-TOKEN/corpo do código das capturas. Corrigir outras falhas antes de fixar candidata.
|
||||
3. B, países/estatísticas e seletores/mapas/documentos continuam no mesmo backlog. API/persistência das operações não aguardam browser; ClamD mantém âmbito específico.
|
||||
4. Após resultados manuais: renovar backup/restauro/compatibilidade sobre a revisão final. Bootstrap/Fortify agora entram nos fingerprints; não reutilizar ready/provas de revisão anterior. Nenhuma ativação ativa autorizada.
|
||||
|
||||
## Próximo lote I0–I3 — após importação e scans reais
|
||||
|
||||
1. **P0/P1 interface:** executar A primeiro em http://127.0.0.1:18097/investimentos; depois B e perfis. Registar URL/ação/esperado/observado/IDs/versão e prova visual; incorporar os resultados manuais na mesma matriz e corrigir falhas antes de fixar candidata. API/HTTP já passaram, não antecipar UI.
|
||||
2. **P1 países/origem/estatísticas:** percorrer cada formulário de cobertura-percursos-i0-i3.md, incluindo negócios/fundiário, serviços Balcão, filtros e agregados separados. Não confundir residência/constituição/origem de fundos com origem declarada de solicitações.
|
||||
3. **P1 territorial:** observar cada seletor/mapa/consumidor; testar nova página `/management/territory-geometry-import?level=1`, depois2/3, confirmando correspondências, resultados e histórico com gestor QA/MFA. A importação não publica. Resolver somente correspondências explícitas fundamentadas, listadas por nome em correspondencias-cartograficas.md; conservar casos2/39/179 e ausência de localidades.
|
||||
4. **P1 documental:** testar visualmente upload/scan/download/substituição/exclusão/restauro/previews; C31/C35/C36 corrigidos em QA. Biblioteca e Balcão têm provas reais específicas, incluindo reutilização do original cifrado sem duplicação e resposta PDF inline verificada. Renderização PDF, lote, tipos/perfis/partilhas/imutabilidade continuam abertos por consumidor. Configuração permanente ClamD/assinaturas/GD ativo é pendência operacional específica.
|
||||
5. **OPS-01:** após demonstração e correções, fixar hashes e renovar backup/restauro/compatibilidade. Preparar provas vinculadas à revisão/alvo, incluindo a prova específica cartográfica. Recursos030000, percurso190000, flag e importação/publicação separados. Nenhuma ativação autorizada agora; fonte oficial aceite não se reabre.
|
||||
|
||||
## Próximo lote atual — critérios abertos após as provas HTTP
|
||||
|
||||
1. **P0/P1 AUD-UI-01, DASH-01, SIM-01, DESK-02, GUIDE-01, CRM-01:** executar [roteiro A/B](roteiro-manual-qa-i0-i3.md), criar projetos novos pela interface, recuperar em outra sessão do navegador, alternar sem mistura, ferramenta/resultado, rascunho de apoio e tarefa paralela. Provas HTTP já passaram; navegador continua sem fornecedor. Fecho exige capturas/resultados/rede/persistência por passo.
|
||||
2. **P1 AUD-COUNTRY-01–04/06–07 e STATS-01:** ensaiar visualmente cada formulário da [cobertura](cobertura-percursos-i0-i3.md), filtros/URL/tabela e agregados separados. Interesse em negócio público e estatística específica da jornada agora têm provas API/persistência próprias; a apresentação e variações condicionais continuam abertas. Perfil/empresa e residência fiscal/fundos preservam significados próprios.
|
||||
3. **P1 AUD-GEO-02/03:** observar cada seletor/mapa, incluindo C27 já preparado; guardar/reabrir campo, limpar descendentes, respeitar acesso e edição.361 disponíveis na QA não são361 públicos nem cobertura visual. Correspondências2/39/179 e localidades permanecem; reutilizar cadastro/originais sem aproximação ou dados inventados. Edição de zonas exige conta QA com MFA; não desativar a permissão.
|
||||
4. **P1 AUD-OPS-01:** após demonstração, renovar backup/restauro/hashes/compatibilidade da versão final; repetir somente ensaios pertinentes e gerar provas verdadeiras. Recursos030000 e percurso190000 são instalações distintas; flag habilita navegação separadamente. Mecanismo cartográfico C30 preparado e demonstrado em QA; verificar interface e preparar prova específica da revisão/alvo após backup final. Importador CLI QA não pode ser apontado ao ativo. C28 preparador corrigido para não exigir contagem381 fixa.
|
||||
5. **Workflow e contratos especializados:** continuam pendentes; sem novas jornadas educativas enquanto falhas prioritárias abertas. ClamD real e GD/scan das três derivadas de oportunidades têm provas QA atuais; arranque permanente/manutenção/PHP ativo e operações ainda não ensaiadas são pendências específicas, sem bloquear países/preparação.
|
||||
|
||||
Todas as linhas permanecem na matriz existente; não reabrir aceitação de fontes oficiais nem recriar estados/dados paralelos. Nenhuma instalação ativa autorizada.
|
||||
|
||||
## Histórico do próximo lote então definido — antes da continuação HTTP/C27
|
||||
|
||||
1. **I0/P0–P1 e AUD-UI-01:** recuperar provider do navegador; executar os A/B completos (criação, nova sessão, alternância, ferramenta/resultado, apoio e resposta interna) e ações existentes por perfil. Servidor QA18096 disponível; provider continua sem apps/browsers. API/persistência continuam executáveis independentemente do browser.
|
||||
2. **COUNTRY01–04/06–07,STATS01,GEO01–03:** cobertura individual de países/origem/filtros/estatísticas e seletores/mapas; integrar os consumidores restantes sem inferir ponto/perímetro/DUAT. 361 geometrias privadas na mesma QA são cadastro/disponibilidade, não apresentação nem publicação. Correspondências2/39/179 e polígonos de localidades continuam em aberto.
|
||||
3. **AUD-DESK-02,SIM01/02,DASH01,GUIDE01,CRM01:** completar prefill por campo/consumidor, testar retorno e conflitos na interface. C25 corrige rascunho por dossier; C26 preserva RLS na recusa de rollback. Motor inicial conserva19 etapas/5 fases e os roteiros antigos; não certifica todas as regras jurídicas/licenças/financiamento.
|
||||
4. **Ativação separada:** renovar backup/restauro/fingerprints da versão final; recursos030000 uma vez, percurso190000 pelo mecanismo autenticado do Balcão, configuração de disponibilização separada e cartografia em lote autenticado próprio ainda por completar. Nenhuma destas ações ativas está autorizada agora.
|
||||
5. **Workflow e contratos especializados:** continuam no backlog. Educação sem novas jornadas. ClamD/GD/derivadas são dependências das operações documentais afetadas, sem bloquear preparação/países.
|
||||
|
||||
Critérios e componentes estão em [execucao-percurso-i1-i3.md](execucao-percurso-i1-i3.md); a [matriz existente](matriz-requisitos.csv) mantém3.354 requisitos/5.830 origens e todos os estados/fontes. I1–I3 não encerrados por ensaios automáticos. Os lotes anteriores abaixo conservam as suas provas/versões.
|
||||
|
||||
## Histórico anterior à execução — prioridades em torno do percurso
|
||||
|
||||
Consultar a [proposta de consolidação](proposta-consolidacao-percurso.md) e a correspondência das 19 etapas aos IDs da matriz. É desenho proposto, não aceitação funcional.
|
||||
|
||||
1. **I0/P0–P1, já autorizado:** falhas de ações/recuperação, países/origem por formulário, cartografia por consumidor e contexto correto; C24 corrigido em QA, visual pendente. Nenhuma dependência de aprovação da consolidação para estes reparos.
|
||||
2. **I1, após aprovação:** painel composto com projeto atual, etapas, pendências/documentos/resultados e próxima ação. Preservar URLs e funções da gestão. Aceitação: UI completa e autorização por origem.
|
||||
3. **I2, após aprovação:** dados mestres e prefill consentido, resultados/contexto por ID/versão, nova sessão e alternância A/B sem contaminação. Aceitação inclui conflitos e ausência de sobrescrita; single-current-draft ainda exige adaptação.
|
||||
4. **I3, após aprovação:** definição configurável/versionada das 19 etapas, aplicabilidade triestado, dependências por ação e estados separados. Reutilizar QuestionnaireVersion, investor_journeys/journey_steps, tasks e eventos. A/B completos na interface são condição de fecho; nenhuma migration executada agora.
|
||||
5. **I4:** licenças/terra/financiamento/execução e monitoria conforme evidências e âmbito, sem integrações externas obrigatórias. Workflow e contratos especializados mantidos. Educação permanece depois das falhas prioritárias, sem nova jornada iniciada.
|
||||
|
||||
Ativação de recursos/cartografia continua separada; não inclui automaticamente o futuro motor. Backup/compatibilidade/rollback deverão ser renovados após alterações estruturais. As quatro decisões humanas anteriores e a aceitação oficial permanecem preservadas.
|
||||
|
||||
09/10/2026. Mesma matriz 3354 requisitos/5830 origens; código/QA/ativo separados. Nenhuma nova jornada educativa iniciada.
|
||||
|
||||
## P0/P1 corrigidos em QA
|
||||
|
||||
**COUNTRY04/DESK01,C21:** país separado no Balcão; origem devolvida para correção já não recebe 422 por whitelist incompleta. Três serviços: guardar cifrado → recuperar → submeter → gestor devolver campos permitidos → dono corrigir → versão 5/GET; autorrevisão e outra conta403, campo não autorizado 422, conflito409. Sem migração/reinstalação. Falta visual.
|
||||
|
||||
**GEO02/03,C22:** consulta/preview de limites administrativos em consumidores existentes, incluindo oportunidade draft/recursos e catálogo/painel.361 limites reais QA recuperados; zero divulgação interna pública; contexto ancestral não vira geometria própria da localidade. Sem novas relações/pontos/perímetros. Fonte/edição/hash preservados. Falta renderização e cobertura individual restante.
|
||||
|
||||
**UI01,C23:** serviço QA recuperado; HTTP200/_test:55441. Provider de UI continua ausente após reset/Chrome/Edge. Retomar cliques/capturas assim que a sessão de navegador for ligada. Causa de configuração não confirmada; não declarar recuperação visual concluída.
|
||||
|
||||
## Próximo lote executável
|
||||
|
||||
1. **Ações por perfil/consumidor: UI01,DASH01,DESK01/02,CRM01,BIZ01,LAND01,PART01.** Reutilizar controllers/services/versionamento/audit_events. Usar acoes-perfis-lote3.csv como índice de casos passados, não substituto da inspeção de todos os botões. Aceitação por ação: perfil autorizado/negado → resposta/erro visível → versão/evento/cifra quando aplicável → GET/nova sessão → resultado apresentado; conflito/inválido conserva dados. Escopo atual já inclui CRM 6, território 13, fundiário 6, recursos 4, Bolsa 9 casos, mas falta cada consumidor/transição visual. Ensaios API avançam independentemente do browser. Anexos têm dependência ClamD/GD concreta.
|
||||
2. **Países/origem/estatísticas: COUNTRY01–04/06–07,STATS01,SIM01.** Revisar variações condicionais/nova sessão/URL/unknown/todos e filtros por cada formulário da tabela do relatório. CountryCatalogue/CountrySelect/payloads cifrados existentes; sem inferir residência/nacionalidade/origem. Aceitação:249 opções/pesquisa, código conhecido, recuperação nome/código, texto histórico conservado, sem nova versão após inválido, conjuntos interests/desk/businesses reconciliados. Falta interface atual e comprovação por cada variação, sem ClamD.
|
||||
3. **Seletores/mapas: GEO01–03/AUD-FIELD.** Em TerritoryFields, gestão territorial, drafts/recursos, catálogo/painel, testar filhos limpos ao trocar pai, paginação, seleção/recuperação, disponibilidade geométrica por perfil, edição/camada/legenda/zoom e ausência visível. Integrar consumidores restantes de estruturas, parcerias e zonas conforme seu contrato: contexto administrativo nunca autoriza perímetro ou localização de investimento. Usar geo_locations/geo_geometries existentes. Sem criar módulos/tabelas paralelos.
|
||||
4. **Lacunas GIS:** resolver explicitamente 2/39/179 correspondências não inequívocas e procurar exemplar oficial de localidades. Reconciliar Maputo/edições/nome/pai; não fuzzy-remapear ou assumir equivalência de códigos. Aceitação:original/hash/scan/correspondência única/validade SRID 4326; replay zero duplicados, classificação e histórico preservados. Aceitação oficial já dada não é reaberta. Atividade/divulgação exige ato explícito, não importação.
|
||||
5. **Ativação:** seguir plano consolidado separado. Código sem migration, extensão de recursos uma vez autenticada, cartografia em lote separado privado. Contagens previstas361=9+120+232 somente se baseline ativo ainda0 e sem conflitos; zero novos geo_locations, zero relações/pontos de oportunidade inferidos. Prévia/cartografia ativa ainda precisa do mecanismo autenticado correspondente: não adaptar o importador QA para apontar ao ativo. Backup/restauro/contagens/hash/rollback verificados antes do ato. Não repetir Balcão/Bolsa/gestão básica.
|
||||
|
||||
## Backlog preservado
|
||||
|
||||
**OP03/04/05:** workflow completo e contratos especializados; filtros/ficha pública conscientes da maturidade versionada, sem vazar draft nem reinterpretar legado. Mantidos abertos; não iniciados como jornadas novas neste lote.
|
||||
|
||||
**EDU02/03/01:** rascunho incompleto, jornadas/painéis educativos continuam depois das falhas prioritárias acima. Sem novas jornadas até seu fecho.
|
||||
|
||||
**LIB01/02,SIM02,GUIDE01:** acervo, regras/cálculos e orientação conforme critérios existentes; estados consulta/jurídico/cálculo independentes. Sem preenchimentos artificiais, parâmetros ausentes nunca zero/taxa recente.
|
||||
|
||||
**SCAN01:** ClamD real funciona e testes reais passaram; arranque após reinício/manutenção/GD web/scan de derivadas ainda pendentes por operação. Não bloquear países/estatísticas/seletores por isso.
|
||||
|
||||
**DOC01:** estados reconciliados, fontes/versões preservadas; revisão semântica de cláusulas ainda pendente. PDFs diretos não entregues por falta de ferramenta nativa; links Adobe falhados não contam como entrega.
|
||||
|
||||
Decisões humanas mantidas: pares de IDs oportunidade–projeto/cluster e citação/papel; entidade operadora/contactos/termos; responsável/links por serviço; pesos/limiares/baseline dos pilotos. Nenhuma revalidação genérica da fonte oficial aceite.
|
||||
|
||||
QA atual 381/5046,zero skips; 156 frontend/reconciliação,TypeScript/PHPStan/build/formato passam,lint11 avisos. UI não observada. Installed=false,ready=true em 2026-10-09T17:50:07+00:00;backup 2026-10-09T17:47:35+00:00/desk_restore_20261009_174726_test:55441/hash 8fe9cbf438a87315c1c20588bd9a748239018d0662af22533774e07f16a06cef. A preparação técnica não fecha ações/mapas/workflow nem é instalação.
|
||||
|
||||
## Histórico do lote 2 e anteriores — não representa o estado atual
|
||||
|
||||
# InvesteMoz — backlog priorizado do lote 2
|
||||
|
||||
09/10/2026. Mesma [matriz](matriz-requisitos.csv): **3.354 requisitos, 5.830 linhas de origem**. Estados: 5 concluídos, 3.198 parciais, 146 não implementados, 1 implementado não ativo, 0 com falha no critério registado, 4 decisões concretas. Parcial pode conter funcionalidade ainda em falta. Código preparado ≠ QA demonstrada ≠ funcionalidade ativa.
|
||||
|
||||
## P0 — guardar, recuperar e preservar
|
||||
|
||||
**AUD-OPS-02/03 — concluídos no critério operacional.** Guarda host/porta/base e lock antes da limpeza; ensaios só em QA; consulta ativa READ ONLY. Aceitação cumprida: runner concorrente recusado, suite sequencial passa, snapshots preservados. Backup/restauro atual compara 288 tabelas/cinco ficheiros; 207/209 hashes temporais coincidem, divergência cache/sessions não atribuída.
|
||||
|
||||
**AUD-GEO-02 / C17 — falha fundiária corrigida em QA, requisito global parcial.** Remover condição errada province.parent_id=null; reutilizar geo_locations/InvestmentGeography, mantendo validação de descendentes e classificação. Aceitação QA: país→província→distrito→posto→localidade guarda/recupera e apresenta caminho nas props; IDs inválidos/outra conta negados sem alterar versão. Falta UI. Sem migration/ClamD.
|
||||
|
||||
**AUD-COUNTRY-07 / C18 — perda da origem corrigida em QA.** Conservar origem explícita no payload/hash/metadata ao solicitar apoio; reutilizar InterestSubmission e CRM interno. Aceitação QA: country PT/origem ZA continuam distintos no caso, recibo, pedido e filtro; uma contagem, replay sem duplicação, sem inferência histórica. Falta clique/resultado visual.
|
||||
|
||||
Toda nova falha de escrita/recuperação nos percursos seguintes sobe a P0, com reprodução, esperado/observado, causa e prova de conservação. Não instalar recursos ativos para diagnosticar.
|
||||
|
||||
## P1 — lote já corrigido, ainda sem aceitação visual
|
||||
|
||||
**AUD-OP-05 / C15 — 422 para 7/8 resolvido.** OpportunityMaturity/OpportunityManagement e seletor reutilizam management_draft. Oito códigos spec-v2 coexistem com seis valores legacy-v1. Aceitação demonstrada: oito criações/GET, 7/8=201, etapa/posição/versão recuperadas, código/posição incompatíveis 422, conflito 409, perfil indevido 403, replay único. Mudança só de versão sem etapa é recusada; legado não é reinterpretado. Próximo: filtros/fichas e publicação conscientes da versão, após workflow; não expor draft privado no catálogo. Sem migration/ClamD.
|
||||
|
||||
**AUD-COUNTRY-06 / C19 — negócios.** CountryCatalogue/CountrySelect + BusinessFormSchema/ExistingBusinessIntake/CanonicalBusinessRepository existentes. País/origem separados, ISO desconhecido 422, texto Portugal preservado no draft até escolha explícita, payload cifrado, cinco revisões conservadas. Filtros operam depois do escopo autorizado; drafts não entram no agregado. Falta visual e versão web ativa. Dependência: catálogo 249 existente, sem dados novos/tabela.
|
||||
|
||||
**AUD-COUNTRY-07 / C17–19 — fundiário.** País/origem separados; GET recupera nomes/códigos/caminho; submissão integra interesses/CRM uma vez; inválido conserva versão e legado exato. Falta visual. Sem ClamD ou extensão de recursos.
|
||||
|
||||
**AUD-STATS-01 — filtros/agregados.** DeclaredOriginStatistics mantém interests, desk e businesses separados; negócio só submetido, fundiário contabilizado como interesse. Aceitação QA: filtro ZA contém pedido, PT não; unknown permanece não informado; país não substitui origem; outra conta negada. Próximo: URL/seleção/nova sessão/tabela no navegador. Não contar investidores únicos.
|
||||
|
||||
**AUD-SCAN-01 / C07 — serviço real disponível.** ClamD 1.5.4 com bases oficiais, EICAR em memória detetado e seis integrações reais. Próximo: arranque após reinício, atualizações regulares e prova de GD/WebP web/scan de cada derivada. Critério: benigno/ameaça por hash, assinatura/data/versão, restrição só na operação afetada. Limite geral de 20 MB mantido; ADM3 GIS teve scan CLI separado, não alargamento do limite do portal.
|
||||
|
||||
**AUD-STYLE-01 / C10 — concluído.** Pint e formato global passaram; lint 0 erros/11 avisos. **AUD-UI-01 / C20 — pesquisa ligada à rota existente**, ainda precisa de clique/feedback no browser.
|
||||
|
||||
## P1 — próximo lote executável, por ordem
|
||||
|
||||
1. **AUD-UI-01; AUD-DASH-01; AUD-DESK-01/02; AUD-CRM-01; AUD-BIZ-01; AUD-LAND-01.** Percorrer ações existentes antes de novas jornadas: criar/editar/guardar/recuperar/pesquisar/filtrar, transições, exclusão lógica/restauro e anexos aplicáveis, por dono/revisor/gestor/consumidor. Reutilizar controllers/services/formulários existentes e inventário de 363 botões. Aceitação por ação: resposta/erro visível, versão/evento, GET seguinte e isolamento; GET de rota não fecha botão. API e persistência avançam sem browser; visual continua pendente. ClamD só nos anexos/scans afetados; recursos pendentes só nos percursos que usam a extensão.
|
||||
2. **AUD-COUNTRY-01–04/06–07; AUD-STATS-01; AUD-SIM-01.** Fechar consumidores restantes por formulário, incluindo campos condicionais de serviços/Balcão e origem na recuperação. Reutilizar catálogo ISO/componentes/payloads; não inferir nacionalidade/residência/origem entre si. Aceitação: seleção/pesquisa → pedido válido → valor cifrado/canónico → nova sessão → nome/código e filtros/agregado reconciliados; ZZ 422 sem escrita, legado exato, unknown/todos, contas isoladas. Não depende de ClamD.
|
||||
3. _*AUD-GEO-01–03; AUD-FIELD-* — todos os seletores._* Inventário de 270 seletores/mapas é evidência de consumidores, não cobertura funcional. Reutilizar TerritoryFields/ProvinceSelect/InvestmentGeography e os 1.920 IDs existentes. Aceitação individual: pai limpa filhos, pesquisa paginada sem omissões, ID válido guarda/recupera, privado/descendente errado 422 conserva versão, nomes e caminho apresentados. Múltiplos locais de oportunidades dependem da extensão instalada em QA, não de repetir módulos.
|
||||
4. **AUD-GEO-03 — camadas e lacunas GIS.** Reutilizar geo_geometries e importador guardado. Já há 361 correspondências internas em QA, scan original real, SRID/validade e replay zero novos. Próximo: conferir camadas em cada mapa, filtro/ID/geometria/legenda/resultado e política existente de acesso. Lacunas concretas: 2/39/179 sem correspondência por nível, nenhuma localidade; Maputo exige reconciliação explícita de versão/designação. Não usar centroides administrativos como investimento. Aceitação: fonte/edição/hash, correspondência inequívoca e resultado da camada; sem publicação ou vigência presumida. Procura de outras geometrias oficiais não reabre aceitação da fonte identificada.
|
||||
5. **AUD-OP-03/04/05 — workflow e contratos especializados.** Reutilizar draft/versionamento/audit_events/categorias existentes. Implementar revisão→devolução→aprovação→publicação com perfis distintos e critérios por categoria; levar catálogo versionado até filtros/ficha pública sem vazar propostas. Aceitação: cada transição autorizada/negada, motivo/ator/versão, recuperação, publicação só do conteúdo aprovado; campos/regras por categoria, legado conservado. Pessoas reais necessárias para atos ativos, não para desenvolver/testar QA.
|
||||
|
||||
Depois de cada incremento, atualizar a mesma linha canónica, referências/versões, caso e cinco etapas de prova. Não esperar por decisões independentes nem criar tabelas/cadastros paralelos.
|
||||
|
||||
## P1/P2 — restantes pedidos preservados
|
||||
|
||||
**AUD-EDU-02/03/01:** rascunho incompleto de procura/capacidade e jornadas/painéis por ator continuam ausentes/incompletos. Curso/proposta em draft não os substitui. Entram depois dos percursos existentes acima. Reutilizar LabourDemand/TrainingCapacity/schemas, sem datas/zeros fictícios. Aceitação: draft privado incompleto guarda/recupera, submissão incompleta 422 conserva draft, versão/conflito/isolamento, exclusão dos agregados; completo segue revisão por ator distinto.
|
||||
|
||||
**AUD-LIB-01/02:** inventário 584 registos, disponibilidade/jurídico/cálculo independentes; preview/hash/dedup por bytes/conflito de identidade/scan/escrita privada/replay, nunca publicação automática. Original e autorização por ficheiro; associação a artigo/módulo não condiciona cadastro/consulta. Fonte fiscal ausente/parâmetro ambíguo indeterminado, nunca zero/taxa recente.
|
||||
|
||||
**AUD-SIM-02; AUD-PART-01; AUD-GUIDE-01:** regras/versionamento/cálculos explicáveis; candidatura/sala/marcos/retirada por papel; orientação com fonte/âmbito/período e recuperação. Preservar cadastros vazios sem fabricar população. Critério individual na matriz, não fecho por existência de menu.
|
||||
|
||||
**AUD-DOC-01:** separar semântica das cláusulas compostas preservando fonte/ID/versões; histórico não substitui estado atual. Original upgrade v4 e relatório outputs indicado não localizados; mensagem preservada como fonte sem hash inventado.
|
||||
|
||||
## Decisões humanas — perguntas exatas
|
||||
|
||||
- **AUD-OP-02:** quais pares de IDs oportunidade–projeto/cluster, papel e citação devem ser associados?
|
||||
- **AUD-HUMAN-01:** qual entidade operadora, contactos e versões de termos/política estão autorizados para divulgação?
|
||||
- **AUD-HUMAN-02:** quais contactos/links específicos e responsável real devem constar por serviço?
|
||||
- **AUD-HUMAN-03:** que pesos, limiares, baseline/período e responsáveis devem ser usados nos pilotos?
|
||||
|
||||
Nenhuma pergunta é uma segunda validação da credibilidade oficial já aceite.
|
||||
|
||||
## Ativação e prova de fecho
|
||||
|
||||
379 testes/4.922 asserções/zero skips; 156 frontend/reconciliação; checks técnicos passaram. [Casos C01–C20](casos-reproducao.md), [cobertura por percurso](cobertura-consumidores-lote2.md), [plano autenticado](plano-ativacao.md). Browser indisponível; nenhuma demonstração visual atual.
|
||||
|
||||
Backup/restauro 09/10 17:29 UTC, 288 tabelas/cinco ficheiros, hash 69252e25…; ready=true, installed=false. Países/origem/estatísticas/maturidade privada não exigem migration; recursos privados exigem só extensão pendente autenticada; geometria QA é independente e privada. Não repetir Balcão/Bolsa/gestão básica. Instalação não fecha workflow/mapas/visual nem ativa cálculo fiscal.
|
||||
|
||||
## Histórico da continuação anterior — não representa o estado atual
|
||||
|
||||
# Backlog consolidado — situação atual
|
||||
|
||||
09/10/2026. Mesma [matriz](matriz-requisitos.csv): **3.354 requisitos canónicos, 5.830 linhas de origem preservadas**. Quatro concluídos, 3.196 parciais, 146 não implementados, um implementado não ativo, três com falha, quatro dependentes de decisão concreta. Critérios/IDs/versões por origem mantidos. Código, QA e atividade são estados separados.
|
||||
|
||||
## P0 — preservação e recuperação
|
||||
|
||||
- **AUD-OPS-02/C03: concluído no critério operacional.** Lock por host/porta/base antes da limpeza. Segundo runner recusado; suite sequencial passa. Reutilizar `tests/TestCase.php`; nunca ensaiar na base ativa.
|
||||
- **AUD-OPS-03: concluído no critério de leitura/preservação.** READ ONLY e snapshots arquivados. 207/209 hashes temporais iguais; cache/sessions diferentes sem atribuir causa. Restauro integral atual compara 288 tabelas/cinco ficheiros.
|
||||
- **AUD-OPS-01/C04: parcial, aplicação ativa pendente.** IDs de auditoria dentro do snapshot; backup/restauro/reversão atuais e preview pronto. Aceitação: hash/destino/validade, migration/evento únicos e classificações/relações/histórico conservados. Recursos continuam não instalados.
|
||||
|
||||
Toda nova falha de guardar/recuperar passa a P0 com payload sintético, resposta, valor/hash recuperado e causa. Escrita só em QA `_test:55441`.
|
||||
|
||||
## P1 — próximo lote executável, por ordem
|
||||
|
||||
1. **AUD-COUNTRY-06/07, 01–04: países nos consumidores restantes.** CountryCatalogue/CountrySelect no wizard de negócios e assistência fundiária; mesmos payloads/cadastros. Dados: 249 ISO existentes; conservar texto legado sem inferir origem/nacionalidade. Aceitação por campo: pesquisa → endpoint autorizado → código no payload canónico → nova sessão recupera → nome/código apresentado; ZZ 422 sem nova versão, outra conta negada e legado exato conservado. Executável sem ClamD/decisão humana.
|
||||
2. **AUD-OP-05/C15: oito etapas de maturidade.** Catálogo versionado conforme especificação, usando `OpportunityManagement`/draft/filtros existentes; manter escala/rótulos antigos e não remapear IDs 1–6 automaticamente. QA reproduz 422 para 7/8 por `between:1,6`. Aceitação: criar/editar/recuperar oito etapas, inválido recusado, legado sem reinterpretar, filtro/ficha coerentes e 409 conserva proposta. Preparar código em QA; adoção em dados reais exige associação explícita.
|
||||
3. **AUD-EDU-02/C16: rascunho educativo incompleto.** Reutilizar LabourDemand/TrainingCapacity/PortalAudit, schemas e contas. Guardar draft privado separado da submissão completa, com dono/versão/conflito; se colunas exigirem completude, extensão compatível pelo mecanismo autenticado existente. Não criar tabela paralela nem zeros/datas fictícios. Aceitação: incompleto guarda/edita/recupera; outra conta negada; submeter incompleto 422 conserva draft; draft fora dos agregados/revisão; declaração completa revista por ator distinto. Os 422 atuais confirmam ausência do percurso, não defeito do validador de submissão.
|
||||
4. **AUD-GEO-01–03/AUD-FIELD-\*, AUD-DASH-01/AUD-UI-01: território e ações por consumidor/perfil.** Reutilizar API povoada, ProvinceSelect/TerritoryFields e relações existentes; verificar seletores próprios, múltiplos locais, devolvido/desativado e filtros. Aceitação: mudança de pai limpa filhos, IDs pesquisados/guardados/recuperados, erro no campo e resultado apresentado. Ações: criar/editar/guardar/recuperar/pesquisar/filtrar/transições/exclusão/restauro/anexos aplicáveis. GET estático não encerra botão. Backend avança sem browser; visual desktop/móvel/teclado fica pendente.
|
||||
5. **AUD-EDU-03/01 e RF/RNF-EDU: jornadas/painéis por ator.** Percursos de estudante, formador, empregador e gestor sobre cadastros existentes. Aceitação por ator: entrada, draft, recuperação, próxima ação, fonte/âmbito/período, indicadores reconciliados e isolamento. Curso/proposta em draft não substitui procura/capacidade. Designações reais só para atos institucionais ativos.
|
||||
|
||||
Atualizar requisito canónico, critérios de origem e caso após cada incremento. Não esperar por geometrias, nomeações ou respostas independentes.
|
||||
|
||||
## P1 — lote preparado e demonstrado parcialmente
|
||||
|
||||
**AUD-COUNTRY-04/C01/C13:** CountrySelect no portal, apoio (quatro tipos), interesse em negócio e jornada; país PT e origem ZA persistem separados. Gestor/jornada recuperam; inválido não escreve; replay único; legado conservado. Novo lote: cinco testes/203 asserções. Falta UI e consumidores restantes. Quatro solicitações históricas ativas continuam sem origem inferida.
|
||||
|
||||
**AUD-STATS-01:** filtro HTTP/Inertia ZA=1/PT=0, conjuntos interest/desk separados. Falta navegador para seleção/URL/unknown/todas/tabela; 403 sem permissão e contagem de solicitações, não investidores únicos. Não depende de CRM externo/ClamD.
|
||||
|
||||
**AUD-COUNTRY-05 concluído no critério HTTP:** 249 códigos, pesquisa/paginação/sem acentos e validação de parâmetros, independente de publicação geo. **AUD-SIM-01/C12 parcial:** simulador usa catálogo ISO e API territorial; snapshots cifrados guardam/recuperam PT/ZA e legado Portugal; ZZ 422, outra conta 404; sem execução fiscal por guardar. Falta UI e demais campos.
|
||||
|
||||
**AUD-GEO-02/C14 parcial:** Balcão hierárquico em quatro níveis guarda/recupera ID e props; erro de ID privado conserva versão/seleção. **AUD-GEO-04 concluído no critério API:** 597 pedidos recuperam 1.920/1.920 IDs públicos administrativos da cópia ativa, sem omissões/duplicados. Não encerra todos os campos/mapas.
|
||||
|
||||
## P1 — recursos, mapas e restantes percursos
|
||||
|
||||
- **AUD-GEO-03/C06:** geo_geometries=0. Recuperar limites/coordenadas concretos do acervo aceite, preview e gestão existente com autorização por ficheiro. Aceitação: geometria/versão/citação por entidade, exclusão/restauro, lista dos não localizados, mapa/filtros recuperáveis. Não inventar centros/pontos.
|
||||
- **AUD-REL-01/02:** preservar 28 locais/13 relações, recuperar citação e usar reparador/contexto existente. Pergunta: **para cada oportunidade ID 1–6, qual projeto/cluster exato, papel e referência devem ser ligados?** Aceitação: pares identificados, conflito/idempotência/reversão; preparação de prova independente.
|
||||
- **AUD-OP-01/02:** gestão básica instalada; só extensão de imagens/documentos/multilocalização pelo plano autenticado. Aceitação: draft/ETag/409, até 50 locais, original/hash/versão, exclusão/restauro e evento/migration únicos, sem publicação automática. ClamD limita binários; metadados/localizações independentes.
|
||||
- **AUD-OP-03/04/C08:** workflow versionado e campos/regras especializados sobre draft/políticas/auditoria e objetos/direitos canónicos existentes. Aceitação: autor não autoaprova, devolução conserva, público só versão aprovada, replay único, histórico/privados preservados. Pergunta só para configuração ativa: **quem são revisores/aprovadores/publicadores designados?** QA pode avançar.
|
||||
- **AUD-DESK-01/02, AUD-GUIDE-01, AUD-CRM-01:** dossier → pedido → orientação → responsável/tarefa/mensagem → recuperação; manifestação → lead → próxima ação → fecho. Reutilizar contexto sem copiar conta/jornada/pedido. Aceitação: título/versão, 409, isolamento, fonte/período, tarefa seguinte e transições. Dados/responsáveis reais só para uso ativo; QA sintética independente.
|
||||
- **AUD-SIM-02:** cálculos/unidades/períodos e regras versionadas; inventariar também fontes não analisadas/artigos sem documento. Aceitação: totais reconciliados e parâmetros documentados; ausente indeterminado, sem zero/taxa recente substituta; publicação não ativa cálculo.
|
||||
- **AUD-LIB-01/02:** todos os ficheiros/anexos inventariados, autorização/âmbito e consulta/lote privado com documents/jobs/histórico. Aceitação: preview/hash/dedup bytes/conflitos/replay, original/edição/proveniência e scan por ficheiro; nunca publicar lote automaticamente. Consulta/situação documental/cálculo separados; associação a módulo não é pré-condição.
|
||||
- **AUD-SCAN-01/C07:** ClamD real/assinaturas e três integrações ainda pendentes; afeta scan/libertação de binários/derivadas afetados, não países/território/estatísticas/drafts. EICAR exclusivamente QA, benigno/derivada por hash próprio e nenhum scan falso. GD/WebP web é dependência separada da geração de derivadas.
|
||||
|
||||
## P2 e decisões concretas
|
||||
|
||||
- **AUD-PART-01:** Bolsa instalada; consentimento, candidaturas/salas/mensagens/marcos por papel, retirada/versão/isolamento; acordo não é assinatura certificada.
|
||||
- **AUD-BIZ-01/AUD-LAND-01:** direitos/mandatos/revisões/fundiário sobre cadastros existentes e MFA; privados não vazam e fonte genérica não prova direito individual. Países desses consumidores foram destacados como P1.
|
||||
- **AUD-UX-01:** UUID da jornada retirado da apresentação, relações mantidas; validar legibilidade e demais informações/botões.
|
||||
- **AUD-STYLE-01/C10:** formato por ficheiro preservando alterações locais; 16 frontend/documentos/scripts e cinco PHP no último check global.
|
||||
- **AUD-HUMAN-01:** **qual entidade operadora, contactos e versões de termos/política estão autorizados para divulgação?**
|
||||
- **AUD-HUMAN-02:** **quais contactos/links específicos e responsável real devem constar por serviço?** Conteúdo/âmbito/expiração; sem recertificação da credibilidade oficial aceite.
|
||||
- **AUD-HUMAN-03:** **que pesos, limiares, baseline/período e responsáveis devem ser usados nos pilotos?** Medir antes de alegar sucesso.
|
||||
- **AUD-DOC-01:** atualizar estados por data/versão/prova e decompor cláusulas compostas individualmente; preservar divergências/decisões. Relatório em outputs não localizado; só mensagem lida. Histórico abaixo não é pendência atual por si só.
|
||||
|
||||
## Provas e ativação
|
||||
|
||||
373/376 testes, 4.608 asserções, três ClamD saltados; 152 frontend, TypeScript/PHPStan/build passaram. Matriz aponta para `phpunit-final.json`, `phpunit-followup-recovery-final.log`, `territory-catalogue-coverage.json`, `pending-actions.json`; quatro 422 deste último são reproduções de pendências, não aceitação aprovada. [Casos C01–C16](casos-reproducao.md).
|
||||
|
||||
Código/assets sem migration → confirmar catálogos/recuperação → extensão única de recursos autenticada → scan/derivadas nas operações afetadas → uso real com dados/designações. Backup/restauro 16:18:09 UTC, 288 tabelas/cinco ficheiros, fingerprint atual e preview `ready=true`, `installed=false`. [Plano](plano-ativacao.md). Não reinstalar Balcão/Bolsa/gestão básica, nem transformar fixture em dado ativo/publicação/cálculo.
|
||||
|
||||
## Histórico inicial — sequência anterior preservada, não estado atual
|
||||
|
||||
# Backlog inicial de conclusão
|
||||
|
||||
Data: 09/10/2026. A [matriz](matriz-requisitos.csv) conserva pedidos/fontes e estados; o [CSV priorizado](backlog-priorizado.csv) contém uma linha por item. A sequência abaixo organiza incrementos concretos sem esperar por decisões independentes. Código preparado, QA demonstrada e funcionalidade ativa são resultados distintos. Não foi demonstrada perda ativa de dados.
|
||||
|
||||
## P0 — integridade e recuperação
|
||||
|
||||
| IDs/caso | Correção/componentes | Dependência | Aceitação e estado |
|
||||
| ---------------- | ---------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
||||
| AUD-OPS-02 / C03 | Lock por host/porta/base em `tests/TestCase.php`, antes de migrations. Suites sequenciais ou bases isoladas distintas. | Nenhuma decisão; QA `_test:55441`. | Segundo processo recusado antes da limpeza; suite sequencial passa. **Corrigido e demonstrado em QA**. |
|
||||
| AUD-OPS-01 / C04 | IDs de auditoria no snapshot de `desk-activation-backup.php`; validar dump/restauro e ficheiros antes de emitir prova. | Provas privadas vinculadas ao código/destino. | 288 tabelas/cinco ficheiros iguais; migration/reversão QA preserva dados. **Tooling corrigido; aplicação ativa pendente**. |
|
||||
| AUD-OPS-03 | Preservar primeiro snapshot, arquivar leituras posteriores e distinguir alterações técnicas de negócio. | Leitor `READ ONLY`, hashes e logs privados. | Classificações/relações preservadas; cache/sessions divergentes explicitados. **Leitura demonstrada**. |
|
||||
|
||||
Se surgir nova falha de guardar/recuperar nos percursos seguintes, registá-la como P0 com payload QA, resposta, valor recuperado e causa. Não fazer instalação ativa para diagnosticar perda.
|
||||
|
||||
## P1 — pedidos expressos e percursos essenciais
|
||||
|
||||
| IDs | Correção concreta / reutilização | Dados e dependência real | Aceitação |
|
||||
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| AUD-COUNTRY-01–04 | Aplicar `CountryCatalogue`/`CountrySelect` aos consumidores restantes, incluindo cadastro inicial e campo genérico legado. Correção da origem pública/legada preparada. | 249 ISO existentes; manter residência/constituição/origem separadas; não converter texto histórico automaticamente. | Pesquisa; ZZ 422 sem escrita; nova sessão recupera; outra conta negada; replay único; ausência não informada. API QA demonstrada; UI pendente. |
|
||||
| AUD-STATS-01 | Conferir filtro CRM país/não informado/todos e totais separados com `DeclaredOriginStatistics`. | Quatro históricos sem origem; browser QA. | URL/seleção recuperáveis; 403 sem permissão; contagens não são investidores únicos. Backend demonstrado; navegador pendente. |
|
||||
| AUD-GEO-01–03; AUD-FIELD-001–046 | Demonstrar/corrigir cada consumidor; reutilizar `TerritoryFields`, `ProvinceSelect`, API e `geo_locations`. Completar campo plano do Balcão, seletores próprios e mapas/listas. | Pesquisa provincial preparada; limites/pontos de fonte concreta identificada; zero geometrias não autoriza coordenadas fictícias. | Pai/filho coerentes; troca de pai limpa descendentes; seleção visível; nova sessão recupera IDs; mapa identifica não localizados; desktop/390 px. Componente comum não conclui todos os consumidores. |
|
||||
| AUD-REL-01–02 | Recuperar citação por associação e gravar pelo reparador/contexto existente. | Manter 28 locais/13 relações. Pergunta por ID 1–6: **qual projeto/cluster exato, papel e referência devem ser ligados?** | Só pares identificados; duplicado/conflito/reversão auditados. Preparar evidência independentemente das respostas restantes. |
|
||||
| AUD-OP-01–02 | Conferir CRUD/ETag/arquivo/restauro e aplicar só extensão de recursos pelo [plano](plano-ativacao.md). Reutilizar `OpportunityManagement`, `OpportunityResources`, `documents`, `geo_locations`. | Backup/prova atuais; conta autorizada; browser QA. ClamD/GD separados de metadados. | Rascunho recuperado; 409 preserva proposta; originais/versões/hash; 50 locais; exclusão/restauro; schema/evento único. Gestão básica ativa; recursos não ativos. |
|
||||
| AUD-OP-03 | Construir validação final e transições versionadas de submissão/devolução/revisão/aprovação/publicação sobre draft/auditoria/políticas existentes. | Pergunta antes de configuração ativa: **quem são os revisores/aprovadores/publicadores designados?** Desenvolvimento QA pode avançar. | Autor não autoaprova; devolução conserva proposta; público só muda por ato autorizado; replay não duplica; histórico preservado. |
|
||||
| AUD-OP-04; OP-FIELD especializados | Implementar por categoria contratos imobiliário/DUAT/transações ligando objetos/direitos canónicos existentes. | Identificadores, direitos, mandatos e documentos concretos; sem cadastros paralelos. | Cada coleção/campo valida, guarda, recupera e respeita visibilidade. Categoria isolada não implementa contrato. |
|
||||
| AUD-DASH-01; AUD-UI-01 | Percorrer dashboard/menu e destinos por perfil; inventariar botões, indicadores, informação desnecessária e retornos 422/403. | Browser/sessão QA; sem ampliar permissões ativas. | Ação com efeito/feedback recuperável; contador corresponde à consulta; teclado/foco/móvel; destinos vazios não dados como concluídos. |
|
||||
| AUD-DESK-01–02; AUD-GUIDE-01 | Dossier → pedido → orientação → tarefa/mensagem → recuperação reutilizando conta/jornada/solicitação. | Serviço/responsável reais só para primeiro pedido ativo; QA sintética independente. | Sem duplicar contexto; título conservado; nova sessão recupera; erro junto ao campo; fonte/âmbito/período; transição/responsável auditados. |
|
||||
| AUD-CRM-01 | Manifestação → lead → responsável → próxima ação → acompanhamento/fecho no CRM interno. | Designações existentes; SuiteCRM externo independente; sem leads ativos de exemplo. | Conversão idempotente; acesso entre contas negado; próxima ação mantida; tarefa/mensagem recuperada; fecho consistente. |
|
||||
| AUD-SIM-01–02 | Conferir rascunho privado, cálculos, unidades/períodos e regras versionadas com os calculadores/armazenamento cifrado existentes. | Inventariar também fontes não analisadas e diplomas/artigos sem documento. Parâmetro ausente indeterminado. | Totais/fluxo reconciliam; versão não reinterpreta histórico; recuperar; ausência não vira zero/taxa recente; publicação não ativa cálculo. |
|
||||
| AUD-LIB-01–02 | Reconciliar inventário/cadastro/autorizações/consulta e lote privado com preview/hash/dedup/conflitos/replay; reutilizar `documents`, jobs e histórico. | Originais/anexos inventariados; divulgação por ficheiro/âmbito; associação a módulo/artigo não é pré-condição. | Original/hash/edição/proveniência; estados consulta/jurídico/cálculo separados; bloqueio só concreto; lote nunca publica automaticamente. |
|
||||
| AUD-SCAN-01 | Disponibilizar ClamD real e verificar PHP web GD/WebP; repetir integrações afetadas. | Serviço/assinaturas reais; PHP CLI não prova web. | EICAR QA detetado; benigno/derivada por hash; restrições só levantadas com evidência; nenhum scan falso ativo. |
|
||||
| AUD-EDU-01; RF/RNF-EDU | Percorrer catálogo e procura/capacidade por ator separadamente; completar rascunho/versões/importação/acesso nos schemas existentes. | Dados institucionais reais; mandatos só para atos institucionais; D01–D08 já documentadas não reabertas genericamente. | Cada ator guarda/recupera; vagas/trabalhadores distintos; fonte/período; publicação não equivale a acreditação. |
|
||||
|
||||
## P2 — restantes requisitos e configuração
|
||||
|
||||
| IDs | Trabalho | Dependência/pergunta exata | Aceitação |
|
||||
| ----------------------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| AUD-PART-01 | Rascunho/candidatura/sala/marcos sobre Bolsa instalada. | Dados/atores/acordos concretos; cadastro ativo vazio. | Consentimento/versões/isolamento; retirada; mensagem/ficheiro recuperável; marcos por papel, sem assinatura certificada presumida. |
|
||||
| AUD-BIZ-01; AUD-LAND-01 | Conferir negócios/revisões, direitos/mandatos e fundiário no cadastro canónico/MFA. | Objeto/direito identificados; fonte oficial genérica não prova direito individual do promotor. | Rascunho/conflito/recuperação; revisão por ator; privado não vaza; sem venda automática de direito. |
|
||||
| AUD-UX-01 | Remover informação interna sem utilidade preservando relações. UUID da jornada já retirado da apresentação. | Percurso visual; sem mudança de dados. | Título/ações legíveis; IDs internos mantidos. |
|
||||
| AUD-STYLE-01 | Corrigir formatação por ficheiro e verificar diff. | Sem decisão; preservar alterações alheias. | Checks passam sem mudar comportamento/texto. |
|
||||
| AUD-HUMAN-01 | Configuração de identidade/contactos/termos. | **Qual entidade operadora, contactos e versões de termos/política estão autorizados para divulgação?** | Dados fornecidos e âmbito registado; operador não inventado. |
|
||||
| AUD-HUMAN-02 | Links/fontes por serviço com conteúdo/expiração/fallback. | **Quais contactos/links específicos e responsável real devem constar por serviço?** | Link aplicável com origem/data e fallback; sem recertificar credibilidade oficial. |
|
||||
| AUD-HUMAN-03 | Modelo/pilotos sobre regras existentes. | **Que pesos, limiares, baseline/período e responsáveis autorizados devem ser usados?** | Resultado explicável/limitado; medir antes de alegar sucesso. |
|
||||
|
||||
Restantes cláusulas: revisão individual e critérios atómicos, com evidência contrato/API/persistência/UI. Depois de cada incremento, atualizar linha de origem e casos; não promover parcial por existir teste do domínio. Executar checks pertinentes e suite global quando a mudança justificar.
|
||||
@@ -0,0 +1,244 @@
|
||||
# Casos de reprodução e lacunas observáveis
|
||||
|
||||
## C37 — causa confirmada; seleção de conta QA corrigida — P0, visual pendente
|
||||
|
||||
O pedido de reabertura referia a conta esperada18. A captura manual21:22–21:24UTC demonstra que foi selecionada a conta13 restaurada. O MFA foi alcançado, mas a autenticação nunca se completou. Causa concreta: credenciais MFA da conta13 cifradas pela chave de origem, incompatíveis com a chave estávelQA; a conta18 sintética não foi desafiada nessa tentativa. Nenhuma chave, MFA ou conta13 foi alterada para contornar o problema.
|
||||
|
||||
| UTC09/10 | Pedido | Resultado observado |
|
||||
|---|---|---|
|
||||
|21:22:10|GET/investimentos|302/login; sessão convidada guardada, destino pretendido /investimentos.|
|
||||
|21:22:11|GET/login|200; mesmo cookie/sessão, sem autenticação.|
|
||||
|21:22:44|POST/login|302/two-factor-challenge; login.id=13, não18.|
|
||||
|21:22:44|GET/two-factor-challenge|200; desafio13 recuperado da mesma sessão; ecrã confirmado pelo utilizador.|
|
||||
|21:23:04|POST/two-factor-challenge|Falha de desencriptação; warning correlacionado conta13;302/login, invalidação intencional e nova sessão convidada.|
|
||||
|21:23:04|GET/login|200; cookie aceite corresponde à sessão regenerada; sem utilizador autenticado.|
|
||||
|
||||
Primeiro desvio do ensaio: POST/login desafia13. Primeira falha técnica: POST/two-factor-challenge às21:23:04 (trace ec68d040a3291cb8, referência26e15b04-07b8-4211-a2a0-7f70509e03f6). Não se tratou de código MFA rejeitado pelo verificador nem de perda após autenticação. Os dois campos cifrados (secret/recovery) são incompatíveis; como nenhum corpo foi retido, não se afirma qual modalidade de entrada foi usada nesta tentativa. Não foram observados conflitos de cookies, mudança de chave/guard ou redirecionamento para outra origem.
|
||||
|
||||
CorreçãoQA, após guarda real desk_restore_20261009_174726_test:55441: login identifica/preenche o email não secreto da conta18; o ecrã MFA identifica a conta realmente desafiada. PortalQaAccountSelection, carregado exclusivamente pelo routerQA, recusa endereços não sintéticos antes do desafio e cancela desafios antigos de contas restauradas, com erro controlado. Os perfis sintéticosQA mantêm o login Fortify normal e respetivo MFA. Contas restauradas e dados ativos preservados. A conta13 continua cifrada como no original; não foi reencryptada nem usa chave ativa como fallback.
|
||||
|
||||
Lacuna de feedback encontrada no código: o Form recém-criado no login começa com erros locais vazios e não lia o errors.email devolvido pela página após redirecionamento do MFA. Login agora apresenta também esse erro da página. A mensagem de falha de desencriptação continua controlada e não autentica; sua apresentação visual ainda exige confirmação.
|
||||
|
||||
Evidência atual2026-10-09T21:37:04.282708+00:00 em c37-auth-redirect-qa.json, pelo servidor18097 e protocolo Inertia/HTML com redirects reais: seletor13 recusado antes do MFA; desafio18 identificado; código inválido mantém desafio sem autenticar; MFA válido regenera/grava18 e redireciona /investimentos; GET e reload mantêm18; logout revoga acesso; novo cookie jar+login+MFA recupera o mesmo dossier413ba1f6-bdf6-402a-a561-c4e2d4098d1a; outra conta403. Negativo sintético19 demonstra falha de desencriptação→login com mensagem, sem autenticação. Nenhuma criação extra de dossier. Estes são resultados de resposta/persistência, não um ensaio visual bem-sucedido.
|
||||
|
||||
Evidências: c37-manual-2122-2124-qa.json conserva os seis pedidos e warning sanitizados; auth-session-trace-qa.jsonl mantém histórico append-only e pseudónimos HMAC; c37-qa-account-auth.xml verifica políticaQA, preservação, MFA válido/inválido e falhas secret/recovery; c37-installation-auth-fingerprint.xml verifica guardas/importação/reversão. TypeScript e build passaram. mfa-persistence-qa.json reconfirma conta13 e .env byte a byte, MFA18 confirmado/oito códigos, chave não gerada/rodada e zero escritas ativas. Cookies, passwords, OTP e corpos não são exportados.
|
||||
|
||||
Estado: causa identificada, preparaçãoQA corrigida e protocolo/persistência demonstrados; C37 permanece aberto para /investimentos visível→reload→logout→novo login da conta18 no navegador. A captura manual demonstrou apenas o MFA da conta13 e retorno ao login; não certifica o percursoA/B nem o feedback atualizado. Próximo teste deve confirmar que o ecrã diz contaQA18 antes de usar o autenticador dessa conta. URL exato http://127.0.0.1:18097/investimentos. Credenciais/segredo permanecem somente no ficheiro privado local investor-mfa-qa-private.json, sem exportação. Workflow/contratos especializados continuam no backlog, sem jornadas educativas novas.
|
||||
|
||||
Ativação não autorizada e revisão candidata não fixada. Fingerprints agora incluem também login.tsx e two-factor-challenge.tsx: percursob402e851b49bfb640f26417f1ff783320210271cd7d84e80dea0db264c89ec28; cartografia95610d2660956a9bb10e6ac9443c24ededf4f3d97f996047c92a5d5c37ff3c6c; recursos4aa6946228b5ebb99bb29e3166e9ce53abdba776b3298a9ccbe437784d8cfa02. Ready/provas de versões anteriores não demonstram esta revisão. Política/seletor/rastreioQA não integram instalação ativa. Após aceitação visualA/B e correções, renovar backup/restauro/compatibilidade e manter a ordem já documentada de recursos→percurso→flag→importação cartográfica→publicação separada, sem repetir o que estiver instalado. ReversãoQA: retirar registo/configuração de PortalQaAccountSelection e overrides Fortify do router; retirar os registos de rastreio; preservar provas. A correção do feedback é código compatível sem migration, alteração de chave ou modificação de dados.
|
||||
|
||||
## C37 — MAC inválido no desafio MFA bloqueia cenário A — P0
|
||||
|
||||
**C37/P0 — falha bloqueante do cenário A reportada pelo utilizador, corrigida por código/HTTP/persistência QA; retoma visual ainda pendente.** URL: http://127.0.0.1:18097/investimentos. Alvo real confirmado antes de qualquer escrita: `desk_restore_20261009_174726_test:55441`.
|
||||
|
||||
Stack completa dos erros20:39:16/20:41:52 (68frames por ocorrência) retida sem argumentos em mfa-original-stack-redacted.json. Falha em TwoFactorLoginRequest::hasValidCode() ao desencriptar users.two_factor_secret da conta13; PreserveFormFeedback apenas chama o próximo middleware. A conta restaurada não é sintética: secret/recovery abrem com a chave do .env de origem, mas não com a chaveQA. Cache de configuração não carregado; source cache também ausente. A ferramenta de preparação do percurso antes não fixava APP_KEY e podia herdar origem. portal-qa-environment.php centraliza a mesma chaveQA já existente entre preparação/web, força alvo/restauro, configura caminho QA de cache separado e recusa cache não reconciliado. Não gera chave, não usa chaves ativas como fallback nem modifica .env/cache ativo.
|
||||
|
||||
Duas sessões pendentes da conta13 removidas exclusivamente do diretório de sessões QA, após guarda do destino e paths. Original conta13 preservado byte a byte pelo hash da linha; nenhuma chave/MFA ativa ou da conta13 alterada. Novo investidor sintético QA: actor18, inscrição normal pelos endpoints Fortify (confirmar password→enable→secret-key→confirm), oito recovery codes, sem injeção direta do segredo nem desativação de MFA. Dados de acesso/segredo somente em investor-mfa-qa-private.json local privado; não exportados aqui.
|
||||
|
||||
POST /two-factor-challenge com DecryptException agora invalida desafio/sessão e retorna422 com mensagem controlada em JSON ou redireciona ao login com erro visível; nenhuma autenticação. Negativas reais de secret/recovery verificam401 após erro e remoção do desafio. A resposta HTML/Inertia contém a mensagem, sem ser prova de renderização visual. Logs controlados incluem apenas referência e ID pendente; as provas não exportam Cookie, X-XSRF-TOKEN, OTP ou corpos.
|
||||
|
||||
No mesmo servidor18097: login/MFA/logout/nova sessão passaram. A retomado por HTTP em `/investimentos/413ba1f6-bdf6-402a-a561-c4e2d4098d1a`: criação→logout→nova sessãoMFA→recuperação→aplicabilidade semterra/semfinanciamento→draft próprio→resultado→Balcão draft→tarefa concluída pela gestão→nova sessãoMFA recupera tudo. Gestão não recebe resultado financeiro privado. Função efetiva do dossier recalcula20unidades/0.00 a partir do resultado recuperado. QA atual5instâncias/95etapas; originals anteriores preservados. Esta conta não vê os A/B da outra contaQA.
|
||||
|
||||
Evidências: mfa-key-diagnosis-qa.json, mfa-session-invalidation-qa.json, mfa-persistence-qa.json, mfa-http-qa.json e mfa-auth-qa.xml. Os17 ensaios autenticam ou recusam os percursos concretos; não substituem interface. Fingerprints passam a incluir bootstrap/Fortify, invalidando ready/provas anteriores para ativação. `integrated_ui_ab_passed=false`, `candidate_revision_fixed=false`, `activation_ready=false`; nenhuma escrita ativa. Mesma matriz3354requisitos/5830origens, sem fecho amplo novo.
|
||||
|
||||
## C01 — origem declarada descartada no percurso público/legado — P1
|
||||
|
||||
Passos: em QA, enviar `POST /api/v1/interest-requests` com consentimento, campos válidos, `country=Moçambique`, `declared_origin_country_code=PT` e chave idempotente nova. Recuperar a solicitação e estatísticas autorizadas. Repetir a submissão; depois alterar só a origem para ZA com a mesma chave. Repetir no apoio e percurso legado de jornada.
|
||||
|
||||
Esperado: origem PT distinta do campo legado; replay retorna o mesmo protocolo sem duplicar; payload diferente com chave igual recebe 409; ZZ recebe 422 sem escrita; ausência de origem permanece não informada.
|
||||
|
||||
Observado antes da correção: validadores/controladores não incluíam a origem no payload persistido; o formulário não recolhia o campo. Causa: percursos legados não integrados com o catálogo/estatísticas de origem. Diagnóstico por código; sem reprodução visual antiga.
|
||||
|
||||
Após correção: `PortalOriginCompatibilityTest` e `InvestmentPortfolioTest` demonstram validação, persistência e idempotência em QA. Seletor ISO preparado nos formulários correspondentes. Os quatro pedidos ativos permaneceram com origem não informada. UI atual pendente.
|
||||
|
||||
## C02 — seleção provincial invisível e pesquisa ausente — P1
|
||||
|
||||
Passos: carregar um consumidor de `ProvinceSelect` com um valor provincial guardado ausente da lista recebida; tentar pesquisar nome/código; alterar rapidamente o texto de pesquisa e observar a resposta final. Este componente legado usa o nome provincial; os campos hierárquicos usam IDs. Não foi feita conversão entre estes contratos.
|
||||
|
||||
Esperado: seleção guardada visível; pesquisa no cadastro existente; resposta antiga não substitui a atual. Observado no código anterior: não existia entrada de pesquisa; o valor apresentado era convertido para vazio quando não encontrado nas opções. Causa: tratamento de lista carregada como universo completo de valores.
|
||||
|
||||
Após correção: `ProvinceSelect` pesquisa com `q`, debounce e cancelamento; conserva opção de seleção guardada explicitamente identificada. TypeScript/build passaram. Reproduzir visualmente em desktop/móvel continua necessário; não se afirma que os 46 consumidores estejam concluídos.
|
||||
|
||||
## C03 — concorrência entre runners da mesma QA — P0, tooling corrigido
|
||||
|
||||
Passos reproduzidos nesta auditoria: iniciar suite global e, enquanto executa, iniciar outra suite com `RefreshDatabase` no mesmo `investmoz_test:55441`.
|
||||
|
||||
Esperado: isolamento entre ensaios ou recusa antes de migrations. Observado: deadlock/remoção concorrente de tabelas, com falhas artificiais na primeira execução. Causa: dois runners partilharam uma base; foi erro de orquestração desta auditoria, não defeito funcional do portal.
|
||||
|
||||
Correção: `tests/TestCase.php` adquire lock exclusivo por host/porta/base antes da conexão/limpeza. Segundo runner recusado com `Another test process owns this QA database`, antes de zero asserções e migrations. Prova `qa-lock-rejection.json`. Repetição sequencial passou: 368 testes, 4.401 asserções, três ClamD saltados. Bases QA distintas podem correr separadamente.
|
||||
|
||||
## C04 — prova de backup podia misturar dois instantes — P0, tooling corrigido
|
||||
|
||||
Passos: inspecionar a ordem de `tools/desk-activation-backup.php`; comparar o snapshot usado para dump/hashes com o ponto de leitura dos IDs de auditoria.
|
||||
|
||||
Esperado: dump, hashes e IDs pertencem ao mesmo snapshot. Observado antes: IDs recolhidos depois de `ROLLBACK`; uma escrita externa naquele intervalo podia produzir prova incoerente. Causa identificada por inspeção de código; não se afirma perda de dados ou ocorrência de escrita concorrente real.
|
||||
|
||||
Correção: recolha dos IDs antes do `ROLLBACK`. Novo restauro em `desk_restore_20261009_151551_test:55441`: 288 tabelas e cinco ficheiros verificados; migration/reversão dos recursos conservam os hashes da cópia. Provas e ZIP/configuração continuam privados.
|
||||
|
||||
## C05 — recursos ausentes na base ativa — P1, instalação pendente
|
||||
|
||||
Passos: executar o leitor de preview e consultar o estado de migrations/tabelas numa transação `READ ONLY`; abrir a página autenticada de pré-visualização quando houver browser/sessão autorizada.
|
||||
|
||||
Esperado para considerar ativo: extension migration presente, tabelas existentes, evento de instalação único e recursos recuperáveis pela conta autorizada. Observado: `installed=false`, ausência do esquema de recursos; `ready=true` apenas para o plano preparado. Causa: extensão ainda não aplicada. Não é falha de CRUD demonstrada por um menu.
|
||||
|
||||
Aceitação após aplicação: uma instalação autenticada, segunda aplicação idempotente, seis classificações e relações intactas. Ensaiar a aplicação/replay apenas em QA; não repetir ações ativas para testar idempotência.
|
||||
|
||||
## C06 — cartografia não povoada e relações indeterminadas — P1
|
||||
|
||||
Passos: contar `geo_geometries`, `opportunity_locations`, `opportunity_projects` e `opportunity_clusters` por leitura; confrontar com catálogo/mapa e fichas existentes.
|
||||
|
||||
Esperado: localizar só entidades com geometria cadastrada; apresentar explicitamente as não localizadas; vínculos por par identificado e citado. Observado: quatro conjuntos com zero registos; os 1.990 territórios textuais não fornecem por si geometria. Causa: dados geométricos/vínculos específicos ainda não cadastrados. Não fabricar pontos do centro provincial nem associar pelo nome/setor/proximidade.
|
||||
|
||||
Correção necessária: selecionar dados e referências concretos do acervo já inventariado, pré-visualizar associações e gravar pela gestão existente. A credibilidade de fontes oficiais identificadas não volta a ser questionada. Percurso visual de todos os campos continua pendente.
|
||||
|
||||
## C07 — scanner real indisponível — P1, ambiente
|
||||
|
||||
Passos: verificar saúde de ClamD e executar as integrações reais de scanner/worker com EICAR apenas em QA.
|
||||
|
||||
Esperado: serviço e assinaturas identificados, deteção de EICAR, ficheiro benigno e derivada analisados por hash próprio. Observado: três casos reais saltados por indisponibilidade; fixtures suportam lógica mas não comprovam scan ativo. Causa: serviço/configuração real ausente ou indisponível no ambiente utilizado. Não atribuir novo estado limpo aos quatro documentos ativos por estes testes.
|
||||
|
||||
Correção necessária: configurar serviço real e repetir apenas as integrações afetadas; verificar GD/WebP do PHP web separadamente. Manter originais, rascunhos e metadados, com binários pendentes devidamente restringidos.
|
||||
|
||||
## C08 — contrato integral e workflow de oportunidades incompletos — P1
|
||||
|
||||
Passos: comparar as ações de `OpportunityManagement`/rotas e o formulário com §20 e contratos especializados §24–28 da especificação; procurar submissão/devolução/aprovação/publicação segregada e campos/coleções da categoria.
|
||||
|
||||
Esperado: versão completa submetida e revisada por ator distinto; público conserva versão aprovada; objetos/direitos canónicos reutilizados. Observado: rascunho/CRUD/arquivo/restauro existentes não implementam o workflow integral; contratos especializados não estão integrados. Causa: incrementos ainda não desenvolvidos. Não provocar uma publicação ativa para testar esta ausência.
|
||||
|
||||
Correção necessária: implementar por categoria e transição com políticas/auditoria existentes, primeiro em QA. Designações reais só são necessárias para atos institucionais; desenvolvimento independente pode avançar.
|
||||
|
||||
## C09 — UUID interno desnecessário na jornada — P2
|
||||
|
||||
Passos: inspecionar a renderização de `JourneyCard` em `portfolio/workspace.tsx`. Observado: apresentação de `Jornada: {journey.id}` além do título e ações. Esperado: identificação legível que ajude o investidor a decidir, mantendo ID nas referências internas.
|
||||
|
||||
Correção preparada: UUID retirado do cartão; ID permanece nos pedidos/relações. TypeScript/build passaram. Validação visual desta mudança e inventário de outros elementos desnecessários pendentes.
|
||||
|
||||
## C10 — checks globais de formatação falham — P2
|
||||
|
||||
Passos: executar `npm.cmd run check` e `php vendor/bin/pint --test`. Esperado: checks globais passam. Observado: problemas de formatação preexistentes, com lista nos logs privados; dois novos scripts desta auditoria foram formatados posteriormente. Causa: divergência do formato exigido pelos formatadores. Não confundir formatação com falha de persistência ou cálculo.
|
||||
|
||||
Correção: por ficheiro, preservar conteúdo/comportamento e validar diff. Não aplicar um fix massivo a código alheio nesta entrega.
|
||||
|
||||
## C11 — cobertura visual e cadastros vazios — P1/P2, demonstração pendente
|
||||
|
||||
Passos: iniciar controlo de navegador e inventariar superfícies disponíveis; consultar contagens dos domínios ativos. Observado: zero browsers conectados; pedidos Balcão, leads CRM, transações Bolsa, cadastros `skills_edu`, direitos/mandatos e vínculos específicos sem registos nos conjuntos consultados.
|
||||
|
||||
Esperado: percurso autorizado com dados sintéticos QA, comprovando gravação/recuperação e todos os botões; operação ativa só com dados reais fornecidos. Causa do vazio não apurada: não se presume falha de gravação nem se preenche com exemplos. Não foi possível afirmar ausência de botões inertes nesta versão. A lista HTTP e as suites mantêm essas lacunas explícitas.
|
||||
|
||||
## C12 — países do simulador dependiam de jurisdições territoriais — P1
|
||||
|
||||
Passos anteriores por código: campos de residência fiscal/origem de fundos usavam `/api/v1/catalogs/jurisdictions?type=country`, sujeito à publicação; cadastro territorial ativo contém Moçambique como único país. Esperado: ISO internacional independente. Causa: catálogo territorial utilizado para país internacional. Sem reprodução visual.
|
||||
|
||||
Correção: `/api/v1/catalogs/countries` usa CountryCatalogue; território usa territory-options; pesquisa sem acentos. QA: 249 códigos únicos em três páginas, Portugal/Mocambique pesquisáveis; draft cifrado POST/PUT/GET conserva PT/ZA e legado Portugal; ZZ 422 e outra conta 404. PortalAuditContinuationTest: cinco testes/203 asserções. AUD-COUNTRY-05 concluído só no critério HTTP; AUD-SIM-01 parcial, visual pendente.
|
||||
|
||||
## C13 — país livre e origem sem apresentação recuperável — P1
|
||||
|
||||
Passos QA: país PT/origem ZA nos formulários públicos/apoio/jornada; recuperar no gestor e estatísticas. Esperado: seletor pesquisável e apresentação distinta após guardar, conservando legado. Antes: country livre/preenchido e sem origem apresentada no detalhe/jornada. Gravação da origem corrigida anteriormente não encerrava país/recuperação/UI.
|
||||
|
||||
Correção: CountrySelect obrigatório conforme formulário, pesquisa e opção de legado; sem país automático; props declaredOrigin e país/origem da jornada. QA: grava PT/ZA nos quatro tipos de apoio, replay único, ZZ 422 sem escrita, detalhe/estatísticas separados, outra conta 403; InvestmentPortfolioTest recupera jornada. Browser pendente. Wizard/fundiário continuam livres, AUD-COUNTRY-06/07 parciais.
|
||||
|
||||
## C14 — Balcão com lista territorial plana — P1
|
||||
|
||||
Passos por código: campo territory recebia select plano; recuperar localidade. Esperado: pesquisa/caminho provincial–distrito–posto–localidade, erro no campo, seleção conservada. Causa: consumidor sem componente hierárquico e validação por abort genérico.
|
||||
|
||||
Correção: TerritoryFields/territoryPaths, mantendo payload.territory_id cifrado. QA: pedido sintético pesquisa quatro níveis, PUT guarda localidade, GET recupera caminho; ID privado 422 no campo conserva versão; outra conta 403; submissão mantém origem PT/estatística separada. Catálogo restaurado: 597 pedidos, 1920/1920 IDs públicos sem omissões/duplicados (territory-catalogue-coverage.json). Sem browser; demais campos/mapas pendentes e geo_geometries=0.
|
||||
|
||||
## C15 — maturidade 7/8 recusada — P1
|
||||
|
||||
Reprodução em `desk_restore_20261009_161758_test:55441`: gestor sintético envia POST `/management/opportunities/drafts`, maturity_level=7 e depois 8, creation_key nova/reason válida. Esperado: oito etapas versionadas guardadas/recuperadas, sem remapear legado. Observado: 422 em maturity_level, sem gravação. Causa: OpportunityManagement::save between:1,6 e seletor de seis etapas. pending-actions.json 16:20:58 UTC; hashes de oportunidades/auditoria iguais. AUD-OP-05 com falha; ainda não corrigido. Sem visual/escrita ativa.
|
||||
|
||||
## C16 — procura/capacidade educativas sem draft incompleto — P1
|
||||
|
||||
Na mesma QA: POST `/management/education/demands` e `/management/education/capacities` apenas com qualification sintética. Esperado para guardar draft: conservação privada incompleta/recuperável. Observado: 422 pelos campos finais obrigatórios, sem gravação. Causa: ação única valida declaração completa e grava submitted; falta guardar draft. O 422 é correto para submissão, mas não satisfaz o percurso solicitado. Curso/proposta em draft não substitui procura/capacidade.
|
||||
|
||||
pending-actions.json confirma hashes de procura/capacidade/histórico iguais e zero chamadas externas/ativas. AUD-EDU-02 não implementado; jornadas/painéis AUD-EDU-03 pendentes por código/documentação, sem alegar ensaio integral por ator. Desenvolver nas entidades/schemas existentes, sem tabelas paralelas/zeros fictícios.
|
||||
|
||||
## Atualização C07/C10/C15 — lote 2, observações antigas preservadas
|
||||
|
||||
C07: indisponibilidade corrigida; ClamD real 1.5.4/assinaturas, EICAR detetado em memória e seis testes reais passaram. Restam arranque após reinício/atualizações e GD web/derivadas. C10: formato global corrigido e checks passaram; lint 11 avisos existentes. C15: POST maturity_level=7/8 agora 201 em QA, GET recupera versão/etapa/posição. Oito etapas spec-v2 explícitas, seis legacy-v1 preservadas. Código/posição incoerentes ou versão sem etapa 422; conflito409/perfil403/replay único. AUD-OP-05 parcial por workflow/publicação/visual, não pela rejeição antiga. PortalAuditNextLotTest/phpunit-lote2-final.xml. Nenhuma escrita ativa.
|
||||
|
||||
## C17 — província com país pai recusada no fundiário — P0/P1
|
||||
|
||||
Reprodução: criar caso privado QA, escolher os IDs válidos país→província→distrito→posto→localidade do cadastro. Esperado: guardar e recuperar hierarquia pública válida. Observado antes: 422 province_id apesar de cadeia correta. Causa identificada: StoreLandAssistanceRequest exigia parent_id=null para província, enquanto o catálogo tem país pai. Correção remove essa suposição; conserva tipo/classificação/descendência/ciclos. QA NextLotTest POST/PUT/GET recupera quatro níveis e territoryPaths; inválido/outra conta recusados, versão preservada. Interface preparada, visual pendente. Ativo não migrado/reescrito.
|
||||
|
||||
## C18 — origem fundiária omitida ao pedir apoio — P0/P1
|
||||
|
||||
Reprodução: caso QA com country PT e declared_origin_country_code ZA; executar request-support e GET gestor/filtrar origem. Esperado: ZA continua origem, PT país. Observado por código anterior: campo não constava do payload enviado a InterestSubmission, perdendo rastreabilidade. Correção inclui origem no payload/hash/metadata existentes. QA conserva ZA no pedido/CRM/recuperação, filtro PT/ZA e agregado interests uma vez; conta indevida 404/403. Não inferir valores históricos. Visual pendente.
|
||||
|
||||
## C19 — negócios/fundiário sem catálogo completo e percurso de origem — P1
|
||||
|
||||
Reprodução por código/API: wizard country texto livre, sem origem separada/filtros/agregado de negócios; fundiário sem seleção ISO. Esperado: países pertinentes selecionáveis, legado conservado, origem explícita independente e recuperável. Correção CountryCatalogue/CountrySelect/validação e payloads cifrados existentes. QA negócios: draft PT/ZA, ZZ422 conserva versão, texto Portugal recuperado exato, escolha explícita PT, submissão válida/agregado ZA1, filtros e outro ator negado; cinco revisões. QA fundiário: PT/ZA/legado Moçambique recuperados, apoio preserva origem. Não reivindicar visual ou cobertura dos outros formulários por estas provas.
|
||||
|
||||
## C20 — botão de pesquisa do cabeçalho sem efeito — P1
|
||||
|
||||
Reprodução por inspeção: app-header.tsx apresentava botão Search sem href/onClick ou formulário/contexto de ação. Esperado: abrir pesquisa existente com destino visível. Causa: ícone decorativo embrulhado em Button sem binding. Correção usa Link /oportunidades via asChild, com nome acessível. Rota/compilação verificadas; clique/URL/feedback visual ainda pendentes por browser indisponível. Não é ação de persistência. Inventário dos demais 363 botões não é aceitação funcional.
|
||||
|
||||
## C21 — Balcão sem país e sem devolução da origem para correção — P1
|
||||
|
||||
Reprodução anterior por código: country não autorizado em validateFields; declared_origin_country_code disponível no formulário, mas não admitido em editable_fields da devolução. Esperado: país e origem distintos, persistidos e correção explícita permitida por gestor. Observado: country sem campo/percurso e devolução da origem422. Causa: campos comuns não incluídos na whitelist de correção/país. Correção: campo separado e duas whitelists coerentes, sem alterar definição histórica do serviço. PortalAuditConsumerLotTest ensaia3 serviços, POST/PUT/GET, cifra, ZZ422, submissão, dono autorrevisão403, gestor devolve, título não autorizado422, country/origin corrigidos versão5, conflito409 e outra conta403. API/props/persistência demonstradas, visual pendente, ativo sem escrita.
|
||||
|
||||
## C22 — geometria importada sem percurso de consulta nos campos/mapas — P1
|
||||
|
||||
Reprodução por código/dados QA: geo_geometries tinha361 limites internos, consumidores partilhados só recuperavam nomes/IDs; mapas públicos exigiam geometrias publicadas/locais e não havia preview administrativo por perfil. Esperado: cadastro/geom disponível/contexto/apresentação separados, sem publicar para resolver UI. Correção: TerritoryGeometry, endpoints público/gestor e preview contextual com edição/legenda, preservando classificação. Prova real READ ONLY361/361 e zero divulgação pública; HTTP sintético testa gestor/outra conta/arquivamento/fallbacklocalidade. Integrações frontend preparadas, mapa renderizado ainda não observado.
|
||||
|
||||
## C23 — servidor QA parado e provider de UI indisponível — P1
|
||||
|
||||
Passos: verificar18096; getState, abrirChrome, reset, getState, abrirEdge. Antes:sem listener18096. Após iniciar servidor QA guardado:HTTP200/header _test:55441. Ainda observado:apps[]/browsers[];Browser is not available:chrome/edge após reset. Causa do servidor:processo QA não em execução; causa subjacente do provider não confirmada, apenas ausência de registo demonstrada. Ligação de navegador pedida ao utilizador. Interface permanece pendente; API/persistência continuam. Nenhum bypass de autenticação/controlo ou captura antiga usada.
|
||||
|
||||
## C24 — orientação abre o simulador sem identificar o draft ligado — P1
|
||||
|
||||
Passos anteriores: criar dossier ligado a um draft do dono; consultar orientação; abrir ação financeira/plano quando a conta tem outro draft corrente. Esperado: recuperar exatamente a origem associada, preservando dono/versão. Observado na reprodução de servidor: href genérico /simulador-fiscal, apesar de existir simulation_id autorizado; destino pode escolher outro draft corrente. Causa: InvestorGuidance::view descartava o identificador na ação; SimulationForm já suporta ?draft=ID e API por ID.
|
||||
|
||||
Correção pontual: actions.simulator, actions.plan e recomendação financeira usam ?draft=ID somente se context confirmou disponibilidade/autorização; gestor permanece sem leitura do draft privado. QA: teste primeiro falhou no href genérico; depois 16 testes de orientação/285 asserções passaram, incluindo duas origens do mesmo dono, recuperação específica e gestor 404. Provas: consolidation-context-red.log, consolidation-context-green.log/XML. Link preparado e API/persistência demonstrados; clique/resultado visual pendentes. Nenhuma mudança de navegação/modelo/motor estrutural ou escrita ativa.
|
||||
|
||||
## C25 — rascunho corrente por conta e perda de contexto entre investimentos — P1
|
||||
|
||||
Pedido/fontes:AUD-SIM-01/DESK-02; aprovação QA preserva investimentos independentes. Causa inicial identificada no código:SimulationFormDrafts::create escolhia o primeiro draft do dono e respondia409 a uma nova chave; current e armazenamento local não distinguiam dossier. Percurso anterior podia recuperar dados de outro investimento no acesso genérico. Esperado:conta com A/B deve gravar/recuperar cada contexto e manter o anónimo/directo compatíveis.
|
||||
|
||||
Correção:contexto autorizado e bloqueado na transação; desk_cases.simulation_id canónico, current scoped, armazenamento por context/draft, verificações de propriedade e vínculo. Reprodução QA final:criar A/B mesma conta→POSTdrafts com context→IDs diferentes→GETcurrent por contexto→retornar snapshot financeiro→limpar sessão HTTP→GETdossier→Balcão/CRM. Replay retorna mesmo ID; chave diferente no mesmo contexto409; GET/PUT de A com contextB403; retorno de draftA paraB403; gestor GETdraftA404. Evidências:path-acceptance-api.xml (3/163),path-regression-final.xml (384/5215). Interface/clique/nova sessão de browser pendentes; nenhuma escrita ativa.
|
||||
|
||||
## C26 — rollback recusado alterava RLS antes de verificar as definições — P0
|
||||
|
||||
Reprodução inicial em QA:suíte completa com nova definição publicada→teste antigo chama down do núcleo de execução→recusa “questionnaire_versions contains data”. Esperado:preservar versões e políticas de segurança quando a reversão é recusada. Causa identificada em código:down desativava RLS dentro do laço antes da verificação. O ensaio inicial registou a recusa; a alteração de RLS é risco confirmado pela sequência SQL, não uma observação de falha ativa.
|
||||
|
||||
Correção:verificar todas as tabelas/definições antes de desativar qualquer RLS. Novo ensaio confirma recusa e igualdade relrowsecurity/relforcerowsecurity antes/depois, com dados/schema preservados. A definição do percurso não foi excluída para fazer passar o teste. Provas:path-regression.log/XML (falha inicial),path-followup.xml (26/551),path-regression-final.xml (384/5215). Reversão ativa não executada.
|
||||
|
||||
## C27 — consumidores sem contexto cartográfico
|
||||
|
||||
Requisitos AUD-GEO-02/03. Reprodução de código: ficha de oportunidade chama InvestmentMapPanel apenas com opportunity_id; preview procura IDs territoriais exclusivamente nos filtros e recebe vazio. Bolsa desenha pontos e omite consulta de limites do território aplicado. Esperado: contexto administrativo do território conhecido, respeitando classificação, sem mudar resultado económico nem inventar implantação. Observado: chamada ao preview ausente nestes consumidores. Causa identificada: ligação de props/componente incompleta. Corrigido em código QA: territoryId separado a partir do primary_territory_path, e TerritoryGeometryPreview da Bolsa a partir de p.filters. TypeScript/build passam; GET real/serviço QA verificam acessos. Reprodução/renderização no navegador ainda pendentes; não confundir causa de código com prova visual.
|
||||
|
||||
## C28 — preparador de prova preso à contagem381
|
||||
|
||||
Requisito AUD-OPS-01. Fonte tools/portal-audit-prepare-activation.php exigia tests=passed=381 e emitia381 fixo; a regressão posterior384/5215, apesar de passar, seria rejeitada por esta condição. Esperado: total positivo, todos passados, sem skips, mantendo hash/backup/restauro/compatibilidade/autenticação independentes. Corrigida condição/serialização para usar total efetivo; a contagem continua apenas inventário de regressão, sem provar critérios ou UI. Sintaxe/Pint verificados. Preparador não executado contra ativo nem prova de ativação emitida; demais dependências continuam obrigatórias.
|
||||
|
||||
## C29 — fixture HTTP com orçamento incompatível
|
||||
|
||||
Requisito AUD-SIM-02; falha na preparação da fixture, não demonstrada como regressão do portal. Reprodução QA: snapshot financeirov1 com incomes=[]/expenses=[], gravar draft e devolver evidência; executar recoverPathResult sobre o snapshot recuperado. Esperado para demonstração:20unidades/gap0(A) ou70000(B). Observado: Entradas incompatíveis. Causa: fixture criada pelo ensaio HTTP não respeitava o contrato de pelo menos uma linha orçamental. Correção no ensaio: novas linhas sintéticas explicitamente identificadas, PUT com ETag/contexto gera draftv2 e novo resultado; originais congeladosv1 preservados. Não relaxada a validação nem atribuído zero ao erro. investor-path-recovered-calculations.json demonstra novos cálculos e recusa dos resultados históricos incompatíveis; HTTP recupera ambos sem sobrescrita. Roteiro visual cria projetos novos e informa o histórico das fixtures de inspeção. Interface permanece pendente.
|
||||
|
||||
## C30 — importação oficial dependia de CLI QA sem ato autenticado — P1
|
||||
|
||||
AUD-GEO-02/03, OPS-01. Reprodução anterior: existiam361 limites privados aplicados por tools/portal-audit-geometry-qa.php, sem rota de prévia/aplicação/reversão por gestor. Esperado: gestor/MFA, prévia/hash/correspondências, receipts idempotentes, auditoria e reversão preservando adotadas. Corrigido: serviço/controlador/página nas entidades existentes, flag desativada fora de QA e guarda de backup/provas no alvo ativo. HTTP real nos3níveis e ensaio de criação/reversão/FK na QA; apresentação visual pendente.
|
||||
|
||||
## C31 — previews de derivadas lançavam RouteNotFoundException — P0
|
||||
|
||||
AUD-SCAN-01. Reprodução: gerar e limpar uma derivada; abrir recursos da oportunidade. Esperado: URL assinada com preview WebP. Observado: Route [opportunity-image-preview] not defined; GET da página falha após existir derivada limpa. Causa: grupo management prefixa nome da rota, mas controlador usava nome sem prefixo; teste antigo saía no ramo GD ausente. Corrigido: management.opportunity-image-preview, sem mudar URL. PHP QA com GD e ClamD1.5.4:3derivadas320/640/1280, scans separados, página/bytes recuperados, assinatura/ator indevidos403 e adulteração409. Visual pendente.
|
||||
|
||||
## C32 — arranque PHP QA com GD falhava antes do cabeçalho de isolamento — P1
|
||||
|
||||
Reprodução: processo18096 reiniciado com extensão GD. Observado: Fatal error Cannot instantiate interface RecursiveIterator no arranque Symfony/Finder, resposta200 sem cabeçalho QA; ensaio abortou antes de escrever. Causa exata do PHP/OPcache não comprovada; funcionamento restabelecido num processo QA18097 com GD e OPcache desligado apenas nele, sem editar vendor/PHP ativo. Tentativa agrupada de reinício foi rejeitada pela revisão automática sem razão detalhada; alternativa isolada permitida. Login/cabeçalho/HTTP A/B/importação/uploads/derivadas verificados; CUA ainda sem provider.
|
||||
|
||||
## C33 — fixture MFA incompatível com serialização Fortify — QA
|
||||
|
||||
Reprodução: primeira fixture de gestor cartográfico usava Crypt::encryptString no secret; POST /two-factor-challenge dava unserialize() offset error. Corrigida somente a fixture QA para Crypt::encrypt, compatível com Fortify. Login TOTP real passou; nenhuma credencial ativa ou controlo MFA alterado.
|
||||
|
||||
## C34 — prévia cartográfica recalculava hash do pai por elemento — P1 QA
|
||||
|
||||
Ao acrescentar verificação da edição/hash do pai, o hash era recalculado por feature. Ensaio de nível3 excedeu limite PHP e devolveu conteúdo fatal em resposta200, recusado pelo consumidor JSON. Corrigido para calcular hash uma vez por nível; transação preserva estado em falha. Repetir prova HTTP integral na revisão final e manter resultado visual pendente.
|
||||
|
||||
## C35 — cadastro documental falha500 quando campos opcionais são omitidos — P0
|
||||
|
||||
AUD-LIB-01/SCAN-01. Reprodução: upload privado, depois POST /management/portal-services/resources com campos obrigatórios, omitindo document_date/issuer permitidos como nullable; o cadastro tenta aceder diretamente a document_date na atualização do documents. Observado: Undefined array key document_date em PortalServicesController:444 e transação revertida. Esperado: cadastro com data desconhecida/sem invenção, preservar emissor/data existentes quando ausentes. Corrigido acesso com ??null tanto na criação como na edição; teste mantém opcionais omitidos e cobre gravação/recuperação/scans reais/classificação/publicação separada, conflitos/dedup/hash/permissões. Sem alteração ativa nem aceitação fictícia de fonte oficial.
|
||||
|
||||
## C36 — original canónico cifrado devolve404 em consumidores — P0
|
||||
|
||||
AUD-LIB-01/SCAN-01/DESK-02. Reprodução QA: documents com storage_encryption=laravel, bytes originais/hash, scan ClamD real clean; GET /management/documents/{id}/download. Esperado200 com original íntegro; observado404 (encrypted-consumer-before-qa.xml). Causa: gestão/biblioteca/Balcão comparavam hash do ficheiro cifrado ao hash original. Corrigido VerifiedDocumentBinary partilhado: mantém guardas do consumidor, scan/hash, path privado e cifra; decifra só em memória e verifica plaintext, sem copiar para disco público. Teste real verifica gestão, associação ao Balcão sem novo documents, download e view PDF após classificação/publicação explícitas, bloqueio antes de publicação, bytes/MIME/CSP e adulteração404 em todos os consumidores. document-consumers-real-qa.xml distingue os três ensaios ClamD de consumidores/worker das fixtures de outros testes. Sem observação visual nem escrita ativa.
|
||||
@@ -0,0 +1,43 @@
|
||||
# Evidências por consumidor — lote 2
|
||||
|
||||
**Histórico preservado.** O estado atual e os novos percursos do Balcão e das geometrias constam no [relatório do lote 3](relatorio-executivo.md), [backlog atualizado](backlog.md) e [índice de ações por perfil](acoes-perfis-lote3.csv). As lacunas e contagens desta página descrevem o lote 2; não prevalecem sobre as evidências posteriores.
|
||||
|
||||
09/10/2026. Inventário de evidências ligado aos IDs da matriz existente; **não é outra matriz de requisitos**. “Props” é resultado de GET/Inertia, não observação visual. Todos os ensaios com escrita são QA; ativo apenas leitura.
|
||||
|
||||
| Consumidor / requisito | Interface preparada | API → gravação → recuperação → resultado | Lacuna |
|
||||
| ------------------------------------------ | -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
|
||||
| Manifestação pública / COUNTRY-01–04 | CountrySelect país/origem | InterestOriginTest/PortalAuditContinuationTest: PT/ZA separados, metadata persistido, GET gestor/estatística, inválido sem escrita/replay único | Browser, restantes variações por consumidor |
|
||||
| Apoio: quatro tipos / COUNTRY-04 | Campo país pertinente e origem opcional | PortalAuditContinuationTest: guarda ambos nos quatro tipos, recupera detalhe/origem, another actor denied | Browser/serviços condicionais restantes |
|
||||
| Interesse em negócio público / COUNTRY-04 | Dois campos distintos | Provas anteriores de InterestSubmission/recuperação; não confundir com wizard privado | Visual e ensaio por cada variação |
|
||||
| Jornada / COUNTRY-04 | Seleção e props country/origin | InvestmentPortfolioTest conserva recuperação; pedidos integram interesses | Visual/nova sessão renderizada |
|
||||
| Wizard de negócios / COUNTRY-06 | CountrySelect país/origem, 249 países | PortalAuditNextLotTest: POST/PUT encrypted payload → GET → filtros country/origin; draft aggregate 0, submitted ZA=1/PT=0; legado Portugal, ZZ 422 preserva versão, other actor 403/list empty | Visual/perfis adicionais/revisão completa |
|
||||
| Assistência fundiária / COUNTRY-07; GEO-02 | País/origem e quatro níveis | Mesmo teste: POST/PUT/GET cifra e recupera nomes/territoryPaths; request-support preserva ZA; gestor filtra PT/ZA, agregado interests uma vez; legado e versão conservados | Visual/mapas/anexos/transições restantes |
|
||||
| Balcão / DESK-01; COUNTRY-04; GEO-02 | Origem e TerritoryFields | VirtualDeskTest/PortalAuditContinuationTest: payload cifrado, localidade/path recuperados; origem agregada desk separada | Todos os campos condicionais por serviço, transições/visual |
|
||||
| Simulador / SIM-01; COUNTRY-05 | País ISO/fundos e território separados | SimulationPrivateDraftTest/Continuation: PT/ZA cifrados GET, legado, ZZ 422/other actor 404; nenhum cálculo por guardar | Demais campos/cálculos/visual |
|
||||
| Gestor/CRM / STATS-01 | Filtros country/origin/unknown e 3 agregados | GET authorized scope/filtered rows/counts; interests/desk/businesses separados, business drafts excluídos | URL/seleção/tabela no navegador; escala/performance das listas cifradas |
|
||||
| Draft de oportunidade / OP-05 | Catálogo server-side 8; opção histórica | NextLotTest: 8 POST/GET, 7/8=201, canonical code/position/version stored private JSON; legacy raw unchanged; mismatch/version-only 422, conflict409/actor403 | Publicação/filtros públicos versionados/visual |
|
||||
|
||||
## Território por consumidor
|
||||
|
||||
Catálogo: 597 pedidos/1920 IDs na cópia ativa restaurada; não se generaliza aos campos. Fundiário e Balcão têm prova própria de hierarquia/persistência; demais controles mantêm prova individual pendente.
|
||||
|
||||
- Seletores de submissão/perfil/oportunidades, negócios, parceria, simuladores e administração: conferência de tipo/pai/paginação/seleção/limpeza de filhos/recuperação/erro/visual por componente. Reutilizar IDs existentes, sem transformar cadastro em preenchimento automático.
|
||||
- Mapas do catálogo/detalhe/portefólio: `/api/v1/investment/map`; mapas de zonas: `/api/v2/investment/zone-map`; mapas de parcerias e respectivas áreas/IDs têm critérios próprios. Campos cartográficos não fecham por responder a API territorial.
|
||||
- Geometrias administrativas INE/UNOCHA 2019: originais 11/159/411, privadas QA 9/120/232. Correspondência única nome+pai; nenhum centro administrativo vira ponto de oportunidade. Sem locality geometry; unmatched 2/39/179. Maputo diverge por designação/versão.
|
||||
|
||||
## Ações e perfil
|
||||
|
||||
consumer-actions-lote2.json inventaria todas as páginas/componentes: 363 botões e 270 seletores/mapas. Cinco bindings requerem contexto (menu/avatar/diálogo de exclusão/passkey/cancelamento). Não se infere falha ou sucesso só pelo AST. C20 encontrou pesquisa sem ação e liga-a à rota existente.
|
||||
|
||||
Ensaios já presentes demonstram negativa entre contas e gravação/recuperação dos percursos específicos; não se afirma cobertura de cada botão. Próximo lote executa dono/revisor/gestor/público, com retorno visível e evento/versão quando aplicável. No browser indisponível, API/persistência continuam; visual fica separado.
|
||||
|
||||
## Manifesto das provas exportáveis
|
||||
|
||||
- phpunit-final.json; phpunit-lote2-final.xml: 379 pass, 4922 assertions, zero skipped.
|
||||
- consumer-actions-lote2.json: inventário estático, não DOM observado.
|
||||
- geometry-qa-adm1/2/3-import.json: destino QA, counts/reuse/SRID/validity/hash; geometry-source-scans.json: scans reais dos originais.
|
||||
- resources-lote2-preview.json; activation-evidence.json: destino ativo somente leitura, hash/provas, ready=true/installed=false.
|
||||
- clamd-lote2.json: saúde/versão/assinatura/EICAR e hashes; sem afirmar scans de derivadas não ensaiadas.
|
||||
- contagens-requisitos.json: 3354 canónicos/5830 origens conservadas; matriz CSV mantém aliases/versões.
|
||||
|
||||
Logs de execução e snapshots pessoais/dumps/configuração permanecem privados. Provas de geometria e compatibilidade usam cópias QA distintas; não misturar seus estados.
|
||||
@@ -0,0 +1,80 @@
|
||||
# Cobertura por percurso e consumidor — continuação QA
|
||||
|
||||
## C37 — MFA QA recuperado; cenário A visual por retomar
|
||||
|
||||
**C37/P0 — falha bloqueante do cenário A reportada pelo utilizador, corrigida por código/HTTP/persistência QA; retoma visual ainda pendente.** URL: http://127.0.0.1:18097/investimentos. Alvo real confirmado antes de qualquer escrita: `desk_restore_20261009_174726_test:55441`.
|
||||
|
||||
Stack completa dos erros20:39:16/20:41:52 (68frames por ocorrência) retida sem argumentos em mfa-original-stack-redacted.json. Falha em TwoFactorLoginRequest::hasValidCode() ao desencriptar users.two_factor_secret da conta13; PreserveFormFeedback apenas chama o próximo middleware. A conta restaurada não é sintética: secret/recovery abrem com a chave do .env de origem, mas não com a chaveQA. Cache de configuração não carregado; source cache também ausente. A ferramenta de preparação do percurso antes não fixava APP_KEY e podia herdar origem. portal-qa-environment.php centraliza a mesma chaveQA já existente entre preparação/web, força alvo/restauro, configura caminho QA de cache separado e recusa cache não reconciliado. Não gera chave, não usa chaves ativas como fallback nem modifica .env/cache ativo.
|
||||
|
||||
Duas sessões pendentes da conta13 removidas exclusivamente do diretório de sessões QA, após guarda do destino e paths. Original conta13 preservado byte a byte pelo hash da linha; nenhuma chave/MFA ativa ou da conta13 alterada. Novo investidor sintético QA: actor18, inscrição normal pelos endpoints Fortify (confirmar password→enable→secret-key→confirm), oito recovery codes, sem injeção direta do segredo nem desativação de MFA. Dados de acesso/segredo somente em investor-mfa-qa-private.json local privado; não exportados aqui.
|
||||
|
||||
POST /two-factor-challenge com DecryptException agora invalida desafio/sessão e retorna422 com mensagem controlada em JSON ou redireciona ao login com erro visível; nenhuma autenticação. Negativas reais de secret/recovery verificam401 após erro e remoção do desafio. A resposta HTML/Inertia contém a mensagem, sem ser prova de renderização visual. Logs controlados incluem apenas referência e ID pendente; as provas não exportam Cookie, X-XSRF-TOKEN, OTP ou corpos.
|
||||
|
||||
No mesmo servidor18097: login/MFA/logout/nova sessão passaram. A retomado por HTTP em `/investimentos/413ba1f6-bdf6-402a-a561-c4e2d4098d1a`: criação→logout→nova sessãoMFA→recuperação→aplicabilidade semterra/semfinanciamento→draft próprio→resultado→Balcão draft→tarefa concluída pela gestão→nova sessãoMFA recupera tudo. Gestão não recebe resultado financeiro privado. Função efetiva do dossier recalcula20unidades/0.00 a partir do resultado recuperado. QA atual5instâncias/95etapas; originals anteriores preservados. Esta conta não vê os A/B da outra contaQA.
|
||||
|
||||
Evidências: mfa-key-diagnosis-qa.json, mfa-session-invalidation-qa.json, mfa-persistence-qa.json, mfa-http-qa.json e mfa-auth-qa.xml. Os17 ensaios autenticam ou recusam os percursos concretos; não substituem interface. Fingerprints passam a incluir bootstrap/Fortify, invalidando ready/provas anteriores para ativação. `integrated_ui_ab_passed=false`, `candidate_revision_fixed=false`, `activation_ready=false`; nenhuma escrita ativa. Mesma matriz3354requisitos/5830origens, sem fecho amplo novo.
|
||||
|
||||
## Complemento atual C30/C31 — critérios distintos
|
||||
|
||||
**QA atual: http://127.0.0.1:18097/investimentos.** Porta18096 anterior não usar; erro PHP/Symfony no arranque com GD, antes do cabeçalho QA. Processo isolado recuperado com GD e OPcache desligado, sem mudança do PHP ativo. Base `desk_restore_20261009_174726_test:55441`, sessões próprias; SuiteCRM/AI externos desativados. CUA permanece sem apps/browsers. Nenhuma observação visual nem escrita ativa.
|
||||
|
||||
**Mesma matriz:**3354 requisitos/linhas canónicas,5830 ocorrências preservadas; parcial: 3198 requisitos/5380 ocorrências; não implementado: 146 requisitos/440 ocorrências; dependente de decisão concreta: 4 requisitos/4 ocorrências; implementado mas não ativado: 1 requisitos/1 ocorrências; concluído e demonstrado: 5 requisitos/5 ocorrências. Nenhum requisito amplo fechado por este lote. `candidate_revision_fixed=false`, `integrated_ui_ab_passed=false`, `activation_ready=false`; não fixar candidata antes dos resultados manuais e correções.
|
||||
|
||||
| Requisito | Correção/prova concreta deste lote | Estado |
|
||||
| --- | --- | --- |
|
||||
| AUD-GEO-02/03, OPS-01 | C30: GET/POST `/management/territory-geometry-import`, POST `/{batch}/reverse`. Fontes retidas/edição/hash/scan; nomes exatos+pai+país, conflitos, preview vinculado ao ator/estado, MFA, `geo_write_receipts`, `audit_events` append-only; nada publicado. HTTP real com login+TOTP, três níveis,361 reutilizadas/0 novas; replay e reversão de lote de reutilização mantêm361. QA de testes demonstra criação e reversão de lote novo, preservação de histórico e recusas de alteração/publicação/FK/scan expirado/MFA/alvo não QA. | Código preparado + API/persistência QA; interface e ativo pendentes |
|
||||
| AUD-SCAN-01 | C31: nome da rota assinada corrigido para `management.opportunity-image-preview`, mantendo URL. Servidor web QA gera3WebP320/640/1280; PDF+PNG+3derivadas têm cinco scans reais ClamAV1.5.4, clean/hash próprios, cifragem Laravel e classificação restricted; downloads reais comparados, assinaturas ausentes403 e outra conta403. QA de testes prova quarentena423, scanner inconclusivo e retry real, substituição sem apagar original, versão409, exclusão/restauro e adulteração409. | Operações de oportunidades demonstradas por API/persistência; apresentação visual pendente |
|
||||
| AUD-LIB-01/SCAN-01/DESK-02 | C35 corrigiu erro500 ao omitir data/emissor opcionais. C36 corrigiu recuperação404 de originais cifrados: os consumidores comparavam o hash do ciphertext com o original. VerifiedDocumentBinary reutiliza decifragem/integridade sem cópia pública nem alteração de permissões. PortalRealDocumentConsumersTest usa ClamD real: biblioteca privada→scan→classificação→publicação separada→download; versão409/dedup/404hash. Balcão testa upload/confidential→scan→download, dedup/403estranho. Original canónico cifrado é reutilizado sem duplicar documents; downloads na gestão/Balcão/biblioteca e view PDF devolvem os bytes originais; antes de publicação/adulteração404. | API/persistência QA; bytes de preview PDF verificados, renderização visual pendente; sem publicação ativa nem fecho global |
|
||||
| AUD-UI-01/DASH-01/SIM-01/DESK-02/GUIDE-01/CRM-01 | A/B repetidos por HTTP no servidor recuperado; nova sessão real, IDs/drafts próprios, recuperação, aplicabilidade, resultado20/0 e20/70000, Balcão e tarefa concluída enquanto terra aguarda; outra conta/contexto recusados. | API/persistência QA; cenários completos na interface pendentes |
|
||||
|
||||
**Correspondências:** províncias11→9/2; distritos159→120/39; postos411→232/179. Esperado refere o exemplar2019, não um cadastro atual certificado. Maputo e Maputo City são as duas pendências provinciais. Distritos:9 por pai não resolvido/30 por nome; postos:86 por pai/93 por nome. [Todas220 lacunas por nome/código/pai/causa](correspondencias-cartograficas.md). Sem polígonos de localidades no exemplar; nenhum limite equivale a implantação/DUAT. Aceitação da fonte oficial preservada.
|
||||
|
||||
**Evidências:** `geometry-auth-http-qa.json`, `resources-real-http-qa.json`, `document-real-persistence-qa.json`, `import-document-real-qa.xml`, `investor-path-http-qa.json` e `investor-path-recovered-calculations.json`, no acervo privado. As15 verificações dirigidas são inventário:4 importação,2 operações documentais reais,5 scanner/negativas e4 recursos com fixture. Não substituem prova por requisito ou interface.
|
||||
|
||||
**Ainda não verificado:** interface de A/B, cada formulário/estatística, cada seletor/mapa e operações documentais visuais. Biblioteca/Balcão têm agora os ensaios reais específicos acima; PDF view tem prova de bytes/MIME/CSP, mas renderização, importação em lote, todos os tipos/documentos/perfis e partilhas/imutabilidade por consumidor continuam pendentes. Os ensaios de compatibilidade/schema e fixtures não constituem prova ClamD real. ClamD real demonstrado nesta sessão é distinto de arranque após reboot/manutenção de assinaturas e GD no PHP ativo, ainda pendentes. Workflow e contratos especializados permanecem abertos; sem jornadas educativas novas.
|
||||
|
||||
## A/B e ações por perfil
|
||||
|
||||
`investor-path-http-qa.json`: servidor real18096, login por password sintética, criação idempotente e recuperação por ID, gravação de aplicabilidade, rascunho exclusivo/contexto, retorno de entradas financeiras congeladas, rascunho Balcão, tarefa assumida/concluída por gestor independente. Logout seguido de401; nova sessão sem cookies anteriores/login; recuperação dos dois projetos. A dispensa preparação da terra/financiamento externo, necessidade esperada0; B terra em espera e necessidade70000. Análise de mercado concluída enquanto terra aguarda. Ambos20 unidades esperadas nas fórmulas. A/B HTTP IDs estão no roteiro manual; são diferentes dos dois dossiers de setup anteriores. QA web agora4 instâncias/76 etapas, não apenas2/38.
|
||||
|
||||
Negativas reais: outra conta403 dossier/404 draft/lista vazia; draft A com contexto B403; devolução A ao B403; gestor404 para draft financeiro e lista de resultados privados vazia. Nenhum teste presume acesso financeiro por ser gestor. `InvestorPathTest` demonstra separadamente38 etapas/2drafts/pedidos/tarefas no banco efémero, versões/conflitos/dependências/dispensa preservando evidências e manutenção dos roteiros antigos.
|
||||
|
||||
Os resultados apresentados no dossier são estimativas recalculadas pelas fórmulas existentes a partir das entradas/versionamento congelados; **não resultados fiscais nem decisões externas**. HTTP não executa/renderiza Leaflet ou React. Nova sessão HTTP está demonstrada; nova sessão **do navegador e resultado visível** continuam pendentes em AUD-SIM-01, AUD-DESK-02, AUD-GUIDE-01, AUD-DASH-01, AUD-CRM-01 e AUD-UI-01.
|
||||
|
||||
`investor-path-recovered-calculations.json` verifica a função efetiva do dossier sobre os snapshots **realmente recuperados**: A20/0.00 e B20/70000.00. C29 encontrou uma fixture HTTP inicial com listas orçamentais vazias: recuperação financeira recusada como incompatível. A fixture foi corrigida por nova versão, sem alterar os resultados congelados anteriores; estes mantêm a incompatibilidade explícita. Não foi alterado o contrato da ferramenta para ocultar o erro. Criar projetos novos no roteiro visual; os dossiers HTTP de inspeção conservam também esses resultados históricos incompatíveis.
|
||||
|
||||
## Países/origem/estatísticas, formulário a formulário
|
||||
|
||||
| Formulário/consumidor | Evidência específica em QA | Critério ainda pendente |
|
||||
| --- | --- | --- |
|
||||
| Manifestação pública `/` e `/manifestar-interesse` | `PortalAuditContinuationTest::test_public_country_and_origin_survive_api_storage_management_recovery_and_statistics`:249 países nos props, PT/ZA separados, 422 inválido sem escrita, replay único, metadata/GET gestor e agregado/filtro CRM ZA=1/PT=0 | Seleção, mensagem/recibo e filtros renderizados em ambas as páginas |
|
||||
| Apoio support | `test_support_kinds_keep_iso_country_separate_and_legacy_text_unchanged`: POST próprio, recuperação detalhe PT/ZA, filtro PT/ZA e delta+1 interests, origem PT=0 | Formulário/recibo/tabela visíveis |
|
||||
| Formulário investor | Mesmo ensaio, iteração própria investor; gravação/recuperação/filtro/delta+1 | Interface própria |
|
||||
| Formulário company | Mesmo ensaio, iteração própria company; gravação/recuperação/filtro/delta+1 | Interface própria |
|
||||
| Apoio partnership | Mesmo ensaio, iteração própria partnership; gravação/recuperação/filtro/delta+1 | Interface própria; não confundir com contrato da Bolsa |
|
||||
| Perfil + empresa | `InvestmentWorkspaceTest::test_country_meanings_are_persisted_separately_without_inference_and_recovered_by_account`: residência PT/constituição MZ/histórico preservado e recuperação em manifestação; origem não inferida | Seletores/profile/empresa renderizados; não são estatística de solicitação por si só |
|
||||
| Manifestação autenticada | Mesmo teste, origem ZA salva/recuperada/ZZ422/conta indevida404; `test_declared_origin_is_snapshotted_on_submission_and_statistics_do_not_infer_old_country`, `test_crm_origin_filter_separates_explicit_missing_and_empty_results_without_writing`: submissão/unknown/PT/ZA/filtros e stats | Caminho completo na interface, campos condicionais/anexos restantes |
|
||||
| Jornada da carteira | `InvestmentPortfolioTest::test_personal_journey_is_isolated_and_retries_do_not_duplicate_interest_or_event`: país/origem metadata/GET jornada/replay/outra conta; CRM preserva investidor; agregado/filtro PT=1/MZ=0 apesar do país histórico Moçambique | Interface e estatística/filtro renderizados; não promover prova de outro formulário |
|
||||
| Interesse em negócio público | `BusinessMarketplacePublicTest::test_interest_is_limited_to_published_business_and_deduplicated_idempotently`: GET do formulário249países/ID, POST PT/ZA, ZZ422 sem escrita, recibo/replay únicos, metadata/GET gestor, filtro PT/ZA e interests ZA=1/PT=0, conta indevida403 | Interface e variações condicionais por modalidade; não confundir com wizard privado |
|
||||
| Wizard privado de negócios | `PortalAuditNextLotTest::test_business_country_origin_save_recover_filters_submission_statistics_and_actor_isolation`: PT/ZA cifra/revisões/GET/filtros; draft fora dos agregados; submissão businesses ZA=1/PT=0; inválido/conflito/conta indevida | Renderização por modalidade e permissões adicionais; não confundir com interesse público |
|
||||
| Fundiário | `test_land_country_origin_and_four_territory_levels_recover_in_support_filters_statistics`: PT/ZA/parcela de4níveis/GET; apoio gera1interesse; filtro/PT/ZA/unknown/estatística; conta indevida404 | Formulário/mapa/recibo visíveis, anexos/transições restantes |
|
||||
| Balcão preparação | `PortalAuditConsumerLotTest::test_all_three_desk_forms_save_recover_countries_and_support_authorized_corrections`, iteração project-preparation: cifra/GET PT/ZA/422; submetido/devolvido/correção MZ/PT/409/403; stats desk migra para PT, coleção interests/businesses vazia | Interface própria e restante ciclo/anexos |
|
||||
| Balcão alteração | Mesmo ensaio, iteração project-change, referências/motivo e correção autorizada; recuperação/estatística própria | Interface própria/campos condicionais restantes |
|
||||
| Balcão acompanhamento | Mesmo ensaio, iteração project-follow-up, referência/progresso e correção autorizada; recuperação/estatística própria | Interface própria/ciclo completo |
|
||||
| Simulador/contexto | `test_simulator_recovers_iso_countries_in_private_draft_without_reinterpreting_legacy_values` + HTTP A/B: residência fiscal PT, fundos PT/ZA, cifra/GET/versão/ZZ422/estranho404; nenhuma execução fiscal por gravar | Seletores, autosave, nova sessão e retorno renderizados; estes campos não são origem de solicitação |
|
||||
| Gestão/CRM | Ensaios acima: filtros origin/country/unknown, contagens separadas interests/desk/businesses e negativos403 | Aplicação do filtro, URL, tabela e estado vazio no navegador; desempenho das listas cifradas |
|
||||
|
||||
Provas atuais: `continuation-consumer-qa.xml` contém os métodos identificados, incluindo regressão territorial e carteira; `continuation-profile-qa.xml` contém perfil/manifestações, CRM, orientação, interesses e Bolsa; `continuation-business-journey-qa.xml` completa interesse em negócio público e agregado/filtro da jornada. As contagens globais destes ficheiros não substituem as asserções de cada linha. Texto legado mantido; país da residência/constituição/fiscal/fundos e origem declarada são significados diferentes. Ausência de origem permanece Não informado.
|
||||
|
||||
## Territórios, geometrias e mapas
|
||||
|
||||
- **Cadastro:** IDs/parentes/tipos/pesquisa/paginação são provas do seletor/API, não geometria. Fundiário/Balcão têm gravação/recuperação específica de quatro níveis; oportunidade tem teste de gravação/rejeição de hierarquia/versão em `InvestmentTerritoryTest`; Bolsa tem filtro hierárquico em `PartnershipExchangeTest`.
|
||||
- **Disponibilidade:** `geometry-consumers-path-qa.json` recupera361/361 limites reais na mesma QA A/B por serviço READ ONLY. `investor-path-http-qa.json` verifica HTTP real para província/distrito/posto: gestor recupera limite próprio, conta comum403 no endpoint de gestão, público0 limites privados. Classificação/originais/fontes aceites preservados, sem publicação. Geometrias administrativas2019:9/120/232; faltam correspondências2/39/179 e nenhum polígono próprio de localidade identificado.
|
||||
- **Integração de código C27:** ficha de oportunidade passa território principal ao preview, sem acrescentar filtro que mudasse os investimentos; Bolsa usa território **aplicado** à pesquisa, não o valor editado ainda não submetido. Reutilizam TerritoryGeometryPreview/Leaflet, sem ponto ou perímetro de investimento inferido. TypeScript e build passaram.
|
||||
- **Apresentação:** todos os seletores e mapas do roteiro manual continuam pendentes. O detalhe de carteira, zonas, estruturas, perfil/submissão, wizard, simulador, fundiário, três serviços e Bolsa requerem prova própria. Endpoints públicos não podem mostrar361 limites internos por conveniência de teste. A ausência de divulgação é condição de acesso; não é motivo para promover classificação silenciosamente.
|
||||
|
||||
Conferir cada componente no inventário existente de ações/seletores; este documento não declara que todas as ações foram exercitadas. Edição de zonas requer MFA; a conta básica do roteiro não satisfaz esse critério. QA automatizada usa perfil com MFA; demonstração manual de edição precisa de conta QA autorizada com MFA, sem desativar a regra. Workflow de oportunidade e contratos especializados permanecem no backlog.
|
||||
|
||||
## Condições de ativação
|
||||
|
||||
Fingerprints mudaram com C27; `ready=true` histórico deixou de valer para estes assets. Prévia QA confirma schema instalado apenas na cópia e `pathQaVerified=false`. A/B visual ainda impede fecho/ativação. Backup/restauro final **não renovado antes da demonstração**, conforme ordem pedida; snapshot anterior preservado como histórico. Plano exato no [plano de ativação](plano-ativacao.md); ativo continua fora da autorização.
|
||||
@@ -0,0 +1,365 @@
|
||||
"Perfil","Rota","HTTP","Cobertura"
|
||||
"public","/api/v1/home","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/sectors","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/opportunities/search","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/business-opportunities","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/legislation/sources","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/documents/recommendations","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/simulation-drafts/current","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/simulation-drafts","401","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/simulation-drafts/claim-preview","401","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/simulation-drafts/linkable-businesses","401","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/simulations/history","401","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/investidor/negocios","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/management/negocios","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/existing-business/reviews","401","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/existing-business/listings","401","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/geo/search","401","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/geo/sources","401","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/geo/drafts","401","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/parcerias/painel","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/parcerias/criar","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/partnerships","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/management/partnerships-install","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/balcao-virtual/servicos","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/balcao-virtual/painel","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/balcao-virtual/contextos","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/management/balcao-install","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/management/balcao/fontes","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/zonas","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v2/investment/zone-map","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v2/investment/zones","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v2/investment/admin/legal-sources","401","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v2/investment/admin/tax-rules","401","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/management/investment/zones","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v2/investment/admin/zones","401","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/sectores","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/como-investir","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/legislacao","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/documentos","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/apoio","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/parcerias","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/simulador-fiscal","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/formularios/investidor","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/formularios/empresa","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/Simulador","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/balcao-virtual","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/management/portal-services","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/carteira","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/oportunidades","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/negocios","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/investidor","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/dashboard","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/settings/profile","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/settings/security","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/educacao","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/investment/search","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/investment/references","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/investment/suggest","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/investment/map","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/investment/compare","422","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/investidor/profile","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/investidor/notifications","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/investment/profile","401","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/investment/notifications","401","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/investidor/manifestacoes","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/investment/submissions","401","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/management/investment/references","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/terra-duat","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/terra-duat/formulario-em-branco","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/investidor/terra-duat","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/investidor/terra-duat/novo","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/management/terra-duat","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/management/ai","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/investment/territory-options?type=province&q=Maputo","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/api/v1/investment/territory-geometries","422","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/management/opportunity-management-install","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/management/opportunity-resources-install","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/management/opportunities","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/management/opportunities/create","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/management/territory-options?type=province&q=Maputo","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/management/territory-geometries","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/management/territory-subjects","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/management/education","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/management/portfolio","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/management/relationship-repair","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/management/opportunity-origin","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/management/crm/investors","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/management/crm/leads","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/management/history","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/management/interests","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"public","/investimentos","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/home","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/sectors","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/opportunities/search","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/business-opportunities","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/legislation/sources","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/documents/recommendations","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/simulation-drafts/current","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/simulation-drafts","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/simulation-drafts/claim-preview","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/simulation-drafts/linkable-businesses","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/simulations/history","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/investidor/negocios","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/management/negocios","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/existing-business/reviews","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/existing-business/listings","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/geo/search","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/geo/sources","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/geo/drafts","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/parcerias/painel","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/parcerias/criar","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/partnerships","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/management/partnerships-install","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/balcao-virtual/servicos","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/balcao-virtual/painel","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/balcao-virtual/contextos","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/management/balcao-install","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/management/balcao/fontes","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/zonas","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v2/investment/zone-map","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v2/investment/zones","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v2/investment/admin/legal-sources","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v2/investment/admin/tax-rules","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/management/investment/zones","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v2/investment/admin/zones","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/sectores","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/como-investir","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/legislacao","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/documentos","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/apoio","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/parcerias","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/simulador-fiscal","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/formularios/investidor","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/formularios/empresa","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/Simulador","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/balcao-virtual","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/management/portal-services","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/carteira","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/oportunidades","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/negocios","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/investidor","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/dashboard","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/settings/profile","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/settings/security","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/educacao","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/investment/search","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/investment/references","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/investment/suggest","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/investment/map","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/investment/compare","422","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/investidor/profile","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/investidor/notifications","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/investment/profile","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/investment/notifications","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/investidor/manifestacoes","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/investment/submissions","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/management/investment/references","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/terra-duat","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/terra-duat/formulario-em-branco","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/investidor/terra-duat","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/investidor/terra-duat/novo","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/management/terra-duat","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/management/ai","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/investment/territory-options?type=province&q=Maputo","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/api/v1/investment/territory-geometries","422","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/management/opportunity-management-install","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/management/opportunity-resources-install","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/management/opportunities","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/management/opportunities/create","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/management/territory-options?type=province&q=Maputo","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/management/territory-geometries","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/management/territory-subjects","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/management/education","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/management/portfolio","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/management/relationship-repair","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/management/opportunity-origin","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/management/crm/investors","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/management/crm/leads","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/management/history","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/management/interests","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"investor","/investimentos","404","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/home","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/sectors","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/opportunities/search","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/business-opportunities","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/legislation/sources","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/documents/recommendations","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/simulation-drafts/current","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/simulation-drafts","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/simulation-drafts/claim-preview","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/simulation-drafts/linkable-businesses","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/simulations/history","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/investidor/negocios","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/management/negocios","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/existing-business/reviews","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/existing-business/listings","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/geo/search","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/geo/sources","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/geo/drafts","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/parcerias/painel","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/parcerias/criar","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/partnerships","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/management/partnerships-install","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/balcao-virtual/servicos","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/balcao-virtual/painel","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/balcao-virtual/contextos","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/management/balcao-install","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/management/balcao/fontes","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/zonas","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v2/investment/zone-map","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v2/investment/zones","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v2/investment/admin/legal-sources","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v2/investment/admin/tax-rules","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/management/investment/zones","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v2/investment/admin/zones","403","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/sectores","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/como-investir","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/legislacao","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/documentos","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/apoio","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/parcerias","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/simulador-fiscal","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/formularios/investidor","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/formularios/empresa","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/Simulador","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/balcao-virtual","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/management/portal-services","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/carteira","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/oportunidades","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/negocios","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/investidor","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/dashboard","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/settings/profile","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/settings/security","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/educacao","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/investment/search","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/investment/references","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/investment/suggest","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/investment/map","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/investment/compare","422","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/investidor/profile","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/investidor/notifications","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/investment/profile","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/investment/notifications","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/investidor/manifestacoes","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/investment/submissions","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/management/investment/references","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/terra-duat","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/terra-duat/formulario-em-branco","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/investidor/terra-duat","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/investidor/terra-duat/novo","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/management/terra-duat","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/management/ai","404","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/investment/territory-options?type=province&q=Maputo","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/api/v1/investment/territory-geometries","422","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/management/opportunity-management-install","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/management/opportunity-resources-install","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/management/opportunities","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/management/opportunities/create","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/management/territory-options?type=province&q=Maputo","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/management/territory-geometries","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/management/territory-subjects","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/management/education","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/management/portfolio","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/management/relationship-repair","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/management/opportunity-origin","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/management/crm/investors","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/management/crm/leads","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/management/history","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/management/interests","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"manager","/investimentos","404","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/home","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/sectors","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/opportunities/search","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/business-opportunities","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/legislation/sources","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/documents/recommendations","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/simulation-drafts/current","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/simulation-drafts","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/simulation-drafts/claim-preview","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/simulation-drafts/linkable-businesses","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/simulations/history","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/investidor/negocios","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/management/negocios","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/existing-business/reviews","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/existing-business/listings","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/geo/search","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/geo/sources","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/geo/drafts","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/parcerias/painel","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/parcerias/criar","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/partnerships","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/management/partnerships-install","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/balcao-virtual/servicos","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/balcao-virtual/painel","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/balcao-virtual/contextos","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/management/balcao-install","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/management/balcao/fontes","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/zonas","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v2/investment/zone-map","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v2/investment/zones","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v2/investment/admin/legal-sources","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v2/investment/admin/tax-rules","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/management/investment/zones","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v2/investment/admin/zones","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/sectores","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/como-investir","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/legislacao","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/documentos","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/apoio","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/parcerias","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/simulador-fiscal","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/formularios/investidor","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/formularios/empresa","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/Simulador","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/balcao-virtual","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/management/portal-services","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/carteira","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/oportunidades","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/negocios","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/investidor","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/dashboard","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/settings/profile","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/settings/security","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/educacao","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/investment/search","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/investment/references","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/investment/suggest","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/investment/map","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/investment/compare","422","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/investidor/profile","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/investidor/notifications","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/investment/profile","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/investment/notifications","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/investidor/manifestacoes","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/investment/submissions","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/management/investment/references","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/terra-duat","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/terra-duat/formulario-em-branco","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/investidor/terra-duat","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/investidor/terra-duat/novo","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/management/terra-duat","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/management/ai","404","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/investment/territory-options?type=province&q=Maputo","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/api/v1/investment/territory-geometries","422","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/management/opportunity-management-install","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/management/opportunity-resources-install","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/management/opportunities","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/management/opportunities/create","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/management/territory-options?type=province&q=Maputo","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/management/territory-geometries","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/management/territory-subjects","302","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/management/education","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/management/portfolio","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/management/relationship-repair","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/management/opportunity-origin","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/management/crm/investors","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/management/crm/leads","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/management/history","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/management/interests","200","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
"designated_mfa_qa","/investimentos","404","HTTP GET, schema migrated and empty QA; not visual acceptance"
|
||||
|
@@ -0,0 +1,390 @@
|
||||
"Ficheiro","Método","Limite da evidência"
|
||||
"tests/Feature/AiGatewayTest.php","test_authentication_authorisation_flag_and_purpose_are_enforced","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/AiGatewayTest.php","test_unreviewed_confidential_and_revoked_sources_never_leak","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/AiGatewayTest.php","test_language_expiry_and_document_version_are_checked_before_retrieval","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/AiGatewayTest.php","test_unsafe_feedback_suspends_capability_and_review_cannot_change_official_state","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/AiGatewayTest.php","test_rules_and_extractive_summary_do_not_call_external_models","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/AiGatewayTest.php","test_text_upload_uses_canonical_documents_and_does_not_auto_authorise_retrieval","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/AiGatewayTest.php","test_triage_requires_specific_consent_and_withdrawal_hides_old_result","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/AiGatewayTest.php","test_recommendations_use_explicit_filters_and_unpublished_results_are_hidden","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ApiContractTest.php","test_simulation_jobs_follow_simulation_access_scope_and_contract_shape","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ApiContractTest.php","test_public_legislation_lists_only_validated_current_sources_with_etag_and_correlation","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ApiContractTest.php","test_contract_errors_include_correlation_and_required_preconditions","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/AuthenticationTest.php","test_login_screen_can_be_rendered","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/AuthenticationTest.php","test_users_can_authenticate_using_the_login_screen","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/AuthenticationTest.php","test_users_with_two_factor_enabled_are_redirected_to_two_factor_challenge","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/AuthenticationTest.php","test_users_can_not_authenticate_with_invalid_password","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/AuthenticationTest.php","test_users_can_logout","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/AuthenticationTest.php","test_users_are_rate_limited","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/EmailVerificationTest.php","test_email_verification_screen_can_be_rendered","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/EmailVerificationTest.php","test_email_can_be_verified","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/EmailVerificationTest.php","test_email_is_not_verified_with_invalid_hash","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/EmailVerificationTest.php","test_email_is_not_verified_with_invalid_user_id","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/EmailVerificationTest.php","test_verified_user_is_redirected_to_dashboard_from_verification_prompt","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/EmailVerificationTest.php","test_already_verified_user_visiting_verification_link_is_redirected_without_firing_event_again","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/PasswordConfirmationTest.php","test_confirm_password_screen_can_be_rendered","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/PasswordConfirmationTest.php","test_password_confirmation_requires_authentication","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/PasswordResetTest.php","test_reset_password_link_screen_can_be_rendered","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/PasswordResetTest.php","test_reset_password_link_can_be_requested","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/PasswordResetTest.php","test_reset_password_screen_can_be_rendered","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/PasswordResetTest.php","test_password_can_be_reset_with_valid_token","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/PasswordResetTest.php","test_password_cannot_be_reset_with_invalid_token","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/RegistrationTest.php","test_registration_screen_can_be_rendered","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/RegistrationTest.php","test_new_users_can_register","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/TwoFactorChallengeTest.php","test_two_factor_challenge_redirects_to_login_when_not_authenticated","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/TwoFactorChallengeTest.php","test_two_factor_challenge_can_be_rendered","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/TwoFactorDecryptionFailureTest.php","test_wrong_key_secret_returns_controlled_json_and_cancels_challenge_without_authenticating","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/TwoFactorDecryptionFailureTest.php","test_wrong_key_recovery_codes_are_controlled_and_never_replaced_or_authenticated","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/TwoFactorDecryptionFailureTest.php","test_browser_failure_redirects_to_login_with_safe_visible_message","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/TwoFactorDecryptionFailureTest.php","test_normal_enrollment_and_valid_mfa_still_authenticate_after_invalid_code_is_rejected","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/VerificationNotificationTest.php","test_sends_verification_notification","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Auth/VerificationNotificationTest.php","test_does_not_send_verification_notification_if_email_is_verified","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/BusinessMarketplacePublicTest.php","test_public_catalogue_and_detail_exclude_reserved_fields_and_locations","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/BusinessMarketplacePublicTest.php","test_interest_is_limited_to_published_business_and_deduplicated_idempotently","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/BusinessMarketplacePublicTest.php","test_public_catalogue_filters_by_existing_opportunity_modality_and_opens_response_flow","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ClamDQueueWorkerIntegrationTest.php","test_database_queue_worker_processes_a_private_document_and_does_not_publish_it","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ClamDScannerIntegrationTest.php","test_real_clamd_scans_a_harmless_document_and_honours_the_file_limit","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ClamDScannerIntegrationTest.php","test_unavailable_clamd_is_indeterminate_and_never_an_approval","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ClamDScannerIntegrationTest.php","test_clamd_response_timeout_is_inconclusive","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ClamDScannerIntegrationTest.php","test_real_clamd_keeps_a_password_protected_archive_inconclusive","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ClamDScannerIntegrationTest.php","test_zip_beyond_the_decompression_limit_is_inconclusive","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ClusterValueChainTest.php","test_links_are_idempotent_and_reject_self_foreign_and_deleted_stages","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ClusterValueChainTest.php","test_removal_preserves_history_and_cannot_target_another_cluster","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ClusterValueChainTest.php","test_gap_requires_details_and_stays_within_cluster","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ClusterValueChainTest.php","test_anonymous_and_unauthorised_users_cannot_write_network_or_gaps","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/CrmIntakeTest.php","test_conversion_is_idempotent_and_preserves_source_with_owner_and_future_task","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/CrmIntakeTest.php","test_existing_contact_requires_explicit_investor_selection_and_is_not_duplicated","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/CrmIntakeTest.php","test_conversion_rechecks_the_canonical_contact_consent_record","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/CrmIntakeTest.php","test_unauthorised_users_cannot_convert_and_input_requires_owner_and_future_action","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/CrmIntakeTest.php","test_active_lead_keeps_a_next_action_and_qualification_is_audited","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/CrmIntakeTest.php","test_investor_edit_and_contact_duplicate_protection_are_scoped","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/DashboardTest.php","test_guests_are_redirected_to_the_login_page","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/DashboardTest.php","test_authenticated_users_can_visit_the_dashboard","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/DashboardTest.php","test_manager_sees_real_counts_and_only_five_recent_requests","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/DashboardTest.php","test_empty_manager_dashboard_has_zero_counts","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/DatabaseErrorRedactionTest.php","test_public_html_database_errors_do_not_expose_sql_or_connection_details","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/DatabaseErrorRedactionTest.php","test_api_database_errors_return_a_safe_reference_without_sql","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/DatabaseErrorRedactionTest.php","test_connection_errors_do_not_expose_host_or_database_name","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/DocumentLibrarySchemaCompatibilityTest.php","test_schema_check_accepts_the_complete_library_and_security_schema","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/DocumentLibrarySchemaCompatibilityTest.php","test_schema_check_rejects_missing_security_columns_without_weakening_queries","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/EducationTest.php","test_educational_proposal_requires_review_and_is_a_single_unpublished_canonical_opportunity","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/EducationTest.php","test_education_filters_and_record_indicators_do_not_treat_expired_records_as_current","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/EducationTest.php","test_provider_and_course_catalogues_follow_documented_capacity_territory","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/EducationTest.php","test_access_requires_verified_manager_and_enabled_feature","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/EducationTest.php","test_intake_does_not_accept_official_status_or_caller_supplied_reviewer","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/EducationTest.php","test_review_requires_another_person_current_evidence_and_matching_version","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/EducationTest.php","test_retired_courses_and_inactive_providers_cannot_receive_capacity","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/EducationTest.php","test_catalogue_keeps_institutions_and_courses_nonofficial","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/EducationTest.php","test_matching_never_subtracts_training_places_from_workers_and_excludes_unavailable_courses","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ExampleTest.php","test_returns_a_successful_response","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ExistingBusinessCompatibilityTest.php","test_shadow_unavailability_does_not_change_private_contract_or_authorization","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ExistingBusinessFoundationTest.php","test_draft_is_encrypted_and_history_is_versioned_with_stale_writes_rejected","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ExistingBusinessFoundationTest.php","test_other_user_including_manager_cannot_edit_reserved_business","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ExistingBusinessFoundationTest.php","test_unverified_account_cannot_create_business","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ExistingBusinessFoundationTest.php","test_database_prevents_publication_and_history_changes","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ExistingBusinessFoundationTest.php","test_empty_rollback_is_reversible_and_populated_rollback_is_refused","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ExistingBusinessIntakeTest.php","test_private_intake_review_information_and_withdrawal_preserve_isolation","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ExistingBusinessIntakeTest.php","test_granular_verification_requires_independent_review_and_invalidates_after_changes","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ExistingBusinessIntakeTest.php","test_flag_mfa_and_current_designation_are_required","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ExistingBusinessIntakeTest.php","test_arbitrary_states_and_incomplete_or_expired_submission_are_rejected","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ExistingBusinessIntakeTest.php","test_submission_triage_two_level_approval_and_publication_require_distinct_designations","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ExistingBusinessIntakeTest.php","test_reserved_objects_are_scoped_versioned_and_never_verified_by_declaration","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ExistingBusinessIntakeTest.php","test_company_sale_real_estate_and_land_right_have_distinct_private_subject_records","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ExistingBusinessWizardTest.php","test_sector_migration_reverses_empty_and_refuses_data_loss","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ExistingBusinessWizardTest.php","test_draft_resume_validation_concurrency_confirmation_and_private_submission","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ExistingBusinessWizardTest.php","test_company_purchase_is_a_distinct_existing_business_modality","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ExistingBusinessWizardTest.php","test_multiple_locations_require_distinct_public_paths_from_the_same_hierarchy","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ExistingBusinessWizardTest.php","test_public_territory_search_matches_names_with_or_without_accents","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ImportDocumentBatchTest.php","test_preview_is_read_only_and_batch_import_is_private_idempotent_and_attributed","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ImportDocumentBatchTest.php","test_apply_refuses_missing_actor_and_source_path_traversal","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ImportLegalSourceArchiveTest.php","test_preview_has_no_storage_or_database_side_effects","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ImportLegalSourceArchiveTest.php","test_import_creates_private_unapproved_records_and_reimport_does_not_duplicate","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InterestSubmissionTest.php","test_replay_reuses_original_confirmation_event_and_notification","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InterestSubmissionTest.php","test_key_reuse_with_changed_payload_is_conflict_and_invalid_keys_are_rejected","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InterestSubmissionTest.php","test_proponent_sharing_is_a_separate_optional_versioned_consent","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InterestSubmissionTest.php","test_old_clients_still_work_and_distinct_keys_create_distinct_submissions","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InterestSubmissionTest.php","test_event_insert_failure_rolls_back_request_receipt_and_notification","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InterestSubmissionTest.php","test_schema_rollback_refuses_to_destroy_captured_identities","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InterestSubmissionTest.php","test_accepted_request_can_be_replayed_after_opportunity_is_archived","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentPortfolioTest.php","test_document_import_is_idempotent_preserves_edits_and_links_all_anchors","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentPortfolioTest.php","test_stale_editor_cannot_overwrite_or_publish_a_newer_version","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentPortfolioTest.php","test_authorized_manager_can_publish_and_internal_evidence_is_hidden","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentPortfolioTest.php","test_import_keeps_documentary_dossiers_private_and_preserves_later_edits","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentPortfolioTest.php","test_personal_journey_is_isolated_and_retries_do_not_duplicate_interest_or_event","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentPortfolioTest.php","test_private_manifestation_link_requires_authentication_and_preserves_the_public_dossier","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentPortfolioTest.php","test_unpublished_and_deleted_entities_cannot_start_journeys","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentPortfolioTest.php","test_origin_context_is_validated_and_preserved_in_the_interest","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentRelationshipTest.php","test_project_location_and_dossier_navigation_are_bidirectional_without_changing_project_status","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentRelationshipTest.php","test_search_and_all_territorial_levels_follow_explicit_project_relations","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentRelationshipTest.php","test_cluster_member_locations_do_not_create_opportunity_project_relations_or_a_cluster_point","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentRelationshipTest.php","test_private_revoked_and_deleted_relationships_are_not_disclosed","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentRelationshipTest.php","test_multiple_documented_sites_are_shown_separately_without_choosing_one","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentRelationshipTest.php","test_direct_context_impact_and_missing_geography_remain_distinct","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentRelationshipTest.php","test_invalid_coordinates_are_rejected_and_polygon_provenance_is_preserved","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentRelationshipTest.php","test_repair_requires_authenticated_management_is_transactional_and_replays_without_duplicates","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentRelationshipTest.php","test_individual_territories_without_coordinates_apply_sequentially_and_audit_actor_date_and_source","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentRelationshipTest.php","test_pending_and_contradictory_rows_are_retained_while_grounded_rows_apply","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentRelationshipTest.php","test_coordinate_inclusion_and_broken_hierarchy_are_checked_without_inventing_boundaries","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentRelationshipTest.php","test_individual_application_rejects_changed_territorial_preview_and_unknown_row","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentStructureTest.php","test_project_validates_money_dates_and_duplicate_codes_without_precision_loss","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentStructureTest.php","test_cluster_membership_is_idempotent_and_role_changes_are_audited","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentStructureTest.php","test_chain_edit_cannot_cross_cluster_and_codes_are_unique_per_cluster","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentStructureTest.php","test_structure_management_requires_authorised_verified_manager","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentStructureTest.php","test_development_corridors_have_private_crud_with_supported_fields_and_statuses","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentStructureTest.php","test_structure_relations_require_sources_and_independent_review","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentTerritorialTraceabilityTest.php","test_authenticated_application_is_idempotent_and_reversible_without_revalidating_sources","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentTerritorialTraceabilityTest.php","test_permissions_and_conflicting_snapshot_prevent_writes_and_show_field_error","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentTerritorialTraceabilityTest.php","test_expired_backup_and_modified_code_proof_require_updated_plan","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentTerritoryTest.php","test_confirmed_coordinates_create_a_marker_without_hiding_missing_records","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentTerritoryTest.php","test_public_cascade_filters_saved_locations_and_hides_unapproved_references","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentTerritoryTest.php","test_opportunities_match_hierarchical_and_multiple_public_locations_without_expanding","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentTerritoryTest.php","test_opportunity_cluster_and_corridor_filters_use_their_public_opportunity_relations","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentTerritoryTest.php","test_cluster_territory_uses_only_public_validated_project_links_and_project_locations","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentTerritoryTest.php","test_opportunity_pagination_retains_the_selected_territory","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentTerritoryTest.php","test_cascade_assignment_persists_and_rejects_mismatched_parent_and_stale_write","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentTerritoryTest.php","test_non_managers_cannot_read_internal_options","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentTerritoryTest.php","test_opportunity_edit_saves_the_geographic_fields_with_the_record","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentTerritoryTest.php","test_database_rejects_a_cycle_wrong_parent_and_duplicate_source_code","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentTerritoryTest.php","test_integrity_migration_reverses_without_data_and_preserves_imported_codes","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentTerritoryTest.php","test_background_options_do_not_consume_form_validation_feedback","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentTerritoryTest.php","test_investment_areas_are_idempotent_and_preserve_legacy_sectors","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentUnificationTest.php","test_submission_is_versioned_encrypted_private_and_idempotently_integrated","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentUnificationTest.php","test_invalid_reference_group_consent_and_unpublished_target_are_rejected","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentUnificationTest.php","test_attachments_are_private_and_content_changes_are_blocked","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentUnificationTest.php","test_context_editing_combined_facets_and_education_discovery","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentUnificationTest.php","test_map_discloses_only_public_coordinates_of_published_opportunities","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentUnificationTest.php","test_territorial_filters_intersect_and_hide_withdrawn_relations","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentUnificationTest.php","test_favourites_comparison_and_csv_respect_publication_and_ownership","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentUnificationTest.php","test_reference_updates_preserve_codes_and_other_option","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentWorkspaceTest.php","test_country_meanings_are_persisted_separately_without_inference_and_recovered_by_account","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentWorkspaceTest.php","test_declared_origin_is_snapshotted_on_submission_and_statistics_do_not_infer_old_country","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentWorkspaceTest.php","test_authorized_origin_statistics_keep_historical_missing_as_not_informed","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentWorkspaceTest.php","test_crm_origin_filter_separates_explicit_missing_and_empty_results_without_writing","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentWorkspaceTest.php","test_profile_and_company_are_private_versioned_and_do_not_grant_organization_access","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentWorkspaceTest.php","test_conversation_is_encrypted_authorized_and_idempotent_with_private_notifications","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentWorkspaceTest.php","test_revisions_preserve_encrypted_prior_values_without_exposing_them_to_other_users","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentWorkspaceTest.php","test_status_review_notifies_owner_once_per_effective_change","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentWorkspaceTest.php","test_incomplete_text_can_be_saved_as_draft_but_cannot_be_submitted","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentZoneAttachmentTest.php","test_upload_is_private_until_administrative_review_and_explicit_public_selection","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentZoneAttachmentTest.php","test_public_selection_rejects_unknown_rights_or_personal_data_and_invalid_file_content","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentZoneTest.php","test_private_drafts_require_mfa_and_preserve_encrypted_immutable_revisions","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentZoneTest.php","test_rollback_refuses_populated_foundation_and_empty_rollback_is_reversible","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentZoneTest.php","test_documented_general_industrial_park_can_publish_without_special_regime_or_operator_and_filters_match_csv","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentZoneTest.php","test_promoter_sourced_industrial_park_can_be_published_as_informational_only","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentZoneTest.php","test_officially_sourced_zee_can_be_published_informationally_by_the_authenticated_author","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentZoneTest.php","test_zone_record_separates_physical_type_and_legal_regime_and_searches_multiple_reviewed_territories_once","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentZoneTest.php","test_initial_zone_import_is_idempotent_and_keeps_records_private_until_review","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentZoneTest.php","test_industrial_candidate_import_is_exact_idempotent_keeps_ambiguity_and_revubue_single","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentZoneTest.php","test_validated_relations_filter_the_same_opportunity_and_revoked_sources_disappear","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentZoneTest.php","test_gis_rejects_invalid_shapes_and_requires_independent_review_without_granting_zone_status","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentZoneTest.php","test_anchor_can_link_multiple_zones_without_duplicates_or_self_approval","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestmentZoneTest.php","test_identity_reconciliation_is_dry_by_default_idempotent_and_preserves_legacy_data","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestorGuidanceTest.php","test_desk_declared_origin_is_recovered_and_invalid_country_preserves_draft","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestorGuidanceTest.php","test_panel_creation_redirect_confirms_persistence_and_never_submits_a_request","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestorGuidanceTest.php","test_message_kind_is_recorded_at_send_time_and_legacy_is_not_reinterpreted","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestorGuidanceTest.php","test_link_monitor_expires_checks_and_records_human_evidence_without_external_calls","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestorGuidanceTest.php","test_complete_idea_request_response_and_internal_crm_task_reuses_existing_identity","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestorGuidanceTest.php","test_incomplete_context_corrections_stale_choices_and_no_external_services","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestorGuidanceTest.php","test_private_linked_draft_is_not_shared_with_manager_and_is_recovered_for_owner","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestorGuidanceTest.php","test_request_constraints_and_draft_permissions_preserve_existing_flow","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestorGuidanceTest.php","test_clarification_resubmission_and_signed_internal_outcome_preserve_snapshots","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestorGuidanceTest.php","test_manual_document_payment_and_communication_evidence_without_external_confirmation","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestorGuidanceTest.php","test_parallel_preparation_unavailable_link_and_ordered_contestable_recommendations","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestorGuidanceTest.php","test_organization_viewers_and_removed_members_keep_module_permissions","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestorGuidanceTest.php","test_pending_installation_preserves_legacy_desk_and_requires_authentication","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestorGuidanceTest.php","test_installation_preview_shows_target_and_refuses_proofs_for_a_different_database","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestorGuidanceTest.php","test_existing_support_request_and_crm_investor_are_associated_without_copying","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestorGuidanceTest.php","test_guidance_evidence_tracks_scope_latest_review_hash_expiration_and_permissions","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestorPathTest.php","test_two_independent_investments_recover_tool_evidence_support_and_internal_tasks_without_external_calls","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestorPathTest.php","test_permissions_stale_versions_and_real_dependencies_do_not_block_independent_preparation","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/InvestorPathTest.php","test_applicability_changes_preserve_old_branch_evidence_and_legacy_workflow","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/LandAssistanceTest.php","test_public_guide_and_blank_form_are_available_without_claiming_official_status","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/LandAssistanceTest.php","test_private_draft_and_support_are_versioned_and_create_one_crm_receipt","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/LandAssistanceTest.php","test_phone_only_support_still_requires_contact_consent","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/LandAssistanceTest.php","test_phone_only_support_is_saved_without_a_synthetic_email","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/LandAssistanceTest.php","test_email_nullable_migration_can_be_reversed_when_no_email_is_missing","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/LandAssistanceTest.php","test_email_nullable_migration_refuses_rollback_with_phone_only_requests","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ManagementAccessTest.php","test_setup_can_be_deferred_without_creating_an_account","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ManagementAccessTest.php","test_unverified_manager_can_view_setup_and_request_verification_but_cannot_manage","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/OpportunityManagementTest.php","test_installation_requires_management_permission_and_current_proofs","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/OpportunityManagementTest.php","test_incomplete_draft_recovers_and_soft_delete_restore_preserves_identity","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/OpportunityManagementTest.php","test_closed_version_edits_do_not_change_public_values_classification_or_relations","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/OpportunityOriginReviewTest.php","test_preview_has_no_decision_and_example_separation_preserves_records_and_interactions","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/OpportunityOriginReviewTest.php","test_permissions_foundation_confirmation_and_conflicts_are_required","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/OpportunityRealDocumentOperationsTest.php","test_real_original_replacement_quarantine_retry_download_delete_restore_and_authorization","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/OpportunityRealDocumentOperationsTest.php","test_three_derivatives_have_independent_real_scans_signed_previews_and_integrity_checks","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/OpportunityResourcesTest.php","test_encrypted_original_scan_pending_recovery_replacement_and_logical_lifecycle","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/OpportunityResourcesTest.php","test_multiple_locations_without_coordinates_and_invalid_hierarchy_and_geometry","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/OpportunityResourcesTest.php","test_invalid_upload_and_cross_opportunity_links_do_not_create_resources","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/OpportunityResourcesTest.php","test_image_processing_is_explicit_and_every_derivative_requires_its_own_scan","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PartnershipExchangeTest.php","test_complete_local_flow_from_personal_draft_to_agreement_and_completed_milestone","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PartnershipExchangeTest.php","test_preserves_legacy_proposal_and_rejects_self_moderation_and_concurrent_updates","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PartnershipExchangeTest.php","test_draft_recovery_and_idempotency_do_not_require_organization_or_documents","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PartnershipExchangeTest.php","test_competing_candidates_and_moderator_cannot_enter_private_room_or_read_other_interests","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PartnershipExchangeTest.php","test_matching_keeps_unknown_information_separate_from_proven_failure_and_desirable_criteria","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PartnershipExchangeTest.php","test_document_sharing_reuses_private_repository_and_scan_controls","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PartnershipExchangeTest.php","test_organization_representation_blocks_viewer_writes_and_revoked_authors","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PartnershipExchangeTest.php","test_hierarchical_filters_and_source_links_use_only_explicit_documented_relations","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PartnershipExchangeTest.php","test_authenticated_installation_preserves_legacy_rows_and_is_repeatable_in_qa","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalAuditConsumerLotTest.php","test_private_official_context_is_authorized_and_does_not_become_a_public_investment_site","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalAuditConsumerLotTest.php","test_all_three_desk_forms_save_recover_countries_and_support_authorized_corrections","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalAuditContinuationTest.php","test_public_country_and_origin_survive_api_storage_management_recovery_and_statistics","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalAuditContinuationTest.php","test_support_kinds_keep_iso_country_separate_and_legacy_text_unchanged","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalAuditContinuationTest.php","test_iso_catalogue_does_not_depend_on_geo_publication_and_is_searchable_and_pageable","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalAuditContinuationTest.php","test_simulator_recovers_iso_countries_in_private_draft_without_reinterpreting_legacy_values","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalAuditContinuationTest.php","test_desk_territory_cascade_is_saved_recovered_and_presented_with_origin_without_cross_account_access","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalAuditNextLotTest.php","test_eight_maturity_stages_recover_versioned_without_reinterpreting_legacy_or_publishing","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalAuditNextLotTest.php","test_business_country_origin_save_recover_filters_submission_statistics_and_actor_isolation","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalAuditNextLotTest.php","test_land_country_origin_and_four_territory_levels_recover_in_support_filters_statistics","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalAuditRoutesTest.php","test_static_portal_get_routes_for_public_investor_and_manager_do_not_crash","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalManagementTest.php","test_catalog_filters_combine_and_survive_pagination","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalManagementTest.php","test_unspecified_geography_has_a_private_review_filter_without_assigning_a_location","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalManagementTest.php","test_management_requires_an_explicit_verified_manager","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalManagementTest.php","test_manager_creates_and_edits_sectors_and_invalidates_home_cache","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalManagementTest.php","test_draft_money_precision_is_preserved_without_editorial_publication_bypass","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalManagementTest.php","test_review_tracks_the_authenticated_reviewer_and_rejects_invalid_states","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalManagementTest.php","test_public_requests_reject_missing_draft_deleted_and_future_opportunities","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalManagementTest.php","test_proponent_sharing_consent_can_be_revoked_with_audited_outbox_event","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalManagementTest.php","test_contact_consent_revocation_blocks_conversion_and_emits_no_duplicate_events","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalManagementTest.php","test_overdue_task_escalation_is_opt_in_and_idempotent","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalManagementTest.php","test_valid_public_submissions_persist_and_return_distinct_references","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalOperationsTest.php","test_audit_records_actor_and_changes_without_free_text","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalOperationsTest.php","test_audit_failure_rolls_back_the_business_change","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalOperationsTest.php","test_public_notifications_are_disabled_by_default_and_enqueued_when_enabled","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalOperationsTest.php","test_job_checks_current_configuration_and_excludes_personal_data","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalOperationsTest.php","test_readiness_reports_non_production_without_mutating_data","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalOriginCompatibilityTest.php","test_public_api_preserves_explicit_origin_in_receipt_replay_and_statistics","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalOriginCompatibilityTest.php","test_support_form_keeps_origin_optional_and_exposes_local_catalogue","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalRealDocumentConsumersTest.php","test_library_private_registration_real_scan_explicit_classification_publication_and_download","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalRealDocumentConsumersTest.php","test_desk_upload_real_scan_dedup_recovery_foreign_actor_and_tamper","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalRealDocumentConsumersTest.php","test_encrypted_canonical_original_is_reusable_in_desk_and_manager_library_download","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalServicesTest.php","test_public_sections_render_and_desk_requires_login","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalServicesTest.php","test_document_management_writes_redirect_to_the_management_get_route","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalServicesTest.php","test_support_receipt_is_idempotent_private_and_requires_consent","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalServicesTest.php","test_home_remains_available_when_document_catalogue_schema_is_incompatible","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalServicesTest.php","test_partnership_requires_moderation_and_hides_owner_identity","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalServicesTest.php","test_document_download_rechecks_classification_checksum_and_publication","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalServicesTest.php","test_document_search_combines_exact_activity_and_territory_filters_without_duplicates","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalServicesTest.php","test_legislation_with_an_identified_source_can_be_published_for_consultation_without_claiming_confirmation","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalServicesTest.php","test_recorded_user_authorization_publishes_only_eligible_document_scope_in_one_manager_action","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalServicesTest.php","test_manager_classifies_a_reviewed_document_public_before_separate_publication","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalServicesTest.php","test_public_pdf_preview_is_available_only_after_publication_and_hash_verification","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalServicesTest.php","test_threat_and_unavailable_results_stay_quarantined_with_hash_history","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalServicesTest.php","test_manager_can_prepare_private_editorial_draft_before_malware_scan_finishes","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalServicesTest.php","test_identical_upload_is_rejected_and_required_applicability_needs_a_basis","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalServicesTest.php","test_requirement_links_use_known_technical_keys_and_expose_only_confirmed_citations_as_evidence","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalServicesTest.php","test_public_recommendations_return_only_confirmed_requirement_citations","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PortalServicesTest.php","test_amount_filters_do_not_mix_currencies_or_expose_drafts","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PublicPortalNavigationTest.php","test_home_cache_contains_only_plain_data_and_survives_restricted_unserialization","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/PublicPortalNavigationTest.php","test_public_links_open_the_expected_views_without_authentication","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ReferenceCatalogTest.php","test_reference_seeds_are_repeatable_and_activity_codes_are_stable","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ReferenceCatalogTest.php","test_catalog_search_pagination_and_explicit_version","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ReferenceCatalogTest.php","test_jurisdiction_dropdown_requires_the_immediate_parent_and_filters_children","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ReferenceCatalogTest.php","test_economic_activity_dropdown_can_be_filtered_by_sector","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ReferenceCatalogTest.php","test_authorities_are_not_fabricated_before_a_source_is_approved","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ReferenceCatalogTest.php","test_published_authority_catalog_only_returns_public_organizations","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ReferenceCatalogTest.php","test_foreign_keys_and_catalog_migration_rollback_guard","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ReferenceCatalogTest.php","test_published_catalog_values_are_immutable","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/ReferenceCatalogTest.php","test_empty_catalog_migration_rolls_back_and_reapplies","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Settings/ProfileUpdateTest.php","test_profile_page_is_displayed","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Settings/ProfileUpdateTest.php","test_profile_information_can_be_updated","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Settings/ProfileUpdateTest.php","test_email_verification_status_is_unchanged_when_the_email_address_is_unchanged","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Settings/ProfileUpdateTest.php","test_user_can_delete_their_account","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Settings/ProfileUpdateTest.php","test_correct_password_must_be_provided_to_delete_account","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Settings/SecurityTest.php","test_security_page_is_displayed","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Settings/SecurityTest.php","test_security_page_requires_password_confirmation_when_enabled","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Settings/SecurityTest.php","test_security_page_renders_without_two_factor_when_feature_is_disabled","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Settings/SecurityTest.php","test_password_can_be_updated","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/Settings/SecurityTest.php","test_correct_password_must_be_provided_to_update_password","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationDraftContinuityTest.php","test_recovery_cookie_is_http_only_scoped_and_has_a_thirty_day_deadline","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationDraftContinuityTest.php","test_automatic_reads_do_not_renew_expiry_but_an_explicit_save_does","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationDraftContinuityTest.php","test_forget_current_soft_deletes_only_the_anonymous_draft_and_clears_cookie","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationDraftContinuityTest.php","test_a_routine_read_does_not_refresh_an_existing_recovery_cookie","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationDraftContinuityTest.php","test_explicit_continue_later_touch_renews_only_the_deadline_without_changing_snapshot_version","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationDraftContinuityTest.php","test_database_details_are_not_returned_by_simulation_draft_api_errors","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationDraftContinuityTest.php","test_claiming_an_anonymous_draft_creates_another_private_project_without_merging_and_is_idempotent","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationDraftContinuityTest.php","test_continue_existing_choice_leaves_the_anonymous_draft_unclaimed","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationDraftContinuityTest.php","test_expired_anonymous_draft_is_not_readable_and_same_recovery_cookie_can_start_a_new_draft","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationDraftContinuityTest.php","test_business_association_is_explicit_reversible_and_does_not_copy_or_publish_data","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationExecutionTest.php","test_account_history_contains_only_the_verified_users_personal_simulations","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationExecutionTest.php","test_account_history_requires_authentication_and_verified_email","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationExecutionTest.php","test_anonymous_execution_keeps_only_token_hash_and_reconciles_immutable_sources","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationExecutionTest.php","test_simulation_audit_events_are_append_only_for_an_authorized_owner","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationExecutionTest.php","test_execution_requires_an_explicit_user_supplied_reduction","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationExecutionTest.php","test_idempotency_replays_same_payload_and_rejects_key_reuse_with_different_payload","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationExecutionTest.php","test_if_match_is_required_and_stale_versions_return_412_then_success_advances_version","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationExecutionTest.php","test_rls_hides_rows_without_context_and_from_an_unrelated_actor","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationExecutionTest.php","test_terminal_job_failure_is_reconciled_without_exposing_exception_text","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationExecutionTest.php","test_organization_membership_scopes_simulation_reads","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationExecutionTest.php","test_postgres_rls_uses_anonymous_token_hmac_not_plain_token","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationExecutionTest.php","test_retry_budget_is_bounded_and_failed_attempt_is_reconciled","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationExecutionTest.php","test_core_rollback_refuses_published_path_definition_and_preserves_rls","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationExecutionTest.php","test_questionnaire_endpoint_exposes_only_published_version_with_etag","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationFormDraftTest.php","test_anonymous_draft_is_encrypted_scoped_and_restorable_without_persisting_personal_data","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationFormDraftTest.php","test_anonymous_autosave_accepts_an_explicitly_empty_personal_snapshot","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationFormDraftTest.php","test_exploratory_small_business_idea_and_market_assumptions_are_saved_in_the_economic_snapshot","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationFormDraftTest.php","test_structured_project_plans_reject_negative_amounts","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationFormDraftTest.php","test_project_risk_responses_reject_negative_costs_and_invalid_statuses","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationFormDraftTest.php","test_creation_is_idempotent_and_rejects_key_reuse_with_changed_data","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationFormDraftTest.php","test_clients_cannot_forge_server_owned_simulation_sources","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationFormDraftTest.php","test_updates_require_a_current_etag_and_delete_is_reversible_until_expiry","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationFormDraftTest.php","test_completed_simulation_is_attached_with_explicit_consent_as_an_immutable_versioned_snapshot","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationFormDraftTest.php","test_simulation_conversion_rejects_a_report_that_does_not_match_the_result_snapshot","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationFormDraftTest.php","test_simulation_conversion_rejects_an_unowned_execution_token","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationFormDraftTest.php","test_server_rejects_invalid_rates_and_unlisted_snapshot_fields","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationFormDraftTest.php","test_fiscal_mode_rejects_manual_rates_and_incomplete_custom_assumptions","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationRateLimitTest.php","test_public_calculation_endpoint_limits_repeated_requests_per_anonymous_token","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationTaxRuleGovernanceTest.php","test_rule_requires_independent_review_approval_publication_and_records_hash_chained_versions","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationTaxRuleGovernanceTest.php","test_source_revocation_stops_publication_and_conflicting_effective_rules_are_rejected","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationTaxRuleGovernanceTest.php","test_draft_edit_uses_optimistic_locking_and_other_roles_cannot_create_rules","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SimulationTaxRuleGovernanceTest.php","test_rollback_refuses_to_drop_rule_versions_or_their_audit_history","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SkillsEducationSchemaTest.php","test_master_types_private_defaults_and_immutable_audit","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SkillsEducationSchemaTest.php","test_reverse_order_rollback_reapply_and_nonempty_refusal","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SuiteCrm/SuiteCrmClientTest.php","test_disabled_client_and_insecure_configuration_never_send_requests","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SuiteCrm/SuiteCrmClientTest.php","test_authentication_contract_and_token_cache_are_encrypted","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SuiteCrm/SuiteCrmClientTest.php","test_401_renews_once_and_replays_the_unauthorised_request","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SuiteCrm/SuiteCrmClientTest.php","test_second_401_is_not_retried","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SuiteCrm/SuiteCrmClientTest.php","test_json_api_create_update_relationship_and_exact_search_contracts","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SuiteCrm/SuiteCrmClientTest.php","test_read_retries_transient_failures_but_create_does_not","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SuiteCrm/SuiteCrmClientTest.php","test_write_timeout_is_not_replayed_and_transport_exception_is_not_retained","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SuiteCrm/SuiteCrmClientTest.php","test_retry_after_is_returned_without_immediate_retry_for_long_delays","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SuiteCrm/SuiteCrmClientTest.php","test_circuit_opens_then_allows_recovery_after_cooldown","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SuiteCrm/SuiteCrmClientTest.php","test_identifiers_modules_and_page_limits_are_rejected_before_network","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SuiteCrm/SuiteCrmClientTest.php","test_invalid_token_response_and_redirect_are_rejected","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SuiteCrm/SuiteCrmClientTest.php","test_token_expiration_and_credential_rotation_obtain_new_tokens","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SuiteCrm/SuiteCrmClientTest.php","test_forbidden_and_invalid_input_responses_are_permanent_and_sanitised","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SuiteCrm/SuiteCrmClientTest.php","test_a_malformed_successful_write_is_treated_as_ambiguous","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SuiteCrm/SuiteCrmClientTest.php","test_retry_after_short_delay_is_respected_and_logs_have_no_payload","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SuiteCrm/SuiteCrmProbeTest.php","test_disabled_probe_does_not_contact_crm","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/SuiteCrm/SuiteCrmProbeTest.php","test_probe_reads_metadata_without_writing_business_records","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/TerritorialRegistryTest.php","test_writes_require_idempotency_and_replays_recheck_current_permissions","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/TerritorialRegistryTest.php","test_drafts_are_private_and_hierarchy_duplicates_and_stale_versions_are_rejected","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/TerritorialRegistryTest.php","test_revoking_ancestor_source_hides_descendants_and_filters_are_scoped","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/TerritorialRegistryTest.php","test_authentication_mfa_and_empty_rollback","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/TerritorialRegistryTest.php","test_editor_reviewer_publisher_workflow_and_source_revocation","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/TerritoryGeometryImportTest.php","test_preview_apply_replay_reuse_and_reverse_preserve_history","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/TerritoryGeometryImportTest.php","test_stale_preview_changed_geometry_mfa_and_foreign_actor_are_rejected","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/TerritoryGeometryImportTest.php","test_expired_scan_and_non_qa_target_cannot_write","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Feature/TerritoryGeometryImportTest.php","test_reversal_refuses_a_real_foreign_key_consumer_and_is_atomic","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/InvestMoz/SchemaLifecycleTest.php","test_schema_constraints_events_and_rollback_in_isolated_postgis","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Unit/AiHybridFusionTest.php","test_fusion_excludes_unauthorised_ids_and_does_not_double_count_duplicates","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Unit/CartographyWorkbookAuditTest.php","test_audit_quarantines_unknown_crs_and_reports_duplicates_without_copying_source_values","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Unit/CartographyWorkbookAuditTest.php","test_checksum_mismatch_is_rejected","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Unit/CartographyWorkbookAuditTest.php","test_inspection_requires_authorization_evidence","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Unit/CartographyWorkbookAuditTest.php","test_xml_entities_are_rejected","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Unit/EducationGapCalculatorTest.php","test_unknown_supply_is_not_zero_and_invalid_comparisons_are_not_gaps","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Unit/EducationGapCalculatorTest.php","test_comparable_people_produce_only_an_unvalidated_nonnegative_gap","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Unit/EducationGapCalculatorTest.php","test_negative_quantities_are_rejected","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Unit/ExampleTest.php","test_that_true_is_true","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Unit/InvestorGuidanceRulesTest.php","test_declared_quantities_require_common_scope_and_never_invent_missing_values","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Unit/InvestorGuidanceRulesTest.php","test_missing_declared_and_attached_information_are_not_verified","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Unit/InvestorGuidanceRulesTest.php","test_scoped_internal_verification_removes_only_the_corresponding_pending_alert","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Unit/InvestorGuidanceRulesTest.php","test_contradictions_expiration_and_replacement_are_specific_non_blocking_alerts","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Unit/SimulationFormDraftPrivacyPolicyTest.php","test_anonymous_snapshots_discard_identity_but_keep_financial_assumptions","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Unit/SimulationFormDraftPrivacyPolicyTest.php","test_authenticated_snapshots_can_retain_identity_in_the_owned_account_draft","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Unit/TerritorialCsvAuditTest.php","test_preserves_leading_zero_codes_and_counts_identical_duplicates","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Unit/TerritorialCsvAuditTest.php","test_conflicting_names_and_coordinates_cancel_whole_dataset","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Unit/TerritorialCsvAuditTest.php","test_no_inferred_parent_or_coordinates_and_unknown_province_are_rejected","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Unit/TerritorialCsvAuditTest.php","test_district_only_rows_do_not_create_localities","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Unit/TerritorialCsvAuditTest.php","test_empty_csv_is_rejected","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
"tests/Unit/TerritorialCsvAuditTest.php","test_wrong_delimiter_is_not_silently_interpreted","Inventário estático; resultado global em phpunit-final.json; não certifica cláusula/UI individual"
|
||||
|
@@ -0,0 +1,255 @@
|
||||
# Correspondências cartográficas — lacunas por nome
|
||||
|
||||
Complemento de AUD-GEO-02/03 da mesma matriz. Exemplar INE/UNOCHA 07/06/2019 aceite; esperado significa total deste exemplar, não um total administrativo atual certificado. Não converte limites administrativos em disponibilidade de terra.
|
||||
|
||||
| Nível | Esperado no exemplar | Resolvido em QA | Pendente |
|
||||
| --- | ---: | ---: | ---: |
|
||||
| Províncias | 11 | 9 | 2 |
|
||||
| Distritos | 159 | 120 | 39 |
|
||||
| Postos administrativos | 411 | 232 | 179 |
|
||||
|
||||
2/39/179 são pendentes, não importados. Foram resolvidos 361 de 581 elementos: 9+120+232. A repetição do ensaio CLI reutilizou361. Aplicação autenticada e interface têm provas independentes.
|
||||
|
||||
A normalização permite somente caixa e diacríticos. Não decide aliases, divisões recentes, fusões, homónimos ou mudança de pai. Maputo e Maputo City permanecem distintos; não renomear os cadastros existentes para forçar correspondência. Para fechar um alias é necessária a correspondência explícita entre código do exemplar e ID existente, com fundamento e âmbito/edição.
|
||||
|
||||
## Províncias — 2 pendentes
|
||||
|
||||
| Código do exemplar | Nome exato | Pai | Causa |
|
||||
| --- | --- | --- | --- |
|
||||
| MZ05 | Maputo | Moçambique | Nome não tem correspondência única no nível |
|
||||
| MZ06 | Maputo City | Moçambique | Nome não tem correspondência única no nível |
|
||||
|
||||
## Distritos — 39 pendentes
|
||||
|
||||
| Código do exemplar | Nome exato | Pai | Causa |
|
||||
| --- | --- | --- | --- |
|
||||
| MZ0501 | Boane | Maputo | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ1002 | Cahora Bassa | Tete | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ0801 | Chimbonila | Niassa | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ0206 | Chongoene | Gaza | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ0502 | Cidade Da Matola | Maputo | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ0601 | Cidade De Maputo | Maputo City | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ1104 | Derre | Zambezia | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ1007 | Doa | Tete | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ0703 | Erati | Nampula | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ0704 | Ilha De Moçambique | Nampula | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ0804 | Ilha Licom | Niassa | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ0805 | Ilha Risunodo | Niassa | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ0807 | Lago Niassa | Niassa | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ0706 | Larde | Nampula | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ0209 | Limpopo | Gaza | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ0707 | Liúpo | Nampula | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ1109 | Luabo | Zambezia | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ0405 | Macate | Manica | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ0503 | Magude | Maputo | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ0211 | Mandlakaze | Gaza | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ0504 | Manhiça | Maputo | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ0212 | Mapai | Gaza | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ1112 | Maquival | Zambezia | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ1010 | Marara | Tete | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ0505 | Marracuene | Maputo | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ0506 | Matutuine | Maputo | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ0310 | Maxixe | Inhambane | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ0109 | Metuge | Cabo Delgado | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ0507 | Moamba | Maputo | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ1115 | Mocubela | Zambezia | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ1116 | Molumbo | Zambezia | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ1119 | Mulevala | Zambezia | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ0719 | Nacala | Nampula | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ0720 | Nacala-A-Velha | Nampula | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ0508 | Namaacha | Maputo | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ0817 | Ngauma | Niassa | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ0722 | Rapale | Nampula | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ0412 | Vanduzi | Manica | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ1015 | Zumbu | Tete | Nome sem correspondência única sob o pai resolvido |
|
||||
|
||||
## Postos administrativos — 179 pendentes
|
||||
|
||||
| Código do exemplar | Nome exato | Pai | Causa |
|
||||
| --- | --- | --- | --- |
|
||||
| MZ110101 | Alto Molocue | Alto Molocue | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ070301 | Alua | Erati | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ072201 | Anchilo | Rapale | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ070101 | Angoche | Angoche | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ111501 | Bajone | Mocubela | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ041101 | Bazua | Tambara | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ050601 | Bela Vista | Matutuine | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ050101 | Boane | Boane | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ070103 | Boila | Angoche | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ090201 | Caia | Caia | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ050401 | Calanga | Manhiça | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ020801 | Caniçado | Guija | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ050602 | Catuane | Matutuine | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ050801 | Changalane | Namaacha | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ101301 | Charre | Mutarara | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ021101 | Chibonzane | Mandlakaze | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ020204 | Chibuto | Chibuto | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ020901 | Chicumbane | Limpopo | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ021102 | Chidenguele | Mandlakaze | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ020401 | Chigubo | Chigubo | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ080101 | Chimbonila | Chimbonila | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ110201 | Chinde | Chinde | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ100201 | Chintholo | Cahora Bassa | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ100901 | Chinthopo | Magoe | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ100301 | Chipembere | Changara | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ101102 | Chiputu | Maravia | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ020902 | Chissano | Limpopo | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ100202 | Chitima | Cahora Bassa | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ040601 | Chitobe | Machaze | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ010301 | Chiure | Chiure | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ020501 | Chokwe | Chokwe | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ020601 | Chongoene | Chongoene | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ090601 | Cidade Da Beira | Cidade Da Beira | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ050201 | Cidade Da Matola | Cidade Da Matola | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ040201 | Cidade De Chimoio | Cidade De Chimoio | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ030101 | Cidade De Inhambane | Cidade De Inhambane | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ080201 | Cidade De Lichinga | Cidade De Lichinga | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ060101 | Cidade De Maputo | Cidade De Maputo | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ070201 | Cidade De Nampula | Cidade De Nampula | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ010401 | Cidade De Pemba | Cidade De Pemba | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ100601 | Cidade De Tete | Cidade De Tete | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ072001 | Covo | Nacala-A-Velha | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ080301 | Cuamba | Cuamba | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ110401 | Derre | Derre | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ020402 | Dindiza | Chigubo | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ100701 | Doa | Doa | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ090701 | Dondo | Dondo | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ080302 | Etarara | Cuamba | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ090801 | Gorongosa | Gorongosa | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ040401 | Guro | Guro | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ110601 | Gurue | Gurue | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ030401 | Homoine | Homoine | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ010501 | Ibo | Ibo | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ070401 | Ilha De Moçambique | Ilha De Moçambique | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ050402 | Ilha Josina Machel | Manhiça | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ080401 | Ilha Licom | Ilha Licom | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ080501 | Ilha Risunodo | Ilha Risunodo | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ011202 | Imbuo | Mueda | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ030501 | Inharrime | Inharrime | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ110802 | Inhassunge | Inhassunge | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ081701 | Itepela | Ngauma | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ071302 | Iuluti | Mogovolas | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ101201 | Kambulatsisi | Moatize | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ010203 | Kuekue | Balama | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ080701 | Lago Niassa | Lago Niassa | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ070501 | Lalaua | Lalaua | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ070601 | Larde | Larde | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ080102 | Lione | Chimbonila | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ070701 | Liúpo | Liúpo | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ110901 | Luabo | Luabo | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ070402 | Lumbo | Ilha De Moçambique | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ081901 | Lussimbesse | Sanga | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ081201 | M'Sawize | Mavago | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ011501 | M'Tamba | Nangade | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ021002 | Mabalane | Mabalane | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ040501 | Macate | Macate | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ050501 | Machubo | Marracuene | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ020101 | Macia | Bilene | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ010602 | Macomia | Macomia | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ021103 | Macuacua | Mandlakaze | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ112001 | Macuze | Namacurra | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ020602 | Madzucane | Chongoene | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ111101 | Maganja | Maganja Da Costa | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ050301 | Magude | Magude | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ050302 | Mahele | Magude | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ020102 | Makluane | Bilene | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ080801 | Malanga | Majune | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ070802 | Malema | Malema | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ101104 | Malowera | Maravia | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ050403 | Maluana | Manhiça | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ040402 | Mandie | Guro | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ080901 | Mandimba | Mandimba | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ021104 | Mandlakaze | Mandlakaze | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ050404 | Manhiça | Manhiça | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ040802 | Manica | Manica | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ021201 | Mapai | Mapai | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ050303 | Mapulanguene | Magude | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ111201 | Maquival | Maquival | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ101001 | Marara | Marara | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ050502 | Marracuene | Marracuene | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ081002 | Marrupa | Marrupa | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ081702 | Massangulo | Ngauma | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ050102 | Matola Rio | Boane | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ041201 | Matsinho | Vanduzi | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ081202 | Mavago | Mavago | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ031001 | Maxixe | Maxixe | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ071103 | Mazula | Memba | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ081402 | Mecula | Mecula | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ080103 | Meponda | Chimbonila | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ110603 | Mepuagiua | Gurue | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ010102 | Mesa | Ancuabe | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ080604 | Metangula | Lago | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ010901 | Metuge | Metuge | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ110202 | Micaune | Chinde | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ010902 | Mieze | Metuge | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ050701 | Moamba | Moamba | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ111401 | Mocuba | Mocuba | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ111502 | Mocubela | Mocubela | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ030502 | Mocumbi | Inharrime | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ111601 | Molumbo | Molumbo | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ071402 | Moma | Moma | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ071502 | Monapo | Monapo | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ011103 | Montepuez | Montepuez | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ071603 | Mossuril | Mossuril | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ050304 | Motaze | Magude | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ100902 | Mphende | Magoe | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ100402 | Mualadze | Chifunde | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ112301 | Mualama | Pebane | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ031102 | Mucoduene | Morrumbene | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ070602 | Mucuali | Larde | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ071702 | Muculoene | Muecate | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ011203 | Mueda | Mueda | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ050603 | Mugazine | Matutuine | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ111901 | Mulevala | Mulevala | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ041002 | Muoha | Sussundenga | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ072202 | Mutivasse | Rapale | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ101501 | Muze | Zumbu | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ011404 | N'Cumpe | Namuno | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ011204 | N'Gapa | Mueda | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ071901 | Nacala | Nacala | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ072002 | Nacala-A-Velha | Nacala-A-Velha | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ050802 | Namaacha | Namaacha | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ072203 | Namaita | Rapale | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ111403 | Namanjavira | Mocuba | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ070302 | Namapa | Erati | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ071304 | Nametil | Mogovolas | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ071201 | Namige | Mogincual | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ070303 | Namiroa | Erati | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ011405 | Namuno | Namuno | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ071305 | Nanhupo Rio | Mogovolas | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ050604 | Ndelane | Matutuine | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ020603 | Nguzene | Chongoene | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ090802 | Nhamadze | Gorongosa | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ040703 | Nhamagua | Macossa | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ112201 | Nicoadala | Nicoadala | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ100403 | Nsadzu | Chifunde | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ101401 | Ntengo-Wa-Mbalame | Tsangano | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ011601 | Olumbi | Palma | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ050405 | Palmeira | Manhiça | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ050305 | Panjane | Magude | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ050702 | Pessene | Moamba | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ070702 | Quinga | Liúpo | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ072204 | Rapale | Rapale | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ050703 | Ressano Garcia | Moamba | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ050704 | Sabie | Moamba | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ090103 | Sofala | Buzi | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ100203 | Songo | Cahora Bassa | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ091003 | Subwe | Maringue | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ100102 | Ulongue | Angonia | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ081904 | Unango | Sanga | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ041202 | Vanduzi | Vanduzi | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ020302 | Vila Eduardo Mondlane | Chicualacuala | Nome sem correspondência única sob o pai resolvido |
|
||||
| MZ021105 | Xhalala | Mandlakaze | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ050406 | Xinavane | Manhiça | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ101502 | Zambue | Zumbu | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ040502 | Zembe | Macate | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ050605 | Zitundo | Matutuine | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ020903 | Zongoene | Limpopo | Pai sem correspondência; não associa por nome isolado |
|
||||
| MZ101503 | Zumbu | Zumbu | Pai sem correspondência; não associa por nome isolado |
|
||||
|
||||
## Lacunas de cobertura além das correspondências
|
||||
|
||||
- O exemplar identificado não contém polígonos próprios de localidades; não inventar nem duplicar territórios.
|
||||
- Os 1.990 territórios cadastrados e estes581 elementos têm níveis/âmbitos distintos; um não é o denominador do outro.
|
||||
- Geometria disponível, acesso autorizado e desenho funcional em cada consumidor são critérios independentes. As361 geometrias permanecem internas em QA; a importação não as publica.
|
||||
- O total previsto no ativo é361 somente se a prévia renovada conservar estas correspondências e zero conflitos. Não repetir instalações nem considerar `ready=true` uma importação.
|
||||
Binary file not shown.
@@ -0,0 +1,98 @@
|
||||
# Execução do percurso InvestMoz — I0 e I1–I3 em QA
|
||||
|
||||
## C37 — MFA QA recuperado; cenário A visual por retomar
|
||||
|
||||
**C37/P0 — falha bloqueante do cenário A reportada pelo utilizador, corrigida por código/HTTP/persistência QA; retoma visual ainda pendente.** URL: http://127.0.0.1:18097/investimentos. Alvo real confirmado antes de qualquer escrita: `desk_restore_20261009_174726_test:55441`.
|
||||
|
||||
Stack completa dos erros20:39:16/20:41:52 (68frames por ocorrência) retida sem argumentos em mfa-original-stack-redacted.json. Falha em TwoFactorLoginRequest::hasValidCode() ao desencriptar users.two_factor_secret da conta13; PreserveFormFeedback apenas chama o próximo middleware. A conta restaurada não é sintética: secret/recovery abrem com a chave do .env de origem, mas não com a chaveQA. Cache de configuração não carregado; source cache também ausente. A ferramenta de preparação do percurso antes não fixava APP_KEY e podia herdar origem. portal-qa-environment.php centraliza a mesma chaveQA já existente entre preparação/web, força alvo/restauro, configura caminho QA de cache separado e recusa cache não reconciliado. Não gera chave, não usa chaves ativas como fallback nem modifica .env/cache ativo.
|
||||
|
||||
Duas sessões pendentes da conta13 removidas exclusivamente do diretório de sessões QA, após guarda do destino e paths. Original conta13 preservado byte a byte pelo hash da linha; nenhuma chave/MFA ativa ou da conta13 alterada. Novo investidor sintético QA: actor18, inscrição normal pelos endpoints Fortify (confirmar password→enable→secret-key→confirm), oito recovery codes, sem injeção direta do segredo nem desativação de MFA. Dados de acesso/segredo somente em investor-mfa-qa-private.json local privado; não exportados aqui.
|
||||
|
||||
POST /two-factor-challenge com DecryptException agora invalida desafio/sessão e retorna422 com mensagem controlada em JSON ou redireciona ao login com erro visível; nenhuma autenticação. Negativas reais de secret/recovery verificam401 após erro e remoção do desafio. A resposta HTML/Inertia contém a mensagem, sem ser prova de renderização visual. Logs controlados incluem apenas referência e ID pendente; as provas não exportam Cookie, X-XSRF-TOKEN, OTP ou corpos.
|
||||
|
||||
No mesmo servidor18097: login/MFA/logout/nova sessão passaram. A retomado por HTTP em `/investimentos/413ba1f6-bdf6-402a-a561-c4e2d4098d1a`: criação→logout→nova sessãoMFA→recuperação→aplicabilidade semterra/semfinanciamento→draft próprio→resultado→Balcão draft→tarefa concluída pela gestão→nova sessãoMFA recupera tudo. Gestão não recebe resultado financeiro privado. Função efetiva do dossier recalcula20unidades/0.00 a partir do resultado recuperado. QA atual5instâncias/95etapas; originals anteriores preservados. Esta conta não vê os A/B da outra contaQA.
|
||||
|
||||
Evidências: mfa-key-diagnosis-qa.json, mfa-session-invalidation-qa.json, mfa-persistence-qa.json, mfa-http-qa.json e mfa-auth-qa.xml. Os17 ensaios autenticam ou recusam os percursos concretos; não substituem interface. Fingerprints passam a incluir bootstrap/Fortify, invalidando ready/provas anteriores para ativação. `integrated_ui_ab_passed=false`, `candidate_revision_fixed=false`, `activation_ready=false`; nenhuma escrita ativa. Mesma matriz3354requisitos/5830origens, sem fecho amplo novo.
|
||||
|
||||
## Lote I0 atual — importação autenticada e operações documentais reais
|
||||
|
||||
**QA atual: http://127.0.0.1:18097/investimentos.** Porta18096 anterior não usar; erro PHP/Symfony no arranque com GD, antes do cabeçalho QA. Processo isolado recuperado com GD e OPcache desligado, sem mudança do PHP ativo. Base `desk_restore_20261009_174726_test:55441`, sessões próprias; SuiteCRM/AI externos desativados. CUA permanece sem apps/browsers. Nenhuma observação visual nem escrita ativa.
|
||||
|
||||
**Mesma matriz:**3354 requisitos/linhas canónicas,5830 ocorrências preservadas; parcial: 3198 requisitos/5380 ocorrências; não implementado: 146 requisitos/440 ocorrências; dependente de decisão concreta: 4 requisitos/4 ocorrências; implementado mas não ativado: 1 requisitos/1 ocorrências; concluído e demonstrado: 5 requisitos/5 ocorrências. Nenhum requisito amplo fechado por este lote. `candidate_revision_fixed=false`, `integrated_ui_ab_passed=false`, `activation_ready=false`; não fixar candidata antes dos resultados manuais e correções.
|
||||
|
||||
| Requisito | Correção/prova concreta deste lote | Estado |
|
||||
| --- | --- | --- |
|
||||
| AUD-GEO-02/03, OPS-01 | C30: GET/POST `/management/territory-geometry-import`, POST `/{batch}/reverse`. Fontes retidas/edição/hash/scan; nomes exatos+pai+país, conflitos, preview vinculado ao ator/estado, MFA, `geo_write_receipts`, `audit_events` append-only; nada publicado. HTTP real com login+TOTP, três níveis,361 reutilizadas/0 novas; replay e reversão de lote de reutilização mantêm361. QA de testes demonstra criação e reversão de lote novo, preservação de histórico e recusas de alteração/publicação/FK/scan expirado/MFA/alvo não QA. | Código preparado + API/persistência QA; interface e ativo pendentes |
|
||||
| AUD-SCAN-01 | C31: nome da rota assinada corrigido para `management.opportunity-image-preview`, mantendo URL. Servidor web QA gera3WebP320/640/1280; PDF+PNG+3derivadas têm cinco scans reais ClamAV1.5.4, clean/hash próprios, cifragem Laravel e classificação restricted; downloads reais comparados, assinaturas ausentes403 e outra conta403. QA de testes prova quarentena423, scanner inconclusivo e retry real, substituição sem apagar original, versão409, exclusão/restauro e adulteração409. | Operações de oportunidades demonstradas por API/persistência; apresentação visual pendente |
|
||||
| AUD-LIB-01/SCAN-01/DESK-02 | C35 corrigiu erro500 ao omitir data/emissor opcionais. C36 corrigiu recuperação404 de originais cifrados: os consumidores comparavam o hash do ciphertext com o original. VerifiedDocumentBinary reutiliza decifragem/integridade sem cópia pública nem alteração de permissões. PortalRealDocumentConsumersTest usa ClamD real: biblioteca privada→scan→classificação→publicação separada→download; versão409/dedup/404hash. Balcão testa upload/confidential→scan→download, dedup/403estranho. Original canónico cifrado é reutilizado sem duplicar documents; downloads na gestão/Balcão/biblioteca e view PDF devolvem os bytes originais; antes de publicação/adulteração404. | API/persistência QA; bytes de preview PDF verificados, renderização visual pendente; sem publicação ativa nem fecho global |
|
||||
| AUD-UI-01/DASH-01/SIM-01/DESK-02/GUIDE-01/CRM-01 | A/B repetidos por HTTP no servidor recuperado; nova sessão real, IDs/drafts próprios, recuperação, aplicabilidade, resultado20/0 e20/70000, Balcão e tarefa concluída enquanto terra aguarda; outra conta/contexto recusados. | API/persistência QA; cenários completos na interface pendentes |
|
||||
|
||||
**Correspondências:** províncias11→9/2; distritos159→120/39; postos411→232/179. Esperado refere o exemplar2019, não um cadastro atual certificado. Maputo e Maputo City são as duas pendências provinciais. Distritos:9 por pai não resolvido/30 por nome; postos:86 por pai/93 por nome. [Todas220 lacunas por nome/código/pai/causa](correspondencias-cartograficas.md). Sem polígonos de localidades no exemplar; nenhum limite equivale a implantação/DUAT. Aceitação da fonte oficial preservada.
|
||||
|
||||
**Evidências:** `geometry-auth-http-qa.json`, `resources-real-http-qa.json`, `document-real-persistence-qa.json`, `import-document-real-qa.xml`, `investor-path-http-qa.json` e `investor-path-recovered-calculations.json`, no acervo privado. As15 verificações dirigidas são inventário:4 importação,2 operações documentais reais,5 scanner/negativas e4 recursos com fixture. Não substituem prova por requisito ou interface.
|
||||
|
||||
**Ainda não verificado:** interface de A/B, cada formulário/estatística, cada seletor/mapa e operações documentais visuais. Biblioteca/Balcão têm agora os ensaios reais específicos acima; PDF view tem prova de bytes/MIME/CSP, mas renderização, importação em lote, todos os tipos/documentos/perfis e partilhas/imutabilidade por consumidor continuam pendentes. Os ensaios de compatibilidade/schema e fixtures não constituem prova ClamD real. ClamD real demonstrado nesta sessão é distinto de arranque após reboot/manutenção de assinaturas e GD no PHP ativo, ainda pendentes. Workflow e contratos especializados permanecem abertos; sem jornadas educativas novas.
|
||||
|
||||
## Continuação atual — sessões reais e evidência por consumidor
|
||||
|
||||
Prova posterior ao lote inicial abaixo: investor-path-http-qa.json executa login/logout e novo cookie jar/login no servidor QA18097, recupera A/B por ID, aplicabilidade, draft próprio, resultado congelado, pedido e tarefa concluída. Outra conta403/draft404 e contexto cruzado403. A mostra necessidade esperada0; B70000; ambas20unidades nas fórmulas. Na QA web existem4instâncias/76etapas, incluindo2fixtures de setup e2HTTP; os38steps dos testes abaixo pertencem a outra base isolada.
|
||||
|
||||
País/origem/filtros/estatísticas foram reforçados por formulário; interesse em negócio público e jornada têm agora provas específicas. C27 liga consumidores de mapas; build/TypeScript passaram. C28 corrige a contagem fixa no preparador. Ver cobertura-percursos-i0-i3.md e roteiro-manual-qa-i0-i3.md.
|
||||
|
||||
Interface ainda não observada; I0–I3 permanecem parciais. Provas anteriores de backup e hashes são históricas; renovar depois da demonstração visual. Nenhuma escrita/ativação ativa autorizada; instalação de schema, flag e importação/divulgação cartográfica são atos separados.
|
||||
|
||||
## Histórico do lote inicial — limites da evidência então obtida
|
||||
|
||||
| Requisito existente | Falha/capacidade tratada | Evidência concreta | Código / QA / ativo |
|
||||
|---|---|---|---|
|
||||
| AUD-SIM-01, AUD-DESK-02 — C25 | Um rascunho corrente por conta impedia investimentos independentes. Criação e recuperação agora usam dossier autorizado; ID e armazenamento local ficam separados. Conta ou contexto indevidos não dão acesso ao snapshot. | `InvestorPathTest`: mesma conta, A/B, dois drafts, replay, conflito, recuperação por contexto, conta terceira negada; testes antigos de anónimo/claim preservados. | Preparado / API e persistência demonstradas / sem ativação |
|
||||
| AUD-DASH-01, AUD-UI-01 — I1 | Painel do investidor composto e página do dossier: projeto recente, pendências, documentos, resultados, tarefas, próxima ação e acesso direto às ferramentas. Gestão conserva as suas funções. | Resposta Inertia verifica componente/19 etapas/5 fases, versões e separação investidor/gestão; TypeScript e build. | Preparado atrás de flag / dados do painel verificados / interface visual pendente |
|
||||
| AUD-DESK-02, AUD-SIM-02 — I2 | Ferramenta abre no contexto, devolve evidência financeira por ID/versão/hash; descrição já preenchida no pedido Balcão com evento de proveniência. | A/B API: guardar → GET → associação idempotente → nova sessão HTTP → resultado recuperado; 20 unidades e 70.000,00 pelas fórmulas existentes em teste frontend. | QA demonstrada para este percurso / prefill transversal ainda parcial / ativo inalterado |
|
||||
| AUD-GUIDE-01, AUD-DOC-01 — I3 | Definição imutável das 19 etapas e cinco fases ligada à instância; aplicabilidade sim/não/desconhecida, fundamentos, dependências por ação e distinção entre preparação, conferência interna e ato externo. | 38 etapas para A/B; preparar S18 permitido enquanto S17 falta, operar recusado; versões antigas409; conclusão/decisão externa sem evidência recusada; mudar ramo preserva estado/fundamento anterior. | Extensão instalada somente em QA / interface pendente / ativo sem colunas novas |
|
||||
| AUD-CRM-01, AUD-DESK-01 | Tarefa independente aceite no CRM existente, atribuída ao responsável e concluída enquanto terra aguarda; resultados recuperados pelo dono. | APIs existentes de tarefas; permissões, versão e evento. Nenhuma chamada externa nos cenários. | QA demonstrada / gestão visual pendente / nenhum envio externo |
|
||||
| AUD-SIM-02 — C26 | Recusa de rollback do núcleo não pode desativar RLS antes de detetar dados/versões a preservar. | Regressão inicial recusou segunda definição; ensaio novo confirma recusa e igualdade das políticas RLS antes/depois. | Corrigido no código / QA demonstrada / sem rollback ativo |
|
||||
| AUD-GEO-02/03 — I0 | Geometrias oficiais privadas agora também na cópia QA do percurso. | Importação 9 províncias +120 distritos +232 postos; repetição zero novos, 361 reutilizados. Originais/hash/scan/edição INE2019 preservados. | QA povoada / camadas públicas e visual por consumidor pendentes / ativo0 geometrias |
|
||||
|
||||
As provas numéricas finais e fingerprints ficam em `storage/app/private/investmoz-v2/portal-audit/investor-path-evidence.json`; logs/JUnit ficam no mesmo diretório. Não substituem a aceitação de cada cláusula da matriz.
|
||||
|
||||
## A/B preparados para demonstração na interface
|
||||
|
||||
QA: `desk_restore_20261009_174726_test`, PostgreSQL loopback55441; servidor `http://127.0.0.1:18096`. Conta sintética `investor-path-qa@example.invalid`; credencial de fixture no script QA, sem alterar credenciais reais.
|
||||
|
||||
- A: `/investimentos/411a1e77-7dcd-4b74-bb51-14beb1ac2b95`; sem terra e sem financiamento externo; ramos de preparação dispensados com fundamento.
|
||||
- B: `/investimentos/41fc4b20-ff1e-408c-81d5-67ca7a915bf5`; com terra/financiamento; preparação financeira independente da informação do terreno.
|
||||
|
||||
Fixtures persistidas são material de ensaio, não demonstração visual. O teste de servidor cria novos A/B, limpa a sessão HTTP, recupera dados com a conta novamente resolvida, prepara apoio e acompanha tarefas. Falta realizar na interface: criar → guardar → terminar sessão → entrar novamente → alternar A/B → usar ferramenta → guardar resultado e voltar → rever/submeter apoio interno → responsável acompanhar → dono recuperar resposta. Incluir conta terceira, responsável sem acesso ao draft privado, erro422/conflito409/412 visíveis, teclado, desktop/tablet/móvel e mapas.
|
||||
|
||||
O navegador continua a devolver `apps=[]`, `browsers=[]`. O servidor QA responde; não foi demonstrado clique, foco, mapa renderizado ou recuperação noutra sessão de navegador. I1–I3 permanecem parciais.
|
||||
|
||||
## Compatibilidade e reversão
|
||||
|
||||
Reutilizados: `desk_cases`, `investor_accounts/investors`, `investor_journeys`, `journey_steps`, `questionnaire_versions`, `tasks`, `desk_events`, `audit_events` e o simulador existente. Nenhuma tabela paralela ou migração dos IDs antigos. `desk_cases.simulation_id` é a ligação canónica; não se criou uma segunda associação para o mesmo draft. Novas entradas financeiras congeladas são evidência versionada, não cópia mestre editável.
|
||||
|
||||
Migration `2026_10_09_190000_prepare_investor_path`: duas colunas (`investor_journeys.path_definition_id`, `journey_steps.path_detail`) e uma definição imutável v1; zero conversões automáticas. Roteiros E0–E11, orientação de sete grupos e roteiro de 14 atividades mantêm os seus códigos/fontes. Cada investimento novo acrescenta um dossier, uma instância e 19 etapas; nenhuma instância é criada por instalar schema. Dados pessoais/evidências em payloads cifrados; ler dossier não concede propriedade do simulador.
|
||||
|
||||
Ensaio em cópia restaurada: 167 tabelas públicas comparadas sem alteração dos registos originais; reversão vazia e rollback transacional verificados. Definição publicada não é apagada pelo `down`. Com fixtures já usadas, o `down` recusou apagar dados. Repetir preparação de fixtures conservou os mesmos IDs; não reinstalou a extensão.
|
||||
|
||||
Reversão preferida: desativar `INVESTOR_PATH_ENABLED`, manter dados/versões/eventos e URLs anteriores, retirar os novos pontos de navegação. Depois do uso, não eliminar colunas/dossiers/decisões/resultados. Restauro integral exige backup novo, teste em cópia isolada e reconciliação de tudo o que foi criado depois dele; nunca executar restauro sobre dados posteriores sem esse inventário.
|
||||
|
||||
## Plano consolidado — ainda não autorizado no ativo
|
||||
|
||||
| Ordem | Alteração | Dependência/efeito e contagem prevista | Reversão/condição de fecho |
|
||||
|---|---|---|---|
|
||||
| 1 | Correções de código I0/C25/C26 e interface I1–I3 | Validar a versão final; preservar URLs/perfis. Flag do novo percurso desativada no ativo. Não requer instalar novamente Balcão/Bolsa/gestão básica. | Reverter código novo e manter dados; backend/UI A/B completos antes do fecho. |
|
||||
| 2 | Extensão de recursos de oportunidades030000 | Mecanismo autenticado existente, migration pendente uma vez; backup/restauro, compatibilidade e fingerprint novos. Preparar anexos/derivadas sem publicar automaticamente. | Guardas de dados/ficheiros existentes; ClamD/GD limitam operações afetadas. |
|
||||
| 3 | Extensão do percurso190000 | Reutiliza `/management/balcao-install` e instala só migrations ausentes. +2 colunas/+1 definição; +0 dossiers/+0 etapas por instalação. Prévia exige API/persistência, A/B visual, backup/compatibilidade da versão final. | `down` sem uso preserva definição; depois do uso, desativação e preservação. A autorização atual não inclui este ato ativo. |
|
||||
| 4 | Configuração de disponibilização do percurso | `INVESTOR_PATH_ENABLED` é separado da instalação; não é ativado pelo schema nem por `ready`. Disponibilizar só após aceitação UI e autorização ativa futura. | Flagfalse; sem apagar entidades/decisões/eventos. |
|
||||
| 5 | Importação cartográfica oficial privada | Lote separado, prévia autenticada/hash/scan/correspondências únicas. Previsão361=9+120+232 somente se base ainda0 e sem conflitos; +0 territórios/+0 pontos ou relações inferidas. | Retirar disponibilidade pelo mecanismo auditado, preservar origem e versões. Não adaptar o CLI QA para ativo. Mecanismo autenticado específico ainda falta. |
|
||||
| 6 | Disponibilidade cartográfica por consumidor | Classificação/divulgação e camada por operação, aprovadas expressamente. Cadastro e importação não autorizam publicação nem representam local de investimento. | Reverter a disponibilização, manter os originais. Aceitação de seletor/mapa individual na interface. |
|
||||
|
||||
Nenhum `ready=true` histórico certifica esta versão. As mudanças invalidam os fingerprints/provas antigas de recursos e Balcão; devem ser renovados. O guard da instalação do percurso exige A/B visual e recusa a execução enquanto essa prova falta. Nenhuma instalação ativa, importação ativa ou alteração de dados ativos foi executada.
|
||||
|
||||
## Lacunas mantidas no backlog
|
||||
|
||||
1. A/B completos na interface, incluindo nova sessão, permissões e resultados apresentados. Provider de navegador indisponível; desenvolvimento/API não foram bloqueados.
|
||||
2. I0 transversal: países/origem/filtros/estatísticas e cada seletor/mapa conforme tabelas de cobertura existentes; esta entrega não fecha o requisito com uma pesquisa ou com 361 geometrias. Permanecem2/39/179 correspondências não inequívocas e ausência de polígonos de localidades no exemplar identificado.
|
||||
3. Prefill de todos os campos e retorno de outros consumidores; ligações a terra/financiamento com ações/evidências específicas, além de contexto administrativo. Resultados financeiros locais são recalculados pelas fórmulas existentes a partir da evidência congelada; não são `simulation_results` fiscais nem decisão externa.
|
||||
4. Dependências legais/licenças/execução precisam dos parâmetros, âmbito e evidências aplicáveis. O conjunto inicial declara apenas dependências seguras exemplificadas; não certifica todas as regras legais das19 etapas nem cria aprovações.
|
||||
5. Workflow completo de oportunidades e contratos especializados preservados; não foram dados como concluídos. Novas jornadas educativas não iniciadas. ClamD mantém pendências específicas de arranque/manutenção e derivadas/GD web, sem bloquear países ou preparação.
|
||||
@@ -0,0 +1,587 @@
|
||||
"Exemplar/caminho","Bytes","SHA256","Tipo","Nota de leitura","Disponibilidade","Uso em cálculo","Situação jurídica/documental","Edição/versão identificada"
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\~WRL2550.tmp","451286","0ae1dc970cc219a57791483bf22f134b2fab1ff5a6d3cd98eba98a5737f23010","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\diagramas.docx","6005783","ece2c2edee8df625e712ff9f285df5c787378fa3477e466303b5a46ee0971c09","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\diagramas.docx#word/media/image1.png","1208097","1495ef144a048018723db1c0e11217fa14b4d7b14d8e65e32a3adeea23d08c4c","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\diagramas.docx#word/media/image2.png","1302649","fe235f3c808f5c0804023dd4c1a079310bb2806806933fa95519f923af759f34","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\diagramas.docx#word/media/image3.png","1155707","d791e296e6436c52e52d3d29954a83faffde2f8a1228ac48a0aee9753aafdb72","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\diagramas.docx#word/media/image4.png","1539","f2f900bc7dd199be5f3e037424a5daa0e2865b46fab8f5a24f9359df1594e144","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\diagramas.docx#word/media/image5.png","1180837","9e28b4fb57f6df624545f1ba63b778a7d5c92ea88dc5d4c6cddd97d1c9fe059e","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\diagramas.docx#word/media/image6.png","1134030","dfa0c37b886b5fd9df356f4b2f3c24a1199093abf8fc60dc2ed335e4bb68dce0","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\FICHA DE OPORTUNIDADE DE INVESTIMENTO.docx","96615","d52bc22b8646f64e5ddb70811793f7d8b46197f4665b6577c8b25b1910ab4768","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Necrologia.docx","53217","21612c9490cf1382e5c1d4499a10d785f8b9add70322132f32af63449c0f1010","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Roteiro de prestação de serviços.docx","16405","3710e58dad14e8bd6c6aa1eebcf1d21fadc391959681a9f0fa6a139355716fea","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\~$vos modulos.docx","162","076a465696c65ff00fce492da12479cbe10d1731e38ca12d3ebd4211111e0fdd","original","Can't find end of central directory : is this a zip file ? If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Guia para Identificação de Áreas e Corredores de Investimento.docx","104659","6e8fec17b7f6efa2cbaec46abb9c67b37693d350a5e3d540aa362a769ccd5ea0","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Guia para Identificação de Áreas e Corredores de Investimento.docx#word/media/image1.png","49813","c8b4bb1417aad29a159c3e5e9576e726a1d50aece731d8fc381238ff3a0f2b65","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\~$oposta de Arquitectura Integrada e Partilha de Dados do Ecossistema Digital da Tempo.docx","162","6ace089e8d5e3f734ec77f9e93cad87834ae58892871fa0b6f98586e5576bdd7","original","Can't find end of central directory : is this a zip file ? If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\conferencia\Agenda2025.ptg_.pdf","1064241","6b7b13eead5191bda3f0318941713dea16fc6d57bbc61ad6f1f3c9efa67672b7","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\conferencia\MARP.pdf","490336","4884bd925ddac14c1c490b822d4ebc391e121df6bb64cef4508ae713fdc59625","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\conferencia\PENSAR-MOCAMBIQUE-2025.pdf","21361335","d70450b6dc90370bd4a6730d2dbabc3ae1b33a6dd775de1b3b983744d497fae5","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\conferencia\2026-RNV-Report-Mozambique-1-1.pdf","5686850","305387a6def4f1646644a0a50dfd27bba4094d0639915b5371e403253230e8dc","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\conferencia\ENDE-2025-2044-vfinal.pdf","3667603","520dd8ec3924321f69d3d58466aec833cf321b007b31fc8dc7fd70bd49b0d42c","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\conferencia\RELATORIO-AGENDA-2026_July_02-final.pdf","1136956","9ffd1074a438d59c6978c8da36fa777abbb351a3c2039dac0fef118b3749ad87","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\conferencia\Apresentações\CMuendane_ConfInt2026-MPD.pdf","636021","708c5a38cf04438ce371f1a39ad2f5a13e0b78f3e45b86693f5a963959dac2ac","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\conferencia\Apresentações\JFerrao_ConfInt2026-MPD.pdf","781278","7debcaad44e8a2df8cba70256b519f4cbebb89454fbf3e5fe7ac0550e74297ae","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\conferencia\Apresentações\PLatilal_ConfInt2026-MPD.pdf","326252","8690da2f9ac9d00e3c826ca7119368c17e959b9ebb945e74427085c2be02d714","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\conferencia\PORTUGUESE-Mozambique-Special-report-2026-vf.pdf","6768008","c1452219bcb608fb4b0fd51f60eeb676d09b6ba867f43c3178466b01c0783c44","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\licenciamento BM\Capital social recomendável.docx","17137","3b86ae01cf839502792fb130eafdfca2a0a0b6cea10d7f445f972196de766ee6","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\licenciamento BM\Para a actividade de prestação de serviços de consultoria financeira.docx","53137","bcae28d5437bca81d6922678051424740e56db2fdb931fc7653966b6f04e2361","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\licenciamento BM\Consultoria e aconselhamento financeiro.docx","24096","5a1aa63b95f5fd45e874b20b7668ef18e715a0b8efe1fa86943784844d88442b","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\licenciamento BM\Minuta ao BM.docx","18441","96a2f0c56836193409e960362c8de72a28f266e73fac594a37aeb9c81f2baa67","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\licenciamento BM\REQUERIMENTO.docx","22496","e79179abbc20030dcbc6ee91bfdd74a7265419b2b5a473521b3ed2ae60674904","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Scan\Terras\Consulta\scan0001.pdf","140871","3c1143fd565d92403e0c175adfbea293afc3f187fd6a201ba26e1d45a998d2ca","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Scan\Terras\Consulta\scan0002.pdf","88860","b6a0ccac07eef71294089dde653f6ed3e600196b75836d69c0e99687e199d6cc","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Scan\Terras\Consulta\scan.pdf","174964","732ff341bbd4c0c05e8accdb6919fa6151d18e50e0c3ed0cd618a4fd69b9018f","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Scan\Terras\exploracao\scan0003.pdf","144995","f1f5778426d16fad122f1df32f40df1b2cd66f5c56ca41a9ea56499f10ed8d60","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Scan\Terras\exploracao\scan0004.pdf","150054","54ee525982c78450611a3c4b93f77ecc00493decdba4cf982bbc45e52de1cf01","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Scan\Terras\Formulario\scan0006.pdf","243123","a45ca527e0581b95939f0a35bf107bf78f24e183513e5ce4ad81c0fe6fec3e53","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Scan\Terras\Formulario\scan0005.pdf","286614","d994a036effb269a1bf808164518fc251458379cc15f1a4d5730e8bd746a9a37","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Uma empresa cuja atividade seja prestação de serviços de consultoria financeira.docx","29727","cf47dfd9686b1d9d8b13288d9b08f720d383cf69abe98f3dacc859c671b3e839","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatório de avaliação e melhoria dos sites da Tempo.docx","38778","ab8a7dc7fbc84bb6f3986b02f9d7cae687708fd501803bf468bc614e1d6ea48d","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Checklist para consultoria financeira.docx","34071","55d26f16a8da9cee38a5af23c4c4a3f8093d22da096a6d395e3303c218d893cc","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Revisão de Arquitectura, Dados, Segurança, QA e Produto.docx","20577","b30968b1ea37c14bdd6b4d069aaca66dd82cb8e38d2c3575923b23a23b5430a9","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Excelente iniciativa.docx","68066","4583386335ddabd88ad9c2910aa30990a4794d90002ea36cca587255d4a9282f","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal do investidor nova versao.docx","799591","3f5040c038fb57702e6cdfad31318730013f9831dd1def99a63df2a084354333","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal do investidor nova versao.docx#word/media/image1.png","708019","753b54d3bef8f345127bcfb3c5272a96c89a03b65436bfaff86cfd22b887a7b5","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V1\Protótipo — Portal do Investidor v1d.pdf","245701","80ff061f26ece6906cc61bb6f0e738d437a6e8524511b80c0f597a919041b0d7","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V1\Protótipo — Portal do Investidor v1e.pdf","215107","cd61f18a374a4d1124bc4a422396f77067f0b92ae18ac35ed3ff1bddcc6ae321","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V1\Protótipo — Portal do Investidor v1 6.pdf","239566","d7f27e01dc9b7369ed60de804ddb7b8c1b33011c00214f58d92742a2648937cb","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V1\Protótipo — Portal do Investidor v1f.pdf","253712","cb6dd9134ab2c1708bc7f746a5c8e4969ce7c2bf750b326cfb06449a21361914","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V1\Protótipo — Portal do Investidor v1 3.pdf","253712","7d4337a3eb78f71aeec818d9d5e0fc3c35aba5b16cbdd35fff2d731918eaab43","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V1\Protótipo — Portal do Investidor v1b.pdf","249702","c8b5505759bfb1beb28110cf0506903776e0da032e5f2cc5f69b32b23586488a","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V1\Protótipo — Portal do Investidor v1c.pdf","259985","f43ddc80836b8739c406b4e869ebe103732a7f1e37d6a44bc7657619f0959b45","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V1\Protótipo — Portal do Investidor v1a.pdf","273681","9b6abd4b188d8301e6d0edda8c9b576c4d6f058bafbe7be6e234e9cebda95565","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V1\Protótipo — Portal do Investidor v1.pdf","351770","c198b8b7cb2e1eee5227be0aada5193cc73435848ca1aa0a354752db73526722","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\aereas de investimento.xlsx","36868","92921856c0b89e22187ac4b370438dac6023c55dcf335b58f6e37d9dfd4086c3","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Reformulacao do portal do investidor.docx","799605","9dee08d0ebbbb262651a01ffc7e0ade97323664bda59fe8ce0b07ead82736ce1","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Reformulacao do portal do investidor.docx#word/media/image1.png","708019","753b54d3bef8f345127bcfb3c5272a96c89a03b65436bfaff86cfd22b887a7b5","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\DADOS cartográficos.docx","18479","42564bb1d940ca4746317a1c7eb0f81212b8ce5a1fe2a98f993bcdd5835c7130","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Protótipo — Portal do Investidor.pdf","239566","55124d6417821f0b0fd2ecf8dac40bc098fe9638cf3a281b338ed3643e6b85e5","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Reformulacao do portal do investidor.pdf","530948","6fa7029ac4beba6979ed08b33f5264ad4f05b73139d79692b03feae41cd21105","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Principaispetos da Lei de Investimento Privado.docx","47642","1a11706f2a63153791e85394f361ba2c7e67c671f738570e3e962824bce2a1a6","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Principaispetos da Lei de Investimento Privado.docx#word/media/image1.png","358","b09d2b50f5bc910bea7dae0125f4d85712072673f411faddbe983261542a7544","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Progresso do upgrade — 25 de Setembro de 2026.docx","19826","2e0441552afcabf084b6f9044457b3217823105cac748d9062b35f274a9f02ef","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\requisitos portal chatgpt.docx","70761","b83360bc1805480d176f346724e0a28f77b3affcba575e2edd2e08b641352642","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\upgrade do portal de investimentos.docx","1332169","471012abb0f56377956f4ab822fe3186e2561bee0471508a5d807091f2e0154f","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\upgrade do portal de investimentos.docx#word/media/image1.png","1137172","06b3fd98532ee4ed1d80ce3f1198fc794582577982cec1e173bbb41a81906452","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Unificação dos Portais.docx","41650","5b8f4e35c77f8376eb55d80e0b05826c2a754d76e285e2a697a98e87f52c482d","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\sites da tempo\Avaliação geral da página www.docx","48183","1a5e2ca2554b59c5ad484c6f2ddc5dd96a905d6a91fa37ebae1fcd92a7793828","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\conteudo local.docx","28720","5f8b2bff0ca00f2cd85b6fceb1972dc22fdb4a2624e51dff1b26d958f642494d","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Progresso do mercado de negócios.docx","18811","e6fb8b747ae21bdb741b620e48c4c3744a01dfc19bdb3e43bbc7ce7ed458ee89","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Protótipo — Portal do Investidor (Informação Pública) movel.pdf","367810","f321f8490cd25792ca034b32b5c9ee197c59c703bda0afc04cbe8cf65c57bf58","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Vamos criar uma versão do portal do investidor onde.docx","22443","1343b30014a2fa4bcf428d65b02d3985ba56c7ed477d7380348f8920b1cad6b5","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal v2\Protótipo — Portal do Investidor (Informação Pública) v2h.pdf","258241","e712b549b7dce6fb9b3f23148e4bbbe7400900740139d0b14c871d434a06b6b5","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal v2\Protótipo — Portal do Investidor (Informação Pública) v2i.pdf","220076","6f3bd3664394b85cc4d5d4bbd9bb17a78ec462af65d9a9e7ab6e945b2cf3bd4d","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal v2\Protótipo — Portal do Investidor (Informação Pública) v2k.pdf","214882","a5672e4078ff74b26307dd35488e16427c50bbadac99be31ad360377c9d55eff","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal v2\Protótipo — Portal do Investidor (Informação Pública) v2j.pdf","209176","1554440ab74ab98810c550b25370291e4d0c3c8eabf43a940acb2382a9da51ed","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal v2\Protótipo — Portal do Investidor (Informação Pública) v2m.pdf","235400","3307b93b078ffb270482bb8eb2365f71acd023d53204dc8f3dfaeff93087dff1","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal v2\Protótipo — Portal do Investidor (Informação Pública) v2l.pdf","219233","257fc4e938899a47da0090a96d2f5b401afe3e5ff981acc5d9f6d8ed5c4dbb7b","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal v2\Protótipo — Portal do Investidor (Informação Pública) v2a.pdf","418445","f10d866eac013a917eee7890117e30c687bbf402202ffa9a12732c2b92514b92","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal v2\Protótipo — Portal do Investidor (Informação Pública) v2b.pdf","270399","699f05745e6413132e4f0092cc903f702be31651bdf6436fa71d16a75e09b03a","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal v2\Protótipo — Portal do Investidor (Informação Pública) v2c.pdf","291689","590c366991383f36ba11c99da810aa07f84d50d257d3402332fb0fe1ab72b5f0","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal v2\Protótipo — Portal do Investidor (Informação Pública) v2g.pdf","247322","aa524c56eb1940c14575d8352497ed256a0aed24732eea2d3358a264d12cd2b8","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal v2\Protótipo — Portal do Investidor (Informação Pública) v2f.pdf","245144","53cb235137563ddb1cfbb0d7366f61d4c4844521f4d325eb40ebe8f68d24d3ae","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal v2\Protótipo — Portal do Investidor (Informação Pública) v2d.pdf","263586","a995e7c92e6a7bf19f04e7892e37d1771df2b810876f976b7d4c1cf5c56884a5","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal v2\Protótipo — Portal do Investidor (Informação Pública) v2e.pdf","222937","2c137bde9bf606887e395ead7c26fdf639af94a12865d556eb1a3767a2602375","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\projectos.docx","62841","f37afdbfd773befc742146f053de765a1682ea93123aa614947c1180f64d2013","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\integrar o SuiteCRM .docx","24325","79b04d446619f6dc9a3bd5e533ee4778bda196b9dff6bc228b365ba0e6c87279","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V4\Matriz detalhada de oportunidades por sector.docx","30331","73d7f7792631d144d69616061354b88fcbbedce825d0af533d5317ed34c8ccd6","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V4\Portal de investimentos v4.docx","1662261","a0438b98c56ce930453f3eb519a952b3274c01fc421b2a2b4c5a994e988a84bb","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V4\Portal de investimentos v4.docx#word/media/image1.png","1137172","06b3fd98532ee4ed1d80ce3f1198fc794582577982cec1e173bbb41a81906452","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V4\~$mulador fiscal.docx","162","e0180ad0d9fc11f260e4f3c5f49fc648f55aa18e9ef100925cc054414bfdefaf","original","Can't find end of central directory : is this a zip file ? If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V4\upgrade do portal de investimentos v6 programacao.docx","1658773","e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V4\upgrade do portal de investimentos v6 programacao.docx#word/media/image1.png","1137172","06b3fd98532ee4ed1d80ce3f1198fc794582577982cec1e173bbb41a81906452","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V4\upgrade do portal de investimentos -casos .docx","48412","b44ec86d313eee6790be68a829f43e00c21e191c16cb89b4f8c37dbddc26d0ba","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V4\correcções a introduzir no portal.docx","21538","bfb24adfdc43afac8492b30b6bb2b7c57d5a3d57c7cd36008d9fdd5a80cd7dc5","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V4\cartografia_moz.xlsx","841177","2c5728c46973866371139cb080b1b1837bb980a43ae91693f0b58f2263a6c455","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V4\simulador fiscal.docx","70093","55997917b3bd85727cffac880b6c46fc85a78fef6a005798b9a110a0bca60fd0","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V4\upgrade do portal de investimentos v1.docx","1338438","f70ce3075523c6278e00dce15b9c7acf2b690679e16959ae5f7d007e754cfc6e","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V4\upgrade do portal de investimentos v1.docx#word/media/image1.png","1137172","06b3fd98532ee4ed1d80ce3f1198fc794582577982cec1e173bbb41a81906452","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V4\upgrade do portal de investimentos v2.docx","1417663","51b8f0ad3296d1064a5c12b450874fc72640869f10a164319cd7f3153dd3a086","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V4\upgrade do portal de investimentos v2.docx#word/media/image1.png","1137172","06b3fd98532ee4ed1d80ce3f1198fc794582577982cec1e173bbb41a81906452","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V4\~$grade do portal de investimentos v4 programacao.docx","162","096add1ae344654e4bcfaf80cf0578da35022211d0937a11d4288b809cec2f4e","original","Can't find end of central directory : is this a zip file ? If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V4\upgrade do portal de investimentos v5 programacao.docx","1627296","edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V4\upgrade do portal de investimentos v5 programacao.docx#word/media/image1.png","1137172","06b3fd98532ee4ed1d80ce3f1198fc794582577982cec1e173bbb41a81906452","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V4\simulador fiscal v1.docx","142685","f038d338fa0247ddd70f9dd34e72b080f9b7c93acfc02aec0d433bca1ee606d2","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Portal V4\~WRL0388.tmp","81042","2bdddd284d9c728eb4c1d93a90dda11eda1d74640091b54ed14e0577c0d5ff4a","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\IA propostas.docx","38021","2ca6ea33195ae3715ec6823980b720ea011ade6716a9885ee32d69f808f0d529","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\codigo .docx","53404","d3b5424c916ca3a727992cfeb33cb9f03c7ad54d2bd6a4156c11f94bf048223c","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\backup\Reformulacao do portal do investidor 1.docx","388939","efd550fd2a9d2a21785d7b3c140d4608f1ba27c52f156e2709e9fbf388a1a569","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\backup\Reformulacao do portal do investidor v2.docx","403675","9f5719c8b0cf78855f727d980b77a8f9409fc7f93e303e25d355d009a07d5734","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\backup\Reformulacao do portal do investidor v3.docx","132293","626cae3d584658842ca36b658e7b5b3cc98d87036747e65b29274f0209734e5a","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\instalaçao investemoz.docx","15796","c74196f927250a35778ab5896e17567aa9689038b99850ab09659b9b7f2aa89e","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\MPD_Relatório Final do PII 26-30_2111.docx","5456742","bcbf8ec976100cc5e978aef54050c3e3e9d959b0d361fa80a788528a8e5049a6","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\MPD_Relatório Final do PII 26-30_2111.docx#word/media/image7.jpeg","545244","d98834afbd035360b025571e38d583b0ed5458afe7f88f0f646badeecbbc40f1","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\MPD_Relatório Final do PII 26-30_2111.docx#word/media/image1.png","2824071","bc81f42453ded18fb3836b665779ac9100d0f3c70d5b6a2505cc5240fad4b2d7","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\MPD_Relatório Final do PII 26-30_2111.docx#word/media/image2.jpeg","468173","c948779500880f5b541a49d96a64c7995e8a41fe5fed9d4514c609b3cceb0ffa","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\MPD_Relatório Final do PII 26-30_2111.docx#word/media/image3.png","91096","e4e3b71dd820cc3733ca0e7bed74be22418122affe1a1471d62a10a6ecb5ee17","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\MPD_Relatório Final do PII 26-30_2111.docx#word/media/image4.svg","6746","d5cd72d2a0f875881c47f2b48945ea54da1a284256da3c1e17d788946eabc3c6","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\MPD_Relatório Final do PII 26-30_2111.docx#word/media/image5.jpeg","678237","3358f74fd99dcd54449349a37e3bbc8010acc4904b6cfc516a9e7228b54590c0","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\MPD_Relatório Final do PII 26-30_2111.docx#word/media/image6.jpeg","538480","efc4716c0764b2adecc020d7c650e6f7725f8ddd2c670f3f471b6c9f50063a84","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Pratica-Portal-do-Investidor.docx","156864","b1173162e6cd0c4b5bc41dc224685cf0e50f1de36cd70f7bb1bc7a7dcc873f4f","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Pratica-Portal-do-Investidor.docx#word/media/image1.png","44266","4becafb4b86fbdcf74bb8f79272e3ba79be99435ca9e853c6a398cfb836b2d3c","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Pratica-Portal-do-Investidor.docx#word/media/image2.png","66716","ccc2bca23bf03dc49354f08dcf9ee341568ef08e3b106682fd7ef1ded5a77b04","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Protótipo — Portal do Investidor (Informação Pública).pdf","417543","c5d574c59fc0587ba8889125f775c88b690834d91125518e959b273a1cd4ce66","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\portal do investidor\Auditoria de cobertura dos requisitos — 25092026.docx","27257","071345e1cbca77810b96beece4d44e12c57242cf6cf99a6349ddce45affb9207","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\sectores.xlsx","10689","8e263ad5a450903e856ca0a2ca10770951638cf1b90dee59a31bf0c5e567357f","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Proposta de Arquitectura Integrada e Partilha de Dados do Ecossistema Digital da Tempo.docx","2392539","0c91bfa7a2ca1af99f8957597d6225c4e56567cea723ca8004e6661c4bd79513","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Proposta de Arquitectura Integrada e Partilha de Dados do Ecossistema Digital da Tempo.docx#word/media/image1.png","1036841","c189c22ba98ec837d9b8e934a904666b316371baa62132b59d6e49ac72a5f334","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Proposta de Arquitectura Integrada e Partilha de Dados do Ecossistema Digital da Tempo.docx#word/media/image2.png","1233132","ac02380189d8ecc388625eeb3737043c722fb35ae4128d3a7fb8508a39c3f466","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\recomendaçoes do CRM.docx","21697","427cd1df6fccd888e24e8c2dbfa81e2db86a4132fc24d7a618e09ed0f399e220","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Benchmark_InvesteMoz_revisto.docx","54060","7fffb2a6ba01ce605504896f65bb078e5f9f906fa399942ca9f4779889809617","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Vendas\vendas da Tempo.docx","62880","52c613bc4301d388d6cdedf90af5074ce2ef0e7d06a7166f25fb352cddd0e55a","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\prompt ZEE ZFI catalogo de invest.docx","81500","dbd59fd85026e8d2cd89a4666e2385191fc1cba376bb45b7425064c6deac8395","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\~$ompt ZEE ZFI catalogo de invest.docx","162","6d45cebdd4fb18b8ed43e6b54454804425810ad3b21312165aae25628795aa61","original","Can't find end of central directory : is this a zip file ? If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Fases de implementação e respectivos prompts.docx","20742","bf0a33961c3b0f68f057584fdd6c2b62266f617ad8a3cdff297e7294138b025d","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\prompt tabelas ZFI ZEE.docx","34492","22010ee3d77d91474912890640fb74c42f81bf20fe7ef416ee54a9018142e4cd","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Método para executar as recomendações do relatório e corrigir as lacunas.docx","29103","d57343711b38352901526e18945a6102f8aeabf377ebdc4eb135e89b5dac1783","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\novos\Prompt a serem aplicados .docx","17943","757551ae205520aa61c688a922a88e2004b7b70bc44db31d08d1d11b5ff7a24e","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\novos\Iniciar uma revisão funcional transversal do portal.docx","18499","99a85c7b7fbab720f958eadc5cc49c61a07c49eb1e45cd79c4b8492193710230","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\novos\Detalhar a arquitetura de integração do CRM com a IA.docx","19823","15415735923b3753e499d8789310dfcc6fa0222191f826cba002ec2d239e1a01","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\novos\Definir os campos obrigatórios das imagens.docx","20689","5c126b3551be81c27a8b8297cf20aea5f62868d0177e5312b37e6d04b0adbb28","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\Optimização do Catálogo de Investimentos do Portal InvestMoz.docx","19378","46f95f4ed8271fdd7aaa088bf861eb4617f16051f569980e76bccf5cbbfb3c6c","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\Plano de negocios\perguntas para o empreendedor ou investidor.docx","23887","27d06a797640e6cc5e1dae45ffc84822081cecc32565fc9c9a2a5bc9fd273458","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\Plano de negocios\Plano de Negocios template.docx","423661","d82b35417f3bb4436cc33bd96cc367a3592d88d9ac0e74d413d502ee0a454849","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\Plano de negocios\Plano de Negocios template.docx#word/media/image1.emf","146356","675a4fd6492451e600d249ef1602349ea1926f2912f30a243e9494da1a03971a","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\Plano de negocios\Plano de Negocios template.docx#word/media/image2.emf","118956","3130897bd1fb72233d1bec77d3da86fa92af2bc1440b2059b5b7183f6d23a2d8","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\Plano de negocios\Plano de Negocios template.docx#word/media/image3.emf","30908","c4c51dde4088e49b62e22cab8a8f6c9c9bf7c615c0315c6da1d90b1e89a9a1bb","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\Plano de negocios\Plano de Negocios template.docx#word/media/image4.emf","874048","cef9c9cbc48336475524dd2a044f80482ed62a7422e03568f61ec4b7a33b3ccf","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\Plano de negocios\Plano de Negocios template.docx#word/media/image5.emf","255104","1dc259f7113bd5ff47af5cf4efffcdfb8e719973df714f3e31114e5a5380526c","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\Plano de negocios\Plano de Negocios template.docx#word/media/image6.emf","170372","8f4fe8e4c6cbc331bacf91595533cfb87b0edbdf05ae268a2ed9c7edaead1f21","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\Plano de negocios\Plano de Negocios template.docx#word/media/image7.emf","136852","2fd409005f2e33ca011be5d9ff7aa460c0c54c5f40a2b9093561b7306ae49a2f","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\Plano de negocios\Plano de Negocios template.docx#word/media/image8.emf","216420","247da53a98e039cdcc2eece983bd2c4f1c283990fd641fefe3c5ec738997ff76","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\Plano de negocios\Plano de Negocios template.docx#word/media/image9.emf","99936","fbfebba12507d917e4e57a1f7e29e71a7bafe0cc69ac20c2da6de967ede2087b","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\Plano de negocios\Plano de Negocios template.docx#word/media/image10.emf","213556","8841a3576a2f4a62dafe0d5aa495d215386372ae1c4c82cfe5b0968841a90edb","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\Plano de negocios\Plano de Negocios template.docx#word/media/image11.emf","84940","7cbd43169ab16ef7ef00f85a50b8da774660753305870c8dd807d848ab8c1f56","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\Plano de negocios\Plano de Negocios template.docx#word/media/image12.emf","271360","4c918c38f44d7af0ff07945f1a4f0137b0d56016a47f43a67fdeede8b3cea53f","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\Formulário de registo de ZEE e ZFI na InvestMoz.docx","25178","9de3ad1a27c040365d3f688ed178cc0994cfa29014c65ec28589b2e76e4068b4","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\Recomendo que o Simulador Fiscal do InvestMoz.docx","148831","faf42f9b69c64291f1ec9be268e912bbe964fad9651e30f3467b6384e4ef5258","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\formulario para publicar uma oportunidade.docx","23372","cb1a117ad5e33e1117c4601ecbb43a7b51c1248df654f0c157b4fa593b55fdb9","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\~$rmulario investidor etapa 9.docx","162","5cce0235d6093310a048fea6e95053b544a46485c9408658e679729d282346f4","original","Can't find end of central directory : is this a zip file ? If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\Melhorar o simulador da investeMoz para utilização pública e empresarial.docx","25831","f3116bf51b04216f9f524f5d024288c9a2c04ba0c79a284b86a808c6808940a8","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\novos formularios\Especificação do Formulário de Cadastro de Oportunidades de Investimento — InvestMoz.docx","320004","9f173ed3024d2beddef7888b692d8b81fc5e4700249955f2bae9bdd2eb2be504","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\Formulário de registo de clusters na InvestMoz.docx","22723","e1a546e7e2d6996b7f92730e6c1421dd6faaef64a45970a30dd5770f91035e4f","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\Requisito Consolidado do InvestMoz.docx","20847","44295a85c3ffb8568ae4c496167fd5d79381d44b0724f4e11ba6e471cf4e1ab9","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\formulario investidor.docx","55430","380df6e0c7236ef208df93b4a1db033db71c04033ee131c7ab98668adf677f17","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\Restauro do portal.docx","44491","12a297f80796c6fd753bc385117016a8f86940312fbf380d52ac25bc403e2210","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\oportunidades de negocio reformulaçao.docx","22890","11bded2839398f8de4f10d1f653200979eb29b32735417f2e380d92d6109e3a5","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\formulario investidor etapa 9.docx","55432","154f96a543febd6b9be51dd26025048d13e7e0efdf51ce88770d2b561891fc13","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Formularios\Zonas Económicas Especiais e Zonas Francas Industriais de Moçambique.docx","22246","41093a37ed1265870a3f4e0674ac7218ac4b7bcd7047ef8d927b69750b9f4f50","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Prompt de Validação da Actividade Realizada até ao Momento.docx","26196","827a850ccec7616b6033754869042f9a2ccd63b496b60e253918584ef913a52f","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\Matriz detalhada de oportunidades por sector.docx","30061","9f52c797dff6f7adf1904efd6e15aaa8f552b7443e57269533c39b428c20e9b0","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\Integração de ZEEIntegração de ZEE, ZFI .docx","24398","086b0468934443d48aebe6707843d481faeb323e78b161a2f5af0c2283217773","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\parques industriais e zonas francas.docx","27152","c5a6945239ea9ca5fab18510fe15e33deeffe8fec72d811f5a639c7388fdcab3","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\Implementação da CAE na investeMoz.docx","18546","ed71465abc672d84471117f710c5179160815d3a02c1c121bd43c915bdab38eb","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\DUAT.docx","25817","9453ba3bcffab0132a1996aeb26d0048cbbb6a3b52a9d0b6a5f7a44129a553f9","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\Prompt mercados existentes.docx","444929","b46d377c5e98268110b64851fd9f1705a413bec9ae7a4eeb4c9c0f2d4160801e","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\Prompt mercados existentes.docx#word/media/image1.jpeg","383819","a23b342fab66e292cdbded2e543dc29c70ea0a2e01cd5c3f0da804a6bb81291a","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\tabelas a implementar educacao.docx","29789","8471f5f41f5113ad779684f6dc0d62099f130ff08a4cfc74265dc25afdf2d693","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\Prompt mercados existentes v1.docx","466730","3bddd804585cee55b6d22fb49d551f13da1b4ddaba237bc5d34dcf85eb57814d","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\Prompt mercados existentes v1.docx#word/media/image1.jpeg","383819","a23b342fab66e292cdbded2e543dc29c70ea0a2e01cd5c3f0da804a6bb81291a","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\Base de referência do directório empresarial.docx","18391","7e4f6dd21185ea69560907edd119f318b91ec4f156b693bf945d17954017bec1","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\prompt de gestao de educação.docx","52637","94ea9a82cddc6e4e265d630f53a464d69a294e93b237b1ab395c62517bf89040","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\Complemento consolidado — Criação de empresas e minutas de contratos sociais.docx","20050","b20c6517784b6d44aa22beb67748d3f3b224f58c60a7dcb378a185669c2c543e","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\Requisito consolidado — Ciclo de vida da empresa.docx","19453","c027dc23895dc743dee65dbc6ab156177226087c2770f63c16bef56219358d36","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\Complemento consolidado compra e venda de empresas.docx","19903","bb216f277efc168910d80f32bafcd7649e53f7c72ce4d1f11cf7f523ac7521c5","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\Prompt consolidado — Melhoria dos ecrãs do InvestMoz mantendo as tecnologias existentes.docx","26653","ac6c720d00913c38fd1fabc6114b73580efd0045cb9b8ab32126df6eb0eaa8b1","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\Prompt de Implementação da Cartografia.docx","23758","467f4dffffac685a4c2f9e67c844b3c5b9e8759f6dc593723c73242f4e0f1818","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\Perfis provinciais e contexto territorial da investeMoz.docx","18558","4ea5eb0bcb3d77cd2623e4fa47ea39838398e9355e2c94400ed590007f1d53b4","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\prompt obrigatorio.docx","17749","b0845167a4c94cc0852b7dc569bc69ac30b472cfecda8f8416d1f7fd1cf7d672","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\~$OMPT Competências e Oportunidades Educativas.docx","162","8618266de24e02c06c049b850f55b03a965145e664175a6fec70167a73e9b7ac","original","Can't find end of central directory : is this a zip file ? If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\Formulário de registo de clusters na InvestMoz.docx","25760","31828090185b73dd8594835dd6f850e312a30b824ec9ce593218d3d0eef30b27","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\PROMPT Competências e Oportunidades Educativas.docx","110812","5da580e3e692a3d9e105c1ad98bfa745acdc5db40dec3491f8baa73f98460198","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\Implementar o módulo de cartografia.docx","880118","5159afe652cd598520f22c75aa02a3b1e9a51a78b0a29a1188a66363f720feb3","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\Implementar o módulo de cartografia.docx#word/media/image1.emf","17864","66b170a85568efaa3286e73ec1cd707ae976f42a5487c7978dba0f910e7228e2","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\Implementar o módulo de cartografia.docx#word/embeddings/Microsoft_Excel_Worksheet.xlsx","840317","b4544df3edce037a269055be2215b2045917ed372dcf04948e2ec16f95e4b280","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\Prompt — Integrar a lista de países nos formulários do InvestMoz.docx","22105","cf7b024ee6401c710662c6b7c310e30f50791729e9f74bccdbf72bedaeba6ea1","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\Prompt — Incorporar projectos âncora e investimentos do PII no InvestMoz com rastreabilidade.docx","24323","d63e63a5a03275170c6d3037b6c3c17d986ced9c791fcc2d754ff6e3ad4b7730","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\Revisão obrigatória simulador.docx","19879","22b7da3b9135c32f392ae0363f3b659242872f12096e760453dc9cd01f5c1ab7","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\oportunidades de negocio reformulaçao.docx","22888","8506a1583541cb8db32df9691d2e994aa3bebf99e2e700631c670c056c03fbf3","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\Integração dos parques industriais e ZFI no InvesteMoz.docx","24372","640cedda8dcb21651fb1021baecf00b887276a219c528e8aff04f1397831163b","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\Integração das referências de oportunidades de investimento.docx","18441","6803ef863bc63c7b6e4be5398307a7238f057504def841e7d12863f9a437e3b3","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\por executar\Modelo de Dados Geográficos.docx","48773","408815d07b9ad63a65daef15cc2a29d58f85fbe56af0d167914c1be0389ca0e1","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\cartografia_moz.xlsx","2235715","1e36c769c4767420b10f1ff5ee0c2955cdb1b03c98179c5cad549e832ffb1f15","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\prompt CRM.docx","29822","8a039779c58d036bb8bfb974e4374086c9afae31fde3b0d6b6e6a1379ae680f9","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\realatorio de auditoria.docx","22314","6e2876d13d8c06db17aff1f2284eb0f298c558a9000fdf3e738e02beecb1635f","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\PROMPT Competências e Oportunidades Educativas 1.docx","36189","183bfb8860d2bcb1af1bc9b897deeb98ba789fe9c7ecc08e1ec63e87d0e25663","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\~$ompt CRM.docx","162","e815230666b07ca9e6120d2f77bbdcb3b334892f2857b6fc8b825b6a8166d856","original","Can't find end of central directory : is this a zip file ? If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\revisão indica que vários prompts já foram parcialmente implementados.docx","21552","4e4fc9949eb8218dbc01c922efb184d906409c41a8290f4d984b089df00d8aa6","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\PROMPT Competências e Oportunidades Educativas.docx","55730","a8b37ee54ac5ebe8f22238bfe46b011a3d385a593601088a0514efc93d72cb69","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\prompt inteligencia arteficial.docx","34436","769761caee9e4c9b4ced1a71d877b40f3de7c6721c9d85bf6a53c05197cf2370","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\prompt dos ecras.docx","42439","ef26857a139de66e25ee43d3a49ab5dc3e6d4b1f2c2eeafcb3579b74261538ae","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Pacoe tecnico.docx","30860","4c50196c21e1add220b423fe5fa70fdc00f65332872566ec49b1c8d3c5925ac1","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\~$ompt inteligencia arteficial.docx","162","58af9455e09420443de9805cbf484b94721e299fcb75cb02cd12823fc9cac356","original","Can't find end of central directory : is this a zip file ? If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Restauro do portal.docx","22560","ff6a04b4950f9ec3b079db934a37ee7c7df3811eca46890e77c0e981309dfb63","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\prompt para resolver problemas encontrados 300926.docx","21446","ef75499200824189bd8e2e022403d4d7c8d9a1a0128e28fad7915ebc883b12dc","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\prompt corrigir.docx","21990","dd72b1aa7c43af3dac9d0a447e6b0d2304bbbbaec1f9846f13781c74328d000d","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\prompt\Prompt master para revisão do potal.docx","30640","a9963f4cc591c7df88630595bf09b616d408062011b663b9f95cb73b231a61c7","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Cópia de dbrosemin.xlsx","20076","6ff3f15d4dbedf78306ae3cf5f53bf3648553280fc74f3184c4ba4b9d37e08bd","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\benchmark de melhorias investeMoz.docx","134291","065203aacfae766c62cf9c2c272ebacc61ff23bd4ff9e91535939fede87f7617","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\melhorar e transformar o Portal do Investidor atual.docx","862272","d0c06a759693e7b74c6daec14539e247e2bbbd630bcaff59aa01b2f7e9aa977e","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\novos\~$ojecto ancora.docx","162","9424159b007fe38435e4ab829e2f3aee55d514c822278d0d78e265e4db5de9b6","original","Can't find end of central directory : is this a zip file ? If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\novos\projecto ancora.docx","54305","7da1e0f49fb106724c2e416c34905d76249fd27514d0aa2066cde7963cdc4c3d","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\Corrigir a ausência de ZEE.docx","19153","453cffa885086eabacdae7138879c096649b437f9b4c62572f5d35744cb231d7","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\Plano de Optimização do Balcão Virtual.docx","79900","74a8ce293f1ffa153c7a1950413fc94c372686c28f5fca43cb751ea6a5f94f03","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\Bolsas de pareceria Bolsa de Parcerias.docx","86714","0c2641ce634b977c99df8729c43f80e5935d26e2a4ed0cc5290d08938bcf0be0","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\Roteiro de implementacao de ideias.docx","11997280","a3df44b77878970ef68303615f85a4e88e600ecd6917e6c82d5b29f01b8dfa98","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\Roteiro de implementacao de ideias.docx#word/media/image1.png","1626117","f44dc437cd1c9b6a978f30fb9ae8977f81e30e4177e05eefb5c5a54cb8626336","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\Roteiro de implementacao de ideias.docx#word/media/image2.png","1745395","e42c3bb28a1bc0c455904c27f9ba0fc18792efb145fd63c107c3a5166874a4cb","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\Roteiro de implementacao de ideias.docx#word/media/image3.png","1913792","53fd77a360a7ecb6ff67c733b92d66cdcdaee8ef078d8025243d2cd475a11ca6","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\Roteiro de implementacao de ideias.docx#word/media/image4.png","1394028","b5f458bff34c013ffffc73730c2637addc7115b0bc58c326881d330969001eca","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\Roteiro de implementacao de ideias.docx#word/media/image5.png","1382473","f0dbbc1025013174f5bedc453d1e8d476456e36f307850ff1bd66765fdeda09a","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\Roteiro de implementacao de ideias.docx#word/media/image6.png","1313377","ab52dae6a50fb216b8daaea09b72df019ce9e93ec5b0fb1a3ba8f7eb670e4b02","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\Roteiro de implementacao de ideias.docx#word/media/image7.png","1437364","72afd50f29f2d2c6e322927a56ba04843c1ca1fa7b9797c5dd91047eb6777e9f","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\Roteiro de implementacao de ideias.docx#word/media/image8.png","1122339","fc8529eb2af0d89f83003143e0afd039a7e8948ea00aa615762bc669c9d31097","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\Estado ZEE e ZFI nao implementado.docx","24370","a1567e498bafeb0665566b26bd0540cad2e5031f79de5727eefce9806a238c7a","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\auditoria v1.docx","19610","a58f4c47cf9306a02193d82cb607f8493e47fd6e9186df7c8e41bcc780c69d67","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\Benchmark_InvesteMoz_revisto.docx","54060","7fffb2a6ba01ce605504896f65bb078e5f9f906fa399942ca9f4779889809617","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\Não há evidência de que isso esteja relacionado com a compra de tokens.docx","21957","f64d930d8a86c11e141b344e37cf294f16273190c2374689a221457a2e3476b7","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\DECLARAÇÃO DE COMPROMISSO DE HONRA.pdf","506695","7c9f5af3100b32781018862c4b9e082515ada087a49fdb096feeb804ad8cb466","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\implementar.docx","26053","77c2c84df6b09616dca6392d0c6b78ddab36ab82d7900cea29cae95aaebd495e","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\Evolução do simulador investeMoz — diagnóstico e progresso.docx","121493","f329a5aed39964f098384ab2e4380bd5f8479bd04551c315984d0c5e535e7aaf","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\SuiteCRM.docx","26455","3dbef3e4fe8cb604be760ac3f556a63bc2643343723921031a2a56ffd3880144","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\Integração dos parques industriais e ZFI no InvesteMoz.docx","24369","a3ab1d84abdd83ca9400d622b0a6c0af65c124f6de043840bc739a630a9a36a1","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Conference on inclusive and sustainable development in Mozambique July 8.WP edits. docx.docx","34821","3f80c5affb0e54c53bd04e82cc37846e09be9bd67728483852043d26a02ea6fd","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Conferencia Internacional MPD.webarchive","14929099","f37af58ca54667a1c83499ef33230c14021b9894b2c5842d584c1ad337d6e28f","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\~WRL0575.tmp","1305935","6c5aea9972fdeacd045793abc774473a6001e90d8ae4f4811a00f671a5105470","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\novos modulos.docx","6803032","c7f725f5515074807abdfff6963cce472420277fe352f4cbc54d438ff4260c00","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\novos modulos.docx#word/media/image1.png","1323697","8223170912d288e7741fcb884c46d83690d98b525f570ed139b332614296b6ac","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\novos modulos.docx#word/media/image2.png","1407311","6ef4609c17aba403a0d67e9fc166ec8e148908a4f22e3bc5a084487647386859","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\novos modulos.docx#word/media/image3.png","1729491","69107fc52e1a7d2ed39821d8ee0977958e382b6a09cbae5a5095784b57f968d7","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\novos modulos.docx#word/media/image4.png","1865233","3fcd53fdac090ca59834133089a19fd003150c2fb89adba92a896051bb185855","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\legislaçao e localizaçao das ZEE.docx","59538","d3ae0d91ac0bc6d6cc73aabda4916f1c8e2e7450a051126ff39e492e3cca7c2c","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\legislaçao e localizaçao das ZEE.docx#word/media/image1.png","980","6b6ad303a6c9b48d0d086a2a9e9d30b2de4aa58da44f59d7d93dd8dd3727ff22","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\legislaçao e localizaçao das ZEE.docx#word/media/image2.png","13242","e3e34126023e0f413ae599d188d6fd3c30aaf64933711e4c7ac67b9b3fa4a2ee","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\legislaçao e localizaçao das ZEE.docx#word/media/image3.png","414","a46bd049cc2b9375f7dce99347b28cfbff2f484d9987ec9f8d4f7d1d99b0e1f6","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\legislaçao e localizaçao das ZEE.docx#word/media/image4.png","12198","dbc05aaad4448c31ca450bc3302493c2be6451b470e897c343dcf2dbe0793b7a","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\legislaçao e localizaçao das ZEE.docx#word/media/image5.png","579","59212bab985967a734c29fdc3d9f8db77347e87df004d579651562ba486140d7","anexo embebido","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\006f3ea6-5bf4-4315-b3b6-5dda9c3a6566\Pasted text.txt","6842","dbf5afdca293302bb84389ac33aa576c25859f8fa54e26d0b9687b9c564be005","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\0ad28475-97cc-4263-b611-022f3de5bebc\Pasted text.txt","72880","f167d9156c2572c0253949a6f0ed88aafc28450cce902e8f445e3d979119aa37","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\11c236f7-e954-499a-b290-3d6dce07543a\Pasted text.txt","5158","a8241744db40871b36d0a2b39796b7168fadcf243e02a352fa794176da389c95","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\13ef8ec2-be07-4b10-93a1-9fe134b928fa\Pasted text.txt","14654","8185bed1e45611af8861c8f00568a7da6901896e2650355c41642805485ffae1","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\1b36f6f0-93cf-49aa-9479-986a57bd18f4\Pasted text.txt","37098","470913bea520a8ee267f8df27c0849e12e0632d0ede2d4556ed463c994b82161","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\1dc38f3d-1455-4b18-8358-899a66386a7f\Pasted text.txt","36260","05ef8ec7da01b185ff0872e917e9fa9c5c1e7407c3d547788f9ad53930dd5990","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\22ddc8a3-c393-40ff-9960-dcf7bd9e34f6\Pasted text.txt","8230","5464cdaab509637a44adc08fe621fde45a0bc16c8fc3aa9483fb1b9f0f9e0e85","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\2368cafa-157f-4177-ac75-255563247749\Pasted text.txt","16046","300ede994ba6cbacdf7ffebb4cbd75777eccb3f359842491404357e8a549b235","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\23b033e6-9ee3-4a6c-a41b-688fe7f09795\Pasted text.txt","44742","5dbf82c2d8ba2c9056b838c4565cb0db9de28da4173075bfdc12b233b3c43fe9","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\27922f5b-f041-47db-bbf1-6bc50f3a83dc\Pasted text.txt","37098","470913bea520a8ee267f8df27c0849e12e0632d0ede2d4556ed463c994b82161","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\2daec0e8-1c8a-4606-bb4a-b7fccd0ea7bf\Pasted text.txt","0","e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\2fabbcdf-a098-4a0c-907f-b5cc428c4608\Pasted text.txt","12095","991d4b34e6dadd23f4c66a61de509fbac1abe83d8cbb316dd24ba400c6f13451","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\4b4f7002-adf3-4004-abb0-f389778dc08b\Pasted text.txt","5601","02f44bafea4ba47adc8b24284d4b189ab9f1db3f6c1d1d63fc06178c400f9ee0","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\50aa6a01-de6b-4fff-9625-46dbbebd033c\Pasted text.txt","13287","129df97b64e3747d626b89e25f70bba14ad50ccdb47f08eeededd41d0509ebe0","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\5d9b9f23-04ef-4e14-89d5-bbe6abb4a06b\Pasted text.txt","24256","b3e17bb11d6ebafa121b623c8ff8949812b35ef0ca5926a33c22f3e2093a01d9","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\5dbe0293-16ad-4975-8956-ea48778d6510\Pasted text.txt","23804","6e51cfcd4ee1329c51736e0fb1a47668a8e9550de94ead8ffc222ba22498179b","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\602a2b85-7e0d-49a3-b048-de31d42fafc9\Pasted text.txt","11118","07bc673aa256f0ccc73138f70121077e948650683b2dd24f2ead3dd75c76831b","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\62a3324a-541d-414e-8fa8-8cc25c41ded3\Pasted text.txt","8048","7ee3460c0fc278057ffb283ab33d556f58ed8d9834f420c76103f69a0e18fbe3","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\65a3763e-afd7-4ba0-b650-1f4c37f3cfbb\Pasted text.txt","11460","dff87ad6bc8d49d487641e0dd577314bf78f75c3d0220a8802461c5da0c48c7f","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\7235d6fa-a6a3-453f-a97c-b6741c083d10\Pasted text.txt","16673","2626df4ca70d52cb5f90247af7b6eebbb251fc64b4915ee0ed1fbbb693cb3586","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\77627963-3e1c-4d41-add5-18eedbf62b01\Pasted text.txt","16486","62719366d33c647930cc4bc92a07d8e933c4f0e0dc06d91e2464da86ca4b6f8a","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\777f05aa-700e-4dd6-8dfe-e277214fb713\Pasted text.txt","21531","4a12de1c0822ef8583ca5bc7f3d4ffa8dbba1c44fbfbf4e0aadc345efa696f65","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\7cb98fa0-99e1-4dcc-a3f1-30cfa71ea9ce\Pasted text.txt","13591","09933d0e63883e691a573ef23b7c13fa8fcf66556fe38618e222275f5e327c54","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\7f29e161-75bb-4e3d-b49b-cc885c8a386b\Pasted text.txt","5586","cb34088522c04f92f121981407e3376a2c2e3f489d09272cb1dc2828f8c26603","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\8528a9d2-b934-4bb3-a132-a18b7e13414d\Pasted text.txt","30136","6c2ae3e9b43133940dd90fa2be0d24c07eed06ace5799cea3efc25574c0a0e8e","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\8865429e-0156-4167-b465-3595b0fda05f\Pasted text.txt","5262310","b2b4878730a3285d9fcacff5236a15671802c172ff28c10704459aa2cfdfb9eb","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\890e42e3-ce0c-4cd0-903d-d97785be9ce5\Pasted text.txt","68522","d60559844425f03f4a722dff3974be91e8e4e279179bd58663ae164fcc9a68cc","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\8a8b785e-862f-41bb-8d03-06fc6f1b853e\Pasted text.txt","39222","0755f56ae929fd37451d7dd589bed8e1f35c6655f2d674ec1be788b2582cf31d","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\8b304349-5505-4827-9c70-f35cd2514513\Pasted text.txt","29220","1f0a4cdeefb86d36719282d409205f49a0b6d9770ee1beb32ca82284135a0993","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\95cf3a5e-fdbf-4005-a877-57d4ac1f93c5\Pasted text.txt","11261","a2434658ad9e75e59f897cb57c4c2934b8a28f879e32584f3d00064900c6a5ee","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\9e57f88e-82d7-45a9-b1b3-4ae8cec7f713\Pasted text.txt","11805","f15768c79a22c039b9137b937da003dd61912cd9e8bb9fd7a40c795dd0af067e","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\a1795b4c-c360-4e31-8eef-2daeb930721c\Pasted text.txt","23694","24f36a01c9b6d0894155cbf09c17f128904626935461897bf59ce2b811d08d9d","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\a2b1c919-0d1e-443b-bb5e-8917c877899d\Pasted text.txt","54479","06996499b4b5a6b84aba61d43bcebbe9bc7d710700bf279172dd92f1016c8bc6","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\a57fcca7-d9b3-45e9-96ab-575b1c5a3536\Pasted text.txt","30350","8e6deaa7f0d738299b1ae3b8bf89b633641e0cc0cb5e7211461601c0c2b6d635","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\a89743e5-3439-4543-9382-2df32e6ceaa9\Pasted text.txt","6636","574657f7fc612bf7760a31f200978b289a911df39964b8c60e3b357845d8bd4d","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\aa68e897-14b6-4504-ad05-93c2e3f0b4fc\Pasted text.txt","9536","b207d14e53cf13e621a01d0e2bf4bb82bdb65ad0ba07c457b42923299d0336a9","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\acb359eb-1a65-486b-8680-c6abeacccef3\Pasted text.txt","14837","99e36a08038f2540114ad87c32423ce9f0aa6c7c7ac866372273b4fd33df3765","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\b1cdf53f-6026-4724-ba91-fb21b176eddb\Pasted text.txt","7348","e115415527ba9a245fd8d44f4b815054f2f22c72152b5d4ba538488a06d14e85","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\b86ad3e6-37f4-4f04-9bbf-6dc33f69250e\Pasted text.txt","6991","a2ad18c729f00e37db23c1b26615dcee50960e0eed7346d6cc013e6a57c2c24d","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\b93f36c6-ac2c-45f4-995d-577c09b3862e\Pasted text.txt","10274","9f6dd1d9c0ca8628443edc69a6151ba49f96a8e044ac8aface249c4957dafb86","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\bf1d310a-d3a8-48fc-953f-0648622a6c85\Pasted text.txt","81460","fd7878021ae5d18c9d4a9a79073552c36876d59726b8fb2612752f2594080ca0","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\bfb8dbf2-ecff-45be-8612-c1868ebe8343\Pasted text.txt","6665","cc874c1e0d7ab1d7779df1664c524ae5f876ef7af99b7fec2358c4be7d0e53c6","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\c1ac842e-1b98-4f18-82bf-5155dbddf288\Pasted text.txt","11603","bd55cac92926fd804e358921924740eb9c7e649af7a845fe85d2c3686ae2ef09","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\c6245408-7052-4478-8804-377b282e8203\Pasted text.txt","30976","600240dd64b59b82bdb92e471b475f9efc96eab67f9cd532a432e1e7a324f0c9","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\ce3b9157-6463-4c3f-af50-6d53cba78a23\Pasted text.txt","30586","6381a59fbe8bd8ee5a76d8755ceb320ef2d14fc1e628b8e1cbef2c5eb83e30c8","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\ce71e769-044b-4eaa-9f8a-793e52cd644d\Pasted text.txt","6128","0a64d4fe9dc2d80211568d74cc49335472d7a2be01a199223bf4b1a0fb58e983","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\cfe4012e-cb54-4a42-8fcf-9567bea45d7d\Pasted text.txt","34983","8ab2b0df6b41a483d72aa852984c627a1c41dea3f05e0f13ac3ee0ad6d680b65","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\d53670c4-f46a-4d49-b188-770b86bdda19\Pasted text.txt","8127","c71ec7adb5af079fc5c93536107fe30ffc0906700b5ee5eef6bd2cca1665dfde","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\d5886992-638e-479f-bc30-e327bd7a10ee\Pasted text.txt","12246","f0da2b58af2e30cc1b1cc353f3a6b00a592c800e17b8d00bd2c13dcbf16c5a78","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\dd19a693-8805-4f81-a65c-bf2af031a37a\Pasted text.txt","9346","2453530cc98ffd9b270eef47786a9d596701e4831e2a3c16c3765152cc916494","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\ddd6740c-486e-4ebf-a11e-c9687206178a\Pasted text.txt","7103","149673c0e35573716086d72f65e1b8e6c805c4f890b44722b839d4ce7e6caf15","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\e11a00e4-8fcc-4ad8-8861-2fc0244c4324\Pasted text.txt","23406","c32107c1735d544d91c1c5e6f94c731e71871c66ff6ddcbecedc4c86fd1630c7","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\e1fa9a32-14ae-46f3-ac02-c7115c832175\Pasted text.txt","8246","55050f60a15d18b119c83799231a0af34b00738f7ae8202a232a07df23f65fd1","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\e51bbb68-0db4-41ba-84b3-e20754ba0d33\Pasted text.txt","37962","214044c4a4a71430ab8f271ba85256e48c6a08785da0e48ecb7507a04f23b6d1","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\e642d815-f449-495f-bd61-4b3e247e23de\Pasted text.txt","9502","5dff89adce75a8b9e0a699bd31986a1a18fd3f25de7218da2800631365b4986e","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\f003a1f1-4ca9-4193-9790-0ba7c1db9812\Pasted text.txt","5158","a8241744db40871b36d0a2b39796b7168fadcf243e02a352fa794176da389c95","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\Users\macbook\.codex\attachments\pasted-text-attachments.json","129812","6bbdddc9c69558cb97444d77b90be34a20324174289a4d7f3f337de89b8f7f85","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\portal-documents\58abf343-e1f5-446d-a9cb-3255f376ece9","9456358","11f0cab15eb6e51010952203ffa24fdc533a24fd642e19525fe4f46b17a1f5e5","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\portal-documents\5c860c48-e8cb-4d8d-ab9b-2e3ea7036ce2","1834284","ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\portal-documents\64c46765-96b9-4f43-afc6-f5b730c010c4","440018","ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\portal-documents\b0ea969a-30ec-477b-8b8b-b7af82a11bfe","67067","5c69b6f189a1d3f5307e0cf7dd8224554705158a682637d3105afad615db26e2","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\geo-ine-source-20260928\layout.txt","57191","2fb8ebe44bb0f9e22e382436890a26822592e1da023b56ca392e9aafdde7d85a","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\geo-ine-source-20260928\original.pdf","67067","5c69b6f189a1d3f5307e0cf7dd8224554705158a682637d3105afad615db26e2","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\opportunity-resources\0ddc290f-423e-42d3-9d71-4d0613f7a0b7","256","44cffa4321c00556030f25ebc0806b9dbeb917cb3ceb2a8c0cb87be575752803","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\opportunity-resources\1c466353-ffdc-42a7-80ac-71f4d27551c5","256","212ef2dc1db7df9904d6eafd0b75dcb2e15aa32cfe875c6a4aaa90f3326fb4ac","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\opportunity-resources\1d2c520a-6320-4a36-b3c5-86afe674947b","256","bce07a2025490b0397f40f1fda70bf68a2a3079c126451c461f23c2a41632f4f","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\opportunity-resources\4e278690-f201-4539-99b3-df9fc22eabe1","1620","091c234abcd17e096dc43df4b58303c6943c9de1f20d53aecf64d42ede08b30f","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\opportunity-resources\6bff5c6c-aec4-4901-a283-598d430bbc6c","1620","f43cf75b9137934e04ed43222a035cf84dc1d4e80740867a480c194ddf5b2beb","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\opportunity-resources\88b4b91c-dfe2-42ca-b96a-8b355661dcf0","256","3d8251075f3f377f30c6c76fdea3c7c283a26e35b47f8fa91768860087ae6799","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\opportunity-resources\8b6201dd-52be-4820-a2e8-1a0de7de6ff4","256","c81fd76282c9cbcff1118465c0725f2e8e7fe173933b52a37a0082b1a82cbbd3","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\opportunity-resources\91fb5959-e621-42e4-8d31-5871ef95b9c4","1620","d0a97bc7153146bb2cf1478d99b786536f71244e51fd04ca702e1066703ebbb0","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\opportunity-resources\9adbea9a-f909-4236-9e44-716329274bb9","1620","d70992539778fa94bba1322b6fed0ba59d5dca89c30d4b2aae2e149b0c0b0c08","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\opportunity-resources\a8a7c442-dc9f-4aa1-8f59-9665c057cd9b","1620","abaf5c018b6a9cbaf4a60e181a9da3b96e8b69036a4f88b0908267a3126c07b5","original","","Acervo inventariado; consulta/publicação individual não inferida","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\ai\api.md","4801","3b7e69dd386de8e8b7f0f201aa6257adb383febe5ccd309362de2e2f95b132dc","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\ai\architecture.md","6392","7d1b66c88903f546c7a2f6f18e00b045417c103481d7dd22cd9c7c6e0f89b221","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\ai\benchmark-results.json","2160","ca1f37224f869a91a8ce0ce23dd8f276382b20feb52cdb5bcfcffc4d7a646ba3","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\ai\coverage.md","6502","b3a1e96463dd9926e439e69fdbc313b9417aa1f112da37e82d983511b22fca32","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\ai\models.md","4247","05b1ff348f98f572fd31ea9a5123517948643457e4bbd9511192f32a203cb8ab","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\ai\README.md","4604","4323bb06506ee427a51475c90f7647bd336df667d07b1a44c50640a90db2850a","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\ai\vector-proposal.sql","1027","3cf9134615be3cd62b7294c1ee7d8add8800975246a50c61033406af93e76bba","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\architecture-and-migrations.md","622246","488ed8672518b42619edfabb9ca7264e6ff330922bb1b824f0ee4a53dbf690ba","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\architecture-data-security-qa-product-review.md","9884","a2ffe042d64de6e47569c59034bda3786e0ed643a7d242563ed260d19bc44a88","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\associations.csv","2036","aef72b1a2f40576feb1f3cd9df382cd82729ef2569505b297e658d560ae96730","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\business-marketplace-progress-2026-09-30.md","5591","f81f76878dee180eda0d8c3cc908cfb284d22b4c1a471b98048fc0235d3dd7af","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\business-marketplace-schema-integration.md","7560","c9020d6efbe7e1c370798da76d1443ab82e98780262b6ce76394f857582a96b1","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\catalogue-review-2026-10-04.md","13200","3fd361cd1cfc8602529874e80df1c34a5b379ba75b0e1ae55dfe4a474cc63136","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\catalogues\openapi.json","11492","2e91ef5d2a1f2171e9f667d916a077e96f26020b59e592a6c26a8333e05408ac","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\checksums.sha256","5228","085c898a1ed900a5d269e5b2d5b0af2a56ada1d18e2401ef990b93d185a5e950","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\completion-audit-2026-10-04.md","14311","e6ce69bfe5ba9840a4f1d4cafda7f42aee4e69875f0e8d75d9fb017817f8ade7","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\consolidated-review-matrix-2026-10-03.md","128154","047bd4716165360af65c874766297b7146c9edfe5d97dbe5a4299faaebc42cfb","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\constraints.csv","39081","61b10edeb087f6a021d3c1d54f45d7f1208ec92dfeb365086a18b10d3a8f77f5","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\data-dictionary.csv","184351","94ccf2d0a5361309634356a3f53dd79c23d9abc5b65928a0b3aaca6228069acf","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\decisions.md","4196","6377ed87016a505cf37bf9a69205321ea6c8cd9d6a32214f12225c5850b133b7","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\delivery-gaps.md","8606","dbddcdbd8f1941ddc8502a29bfa433977eefdf3433ca5452643689e50287ff67","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\deployment.md","6603","389cef96440adb07a0085fd1ce386651378f9dcf42911fc1222d4fbab9665665","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\document-corpus-inventory-2026-10-06.csv","36993","5a012645c6633cdce844f34a4f67ca0ac3c3c7074884236b554a86a2cfb0a908","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\document-corpus-reconciliation-2026-10-06.md","20640","71c7ef081e4ed20e8fcf31d72b1ec777d8054af283a8636c25ef20c803ee9ce5","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\document-import-manifest.example.json","823","7257e582d70a58dcb993536583da954049d7186f9b4b4ebbbc02bbfa5e9cf5c0","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\document-library-browser-2026-10-05.json","1018","32a6a0fd1147c98d77bb8864e378e2bb95a95b74664b7b06cd1206ce80021ff1","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\document-library-completion-2026-10-06.md","11706","a0e41142c688c7d33578e4f43e213112351d56389f4d1aacc4511eb4e48773d4","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\document-library-completion-browser-2026-10-06.json","1873","45f0595624860c804929b10ed46f04fdaa4c811bf4c144ae60d88b9280e8e0ca","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\document-library-completion-desktop-2026-10-06.png","104742","cd4cce9587832916b9cc48fe0e417307eaf9264bb0cdfee1702cc9852a27a4a5","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\document-library-completion-mobile-2026-10-06.png","98371","991ebcd793ecc567ebc263896cfd6b6409317e7929f2a88a9deb54ec08b2e403","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\document-library-desktop-2026-10-05.png","99244","a6bf38faee150217fd01e9224d6fa3ab0bb9c77b30ed2e72d6dbb06e64dda4eb","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\document-library-implementation-2026-10-05.md","7296","af56b14093af5faa0fecd85d1221e324602113d838619bde7696942f8bf7f330","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\document-library-inventory-2026-10-05.md","7232","8a8eb56d1fb87bb86029698579b4bfe1b4385d9dfc85ffa775c82d489a47d1b6","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\document-library-migration-desktop-2026-10-06.png","99244","a6bf38faee150217fd01e9224d6fa3ab0bb9c77b30ed2e72d6dbb06e64dda4eb","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\document-library-migration-mobile-2026-10-06.png","95291","5ad43f381b171ee443e866c1eb1a8f878d9895a3f02a47dc3c237c6a8294b4a9","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\document-library-mobile-2026-10-05.png","95291","5ad43f381b171ee443e866c1eb1a8f878d9895a3f02a47dc3c237c6a8294b4a9","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\document-library-schema-incident-2026-10-05.md","4638","e10f266a46a5af3e092761d4b0784ace0ef6da2dd0249c09f2254c598112f357","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\document-requirement-associations-2026-10-06.md","15749","60e8f9fcfe3b14042cbbee3cf1c72deeadf8f30ef3bc77b78b964557dc98ba7c","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\education\conformity.csv","8588","81e6f0451dd5d5f526c8b7c9a78f61f6293ceb5eec55d4b5ccccde40daffe7b6","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\education\decisions.md","8747","ae144e7594d0e730dc62e0a4754072c09095f4187df8de9e5d585872402f3b1c","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\education\entities.csv","22778","ad66733605c17455a2c03f007ecd1f9f26ec71685d60ee73be959bfb53b8b958","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\education\examples\gap-calculator.mjs","1523","70dd4a73ba2b5644e66b307279141bfe6a31cd9c991bdab8a4568a8507787d95","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\education\examples\gap-calculator.test.mjs","2509","eff94de4752e056babe877a008edb0007b123fc5bc87019dd78b0699081a7293","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\education\examples\package.test.mjs","4736","0b7fa5eef2359f6c86a504f87bfe0e15ddc9b2616668c3be61e2ec1cec65f985","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\education\implementation-status.md","14670","08243231dcb0fd618af59ed123943e22bf985f2e4967a9ecf2e7e67bfe401198","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\education\indicators.csv","14969","2cf4a982c32befe5d703a332b9baf9ab35d91e53df47c9af0766ac0b94faf796","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\education\migration-proposal.md","8435","4983843c47a74ee206d8a5b697581f4288d81971a6452f5b438521ee6a3d44f4","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\education\nonfunctional.csv","6333","51ba1bb3767bd2aeddcde2a88da6c373a3ed98a1082addacb05111a7950ef170","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\education\openapi.proposed.json","32636","5b4e76561f11ddc29bf6c1adf46fe2d923601cf62b1869b119c246f60a992743","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\education\README.md","7951","5bbfabd1ad0b34a05ce23afe2d466e8eec58c594c7345d2fc6380469b56b38a7","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\education\requirements.csv","22521","ac4d0da696fb4b562e2a832cc33883a9a870c5b4f730eadfdc0e652ff3fea9ee","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\education\skills-education-schema.md","7588","89276898fc606dff493724c3a9e33beb0be9dc7ae9448253d4ad6685052d30db","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\education\skills-functional-diagnosis.md","13135","8a271c555b67012f0e50ed71b5edaed8ffecf67919cd1cb6b440dea97d7781d0","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\education\specification.md","63304","0419f22de21a328a8407660caab409695c35fd8868580a2e3331f35af45a85b6","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\erd.mmd","24399","7373bf93e95db348b63192997d78ba1ce8414c95d6011c58312806022fc6e974","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\existing-business\annex-de-execution.md","4387","8e5504eb242b54a8915c14d50f7dc4762e43df4fc7d3cdc353fffbac32a2ea2e","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\existing-business\browser-validation.json","723","4295fbe5ff0ff45429acde848f8af5632f15590be0114e3d6487d8b435a209de","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\existing-business\canonical-integrity.md","3028","d9f89c386b9df543f8dc2099823a52b836d582fbec6e6e67e2b528b5e1759f9a","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\existing-business\compatibility.md","6456","9372a6be5d1ca7a71e98a032a8d3092fed8015e83df479f50999a4b90ffd403a","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\existing-business\form-schema.json","17645","45c3a18a7815b0cb29bc11a16a0a81ef3b692b38fef06664fd1024547b2f06dc","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\existing-business\implementation-status.md","11833","6228c332b325cd9b71860db896c8e1ffbb2ef6c2a47f5792f0bf4c8e41ab3cad","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\existing-business\openapi.json","134052","4c4e42306f85e8ea26bda21999e3b21dfc8560ee18f34c6cad0795ec9cea763a","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\existing-business\phase-1.md","8409","a9271a278e96034cb14189fa8169e0a5203df81933eabad59e4ca666fed9a44b","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\existing-business\README.md","21344","d7552eef64ac2628b9f3a81f219241205af74f2fd26796bdd3a5fbe0f600073f","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\existing-business\traceability.csv","2535","f5d449b5e317959bbd12b67a39faff1ca85cbc3e2395643d30dc9b0e035ba057","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\existing-business\validation.md","4768","86514166a31c99a8d57531805ca894952d96491db0cf2a914b753ff01ce40584","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\existing-business\verification-evidence.md","3874","f7535a947c9a92b3cddfcd4b3f6865b2123e7c08637fa99c0a28ea2de6c2a33f","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\existing-business\wizard-browser-validation.json","499","c177700ec3eb8d31a9024b83abadde343209a9fe3a14f6f6071ec8ee8c319f8d","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\existing-business\wizard-implementation.md","15735","fc3aca9367dc714e0ec6771920aa1c784a212e1543b09747ba9e5cde2bc4e356","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\fiscal-source-references-2026-10-06.csv","9992","f2fde2257fd481f984e59bdfc62ce209c849b350961111616d2c2927c1421d6f","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\frontend-integration.md","2619","a4250eb4d56c7c4a1893d974c72a1a6e423a09d8f5aff9498deb5ae2ea18efce","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\gis\ine-import-status.md","7359","1298c29dc6aee460d03b45b0d1c883c81e2a123a295ffcf1b5de30a8edc3791d","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\gis\interactive-map.md","5607","5579a82b0d1008b6b5af034a8c216cadd3209e840de4f7f998545036b49c9a2a","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\gis\investment-dropdowns.md","5831","76cd7beec972a010fb17c3fd1f65cd6b268d8c3b5fed1c8fc62c54384f1624ca","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\gis\map-coverage.json","2755","98475bf387143b988df9fa69f0453ec6eb6d93262716bc5b4d9b0d3cb6d46f5e","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\gis\opportunity-dropdown-browser.json","2924","dd605b3db0cee0f5a14b7260878a723bbf1b0bf55fb5af3a656d245fb74ff5ad","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\gis\README.md","17375","c3d14064c552f338e4ce2480110a7d8dab4657f23b9f075a997f50edd2ff82c0","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\gis\source-manifest.example.json","247","cfd02f4c01174e799936234a897e65a6707c85217ebfa065e3805f56c20d2923","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\gis\sql-workbook-inspection.json","655","c44a6edd502134fd6500b1907e81a1134560d59136099b9a6d843ffc91b09e46","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\gis\sql-workbook-validation.json","787","42f0b796c911bff0289c19bba0683cf45d88c762b75bf54f9f9b730dff07a584","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\gis\territorial-mvp.md","8069","16b46d4b0a66031f25701d2a8cc4327a0b43abc24f6db53da8d7394e04e8a4fd","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\gis\territorial-openapi.json","49691","e0e27e7650f43b35ccbf9491e647aa744c860bb2a323fcfabb389d9a239dfcd6","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\gis\territory-integrity-results.json","3783","8062e5d9975f6e8d16083b9c8ec06bcacba1add9d68de3136a99001e39a9a3d3","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\indexes.csv","40127","142728247045678e5f026cdebfed7e4cd69ebc637680b91380f4d3e0f7349dd4","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\integration-repair-2026-10-04.md","12760","44d02093f1a97a006a18a9a7a41a9d093d6afb89ab1f128f893c3ca290eb83df","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\land-assistance\implementation.md","6487","84321b7d69d01a2eeca04efca0d791a204850e215c2781ee90ade882d14e26d1","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\land-assistance\legal-source-review-2026-10-03.md","14376","f9030854e6fe69b636ab61951643a8f9fdba4b5100eb454836eaa0a423e67e38","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\land-assistance\requirement-traceability.md","15535","ac3b3137123bcac34b4390df26d1474eb19bea8d6fd5ee0b156efd58d9a7ab15","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\land-assistance\source-inventory.md","8648","cbf0a5b0d55668f6ce18a3a03fd19478a2868c32482e2afc2dc2115ce37c4f99","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\legacy-schema.json","52671","4c6982432c7451d144ae1b03a8291e7796c977f698c8b809b57824aacf5d3629","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\legal-source-library-migration-2026-10-06.md","13327","ec3ac22cf2a374777c875e1cb46906596dc49b685fde00f6110f5f87333af38b","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\malware-scanning-2026-10-05.md","10742","914b859d4cd1177e4085f7c96f59545de3e53adb6b8ba16ba725d4b84ddbffaa","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\management.md","5709","5d9e3c898949d510858a0eb6697b3b40c2d3b786ce063e3d1b2d5115a38a5ad6","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\objects.json","10834","9d7613c948de2b1ba6f70b97472ac9f06ef445fb4d82ef1eaf3ca67dab239160","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\partnerships\browser-qa.json","405","defb676b16f21eced0f715945a3fe770b63c8ac065b0738d9b4f68533f3d9249","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\partnerships\contracts.md","3509","950bf6c89c0ab7f02bbfe804db4950a44cdfcac94af615aa1ef239aea517f2fa","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\partnerships\README.md","5068","98c3be76059731061d17a8a2d5d3d33a3316331aecd6d37956bc073d9ab6c76a","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\partnerships\requirements.md","5339","17393cdd83da8ff46cc0accee7ad9465679e8ae7c7099897bf61a164fd1dfc18","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\partnerships\room-1440.png","202889","5057540714b81f4618f0ea150febc77223d3fa91cf50050a83d18fad8b4b3501","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\partnerships\room-390.png","174441","754f21c816f960c1db6d7035dcf6ecec7c24064f43627deb08b31432a4b4394a","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\pii-extraction-review-2026-10-03.md","8638","d606cf522e8be973805529bb341c8a16d3bd70f161a5e97ec01324c25dc7f9cb","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\pilot\authorized-opportunity-filter-browser-2026-10-04.json","915","b67e04eb2c9660ac23b74edc4e293d2bf3d7c5f9bff5527f9436a015b244c589","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\pilot\field-usability-pilot-2026-10.md","6408","b9b820c39bc4323ff19b9897b9cc533a38d76ab943ee9ff84054f62e0bd7f967","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\pilot\investmoz-catalogue-guide-browser-2026-10-04.json","2850","e5bd7c71a23a9bd7f6f5b61188cbd995b8115acdd7a6984b711446262d2d599c","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\pilot\investmoz-guide-mobile-2026-10-04.png","326034","b5512909b6493b60013035187c950a7b396d5dfad8d3aec1099e4719da42c0f4","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\pilot\private-dossier-association-browser-2026-10-04.json","343","d14327e8c37cc160cbc8ded3602970dd1a63932389984d2731777ca92f84f9bb","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\pilot\private-dossier-association-browser-2026-10-04.png","417060","1e39c9a6bf377d537853024481d4e2d92a3907e185f51a89c695ef8abc3280ea","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\pilot\territorial-filter-removal-browser-2026-10-04.json","446","b3e15d696dd1c4d8fd3305395c48221971112a1579a5ea284edcdf32d06e42dd","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\pilot\territorial-filter-removal-browser-2026-10-04.png","447090","e9a1c971179fbdfaf95b4ffbb49f79eb5d45658c1c163d758dcde5cb305424c8","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\pilot\territorial-search-browser-2026-10-04.json","1595","8bc6045b45eef8b2e051b77f9c809517b29f1fe2b4f5eb1048182b930a48a05e","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\pilot\territorial-search-desktop-2026-10-04.png","816346","c3ce06800fe438e481b11ea58c47e9c9a493091c4c5a303f2118c6c23d87954a","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\pilot\territorial-search-filtered-2026-10-04.png","467961","8a31415585275ba6bccc623f6280e178c91e961dcda3037a51553e73d3e647c5","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\pilot\territorial-search-filtered-mobile-2026-10-04.png","298053","e923261b8ecbec431a060e7bbcf49c95d43aa3e90cad15764d27664036179e26","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\pilot\territorial-search-followup-2026-10-04.md","6700","e7cd4e5cf3372aacd594da39bb2526c9bd393428a96e640594246fb515aa4708","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\pilot\territorial-search-mobile-2026-10-04.png","717500","545d3e39fcdbcdd9a24722d6d569508b410a1e9b2ffe96c7b63ab3b6675c8bcb","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\pilot\territorial-search-positive-browser-2026-10-04.json","987","e8023c8df2bdff4e29da8ee9cc26f035af9f18b5a48bc54b85d0a16013d5a347","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\pilot\territorial-search-positive-desktop-2026-10-04.png","480868","af393579700ed3a7f29bc0ea06ff1f0316e2af6dcafcf8b325b1afdf721add30","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\pilot\territorial-search-positive-mobile-2026-10-04.png","367616","8afbbed084b57fcb20298d7aefc478336942b3ba7a0608287bdad34388711c30","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\portfolio-journey.md","8763","079dc2d9a5aa5384cf38680eef60876932f9e0a2e4260aa7a6dd8bec3fa6bdcf","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\production-reference-seeding.md","2422","b4c9585fc9470b1c0fc323417083c40cd9dce98946731c55c4e5a71a88a6bf3e","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\public-portal-browser-validation.json","2180","7a30088ef81871d55d93e0cc3a348fd9cd0a9afc772bfb61572e829dd892561d","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\public-portal-sections.md","7820","1b0a213480a9700f6f0dcb68bac5459f2e0af9cd274f2f2f43e62750e3d0f81b","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\qa-database-target-incident-2026-10-03.md","5050","882547616032a06c6e876a0ef08e54d36018990c1f71d6ae6d4ed4dcb23969a0","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\README.md","873","1cd4bfb21be5cda9bf2d66574ec05a71d1a7cf3acf4e78d2403cfc708b6a7ae6","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\reference-schema-reconciliation.md","15940","0b3c93bade03cf395e5400d30e1d88da25921fbd9b9c79d180574d2b0d2f78ec","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\relationships\browser-qa.json","489","43df26a5719e03adffc463688313c0ee96536901851101984be6fc35c4ed035b","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\relationships\cluster-1440.png","463640","bcf2059a862a3ee4866d05870eae80c0af9aa6b9a831b66d3fd94a7d7df046ec","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\relationships\cluster-390.png","256636","907b8e5ac1075f4cc8f4b34caf1a71170e68d8ff031e1527a8bbed9836bf541b","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\relationships\README.md","11108","9794868e15c530a8e5ce1b5c16c8bdf6197a6c5526da2aaed4350ede77e27b5b","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\relationships\territorial-1440.png","371150","914ce5df89ddc4a49d8f283041da3b21aa46a22436348683e78c08481e6f20d4","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\relationships\territorial-390.png","341234","50504637502caffac0c82097006d8f526e8ff25d1d922e65008236abef490895","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\relationships\territorial-browser-qa.json","284","26d1cde41c7a1be0f8394838917d627698ec2185b4ece095d365efa1a8c7e6c8","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\relationships.csv","11815","e236a15a8bd8b55ae2c7c74a7e66185066ac24708344f5836ebea88545a544e3","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\remediation-execution-2026-09-30.md","14937","c75582728aeb1d1490cf9a007745a87e540ecbc0f5082c7eb3ef4be85a7e8e5b","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\requirements-audit.csv","57329","522507d7b2d491ce63440a7c9822d28adc41d8630e1136b945b3671ec55f7ecb","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\requirements-audit.md","17494","1fc38e37528235a75789c92842995739474be58d96fe77bd5daecd1a449d8f88","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\roadmap\README.md","5113","df844466ee6e4c2a871191bbb2a3038b59d6c6fc307e42d27f434cfdbf60e5a9","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\roadmap\source-inventory.json","9580","348b0b2153cd9134d0cbb5f2604f6bca89c0816fcc6b078f96c86a77d6104891","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\runbook.md","4965","393bc08a00e6054d1881a256663ca25a487acffc16405b35441d5ac42da3a7e8","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\schema.json","419778","8881545beb64f48c7c1afe97d24744054bccfe9f698861d809c8e714a3bb29c4","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\current-status-2026-10-03.md","61546","09da758c9d82751c5ca0edfe0656d8efaaa0c610ea3c6f1de45ee6dbccc0fb50","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\data-contracts.md","18346","714ebb4a4215af491de89a7251ece2db3d5b25f4770fede1a7b4af41614f4dab","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\entrepreneur-question-mapping-2026-10-05.md","11451","b374e20193ca20ee2b24fd53ab4bf4bb9c716bd2b519e2c6f419a4fe4eac9f70","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\fiscal-reform-2026-review.md","49068","b334895e6647c6776f54488fd03afd4e199f6bf6eb8c9ba4db52ab977f6fd618","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\investor-project-journey-2026-10-04.md","3839","5c3dedd8a32d21eb53c72172dea45b3760aaf62e4d8076ff71cc86a95370ed46","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\official-source-register.md","51676","8ffef016d4bcdc045e3e3f4ff827d1b014736a91fdd2139fabae88d70bc93a53","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\openapi.json","79479","a5ebb2ade09de0a9b620b58b1c1e3c14d0745505d127b563bd178bdd322948b7","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\primary-text-review-2025-2026.md","24783","e0a25324df6742dcd2a0b4ac57c79c86452ab87a64572893befeb321e322d78d","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\project-dossier-print-qa-2026-10-04.json","894","bc41af7585ac4444b5fbf932c0dbc45a7740c6915555c0ae279c9df317335d0e","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\project-dossier-report-2026-10-04.md","4989","2fc15d456bd12dde01b7dc1b287b30c4bed509a97b0c26f272088e291cadfe21","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\rule-governance-openapi.json","11400","fa52572acfb7703648f2590ca114fe6a6e8f53b64d6bd2253281f4f121d26bb6","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\rule-governance.md","9038","9fe043cd46258e470a30ba066245aa8a2a341821a426f0ed95da5dd2a7359896","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\simulation-draft-continuity-active-after-forget-2026-10-04.png","119300","eab0f37d1c013c6200e623edbc46c17647f5a34dbd06a242f7942ee6bb9906de","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\simulation-draft-continuity-active-before-forget-2026-10-04.png","148320","b57b5cc5f2e8b84a882230a139a660ca3412a4f67b766ac6d8d315ddff9fb456","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\simulation-draft-continuity-active-browser-2026-10-04.json","1440","7fc66d67c69b862e2adc85feb897c07b33516089136781acdf3bc8ca78294e8d","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\simulation-draft-continuity-incident-2026-10-04.md","6347","5f6086944e6fa6b310994e34ca32064e202f4911230cf5cab34441039dd61a1e","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\simulator-a11y-browser-2026-10-04.json","3689","258c9e80b028ffb0ff6e3cb723c1cd6671dadc289baffce32e97e42771fbd676","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\simulator-api-errors-browser-2026-10-03.json","1598","840abac878be29b36cae7699a6fd764677ac75c902ab6d780ca009d1f3968342","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\simulator-browser-audit-2026-10-03-rerun-qa-verified.json","3689","7b34046113d90a8fb3078c51ac9f96b74f74720ed90010b389e09f201a705957","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\simulator-browser-audit-2026-10-03-rerun-runtime-verified.json","3689","5ef9e5c31795c6f0304f1483864f9c2ad685a0bebee59078f815efa7a7b7d3d0","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\simulator-browser-audit-2026-10-03-rerun.json","3563","520c912342d25ee8412d969cae15d9745969f657709a31d042511a0915924d89","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\simulator-browser-audit-2026-10-03.json","3563","8671f4f23d1b55df0876de13476781cba79467ea9061e81814b0ed879f30744e","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\simulator-calculation-browser-2026-10-03.json","2859","f5f64227fb7d5322e4a184e4a05052d032a4697d660cc86b0003514825c88092","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\simulator-calculation-responsive-browser-2026-10-03.json","37757","54771a108906d96491144df69933a4cc0da8cf125d2d88e367ebba38f4454397","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\simulator-cashflow-browser-2026-10-03.json","2978","4e78a67cbee67c1dae4ab6b19dd8e63b27560bde00deb8c66a3c868c8cc65146","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\simulator-continuity-browser-2026-10-04.json","900","30f261ffdb7f6e10c7305465166583820530b534f87933049cbbd3ffd281c495","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\simulator-final-validation-browser-2026-10-05.json","4293","3ecd4b3f1d2c212e5c2cc4d44270c25ba7d7b5c15952d89248f38b3171737e6f","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\simulator-journey-browser-2026-10-04.json","4078","98af71bd0adbcb6729da7519d0a41457bb9b86c34568935fd7d57fef0dd8c06c","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\source-archive\BR-248-I-Suplemento-1-2025.pdf","440018","ccf2a8deeca820f2dd076b4b2141b1efe3f6a806568c3a587ca59a8e92f4c251","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\source-archive\BR-89-I-Serie-2017-06-08.pdf","9456358","11f0cab15eb6e51010952203ffa24fdc533a24fd642e19525fe4f46b17a1f5e5","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\source-archive\Lei-22-2022-IVA-republicada-BR-250-2-suplemento.pdf","1834284","ea1b0dc6f5cf6e595f6d9a19e7042f398999e0087caef1785f6e8fac571b5f53","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\stage-10-extension-traceability.md","6420","ecd8707ce939223f27245b88af75d349ff054582b92f7edf63691b5a7308dd0f","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\stage-10-gate.md","22365","e103c93808d7291b52f392dd7a2bf5bde8e1a1585d2402539f25f1e0c5fd270c","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\stage-10-technical-traceability.md","6748","21add6ba1bcd9e9229aeac7b3a1fb605186e88728baf767ebb9aa17319826c8d","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\stage-11-gate.md","7188","41015335082056a3fe8f0ac8d0a08512fb0d6b449a48a40a549f8c2cacab7c80","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\stage-6-technical-traceability.md","10008","b651581dbbc9a4deebdf29306ddc41e854a8b94dfcda46f33f9ec5b2a231bac2","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\stage-7-technical-traceability.md","11008","5c0ee04bfd55cb0a594af0234385f849fbc1b784b7a49345213419388deac582","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\stage-8-technical-traceability.md","8036","e776a33e000f1787d7ac71616b0b2832339f5e8242a553d650f7c7310df11223","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\stage-9-gate.md","6824","da2048d365ff9721d1104ccfdec10dc8802b8f02dedb1a3bb6e5417fe4d4961d","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulations\stage-9-technical-traceability.md","6063","80d4adb5e4da8e6b740d6343332869c5d6d1a437bb213c2790a81ed7356cd560","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\simulator-evolution-progress.md","273004","625a0bcd98d72617656ddb71679e12fca2d3ed23a6bc55782c32ae972c8a2b9f","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\source-reconciliation.json","372","53783524c4eb928cd1eaa5c575a6f45fca4f1dee8b3aeb0be6d874807e177748","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\source-staging\pii-26-30-review-only.csv","101415","a46e658cacce19a387fb314842150693f4020f479ad14192282205d5e71ce3c3","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\source-staging\zone-integration-2026-10-04\Pasted text.txt","9346","2453530cc98ffd9b270eef47786a9d596701e4831e2a3c16c3765152cc916494","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\suitecrm\architecture.md","13447","4a282fb574af39cce16a5f4f14324699bb13469c8639a221464232718ecf6597","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\suitecrm\client.md","7995","9767c99c96c3660fcaa98f39df1db58f47a6bb5a802c4ea966fdc26bd45068ac","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\suitecrm\mapping-catalog.md","18692","39505269ba8cec49cf0642e9b603a31912a1ba0c06ee2d7969cc21333febc6a0","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\suitecrm\outbox.md","4795","3c0bde5e1dc9e0352f060ba37d58f822a7cc1eb1b2df52fa881928e088b05bbb","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\table-catalog.csv","9934","45ef0a893111afd342963d8240ca17fb276a090e92efd1ad2ab41d6a48c8e9d1","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\territorial-search-audit-2026-10-04.md","7237","704e41a660afc1eb774d6320d5681ee5f348aae6651d3b5cae3c8989bbe38d55","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\traceability.csv","88017","4ad83685122a63d90c77eb2c1be2858861b61bdde4c2300012734482af77ef8f","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\unification\browser-validation.json","5045","4ca6419b44a6fea847212916af59ae6672c0ad062cb2daf535acb2a90d15f0b5","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\unification\data-and-operations.md","14690","e63e32831b0dc4172f1b7f4a028c45c3b2de99dfdaca6ae3eb408a426cd9cba4","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\unification\local-latency.json","952","ec0e2d6f35b02d87c1a56150da7135efa6067c11ccc64582e15e2275b33be92c","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\unification\openapi.json","191844","ed1ba3868a71ea1ca0f6e2aa8f0ac5199dd60dfde5cbe6e2cc359baa4ff9cf0a","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\unification\public-browser-validation.json","2615","f18a29cf9b7ff5978ca2e7b4fb53dd624de5f68a2e573c0282b52fdea94a7bc0","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\unification\README.md","9760","1dbda44d61d217f0179127fd128c2daf5bd5028a28f5bd240f3113f2a865173a","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\unification\traceability-and-manual.md","13614","66e5bf20cf423c58b923753290e30903265905a2eac69995777296bd19757d6e","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\unification\validation.md","5778","999cca6894fe87ab0f579a1d248764a2af5a412049536cea51db20c0a07aa90c","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\upgrade-progress.md","13050","c33a1d528fe234677f267cd3874c83d87bca5e2fdc143f20c63306ab10297fad","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\v2\ativacao-rastreabilidade-territorial.md","12206","904787c7040c29f7410d599fe357319afc559baba5c68dc319ade17d21e801d4","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\v2\ativacao-segunda-entrega.md","8837","c8acd38715c26b13b563afbc8ee02851c929af9448d2e78cb1656d16988803d7","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\v2\backlog-mestre.md","49028","8bcc5e66de95426dbb291d8a380e86d0f4a3ef0e3e70b48ad6c7d9e31893c7b3","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\v2\consolidacao-nove-diferencas.json","10320","d9f474c0dcae06e78b71c720611b16a2a0ec0d6b83bfd9c83558781eb130f0cf","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\v2\consolidacao-variantes.md","7958","3defe7f46aeaa37da2f06f5c358da83f48ff4656566d4044bfe7cfb0ad50d5b2","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\v2\ficheiros-primeira-entrega.csv","15338","b8c6eefb8fe879df7637bcda4aa4d458254edd82aceaa86991b5d885c046ee0a","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\v2\ficheiros-segunda-entrega.csv","3345","a7445854213ad91cf5a929237dc7c2ab2f2f682f5eb014cd10c4f9623ac30d20","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\v2\gestao-oportunidades-dashboard.md","13951","a12b57985e779180860983968922941bac9db3ab91aa4977d4ccf2b5b6d74997","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\v2\indice-documento-mestre-atual.csv","151889","35ffb5d727f8ab1811ac946c2f89c2e95a74108b9a9cfbdd688a29fffee6080f","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\v2\indice-documento-mestre.csv","153757","4c13f1efd25a130c0d63e4a7f2efd9f9c2fbe9eb7ddee452534f06e8d7759bdd","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\v2\oportunidades-correspondencias.md","15378","3812fe47bf667a5323363cbfc7c0b329c1f717f4ea814a6e3c454e6624224a72","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\v2\origem-oportunidades-e-separacao.md","7039","83c37556b898e3e2f52b272f515d2e10830218b133298dd7086c6b380bae418c","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\v2\primeira-entrega.md","12287","91af08a26aff26afd420c3fd9164d391014ef224b19db5dbe0f00758a2ecc571","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\v2\primeiro-percurso-ativo.md","17401","432b134b6aec7612776d510fcc9c38d8d566eadf821928994b60ed717e0eb84d","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\v2\qualidade-territorial.md","48392","6bf7866d3946b6c99f8c3ba2c6bc0b633d54d4da5b9369a4883e06d6e30bffa8","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\v2\reconciliacao-documental.md","5009","dab706f8e0b6a66e6cd3fde2bc8989d9f56bd6ad3f4e34f9fec52db6e38eaec4","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\v2\reconciliacao-fontes-territoriais.md","97710","3733136a7a2696b2cea4e9ac4ba5e0891369ff8969497ed87cd2962084323ee4","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\v2\recursos-oportunidades.md","10792","7829ad26ad1060710426706b05c9dfbdf1912a08ca190b23c8662bba5827c632","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\v2\releitura-documento-mestre.md","3985","e7f743c0e28a07146e391e20675360c52ba9272cbc4875e8d74b7116946e590b","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\v2\repeticoes-reconciliacao-atual.json","235914","9166ebb15935153b33f60021a8b008ab8479ca0671640af28a9e87138bfd5758","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\v2\repeticoes-reconciliacao.json","278145","1f49b0ae5e4cfd95c60011d6af4a16a5d6f7ea2c13446ff1d5224ea66343fe59","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\v2\repositorio-legal-jornada.md","3245","1729692568c02aba71f246e20e842175bbb78795645f762091e679f3fe77b056","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\v2\revisao-funcional-transversal.md","11226","90ed3ac0021863aa92a864e1cef754ec45e16667f595a7fd26f771290325e44c","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\v2\revisao-origem-oportunidades.md","5942","1feddb2d78b8a04f2aa46151784a3643ceea08b7f9b52935ff336745263a4cdf","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\validation-results.json","5131","8a35788bfda5fd7782f269f60c963b909e152d55880d3d090cc960a5d52a8605","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\validation.md","2958","b9d1ec9d4f8f8879ce9c650a8ba59a811065fe7b7e3f53f201fb64151533fec2","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\verification.sql","1732","d15685b13971cb526cdcef65c8511e79f9de7da28074450dea1bb5654bc69596","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\zones\baseline-data.json","3528","72736fbe37f8237fad1ee0a1f6dd97709c8d0464862d2635a6ef51c6bf8b18fc","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\zones\baseline.md","7117","db6df0dff91244ff950acbc9a285b4bb17038d9514141e236c12286cbe97b617","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\zones\browser-validation.json","2976","b89e20bb6f0710e9e1ef0e7392790320da1bea936463a3bbc205dc9b2016c12c","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\zones\current-data.json","3910","81d25d5de6f22a01c55b8e945efd6626c9ca61bf9039cc93995ff00cbbf1a9fb","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\zones\data-dictionary.md","4418","d851147c7b36b738a92f91f6c697e49d4b5855ce42a474ffa9e672c90f445986","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\zones\diagnosis-and-adr.md","7962","c5a1a40aa17d2793d5c529a634770d2ca3f934ba18677703d741ef800907935f","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\zones\implementation-status.md","7694","263b86d4eeb98c7996674a0a26e070c50c4f6f7638ac1c4d810262ac0adafc19","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\zones\industrial-parks-reconciliation-2026-10-04.md","12705","b6aad32e2330edabd8f7c06e7cd75dc7a8faf5dd1be657676e9db5670d1648e9","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\zones\integration-2026-10-04.md","10944","a74fe74d871f0692ecfbfc79a62309e0fda9bec5cb43757897cf589aafbee076","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\zones\legal-matrix.md","2918","1178627b7f57c31e837688360cf0d2dc02b010a0114f3a8007c25e7fa843c0a1","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\zones\openapi.json","93753","314cc7171e75d37d22afc9042e175db71b373bb94c0d1becc4c08fc1a73d414d","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\zones\operations.md","5020","d0480f301875b84f144e272b2a41c67cf2d13bc15ffd8fb5141e8d4c5c584f66","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\zones\phase-1-attachments-qa-2026-10-04.md","6110","abfb7a9925886f5c4faa88350038f13babf8cc2bc27cf49c1e9e9d92db700bc8","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\zones\plan-and-traceability.md","11977","4516ea21664f2c0b56f5185515b6e05a1292377a92d0fe4123b1ed97639f3c10","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\zones\README.md","3529","cab2d4152ffd7772bab56c5caa98261ad497be58696594fc9e0d4d9e909aeb88","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\zones\validation.md","2987","bcf73cbc4ef5ef4660ab008c64f348ba3c2e3d77d15ec0c04617fe851d11080d","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\docs\investmoz\zones\zone-catalog-active-empty-2026-10-04.png","79809","285108e8ac37bd2ccf546d67f72d9f73aed3f9ff26597d68db0ffb514b163855","original","","Documentação do repositório","Nenhum cálculo ativado pela auditoria","Situação documental não determinada por inventário",""
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\investmoz-v2\portal-audit\arcgis-moz-adm1.json","15442","41efdc512ba971d6ca3b447d929e04c86d85ea8af1dc6c13bde419ec4533e448","original","","Metadados/candidato geográfico inventariado; seleção e publicação não inferidas","Nenhum cálculo ativado","Vigência atual indeterminada; edição histórica preservada",""
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\investmoz-v2\portal-audit\arcgis-moz-item.json","1513","4f95009b98c7979fecfa0986a38bf77e660376f98bcfd70d7369bbf363298af3","original","","Metadados/candidato geográfico inventariado; seleção e publicação não inferidas","Nenhum cálculo ativado","Vigência atual indeterminada; edição histórica preservada",""
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\investmoz-v2\portal-audit\arcgis-moz-service.json","5929","67168029d5f559d926b8b3c432729a8973cf1dd2868826e86d756a0c53c2ea4c","original","","Metadados/candidato geográfico inventariado; seleção e publicação não inferidas","Nenhum cálculo ativado","Vigência atual indeterminada; edição histórica preservada",""
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\investmoz-v2\portal-audit\arcgis-source-search.json","30681","247f600f88a30a7052c62b489d98889e49f55f75759c07d3f8e992418ef5cf0a","original","","Metadados/candidato geográfico inventariado; seleção e publicação não inferidas","Nenhum cálculo ativado","Vigência atual indeterminada; edição histórica preservada",""
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\investmoz-v2\portal-audit\moz-adm1-ine-20190607.geojson","5254315","ce5cd5f6090b7ba9ac78f919c9dd149f6c7880ab8275051a3398b1c6593fa989","original","","Exemplar INE/UNOCHA 2019-06-07 conservado privadamente em QA; fonte oficial identificada aceite; publicação/vigência atual não inferidas","Nenhum cálculo ativado","Vigência atual indeterminada; edição histórica preservada","2019-06-07"
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\investmoz-v2\portal-audit\moz-adm1-ine-metadata.html","5769","de118cda24c594402adda6f11143ce236f928502b096cca45be7f5897b3ecbcf","original","","Exemplar INE/UNOCHA 2019-06-07 conservado privadamente em QA; fonte oficial identificada aceite; publicação/vigência atual não inferidas","Nenhum cálculo ativado","Vigência atual indeterminada; edição histórica preservada","2019-06-07"
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\investmoz-v2\portal-audit\moz-adm2-ine-20190607.geojson","18086741","16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707","original","","Exemplar INE/UNOCHA 2019-06-07 conservado privadamente em QA; fonte oficial identificada aceite; publicação/vigência atual não inferidas","Nenhum cálculo ativado","Vigência atual indeterminada; edição histórica preservada","2019-06-07"
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\investmoz-v2\portal-audit\moz-adm2-ine-metadata.html","5958","5df480267f2bc98a734d6a0a9b2531ded59cea715501006d2f869c35a12cd420","original","","Exemplar INE/UNOCHA 2019-06-07 conservado privadamente em QA; fonte oficial identificada aceite; publicação/vigência atual não inferidas","Nenhum cálculo ativado","Vigência atual indeterminada; edição histórica preservada","2019-06-07"
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\investmoz-v2\portal-audit\moz-adm3-ine-20190607.geojson","26773796","ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635","original","","Exemplar INE/UNOCHA 2019-06-07 conservado privadamente em QA; fonte oficial identificada aceite; publicação/vigência atual não inferidas","Nenhum cálculo ativado","Vigência atual indeterminada; edição histórica preservada","2019-06-07"
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\investmoz-v2\portal-audit\moz-adm3-ine-metadata.html","6063","1366696c41e95fd3ffaa7190764e7bee82ad5cacc062d9f66b74090bb0da7431","original","","Exemplar INE/UNOCHA 2019-06-07 conservado privadamente em QA; fonte oficial identificada aceite; publicação/vigência atual não inferidas","Nenhum cálculo ativado","Vigência atual indeterminada; edição histórica preservada","2019-06-07"
|
||||
"C:\laragon\www\portal-investidor\storage\app\private\investmoz-v2\portal-audit\unfpa-moz-adm1.json","15458","a723d8745e6c1b66f5b374839dba9863ead819f2e65279b1bbd32a8cee8db47a","original","","Metadados/candidato geográfico inventariado; seleção e publicação não inferidas","Nenhum cálculo ativado","Vigência atual indeterminada; edição histórica preservada",""
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\O InvestMoz deve funcionar como um assistente de investimento orientado por etapas e regras de aplicabilidade.docx","1327814","aa13c53138ec15cd808de43d9dc2fc6808da86943d09d3352c9dd0944bdae364","original","","Exemplar integral lido para proposta; publicação não inferida","Especificação funcional; nenhum cálculo ou regra jurídica ativados","Documento de programação do responsável, não diploma oficial","Exemplar identificado por SHA256; data/edição interna não identificada"
|
||||
"C:\Mac\Home\Documents\TEMPO\Portal Tempo\Servicos Tempo\Relatorios\O InvestMoz deve funcionar como um assistente de investimento orientado por etapas e regras de aplicabilidade.docx#word/media/image1.png","1288315","1da7d5a84162f3a4772e1f58a5dc4af701694e92ee3110a6530288916f728d80","anexo embebido","","Exemplar integral lido para proposta; publicação não inferida","Especificação funcional; nenhum cálculo ou regra jurídica ativados","Documento de programação do responsável, não diploma oficial","Exemplar identificado por SHA256; data/edição interna não identificada"
|
||||
|
@@ -0,0 +1,221 @@
|
||||
ADM,PCODE da fonte,Nome da fonte,Pai na fonte,Motivo,Candidatos inequívocos,SHA256 do exemplar
|
||||
1,MZ05,Maputo,,unresolved_no_implicit_translation_or_parent_mapping,0,ce5cd5f6090b7ba9ac78f919c9dd149f6c7880ab8275051a3398b1c6593fa989
|
||||
1,MZ06,Maputo City,,unresolved_no_implicit_translation_or_parent_mapping,0,ce5cd5f6090b7ba9ac78f919c9dd149f6c7880ab8275051a3398b1c6593fa989
|
||||
2,MZ0501,Boane,MZ05,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ1002,Cahora Bassa,MZ10,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0801,Chimbonila,MZ08,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0206,Chongoene,MZ02,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0502,Cidade Da Matola,MZ05,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0601,Cidade De Maputo,MZ06,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ1104,Derre,MZ11,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ1007,Doa,MZ10,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0703,Erati,MZ07,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0704,Ilha De Moçambique,MZ07,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0804,Ilha Licom,MZ08,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0805,Ilha Risunodo,MZ08,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0807,Lago Niassa,MZ08,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0706,Larde,MZ07,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0209,Limpopo,MZ02,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0707,Liúpo,MZ07,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ1109,Luabo,MZ11,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0405,Macate,MZ04,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0503,Magude,MZ05,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0211,Mandlakaze,MZ02,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0504,Manhiça,MZ05,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0212,Mapai,MZ02,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ1112,Maquival,MZ11,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ1010,Marara,MZ10,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0505,Marracuene,MZ05,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0506,Matutuine,MZ05,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0310,Maxixe,MZ03,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0109,Metuge,MZ01,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0507,Moamba,MZ05,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ1115,Mocubela,MZ11,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ1116,Molumbo,MZ11,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ1119,Mulevala,MZ11,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0719,Nacala,MZ07,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0720,Nacala-A-Velha,MZ07,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0508,Namaacha,MZ05,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0817,Ngauma,MZ08,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0722,Rapale,MZ07,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ0412,Vanduzi,MZ04,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
2,MZ1015,Zumbu,MZ10,unresolved_no_implicit_translation_or_parent_mapping,0,16781986ac938bc8e81c9ca01a076b4bd46e333e8877645844d0cc7cd2919707
|
||||
3,MZ110101,Alto Molocue,MZ1101,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ070301,Alua,MZ0703,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ072201,Anchilo,MZ0722,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ070101,Angoche,MZ0701,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ111501,Bajone,MZ1115,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ041101,Bazua,MZ0411,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050601,Bela Vista,MZ0506,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050101,Boane,MZ0501,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ070103,Boila,MZ0701,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ090201,Caia,MZ0902,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050401,Calanga,MZ0504,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ020801,Caniçado,MZ0208,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050602,Catuane,MZ0506,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050801,Changalane,MZ0508,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ101301,Charre,MZ1013,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ021101,Chibonzane,MZ0211,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ020204,Chibuto,MZ0202,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ020901,Chicumbane,MZ0209,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ021102,Chidenguele,MZ0211,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ020401,Chigubo,MZ0204,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ080101,Chimbonila,MZ0801,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ110201,Chinde,MZ1102,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ100201,Chintholo,MZ1002,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ100901,Chinthopo,MZ1009,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ100301,Chipembere,MZ1003,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ101102,Chiputu,MZ1011,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ020902,Chissano,MZ0209,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ100202,Chitima,MZ1002,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ040601,Chitobe,MZ0406,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ010301,Chiure,MZ0103,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ020501,Chokwe,MZ0205,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ020601,Chongoene,MZ0206,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ090601,Cidade Da Beira,MZ0906,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050201,Cidade Da Matola,MZ0502,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ040201,Cidade De Chimoio,MZ0402,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ030101,Cidade De Inhambane,MZ0301,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ080201,Cidade De Lichinga,MZ0802,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ060101,Cidade De Maputo,MZ0601,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ070201,Cidade De Nampula,MZ0702,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ010401,Cidade De Pemba,MZ0104,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ100601,Cidade De Tete,MZ1006,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ072001,Covo,MZ0720,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ080301,Cuamba,MZ0803,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ110401,Derre,MZ1104,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ020402,Dindiza,MZ0204,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ100701,Doa,MZ1007,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ090701,Dondo,MZ0907,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ080302,Etarara,MZ0803,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ090801,Gorongosa,MZ0908,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ040401,Guro,MZ0404,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ110601,Gurue,MZ1106,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ030401,Homoine,MZ0304,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ010501,Ibo,MZ0105,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ070401,Ilha De Moçambique,MZ0704,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050402,Ilha Josina Machel,MZ0504,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ080401,Ilha Licom,MZ0804,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ080501,Ilha Risunodo,MZ0805,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ011202,Imbuo,MZ0112,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ030501,Inharrime,MZ0305,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ110802,Inhassunge,MZ1108,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ081701,Itepela,MZ0817,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ071302,Iuluti,MZ0713,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ101201,Kambulatsisi,MZ1012,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ010203,Kuekue,MZ0102,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ080701,Lago Niassa,MZ0807,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ070501,Lalaua,MZ0705,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ070601,Larde,MZ0706,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ080102,Lione,MZ0801,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ070701,Liúpo,MZ0707,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ110901,Luabo,MZ1109,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ070402,Lumbo,MZ0704,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ081901,Lussimbesse,MZ0819,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ081201,M'Sawize,MZ0812,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ011501,M'Tamba,MZ0115,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ021002,Mabalane,MZ0210,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ040501,Macate,MZ0405,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050501,Machubo,MZ0505,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ020101,Macia,MZ0201,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ010602,Macomia,MZ0106,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ021103,Macuacua,MZ0211,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ112001,Macuze,MZ1120,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ020602,Madzucane,MZ0206,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ111101,Maganja,MZ1111,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050301,Magude,MZ0503,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050302,Mahele,MZ0503,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ020102,Makluane,MZ0201,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ080801,Malanga,MZ0808,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ070802,Malema,MZ0708,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ101104,Malowera,MZ1011,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050403,Maluana,MZ0504,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ040402,Mandie,MZ0404,unresolved_no_implicit_translation_or_parent_mapping,2,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ080901,Mandimba,MZ0809,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ021104,Mandlakaze,MZ0211,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050404,Manhiça,MZ0504,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ040802,Manica,MZ0408,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ021201,Mapai,MZ0212,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050303,Mapulanguene,MZ0503,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ111201,Maquival,MZ1112,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ101001,Marara,MZ1010,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050502,Marracuene,MZ0505,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ081002,Marrupa,MZ0810,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ081702,Massangulo,MZ0817,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050102,Matola Rio,MZ0501,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ041201,Matsinho,MZ0412,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ081202,Mavago,MZ0812,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ031001,Maxixe,MZ0310,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ071103,Mazula,MZ0711,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ081402,Mecula,MZ0814,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ080103,Meponda,MZ0801,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ110603,Mepuagiua,MZ1106,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ010102,Mesa,MZ0101,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ080604,Metangula,MZ0806,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ010901,Metuge,MZ0109,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ110202,Micaune,MZ1102,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ010902,Mieze,MZ0109,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050701,Moamba,MZ0507,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ111401,Mocuba,MZ1114,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ111502,Mocubela,MZ1115,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ030502,Mocumbi,MZ0305,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ111601,Molumbo,MZ1116,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ071402,Moma,MZ0714,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ071502,Monapo,MZ0715,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ011103,Montepuez,MZ0111,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ071603,Mossuril,MZ0716,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050304,Motaze,MZ0503,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ100902,Mphende,MZ1009,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ100402,Mualadze,MZ1004,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ112301,Mualama,MZ1123,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ031102,Mucoduene,MZ0311,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ070602,Mucuali,MZ0706,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ071702,Muculoene,MZ0717,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ011203,Mueda,MZ0112,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050603,Mugazine,MZ0506,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ111901,Mulevala,MZ1119,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ041002,Muoha,MZ0410,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ072202,Mutivasse,MZ0722,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ101501,Muze,MZ1015,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ011404,N'Cumpe,MZ0114,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ011204,N'Gapa,MZ0112,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ071901,Nacala,MZ0719,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ072002,Nacala-A-Velha,MZ0720,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050802,Namaacha,MZ0508,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ072203,Namaita,MZ0722,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ111403,Namanjavira,MZ1114,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ070302,Namapa,MZ0703,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ071304,Nametil,MZ0713,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ071201,Namige,MZ0712,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ070303,Namiroa,MZ0703,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ011405,Namuno,MZ0114,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ071305,Nanhupo Rio,MZ0713,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050604,Ndelane,MZ0506,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ020603,Nguzene,MZ0206,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ090802,Nhamadze,MZ0908,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ040703,Nhamagua,MZ0407,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ112201,Nicoadala,MZ1122,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ100403,Nsadzu,MZ1004,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ101401,Ntengo-Wa-Mbalame,MZ1014,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ011601,Olumbi,MZ0116,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050405,Palmeira,MZ0504,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050305,Panjane,MZ0503,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050702,Pessene,MZ0507,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ070702,Quinga,MZ0707,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ072204,Rapale,MZ0722,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050703,Ressano Garcia,MZ0507,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050704,Sabie,MZ0507,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ090103,Sofala,MZ0901,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ100203,Songo,MZ1002,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ091003,Subwe,MZ0910,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ100102,Ulongue,MZ1001,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ081904,Unango,MZ0819,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ041202,Vanduzi,MZ0412,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ020302,Vila Eduardo Mondlane,MZ0203,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ021105,Xhalala,MZ0211,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050406,Xinavane,MZ0504,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ101502,Zambue,MZ1015,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ040502,Zembe,MZ0405,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ050605,Zitundo,MZ0506,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ020903,Zongoene,MZ0209,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
3,MZ101503,Zumbu,MZ1015,unresolved_no_implicit_translation_or_parent_mapping,0,ef11737c1ef68870bfcee67903352b7e554cb40ca39dd85f020c2a13631e1635
|
||||
|
File diff suppressed because one or more lines are too long
@@ -0,0 +1,185 @@
|
||||
# Plano consolidado de ativação — lote 3
|
||||
|
||||
## C37 — causa confirmada; seleção de conta QA corrigida — P0, visual pendente
|
||||
|
||||
O pedido de reabertura referia a conta esperada18. A captura manual21:22–21:24UTC demonstra que foi selecionada a conta13 restaurada. O MFA foi alcançado, mas a autenticação nunca se completou. Causa concreta: credenciais MFA da conta13 cifradas pela chave de origem, incompatíveis com a chave estávelQA; a conta18 sintética não foi desafiada nessa tentativa. Nenhuma chave, MFA ou conta13 foi alterada para contornar o problema.
|
||||
|
||||
| UTC09/10 | Pedido | Resultado observado |
|
||||
|---|---|---|
|
||||
|21:22:10|GET/investimentos|302/login; sessão convidada guardada, destino pretendido /investimentos.|
|
||||
|21:22:11|GET/login|200; mesmo cookie/sessão, sem autenticação.|
|
||||
|21:22:44|POST/login|302/two-factor-challenge; login.id=13, não18.|
|
||||
|21:22:44|GET/two-factor-challenge|200; desafio13 recuperado da mesma sessão; ecrã confirmado pelo utilizador.|
|
||||
|21:23:04|POST/two-factor-challenge|Falha de desencriptação; warning correlacionado conta13;302/login, invalidação intencional e nova sessão convidada.|
|
||||
|21:23:04|GET/login|200; cookie aceite corresponde à sessão regenerada; sem utilizador autenticado.|
|
||||
|
||||
Primeiro desvio do ensaio: POST/login desafia13. Primeira falha técnica: POST/two-factor-challenge às21:23:04 (trace ec68d040a3291cb8, referência26e15b04-07b8-4211-a2a0-7f70509e03f6). Não se tratou de código MFA rejeitado pelo verificador nem de perda após autenticação. Os dois campos cifrados (secret/recovery) são incompatíveis; como nenhum corpo foi retido, não se afirma qual modalidade de entrada foi usada nesta tentativa. Não foram observados conflitos de cookies, mudança de chave/guard ou redirecionamento para outra origem.
|
||||
|
||||
CorreçãoQA, após guarda real desk_restore_20261009_174726_test:55441: login identifica/preenche o email não secreto da conta18; o ecrã MFA identifica a conta realmente desafiada. PortalQaAccountSelection, carregado exclusivamente pelo routerQA, recusa endereços não sintéticos antes do desafio e cancela desafios antigos de contas restauradas, com erro controlado. Os perfis sintéticosQA mantêm o login Fortify normal e respetivo MFA. Contas restauradas e dados ativos preservados. A conta13 continua cifrada como no original; não foi reencryptada nem usa chave ativa como fallback.
|
||||
|
||||
Lacuna de feedback encontrada no código: o Form recém-criado no login começa com erros locais vazios e não lia o errors.email devolvido pela página após redirecionamento do MFA. Login agora apresenta também esse erro da página. A mensagem de falha de desencriptação continua controlada e não autentica; sua apresentação visual ainda exige confirmação.
|
||||
|
||||
Evidência atual2026-10-09T21:37:04.282708+00:00 em c37-auth-redirect-qa.json, pelo servidor18097 e protocolo Inertia/HTML com redirects reais: seletor13 recusado antes do MFA; desafio18 identificado; código inválido mantém desafio sem autenticar; MFA válido regenera/grava18 e redireciona /investimentos; GET e reload mantêm18; logout revoga acesso; novo cookie jar+login+MFA recupera o mesmo dossier413ba1f6-bdf6-402a-a561-c4e2d4098d1a; outra conta403. Negativo sintético19 demonstra falha de desencriptação→login com mensagem, sem autenticação. Nenhuma criação extra de dossier. Estes são resultados de resposta/persistência, não um ensaio visual bem-sucedido.
|
||||
|
||||
Evidências: c37-manual-2122-2124-qa.json conserva os seis pedidos e warning sanitizados; auth-session-trace-qa.jsonl mantém histórico append-only e pseudónimos HMAC; c37-qa-account-auth.xml verifica políticaQA, preservação, MFA válido/inválido e falhas secret/recovery; c37-installation-auth-fingerprint.xml verifica guardas/importação/reversão. TypeScript e build passaram. mfa-persistence-qa.json reconfirma conta13 e .env byte a byte, MFA18 confirmado/oito códigos, chave não gerada/rodada e zero escritas ativas. Cookies, passwords, OTP e corpos não são exportados.
|
||||
|
||||
Estado: causa identificada, preparaçãoQA corrigida e protocolo/persistência demonstrados; C37 permanece aberto para /investimentos visível→reload→logout→novo login da conta18 no navegador. A captura manual demonstrou apenas o MFA da conta13 e retorno ao login; não certifica o percursoA/B nem o feedback atualizado. Próximo teste deve confirmar que o ecrã diz contaQA18 antes de usar o autenticador dessa conta. URL exato http://127.0.0.1:18097/investimentos. Credenciais/segredo permanecem somente no ficheiro privado local investor-mfa-qa-private.json, sem exportação. Workflow/contratos especializados continuam no backlog, sem jornadas educativas novas.
|
||||
|
||||
Ativação não autorizada e revisão candidata não fixada. Fingerprints agora incluem também login.tsx e two-factor-challenge.tsx: percursob402e851b49bfb640f26417f1ff783320210271cd7d84e80dea0db264c89ec28; cartografia95610d2660956a9bb10e6ac9443c24ededf4f3d97f996047c92a5d5c37ff3c6c; recursos4aa6946228b5ebb99bb29e3166e9ce53abdba776b3298a9ccbe437784d8cfa02. Ready/provas de versões anteriores não demonstram esta revisão. Política/seletor/rastreioQA não integram instalação ativa. Após aceitação visualA/B e correções, renovar backup/restauro/compatibilidade e manter a ordem já documentada de recursos→percurso→flag→importação cartográfica→publicação separada, sem repetir o que estiver instalado. ReversãoQA: retirar registo/configuração de PortalQaAccountSelection e overrides Fortify do router; retirar os registos de rastreio; preservar provas. A correção do feedback é código compatível sem migration, alteração de chave ou modificação de dados.
|
||||
|
||||
## C37 — revisão ainda sem candidatura ou ativação
|
||||
|
||||
Correção MFA é código, não migration/importação/publicação. Aplicação e preparação QA usam chave estável existente; não executar key:generate nem rekey dos dados. Conta13 ativa/copiada preservada; contas sintéticas e invalidação de sessões exclusivamenteQA. Fingerprints incluem bootstrap/app.php e configuração/provider Fortify; provas antigas devem ser renovadas depois da retoma visual A/B e correções. Ordem de recursos030000, percurso190000, flag e cartografia/divulgação continua no plano abaixo, sem repetir instalações. Ação ativa não autorizada.
|
||||
|
||||
## Importação C30 — ações exatas e dependências
|
||||
|
||||
Esta sequência é preparação, fora da autorização ativa atual. Antes de cada ação reconfirmar alvo/ledger/contagens; números abaixo são previsão do último retrato, não valores a forçar.
|
||||
|
||||
1. Incorporar A/B e consumidores manuais, corrigir falhas, repetir provas pertinentes e fixar revisão/manifest/fingerprints. Hoje continuam pendentes.
|
||||
2. Renovar backup de DB/ficheiros privados/chaves e originais cartográficos/metadados; restaurar em nova QA com guarda, comparar schema/contagens/hashes/IDs/relações/classificações/RLS. Preservar prova anterior. Validar reversão vazia e recusa após uso. Preparar prova específica cartográfica a partir dessas evidências e resultados manuais; não fabricar `ui_passed=true`.
|
||||
3. Disponibilizar código/assets, mantendo `INVESTOR_PATH_ENABLED=false` e `TERRITORY_GEOMETRY_IMPORT_ENABLED=false`.
|
||||
4. Gestor autenticado: GET/POST `/management/opportunity-resources-install`, somente se030000 ausente. Previsto3tabelas de associação+1coluna de documents+função/3triggers;0recursos novos automáticos. Não repetir gestão/Balcão/Bolsa já instalados.
|
||||
5. GET/POST `/management/balcao-install`, somente migrations realmente pendentes, prevista190000.2colunas+1definição imutável;0conversões/dossiers/steps automáticos. Prova visual da revisão é pré-condição; instalar não disponibiliza percurso.
|
||||
6. Habilitar separadamente `INVESTOR_PATH_ENABLED` após schema/provas; novos dossiers instanciam19etapas nas5fases sem renumerar roteiros. Rollback imediato: flagfalse preservando dados e ferramentas diretas.
|
||||
7. Preparar `geometry-import-activation-proof.json`, vinculada ao fingerprint cartográfico, alvo real, QA/UI e backup restaurado/hash/data<24h; configuração específica habilita rota, não equivale a aplicar. Este artefacto final não foi emitido. Gestor com MFA: GET `/management/territory-geometry-import?level=1`, rever linhas/hash; POST `/management/territory-geometry-import` com level/hash/idempotency_key/reason/confirm. Repetir2 só após pais1, depois3. Se prévia conservar todas as correspondências e ativo0:9+120+232=361 geometrias privadas novas;0territórios/locais/pontos novos. Hoje QA reutilizou361 e inseriu0. Fonte/scan expirado exige atualização da prova por bytes, não revalidação de credibilidade oficial.
|
||||
8. Publicação de camadas por consumidor/âmbito é ato separado. O importador não tem comando de publicação. Não alterar para public nem usar publicação de zonas de investimento para publicar limites administrativos; mecanismo de divulgação correspondente permanece no backlog quando necessário.
|
||||
|
||||
Reversão do lote: POST `/management/territory-geometry-import/{batch}/reverse`, com MFA, idempotency_key/reason/confirm. Só faz exclusão lógica das geometrias criadas por esse lote, intactas e sem FK consumidor; preserva361 reutilizadas, originais, receipts e auditoria. Se houver uso/alteração/publicação, recusa e exige reconciliação, sem apagar relações. Rollback de migrations030000/190000 apenas vazio; após utilização desligar disponibilização e preservar dados. Restauro integral nunca sobrescreve escritas posteriores sem reconciliação/autorização.
|
||||
|
||||
## Sequência atual — após demonstração e sem autorização ativa
|
||||
|
||||
Plano preparado, **não executado**. A/B HTTP/nova sessão real passaram; interface ainda pendente. Por isso não renovar o backup final como se a demonstração visual estivesse concluída nem considerar pronta a ativação. A revisão atual alterou fingerprints: percurso `ba3781ad7af15b02c3021e69081f4129a2a19339fd740094d39e913f3657977c`; recursos `2d3b517a4b37af385b1f128a0d2be2dd17b82eeee9f23b2429132d9b7360311d`. Provas anteriores preservadas e insuficientes para esses hashes. `activation_ready=false`.
|
||||
|
||||
| Ordem | Ação exata futura | Dependência/efeito esperado | Verificação e reversão |
|
||||
| --- | --- | --- | --- |
|
||||
| 0 | Concluir roteiro QA A/B e consumidores; fixar revisão/assets/hashes | Interface com nova sessão/perfis/resultados; nenhuma mistura. Não usar contagem global como substituto. | Registar cada critério na mesma matriz; se mudar código relevante, repetir respetiva demonstração. |
|
||||
| 1 | Renovar dump + ficheiros privados e restaurar numa nova base loopback*_test:55441; ensaiar compatibilidade/reversão sobre essa cópia | Origem ativa apenas READ ONLY; destino QA com guarda. Usar mecanismos de backup existentes, incluindo tools/desk-activation-backup.php; preservar prova antiga antes de substituir. Comparar schema, contagens, hashes por tabela, ficheiros/chave privada, órfãos/relações/RLS.288tabelas/5ficheiros são baseline histórico, não contagem a forçar. | Repetir ensaio vazio e recusa depois de uso; gerar provas para ambos os fingerprints sem fabricar true nem copiar flags visuais de outra versão. Não renovar/aplicar no ativo agora. |
|
||||
| 2 | Disponibilizar correções/assets desta revisão, mantendo INVESTOR_PATH_ENABLED=false | Países/origem/filtros/maturidade/C27; sem reclassificar valores legados, sem novo dado por deploy. | Confirmar assets servidos; rollback de código compatível preserva novos payloads/histórico. |
|
||||
| 3 | Conta ativa autorizada: GET `/management/opportunity-resources-install`, confirmar prévia atual, depois POST nessa rota **somente se030000 estiver ausente** | `2026_10_09_030000_extend_opportunity_resources`:3tabelas de associação existentes no desenho,1coluna em documents,1função/3triggers,1migration/evento;0recursos/documentos/localizações novos automaticamente. Backup/restauro/compatibilidade/hash/permissões. | Ler ledger/evento/autor/hash e comparar dados/classificações/relações/originais. Não repetir instalação como ensaio. Down só sem recursos/originais cifrados; após uso preservação/exportação antes de recuperação. |
|
||||
| 4 | GET `/management/balcao-install`, conferir apenas migration190000 pendente; POST autenticado pela mesma rota |2colunas nas entidades atuais +1definição publicada imutável +ledger/evento.0conversões de journeys antigos,0dossiers/etapas/tarefas criados. `pathQaVerified` exige API e A/B visual dessa revisão. Não repetir migrations básicas do Balcão/Bolsa/gestão já instaladas. | Schema/definição/ledger/evento/hash; instalação não habilita percurso. Down recusa após uso; preservar definição/história/RLS. |
|
||||
| 5 | Em ação de configuração/deploy separada, habilitar INVESTOR_PATH_ENABLED e atualizar configuração servida | Só depois de schema instalado e QA visual da versão. Mostra `/investimentos`/painel; instancia19etapas apenas ao criar novo dossier, sem renumerar roteiros. | Confirmar rotas/layout/perfis/recuperação. Reversão imediata: desligar flag preservando dossiers, drafts, resultados, documentos, consentimentos, tarefas e eventos; ferramentas diretas mantidas. |
|
||||
| 6 | Prévia/aplicação **cartográfica autenticada**, lote oficial privado, em geo_geometries existentes | C30: GET/POST `/management/territory-geometry-import`, POST `/{batch}/reverse`; mecanismo preparado e demonstrado em QA. **Não existe prova ativa válida desta revisão agora**. Depende de prévia/hash/original/scan/dedup/conflitos. Se base continuar0 e todas as correspondências permanecerem inequívocas:361=9+120+232novos;0geo_locations/pontos/perímetros de investimento.2/39/179ficam de fora. | Guardar lote/origem/edição/IDs/autor/eventos; replay0novos. Não apontar portal-audit-geometry-qa.php ao ativo. Reverter acesso/arquivar apenas lote novo sem uso; preservar originais/relações/história. |
|
||||
| 7 | Disponibilizar camadas por consumidor/âmbito autorizado, ato separado de importar | Fonte aceite não é divulgação automática; edição2019/atualidade jurídica/administrativo vs implantação explícitos. Limites internos não podem aparecer publicamente para tornar o teste verde. | Conferir cada mapa/selector/perfil. Retirar camada/autorização sem apagar geometria ou histórico. |
|
||||
|
||||
ClamD é requisito de scan/reabertura/download/publicação dos binários afetados; arranque/assinaturas e cada derivada têm provas próprias. GD/WebP depende do PHP web. Não bloquear metadados, países, estatísticas ou preparação independente por estes itens. Nenhum cálculo fiscal ativado por importação/publicação.
|
||||
|
||||
Restauro integral ativo continua fora da autorização; antes dele reconciliar todas as escritas posteriores ao backup. A renovação após interface pode envolver leitura ativa/restoreQA, mas nenhuma instalação, importação, publicação ou sobrescrita ativa está autorizada.
|
||||
|
||||
## Histórico da versão anterior — separar preparação, instalação e disponibilização
|
||||
|
||||
**Nenhuma ação ativa foi autorizada ou executada.** Execução I1–I3 foi aprovada apenas em QA. O fingerprint atual do percurso é `e29eb8c4b11fce6aa78c798e24330bbf96efbea7ac2eb39c3f03b978caeef076`; recursos `1ac26c87ae1919cc8148fc550cd44596998cc5d1ce3b9ff2f08c11b7cc27b2c5`. Provas antigas/ready anteriores não abrangem esta versão.
|
||||
|
||||
Ordem detalhada, dependências, contagens e reversão: [plano no relatório da execução](execucao-percurso-i1-i3.md#plano-consolidado--ainda-não-autorizado-no-ativo). Preparar primeiro correções e aceitação UI; renovar backup/restauro/compatibilidade exatos; instalar recursos030000 somente se ausente; preparar percurso190000 via `/management/balcao-install`, que instala só ausentes e agora exige evidência A/B visual. +2 colunas/+1 definição/+0 dossiers/+0 etapas por instalação. Depois, disponibilização por `INVESTOR_PATH_ENABLED` separada e autorizada; importação cartográfica privada por lote próprio autenticado (mecanismo ainda pendente), previsão361 somente com prévia sem conflitos e base ainda0. Não repetir Balcão/Bolsa/gestão já instalada.
|
||||
|
||||
Reversão vazia em QA e preservação de167 tabelas públicas demonstradas. Após uso, `down` recusa apagar o percurso; desligar flag e preservar dados/eventos/versões. O núcleo fiscal também recusa apagar definição publicada antes de alterar RLS. Restauro integral futuro exige reconciliar dados posteriores ao backup. Browser indisponível mantém aceitação A/B pendente; `activation_ready=false` no dossier de evidências.
|
||||
|
||||
As informações abaixo pertencem aos lotes anteriores; instalar/publicar não ativa cálculo fiscal nem reabre a aceitação das fontes oficiais.
|
||||
|
||||
## Histórico anterior à execução — limite do plano então proposto
|
||||
|
||||
Este plano cobre os recursos e importação identificados na auditoria; **não autoriza nem certifica o futuro painel/modelo/motor das 19 etapas**. A [proposta](proposta-consolidacao-percurso.md) exige aprovação antes de I1–I3. I0, correções existentes, continua autorizado.
|
||||
|
||||
A alteração pontual C24 reutiliza uma URL de draft já existente e não instala schema. Cenários A/B não foram demonstrados. Depois de qualquer mudança estrutural aprovada, preparar preview de migrations/contagens/órfãos, preservar snapshots e renovar backup/restauro/compatibilidade antes do ato autenticado. Reversão pós-uso nunca apaga decisões, vínculos, consentimentos, documentos ou auditoria.
|
||||
|
||||
09/10/2026. Três grupos separados, nenhuma instalação/importação ativa executada. Preview 2026-10-09T17:50:07+00:00: installed=false,ready=true. QA global 381 testes/5046 asserções/zero skips; visual pendente.
|
||||
|
||||
| Grupo | Ordem/efeito | Dependência e contagem prevista | Reversão |
|
||||
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Correções de código/assets | Primeiro: país/origem/correção Balcão, consulta/preview de limites, maturidade draft/filtros já preparados | Sem migration; zero cadastros/relações/classificações reescritos; confirmar versão servida/assets e percursos | Reverter código compatível preservando novos payloads e versões, sem apagar campos novos |
|
||||
| Recursos privados | Depois: ação autenticada existente /management/opportunity-resources-install, migration2026_10_09_030000_extend_opportunity_resources uma vez | Backup/prova/fingerprint; tabelas/recurso privado da extensão, zero publicação automática. Não repetir instalações básicas. ClamD só para binários; GD web/derivadas específicos | Up/down demonstrado antes de novos dados. Depois de uso, preservar/consolidar novas escritas; não executar down que apague versões/ficheiros |
|
||||
| Importação cartográfica | Lote independente, preview/original/hash/scan/dedup/conflitos, escrita privada por mecanismo autenticado | Baseline ativo 0: 361=9+120+232 correspondências previstas; zero geo_locations novos, zero locais/pontos/perímetros de investimento. 2/39/179 não importados. Fonte 2019 não presume vigência atual | Identificar lote/origem/edição/IDs/eventos; arquivar/reverter apenas o lote novo não usado. Se houver novas relações/escritas, reconciliar antes de restaurar snapshot |
|
||||
| Camadas/divulgação | Ato separado de importação, com âmbito/edição e acesso por consumidor | Publicar só geometrias autorizadas; fonte aceite não implica publicidade automática. Contexto administrativo não autoriza zona/implantação. UI atual ainda pendente | Retirar camada/autorização sem apagar original/hash/histórico; preservar relações legítimas |
|
||||
|
||||
Backup/restauro **2026-10-09T17:47:35+00:00**, destino ativo investemoz:5432, cópia compatível **desk_restore_20261009_174726_test:55441**. 288 tabelas/cinco ficheiros iguais; reversão demonstrada. Fingerprint **8fe9cbf438a87315c1c20588bd9a748239018d0662af22533774e07f16a06cef**. Validade 24h; mudanças/expiração/destino exigem renovar provas pertinentes. Recursos ready=true não indica instalação nem aceitação funcional.
|
||||
|
||||
QA cartográfica preservada:desk_restore_20261009_171209_test:55441,361 limites internos, replay zero novos e consulta361/361 READ ONLY. Não é a cópia de compatibilidade dos recursos, não importar fixtures. O importador existente é deliberadamente QA-only. **Execução cartográfica ativa ainda precisa de preview/aplicação autenticados no mecanismo existente**; não há autorização para contornar essa condição com CLI ou converter o script QA em instalador ativo.
|
||||
|
||||
Antes do ato: verificar identidade/hash/validade/estado instalado e schema; preservar classificações IDs 1–6, relações 28/13, originais/histórico; obter contagens frescas para recusar duplicados/conflitos. Após cada ato, consultar migration/evento/autor/versão e comparar baseline. Dumps/.env/chaves privados. Nenhuma importação/publicação ativa cálculo fiscal.
|
||||
|
||||
Browser:QA 18096 responde HTTP200/_test, mas provider de UI ausente; Chrome/Edge indisponíveis após reset. Não certificar resultado visual. Fluxos ativos de revisão/publicação e contratos especializados continuam no backlog; não criados pela instalação de recursos.
|
||||
|
||||
## Histórico do lote 2 e anteriores — não representa o estado atual
|
||||
|
||||
# Plano de ativação autenticada — lote 2
|
||||
|
||||
09/10/2026. Preview READ ONLY 17:29:58 UTC: **installed=false, ready=true**. Preparação não é instalação ou conclusão funcional. Nenhum ato ativo executado nesta auditoria.
|
||||
|
||||
## Ordem e dependências reconciliadas
|
||||
|
||||
1. **Código/assets, sem migration:** maturidade versionada no draft, países/origem de negócios/fundiário, filtros/estatísticas, hierarquia fundiária e pesquisa. Reutilizam JSON/payloads cifrados/catálogos existentes; não convertem valores históricos. Verificar versão web/manifesto e percursos QA. ClamD e recursos não são dependências deste grupo.
|
||||
2. **Preview com conta autorizada existente:** `/management/opportunity-resources-install`; destino `investemoz:5432`. Backup/restauro verificado em **09/10/2026 17:29:44 UTC**, válido até **10/10/2026 17:29:44 UTC** sujeito a código/destino/guardas. QA de compatibilidade `desk_restore_20261009_172936_test:55441`, 288 tabelas/cinco ficheiros; up/down preservou baseline. Fingerprint **69252e258339bbef24d78681aaf78f968a281e85c5a103870f5d6363aca98831**. Mudança/expiração exige renovar provas pertinentes; não modificar prova para simular aceitação.
|
||||
3. **Só extensão pendente, uma vez:** ação autenticada aplica `2026_10_09_030000_extend_opportunity_resources`. Imagens/documentos/multilocalização privados ficam disponíveis; não publica, não atribui relação/classificação e não ativa cálculo. Confirmar por leitura migration/evento/autor/hash e conservação dos IDs 1–6, relações 28/13, ficheiros/histórico. Não repetir Balcão/Bolsa/gestão básica: cada um tem um evento de instalação.
|
||||
4. **Binários/derivadas afetados:** ClamD real 1.5.4 está disponível nesta sessão e integrações QA passaram. Arranque após reinício/atualização periódica, GD/WebP no PHP web e scan de cada derivada são provas específicas ainda pendentes. Não impedir metadados/países/origem/pesquisas por esta dependência; manter restrição concreta nos binários não verificados.
|
||||
5. **Geometria, independente:** QA `desk_restore_20261009_171209_test:55441` contém 361 geometrias internas de 2019, originals/hash/scan e correspondências inequívocas; replay zero novos. Esta cópia não é a cópia de compatibilidade de recursos. Não copiar fixtures, publicar camadas ou declarar atualidade jurídica por importar. Ativo continua zero; reconciliar camadas/consumidores/lacunas antes do ato autenticado de uso ativo pertinente.
|
||||
6. **Conteúdo/workflow real:** publicação/aprovação/contratos especializados e designações institucionais não surgem da extensão. QA avança sem pessoas inventadas; atos ativos usam contas/designações reais. Revisão visual retoma assim que o browser existir, sem declarar frontend observado agora.
|
||||
|
||||
QA global: 379 testes, 4.922 asserções, zero skips; 156 frontend/reconciliação; TypeScript/PHPStan/build/formato passaram. Escopo é preparação técnica/API/persistência, não aceitação integral do portal.
|
||||
|
||||
Reversão direta demonstrada **antes de novas escritas**. Depois de uso, preservar novos dados/eventos e reconciliar antes de down/restauro. Dumps, ZIP, .env/chaves permanecem privados. Provas: backup-proof, compatibility, activation-proof e resources-lote2-preview; não contornar autenticação ou impersonar conta ativa via CLI.
|
||||
|
||||
## Histórico da continuação anterior — não representa o estado atual
|
||||
|
||||
# Plano consolidado de ativação autenticada — atualização
|
||||
|
||||
09/10/2026. **Preparado por leitura; nenhuma instalação ativa executada.** Recursos `installed=false`, preview `ready=true` às 16:22:20 UTC. Prova anterior substituída, conservando histórico abaixo.
|
||||
|
||||
## Ordem, dependências e efeito
|
||||
|
||||
1. **Código/assets sem migration.** Países públicos/simulador, origem/estatísticas, Balcão hierárquico e pesquisa provincial reutilizam cadastros/payloads existentes. Efeito: recolher/guardar/recuperar novos valores, sem reescrever históricos. Confirmar versão servida/assets e percurso QA; visual pendente. ClamD não é dependência.
|
||||
2. **Preview com conta autorizada existente.** `/management/opportunity-resources-install`, destino `investemoz:5432`, fingerprint/validade. Backup/restauro **09/10 16:18:09 UTC / 18:18:09 locais**, 288 tabelas/cinco ficheiros; cópia `desk_restore_20261009_161758_test:55441`; up/down conservou hashes. Hash `c328f542acd9d83e8312b13a1e58317cf5e665fa5d728ea3cd132d58f9a9725f`; validade até **10/10 16:18:09 UTC**, sujeita a hash/destino/guardas. Não impersonar conta ativa via CLI.
|
||||
3. **Só extensão pendente, uma vez.** Ação autenticada aplica `2026_10_09_030000_extend_opportunity_resources`. Efeito: imagens/documentos/multilocalização privados; nenhuma publicação, classificação automática, relação territorial inferida ou cálculo fiscal ativado. Não repetir Balcão/Bolsa/gestão básica: uma instalação cada. Confirmar schema/evento e seis classificações/relações/histórico por leitura.
|
||||
4. **Binários/derivadas afetados.** ClamD real/assinaturas e integrações/EICAR só em QA; libertar binário com evidência exigida. GD/WebP do PHP web limita gerar derivadas e tem prova separada. Ausência mantém restrição nesses atos, sem bloquear metadados/localizações/drafts/catálogos/estatísticas nem reinstalar módulos.
|
||||
5. **Próximos dados/incrementos.** Geometrias concretas/autorizadas, relações por par/citação, maturidade versionada e drafts educativos têm preparação própria nas entidades existentes. A extensão de recursos não ativa funcionalidades ainda não implementadas. Não importar fixtures QA; designações reais só antes dos atos institucionais ativos.
|
||||
|
||||
QA: 373/376 testes, 4.608 asserções, três ClamD reais saltados; 152 frontend, TypeScript/PHPStan/build passaram. `ready=true` é prontidão técnica, não aceitação visual integral. Provas privadas: backup-proof/compatibility/activation-proof, `portal-audit/activation-evidence.json` e `resources-followup-preview.json`. Dumps, ZIP/.env/chaves não são anexos públicos.
|
||||
|
||||
Reversão direta demonstrada antes de novos dados/eventos. Depois do uso, preservar novas escritas e preparar reconciliação; não executar down/restauro por conveniência. Mudança de fingerprint ou expiração exige renovar provas pertinentes. Instalação/restauro ativo continuam atos autenticados/autorizados, não realizados pelo preparador.
|
||||
|
||||
## Histórico do plano anterior — substituído pela prova acima
|
||||
|
||||
# Plano inicial de ativação autenticada
|
||||
|
||||
Preparado em 09/10/2026. **Pronto por leitura; não aplicado na base ativa.** Cobre apenas recursos privados de oportunidades; não declara concluído o portal, workflow editorial, contratos especializados ou biblioteca.
|
||||
|
||||
| Elemento | Evidência atual |
|
||||
| ----------------- | --------------------------------------------------------------------------------------------------------- |
|
||||
| Destino | `investemoz:5432`, confirmado por leitura |
|
||||
| Ação existente | [Gestão → instalação dos recursos](http://127.0.0.1:8000/management/opportunity-resources-install) |
|
||||
| Extensão única | `2026_10_09_030000_extend_opportunity_resources` |
|
||||
| Hash código/prova | `e90ab685dac9441b7fc5f9da231770cb607a91b7e991876ded652827d76efa50` |
|
||||
| Backup/restauro | **09/10/2026 15:16:03 UTC / 17:16:03 locais**; 288 tabelas e cinco ficheiros iguais |
|
||||
| Cópia isolada | `desk_restore_20261009_151551_test:55441` |
|
||||
| Reversão QA | `up/down` antes de novos dados/eventos conservou hashes das 288 tabelas |
|
||||
| Validade | Até **10/10/2026 15:16:03 UTC / 17:16:03 locais**, sujeita a hash/destino/guardas |
|
||||
| QA automatizada | 368 passaram, 4.401 asserções; três ClamD reais saltados; 152 frontend; TypeScript/PHPStan/build passaram |
|
||||
| Preview | `installed=false`, `ready=true`; zero escritas ativas pelo preparador/leitor |
|
||||
|
||||
Provas privadas em `storage/app/private/investmoz-v2`: `opportunity-resources-backup-proof.json`, `opportunity-resources-compatibility.json`, `opportunity-resources-activation-proof.json`; resumo em `portal-audit/activation-evidence.json`. Dump, ZIP, `.env` e chaves permanecem privados.
|
||||
|
||||
## Antes da aplicação
|
||||
|
||||
1. Disponibilizar browser com sessão **QA**; verificar filtro CRM, países, seletor provincial, guardar/recuperar recursos e estados de scan/derivadas desta versão. Capturas/rede/persistência; prova antiga não substitui aceitação atual. `ready=true` valida o plano técnico, não inspeção visual.
|
||||
2. Verificar ClamD real e GD/WebP do PHP web. Ausência mantém restrições concretas de binários/derivadas, preservando rascunhos/metadados. Não marcar scan limpo sem evidência nem ativar publicação/cálculo.
|
||||
3. Rever diff e versão servida. Países/UX são código sem migration; leitura de tabelas não comprova que o web serve os assets atuais. Confirmar versão/manifesto no percurso autenticado.
|
||||
4. Abrir preview ativo com a **conta autorizada existente**. Conferir destino, migration pendente, hash, backup/restauro e validade. Se rejeitado/expirado, renovar só a preparação necessária. Não alterar prova para simular verificação não realizada.
|
||||
|
||||
## Aplicação e confirmação
|
||||
|
||||
1. Executar a ação autenticada existente para esta extensão uma única vez. Não usar CLI para contornar autenticação ou impersonar conta ativa. Nenhuma instalação foi feita nesta auditoria.
|
||||
2. Confirmar por leitura migration/tabelas, evento `opportunity_resources_installed`, autor/data/hash e disponibilidade da página de recursos.
|
||||
3. Comparar classificações dos IDs 1–6, relações 28/13, originais e eventos anteriores. Nenhuma associação/publicação deve surgir automaticamente.
|
||||
4. Idempotência é ensaiada em QA; não repetir instalação ativa como teste. Módulo instalado não significa cadastro povoado/publicado: primeiro recurso real depende do utilizador e scan aplicável.
|
||||
|
||||
Balcão (`desk_installed`), Bolsa (`partnership_module_installed`) e gestão básica (`opportunity_management_installed`) já têm um evento cada. **Não repetir essas instalações** nem criar cadastros canónicos paralelos.
|
||||
|
||||
## Reversão e recuperação
|
||||
|
||||
Reversão direta foi demonstrada apenas antes de novos recursos/dados/eventos. Depois de uso, preservar originais, relações, versões e história; preparar reconciliação/reversão que não elimine esse uso. Não executar `down` ou restauro sobre escritas posteriores por conveniência.
|
||||
|
||||
Restauro integral exige janela, reconciliação de escritas posteriores e ação autorizada. Cópia QA prova capacidade de recuperar o backup, não autorização de sobrescrita ativa. Expiração ou mudança dos ficheiros do fingerprint exige renovar prova/QA pertinente.
|
||||
|
||||
## Estado de entrega
|
||||
|
||||
- **Código preparado:** origem pública/legada, seletor provincial, apresentação da jornada, guardas e recursos privados.
|
||||
- **QA demonstrada:** API/persistência/acesso/versões e suites; backup/restauro/reversão; recusa concorrente.
|
||||
- **Ativo:** gestão básica/Balcão/Bolsa constatados por leitura; recursos não instalados. UI e ClamD real atuais pendentes.
|
||||
@@ -0,0 +1,250 @@
|
||||
# Proposta de consolidação do InvestMoz em torno do percurso do investidor
|
||||
|
||||
> Estado de execução aprovado em QA: I1–I3 autorizados pela mensagem posterior do responsável. Implementação/evidência e limites em [execucao-percurso-i1-i3.md](execucao-percurso-i1-i3.md). Texto abaixo preserva a proposta e as condições originais; não autoriza ativação ativa.
|
||||
|
||||
09/10/2026. Proposta para aprovação, ligada à [matriz existente](matriz-requisitos.csv). Não altera navegação, modelo ou motor do percurso. A correção pontual C24 do encaminhamento para um simulador existente fica separada desta proposta. Nenhuma escrita na base ativa; nenhuma funcionalidade eliminada; nenhuma nova jornada educativa.
|
||||
|
||||
## Recomendação e âmbito
|
||||
|
||||
**Aprovar com condições a consolidação incremental.** Usar o dossier de trabalho existente como contexto privado do investidor, reutilizar as entidades e ferramentas e criar uma apresentação única das 19 etapas. Preservar o projeto estruturado, a ficha publicada, o pedido e a decisão como recursos distintos, ligados por identificadores. A primeira entrega estrutural, depois de aprovada, deve permitir demonstrar os cenários A e B completos na interface QA antes de qualquer ativação.
|
||||
|
||||
O investidor começa por uma ideia, conhece a posição no percurso, guarda sem preencher tudo e escolhe uma ação que pode executar agora. A preparação pode ocorrer em paralelo. A consulta de ferramentas e a preparação de documentos continuam disponíveis mesmo quando uma submissão, decisão ou execução depende de informação ainda ausente. O portal não garante viabilidade, licenças, financiamento, incentivos ou sucesso do negócio.
|
||||
|
||||
## Fonte integral e divergências preservadas
|
||||
|
||||
Foi lido integralmente o exemplar **O InvestMoz deve funcionar como um assistente de investimento orientado por etapas e regras de aplicabilidade.docx**, no acervo `Servicos Tempo/Relatorios`: SHA256 `aa13c53138ec15cd808de43d9dc2fc6808da86943d09d3352c9dd0944bdae364`, 1.327.814 bytes, 459 parágrafos com texto em `word/document.xml`, sem notas/comentários ou alterações controladas identificadas, mais o fluxograma original `word/media/image1.png`, inspecionado. A numeração de parágrafos abaixo identifica o XML extraído, não páginas presumidas. Extração completa em `assistant-source-full.json`, privada.
|
||||
|
||||
O texto da secção 2.1, parágrafos 22–40, define **19 etapas**, incluindo decisões. O fluxograma embebido numera **17 blocos**, agrupa terra em três blocos e deixa decisões em losangos sem número. A imagem inclui operação no bloco de licenciamento; o texto determina que a licença de operação aguarde inspeções/testes. Esta proposta segue o texto para dependências e preserva a correspondência com a imagem. Os códigos S01–S19 são identificadores de rastreabilidade propostos, não uma renumeração dos valores gravados.
|
||||
|
||||
Há outros roteiros em uso: `config/virtual-desk.php` contém E0–E11 de constituição/preparação; `InvestorGuidanceRules` contém sete grupos de orientação; `investment-roadmap-source.ts` transcreve outro DOCX, com cinco fases e 14 atividades. Não equivalem às 19 etapas nem são fontes legais por si mesmos. Manter versão, significado, exemplares e histórico; introduzir adaptadores explícitos. A aceitação já dada às fontes oficiais mantém-se. Conferir âmbito, período e regra aplicável é aplicação da fonte, não recertificação.
|
||||
|
||||
O documento exige aprovação antes de implementar na secção 16, parágrafo 326, e aprovação explícita após diagnóstico na secção 19.1, parágrafo 497. O pedido atual autoriza apresentar o desenho e continuar as correções já autorizadas. Não autoriza executar este desenho estrutural antes da aprovação.
|
||||
|
||||
## Arquitetura efetivamente encontrada
|
||||
|
||||
Leitura complementar ativa em transação PostgreSQL `REPEATABLE READ READ ONLY`, sem conteúdos pessoais exportados, regista schema, constraints, índices e volumes em `investor-consolidation-runtime.json`. Continua o inventário anterior; não é outro diagnóstico do zero.
|
||||
|
||||
| Tema | Encontrado e evidência | Consequência para a proposta |
|
||||
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| Aplicação | Laravel 13.30.1, PHP CLI 8.5.11; React 19.2.8, TypeScript 5.9.3, Inertia React 3.7.0, Leaflet 1.9.4; Node 24.20.0, npm 11.19.0, Composer 2.8.12 | Evoluir a aplicação existente; versões de CLI/lock não certificam o processo web ativo |
|
||||
| Base ativa | PostgreSQL 17.11, PostGIS 3.6.2, `investemoz:5432`; 288 tabelas na auditoria anterior | MySQL é descrição histórica do documento; nenhuma migração MySQL→PostgreSQL é necessária por pressuposto |
|
||||
| Contextos | 16 `projects`, 29 `investment_dossiers`, 1 `investor_journeys`, 1 `desk_cases`, 3 `investment_submissions` | Dossier de preparação, ficha editorial, projeto e manifestação não são sinónimos; conservar IDs |
|
||||
| Balcão | 3 versões de serviço publicadas; 0 pedidos, documentos ligados e tarefas no ativo; código tem criação, rascunho, submissão, devolução, parecer e apreciação interna | Não confundir capacidades testadas em QA com pedidos reais ativos ou decisão institucional |
|
||||
| Simuladores | 22 drafts, 16 simulações/resultados; snapshots cifrados, versionamento, ETag/If-Match, histórico e vínculo explícito a negócio | Reutilizar; associação a dossier não partilha automaticamente um draft privado com gestor/representante |
|
||||
| Acompanhamento | `tasks`, `leads`, `contacts`, `consents`, `desk_events`, `audit_events`, aftercare existentes; 0 leads/tarefas/aftercare ativos | Acompanhamento interno funciona sem CRM externo; não preencher cadastros vazios artificialmente |
|
||||
| Integrações | `suitecrm.enabled=false`, notificações externas desativadas; filas, cache e sessões configurados em database; AI habilitada não prova modelo externo operacional | Não depender de SuiteCRM, IA, correio, SMS ou endpoints institucionais para guardar/acompanhar internamente |
|
||||
| Acesso | Fortify/sessão, conta verificada, gate `manage-portal`, memberships e analista atribuído ao pedido | Não afirmar que os 11 perfis conceptuais, OAuth/OIDC/PKCE ou contas de entidades externas já estão implementados |
|
||||
| Licenças e terra | Assistência fundiária existente; `mne.licences` e `mne.land_rights` são estruturas de ativos sem dados na leitura anterior, com consumidores próprios | Não reutilizar um registo de ativo negociável como licença do projeto sem contrato; sem módulo completo de licenciamento demonstrado |
|
||||
| Território | 1.990 registos ativos, incluindo 1.920 administrativos públicos; 0 geometrias ativas. QA conserva 361 limites internos de 2019 | Separar cadastro, geometria disponível, acesso autorizado, perímetro do projeto e mapa funcional |
|
||||
|
||||
O adaptador de negócios atual devolve `ExistingBusiness` por `CompatibleBusinessRepository`→`LegacyBusinessRepository`; schema `mne` preparado não significa transferência de escrita. A API v1 usa contratos e middleware diferentes por domínio. Sessão web, MFA quando exigida e autenticação de integrações devem conservar os contratos em vigor; não substituir tudo por OAuth nem anunciar webhooks como ativos.
|
||||
|
||||
## Mapa de navegação proposto
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Publico[Explorar InvestMoz] --> Ferramentas[Oportunidades · mapas · parceiros · biblioteca · simuladores]
|
||||
Publico --> Entrada[Preparar o meu investimento]
|
||||
Entrada --> Conta[Entrar ou guardar preparação anónima sem dados pessoais]
|
||||
Conta --> Painel[Meus investimentos · projeto atual]
|
||||
Painel --> Contexto[Dossier de trabalho e percurso]
|
||||
Contexto --> Fases[Ideia · dossier · licenças e terra · recursos · execução]
|
||||
Contexto --> Pendencias[Pendências · documentos · resultados · próxima ação]
|
||||
Contexto --> Ferramentas
|
||||
Ferramentas --> Retorno[Guardar ou associar resultado ao contexto autorizado]
|
||||
Retorno --> Contexto
|
||||
Contexto --> Balcao[Preparar apoio · rever · submeter separadamente]
|
||||
Balcao --> Seguimento[Mensagens · tarefas · protocolo · acompanhamento interno]
|
||||
Seguimento --> Contexto
|
||||
Gestao[Área da gestão] --> Fila[Pedidos e tarefas atribuídos]
|
||||
Gestao --> Cadastros[Oportunidades · estruturas · território · biblioteca · parceiros]
|
||||
Gestao --> Governo[Revisões · fontes · regras versionadas · auditoria · ativação]
|
||||
Fila --> Analise[Analisar · pedir correção · parecer interno · registo assistido externo]
|
||||
Analise --> Seguimento
|
||||
```
|
||||
|
||||
Investidor: **Meus investimentos, Percurso, Documentos e resultados, Apoio e acompanhamento, Ferramentas**. Projeto atual sempre identificado; lista de dossiers permite alternar sem substituir os dados de outro. Dentro do contexto: resumo, fases e S01–S19, pendências com motivo, documentos/validades, resultados/versões, licenças/terra/financiamento, mensagens, cronograma, riscos e próxima ação com alternativas executáveis. Em móvel conserva a mesma informação em cartões e foco acessível após ação.
|
||||
|
||||
Gestão: **Fila de trabalho, Investidores e dossiers, Cadastros e conteúdos, Regras e referências, Auditoria e operação**. As funções administrativas não entram na sequência de etapas do investidor. Estado administrativo ou publicação editorial não aumenta a maturidade do investimento. Auditoria e consultas só apresentam dados dentro do âmbito autorizado.
|
||||
|
||||
Evoluir `/dashboard`, `/investidor` e `/balcao-virtual/painel` por composição, depois da aprovação. Manter cada URL acessível e compatível; preservar `/carteira`, `/oportunidades`, `/negocios`, `/terra-duat`, `/parcerias`, `/simulador-fiscal`, `/documentos`, `/legislacao`, manifestações e rotas da gestão. Não transformar links diretos em redirecionamentos que criem um dossier ou efetuem submissão. Utilizador com perfil de gestão escolhe explicitamente a área; não muda implicitamente de papel.
|
||||
|
||||
## Cinco fases com as 19 etapas rastreáveis
|
||||
|
||||
O mapa abaixo é de capacidades, ligado à matriz única por ID; não cria outra matriz de requisitos. **Todas as 19 etapas continuam sem demonstração integrada da interface desta proposta.** “Reutilizar” não significa etapa concluída. Preparação indicada pode avançar sem os pré-requisitos do ato final.
|
||||
|
||||
| Fase / etapa textual | Fonte XML / imagem | Reutilizar ou melhorar | Aplicabilidade, dependência do ato e resultado esperado | IDs da matriz |
|
||||
| ------------------------------------------------------------------ | ---------------------------------- | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |
|
||||
| 1. Ideia e análise — S01 Sistematizar ideia | P22 / bloco 1 | Draft do simulador, dossier Balcão, perfil, planejamento | Sempre; título/objetivo mínimos para guardar, proposta/promotores/localização preliminar quando conhecidos | AUD-DESK-01/02, AUD-SIM-01, AUD-GUIDE-01 |
|
||||
| S02 Análise preliminar | P23 / bloco 2 | Plano empresarial, riscos, cenários financeiros, biblioteca | Sempre; evidências e pressupostos separados, valores ausentes indeterminados | AUD-SIM-02, AUD-LIB-01, AUD-GUIDE-01 |
|
||||
| S03 Decidir viabilidade | P24 / losango ideia viável | Readiness e orientação explicável | Decisão do promotor com fundamentos; prosseguir/reformular/arquivar. Sem score automático, aprovação pública ou bloqueio da preparação | AUD-GUIDE-01, AUD-DASH-01 |
|
||||
| S04 Estruturar investimento | P25 / bloco 3 | Plano, equipa, marcos e snapshots | Sempre; consolidar estratégia, finanças, calendário e forma jurídica, sem reintroduzir dados conhecidos | AUD-DESK-02, AUD-SIM-01/02 |
|
||||
| 2. Entidade e dossier — S05 Constituir/registar entidade | P26 / bloco 4 | Declarações empresariais e Balcão E1–E9 | Conforme entidade/tipo de investimento; registo/NUIT são atos externos, dados declarados não os provam; entidade existente reutilizada | AUD-DESK-01/02, AUD-LIB-01 |
|
||||
| S06 Preparar processo | P27 / bloco 5 | `desk_cases`, documentos e revisões, investment submission | Preparação paralela à constituição; atos de envio exigem somente os campos/documentos do serviço aplicável | AUD-DESK-01/02, AUD-LIB-01/02 |
|
||||
| S07 Submeter projeto/autorização/incentivo | P28 / bloco 6 | Serviço project-preparation, protocolo, recibo, revisão | Apenas quando aplicável e após revisão/consentimento; pedido interno não equivale a envio ou aprovação APIEX/incentivo | AUD-DESK-01, AUD-GUIDE-01 |
|
||||
| 3. Licenças e terra — S08 Licenciamento prévio/integrado | P29 / bloco 7 | Etapas documentais Balcão, fontes, documentos e validade | Regras por atividade/localização; preparar em paralelo; cada submissão depende do seu contrato. Operação fica em S17 | AUD-DESK-01/02, AUD-LIB-01, AUD-GUIDE-01 |
|
||||
| S09 Decidir necessidade de terra | P30 / losango terra | Perguntas de localização e assistência fundiária | Sim/não/por determinar com fundamento e histórico. Não depende de licença já aprovada para responder | AUD-LAND-01, AUD-GEO-02, AUD-GUIDE-01 |
|
||||
| S10 Regularizar terra | P31 / blocos 8–10 | LandAssistance, seletores, mapas, anexos | Só se S09=sim; área, compatibilidade, consulta/levantamento/título/registo conforme regra oficial. Geometria não é DUAT nem prova de disponibilidade | AUD-LAND-01, AUD-GEO-01/02/03, AUD-LIB-01 |
|
||||
| S11 Confirmar regularização | P32 / losango licenças e terra | Evidência e revisão documental separadas | Verificar requisitos efetivamente aplicáveis; devolver pendências a S08/S10. Ato condiciona execução, não bloqueia S02/S04 ou preparação financeira | AUD-DESK-01/02, AUD-GUIDE-01 |
|
||||
| 4. Recursos e financiamento — S12 Decidir/estruturar financiamento | P33 / bloco 11 e condição do texto | Fontes de fundos, plano, simulador, parceiros | Sim/não/por determinar. Sem financiamento externo: guardar fonte/capital próprio; não afirmar disponibilidade sem evidência | AUD-SIM-01/02, AUD-PART-01, AUD-GUIDE-01 |
|
||||
| S13 Due diligence/negociação financeira | P34 / bloco 12 | Sala de parceria, documentos, tarefas, cenários | Ramo de financiamento externo; preparação paralela a terra. Não dispensa outras diligências aplicáveis fora desse ramo | AUD-PART-01, AUD-LIB-01, AUD-GUIDE-01 |
|
||||
| S14 Decidir financiamento | P35 / losango aprovado | Marcos/parcerias e registo assistido | Resultado do financiador, com referência/documento/data; recusa regressa à estrutura sem apagar propostas anteriores | AUD-PART-01, AUD-DESK-02 |
|
||||
| S15 Fecho/desembolso | P36 / bloco 13 | Marcos, documentos e obrigações declaradas | Se financiamento externo; aprovação não comprova contrato, condições cumpridas ou desembolso | AUD-PART-01, AUD-GUIDE-01 |
|
||||
| 5. Execução e operação — S16 Implementar | P37 / bloco 14 | ProjectPlanning, tarefas, marcos, aftercare | Planejar sempre; executar apenas requisitos prévios aplicáveis cumpridos, com motivo específico e evidência | AUD-GUIDE-01, AUD-CRM-01, AUD-DASH-01 |
|
||||
| S17 Inspeções/testes/licença de operação | P38 / bloco 15 | Documentos, resultados e tarefas | Conforme atividade; inspeção e emissão são externas, checklist concluída não é licença | AUD-DESK-02, AUD-LIB-01, AUD-GUIDE-01 |
|
||||
| S18 Iniciar operação | P39 / bloco 16 | Marcos de execução e acompanhamento | Cumprir exigências aplicáveis de S17 e anteriores; guardar data/decisão declarada/evidências, sem assumir legalidade por clique | AUD-GUIDE-01, AUD-CRM-01 |
|
||||
| S19 Monitoria contínua | P40 / bloco 17 | Aftercare, tarefas, validade documental, audit_events | Operação ativa; conformidade, renovações, indicadores e medidas corretivas. É recorrente, não fica definitivamente concluída por preencher | AUD-CRM-01, AUD-DASH-01, AUD-LIB-01 |
|
||||
|
||||
## Relações e fontes mestres
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
U[Conta users] --> I[Identidade investors e investor_accounts]
|
||||
I --> D[Dossier de trabalho desk_cases]
|
||||
D --> J[Percurso investor_journeys e journey_steps]
|
||||
D --> P[projects quando já existir projeto estruturado]
|
||||
P --> F[investment_dossiers ficha editorial]
|
||||
D --> S[simulation_form_drafts e resultados existentes]
|
||||
D --> R[desk_requests e service_versions]
|
||||
D --> L[land_assistance_cases]
|
||||
D --> Docs[documents e ligações autorizadas]
|
||||
R --> T[tasks e desk_events]
|
||||
R --> Ext[Registo assistido de decisão externa]
|
||||
D --> Ref[Oportunidades · parceiros · biblioteca · território]
|
||||
IR[interest_requests e consents] --> CRM[leads · contacts · tasks internos]
|
||||
D --> IR
|
||||
```
|
||||
|
||||
As setas mostram vínculos existentes ou propostos; não todas FKs já instaladas. Referências físicas confirmadas estão em `investor-consolidation-runtime.json`. A ligação dossier→terra e o retorno completo de resultados ainda são lacunas a implementar após aprovação. Um lead deve ser criado apenas para captação/acompanhamento que o exija; uma tarefa interna do dossier não depende dessa conversão.
|
||||
|
||||
| Dado mestre | Fonte a reutilizar | Reutilização e conflito |
|
||||
| ---------------------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| Conta/identidade | users; investors; investor_accounts; contacts | Separar autenticação, investidor e contacto. Reutilizar associação por ID; email coincidente não autoriza fusão |
|
||||
| Dados pessoais/declarados | investment_accounts.payload cifrado | Prefill consentido; identificar fonte/versão. Alteração no pedido é snapshot da declaração, não atualização silenciosa do perfil |
|
||||
| Empresa/mandato | organizations/memberships; investment_company_declarations; ExistingBusiness quando pertinente | Representação efetiva e direitos verificados; declaração não é registo comercial. Não trocar automaticamente adaptador por tabelas mne |
|
||||
| Ideia/projeto de trabalho | desk_cases.id, title, payload; project_id nullable | Começar aqui sem obrigar oportunidade publicada, empresa constituída ou projeto de carteira. Reutilizar projects quando já houver vínculo; eventual criação explícita usa a mesma tabela e autorização |
|
||||
| Percurso | investor_journeys e journey_steps | Agregar etapas existentes em versão explícita; não criar investment_projects ou project_stage_instances paralelos |
|
||||
| Dados financeiros | Draft e snapshots versionados; simulation_results quando execução de servidor existir | Fórmulas financeiras atuais reutilizadas. Snapshot financeiro guarda entradas, não necessariamente resultado imutável: distinguir recuperação/recalculo de resultado guardado |
|
||||
| Pedidos | desk_requests + service_version_id; investment_submissions/interest_requests mantidos | Campos mestre mapeados com origem/versão e edição consciente. Pedido submetido permanece snapshot, nunca sincronização retroativa |
|
||||
| Documentos | documents, desk_documents, project_documents e vínculos específicos existentes | Um original, checksum/versão, múltiplos vínculos quando autorizados; mesma obrigação pode apontar ao mesmo documento. Dedup de bytes não concede novos direitos de acesso |
|
||||
| Território | geo_locations; geo_geometries; relações existentes | País do requerente, origem da solicitação e território do investimento são independentes; manter ISO e árvore territorial sem inferências |
|
||||
| Biblioteca/regras | portal_resources, investment_legal_sources e acervo oficial identificado | Consulta, situação jurídica/documental e uso em cálculo independentes; ligação a uma etapa nunca condiciona consulta autorizada |
|
||||
| Acompanhamento/consentimento | tasks, desk_events, audit_events, consents | Tarefa, parecer interno, decisão externa e concessão de contacto separados; evitar duplicar transições entre módulos |
|
||||
|
||||
Em cada reutilização, apresentar origem, versão, data e opção de revisão. Copiar só os campos necessários e autorizados; não transportar dados pessoais em URLs. Resolver conflito entre declaração atual e versão submetida sem reescrever a versão anterior. Projeto atual é seleção recuperável e autorizada; sessionStorage pode acelerar a interface, mas não pode ser a única forma de recuperar o contexto noutra sessão.
|
||||
|
||||
## Consolidações e duplicações a resolver
|
||||
|
||||
| Situação atual | Consolidação proposta | Compatibilidade |
|
||||
| ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `/dashboard` devolve summary=null ao investidor; `/investidor` lista jornadas de carteira; Balcão agrega dossiers/pedidos | Um painel do investidor composto sobre fontes existentes, sem mover gestão para esse painel | URLs existentes permanecem; ativação de apresentação por configuração, sem criar recursos no GET |
|
||||
| E0–E11, sete grupos de orientação e roteiro de 14 atividades | Uma definição versionada das 19 etapas, com adaptadores e correspondências explícitas | Não converter códigos/estados antigos por posição; não aplicar regras novas retroativamente |
|
||||
| Título/objetivo/orçamento/país/localização em draft, dossier, manifestação e pedido | Dicionário de campos e read model de contexto; prefill com seleção consciente e versão | Snapshots transacionais permanecem; nenhuma dupla escrita automática |
|
||||
| `createRequest` preenche título/descrição limitada mas não orçamento completo do simulador | Prefill de campos compatíveis e unidades/moeda explícitas, sem repetir preenchimento | Atualizar preparação de novo pedido; submissões anteriores imutáveis |
|
||||
| `SimulationFormDrafts::create` admite um draft corrente por conta; recuperação tem caminho por ID | Primeiro preservar associação por ID; depois adaptar criação/seleção por contexto e idempotência | Não remover proteção de sobrescrita nem isolamento anónimo; não prometer vários projetos só porque o índice permite linhas |
|
||||
| Estados pedido, etapa Balcão, journey_steps, prontidão e decisão externa diferentes | Dimensões separadas e projeção de apresentação coerente | `accepted` continua aceitação interna; não vira aprovação APIEX/bancária/licença |
|
||||
| Cartografia cadastrada/importada não prova uso em cada mapa | Contexto territorial compartilhado, acessos por consumidor, legendas e ausência explícita | Limite administrativo não vira localização de investimento/DUAT/zona; preservar classificação |
|
||||
| Leads/contactos e contas de investidor | Serviços existentes de identidade e conversão consentida | Sem CRM externo obrigatório ou fusões por email; tratar ambiguidades antes de converter |
|
||||
|
||||
## Estados, aplicabilidade e permissões
|
||||
|
||||
Cada etapa tem quatro dimensões: **aplicabilidade** (`aplicável`, `dispensada com fundamento`, `por determinar`), **preparação** (vazio/incompleto/verificado internamente/pronto), **tramitação** (não enviado/enviado/em análise/devolvido/aguarda externo/encerrado) e **decisão externa** (não requerida/não conhecida/ato registado favorável/desfavorável/expirado). A apresentação usa os 12 estados pedidos, com âmbito visível. Bloqueio é atributo da ação com dependência e motivo, não encerramento de toda a fase.
|
||||
|
||||
| Estado apresentado | Origem possível atual | Quem e condição para mudar | O que não significa |
|
||||
| --------------------------- | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
|
||||
| Não iniciada | Balcão not_started; journey pending | Sistema em nova versão; sem apagar etapas existentes | Falta de aplicabilidade já determinada |
|
||||
| Em preparação | preparing; draft; tarefa open/in_progress | Dono/representante autorizado pode guardar incompleto | Submissão ou aprovação |
|
||||
| Pronta para submissão | ready e validação do contrato do serviço | Regra determinística com versão e faltas visíveis | Envio automático ou elegibilidade |
|
||||
| Submetida | desk submitted; submission próprio | Dono/representante confirma serviço, conteúdo, consentimento e destino | Envio para órgão externo sem referência real |
|
||||
| Em análise | reviewing; analista atribuído | Analista/gestor no âmbito do pedido | Aprovação institucional |
|
||||
| Requer correção | returned; pending | Analista indica motivo/campos permitidos; dono corrige em nova versão | Perda de documentos ou reescrita da submissão |
|
||||
| A aguardar entidade externa | referred/waiting com referência/canal | Registo assistido por autorizado, com data e próxima revisão | Integração ativa ou resposta recebida |
|
||||
| Aprovada | Novo registo de ato externo fundamentado | Autoridade identificada; captura assistida/conferência por pessoa competente distinta quando exigido | accepted/opinion interno ou decisão automática do portal |
|
||||
| Rejeitada | Rejeição interna ou ato externo, rotulados separadamente | Responsável autorizado, motivo e evidência; opção de reformular | Apagar a proposta/reutilização proibida para sempre |
|
||||
| Dispensada | not_applicable, decisão condicional do promotor e/ou regra aplicável | Negativa declarada ativa adaptação de preparação; dispensa legal exige fundamento e revisão no seu âmbito | Regra jurídica criada pelo investidor ou null interpretado como não |
|
||||
| Concluída | completed documental ou tarefa done, âmbito indicado | Critérios/evidências do marco e independência de revisão quando exigida | Aprovação externa; S19 definitivamente terminado |
|
||||
| Expirada | expired e validade documental | Data válida explícita; reabrir dependentes afetados e conservar histórico | Documento oficial sem rastreabilidade rejeitado como falso |
|
||||
|
||||
S03, S09 e S12 têm decisão do investidor auditada. S14 não aceita resposta do investidor como aprovação do banco sem evidência e âmbito. Uma resposta “por determinar” mantém visíveis as opções de preparação e a pergunta exata. S10 pode ser dispensada por ausência declarada de necessidade de terra; isso não resolve uma exigência de uso de espaço que se venha a verificar. No ramo sem financiamento externo, S13–S15 financeiros são dispensados com motivo e fonte própria em S12; as demais diligências continuam quando aplicáveis.
|
||||
|
||||
Dependências serão por **ação**, com `prepare`, `submit`, `execute`, `operate` distintos. Exemplos: orçamento e pesquisa de parceiros não dependem de DUAT aprovado; preparar dossier não exige todas as licenças; emitir/iniciar operação depende das inspeções e condições aplicáveis; importar documento não ativa regra fiscal. A interface mostra dependência, estado e evidência em falta e oferece ações independentes. Reabrir uma evidência invalida apenas conclusões dependentes, mantendo versões e tarefas já realizadas.
|
||||
|
||||
Próxima ação: primeiro correção solicitada ou obrigação aplicável com prazo, depois tarefa executável necessária; havendo bloqueio, apresentar o motivo e uma preparação independente. Nunca recomendar ato indisponível por autorização ou integração. Mostrar contagem de tarefas/marcos aplicáveis concluídos; se houver percentagem, informar denominador e itens indeterminados, nunca “probabilidade de sucesso”, aprovação ou progresso jurídico inferido.
|
||||
|
||||
| Perfil | Reutilização atual / ação permitida | Limite da primeira demonstração |
|
||||
| --------------------------------------- | ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
|
||||
| Visitante | Ferramentas públicas e preparação anónima limitada | Sem dados pessoais, pedidos privados ou decisões institucionais |
|
||||
| Investidor | Dono do dossier/draft, prepara, associa resultados, confirma pedido | Não se autoaprova internamente nem lê dossier de terceiro |
|
||||
| Representante | Membership ativa e papel admin/manager/officer para escrita | Acesso ao dossier não concede acesso automático ao draft pessoal de outro membro |
|
||||
| Atendimento/analista | Atribuição ao pedido; consulta e acompanhamento dentro do âmbito | Não consultar todos os documentos/pedidos da organização por associação indireta |
|
||||
| Supervisor/gestor | manage-portal, revisões/atribuição/administração existentes | Separar editor/revisor; não apresentar gate amplo como RBAC completo de todos os perfis |
|
||||
| Entidades externas/financiador/inspetor | Registo assistido interno, com autoridade/canal/evidência | Sem login ou integração externa inventados; concessão futura exige âmbito e autenticação aprovados |
|
||||
| Administrador de regras | Publicação de versão com revisão e auditoria propostas | Não alterar a versão de percursos em curso silenciosamente |
|
||||
| Auditor | Projeção de leitura restrita proposta | Não existe ainda papel granular demonstrado; implementar permissão específica, sem editar decisões |
|
||||
|
||||
## Modelo e contratos incrementais propostos
|
||||
|
||||
Primeiro read model: composição de `VirtualDesk`, `InvestorGuidance`, `InvestmentWorkspace`, simuladores, documentos e tarefas, respeitando em cada leitura a policy de origem. Os nomes de novos serviços abaixo são **propostos**, não capacidades instaladas.
|
||||
|
||||
1. `InvestorProjectContext` agrega dossier, jornada, referências, pendências e links autorizados. Não cria novo cadastro de projeto. `desk_cases.project_id` permanece nullable para ideia; projeto estruturado usa `projects` quando houver vínculo explícito, nunca uma cópia pública automática. Campos mestres são lidos ou materializados em snapshot do pedido por confirmação; sem sincronização bidirecional.
|
||||
2. Reutilizar `QuestionnaireVersion`/`questionnaire_versions.schema_snapshot` para uma definição versionada com código reservado `investor-path-19`, locale, steps, applicability e dependências por ação. Acrescentar validação específica e aprovação/auditoria de publicação; não usar esse código como regra fiscal ou ficheiro pessoal. Versão de definição presa ao percurso por FK. A API pública de questionários só pode expor configuração não sensível; administração e rascunhos ficam protegidos. Não criar novas tabelas de etapas/requisitos por analogia com a lista conceptual do DOCX.
|
||||
3. Usar `investor_journeys` para a instância: novo percurso privado pode não ter ficha editorial; associá-lo por `desk_cases.journey_id` existente. Usar `journey_steps` para S01–S19 com versão e dados de aplicabilidade/estado detalhado. Estados legacy pending/active/completed/blocked mantêm tradução explícita por versão; não converter dados antigos em massa. `desk_cases.workflow` histórico E0–E11 permanece preservado, como percurso documental ligado, sem segunda cópia atualizável das mesmas decisões.
|
||||
4. `tasks` continua a fonte de tarefas de orientação/CRM. Propor vínculo nullable à etapa e chaves de idempotência por tarefa; conservar lead_id, desk_case_id, aceitação, classificação e regras atuais. Eventos usam `desk_events`/`audit_events`, com etapa, definição, motivo, anterior/novo, documentos e correlação.
|
||||
5. Propor vínculo nullable a `land_assistance_cases` em `desk_cases`, e vínculos/resultados por IDs existentes no contexto. Conferir owner/representação/versão na associação. Acrescentar FKs/indexes apenas depois de análise de órfãos/conflitos; sem converter estruturas mne nem criar financing_requests paralelo à sala de parceiros e documentos existentes.
|
||||
|
||||
Migrations potencialmente necessárias: FK de versão da definição em investor_journeys; campos detalhados de aplicabilidade/evidência em journey_steps, unicidade por jornada/código para novas instâncias; vínculo de terra no dossier; vínculo de etapa em tasks. A criação de múltiplos drafts autenticados por contexto exige ajustar o serviço e contratos idempotentes, não simplesmente um índice. Antes de qualquer migration, produzir preview de contagens, nulabilidade, órfãos, referências repetidas e consumidores; não aplicar por esta análise.
|
||||
|
||||
Contratos atuais mantidos: criação/GET do Balcão, PUT do pedido e POST de estado; drafts `/api/v1/simulation-drafts/{id}` com ETag/If-Match; simulações/resultados/report; APIs v1 de interesse e referências; tarefas de orientação. Endpoints novos candidatos, ainda inexistentes: GET `/api/v1/investment/contexts/{caseId}/journey`, POST de decisão condicional e POST de associação de resultado no mesmo contexto. Pedido deve incluir versão esperada/chave idempotente; resposta contém motivo, âmbito, source IDs/versões, ações executáveis e dependências. Não substituir endpoints atuais ou remover os erros/autorizações já testados.
|
||||
|
||||
Viabilidade: consultar e comparar cenários com hipóteses identificadas, lacunas e limites; decisão de prosseguir é do promotor. O resultado financeiro local é recalculado pelas funções existentes a partir do snapshot guardado; resultado imutável só é afirmado quando tiver ID, entradas/hash e versão de motor persistidos. Se a análise fiscal estiver indeterminada, recuperar e apresentar essa indeterminação. Não inventar parâmetros legais para tornar a demonstração positiva.
|
||||
|
||||
As condições da definição serão declarativas, com campos e operadores permitidos, sem execução de código introduzido na administração. Publicação valida códigos únicos, referências de dependência, ausência de ciclos, versões de fontes e permissões por ação. Uma condição indeterminada devolve a pergunta/dado em falta; não assume false nem fixa taxa/prazo legal. Mudança de versão requer comparação das etapas/decisões afetadas e opção explícita de manter o percurso anterior; não há migração automática de instâncias.
|
||||
|
||||
## Primeira demonstração integrada em QA
|
||||
|
||||
**Estado: cenários de aceitação preparados; não executados como percursos integrados novos.** As provas anteriores de APIs/componentes são reutilizadas como pré-condições, não como aprovação da consolidação. Escritas somente em base loopback `*_test:55441`, com guarda de identidade e execução sequencial. A cópia cartográfica e a cópia de compatibilidade de recursos são bases distintas; não misturar fixtures ou anunciar 361 geometrias na base que não as contém.
|
||||
|
||||
Dados de ensaio identificados como sintéticos: A = prestação remota de serviços, sem nova terra/financiamento externo; B = pequena unidade produtiva, com necessidade de terra e capital externo. Em ambos, situação jurídica aplicável permanece por determinar até evidência, sem dispensa legal inventada.
|
||||
|
||||
| Passo de aceitação | A | B | Prova exigida |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| Criar e guardar | Criar ideia/dossier e reutilizar identidade | Idem, dossier distinto | UI, POST/201, ID/version/evento; duplo envio cria um; nenhuma submissão implícita |
|
||||
| Recuperar noutra sessão | Sair/entrar e selecionar A | Sair/entrar e selecionar B; alternar para A | GET/persistência/hash; sem depender só de storage local; terceiro 403/404 |
|
||||
| Adaptar percurso | Terra=não, financiamento externo=não; motivo e fonte própria | Terra=sim e externo=sim; perguntas/documentos/ações apropriados | Decisões auditadas por versão, S10 e S13–S15 dispensados no ramo A; B mantém etapas abertas; unknown não é não |
|
||||
| Usar ferramenta | Ponto de equilíbrio: custos fixos 1.000, preço 100, variável 50 → 20 unidades | Necessidade total 100.000, capital confirmado declarado 30.000 → diferença 70.000, sem promessa de financiamento | Link com contexto autorizado; entradas/unidade/período/moeda visíveis; cálculo financeiro existente, sem taxa fiscal inventada |
|
||||
| Devolver/recuperar resultado | Guardar snapshot e voltar ao dossier A; outra sessão recupera entradas e recalcula 20 | Idem B, recupera diferença 70.000; reabrir A não apresenta B | Dossier/draft IDs, versão/hash/motor e resultado exibido; distinguir recalculado de resultado imutável persistido |
|
||||
| Preparar Balcão | Reutilizar título/objetivo/moeda/valor; criar rascunho project-preparation | Idem B com necessidades próprias | Prefill com origem/versão, edição, gravação/GET; snapshot distinto, sem duplicar investidor |
|
||||
| Acompanhar internamente | Aceitar tarefa concreta de preparação e registá-la no dossier | Tarefa de terra aguarda documento; tarefa de orçamento avança | Task ID/status/assignee/evento recuperados; CRM externo e notificações desativados durante o ensaio |
|
||||
| Preparação paralela | Fonte de mercado em falta; plano de equipa avança | Consulta/levantamento de terra em falta; orçamento/parceiros avança | Interface mostra motivo e ação independente, gravação e recuperação, sem fechar o impedimento artificialmente |
|
||||
| Revisão/negativos | Inválido 422, versão antiga 409, perfil sem direito negado | Idem; voltar sim→unknown não apaga documentos, invalida só dependentes | Dados/version/hash conservados; erros visíveis com foco e ação de recuperação |
|
||||
|
||||
Para observar análise/atribuição do gestor, o ensaio QA pode rever o rascunho e **submeter explicitamente um pedido sintético interno**, capturando o conteúdo, protocolo e versão; nunca auto-submeter por usar ferramenta. Gestor distinto atribui tarefa/pede correção; investidor recupera a mensagem e corrige somente campos permitidos. O resultado permanece interno; nenhuma chamada ou aprovação de entidade real. O apoio pode ser preparado sem anexos, enquanto scan/derivadas são testados separadamente nas operações afetadas.
|
||||
|
||||
Cartografia em B: selecionar e recuperar cada nível; mostrar cadastro, geometria autorizada ou ausência e fonte/edição. Se forem usados limites reais em mapa do investidor, a sua disponibilização deve ser explicitamente configurada **só na QA**, com classificação/escopo registados; importar limites privados não os torna automaticamente públicos. Nenhum polígono é tomado por título de terra.
|
||||
|
||||
Capturar interface em computador, tablet e telemóvel (1440, 768 e 390 px), teclado/foco, erros, screenshots, respostas HTTP e persistência consultada. Relacionar cada screenshot ao dossier/etapa/versão, sem expor dados pessoais. Sem browser disponível, deixar “UI pendente” e executar só API/persistência. Go exige A e B completos e repetíveis; testes unitários ou links de documentos não substituem essa prova.
|
||||
|
||||
## Plano incremental e reversão
|
||||
|
||||
| Lote | Componentes afetados | Critério de aceitação | Compatibilidade e reversão |
|
||||
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| I0 — já autorizado | Falhas existentes, CountryCatalogue/CountrySelect, VirtualDesk, seleção territorial/mapas; C24 InvestorGuidance | Guardar/recuperar/filtros por formulário e perfil; contexto correto; geometrias por consumidor; UI pendente identificada | Sem navegação/modelo novo; reverter código pontual conservando payloads e provas |
|
||||
| I1 — após aprovação | DashboardController, InvestorWorkspaceController, VirtualDeskController; dashboard, portfolio/workspace, desk/panel, JourneyCompanion | Painel mostra contexto, posição, documentos/resultados, pendências e próxima ação; acesso direto e ausência visível | Read model composto, sem migração ou criação em GET; opção de apresentação nova para QA; desligar opção restaura apresentação anterior |
|
||||
| I2 — dados e retorno | VirtualDesk, InvestmentWorkspace, SimulationFormDrafts/Controller, SimulationForm, field mapping | Prefill consentido, vínculo por ID, conflito/versionamento, A/B sem contaminação, nova sessão | Aditivo; preservar snapshots; retornar aos módulos diretos sem apagar vínculos/resultados; adaptar um draft por contexto antes de multi-projetos |
|
||||
| I3 — 19 etapas | QuestionnaireVersion, investor_journeys/journey_steps, InvestorGuidanceRules como adaptador, tasks, audit | S01–S19 identificáveis; aplicabilidade triestado; dependência por ação; fundamentos e permissões; A/B completos na UI | Versões presas às instâncias; migrations só QA, preview/reconciliação; reverter apresentação/motor, nunca down destrutivo após novas decisões |
|
||||
| I4 — aprofundar execução | Licenças, terra, contratos/parceiros, aftercare, calendário e obrigações | Cada ato tem fonte aplicável, evidência, papel competente e decisão externa distinta | Primeiro usar documentos/tarefas atuais; novas capacidades apenas quando demonstradamente ausentes; sem integração externa obrigatória |
|
||||
| Ativação separada | Extensão de recursos, cartografia privada, divulgação por consumidor | Backup/restauro fresco, schema/evento/autor/versão/contagens e QA visual; instalação única | Não repetir Balcão/Bolsa/gestão básica. Recursos ready=true é preparação. Cartografia ativa depende do mecanismo autenticado ainda pendente; reversão por lote sem apagar uso/histórico |
|
||||
|
||||
O plano de ativação anterior permanece válido apenas no seu âmbito e prazo, com provas identificadas. Não inclui automaticamente o futuro modelo do percurso. Depois de alterações estruturais, renovar backup/restauro e provas de compatibilidade/rollback antes do ato autenticado. Antes de escrita ativa, reconciliação por IDs, contagens e hashes; o estado anterior das 288 tabelas e ficheiros privados não autoriza apagar novas decisões.
|
||||
|
||||
Riscos prioritários: mistura entre projetos por draft corrente; prefill que sobrescreva snapshot; gestor com acesso indevido a módulo privado; regra legal ausente tratada como dispensa; aprovação interna apresentada como externa; duplicação de tarefas/identidade; versão nova reinterpretando E0–E11; publicação involuntária de geometrias/documentos. Cada risco tem ensaio negativo nos lotes I0–I3. ClamD/scan condicionam somente binários/libertação; GD/derivadas e manutenção mantêm critérios próprios.
|
||||
|
||||
Workflow de publicação de oportunidades, contratos especializados e campos ainda incompletos continuam no backlog ligado ao objetivo, sem encerramento por esta proposta. Educação continua depois das falhas prioritárias; não se inicia nova jornada educativa.
|
||||
|
||||
## Evidências e decisão pedida
|
||||
|
||||
Mesma matriz: 3.354 requisitos, 3.354 linhas de dados mais cabeçalho, 5.830 linhas de origem preservadas. Este documento complementa fontes e evidências de requisitos existentes; não certifica 3.354 percursos. A contagem de estados continua independente da proposta aprovada. Ligações: [relatório executivo](relatorio-executivo.md), [backlog](backlog.md), [ativação](plano-ativacao.md), [casos](casos-reproducao.md).
|
||||
|
||||
C24: teste de regressão reproduziu o link genérico em vez do draft ligado; correção encaminha plano/simulador/recomendação financeira por `?draft=ID` apenas quando a leitura da origem está autorizada. QA de InvestorGuidance: 16 testes, 285 asserções; vínculo/dados recuperados por API, outro draft não substitui o esperado, gestor não ganha acesso. Clique e visual continuam pendentes.
|
||||
|
||||
**Decisão concreta:** aprovar a composição do painel sobre o dossier de trabalho existente, as cinco fases com rastreabilidade S01–S19, fonte mestre com snapshots explícitos, estados por âmbito e preparação paralela; autorizar I1–I3 exclusivamente em QA, com A/B completos na interface como condição de fecho. Não inclui instalação ativa, divulgação automática, RBAC de entidades externas ou nova jornada educativa. Se houver alteração pretendida, identificar o princípio/etapa/lote concreto; manter I0 independente dessa decisão.
|
||||
@@ -0,0 +1,346 @@
|
||||
{
|
||||
"kind": "capability_map_not_a_parallel_requirement_matrix",
|
||||
"source_sha256": "aa13c53138ec15cd808de43d9dc2fc6808da86943d09d3352c9dd0944bdae364",
|
||||
"runtime_read_only_capture": "2026-10-09T19:03:32+00:00",
|
||||
"stage_count": 19,
|
||||
"phase_count": 5,
|
||||
"structural_implementation_approved": true,
|
||||
"active_writes": 0,
|
||||
"stages": [
|
||||
{
|
||||
"stage_id": "S01",
|
||||
"phase": 1,
|
||||
"source": {
|
||||
"sha256": "aa13c53138ec15cd808de43d9dc2fc6808da86943d09d3352c9dd0944bdae364",
|
||||
"part": "word/document.xml",
|
||||
"paragraph": 22,
|
||||
"text": "Sistematizar a ideia: identificar o problema ou oportunidade, definir a proposta de valor, os promotores e a localização preliminar."
|
||||
},
|
||||
"diagram_mapping": "bloco 1",
|
||||
"capabilities": "Draft do simulador, dossier Balcão, perfil, planejamento",
|
||||
"applicability_dependencies_result": "Sempre; título/objetivo mínimos para guardar, proposta/promotores/localização preliminar quando conhecidos",
|
||||
"audit_requirement_refs": "AUD-DESK-01/02, AUD-SIM-01, AUD-GUIDE-01",
|
||||
"proposed": true,
|
||||
"runtime_definition_prepared": true,
|
||||
"integrated_ui_demonstrated": false
|
||||
},
|
||||
{
|
||||
"stage_id": "S02",
|
||||
"phase": 1,
|
||||
"source": {
|
||||
"sha256": "aa13c53138ec15cd808de43d9dc2fc6808da86943d09d3352c9dd0944bdae364",
|
||||
"part": "word/document.xml",
|
||||
"paragraph": 23,
|
||||
"text": "Realizar a análise preliminar: avaliar o mercado, a viabilidade técnica, o impacto económico e social e os principais riscos."
|
||||
},
|
||||
"diagram_mapping": "bloco 2",
|
||||
"capabilities": "Plano empresarial, riscos, cenários financeiros, biblioteca",
|
||||
"applicability_dependencies_result": "Sempre; evidências e pressupostos separados, valores ausentes indeterminados",
|
||||
"audit_requirement_refs": "AUD-SIM-02, AUD-LIB-01, AUD-GUIDE-01",
|
||||
"proposed": true,
|
||||
"runtime_definition_prepared": true,
|
||||
"integrated_ui_demonstrated": false
|
||||
},
|
||||
{
|
||||
"stage_id": "S03",
|
||||
"phase": 1,
|
||||
"source": {
|
||||
"sha256": "aa13c53138ec15cd808de43d9dc2fc6808da86943d09d3352c9dd0944bdae364",
|
||||
"part": "word/document.xml",
|
||||
"paragraph": 24,
|
||||
"text": "Decidir sobre a viabilidade da ideia: se não for viável, reformular ou arquivar e regressar à sistematização; se for viável, avançar para a estruturação."
|
||||
},
|
||||
"diagram_mapping": "losango ideia viável",
|
||||
"capabilities": "Readiness e orientação explicável",
|
||||
"applicability_dependencies_result": "Decisão do promotor com fundamentos; prosseguir/reformular/arquivar. Sem score automático, aprovação pública ou bloqueio da preparação",
|
||||
"audit_requirement_refs": "AUD-GUIDE-01, AUD-DASH-01",
|
||||
"proposed": true,
|
||||
"runtime_definition_prepared": true,
|
||||
"integrated_ui_demonstrated": false
|
||||
},
|
||||
{
|
||||
"stage_id": "S04",
|
||||
"phase": 1,
|
||||
"source": {
|
||||
"sha256": "aa13c53138ec15cd808de43d9dc2fc6808da86943d09d3352c9dd0944bdae364",
|
||||
"part": "word/document.xml",
|
||||
"paragraph": 25,
|
||||
"text": "Estruturar o investimento: preparar o plano de negócios, o modelo financeiro, o cronograma, a governação e a forma jurídica."
|
||||
},
|
||||
"diagram_mapping": "bloco 3",
|
||||
"capabilities": "Plano, equipa, marcos e snapshots",
|
||||
"applicability_dependencies_result": "Sempre; consolidar estratégia, finanças, calendário e forma jurídica, sem reintroduzir dados conhecidos",
|
||||
"audit_requirement_refs": "AUD-DESK-02, AUD-SIM-01/02",
|
||||
"proposed": true,
|
||||
"runtime_definition_prepared": true,
|
||||
"integrated_ui_demonstrated": false
|
||||
},
|
||||
{
|
||||
"stage_id": "S05",
|
||||
"phase": 2,
|
||||
"source": {
|
||||
"sha256": "aa13c53138ec15cd808de43d9dc2fc6808da86943d09d3352c9dd0944bdae364",
|
||||
"part": "word/document.xml",
|
||||
"paragraph": 26,
|
||||
"text": "Constituir e registar a entidade: obter o NUIT, efectuar o registo comercial, abrir a conta bancária e concluir os cadastros laboral e fiscal aplicáveis."
|
||||
},
|
||||
"diagram_mapping": "bloco 4",
|
||||
"capabilities": "Declarações empresariais e Balcão E1–E9",
|
||||
"applicability_dependencies_result": "Conforme entidade/tipo de investimento; registo/NUIT são atos externos, dados declarados não os provam; entidade existente reutilizada",
|
||||
"audit_requirement_refs": "AUD-DESK-01/02, AUD-LIB-01",
|
||||
"proposed": true,
|
||||
"runtime_definition_prepared": true,
|
||||
"integrated_ui_demonstrated": false
|
||||
},
|
||||
{
|
||||
"stage_id": "S06",
|
||||
"phase": 2,
|
||||
"source": {
|
||||
"sha256": "aa13c53138ec15cd808de43d9dc2fc6808da86943d09d3352c9dd0944bdae364",
|
||||
"part": "word/document.xml",
|
||||
"paragraph": 27,
|
||||
"text": "Preparar o processo de investimento: reunir a memória descritiva, o orçamento, as fontes de financiamento, os estudos e os comprovativos."
|
||||
},
|
||||
"diagram_mapping": "bloco 5",
|
||||
"capabilities": "`desk_cases`, documentos e revisões, investment submission",
|
||||
"applicability_dependencies_result": "Preparação paralela à constituição; atos de envio exigem somente os campos/documentos do serviço aplicável",
|
||||
"audit_requirement_refs": "AUD-DESK-01/02, AUD-LIB-01/02",
|
||||
"proposed": true,
|
||||
"runtime_definition_prepared": true,
|
||||
"integrated_ui_demonstrated": false
|
||||
},
|
||||
{
|
||||
"stage_id": "S07",
|
||||
"phase": 2,
|
||||
"source": {
|
||||
"sha256": "aa13c53138ec15cd808de43d9dc2fc6808da86943d09d3352c9dd0944bdae364",
|
||||
"part": "word/document.xml",
|
||||
"paragraph": 28,
|
||||
"text": "Submeter o projecto: solicitar as autorizações de investimento e os incentivos aplicáveis."
|
||||
},
|
||||
"diagram_mapping": "bloco 6",
|
||||
"capabilities": "Serviço project-preparation, protocolo, recibo, revisão",
|
||||
"applicability_dependencies_result": "Apenas quando aplicável e após revisão/consentimento; pedido interno não equivale a envio ou aprovação APIEX/incentivo",
|
||||
"audit_requirement_refs": "AUD-DESK-01, AUD-GUIDE-01",
|
||||
"proposed": true,
|
||||
"runtime_definition_prepared": true,
|
||||
"integrated_ui_demonstrated": false
|
||||
},
|
||||
{
|
||||
"stage_id": "S08",
|
||||
"phase": 3,
|
||||
"source": {
|
||||
"sha256": "aa13c53138ec15cd808de43d9dc2fc6808da86943d09d3352c9dd0944bdae364",
|
||||
"part": "word/document.xml",
|
||||
"paragraph": 29,
|
||||
"text": "Executar o licenciamento prévio e integrado: tratar, conforme a aplicabilidade, das licenças ambiental, sectorial e de construção, bem como das autorizações de segurança, trabalho, fiscais e municipais necessárias antes da implementação. A licença de operação deve permanecer condicionada às inspecções e aos testes posteriores."
|
||||
},
|
||||
"diagram_mapping": "bloco 7",
|
||||
"capabilities": "Etapas documentais Balcão, fontes, documentos e validade",
|
||||
"applicability_dependencies_result": "Regras por atividade/localização; preparar em paralelo; cada submissão depende do seu contrato. Operação fica em S17",
|
||||
"audit_requirement_refs": "AUD-DESK-01/02, AUD-LIB-01, AUD-GUIDE-01",
|
||||
"proposed": true,
|
||||
"runtime_definition_prepared": true,
|
||||
"integrated_ui_demonstrated": false
|
||||
},
|
||||
{
|
||||
"stage_id": "S09",
|
||||
"phase": 3,
|
||||
"source": {
|
||||
"sha256": "aa13c53138ec15cd808de43d9dc2fc6808da86943d09d3352c9dd0944bdae364",
|
||||
"part": "word/document.xml",
|
||||
"paragraph": 30,
|
||||
"text": "Decidir sobre a necessidade de terra: se o projecto não necessitar de terra, avançar para o financiamento; se necessitar, activar o subpercurso de terra."
|
||||
},
|
||||
"diagram_mapping": "losango terra",
|
||||
"capabilities": "Perguntas de localização e assistência fundiária",
|
||||
"applicability_dependencies_result": "Sim/não/por determinar com fundamento e histórico. Não depende de licença já aprovada para responder",
|
||||
"audit_requirement_refs": "AUD-LAND-01, AUD-GEO-02, AUD-GUIDE-01",
|
||||
"proposed": true,
|
||||
"runtime_definition_prepared": true,
|
||||
"integrated_ui_demonstrated": false
|
||||
},
|
||||
{
|
||||
"stage_id": "S10",
|
||||
"phase": 3,
|
||||
"source": {
|
||||
"sha256": "aa13c53138ec15cd808de43d9dc2fc6808da86943d09d3352c9dd0944bdae364",
|
||||
"part": "word/document.xml",
|
||||
"paragraph": 31,
|
||||
"text": "Regularizar a terra: identificar a área, verificar a compatibilidade territorial, realizar a consulta comunitária e o levantamento, tramitar o DUAT, a cessão ou o arrendamento e efectuar o registo aplicável."
|
||||
},
|
||||
"diagram_mapping": "blocos 8–10",
|
||||
"capabilities": "LandAssistance, seletores, mapas, anexos",
|
||||
"applicability_dependencies_result": "Só se S09=sim; área, compatibilidade, consulta/levantamento/título/registo conforme regra oficial. Geometria não é DUAT nem prova de disponibilidade",
|
||||
"audit_requirement_refs": "AUD-LAND-01, AUD-GEO-01/02/03, AUD-LIB-01",
|
||||
"proposed": true,
|
||||
"runtime_definition_prepared": true,
|
||||
"integrated_ui_demonstrated": false
|
||||
},
|
||||
{
|
||||
"stage_id": "S11",
|
||||
"phase": 3,
|
||||
"source": {
|
||||
"sha256": "aa13c53138ec15cd808de43d9dc2fc6808da86943d09d3352c9dd0944bdae364",
|
||||
"part": "word/document.xml",
|
||||
"paragraph": 32,
|
||||
"text": "Confirmar a regularização: se as licenças e a terra não estiverem regularizadas, corrigir as pendências e regressar às etapas correspondentes; se estiverem regularizadas, prosseguir."
|
||||
},
|
||||
"diagram_mapping": "losango licenças e terra",
|
||||
"capabilities": "Evidência e revisão documental separadas",
|
||||
"applicability_dependencies_result": "Verificar requisitos efetivamente aplicáveis; devolver pendências a S08/S10. Ato condiciona execução, não bloqueia S02/S04 ou preparação financeira",
|
||||
"audit_requirement_refs": "AUD-DESK-01/02, AUD-GUIDE-01",
|
||||
"proposed": true,
|
||||
"runtime_definition_prepared": true,
|
||||
"integrated_ui_demonstrated": false
|
||||
},
|
||||
{
|
||||
"stage_id": "S12",
|
||||
"phase": 4,
|
||||
"source": {
|
||||
"sha256": "aa13c53138ec15cd808de43d9dc2fc6808da86943d09d3352c9dd0944bdae364",
|
||||
"part": "word/document.xml",
|
||||
"paragraph": 33,
|
||||
"text": "Decidir sobre a necessidade de financiamento: se o projecto necessitar de financiamento externo, activar a estruturação financeira, a due diligence, a negociação, a aprovação, o fecho e o desembolso; se não necessitar, registar a fonte de capital próprio e avançar directamente para a implementação, desde que as restantes condições estejam cumpridas."
|
||||
},
|
||||
"diagram_mapping": "bloco 11 e condição do texto",
|
||||
"capabilities": "Fontes de fundos, plano, simulador, parceiros",
|
||||
"applicability_dependencies_result": "Sim/não/por determinar. Sem financiamento externo: guardar fonte/capital próprio; não afirmar disponibilidade sem evidência",
|
||||
"audit_requirement_refs": "AUD-SIM-01/02, AUD-PART-01, AUD-GUIDE-01",
|
||||
"proposed": true,
|
||||
"runtime_definition_prepared": true,
|
||||
"integrated_ui_demonstrated": false
|
||||
},
|
||||
{
|
||||
"stage_id": "S13",
|
||||
"phase": 4,
|
||||
"source": {
|
||||
"sha256": "aa13c53138ec15cd808de43d9dc2fc6808da86943d09d3352c9dd0944bdae364",
|
||||
"part": "word/document.xml",
|
||||
"paragraph": 34,
|
||||
"text": "Realizar a due diligence e a negociação: validar os aspectos jurídicos, técnicos, financeiros e operacionais e negociar as condições."
|
||||
},
|
||||
"diagram_mapping": "bloco 12",
|
||||
"capabilities": "Sala de parceria, documentos, tarefas, cenários",
|
||||
"applicability_dependencies_result": "Ramo de financiamento externo; preparação paralela a terra. Não dispensa outras diligências aplicáveis fora desse ramo",
|
||||
"audit_requirement_refs": "AUD-PART-01, AUD-LIB-01, AUD-GUIDE-01",
|
||||
"proposed": true,
|
||||
"runtime_definition_prepared": true,
|
||||
"integrated_ui_demonstrated": false
|
||||
},
|
||||
{
|
||||
"stage_id": "S14",
|
||||
"phase": 4,
|
||||
"source": {
|
||||
"sha256": "aa13c53138ec15cd808de43d9dc2fc6808da86943d09d3352c9dd0944bdae364",
|
||||
"part": "word/document.xml",
|
||||
"paragraph": 35,
|
||||
"text": "Decidir sobre o financiamento: se não for aprovado, rever a estrutura financeira e as garantias e regressar à estruturação do financiamento; se for aprovado, concluir o fecho financeiro."
|
||||
},
|
||||
"diagram_mapping": "losango aprovado",
|
||||
"capabilities": "Marcos/parcerias e registo assistido",
|
||||
"applicability_dependencies_result": "Resultado do financiador, com referência/documento/data; recusa regressa à estrutura sem apagar propostas anteriores",
|
||||
"audit_requirement_refs": "AUD-PART-01, AUD-DESK-02",
|
||||
"proposed": true,
|
||||
"runtime_definition_prepared": true,
|
||||
"integrated_ui_demonstrated": false
|
||||
},
|
||||
{
|
||||
"stage_id": "S15",
|
||||
"phase": 4,
|
||||
"source": {
|
||||
"sha256": "aa13c53138ec15cd808de43d9dc2fc6808da86943d09d3352c9dd0944bdae364",
|
||||
"part": "word/document.xml",
|
||||
"paragraph": 36,
|
||||
"text": "Concluir o fecho financeiro e o desembolso: cumprir as condições precedentes, formalizar os contratos e disponibilizar os fundos."
|
||||
},
|
||||
"diagram_mapping": "bloco 13",
|
||||
"capabilities": "Marcos, documentos e obrigações declaradas",
|
||||
"applicability_dependencies_result": "Se financiamento externo; aprovação não comprova contrato, condições cumpridas ou desembolso",
|
||||
"audit_requirement_refs": "AUD-PART-01, AUD-GUIDE-01",
|
||||
"proposed": true,
|
||||
"runtime_definition_prepared": true,
|
||||
"integrated_ui_demonstrated": false
|
||||
},
|
||||
{
|
||||
"stage_id": "S16",
|
||||
"phase": 5,
|
||||
"source": {
|
||||
"sha256": "aa13c53138ec15cd808de43d9dc2fc6808da86943d09d3352c9dd0944bdae364",
|
||||
"part": "word/document.xml",
|
||||
"paragraph": 37,
|
||||
"text": "Implementar o projecto: executar aquisições, contratações, obras e instalação dos equipamentos."
|
||||
},
|
||||
"diagram_mapping": "bloco 14",
|
||||
"capabilities": "ProjectPlanning, tarefas, marcos, aftercare",
|
||||
"applicability_dependencies_result": "Planejar sempre; executar apenas requisitos prévios aplicáveis cumpridos, com motivo específico e evidência",
|
||||
"audit_requirement_refs": "AUD-GUIDE-01, AUD-CRM-01, AUD-DASH-01",
|
||||
"proposed": true,
|
||||
"runtime_definition_prepared": true,
|
||||
"integrated_ui_demonstrated": false
|
||||
},
|
||||
{
|
||||
"stage_id": "S17",
|
||||
"phase": 5,
|
||||
"source": {
|
||||
"sha256": "aa13c53138ec15cd808de43d9dc2fc6808da86943d09d3352c9dd0944bdae364",
|
||||
"part": "word/document.xml",
|
||||
"paragraph": 38,
|
||||
"text": "Realizar inspecções e testes: verificar a conformidade e obter a licença de operação."
|
||||
},
|
||||
"diagram_mapping": "bloco 15",
|
||||
"capabilities": "Documentos, resultados e tarefas",
|
||||
"applicability_dependencies_result": "Conforme atividade; inspeção e emissão são externas, checklist concluída não é licença",
|
||||
"audit_requirement_refs": "AUD-DESK-02, AUD-LIB-01, AUD-GUIDE-01",
|
||||
"proposed": true,
|
||||
"runtime_definition_prepared": true,
|
||||
"integrated_ui_demonstrated": false
|
||||
},
|
||||
{
|
||||
"stage_id": "S18",
|
||||
"phase": 5,
|
||||
"source": {
|
||||
"sha256": "aa13c53138ec15cd808de43d9dc2fc6808da86943d09d3352c9dd0944bdae364",
|
||||
"part": "word/document.xml",
|
||||
"paragraph": 39,
|
||||
"text": "Iniciar a operação: colocar o investimento em funcionamento após o cumprimento dos requisitos aplicáveis."
|
||||
},
|
||||
"diagram_mapping": "bloco 16",
|
||||
"capabilities": "Marcos de execução e acompanhamento",
|
||||
"applicability_dependencies_result": "Cumprir exigências aplicáveis de S17 e anteriores; guardar data/decisão declarada/evidências, sem assumir legalidade por clique",
|
||||
"audit_requirement_refs": "AUD-GUIDE-01, AUD-CRM-01",
|
||||
"proposed": true,
|
||||
"runtime_definition_prepared": true,
|
||||
"integrated_ui_demonstrated": false
|
||||
},
|
||||
{
|
||||
"stage_id": "S19",
|
||||
"phase": 5,
|
||||
"source": {
|
||||
"sha256": "aa13c53138ec15cd808de43d9dc2fc6808da86943d09d3352c9dd0944bdae364",
|
||||
"part": "word/document.xml",
|
||||
"paragraph": 40,
|
||||
"text": "Monitorar continuamente: acompanhar a conformidade fiscal, laboral, ambiental e regulatória, a validade das licenças, os indicadores e as auditorias."
|
||||
},
|
||||
"diagram_mapping": "bloco 17",
|
||||
"capabilities": "Aftercare, tarefas, validade documental, audit_events",
|
||||
"applicability_dependencies_result": "Operação ativa; conformidade, renovações, indicadores e medidas corretivas. É recorrente, não fica definitivamente concluída por preencher",
|
||||
"audit_requirement_refs": "AUD-CRM-01, AUD-DASH-01, AUD-LIB-01",
|
||||
"proposed": true,
|
||||
"runtime_definition_prepared": true,
|
||||
"integrated_ui_demonstrated": false
|
||||
}
|
||||
],
|
||||
"qa_scenarios": {
|
||||
"A": {
|
||||
"land_needed": false,
|
||||
"external_funding_needed": false,
|
||||
"status": "api_persistence_demonstrated_integrated_ui_pending"
|
||||
},
|
||||
"B": {
|
||||
"land_needed": true,
|
||||
"external_funding_needed": true,
|
||||
"status": "api_persistence_demonstrated_integrated_ui_pending"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,399 @@
|
||||
# InvesteMoz — relatório executivo do lote 3
|
||||
|
||||
## C37 — causa confirmada; seleção de conta QA corrigida — P0, visual pendente
|
||||
|
||||
O pedido de reabertura referia a conta esperada18. A captura manual21:22–21:24UTC demonstra que foi selecionada a conta13 restaurada. O MFA foi alcançado, mas a autenticação nunca se completou. Causa concreta: credenciais MFA da conta13 cifradas pela chave de origem, incompatíveis com a chave estávelQA; a conta18 sintética não foi desafiada nessa tentativa. Nenhuma chave, MFA ou conta13 foi alterada para contornar o problema.
|
||||
|
||||
| UTC09/10 | Pedido | Resultado observado |
|
||||
|---|---|---|
|
||||
|21:22:10|GET/investimentos|302/login; sessão convidada guardada, destino pretendido /investimentos.|
|
||||
|21:22:11|GET/login|200; mesmo cookie/sessão, sem autenticação.|
|
||||
|21:22:44|POST/login|302/two-factor-challenge; login.id=13, não18.|
|
||||
|21:22:44|GET/two-factor-challenge|200; desafio13 recuperado da mesma sessão; ecrã confirmado pelo utilizador.|
|
||||
|21:23:04|POST/two-factor-challenge|Falha de desencriptação; warning correlacionado conta13;302/login, invalidação intencional e nova sessão convidada.|
|
||||
|21:23:04|GET/login|200; cookie aceite corresponde à sessão regenerada; sem utilizador autenticado.|
|
||||
|
||||
Primeiro desvio do ensaio: POST/login desafia13. Primeira falha técnica: POST/two-factor-challenge às21:23:04 (trace ec68d040a3291cb8, referência26e15b04-07b8-4211-a2a0-7f70509e03f6). Não se tratou de código MFA rejeitado pelo verificador nem de perda após autenticação. Os dois campos cifrados (secret/recovery) são incompatíveis; como nenhum corpo foi retido, não se afirma qual modalidade de entrada foi usada nesta tentativa. Não foram observados conflitos de cookies, mudança de chave/guard ou redirecionamento para outra origem.
|
||||
|
||||
CorreçãoQA, após guarda real desk_restore_20261009_174726_test:55441: login identifica/preenche o email não secreto da conta18; o ecrã MFA identifica a conta realmente desafiada. PortalQaAccountSelection, carregado exclusivamente pelo routerQA, recusa endereços não sintéticos antes do desafio e cancela desafios antigos de contas restauradas, com erro controlado. Os perfis sintéticosQA mantêm o login Fortify normal e respetivo MFA. Contas restauradas e dados ativos preservados. A conta13 continua cifrada como no original; não foi reencryptada nem usa chave ativa como fallback.
|
||||
|
||||
Lacuna de feedback encontrada no código: o Form recém-criado no login começa com erros locais vazios e não lia o errors.email devolvido pela página após redirecionamento do MFA. Login agora apresenta também esse erro da página. A mensagem de falha de desencriptação continua controlada e não autentica; sua apresentação visual ainda exige confirmação.
|
||||
|
||||
Evidência atual2026-10-09T21:37:04.282708+00:00 em c37-auth-redirect-qa.json, pelo servidor18097 e protocolo Inertia/HTML com redirects reais: seletor13 recusado antes do MFA; desafio18 identificado; código inválido mantém desafio sem autenticar; MFA válido regenera/grava18 e redireciona /investimentos; GET e reload mantêm18; logout revoga acesso; novo cookie jar+login+MFA recupera o mesmo dossier413ba1f6-bdf6-402a-a561-c4e2d4098d1a; outra conta403. Negativo sintético19 demonstra falha de desencriptação→login com mensagem, sem autenticação. Nenhuma criação extra de dossier. Estes são resultados de resposta/persistência, não um ensaio visual bem-sucedido.
|
||||
|
||||
Evidências: c37-manual-2122-2124-qa.json conserva os seis pedidos e warning sanitizados; auth-session-trace-qa.jsonl mantém histórico append-only e pseudónimos HMAC; c37-qa-account-auth.xml verifica políticaQA, preservação, MFA válido/inválido e falhas secret/recovery; c37-installation-auth-fingerprint.xml verifica guardas/importação/reversão. TypeScript e build passaram. mfa-persistence-qa.json reconfirma conta13 e .env byte a byte, MFA18 confirmado/oito códigos, chave não gerada/rodada e zero escritas ativas. Cookies, passwords, OTP e corpos não são exportados.
|
||||
|
||||
Estado: causa identificada, preparaçãoQA corrigida e protocolo/persistência demonstrados; C37 permanece aberto para /investimentos visível→reload→logout→novo login da conta18 no navegador. A captura manual demonstrou apenas o MFA da conta13 e retorno ao login; não certifica o percursoA/B nem o feedback atualizado. Próximo teste deve confirmar que o ecrã diz contaQA18 antes de usar o autenticador dessa conta. URL exato http://127.0.0.1:18097/investimentos. Credenciais/segredo permanecem somente no ficheiro privado local investor-mfa-qa-private.json, sem exportação. Workflow/contratos especializados continuam no backlog, sem jornadas educativas novas.
|
||||
|
||||
Ativação não autorizada e revisão candidata não fixada. Fingerprints agora incluem também login.tsx e two-factor-challenge.tsx: percursob402e851b49bfb640f26417f1ff783320210271cd7d84e80dea0db264c89ec28; cartografia95610d2660956a9bb10e6ac9443c24ededf4f3d97f996047c92a5d5c37ff3c6c; recursos4aa6946228b5ebb99bb29e3166e9ce53abdba776b3298a9ccbe437784d8cfa02. Ready/provas de versões anteriores não demonstram esta revisão. Política/seletor/rastreioQA não integram instalação ativa. Após aceitação visualA/B e correções, renovar backup/restauro/compatibilidade e manter a ordem já documentada de recursos→percurso→flag→importação cartográfica→publicação separada, sem repetir o que estiver instalado. ReversãoQA: retirar registo/configuração de PortalQaAccountSelection e overrides Fortify do router; retirar os registos de rastreio; preservar provas. A correção do feedback é código compatível sem migration, alteração de chave ou modificação de dados.
|
||||
|
||||
## C37 — MFA QA recuperado; cenário A visual por retomar
|
||||
|
||||
**C37/P0 — falha bloqueante do cenário A reportada pelo utilizador, corrigida por código/HTTP/persistência QA; retoma visual ainda pendente.** URL: http://127.0.0.1:18097/investimentos. Alvo real confirmado antes de qualquer escrita: `desk_restore_20261009_174726_test:55441`.
|
||||
|
||||
Stack completa dos erros20:39:16/20:41:52 (68frames por ocorrência) retida sem argumentos em mfa-original-stack-redacted.json. Falha em TwoFactorLoginRequest::hasValidCode() ao desencriptar users.two_factor_secret da conta13; PreserveFormFeedback apenas chama o próximo middleware. A conta restaurada não é sintética: secret/recovery abrem com a chave do .env de origem, mas não com a chaveQA. Cache de configuração não carregado; source cache também ausente. A ferramenta de preparação do percurso antes não fixava APP_KEY e podia herdar origem. portal-qa-environment.php centraliza a mesma chaveQA já existente entre preparação/web, força alvo/restauro, configura caminho QA de cache separado e recusa cache não reconciliado. Não gera chave, não usa chaves ativas como fallback nem modifica .env/cache ativo.
|
||||
|
||||
Duas sessões pendentes da conta13 removidas exclusivamente do diretório de sessões QA, após guarda do destino e paths. Original conta13 preservado byte a byte pelo hash da linha; nenhuma chave/MFA ativa ou da conta13 alterada. Novo investidor sintético QA: actor18, inscrição normal pelos endpoints Fortify (confirmar password→enable→secret-key→confirm), oito recovery codes, sem injeção direta do segredo nem desativação de MFA. Dados de acesso/segredo somente em investor-mfa-qa-private.json local privado; não exportados aqui.
|
||||
|
||||
POST /two-factor-challenge com DecryptException agora invalida desafio/sessão e retorna422 com mensagem controlada em JSON ou redireciona ao login com erro visível; nenhuma autenticação. Negativas reais de secret/recovery verificam401 após erro e remoção do desafio. A resposta HTML/Inertia contém a mensagem, sem ser prova de renderização visual. Logs controlados incluem apenas referência e ID pendente; as provas não exportam Cookie, X-XSRF-TOKEN, OTP ou corpos.
|
||||
|
||||
No mesmo servidor18097: login/MFA/logout/nova sessão passaram. A retomado por HTTP em `/investimentos/413ba1f6-bdf6-402a-a561-c4e2d4098d1a`: criação→logout→nova sessãoMFA→recuperação→aplicabilidade semterra/semfinanciamento→draft próprio→resultado→Balcão draft→tarefa concluída pela gestão→nova sessãoMFA recupera tudo. Gestão não recebe resultado financeiro privado. Função efetiva do dossier recalcula20unidades/0.00 a partir do resultado recuperado. QA atual5instâncias/95etapas; originals anteriores preservados. Esta conta não vê os A/B da outra contaQA.
|
||||
|
||||
Evidências: mfa-key-diagnosis-qa.json, mfa-session-invalidation-qa.json, mfa-persistence-qa.json, mfa-http-qa.json e mfa-auth-qa.xml. Os17 ensaios autenticam ou recusam os percursos concretos; não substituem interface. Fingerprints passam a incluir bootstrap/Fortify, invalidando ready/provas anteriores para ativação. `integrated_ui_ab_passed=false`, `candidate_revision_fixed=false`, `activation_ready=false`; nenhuma escrita ativa. Mesma matriz3354requisitos/5830origens, sem fecho amplo novo.
|
||||
|
||||
## Lote I0 atual — importação autenticada e operações documentais reais
|
||||
|
||||
**QA atual: http://127.0.0.1:18097/investimentos.** Porta18096 anterior não usar; erro PHP/Symfony no arranque com GD, antes do cabeçalho QA. Processo isolado recuperado com GD e OPcache desligado, sem mudança do PHP ativo. Base `desk_restore_20261009_174726_test:55441`, sessões próprias; SuiteCRM/AI externos desativados. CUA permanece sem apps/browsers. Nenhuma observação visual nem escrita ativa.
|
||||
|
||||
**Mesma matriz:**3354 requisitos/linhas canónicas,5830 ocorrências preservadas; parcial: 3198 requisitos/5380 ocorrências; não implementado: 146 requisitos/440 ocorrências; dependente de decisão concreta: 4 requisitos/4 ocorrências; implementado mas não ativado: 1 requisitos/1 ocorrências; concluído e demonstrado: 5 requisitos/5 ocorrências. Nenhum requisito amplo fechado por este lote. `candidate_revision_fixed=false`, `integrated_ui_ab_passed=false`, `activation_ready=false`; não fixar candidata antes dos resultados manuais e correções.
|
||||
|
||||
| Requisito | Correção/prova concreta deste lote | Estado |
|
||||
| --- | --- | --- |
|
||||
| AUD-GEO-02/03, OPS-01 | C30: GET/POST `/management/territory-geometry-import`, POST `/{batch}/reverse`. Fontes retidas/edição/hash/scan; nomes exatos+pai+país, conflitos, preview vinculado ao ator/estado, MFA, `geo_write_receipts`, `audit_events` append-only; nada publicado. HTTP real com login+TOTP, três níveis,361 reutilizadas/0 novas; replay e reversão de lote de reutilização mantêm361. QA de testes demonstra criação e reversão de lote novo, preservação de histórico e recusas de alteração/publicação/FK/scan expirado/MFA/alvo não QA. | Código preparado + API/persistência QA; interface e ativo pendentes |
|
||||
| AUD-SCAN-01 | C31: nome da rota assinada corrigido para `management.opportunity-image-preview`, mantendo URL. Servidor web QA gera3WebP320/640/1280; PDF+PNG+3derivadas têm cinco scans reais ClamAV1.5.4, clean/hash próprios, cifragem Laravel e classificação restricted; downloads reais comparados, assinaturas ausentes403 e outra conta403. QA de testes prova quarentena423, scanner inconclusivo e retry real, substituição sem apagar original, versão409, exclusão/restauro e adulteração409. | Operações de oportunidades demonstradas por API/persistência; apresentação visual pendente |
|
||||
| AUD-LIB-01/SCAN-01/DESK-02 | C35 corrigiu erro500 ao omitir data/emissor opcionais. C36 corrigiu recuperação404 de originais cifrados: os consumidores comparavam o hash do ciphertext com o original. VerifiedDocumentBinary reutiliza decifragem/integridade sem cópia pública nem alteração de permissões. PortalRealDocumentConsumersTest usa ClamD real: biblioteca privada→scan→classificação→publicação separada→download; versão409/dedup/404hash. Balcão testa upload/confidential→scan→download, dedup/403estranho. Original canónico cifrado é reutilizado sem duplicar documents; downloads na gestão/Balcão/biblioteca e view PDF devolvem os bytes originais; antes de publicação/adulteração404. | API/persistência QA; bytes de preview PDF verificados, renderização visual pendente; sem publicação ativa nem fecho global |
|
||||
| AUD-UI-01/DASH-01/SIM-01/DESK-02/GUIDE-01/CRM-01 | A/B repetidos por HTTP no servidor recuperado; nova sessão real, IDs/drafts próprios, recuperação, aplicabilidade, resultado20/0 e20/70000, Balcão e tarefa concluída enquanto terra aguarda; outra conta/contexto recusados. | API/persistência QA; cenários completos na interface pendentes |
|
||||
|
||||
**Correspondências:** províncias11→9/2; distritos159→120/39; postos411→232/179. Esperado refere o exemplar2019, não um cadastro atual certificado. Maputo e Maputo City são as duas pendências provinciais. Distritos:9 por pai não resolvido/30 por nome; postos:86 por pai/93 por nome. [Todas220 lacunas por nome/código/pai/causa](correspondencias-cartograficas.md). Sem polígonos de localidades no exemplar; nenhum limite equivale a implantação/DUAT. Aceitação da fonte oficial preservada.
|
||||
|
||||
**Evidências:** `geometry-auth-http-qa.json`, `resources-real-http-qa.json`, `document-real-persistence-qa.json`, `import-document-real-qa.xml`, `investor-path-http-qa.json` e `investor-path-recovered-calculations.json`, no acervo privado. As15 verificações dirigidas são inventário:4 importação,2 operações documentais reais,5 scanner/negativas e4 recursos com fixture. Não substituem prova por requisito ou interface.
|
||||
|
||||
**Ainda não verificado:** interface de A/B, cada formulário/estatística, cada seletor/mapa e operações documentais visuais. Biblioteca/Balcão têm agora os ensaios reais específicos acima; PDF view tem prova de bytes/MIME/CSP, mas renderização, importação em lote, todos os tipos/documentos/perfis e partilhas/imutabilidade por consumidor continuam pendentes. Os ensaios de compatibilidade/schema e fixtures não constituem prova ClamD real. ClamD real demonstrado nesta sessão é distinto de arranque após reboot/manutenção de assinaturas e GD no PHP ativo, ainda pendentes. Workflow e contratos especializados permanecem abertos; sem jornadas educativas novas.
|
||||
|
||||
## Continuação atual — prova HTTP, cobertura por formulário e interface pendente
|
||||
|
||||
**I0–I3 continuam parciais; nenhuma escrita ativa.** A/B passaram no servidor QA real18097: login → criação/gravação → logout → nova sessão/cookies/login → recuperação → aplicabilidade → ferramenta/entradas congeladas → resultado no dossier → rascunho Balcão → acompanhamento interno. Outra conta403/404; troca de contexto403; gestor não lê draft/resultado financeiro privado. Tarefa de mercado concluída enquanto terra aguarda. QA web{runtime['qa_path_journeys']} instâncias/{runtime['qa_path_steps']} etapas; inclui os dossiers sintéticos preservados e a continuação com MFA quando demonstrada. Não importar fixtures no ativo.
|
||||
|
||||
País/origem/filtros/estatísticas: provas específicas dos quatro tipos de apoio e três serviços Balcão reforçadas; wizard, fundiário, perfil/empresa/submissão e CRM conservam provas próprias. Complemento continuation-business-journey-qa.xml demonstra interesse em negócio público PT/ZA, recibo/replay, recuperação/filtro/estatística e jornada PT=1/MZ=0, sem inferir país como origem. Ver [cobertura por formulário/consumidor](cobertura-percursos-i0-i3.md), ligada aos IDs da matriz. Apresentação visual continua pendente.
|
||||
|
||||
C27 preparou a ligação do território principal ao preview na ficha da oportunidade e do filtro aplicado ao mapa da Bolsa; TypeScript/build passaram.361/361 limites reais recuperados READ ONLY na mesma QA A/B; perfis HTTP gestor/público/conta comum ensaiados em província/distrito/posto. Públicos0, internos361; faltam2/39/179 correspondências e polígonos de localidades. **Nenhum mapa ou seletor foi visualmente aceite.**
|
||||
|
||||
C29: a fixture HTTP inicial tinha listas orçamentais vazias incompatíveis. Corrigida por nova versão, mantendo os resultados congelados anteriores e o erro explícito. A função efetiva do dossier verifica agora os snapshots realmente recuperados: A20unidades/0.00 e B20/70000.00; é cálculo demonstrado, sem observação visual.
|
||||
|
||||
Browser: inventário vazio antes/depois de reset, IAB/Chrome/Edge indisponíveis; login QA HTTP200. Causa observada é fornecedor não exposto nesta sessão; causa de conexão/registo não determinada. [Roteiro manual executável](roteiro-manual-qa-i0-i3.md) com URLs, contas QA, ações/esperados e negativas preparado. HTML/props/HTTP não substituem essa execução.
|
||||
|
||||
Matriz única mantém3.354 requisitos/linhas canónicas e5.830 ocorrências;5 concluídos anteriores,3.198 parciais,146 não implementados,1 implementado mas não ativado,4 decisões concretas. **Nenhum novo requisito encerrado.** Evidências complementares por método nos JUnit continuation-consumer/profile/install, sessão real em investor-path-http-qa.json e mapa de cobertura acima. Regressão global384/5215 é anterior a C27; não serve como prova atual de interface. C28 remove número381 fixo no preparador de evidências, sem eliminar guardas/hashes/autenticação.
|
||||
|
||||
Backup/restauro final não renovado antes da demonstração visual. Fingerprints mudaram; ready=true histórico não vale para a versão atual. Instalação de recursos, extensão do percurso, disponibilização por configuração e importação/divulgação cartográfica são ações separadas, fora da autorização ativa. Workflow e contratos especializados permanecem no backlog; nenhuma jornada educativa nova.
|
||||
|
||||
## Histórico do lote inicial I0/I1–I3 — antes da continuação HTTP/C27
|
||||
|
||||
A execução QA foi aprovada; a ativação ativa não foi autorizada. Código preparado: painel composto, rascunho por dossier, contexto/retorno financeiro e definição imutável de cinco fases/19 etapas. QA demonstrada: API, gravação/recuperação, permissões, tarefas independentes e reversão protegida. **Interface A/B ainda não demonstrada; I1–I3 permanecem parciais.**
|
||||
|
||||
Provas finais: 384 testes globais/5.215 asserções; complemento A/B 3 testes/163 asserções; 158 ensaios frontend; TypeScript/build/PHPStan passaram. Lint dirigido sem erros, com quatro avisos anteriores nos consumidores reaproveitados. Importação oficial privada na QA do percurso:361=9+120+232; replay zero novos. Ativo consultado em READ ONLY: mesmos13 utilizadores/1 percurso/0 etapas/0 geometrias; nenhuma escrita ativa.
|
||||
|
||||
Matriz única:3.354 requisitos/linhas canónicas e5.830 linhas de origem. Estados por requisito:5 concluídos e demonstrados,3.198 parciais,146 não implementados,1 implementado mas não ativado,4 decisões concretas. A coluna “parcial” inclui falhas/cobertura pendente; zero na categoria “com falha” não significa ausência de falhas. Os cinco fechamentos estreitos anteriores permanecem; nenhum fecho novo por testes ou implementação estrutural.
|
||||
|
||||
Ver [execução, evidências e lacunas](execucao-percurso-i1-i3.md) e [plano consolidado](plano-ativacao.md). Os textos de proposta e provas anteriores abaixo são históricos e não revogam a aprovação QA agora recebida nem certificam ativação.
|
||||
|
||||
## Consolidação do percurso — aprovação QA e execução parcial
|
||||
|
||||
O estado atual inclui a [proposta fundamentada](proposta-consolidacao-percurso.md), baseada na leitura integral do DOCX solicitado e do seu fluxograma: cinco fases e 19 etapas, vinculadas aos IDs da mesma matriz. O texto tem 19 etapas; a imagem tem 17 blocos numerados e decisões separadas. Os roteiros E0–E11, sete grupos de orientação e outro roteiro com 14 atividades permanecem identificados por versão.
|
||||
|
||||
PostgreSQL/PostGIS e CRM externo desativado foram confirmados por leitura efetiva. O complemento não reinicia inventário: acrescenta um original e um anexo, ficando 525 ficheiros + 61 anexos = 586 registos. A matriz conserva 3.354 requisitos/linhas e 5.830 linhas de origem; estados não mudam por proposta. Os 381 testes/5.046 asserções do lote 3 abaixo são históricos desse lote; a nova regressão fica em consolidation-regression.log/XML.
|
||||
|
||||
C24: corrigido o encaminhamento do dossier para o draft específico do simulador, sem partilha de dados pessoais ou permissão do gestor. Regressão red→green: 16 testes de orientação/285 asserções; UI pendente. Execução I1–I3 aprovada em QA. Código/modelo/motor preparados e API/persistência A/B demonstradas; aceitação na interface ainda pendente. A extensão foi instalada apenas na cópia QA restaurada, sem conversão de roteiros anteriores. Ver execucao-percurso-i1-i3.md; a aprovação não autoriza a base ativa. Nenhuma escrita ativa.
|
||||
|
||||
## Histórico anterior à aprovação QA — proposta de consolidação
|
||||
|
||||
O estado atual inclui a [proposta fundamentada](proposta-consolidacao-percurso.md), baseada na leitura integral do DOCX solicitado e do seu fluxograma: cinco fases e 19 etapas, vinculadas aos IDs da mesma matriz. O texto tem 19 etapas; a imagem tem 17 blocos numerados e decisões separadas. Os roteiros E0–E11, sete grupos de orientação e outro roteiro com 14 atividades permanecem identificados por versão.
|
||||
|
||||
PostgreSQL/PostGIS e CRM externo desativado foram confirmados por leitura efetiva. O complemento não reinicia inventário: acrescenta um original e um anexo, ficando 525 ficheiros + 61 anexos = 586 registos. A matriz conserva 3.354 requisitos/linhas e 5.830 linhas de origem; estados não mudam por proposta. Os 381 testes/5.046 asserções do lote 3 abaixo são históricos desse lote; a nova regressão fica em consolidation-regression.log/XML.
|
||||
|
||||
C24: corrigido o encaminhamento do dossier para o draft específico do simulador, sem partilha de dados pessoais ou permissão do gestor. Regressão red→green: 16 testes de orientação/285 asserções; UI pendente. Cenários A/B estão preparados, não demonstrados. Navegação/modelo/motor e migrations ainda não implementados; aprovação pendente. Nenhuma escrita ativa.
|
||||
|
||||
09/10/2026. Continuação da mesma matriz, sem novas jornadas educativas. Código preparado e API/persistência demonstradas em QA; nenhuma escrita ativa pela auditoria. Resultados visuais e anexação direta de PDFs continuam pendentes.
|
||||
|
||||
## Lote executado
|
||||
|
||||
- **AUD-COUNTRY-04 / AUD-DESK-01, C21:** os três serviços existentes do Balcão têm agora país do requerente separado da origem da solicitação. Ambos guardam no payload cifrado existente e recuperam via GET/Inertia; catálogo de 249 países. ZZ recebe 422 sem nova versão. Submissão recuperável; dono não analisa o próprio pedido, outra conta não consulta, gestor devolve os campos explicitamente permitidos. Corrigida a rejeição da origem na lista de campos devolvidos para correção. Correção permitida guarda versão 5; alteração de título não autorizado 422; versão antiga 409. Definições/histórico dos serviços preservados, sem reinstalação.
|
||||
- **AUD-GEO-02/03, C22:** consulta de contexto administrativo ligada ao seletor territorial partilhado, gestão territorial, draft/recursos de oportunidades, catálogo e painel de mapas. TerritoryGeometry usa geo_locations/geo_geometries existentes; não cria local de investimento, perímetro de zona ou ponto fictício. GeoJSON simplificado, origem/edição/hash e legenda administrativa independentes dos marcadores de investimento.
|
||||
- **Geometrias reais:** na QA 171209,361/361 limites importados recuperados pelo novo serviço; zero geometrias internas divulgadas publicamente. Teste HTTP separado demonstra autorização de gestor 403 para outra conta, UUID inválido 422, geometria arquivada retirada, edição 2019 preservada. Localidade sem polígono próprio continua sem geometria própria mesmo tendo contexto ancestral. Nenhuma classificação/publicação ativa alterada.
|
||||
- **AUD-UI-01:** ações de CRM, Bolsa, recursos, território, fundiário e Balcão passaram nos casos automatizados ligados em acoes-perfis-lote3.csv. Resultado de resposta/GET/Inertia/evento é prova de servidor, não de clique observado. Inventário atual 363 botões/272 seletores e mapas não fecha todos os consumidores.
|
||||
|
||||
## Cobertura por formulário
|
||||
|
||||
| Formulário | País/origem | API, gravação e recuperação | Interface atual |
|
||||
| ---------------------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | --------------------------------------- |
|
||||
| Manifestação pública | Campos distintos | Provas de InterestOrigin/Continuation/Compatibility: payload, metadata, inválido e replay | Preparada; visual pendente |
|
||||
| Apoio: 4 tipos | País pertinente/origem opcional | Quatro percursos já ensaiados, recuperação/agregado | Preparada; visual pendente |
|
||||
| Interesse público em negócio | País/origem distintos | Provas anteriores próprias, não confundidas com wizard | Visual/variações pendentes |
|
||||
| Jornada | País/origem separados | Recuperação de jornada/solicitação | Visual pendente |
|
||||
| Wizard de negócios | Catálogo 249 e legado conservado | Cifra, GET, filtros autorizados, submetido no agregado; draft excluído | Visual/revisão completa pendentes |
|
||||
| Assistência fundiária | Catálogo 249/legado/origem | Grava/recupera, apoio mantém origem, filtros/agregado e hierarquia 4 níveis | Visual/mapa/anexos pendentes |
|
||||
| Balcão preparação | País/origem separados | Novo percurso completo servidor, incluindo devolução/correção autorizada | Visual pendente |
|
||||
| Balcão alteração | País/origem separados | Mesmo ensaio individual com campos próprios do serviço | Visual pendente |
|
||||
| Balcão acompanhamento | País/origem separados | Mesmo ensaio individual com campos próprios do serviço | Visual pendente |
|
||||
| Simulador | Residência fiscal/países dos fundos; sem inferir origem de solicitação | Snapshots cifrados/GET, legado e inválido, sem cálculo por guardar | Demais campos/cálculos/visual pendentes |
|
||||
| Gestor/CRM | Filtros de país/origem/unknown | Interests/desk/businesses separados; solicitações, não investidores únicos | URL/seleção/tabela visuais pendentes |
|
||||
|
||||
Campo opcional ausente permanece não informado. Não preencheu cadastros vazios nem converteu textos/valores históricos silenciosamente. Cobertura global continua parcial: alterações em componentes comuns não demonstram individualmente todos os formulários.
|
||||
|
||||
## Três estados territoriais independentes
|
||||
|
||||
1. **Território cadastrado:**1920 IDs administrativos públicos recuperados pela API, além do país; fonte workbook existente. Não representa campo preenchido.
|
||||
2. **Geometria disponível:**361 limites internos QA, 9 províncias/120 distritos/232 postos. Fonte INE/UNOCHA, edição 07/06/2019, originais/hash/scan preservados e aceitação oficial mantida. Lacunas nominais continuam 2 províncias/39 distritos/179 postos; sem polígonos de localidade nesse exemplar. Ativo:zero geometrias.
|
||||
3. **Apresentação funcional:** endpoints e consumidores preparados, recuperação real361/361, sem divulgação pública. Mapa renderizado/zoom/seleção/filtro/feedback ainda não observados. Não fechar requisito por GeoJSON disponível. Zonas/perímetros e locais documentados de projetos/parcerias têm regras próprias; limite administrativo não os substitui.
|
||||
|
||||
## Navegador e documentação
|
||||
|
||||
C23: servidor QA 18096 não escutava; foi iniciado e respondeu HTTP200 com header de destino _test:55441. O controlo de UI devolveu apps[]/browsers[] antes e depois de reset; Chrome e Edge responderam Browser is not available. Diagnóstico concreto: serviço QA recuperado, fornecedor de UI não registado nesta sessão. Causa subjacente do registo não foi demonstrada. Ligação de navegador solicitada, sem parar API/persistência. Não foram usadas capturas antigas como prova atual.
|
||||
|
||||
Não existe ferramenta de anexação nativa de PDF nesta sessão. Os links Adobe anteriores não funcionaram para o utilizador; logo os PDFs **não foram entregues como anexos diretos**, nem considerados revisão documental concluída. Este relatório/backlog mantêm-se no workspace e o conteúdo necessário à revisão é apresentado na conversa, sem novos links Adobe. PDFs do lote2 permanecem históricos.
|
||||
|
||||
## Provas, matriz e ativo
|
||||
|
||||
381 testes passaram, 5046 asserções, zero skips; 156 frontend/reconciliação. TypeScript, PHPStan, build e formato passaram. Lint 0 erros/11 avisos; npm check termina1 por avisos, não aprovação limpa. Novos 2 testes/124 asserções mais regressão integral381. 360 GET por 4 perfis, sem falhas registadas; não demonstra todos os botões/transições.
|
||||
|
||||
Mesma matriz: 3354 requisitos/3354 linhas de dados+header; 5830 linhas de origem preservadas, com referências adicionais ao pedido deste lote. Estados: 5 concluídos no critério estreito, 3198 parciais, 146 não implementados, 1 implementado não ativo, 0 com falha no critério atualmente registado, 4 decisões concretas. Parcial pode conter ações/campos ainda ausentes; zero com falha não significa portal sem falhas. Concluídos:OPS02/03,COUNTRY05,GEO04,STYLE01. Workflow,contratos especializados e decomposição semântica de cláusulas continuam no backlog.
|
||||
|
||||
Leitura ativa17:47:24UTC:288 tabelas; zero geometrias; Balcão/Bolsa/gestão básica com um evento de instalação cada. Recursos installed=false,ready=true; não repetidos. Fonte oficial aceite, importação não publica nem ativa cálculo.
|
||||
|
||||
Plano atual: código sem migration → recursos autenticados uma vez → importação cartográfica separada/privada → divulgação/camadas por ato explícito e prova por consumidor. Backup/restauro verificado 2026-10-09T17:47:35+00:00, cópia desk_restore_20261009_174726_test:55441,288 tabelas/cinco ficheiros e reversão comparados. Hash 8fe9cbf438a87315c1c20588bd9a748239018d0662af22533774e07f16a06cef. Validade 24h sujeita às guardas. ClamD só afeta scans/libertação binária; manutenção após reinício e GD/WebP web/derivadas pendentes.
|
||||
|
||||
Evidências: matriz-requisitos.csv, acoes-perfis-lote3.csv, casos C01–C23, phpunit-lote3-final.xml, geometry-consumers-lote3.json, resources-lote3-preview.json, activation-evidence.json. Dumps/configuração/chaves não são anexos.
|
||||
|
||||
## Histórico do lote 2 e anteriores — não representa o estado atual
|
||||
|
||||
# InvesteMoz — relatório executivo do lote 2
|
||||
|
||||
09/10/2026. Continuação da **mesma matriz**. Código preparado, API/persistência demonstradas em QA e funcionalidade ativa são estados separados. **Nenhuma escrita de dados na base ativa por esta auditoria.** Leitura ativa: 17:20:47 UTC. Navegador indisponível: a tentativa de abrir QA voltou a falhar; não há demonstração visual desta versão.
|
||||
|
||||
## Resultado e prioridades
|
||||
|
||||
As três falhas anteriormente classificadas foram corrigidas no âmbito ensaiado: rejeição 422 da maturidade 7/8, indisponibilidade do ClamD e checks globais de formato. Isto não encerra os requisitos mais amplos de maturidade/publicação, binários/derivadas ou interface. Foram ainda encontrados e corrigidos a rejeição da hierarquia territorial fundiária, a perda da origem ao solicitar apoio e o botão de pesquisa sem ação.
|
||||
|
||||
| Requisito / caso | Correção e evidência | QA / ativo |
|
||||
| ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
|
||||
| AUD-OP-05 / C15 | Oito etapas versionadas; 7/8 recebem 201 e GET recupera etapa/posição/versão. Legado de seis níveis mantém significado; discrepância 422, conflito 409, outro utilizador 403. | API/persistência QA; visual/publicação pendentes. Sem conversão ativa. |
|
||||
| AUD-COUNTRY-06/07; AUD-STATS-01 / C17–19 | País e origem separados em negócios/fundiário; gravação cifrada, recuperação, filtros autorizados e agregados. Texto legado conservado. | QA demonstrada por formulário; visual e versão servida ativa não demonstradas. |
|
||||
| AUD-GEO-02/03 / C17 | Fundiário aceita país→província→distrito→posto→localidade. 361 geometrias oficiais inequívocas importadas privadamente e recuperadas, sem duplicar na segunda execução. | QA: 9 províncias, 120 distritos, 232 postos. Ativo: zero geometrias. |
|
||||
| AUD-SCAN-01 / C07 | ClamD real 1.5.4, assinaturas atualizadas, EICAR detetado e seis integrações reais passaram. | Serviço local disponível; arranque após reinício, manutenção e derivadas web pendentes. |
|
||||
| AUD-STYLE-01 / C10 | Formato global passou; lint sem erros, 11 avisos existentes. | Critério concluído; não certifica interface. |
|
||||
| AUD-UI-01 / C20 | Ícone de pesquisa ligado à rota existente de oportunidades. | Código preparado/rota ensaiada; clique visual pendente. |
|
||||
|
||||
O próximo lote prioriza **percursos existentes de guardar/recuperar, filtros, seletores, mapas e ações por perfil**. Rascunhos e novas jornadas educativas ficam depois destas correções, sem desaparecer do backlog.
|
||||
|
||||
## Contagens reconciliadas
|
||||
|
||||
A [matriz existente](matriz-requisitos.csv) contém **3.354 requisitos canónicos e 3.354 linhas de dados**, mais cabeçalho. Preserva **5.830 linhas de origem**, com IDs/aliases, fontes, trechos, hashes, versões divergentes e critérios por operação. Não foi criada outra matriz.
|
||||
|
||||
| Estado | Requisitos | Linhas de origem |
|
||||
| ------------------------------------------ | ---------: | ---------------: |
|
||||
| Concluído e demonstrado | 5 | 5 |
|
||||
| Parcial | 3.198 | 5.380 |
|
||||
| Não implementado | 146 | 440 |
|
||||
| Implementado mas não ativado | 1 | 1 |
|
||||
| Com falha no critério atualmente registado | 0 | 0 |
|
||||
| Dependente de decisão concreta | 4 | 4 |
|
||||
| Total | 3.354 | 5.830 |
|
||||
|
||||
Zero linhas no estado «com falha» **não significa zero falhas no portal**: requisitos com componentes corrigidos e componentes ainda ausentes permanecem parciais. Continuam sem implementação o workflow completo, contratos especializados e rascunho educativo incompleto. Continuam não demonstrados todos os consumidores/mapas e a interface renderizada.
|
||||
|
||||
Concluídos apenas nos critérios estreitos: AUD-OPS-02 (guarda QA), AUD-OPS-03 (leitura/preservação), AUD-COUNTRY-05 (API ISO), AUD-GEO-04 (recuperação do catálogo administrativo) e AUD-STYLE-01 (checks de formato). Catálogo API não encerra formulário/mapa. Contagens não são percentagem de aceitação; decomposição semântica de cláusulas compostas permanece AUD-DOC-01. As cinco etapas de prova estão separadas por requisito: interface → API → gravação → recuperação → resultado apresentado.
|
||||
|
||||
## Países, origem e estatísticas por percurso
|
||||
|
||||
**Negócios:** CountrySelect e 249 países nas props → POST/PUT autorizados → country=PT/origem=ZA no payload cifrado existente → GET recupera os dois → lista filtrada e estatísticas de negócio submetido ZA=1/PT=0. Draft fica fora do agregado; outra conta recebe 403/lista vazia. ZZ recebe 422 sem nova versão. Texto histórico Portugal conserva-se no draft até escolha explícita de PT; submissão completa exige ISO conhecido.
|
||||
|
||||
**Fundiário:** CountrySelect país/origem → POST/PUT do caso → payload cifrado separado → GET recupera país/origem e caminho dos quatro níveis → solicitar apoio conserva origem na solicitação/CRM; gestor filtra país PT/origem ZA. Agregado de interesses conta o pedido uma vez. Texto legado Moçambique permanece exato; inválido conserva versão; outra conta 404/403.
|
||||
|
||||
**Percursos anteriores preservados:** manifestação pública, quatro tipos de apoio, interesse em negócio, jornada e Balcão têm provas específicas de origem; simulador guarda países em snapshots cifrados, sem gerar cálculo por isso. Os conjuntos interests, desk e businesses são apresentados separadamente. São solicitações/negócios, não investidores únicos. Ausência permanece «não informado»: não foi inferida origem para os quatro interesses históricos ativos. [Cobertura por consumidor](cobertura-consumidores-lote2.md) identifica o que falta por formulário.
|
||||
|
||||
## Território, fontes e mapas
|
||||
|
||||
O inventário passa a **524 ficheiros e 60 anexos embebidos: 584 registos**, incluindo 11 originais novos de serviço/metadados/datasets GIS. Binários ClamAV e logs são artefactos de execução, não acervo documental. A aceitação das fontes oficiais mantém-se; metadados servem para identificar edição/âmbito, não recertificar credibilidade.
|
||||
|
||||
Fonte selecionada: serviço Mozambique/FeatureServer, origem **INE**, distribuição UNOCHA, edição **07/06/2019**, disponível no alojamento ArcGIS do Banco Mundial. Originais GeoJSON preservados por hash: ADM1=11, ADM2=159, ADM3=411. Importação exige origem, contagem integral, scan real do original, geometria válida/SRID 4326 e correspondência única de nome normalizado + pai. Códigos de fontes diferentes não foram equiparados automaticamente.
|
||||
|
||||
QA `desk_restore_20261009_171209_test:55441`: **9 + 120 + 232 = 361** correspondências importadas em `geo_geometries` existente; segundo import reutiliza todas e cria zero. Todas válidas e recuperáveis. **Lacunas: 2 províncias, 39 distritos, 179 postos sem correspondência inequívoca; nenhuma geometria de localidade nessa fonte.** As duas designações de Maputo diferem entre versões; sem remapeamento silencioso. Edição de 2019 não é declaração de atualidade jurídica.
|
||||
|
||||
Geometrias estão **internas, privadas, QA**. Não viram locais de investimento, polígonos publicados ou pontos inventados. Os 1.920 territórios recuperados em 597 pedidos API continuam prova de catálogo, não de campos/mapas. Mapas de oportunidades, catálogo/detalhe/portefólio, parcerias e zonas precisam de provas próprias de camada, filtro, geometria/identificador e resultado. Ativo mantém zero geometrias; 28 locais de projetos e 13 relações cluster–projeto foram preservados.
|
||||
|
||||
## QA, ações e limites
|
||||
|
||||
**379 testes passaram, 4.922 asserções, zero saltados; 156 testes frontend/reconciliação passaram.** TypeScript, PHPStan, build e formato global passaram; build conserva aviso de tamanho de chunks, lint 11 avisos existentes. O comando npm check termina com código 1 devido a esses avisos, sem erros de lint. PortalAuditNextLotTest demonstra maturidade, negócios e fundiário com persistência, recuperação, isolamento, inválidos e conflitos. Seis testes de ClamD real passaram, sem substituto fictício.
|
||||
|
||||
Inventário estático de todas as páginas/componentes TSX: **363 ocorrências de botões e 270 seletores/mapas**. Cinco dependem de contexto de diálogo/menu e exigem confirmação por percurso; não são classificados como falha só por falta de handler direto. Binding estático e os 352 GET anteriores por quatro perfis não demonstram todos os cliques/transições/anexos. O navegador continua indisponível; não há capturas apresentadas como prova atual.
|
||||
|
||||
Base ativa consultada READ ONLY: 288 tabelas; seis oportunidades reais IDs 1–6, 1.990 territórios, zero geometrias, dois negócios/duas revisões, quatro interesses sem origem, um dossier Balcão/zero pedidos. Cadastros vazios educativos/CRM/Bolsa não foram preenchidos artificialmente. Dos 209 hashes temporais comparáveis, 207 coincidem; cache/sessions diferem sem causa atribuída. Backup/restauro atual compara todas as 288 tabelas e cinco ficheiros.
|
||||
|
||||
## Instalação e próximo lote
|
||||
|
||||
Recursos continuam **installed=false; ready=true** no preview READ ONLY de 17:29:58 UTC. Backup/restauro verificado às **17:29:44 UTC**, QA `desk_restore_20261009_172936_test:55441`; reversão compatível nas 288 tabelas. Fingerprint `69252e258339bbef24d78681aaf78f968a281e85c5a103870f5d6363aca98831`; validade até 10/10 17:29 UTC, sujeita às guardas.
|
||||
|
||||
Países/origem/estatísticas/maturidade do draft não exigem migration nem ClamD. Extensão privada de imagens/documentos/multilocalização exige a ação autenticada existente e aplica só `2026_10_09_030000_extend_opportunity_resources`, uma vez. Não repetir Balcão/Bolsa/gestão básica. ClamD limita scans/libertação dos binários afetados; GD/WebP do PHP web e scans de derivadas continuam prova separada. Serviço ClamD atual não comprova arranque após reinício.
|
||||
|
||||
Próximo lote: fechar API/persistência dos restantes seletores/filtros e ações existentes por consumidor/perfil; integrar em QA as camadas privadas já correspondidas e demonstrar resultados; completar workflow e consumidores da maturidade versionada sem reinterpretar histórico. Verificação visual retoma assim que houver navegador. Instalação não transforma preparação em aceitação integral.
|
||||
|
||||
Decisões humanas mantidas: pares oportunidade–projeto/cluster por ID/papel/citação; entidade operadora/contactos/termos; contactos/links/responsável por serviço; pesos/limiares/baseline dos pilotos. Nenhuma reabertura da aceitação oficial.
|
||||
|
||||
[Backlog](backlog.md) · [Matriz](matriz-requisitos.csv) · [Casos C01–C20](casos-reproducao.md) · [Cobertura e evidências](cobertura-consumidores-lote2.md) · [Plano de ativação](plano-ativacao.md) · [Inventário](inventario-fontes.csv). Dumps, ZIP, configuração, chaves e dados pessoais não acompanham os anexos.
|
||||
|
||||
## Histórico da continuação anterior — não representa o estado atual
|
||||
|
||||
# Auditoria InvesteMoz — relatório executivo atualizado
|
||||
|
||||
9 de outubro de 2026. Continuação da mesma auditoria. **Código preparado e QA demonstrada; nenhuma alteração de dados na base ativa por esta auditoria.** Leitura ativa: 16:17:55 UTC / 18:17:55 locais. A verificação visual permanece pendente: zero browsers disponíveis no controlo de superfícies.
|
||||
|
||||
## Resultado atual
|
||||
|
||||
- **Concluídos no critério indicado:** exclusividade dos ensaios QA (`AUD-OPS-02`), leitura/preservação (`AUD-OPS-03`), catálogo HTTP ISO (`AUD-COUNTRY-05`) e recuperação integral do catálogo administrativo pela API (`AUD-GEO-04`). Os critérios dos catálogos não encerram formulários ou mapas.
|
||||
- **Corrigidos no servidor, ainda parciais:** país e origem separados nos formulários públicos/apoio/jornada, recuperação da origem no gestor, estatísticas por origem, países do simulador e hierarquia do Balcão (`AUD-COUNTRY-04`, `AUD-STATS-01`, `AUD-SIM-01`, `AUD-GEO-02`). Props Inertia e código de apresentação verificados; falta observar a interface renderizada.
|
||||
- **Continuam a falhar/faltar:** maturidade 7/8, workflow integral, contratos especializados, rascunho incompleto de procura/capacidade, jornadas/painéis educativos por ator, restantes consumidores de países/território, geometrias e instalação dos recursos. ClamD limita as operações binárias afetadas.
|
||||
- **Próximo lote:** países no wizard de negócios e assistência fundiária; catálogo de maturidade com oito etapas e versão explícita; rascunhos educativos; ensaios de ações/recuperação por consumidor e perfil. Não espera por pendências independentes.
|
||||
|
||||
## Uma matriz: requisitos e linhas de origem
|
||||
|
||||
A [matriz existente](matriz-requisitos.csv) tem **3.354 requisitos canónicos / 3.354 linhas de dados**, mais cabeçalho. Conserva **5.830 linhas de origem**: as 5.822 anteriores, dois critérios de catálogo e seis requisitos operacionais explicitados na continuação. Não foi criada matriz paralela.
|
||||
|
||||
| Estado | Requisitos | Linhas de origem |
|
||||
| ------------------------------ | ---------: | ---------------: |
|
||||
| Concluído e demonstrado | 4 | 4 |
|
||||
| Parcial | 3.196 | 5.378 |
|
||||
| Não implementado | 146 | 440 |
|
||||
| Implementado mas não ativado | 1 | 1 |
|
||||
| Com falha | 3 | 3 |
|
||||
| Dependente de decisão concreta | 4 | 4 |
|
||||
| Total | 3.354 | 5.830 |
|
||||
|
||||
Textos exatamente equivalentes no mesmo módulo foram reunidos. Variantes `Create/Patch/Response` do mesmo campo tornam-se um requisito canónico; obrigatoriedade, critérios, texto, IDs, fontes/hash/parágrafo e diferenças de operação permanecem em **Critérios e versões por origem (JSON)**. A matriz contém aliases de todos os IDs, quantidade de linhas de origem e cinco colunas separadas: **interface → API → gravação → recuperação → resultado apresentado**. A verificação de conservação recusa perda/duplicação de identidades.
|
||||
|
||||
Não se fundiram textos divergentes por coincidência de ID. `RF-EDU-001–016` conserva namespaces `@UPGRADE`/`@EDUCACAO`. **As contagens não são percentagem de aceitação integral:** cláusulas compostas ainda precisam de decomposição/revisão semântica (`AUD-DOC-01`), e requisitos sem prova individual conservam o percurso explicitamente não demonstrado. Não se afirmam 3.354 percursos aprovados.
|
||||
|
||||
Versões/exemplares anteriores permanecem referenciados: mestre histórico `fc771363…`, atual `d0c06a75…`, especificação `9f173ed3…`, upgrades/reformulações/educação por hash/parágrafo. A decisão de aceitação das fontes oficiais permanece válida. O original upgrade v4 não foi localizado; marcador Office não é original. O relatório indicado em `outputs/auditoria-portal-2026-10-09.md` não está disponível neste workspace; foi registada a mensagem do utilizador como fonte direta, sem inventar leitura/hash desse ficheiro.
|
||||
|
||||
Inventário preservado: 513 ficheiros e 60 anexos embebidos; 17 DOCX e 57 TXT processados; 4.576 ocorrências prescritivas e 110 definições de objetos. As 46 ocorrências iniciais de componentes/seletores são inventário de chamadas com contexto, não prova de 46 campos completos. Linhas de código antigas permanecem referências históricas.
|
||||
|
||||
## Percursos prioritários demonstrados e lacunas
|
||||
|
||||
**Países/origem — AUD-COUNTRY-01–04/06–07; C01/C13.** Interface preparada com catálogo pesquisável, sem preenchimento automático → POST API/apoio → `interest_requests.country=PT` e `metadata.declared_origin_country_code=ZA` → GET do gestor/jornada → props apresentam ambos separados. Os quatro tipos de apoio foram ensaiados. ZZ recebe 422 sem escrita; replay não duplica; outra conta 403; texto legado Moçambique permanece exato. Compatibilidade com texto livre não significa validar todo texto como ISO. País de residência/constituição e origem não são inferidos entre si. Países no wizard de negócios e assistência fundiária ainda são texto livre, com ligação ao catálogo e ensaio individual pendentes.
|
||||
|
||||
**Estatísticas — AUD-STATS-01.** Origem persistida → GET CRM `origin=ZA` → agregado QA ZA=1; filtro PT não recebe esse pedido. Interesses e pedidos Balcão separados; quatro interesses históricos ativos permanecem não informados. São solicitações, não investidores únicos. Resultado Inertia demonstrado; filtro/tabela visuais pendentes. Não depende de SuiteCRM externo ou ClamD.
|
||||
|
||||
**Simulador — AUD-COUNTRY-05/AUD-SIM-01; C12.** Falha encontrada: países consultavam jurisdições territoriais, limitadas a Moçambique e à publicação desse catálogo. Países agora usam `/api/v1/catalogs/countries`; campos territoriais usam a API administrativa povoada. API ISO entrega 249 códigos únicos em três páginas, pesquisa nome/código e sem acentos. POST/PUT guarda PT e `[PT, ZA]` em snapshots privados cifrados → GET recupera exatamente → outra conta 404; ZZ 422; atualização com ETag conserva o legado Portugal. Nenhuma execução fiscal criada por guardar países. Formulário preparado; UI e demais campos continuam parciais.
|
||||
|
||||
**Território — AUD-GEO-01–04/AUD-FIELD-\*; C02/C06/C14.** Na cópia restaurada do catálogo ativo, **597 pedidos recuperaram todos os 1.920 IDs administrativos públicos**, sem omissões/duplicados: 11 províncias, 148 distritos, 437 postos e 1.324 localidades. O país público adicional explica o total histórico 1.921. Os 69 registos internos não foram promovidos a públicos.
|
||||
|
||||
Balcão: `TerritoryFields` substitui lista plana → API pesquisa quatro níveis → PUT guarda ID da localidade no payload cifrado existente → GET recupera ID e `territoryPaths` → props permitem apresentar a hierarquia. ID privado recebe erro junto ao campo e conserva versão/valor; outra conta negada. **Há zero geometrias ativas.** Catálogo povoado e pesquisa provincial não encerram mapas, multilocalização ou todos os consumidores. Restantes campos próprios/estados/filtros precisam de prova individual; não inferir pontos de centros provinciais.
|
||||
|
||||
**Oportunidades/educação — AUD-OP-03–05/AUD-EDU-01–03; C08/C15/C16.** Quatro reproduções HTTP na cópia QA: maturidade 7/8 recebe 422 em `maturity_level`; procura/capacidade incompletas recebem 422 pelos campos finais obrigatórios. Hashes de oportunidades, procura, capacidade e histórico mantiveram-se iguais. São falhas do critério solicitado, não aceitação aprovada.
|
||||
|
||||
Maturidade tem `between:1,6` e seletor de seis etapas; corrigir com oito etapas versionadas da especificação, sem remapear as seis antigas. Workflow de revisão/aprovação/publicação e campos/regras especializados continuam ausentes/incompletos. Selecionar categoria não os implementa. Educação exige declaração completa e grava `submitted`; draft de curso/proposta de investimento não satisfaz draft incompleto de procura/capacidade. Catálogo/gestão interna não satisfaz jornadas/painéis por ator. Reutilizar entidades/schemas existentes.
|
||||
|
||||
## QA, base ativa e cobertura
|
||||
|
||||
Suite atual: **376 testes, 373 passaram, 4.608 asserções; três ClamD reais saltados**. Novo lote: cinco testes, 203 asserções. Passaram 152 frontend, TypeScript, PHPStan e build. Build conserva aviso de tamanho de chunks. Check global de formato permanece aberto: 16 frontend/documentos/scripts e cinco PHP; ficheiros alterados verificados seletivamente.
|
||||
|
||||
Os 352 GET anteriores por quatro perfis não encontraram 5xx, mas não cobrem todos os botões, IDs/transições/anexos. 401/403/302 são controlo de acesso, não prova funcional. A matriz inclui novos casos de falha e mantém limites do varrimento.
|
||||
|
||||
Leitura ativa READ ONLY: 288 tabelas, seis oportunidades IDs 1–6 classificadas real; 1.990 territórios e zero geometrias; 28 locais de projetos e 13 relações cluster–projeto; zero relações oportunidade–projeto/cluster/localizações de oportunidades. Quatro documentos públicos com scan histórico, sem novo scan real. Quatro solicitações sem origem; um dossier Balcão, zero pedidos, três versões de serviço; zero leads/negociações. Bolsa/conjuntos educativos consultados vazios; dois negócios/duas revisões e direitos/mandatos/documentos consultados vazios. Vazio não prova perda e não foi preenchido artificialmente.
|
||||
|
||||
Balcão, Bolsa e gestão básica têm uma instalação cada; recursos não instalados. IA local ligada não comprova fornecedor externo. Das 209 tabelas comparáveis iniciais, 207 hashes coincidem; cache/sessions diferem sem causa atribuída. Não se afirma comparação temporal das outras 79. Backup/restauro atual compara todas as 288 tabelas e cinco ficheiros privados.
|
||||
|
||||
## Ativação, decisões e evidências
|
||||
|
||||
Ordem: servir/verificar código e assets dos catálogos/recuperação, sem migration → aplicar só extensão privada de recursos pelo mecanismo autenticado existente → scan/derivadas nas operações afetadas → uso real com dados/designações fornecidos. [Plano reconciliado](plano-ativacao.md).
|
||||
|
||||
Backup/restauro **16:18:09 UTC**, cópia `desk_restore_20261009_161758_test:55441`, compatibilidade/reversão das 288 tabelas demonstradas. Fingerprint `c328f542…`; preview READ ONLY `installed=false`, `ready=true`. Validade até 10/10/2026 16:18:09 UTC, condicionada a hash/destino/guardas. Não houve instalação ativa nem repetição de Balcão/Bolsa/gestão básica.
|
||||
|
||||
ClamD é dependência específica de scan/libertação de binários/anexos/derivadas afetados; não bloqueia países, pesquisas territoriais, estatísticas, metadados ou rascunhos. GD/WebP do PHP web diz respeito a gerar derivadas e tem prova separada. Não publicar lote ou ativar cálculo por importação.
|
||||
|
||||
Decisões humanas: pares oportunidade–projeto/cluster por ID/papel/citação; operador/contactos/termos; links/responsável por serviço; pesos/limiares/baseline dos pilotos. Revisores/aprovadores reais são necessários antes dos atos institucionais ativos, não do desenvolvimento QA. Nenhuma reabertura genérica da credibilidade oficial aceite.
|
||||
|
||||
[Backlog](backlog.md), [casos C01–C16](casos-reproducao.md), [matriz/aliases](matriz-requisitos.csv), [fontes/anexos](inventario-fontes.csv), `cobertura-rotas.csv` e `cobertura-testes.csv`. Provas privadas sem exportar dados pessoais: `contagens-requisitos.json`, `phpunit-final.json`, `phpunit-followup-recovery-final.log`, `territory-catalogue-coverage.json`, `pending-actions.json`, `active-followup-output.json`, `resources-followup-compatibility.json`, `resources-followup-preview.json`, `activation-evidence.json`. Dumps, ZIP/configuração/chaves não acompanham anexos.
|
||||
|
||||
## Histórico inicial — números e provas abaixo não são o estado atual
|
||||
|
||||
O texto inicial é conservado para rastreabilidade. Onde divergir, prevalecem a situação reconciliada acima e as versões/critério de origem na matriz. O plano/hash de 15:16 foi substituído pela prova de 16:18; as 5.822 linhas iniciais não são 5.822 requisitos aceites.
|
||||
|
||||
# Auditoria inicial — diagnóstico e primeiro incremento
|
||||
|
||||
Data: 9 de outubro de 2026. Estado ativo consultado às **15:23:42 UTC / 17:23:42 locais**. O portal tem componentes funcionais em QA, mas não satisfaz integralmente os pedidos reconciliados. A gestão básica de oportunidades está instalada; os recursos privados de oportunidades continuam **preparados e demonstrados por testes QA, sem instalação ativa**. Não houve instalação, importação, publicação ou alteração de dados ativos nesta auditoria.
|
||||
|
||||
Entregas: [matriz única](matriz-requisitos.csv), [backlog por requisito](backlog-priorizado.csv), [sequência de execução](backlog.md), [casos de reprodução](casos-reproducao.md), [plano autenticado de ativação](plano-ativacao.md), [inventário de fontes e anexos](inventario-fontes.csv), [ensaios HTTP por perfil](cobertura-rotas.csv) e [inventário de métodos de teste](cobertura-testes.csv).
|
||||
|
||||
## O que impede a conclusão
|
||||
|
||||
| Prioridade | Constatação | Resultado necessário |
|
||||
| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| P0 | Uma execução concorrente de PHPUnit sobre a mesma QA produziu deadlock e colisões de migrations. Foi um erro de orquestração desta auditoria. | Guarda de exclusividade acrescentada e demonstrada: o segundo processo é recusado antes da limpeza; suite sequencial passa. |
|
||||
| P0 | O coletor de backup recolhia IDs de auditoria depois de terminar o snapshot. | IDs recolhidos dentro da mesma transação. Novo backup/restauro integral verificado antes de preparar a ativação. |
|
||||
| P1 | Origem declarada era descartada nos formulários públicos/API e percurso legado. | Correção conserva ISO em `interest_requests.metadata`, sem inferir valores históricos. API/persistência/replay demonstrados em QA; UI nova pendente. |
|
||||
| P1 | Seletor provincial comum não oferecia pesquisa e podia ocultar uma seleção guardada ausente das opções. | Pesquisa por nome/código, cancelamento de resposta antiga e apresentação da seleção guardada preparados. Validação visual pendente. |
|
||||
| P1 | Recursos de oportunidades não existem no esquema ativo. | Aplicar uma única extensão pelo fluxo autenticado, após os passos do plano. Não reinstalar gestão básica, Balcão ou Bolsa. |
|
||||
| P1 | Workflow integral de oportunidades e contratos especializados continuam ausentes do cadastro integrado. | Construir incrementos sobre as entidades existentes; separar autoria, revisão, aprovação e publicação. Escolher uma categoria não implementa o respetivo contrato. |
|
||||
| P1 | Cartografia transversal não está demonstrada; existem **zero geometrias ativas**. | Conferir cada consumidor e os dados geométricos disponíveis no acervo; manter entidades sem localização explicitamente identificadas. |
|
||||
| P1 | ClamD real indisponível; três ensaios reais foram saltados. | Demonstrar serviço/assinaturas e scan real em QA. Metadados e rascunhos continuam utilizáveis; nenhum scan real é substituído por fixture. |
|
||||
| P2 | Há checks globais de formatação com falhas preexistentes e módulos instalados sem operação real povoada. | Corrigir formatação por ficheiro e executar percursos com dados e responsáveis reais quando fornecidos. Não criar exemplos ativos para aparentar utilização. |
|
||||
|
||||
Não foi identificada nova falha 5xx nos 352 GET ensaiados em QA. Esse resultado não exclui falhas em rotas com identificadores, botões, anexos, transições ou percursos visuais ainda não executados.
|
||||
|
||||
## Reconciliação e limites da matriz
|
||||
|
||||
Foi lido o `AGENTS.md`, o [backlog V2](../backlog-mestre.md), as matrizes anteriores, os relatórios de gestão/recursos/origem/território/Balcão, os documentos mestres e a especificação de oportunidades. A inventariação precedeu a seleção de fontes para extração. O inventário regista **513 ficheiros e 60 anexos embebidos**: 244 documentos do repositório e 269 ficheiros nos diretórios de fontes/anexos/originais privados identificados. Inclui os quatro originais da biblioteca ativa, staging e fontes territoriais. Os backups e a configuração com segredos permanecem privados; não constituem documentos a publicar no acervo.
|
||||
|
||||
Foram processados 17 DOCX de especificação/mestres e 57 TXT acessíveis, incluindo versões de texto dos pedidos. Foram conservadas 4.576 ocorrências de cláusulas prescritivas. O contrato de oportunidades contém 110 definições de objetos, não 110 módulos. O inventário de chamadas encontrou 46 consumidores de componentes de países/território; cada consumidor tem linha própria e aceitação individual pendente.
|
||||
|
||||
O registo atual tem **5.822 linhas**: requisitos formais anteriores, V2, cláusulas de documentos, campos do contrato, consumidores e 37 verificações operacionais revistas. Todas as linhas têm as colunas solicitadas. Os IDs `RF-EDU-001` a `RF-EDU-016` repetiam-se em fontes distintas; recebem namespace `@UPGRADE` ou `@EDUCACAO`, conservando ID original e texto. Não foram fundidos por coincidência do identificador.
|
||||
|
||||
| Estado | Linhas |
|
||||
| ------------------------------ | -----: |
|
||||
| concluído e demonstrado | 2 |
|
||||
| parcial | 5.375 |
|
||||
| não implementado | 438 |
|
||||
| implementado mas não ativado | 1 |
|
||||
| com falha | 2 |
|
||||
| dependente de decisão concreta | 4 |
|
||||
|
||||
**Esta é uma matriz inicial de reconciliação, não uma certificação integral de 5.822 requisitos.** A extração de cláusulas conserva candidatos que ainda podem exigir divisão em critérios atómicos e revisão semântica. A evidência do domínio, as rotas inferidas e os componentes encontrados não demonstram automaticamente cada linha. As linhas não revistas individualmente estão explicitamente parciais; o backlog não pode ser usado como percentagem de conclusão. As 438 linhas não implementadas incluem campos especializados e requisitos operacionais relacionados; não representam 438 funcionalidades independentes.
|
||||
|
||||
Versões preservadas: mestre V2 histórico com hash `fc771363…` e exemplar atual `d0c06a75…`; especificação de oportunidades `9f173ed3…`; variantes upgrade v1/v2/v5/v6, reformulações e educação separadas por exemplar/hash/parágrafo. O original upgrade v4 referido pela matriz histórica não foi localizado entre os exemplares atuais; o ficheiro `~$…v4…docx` é um marcador de bloqueio do Office e não o documento original. Erros de ZIP desses marcadores não demonstram corrupção do original ou malware. Ausência de um exemplar atual não elimina a rastreabilidade anterior.
|
||||
|
||||
As fontes governamentais já identificadas continuam aceites conforme a decisão de 08/10/2026. Pendências históricas genéricas de certificação dessa proveniência não são dependências atuais. Conferir âmbito, período, alterações expressas e parâmetros de cálculo continua necessário. Não se atribuiu origem oficial a documentos de promotores/programação e não se ativou cálculo fiscal por inventário ou publicação.
|
||||
|
||||
## Estado efetivo da base ativa
|
||||
|
||||
A leitura usou transação PostgreSQL `REPEATABLE READ READ ONLY`, destino `investemoz:5432`, abrangendo **288 tabelas** em todos os schemas não sistémicos. Foram exportados contagens, estrutura, hashes e estados agregados; não foram exportados registos pessoais. Os ensaios de escrita usaram apenas bases com sufixo `_test`, na porta 55441.
|
||||
|
||||
| Domínio | Disponibilidade observada | Limite da conclusão |
|
||||
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Países/origem/estatísticas | Catálogo local de 249 códigos; quatro pedidos ativos com origem não informada | Não inferir origem de residência, constituição, IP ou texto legado. Filtro CRM atual sem validação visual nesta sessão. |
|
||||
| Oportunidades | Seis oportunidades, IDs 1–6 classificados `real`; gestão instalada uma vez em 09/10, 06:29:42 UTC | Recursos ainda ausentes; contratos completos e workflow não concluídos. |
|
||||
| Território/cartografia | 1.990 territórios: 1.921 públicos e 69 internos; 11 províncias, 150 distritos, 451 postos, 1.377 localidades e um país; zero geometrias | Os relatórios com 1.921 contam só públicos. Cadastro textual não demonstra cobertura cartográfica. |
|
||||
| Relações territoriais | 28 localizações de projetos e 13 relações cluster–projeto; zero relações oportunidade–projeto/cluster e zero localizações de oportunidades | Preservar pares existentes; as correspondências dos seis IDs não podem ser inferidas. |
|
||||
| Balcão/orientação | Instalado uma vez em 08/10, 09:56:37 UTC; um dossier, zero pedidos, três versões de serviço | Três versões não significam três serviços distintos. Primeiro pedido real e referências institucionais específicas pendentes. |
|
||||
| CRM interno | Quatro solicitações; zero leads e zero negociações CRM | Testes de conversão/acompanhamento não povoam a base ativa. SuiteCRM externo está desligado e não bloqueia CRM interno. |
|
||||
| Biblioteca/simuladores | Quatro documentos públicos com estado de scan historicamente registado como limpo; calculadores e rascunhos existentes | Não foi feito novo scan real. Inventário não equivale a publicação; regra fiscal exige parâmetros e versão aplicáveis. |
|
||||
| Educação | Flag ligada; schema `skills_edu` instalado, cadastros consultados vazios | Catálogo educativo e submódulo de procura/capacidade têm requisitos distintos; não aceitar o fluxo de cada ator por existir menu. |
|
||||
| Bolsa/parcerias | Instalada uma vez em 07/10, 17:24:39 UTC; tabelas transacionais consultadas vazias | Não foram demonstradas candidaturas/salas/acordos reais. |
|
||||
| Negócios existentes/fundiário | Dois negócios e duas revisões; documentos/direitos/mandatos consultados vazios | Reutilizar cadastro canónico e políticas existentes; não criar tabelas paralelas para o contrato de oportunidades. |
|
||||
| Dashboard/perfis/IA | Rotas e permissões ensaiadas em QA; flag local de IA ligada | Flag não comprova fornecedor externo configurado. Todos os botões e indicadores ainda exigem percurso visual. |
|
||||
|
||||
Preservação: das 209 tabelas presentes na primeira leitura, **207 hashes coincidem** na leitura final; só `public.cache` e `public.sessions` diferem, sem causa atribuída. Cadastros de negócio, seis classificações, relações e histórico comparáveis mantêm hashes. A primeira leitura tinha âmbito menor que a final; não se afirma comparação temporal das outras 79 tabelas. O backup/restauro integral compara as 288 tabelas e cinco ficheiros (quatro originais e configuração privada).
|
||||
|
||||
## Ensaios e correções validadas
|
||||
|
||||
A suite global final passou sequencialmente: **368 de 371 testes, 4.401 asserções**, com três testes reais de ClamD saltados. Passaram também 152 testes frontend, TypeScript, PHPStan e build. Os ensaios dirigidos de origem/portfólio/CRM passaram: 34 testes, 765 asserções. Um GET transversal adicional passou após tornar a guarda contra 5xx mais estrita.
|
||||
|
||||
Foram ensaiadas 88 rotas GET sem parâmetros, quatro vezes: público, investidor, gestor e ator MFA designado **apenas em QA**, totalizando 352 verificações. Respostas 401/403/302 são registadas como controlo de acesso, não como sucesso funcional. Um pedido de comparação sem IDs recebe 422; IA desligada na QA recebe 404. Exportações e rotas com parâmetros ficam fora desse varrimento e dependem das suites/percurso individual. Nenhuma chamada externa foi enviada por esse ensaio.
|
||||
|
||||
As suites exercitam criação/edição, persistência/recuperação, versões/conflitos, acesso entre contas, replay, cálculos, anexos, exclusão/restauro e transições implementadas nos seus domínios. O [inventário de métodos](cobertura-testes.csv) permite localizar esses casos, sem atribuir a cada método uma aceitação visual ou documental que não fornece.
|
||||
|
||||
Código preparado nesta entrega:
|
||||
|
||||
- Origem ISO opcional nos formulários públicos, apoio, negócio e jornada legada; validação e gravação nos controladores/API existentes. Campo `country` legado não foi reinterpretado. Origem omitida continua não informada.
|
||||
- Pesquisa provincial partilhada e conservação da seleção fora da lista; sem alterar IDs ou inventar coordenadas.
|
||||
- Exclusividade por host/porta/base nos testes antes de migrations/limpeza. Rejeição concorrente demonstrada e resultado sequencial repetido.
|
||||
- IDs de auditoria recolhidos no snapshot de backup; restauro/reversão renovados e prova vinculada ao código atual.
|
||||
- UUID interno retirado da apresentação do cartão de jornada; referências e relações permanecem pelo mesmo ID.
|
||||
|
||||
Os checks globais de formatação falharam em sete ficheiros PHP preexistentes e, na verificação final, 17 ficheiros frontend/documentos/scripts preexistentes. A primeira verificação tinha 19, incluindo dois scripts novos entretanto formatados. O resultado global permanece aberto e não foi omitido. Os ficheiros de código alterados foram verificados pelos checks aplicáveis.
|
||||
|
||||
## Pendências que exigem ambiente ou resposta concreta
|
||||
|
||||
Não havia qualquer browser conectado no controlo de navegador. Não foram executados os percursos visuais desta versão, incluindo filtro CRM, seletores, todos os botões e recuperação em nova sessão. As provas de navegador anteriores continuam históricas e não certificam as alterações atuais. ClamD real e GD/WebP do PHP web atual exigem verificação própria; sucesso do PHP CLI/build não a substitui.
|
||||
|
||||
Perguntas humanas estão restritas a dados/designações concretos: pares dos IDs 1–6 com projeto/cluster e papel/citação; entidade operadora/contactos/termos autorizados; contactos/links e responsável por serviço; pesos/limiares/baseline dos pilotos. As designações para atos de revisão/publicação precisam de pessoas reais. Nenhuma destas respostas impede o desenvolvimento de rascunhos, a pesquisa territorial, a auditoria de campos ou outros incrementos independentes.
|
||||
|
||||
O [plano de ativação](plano-ativacao.md) está pronto por leitura, com backup/restauro verificado em **15:16:03 UTC / 17:16:03 locais**, validade de 24 horas e hash atual. A aplicação continua a exigir a conta autorizada no mecanismo existente; não foi simulada uma autenticação ativa nem repetida instalação já feita.
|
||||
@@ -0,0 +1,136 @@
|
||||
# Roteiro executável de interface — I0–I3 QA
|
||||
|
||||
## C37 — causa confirmada; seleção de conta QA corrigida — P0, visual pendente
|
||||
|
||||
O pedido de reabertura referia a conta esperada18. A captura manual21:22–21:24UTC demonstra que foi selecionada a conta13 restaurada. O MFA foi alcançado, mas a autenticação nunca se completou. Causa concreta: credenciais MFA da conta13 cifradas pela chave de origem, incompatíveis com a chave estávelQA; a conta18 sintética não foi desafiada nessa tentativa. Nenhuma chave, MFA ou conta13 foi alterada para contornar o problema.
|
||||
|
||||
| UTC09/10 | Pedido | Resultado observado |
|
||||
|---|---|---|
|
||||
|21:22:10|GET/investimentos|302/login; sessão convidada guardada, destino pretendido /investimentos.|
|
||||
|21:22:11|GET/login|200; mesmo cookie/sessão, sem autenticação.|
|
||||
|21:22:44|POST/login|302/two-factor-challenge; login.id=13, não18.|
|
||||
|21:22:44|GET/two-factor-challenge|200; desafio13 recuperado da mesma sessão; ecrã confirmado pelo utilizador.|
|
||||
|21:23:04|POST/two-factor-challenge|Falha de desencriptação; warning correlacionado conta13;302/login, invalidação intencional e nova sessão convidada.|
|
||||
|21:23:04|GET/login|200; cookie aceite corresponde à sessão regenerada; sem utilizador autenticado.|
|
||||
|
||||
Primeiro desvio do ensaio: POST/login desafia13. Primeira falha técnica: POST/two-factor-challenge às21:23:04 (trace ec68d040a3291cb8, referência26e15b04-07b8-4211-a2a0-7f70509e03f6). Não se tratou de código MFA rejeitado pelo verificador nem de perda após autenticação. Os dois campos cifrados (secret/recovery) são incompatíveis; como nenhum corpo foi retido, não se afirma qual modalidade de entrada foi usada nesta tentativa. Não foram observados conflitos de cookies, mudança de chave/guard ou redirecionamento para outra origem.
|
||||
|
||||
CorreçãoQA, após guarda real desk_restore_20261009_174726_test:55441: login identifica/preenche o email não secreto da conta18; o ecrã MFA identifica a conta realmente desafiada. PortalQaAccountSelection, carregado exclusivamente pelo routerQA, recusa endereços não sintéticos antes do desafio e cancela desafios antigos de contas restauradas, com erro controlado. Os perfis sintéticosQA mantêm o login Fortify normal e respetivo MFA. Contas restauradas e dados ativos preservados. A conta13 continua cifrada como no original; não foi reencryptada nem usa chave ativa como fallback.
|
||||
|
||||
Lacuna de feedback encontrada no código: o Form recém-criado no login começa com erros locais vazios e não lia o errors.email devolvido pela página após redirecionamento do MFA. Login agora apresenta também esse erro da página. A mensagem de falha de desencriptação continua controlada e não autentica; sua apresentação visual ainda exige confirmação.
|
||||
|
||||
Evidência atual2026-10-09T21:37:04.282708+00:00 em c37-auth-redirect-qa.json, pelo servidor18097 e protocolo Inertia/HTML com redirects reais: seletor13 recusado antes do MFA; desafio18 identificado; código inválido mantém desafio sem autenticar; MFA válido regenera/grava18 e redireciona /investimentos; GET e reload mantêm18; logout revoga acesso; novo cookie jar+login+MFA recupera o mesmo dossier413ba1f6-bdf6-402a-a561-c4e2d4098d1a; outra conta403. Negativo sintético19 demonstra falha de desencriptação→login com mensagem, sem autenticação. Nenhuma criação extra de dossier. Estes são resultados de resposta/persistência, não um ensaio visual bem-sucedido.
|
||||
|
||||
Evidências: c37-manual-2122-2124-qa.json conserva os seis pedidos e warning sanitizados; auth-session-trace-qa.jsonl mantém histórico append-only e pseudónimos HMAC; c37-qa-account-auth.xml verifica políticaQA, preservação, MFA válido/inválido e falhas secret/recovery; c37-installation-auth-fingerprint.xml verifica guardas/importação/reversão. TypeScript e build passaram. mfa-persistence-qa.json reconfirma conta13 e .env byte a byte, MFA18 confirmado/oito códigos, chave não gerada/rodada e zero escritas ativas. Cookies, passwords, OTP e corpos não são exportados.
|
||||
|
||||
Estado: causa identificada, preparaçãoQA corrigida e protocolo/persistência demonstrados; C37 permanece aberto para /investimentos visível→reload→logout→novo login da conta18 no navegador. A captura manual demonstrou apenas o MFA da conta13 e retorno ao login; não certifica o percursoA/B nem o feedback atualizado. Próximo teste deve confirmar que o ecrã diz contaQA18 antes de usar o autenticador dessa conta. URL exato http://127.0.0.1:18097/investimentos. Credenciais/segredo permanecem somente no ficheiro privado local investor-mfa-qa-private.json, sem exportação. Workflow/contratos especializados continuam no backlog, sem jornadas educativas novas.
|
||||
|
||||
Ativação não autorizada e revisão candidata não fixada. Fingerprints agora incluem também login.tsx e two-factor-challenge.tsx: percursob402e851b49bfb640f26417f1ff783320210271cd7d84e80dea0db264c89ec28; cartografia95610d2660956a9bb10e6ac9443c24ededf4f3d97f996047c92a5d5c37ff3c6c; recursos4aa6946228b5ebb99bb29e3166e9ce53abdba776b3298a9ccbe437784d8cfa02. Ready/provas de versões anteriores não demonstram esta revisão. Política/seletor/rastreioQA não integram instalação ativa. Após aceitação visualA/B e correções, renovar backup/restauro/compatibilidade e manter a ordem já documentada de recursos→percurso→flag→importação cartográfica→publicação separada, sem repetir o que estiver instalado. ReversãoQA: retirar registo/configuração de PortalQaAccountSelection e overrides Fortify do router; retirar os registos de rastreio; preservar provas. A correção do feedback é código compatível sem migration, alteração de chave ou modificação de dados.
|
||||
|
||||
## Retoma obrigatória após C37 — sessão e investidor MFA
|
||||
|
||||
Endereço exato: http://127.0.0.1:18097/investimentos; login /login. Fechar a sessão anterior e abrir janela privada nova; as duas sessõesQA da conta13 foram invalidadas. Confirmar X-Investmoz-QA-Target=desk_restore_20261009_174726_test:55441 antes de escrever. Não usar a conta13 restaurada como fixtureQA.
|
||||
|
||||
Usar o investidor sintético MFA preparado (actor18). As credenciais e segredo para configurar o autenticador ficam somente no ficheiro local privado storage/app/private/investmoz-v2/portal-audit/investor-mfa-qa-private.json; não colar conteúdo/código/cookies nesta conversa. MFA foi ativado/confirmado normalmente pelo Fortify e é obrigatório no login. Gestão e outra contaQA conservadas para os restantes passos/permissões.
|
||||
|
||||
1. Entrar com a contaQA, confirmar desafioMFA antes do acesso ao investimento, usar o autenticador e abrir /investimentos. Esperado: entrada depois do código; nenhum500.
|
||||
2. Criar um A visual novo, guardar; logout, fechar janela e nova sessão com password+MFA. Esperado: mesmoID/título recuperado.
|
||||
3. Continuar a sequência A/B deste roteiro: aplicabilidade→ferramenta→resultado→Balcão→acompanhamento; registar cada prova. O dossier A HTTP atual é apenas inspeção complementar, não prova de criação na interface.
|
||||
4. Para falha de desencriptação, esperado422JSON/mensagem controlada ou retorno ao login; nunca autenticação. Esse negativo foi ensaiado com fixture sintética separada, sem alterar conta13. Não adulterar manualmente a conta do investidor para o reproduzir.
|
||||
|
||||
Capturas/requisições exportadas devem omitir Cookie, X-XSRF-TOKEN, passwords e corpo com code/recovery_code. As provas exportadas pela ferramenta registam somente método/URL/status/alvo, não cabeçalhos/corpos. Retoma visual permanece pendente até resultados observados pelo utilizador.
|
||||
|
||||
## Ambiente e contas
|
||||
|
||||
Base exclusiva: **http://127.0.0.1:18097**. Login: http://127.0.0.1:18097/login. Antes de escrever, conferir no separador Rede a resposta `X-Investmoz-QA-Target: desk_restore_20261009_174726_test:55441`. Não usar portas 8000/80 nem outro destino. O servidor usa router `tools/opportunity-resources-qa.php`, sessões privadas próprias e configuração do percurso habilitada somente nesta QA.
|
||||
|
||||
Usar as contas sintéticas já preparadas na máquina, exclusivamente nesta QA. O roteiro não exporta credenciais:
|
||||
|
||||
| Perfil | Utilização |
|
||||
| --- | --- |
|
||||
| Investidor QA | Criar e recuperar A/B |
|
||||
| Gestão QA | Acompanhamento e operações documentais |
|
||||
| Gestão cartográfica QA com MFA | Aplicação/reversão cartográfica com TOTP |
|
||||
| Outra conta QA | Verificar ausência de acesso a A/B |
|
||||
|
||||
Não executar novamente `opportunity-resources-qa.php prepare`: a instalação já foi feita nesta cópia. A preparação idempotente das contas é `php tools/portal-investor-path-qa.php fixtures`, com guarda de destino antes de qualquer escrita. O PHP QA foi recuperado num processo separado com GD/WebP e OPcache desligado apenas nesse processo; a porta18096 anterior apresentou erro de arranque antes do cabeçalho QA e não deve ser usada. Se o servidor deixar de responder, iniciar no diretório do projeto, por terminal técnico: `php -d extension=gd -d opcache.enable=0 -S 127.0.0.1:18097 -t public tools/opportunity-resources-qa.php`. Não executar este comando sobre outra configuração ou trocar o router pelo servidor ativo.
|
||||
|
||||
Diagnóstico: `getState()` antes/depois de reset devolveu apps/browsers vazios; IAB/Chrome/Edge devolveram `Browser is not available`. `/login` respondeu HTTP200 com identidade QA. O bloqueio é ausência de fornecedor disponível na sessão de controlo; a causa de registo/conexão desse fornecedor não foi determinada. Não é evidência de falha do portal nem de renderização correta. Quando um navegador for exposto, retomar este roteiro pelo início.
|
||||
|
||||
## A/B, desde criação até acompanhamento
|
||||
|
||||
Usar títulos novos, por exemplo `A visual QA 09-10` e `B visual QA 09-10`. Não aceitar como prova de criação abrir apenas os dossiers já preparados. Para inspeção complementar, a execução HTTP deixou:
|
||||
|
||||
- A: http://127.0.0.1:18097/investimentos/5935737d-9e91-44d6-87fa-05444a37c117
|
||||
- B: http://127.0.0.1:18097/investimentos/3026f22a-d3d9-42ed-9660-529f29dc5b90
|
||||
|
||||
Estes dossiers de inspeção mantêm uma evidência inicial com orçamento incompatível e uma revisão posterior válida (C29); o alerta da primeira deve permanecer explícito. Para a aceitação de criação/interface, usar os projetos novos indicados acima. Na ferramenta, preencher também pelo menos uma linha sintética de receita100 e despesa50, além dos valores do passo4, para respeitar o contrato orçamental.
|
||||
|
||||
| Passo | Ação na interface | Resultado esperado e prova a guardar |
|
||||
| --- | --- | --- |
|
||||
| 1 | Entrar como investidor; abrir `/investimentos`. Escrever título A, marcar autorização de reutilização e clicar **Criar e guardar dossier**. Repetir para B voltando à lista. | Dois IDs diferentes, títulos recuperados, cinco fases e S01–S19 em cada ficha. POST seguido de GET; registar IDs e versões. Nenhum roteiro antigo renumerado. |
|
||||
| 1a | Antes de decidir aplicabilidade, terminar sessão, fechar as janelas privadas e abrir uma nova sessão autenticada QA. Recuperar A/B pela lista e URLs anotadas. | Ambos existem com os mesmos IDs/títulos/versões e sem mistura de dados; só então continuar as decisões do passo2. |
|
||||
| 2 | Em A, **Precisa de terra? Não**; financiamento externo **Não**; intenção de prosseguir; fundamento sintético. **Guardar decisões**. Em B, terra **Sim**, financiamento **Sim**, fundamento distinto; guardar. | A: S10 e S13–S15 dispensados apenas da preparação; S12 não dispensado. B: ramos aplicáveis. Texto não declara licença, dispensa legal ou financiamento aprovado. Nova versão recuperada após recarregar. |
|
||||
| 3 | Em B, abrir S10 → **Registar avanço ou pendência**; selecionar espera externa, ação Preparar e fundamento `Aguarda informação do terreno`. Guardar. Abrir S02, preparar análise de mercado e guardar. | S10 permanece em espera; S02 avança sem bloquear. Em S18, tentar ação Operar sem S17: mensagem de dependência real; a opção Preparar continua possível. Não inventar decisão externa para desbloquear. |
|
||||
| 4 | A → **Plano e simulador**; verificar `context=ID_A` na URL. Preencher título/resumo A; na ferramenta financeira, custos fixos1000, preço100, custo variável50, necessidade total100000, capital assegurado100000, moeda MZN. Aguardar confirmação de gravação; clicar **Guardar resultado financeiro e voltar ao dossier**. Repetir B com título/resumo B e capital assegurado30000. | URLs/drafts distintos. A mostra20 unidades e necessidade0; B20 unidades e necessidade70000. Resultados com IDs/draft/versão próprios. Texto identifica estimativa, não aprovação. Recarregar ficha conserva resultado. Gravação pendente/erro não deve produzir sucesso aparente. |
|
||||
| 5 | Alternar A → B → A e voltar à ferramenta pelo link de cada dossier. Abrir também `/simulador-fiscal` diretamente. | A nunca recebe título, rascunho, resultado ou estado B. A ferramenta direta conserva acesso independente e não escolhe silenciosamente outro projeto. Guardar capturas e requisições `current?context=...`. |
|
||||
| 6 | Terminar sessão pelo menu; fechar todas as janelas privadas. Abrir nova janela privada, entrar novamente e abrir `/investimentos`, depois A e B pelas URLs registadas. | Recuperação do servidor: títulos, aplicabilidade, drafts, resultados e estados iguais. Este passo exige nova sessão do navegador, não apenas atualizar página. Registar a nova entrada e os GETs sem guardar cookies/passwords nas evidências. |
|
||||
| 7 | Em cada ficha → **Apoio no Balcão**; escolher serviço de preparação; **Preparar pedido com dados do dossier**. Abrir o rascunho ligado. Preencher campos ainda necessários, guardar e recarregar. | Um pedido por ação/chave; associação ao dossier correto. Título e descrição reutilizados da ideia correspondente; estado rascunho, sem submissão automática. País e origem são escolhidos conscientemente, não inferidos do contexto. |
|
||||
| 8 | Em cada ficha → **Acompanhamento interno**: S02, título diferente por cenário, prazo futuro, marcar aceitação e **Guardar tarefa**. | Tarefa visível na própria ficha após GET, com responsável/prazo/versão; nenhuma transmissão externa. |
|
||||
| 9 | Terminar sessão; entrar como gestor; abrir URLs A/B. Introduzir fundamento, **Assumir acompanhamento**, **Iniciar tarefa**, **Registar conclusão**. | Tarefa atribuída ao gestor e concluída, com versão/eventos. Gestor vê contexto necessário à gestão, mas não entradas/resultados financeiros privados do investidor. Conferência interna aparece com esse âmbito; ato externo sem documento/entidade/data/referência é rejeitado. |
|
||||
| 10 | Entrar novamente como investidor. Abrir A/B e Balcão. | Conclusão recuperada; em B, S10 ainda aguarda informação. Próxima ação e pendências visíveis. Resultado financeiro e pedido de cada projeto continuam próprios. |
|
||||
| 11 | Entrar como outra conta; tentar URLs A/B e URLs dos drafts copiadas da Rede. Abrir `/investimentos`. Em sessão terminada, tentar A. | Outra conta: dossiers403, drafts404 e lista sem A/B; sessão terminada exige login/401 na API. Nenhum conteúdo privado no erro. Na conta dona, pedido para recuperar draft A com `context=ID_B` deve403, sem alteração persistente. Esta última negativa é prova de API; registar separadamente da apresentação visual. |
|
||||
|
||||
## País/origem por formulário, filtros e estatísticas
|
||||
|
||||
Em cada linha aplicável escolher país **PT** e origem declarada **ZA**, guardar/submeter segundo o contrato, recarregar e recuperar noutra sessão. Nas estatísticas, ZA é origem; PT não é inferido como origem. Registar valor ISO enviado, valor persistido e valor apresentado. Não agregar dossier/rascunho como solicitação submetida.
|
||||
|
||||
| Formulário/URL | Campo/significado e prova esperada |
|
||||
| --- | --- |
|
||||
| `/manifestar-interesse` e manifestação da página `/` | País e origem distintos; recibo único; detalhe de gestão recupera ambos. |
|
||||
| `/apoio`, `/formularios/investidor`, `/formularios/empresa`, `/parcerias` (formulário de apoio) | Executar separadamente support/investor/company/partnership. Cada pedido aparece uma vez em interests; filtro `country=PT&origin=ZA` e agregado ZA aumentam1. |
|
||||
| `/investidor/profile` | Residência PT; empresa com país de constituição MZ. Não inferir origem de solicitação a partir destes campos. |
|
||||
| `/investidor/manifestacoes` → criar/abrir ficha | Recuperar residência/constituição; declarar origem ZA. Rascunho fora das estatísticas; submissão gera interesse com origem explícita; ausência permanece Não informado. |
|
||||
| `/carteira/{ID público}` → guardar → `/investidor` | Manifestação da jornada: país/origem recuperados, repetição não duplica interesse. Usar ID disponibilizado pela própria lista QA, não ID inventado. |
|
||||
| `/negocios/{slug}/manifestar-interesse` | Dois campos de país/origem; recuperar no detalhe de gestão. Prova visual do formulário/filtro/estatística ainda pendente; API/persistência/estatística deste consumidor ensaiadas em continuation-business-journey-qa.xml. Usar slug da lista QA; falta de publicação é lacuna de cadastro, não sucesso. |
|
||||
| `/investidor/negocios` → novo/editar | Wizard privado: gravar/reabrir PT/ZA, filtrar lista por ambos; rascunho não conta, após submissão apenas businesses ZA+1. ZZ rejeitado sem alterar versão; outro ator não recupera. |
|
||||
| `/investidor/terra-duat/novo` | País PT/origem ZA e parcela territorial; guardar/reabrir; Solicitar apoio gera um interesse. Gestor: filtro PT/ZA e estatística interests ZA+1, repetição sem duplicação. |
|
||||
| `/balcao-virtual/painel` → dossier → pedido | Executar os três serviços: preparação, alteração e acompanhamento. Guardar PT/ZA, submeter, gestor devolver autorizando apenas país/origem, corrigir MZ/PT e recuperar. Estatística desk deve mover ZA→PT; não contar draft/cancelado. |
|
||||
| `/simulador-fiscal?context={ID}` | Residência fiscal PT e países de origem de fundos PT/ZA; guardar/reabrir. Estes não são origem de solicitação e não criam estatística nem cálculo fiscal por gravação. |
|
||||
| `/management/interests?country=PT&origin=ZA`, `/management/crm/leads?origin=ZA`, depois `origin=PT`, `origin=unknown` | Tabela/filtros/URL/contagens coerentes, coleções interests/desk/businesses separadas; utilizador comum403. Comparar antes/depois de cada formulário, não só total geral. |
|
||||
|
||||
## Seletores e mapas por consumidor
|
||||
|
||||
Em **cada seletor**, executar: carregar província → pesquisar → escolher distrito do pai → posto → localidade quando cadastrada; mudar província e confirmar limpeza dos filhos; guardar campo quando editável; recarregar e recuperar nomes/IDs; pesquisar sem correspondência e confirmar resultado vazio explicado; verificar paginação quando aplicável. Registar erro/contexto inacessível sem substituição silenciosa. As provas partilhadas de API não encerram cada consumidor.
|
||||
|
||||
Consumidores a percorrer individualmente: catálogo `/oportunidades`; negócio público `/negocios`; zonas `/zonas` e `/zonas/{ID}`; carteira `/carteira` e `/carteira/{ID}`; perfil/manifestações; wizard privado de negócios; fundiário e todas as parcelas; cada campo territorial dos três serviços do Balcão; simulador/contexto; Bolsa `/parcerias` e criação/edição; gestão de oportunidade `/management/opportunities/{ID}/edit` e recursos; estruturas `/management/projects/create`, `/management/clusters/create`, `/management/corridors/create`; gestão territorial; educação já existente `/management/education` e análise. Não iniciar jornadas educativas novas. Usar IDs/URLs que as listas QA efetivamente apresentam.
|
||||
|
||||
Exemplos de limites oficiais presentes nesta QA:
|
||||
|
||||
| Nível | Nome | ID |
|
||||
| --- | --- | --- |
|
||||
| Província | Cabo Delgado | 059b02ca-7095-577a-8705-4d4c46896747 |
|
||||
| Distrito | ALTO MOLOCUE | 909f9937-07c1-51a2-9d7a-e2f03d586d6d |
|
||||
| Posto | 7 DE ABRIL | 661be5db-dea8-5243-a281-b87e07c97a68 |
|
||||
|
||||
Os exemplos não formam uma única cadeia: escolher os respetivos pais pelo cadastro. No endpoint `/management/territory-geometries?territory_id={ID}`, o gestor recupera limite próprio e contexto; no público `/api/v1/investment/territory-geometries?territory_id={ID}` os limites privados não aparecem. Esperado visual: território cadastrado, disponibilidade própria e contexto ancestral separados. Não publicar geometrias reais para tornar o teste verde. Uma localidade sem polígono próprio pode apresentar contexto ancestral autorizado; não declarar polígono próprio.
|
||||
|
||||
Mapas a observar separadamente: catálogo e detalhe de oportunidade; carteira/detalhe; zonas/detalhe; Bolsa; preview dos campos públicos; preview da gestão nos drafts/recursos/estruturas. C27 preparou contexto do território principal na ficha de oportunidade e do filtro aplicado na Bolsa. Confirmar Rede + legenda + desenho + recuperação do filtro. Marcadores/perímetros dos investimentos mantêm as suas fontes; limites administrativos2019 não os substituem. Continuam sem correspondência2 províncias/39 distritos/179 postos e sem polígonos próprios de localidades identificados.
|
||||
|
||||
## Importação cartográfica e operações documentais
|
||||
|
||||
Gestão: http://127.0.0.1:18097/management/territory-geometry-import?level=1. Abrir com gestor QA; repetir níveis2/3. Esperado:11/9/2,159/120/39,411/232/179, nomes/pais/IDs, hash do original e scan separado. A aplicação exige MFA confirmado, fundamento20caracteres e confirmação; o gestor QA comum sem MFA deve403. O ensaio autenticado usou conta sintética própria com login+TOTP, cujas credenciais não são exportadas neste roteiro. Não usar conta ativa nem desativar MFA para executar.
|
||||
|
||||
Na QA já povoada, Aplicar deve informar0criadas/9reutilizadas (nível1),0/120 (nível2),0/232 (nível3), e respetivas pendências; nada publicado. Registar lote, recarregar e verificar geometrias/histórico. Reverter o lote de reutilização deve informar0revertidas e preservar9/120/232. Não tentar excluir geometrias preexistentes para fabricar ensaio de inserção: a criação/reversão foi verificada na QA isolada de testes. Importação não tem botão de publicação.
|
||||
|
||||
Recursos de oportunidades: usar `/management/opportunities` para criar oportunidade QA, abrir Recursos; carregar PDF/PNG sintéticos, conferir estado de scan e descarregar bytes. Substituir PDF com versão seguinte, recuperar original no histórico, excluir logicamente/restaurar. Imagem1600×1600 deve gerar3WebP320/640/1280; cada uma só tem preview após o próprio scan. Abrir previews, recarregar página e verificar recuperação; outra conta403, assinatura removida403, versões antigas409. Não testar adulteração física de ficheiros pelo navegador; esse caso foi ensaiado de forma isolada por API/persistência.
|
||||
|
||||
Provas backend reais disponíveis: resources-real-http-qa.json/document-real-persistence-qa.json registam cinco ficheiros cifrados/restricted com scans ClamAV1.5.4 próprios e downloads web; import-document-real-qa.xml distingue scanner real das fixtures. document-consumers-real-qa.xml acrescenta biblioteca/Balcão: scans reais, classificação/publicação separadas, recuperação, dedup/permissões/integridade e reutilização de original cifrado sem novo documents (C35/C36). A resposta inline PDF tem prova de bytes/MIME/CSP, não de renderização visual.
|
||||
|
||||
Na biblioteca QA: carregar ficheiro sintético, cadastrar metadados deixando data/emissor desconhecidos, recuperar cadastro sem erro500; conferir acesso privado antes de classificação/publicação, depois publicar explicitamente apenas o documento sintético autorizado e verificar download/visualização. No Balcão QA: carregar anexo sintético confidencial e, separadamente, reutilizar um original cifrado próprio existente; recuperar noutra sessão, confirmar que não houve duplicação e que outra conta não acede. Não classificar fonte sintética como oficial. Registar separadamente operações ainda não ensaiadas por tipo/perfil/lote; não estender estas provas a todos os documentos.
|
||||
|
||||
## Registo e critério de fecho
|
||||
|
||||
Para cada passo/consumidor preencher: ID da matriz; cenário/perfil; URL; versão de código/assets; data; ação; esperado; observado; HTTP/API; IDs/versões/resultado recuperado; captura visual; pass/fail/pendente; causa e reprodução. Não guardar cookies, passwords, dados ativos ou dumps nas capturas exportadas. Evidência HTML/Inertia não é captura visual.
|
||||
|
||||
Só depois de A/B completos na interface e destas provas por consumidor é possível fechar os critérios correspondentes. Atualizar a mesma matriz preservando fontes/versões. `integrated_ui_ab_passed` permanece false até essa demonstração. Renovação do backup/restauro final aguarda esse ponto; ativação continua fora da autorização.
|
||||
@@ -1,5 +1,9 @@
|
||||
# InvesteMoz V2 — backlog reconciliado da primeira entrega
|
||||
|
||||
Continuação de 09/10/2026: [relatório](auditoria-portal/relatorio-executivo.md), [mesma matriz](auditoria-portal/matriz-requisitos.csv) e [backlog priorizado atual](auditoria-portal/backlog.md). 3.354 requisitos / 5.830 linhas de origem preservadas, não percentagem de aceitação. Novo lote QA de países/origem/estatísticas/simulador/Balcão; maturidade de oito etapas e draft educativo continuam lacunas reproduzidas. Prova técnica dos recursos renovada em 16:18:09 UTC; instalação autenticada continua pendente. ClamD específico de atos binários afetados, sem bloquear catálogos/drafts. Histórico anterior não substitui evidência atual.
|
||||
|
||||
Atualização transversal de 09/10/2026: [diagnóstico executivo](auditoria-portal/relatorio-executivo.md), [matriz única com fontes/versões](auditoria-portal/matriz-requisitos.csv), [pendências P0/P1/P2](auditoria-portal/backlog.md) e [ativação autenticada sem reinstalações](auditoria-portal/plano-ativacao.md). As evidências anteriores permanecem históricas; o estado corrente distingue código preparado, QA demonstrada e base ativa. O exemplar mestre atual `d0c06a75…` e as variantes não eliminam o exemplar histórico abaixo. Fontes oficiais identificadas continuam aceites segundo AGENTS.md.
|
||||
|
||||
Data: 8 de outubro de 2026. Este backlog complementa [a auditoria existente](../requirements-audit.md) e [a matriz consolidada](../consolidated-review-matrix-2026-10-03.md); não substitui trabalho em curso.
|
||||
|
||||
## Fonte e interpretação
|
||||
@@ -153,14 +157,14 @@ Propostas e [relatório territorial](qualidade-territorial.md) corrigidos para d
|
||||
|
||||
[Plano autenticado, restauro e reversão](ativacao-rastreabilidade-territorial.md). A aceitação das fontes oficiais identificadas foi reutilizada, sem nova verificação de proveniência.
|
||||
|
||||
| Requisito | Preparado / validado em QA | Aplicado na base ativa |
|
||||
| --- | --- | --- |
|
||||
| V2-08 — rastreabilidade | 46 registos reconciliados; 112 entradas por associação; 11 referências oficiais/legais, 14 fichas validadas e pacote INE preservados | Nenhuma nova gravação; faltas de ligação documental não revogam aceitação |
|
||||
| V2-08 — relações | 13 citações cluster–projeto recuperadas; proposta de preencher referências existentes; 28 vínculos territoriais de projetos reutilizados | Proposta não aplicada; sem novas relações inferidas |
|
||||
| V2-08/V2-09 — fichas, filtros e mapa | Papéis e geometria preservados; fundamento por associação nas fichas autorizadas; navegação e filtros da entrega anterior reutilizados | Código local; sem novos pontos, limites ou capacidade atribuída |
|
||||
| V2-13 — aplicação | Página `/management/relationship-repair`, botão específico V2, conflitos visíveis, idempotência e reversão auditada | Ação autenticada ainda por executar |
|
||||
| V2-13 — backup/restauro | 288 tabelas comparadas e cinco ficheiros restaurados; aplicação/reversão ensaiadas em `desk_restore_20261008_235546_test:55441` | Leitura/backup apenas; prova vinculada ao plano/código, validade 24 horas |
|
||||
| QA | 56 testes PHP/884 asserções, quatro testes de reconciliação, TypeScript, lint, PHPStan, build e percurso autenticado no navegador | Zero eventos deste incremento na leitura ativa final; dados territoriais inalterados |
|
||||
| Requisito | Preparado / validado em QA | Aplicado na base ativa |
|
||||
| ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
|
||||
| V2-08 — rastreabilidade | 46 registos reconciliados; 112 entradas por associação; 11 referências oficiais/legais, 14 fichas validadas e pacote INE preservados | Nenhuma nova gravação; faltas de ligação documental não revogam aceitação |
|
||||
| V2-08 — relações | 13 citações cluster–projeto recuperadas; proposta de preencher referências existentes; 28 vínculos territoriais de projetos reutilizados | Proposta não aplicada; sem novas relações inferidas |
|
||||
| V2-08/V2-09 — fichas, filtros e mapa | Papéis e geometria preservados; fundamento por associação nas fichas autorizadas; navegação e filtros da entrega anterior reutilizados | Código local; sem novos pontos, limites ou capacidade atribuída |
|
||||
| V2-13 — aplicação | Página `/management/relationship-repair`, botão específico V2, conflitos visíveis, idempotência e reversão auditada | Ação autenticada ainda por executar |
|
||||
| V2-13 — backup/restauro | 288 tabelas comparadas e cinco ficheiros restaurados; aplicação/reversão ensaiadas em `desk_restore_20261008_235546_test:55441` | Leitura/backup apenas; prova vinculada ao plano/código, validade 24 horas |
|
||||
| QA | 56 testes PHP/884 asserções, quatro testes de reconciliação, TypeScript, lint, PHPStan, build e percurso autenticado no navegador | Zero eventos deste incremento na leitura ativa final; dados territoriais inalterados |
|
||||
|
||||
Restam pontes de rastreabilidade e seis correspondências oportunidade–âncora/cluster sem fundamento explícito recuperado; não se retirou a aceitação existente. Questões jurídicas específicas, diferença de cobertura do inventário, ClamD real e primeiro pedido real permanecem separadas.
|
||||
|
||||
@@ -242,3 +246,19 @@ Leitura em 09/10/2026 06:34:48 UTC: migration aplicada uma vez; evento `opportun
|
||||
**Estado ativo:** só leitura/backup pelo Codex. Seis IDs reais, relações e 124 eventos anteriores preservados; recursos ainda não instalados. Instalação autenticada continua necessária; cobertura transversal não é dada como concluída. Questões jurídicas específicas, diferença de cobertura documental, fontes institucionais, ClamD real e primeiro pedido real mantêm estados separados.
|
||||
|
||||
Continuação de 9 de outubro: filtro de país/«Não informado» nas estatísticas do CRM preparado, com conjuntos separados e sem inferir origem de campos históricos. GET autorizado e validado; a lista de leads mantém os seus filtros próprios. 25 testes/430 asserções em QA isolada, TypeScript, PHPStan e build passaram. Percurso deste filtro no navegador ainda pendente; sem migration nem escrita ativa. [Escopo e evidência](revisao-funcional-transversal.md#continuação--filtro-das-estatísticas-de-origem).
|
||||
|
||||
## Estado de auditoria — lote 2, 09/10/2026
|
||||
|
||||
Prevalece o [relatório atualizado](auditoria-portal/relatorio-executivo.md) sobre estados históricos: maturidade 7/8 já grava/recupera em QA com catálogo versionado, negócios/fundiário têm países/origem separados e provas por percurso, 361 geometrias oficiais internas estão em QA, ClamD real está disponível. Workflow/publicação, cobertura transversal/visual/mapas e recursos ativos continuam pendentes. 379 testes/4922 asserções/zero skips; recursos ready=true, installed=false. A [mesma matriz](auditoria-portal/matriz-requisitos.csv) conserva 3354 requisitos/5830 origens; próximo lote no [backlog](auditoria-portal/backlog.md) prioriza falhas de percursos existentes antes de novas jornadas educativas.
|
||||
|
||||
## Estado de auditoria — lote 3, 09/10/2026
|
||||
|
||||
Balcão:país/origem e devolução para correção demonstrados nos3 serviços; contexto administrativo ligado aos consumidores existentes e361 limites QA recuperados sem publicação.381 testes/5046 asserções/zero skips. QA HTTP recuperada; provider de UI indisponível e visual pendente. Recursos prontos,não instalados; cartografia ativa requer ato autenticado separado. Workflow/contratos mantidos no backlog; nenhuma jornada educativa nova. Prevalecem [relatório](auditoria-portal/relatorio-executivo.md),[backlog](auditoria-portal/backlog.md) e [plano](auditoria-portal/plano-ativacao.md) atuais sobre estados anteriores. PDFs diretos não anexados nesta sessão.
|
||||
|
||||
## Histórico — proposta de consolidação antes da aprovação QA
|
||||
|
||||
Foi lido integralmente o documento de assistente por etapas. A [proposta](auditoria-portal/proposta-consolidacao-percurso.md) organiza cinco fases/19 etapas e cenários A/B, com dados mestres, estados/permissões, reutilização, compatibilidade e reversão. Navegação/modelo/motor aguardam aprovação; nenhuma alteração estrutural ou escrita ativa. Correções anteriores de países/cartografia permanecem em I0. C24 corrige somente o link para o draft associado, demonstrado em API/QA e ainda sem clique visual. A proposta complementa a mesma matriz, não a substitui.
|
||||
|
||||
## Execução I1–I3 autorizada em QA
|
||||
|
||||
Código/API/persistência preparados para cinco fases/19 etapas e investimentos independentes por dossier. 384 ensaios globais/5.215 asserções; A/B API3/163, interface pendente. I0 continua; nenhum dado ativo alterado. Relatório executivo, matriz, backlog e plano em [execucao-percurso-i1-i3.md](auditoria-portal/execucao-percurso-i1-i3.md). Workflow e contratos especializados continuam pendentes; nenhuma nova jornada educativa.
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# Gestão de Oportunidades integrada no Dashboard
|
||||
|
||||
Continuação da auditoria — 09/10/2026, após 18:22 locais: [relatório atual](auditoria-portal/relatorio-executivo.md), [mesma matriz consolidada](auditoria-portal/matriz-requisitos.csv) e [backlog atual](auditoria-portal/backlog.md). 3.354 requisitos canónicos / 5.830 linhas de origem; critérios/versões/aliases e percurso interface–API–gravação–recuperação–resultado conservados. QA: 373/376 testes, 4.608 asserções, três ClamD reais saltados. Países públicos/simulador, origem/estatísticas e hierarquia do Balcão demonstrados no servidor; UI e cobertura transversal pendentes. Maturidade 7/8 e draft incompleto educativo reproduzidos como 422 na QA, não concluídos. Recursos não instalados; prova renovada às 16:18:09 UTC, fingerprint `c328f542…`, preview `ready=true`. As provas anteriores abaixo são históricas. Nenhuma escrita ativa por esta auditoria.
|
||||
|
||||
Atualização de auditoria — 09/10/2026, 17:23:42 locais: [relatório transversal](auditoria-portal/relatorio-executivo.md), [matriz única](auditoria-portal/matriz-requisitos.csv), [backlog](auditoria-portal/backlog.md) e [plano consolidado](auditoria-portal/plano-ativacao.md). O plano de recursos foi renovado para o hash `e90ab685dac9441b7fc5f9da231770cb607a91b7e991876ded652827d76efa50` e está pronto por leitura, **não instalado**. Backup/restauro verificado em 15:16:03 UTC, validade de 24 h. QA global: 368 passaram/4.401 asserções e três ClamD saltados. UI desta versão pendente por ausência de browser conectado. Os registos de hashes/validade abaixo mantêm-se como histórico, não como prova corrente.
|
||||
|
||||
Entrega de 9 de outubro de 2026. **Primeiro incremento instalado pelo utilizador e confirmado por leitura. O incremento de recursos está preparado em QA, ainda não aplicado. A especificação integral não está concluída.**
|
||||
|
||||
## Fonte e reconciliação
|
||||
@@ -14,24 +18,24 @@ O cadastro anterior usava `Opportunity`, setores, territórios e relações exis
|
||||
|
||||
## Matriz de cobertura da primeira entrega
|
||||
|
||||
| Fonte / requisito | Estado | Implementação e lacuna |
|
||||
| --- | --- | --- |
|
||||
| §8/8.1 — rascunho vs exigências finais | Implementado para guardar; parcial global | Rascunho incompleto persistido; não declara validação final, submissão, aprovação ou publicação. Contrato JSON final não impede guardar. |
|
||||
| §9 — gestão integrada | Implementado no escopo autorizado | Lista, pesquisa, filtros por estado/categoria/setor/âmbito, paginação e contagens; Nova, Ver, Editar, Excluir/Arquivar, Restaurar. Indicadores avançados e papéis adicionais pendentes. |
|
||||
| §10 — núcleo/catálogos | Parcial | Campos legados preservados, categoria opcional e seleção territorial. Valor histórico `privado` conservado. Catálogos completos, dropdowns pesquisáveis e maturidade de oito etapas pendentes; não remapear automaticamente as seis etapas antigas. |
|
||||
| §11 — multilocalização | Parcial existente | Território principal e hierarquia reutilizados; contexto consultável. Formulário de até 50 localizações, papéis, distribuição e geometrias/evidência por localização pendente. Não inventa coordenadas. |
|
||||
| §12 — mercado/financiamento/calendário | Parcial | Montante decimal validado, campos existentes conservados. Estruturas completas e coerência cruzada por categoria pendentes; não calcula resultados financeiros/fiscais. |
|
||||
| §13 — documentos/visibilidade | Parcial existente | Infraestrutura preservada, sem publicação automática. Integração completa de documentos, idiomas e pré-visualização exata de visibilidade pendente. |
|
||||
| §15 — guardar/recuperar/editar | Implementado no incremento | Confirmação visível com foco, erros por campo, preservação e bloqueio durante operação, recuperação numa nova sessão pelo servidor. Wizard, autosave, validação final e comparação de duplicados documentais pendentes. |
|
||||
| §15.2 — ciclo de exclusão | Implementado para oportunidade | Motivo 20–1000 caracteres e confirmação; draft eliminado logicamente, versão fechada arquivada, restauração autorizada como draft sem republicar. Trigger proíbe eliminação física após fecho/submissão. Ciclo individual de coleções/anexos pendente. |
|
||||
| §15.3 — concorrência/idempotência | Implementado nos endpoints novos | Versão crescente, ETag do estado completo, bloqueio transacional e conflito HTTP 409; UUID de criação evita duplicação por replay. Token no payload e cabeçalho ETag na resposta. Contrato integral de todos os endpoints documentais pendente. |
|
||||
| §16 — imagens | Pendente | Pipeline completo, direitos, MIME, EXIF, capa e versões. ClamD real separado; scanner simulado não valida ficheiros reais. |
|
||||
| §17/19 — persistência/versões | Parcial | Mesmos IDs; alterações de versão fechada em `management_draft`, sem alterar ficha pública. Snapshots anterior/novo cifrados na auditoria existente. Fluxo completo de revisão pendente. |
|
||||
| §20 — permissões/workflow | Parcial | Gate existente no servidor, sem conceder novos papéis. Editor genérico deixa de publicar após instalação. Segregação de papéis e workflow integral pendentes. Revisão interna não é aprovação institucional. |
|
||||
| §21 — DT01–DT15 | Parcial | QA cobre rascunho, concorrência, permissões, replay, exclusão/arquivo/restauro e preservação. Critérios de imagens, validação final, publicação e coleções completas continuam abertos. |
|
||||
| §22 — REQ01–REQ17 | Parcial global | Cobertura por grupos acima; requisitos dos módulos finais continuam pendentes. Não declarar Go/No-Go integral por CRUD. |
|
||||
| §24–28 — categorias especializadas | Pendente além da seleção | Investimento, imobiliário, direitos fundiários, venda de negócio, parceria, franquia, concessão, financiamento, fornecimento e outros selecionáveis. Perfis, coleções e validações específicas exigem incrementos com reutilização dos módulos existentes. |
|
||||
| Relações e fontes oficiais | Preservado | Consulta do contexto existente; nenhum par inferido por nome, setor ou proximidade. Editor de evidência por ligação permanece na frente territorial. |
|
||||
| Fonte / requisito | Estado | Implementação e lacuna |
|
||||
| -------------------------------------- | ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| §8/8.1 — rascunho vs exigências finais | Implementado para guardar; parcial global | Rascunho incompleto persistido; não declara validação final, submissão, aprovação ou publicação. Contrato JSON final não impede guardar. |
|
||||
| §9 — gestão integrada | Implementado no escopo autorizado | Lista, pesquisa, filtros por estado/categoria/setor/âmbito, paginação e contagens; Nova, Ver, Editar, Excluir/Arquivar, Restaurar. Indicadores avançados e papéis adicionais pendentes. |
|
||||
| §10 — núcleo/catálogos | Parcial | Campos legados preservados, categoria opcional e seleção territorial. Valor histórico `privado` conservado. Catálogos completos, dropdowns pesquisáveis e maturidade de oito etapas pendentes; não remapear automaticamente as seis etapas antigas. |
|
||||
| §11 — multilocalização | Parcial existente | Território principal e hierarquia reutilizados; contexto consultável. Formulário de até 50 localizações, papéis, distribuição e geometrias/evidência por localização pendente. Não inventa coordenadas. |
|
||||
| §12 — mercado/financiamento/calendário | Parcial | Montante decimal validado, campos existentes conservados. Estruturas completas e coerência cruzada por categoria pendentes; não calcula resultados financeiros/fiscais. |
|
||||
| §13 — documentos/visibilidade | Parcial existente | Infraestrutura preservada, sem publicação automática. Integração completa de documentos, idiomas e pré-visualização exata de visibilidade pendente. |
|
||||
| §15 — guardar/recuperar/editar | Implementado no incremento | Confirmação visível com foco, erros por campo, preservação e bloqueio durante operação, recuperação numa nova sessão pelo servidor. Wizard, autosave, validação final e comparação de duplicados documentais pendentes. |
|
||||
| §15.2 — ciclo de exclusão | Implementado para oportunidade | Motivo 20–1000 caracteres e confirmação; draft eliminado logicamente, versão fechada arquivada, restauração autorizada como draft sem republicar. Trigger proíbe eliminação física após fecho/submissão. Ciclo individual de coleções/anexos pendente. |
|
||||
| §15.3 — concorrência/idempotência | Implementado nos endpoints novos | Versão crescente, ETag do estado completo, bloqueio transacional e conflito HTTP 409; UUID de criação evita duplicação por replay. Token no payload e cabeçalho ETag na resposta. Contrato integral de todos os endpoints documentais pendente. |
|
||||
| §16 — imagens | Pendente | Pipeline completo, direitos, MIME, EXIF, capa e versões. ClamD real separado; scanner simulado não valida ficheiros reais. |
|
||||
| §17/19 — persistência/versões | Parcial | Mesmos IDs; alterações de versão fechada em `management_draft`, sem alterar ficha pública. Snapshots anterior/novo cifrados na auditoria existente. Fluxo completo de revisão pendente. |
|
||||
| §20 — permissões/workflow | Parcial | Gate existente no servidor, sem conceder novos papéis. Editor genérico deixa de publicar após instalação. Segregação de papéis e workflow integral pendentes. Revisão interna não é aprovação institucional. |
|
||||
| §21 — DT01–DT15 | Parcial | QA cobre rascunho, concorrência, permissões, replay, exclusão/arquivo/restauro e preservação. Critérios de imagens, validação final, publicação e coleções completas continuam abertos. |
|
||||
| §22 — REQ01–REQ17 | Parcial global | Cobertura por grupos acima; requisitos dos módulos finais continuam pendentes. Não declarar Go/No-Go integral por CRUD. |
|
||||
| §24–28 — categorias especializadas | Pendente além da seleção | Investimento, imobiliário, direitos fundiários, venda de negócio, parceria, franquia, concessão, financiamento, fornecimento e outros selecionáveis. Perfis, coleções e validações específicas exigem incrementos com reutilização dos módulos existentes. |
|
||||
| Relações e fontes oficiais | Preservado | Consulta do contexto existente; nenhum par inferido por nome, setor ou proximidade. Editor de evidência por ligação permanece na frente territorial. |
|
||||
|
||||
## QA e preservação
|
||||
|
||||
@@ -70,3 +74,19 @@ Tentativa de conclusão às 14:19:42 locais de 9 de outubro: controlo de navegad
|
||||
[Imagens, documentos e multilocalização: matriz, QA, lacunas e plano](recursos-oportunidades.md). Guardar/recuperar recursos, originais cifrados, versões e exclusão lógica/restauro implementados; coleção territorial até 50 itens com hierarquia/papéis, áreas/distribuição e GeoJSON validado. Relações existentes conservadas; novas associações são preparação privada até workflow explícito. Processador GD gera WebP/miniaturas sem EXIF e scan independente; GD ativo e ClamD real mantêm dependências concretas. Não publicar automaticamente.
|
||||
|
||||
Leitura ativa em 11:10:21 UTC confirmou novamente os seis IDs reais, dados/relações e 124 eventos anteriores intactos; dois eventos posteriores explicam diferença global do histórico. Novo esquema de recursos ausente, zero eventos deste incremento. QA: 80 testes passaram/1 252 asserções, três ClamD reais saltados; navegador desktop/móvel passou. Plano único `/management/opportunity-resources-install`, backup/restauro e reversão em cópia, validade até 10/10/2026 11:09:13 UTC. Não aplicado automaticamente.
|
||||
|
||||
## Estado de auditoria — lote 2, 09/10/2026
|
||||
|
||||
Prevalece o [relatório atualizado](auditoria-portal/relatorio-executivo.md) sobre estados históricos: maturidade 7/8 já grava/recupera em QA com catálogo versionado, negócios/fundiário têm países/origem separados e provas por percurso, 361 geometrias oficiais internas estão em QA, ClamD real está disponível. Workflow/publicação, cobertura transversal/visual/mapas e recursos ativos continuam pendentes. 379 testes/4922 asserções/zero skips; recursos ready=true, installed=false. A [mesma matriz](auditoria-portal/matriz-requisitos.csv) conserva 3354 requisitos/5830 origens; próximo lote no [backlog](auditoria-portal/backlog.md) prioriza falhas de percursos existentes antes de novas jornadas educativas.
|
||||
|
||||
## Estado de auditoria — lote 3, 09/10/2026
|
||||
|
||||
Balcão:país/origem e devolução para correção demonstrados nos3 serviços; contexto administrativo ligado aos consumidores existentes e361 limites QA recuperados sem publicação.381 testes/5046 asserções/zero skips. QA HTTP recuperada; provider de UI indisponível e visual pendente. Recursos prontos,não instalados; cartografia ativa requer ato autenticado separado. Workflow/contratos mantidos no backlog; nenhuma jornada educativa nova. Prevalecem [relatório](auditoria-portal/relatorio-executivo.md),[backlog](auditoria-portal/backlog.md) e [plano](auditoria-portal/plano-ativacao.md) atuais sobre estados anteriores. PDFs diretos não anexados nesta sessão.
|
||||
|
||||
## Histórico — proposta de consolidação antes da aprovação QA
|
||||
|
||||
Foi lido integralmente o documento de assistente por etapas. A [proposta](auditoria-portal/proposta-consolidacao-percurso.md) organiza cinco fases/19 etapas e cenários A/B, com dados mestres, estados/permissões, reutilização, compatibilidade e reversão. Navegação/modelo/motor aguardam aprovação; nenhuma alteração estrutural ou escrita ativa. Correções anteriores de países/cartografia permanecem em I0. C24 corrige somente o link para o draft associado, demonstrado em API/QA e ainda sem clique visual. A proposta complementa a mesma matriz, não a substitui.
|
||||
|
||||
## Execução I1–I3 autorizada em QA
|
||||
|
||||
Código/API/persistência preparados para cinco fases/19 etapas e investimentos independentes por dossier. 384 ensaios globais/5.215 asserções; A/B API3/163, interface pendente. I0 continua; nenhum dado ativo alterado. Relatório executivo, matriz, backlog e plano em [execucao-percurso-i1-i3.md](auditoria-portal/execucao-percurso-i1-i3.md). Workflow e contratos especializados continuam pendentes; nenhuma nova jornada educativa.
|
||||
|
||||
@@ -18,14 +18,14 @@ Os textos já extraídos do acervo contêm menções a parte destes registos em
|
||||
|
||||
Para **cada ID 1–6**, confirmar: investimento real, exemplo/demonstração ou origem ainda desconhecida; nome do promotor e identificador do investimento/componente, se disponíveis; documento ou decisão de cadastro que identifica o registo; responsável e data da declaração. Não pedir certificação adicional da credibilidade de uma fonte oficial já aceite.
|
||||
|
||||
| ID | Referência e título | Esclarecimento necessário antes de associar |
|
||||
| --- | --- | --- |
|
||||
| 1 | INV-MZ-AGR-001 — Unidade de processamento agrícola em Nampula | A que projeto/polo concreto pertence? Qual a atividade/cultura, unidade e código do componente? |
|
||||
| 2 | INV-MZ-ENE-002 — Mini-rede solar para polo produtivo | Qual é o polo abastecido, o operador e a mini-rede concreta? Como se identifica o investimento das 40 unidades? |
|
||||
| 3 | INV-MZ-TUR-003 — Eco-lodge costeiro com integração comunitária | Qual é o empreendimento e a sua pertença concreta a um projeto/polo? Não decidir apenas por Inhambane ou pela atividade turística. |
|
||||
| 4 | INV-MZ-INF-004 — Centro logístico provincial | Qual a localização efetiva, instalação e corredor servido? Serve um corredor ou vários? |
|
||||
| 5 | INV-MZ-BLUE-005 — Processamento de pescado e cadeia fria | Integra expressamente A12 ou é uma iniciativa independente? Qual é a unidade/componente que o demonstra? |
|
||||
| 6 | INV-MZ-FIN-006 — Plataforma de crédito para PME agrícolas | Pertence a um cluster ou presta apenas serviço financeiro aos seus participantes? Qual o instrumento, operador e relação assumida? |
|
||||
| ID | Referência e título | Esclarecimento necessário antes de associar |
|
||||
| --- | -------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 1 | INV-MZ-AGR-001 — Unidade de processamento agrícola em Nampula | A que projeto/polo concreto pertence? Qual a atividade/cultura, unidade e código do componente? |
|
||||
| 2 | INV-MZ-ENE-002 — Mini-rede solar para polo produtivo | Qual é o polo abastecido, o operador e a mini-rede concreta? Como se identifica o investimento das 40 unidades? |
|
||||
| 3 | INV-MZ-TUR-003 — Eco-lodge costeiro com integração comunitária | Qual é o empreendimento e a sua pertença concreta a um projeto/polo? Não decidir apenas por Inhambane ou pela atividade turística. |
|
||||
| 4 | INV-MZ-INF-004 — Centro logístico provincial | Qual a localização efetiva, instalação e corredor servido? Serve um corredor ou vários? |
|
||||
| 5 | INV-MZ-BLUE-005 — Processamento de pescado e cadeia fria | Integra expressamente A12 ou é uma iniciativa independente? Qual é a unidade/componente que o demonstra? |
|
||||
| 6 | INV-MZ-FIN-006 — Plataforma de crédito para PME agrícolas | Pertence a um cluster ou presta apenas serviço financeiro aos seus participantes? Qual o instrumento, operador e relação assumida? |
|
||||
|
||||
As alternativas do relatório de correspondências são apenas hipóteses de esclarecimento. Uma relação de serviço financeiro não deve ser gravada como pertença a cluster no pivot atual; exige representação explícita do papel sem alterar a identidade dos participantes.
|
||||
|
||||
|
||||
@@ -10,16 +10,16 @@ Recursos novos permanecem em preparação privada, inclusive quando o campo de v
|
||||
|
||||
## Cobertura e requisitos ainda abertos
|
||||
|
||||
| Fonte | Implementado e testado | Lacuna concreta |
|
||||
| --- | --- | --- |
|
||||
| §11 — localizações | Coleção até 50 itens; hierarquia província/distrito/posto/localidade; múltiplos papéis/unidades; localização principal; áreas/unidades/distribuição; fonte/data; endereço; fundamento multidistrito; implantação/contexto/impacto/abrangência separados. Locais sem coordenadas guardados e recuperados. | Grelha/cartografia interativa integral, unidades de catálogo pesquisáveis e ligação a documento/página por seleção ainda pendentes. Requisitos finais são pendências visíveis, não bloqueiam rascunho. |
|
||||
| §11 — coerência territorial | Duplicação por hierarquia/papel/unidade rejeitada; principal duplicada rejeitada. Resumo confere exatamente uma principal, soma de distribuição 100% ±0,01, âmbito derivado, lacunas e fundamento multidistrito. | Compatibilidade espacial com limites oficiais ausentes mantém-se indeterminada; não reabre aceitação das fontes oficiais. |
|
||||
| §11 — geometrias | GeoJSON Point, LineString, Polygon/MultiPolygon EPSG:4326; PostGIS verifica validade, vazio e limites de coordenadas. Consulta por metadados; coordenadas não são inventadas. | Sem limites correspondentes, não declara compatibilidade territorial. Área poligonal/requisitos finais completos e desenho no mapa pendentes. |
|
||||
| §13 — documentos | PDF/DOCX/XLSX/PNG/JPEG, conteúdo/MIME e limites, checksum, original cifrado, categoria/emissor/edição/data/validade/classificação, secção/afirmação; substituição gera outro documento, preservando o anterior. | Evidências com proprietário/data de verificação e associação por campo, catálogos completos e workflow de aprovação documental pendentes. Fonte pendente não invalida um documento oficial já aceite. |
|
||||
| §16 — imagens | JPEG/PNG/WebP, dimensões mínimas 400×400, conteúdo básico, deteção de animação/código, checksum e repetição na mesma oportunidade; título/legenda/alt/autor/data/direitos/comprovativo/visibilidade/ordem/capa e ligação a localização. | Descodificação integral ocorre no processador GD; revisão humana de dados pessoais/direitos e aprovação não foram simuladas. Aviso de duplicados entre oportunidades, catálogo pesquisável e edição por arrastar pendentes. |
|
||||
| §16.1 — derivados | Processador GD explícito após scan do original; WebP responsivo sem metadados originais, sem deformar ou ampliar; originais preservados. Cada derivada recebe o próprio documento/hash/cifragem e scan independente. Pré-visualização autenticada com URL assinada por dez minutos. | GD não está carregado no PHP ativo; validação do processador feita apenas em processo QA com extensão carregada. ClamD real indisponível; nenhum ficheiro real declarado limpo. |
|
||||
| §15.2/15.3 — ciclo/versionamento | Recuperação no servidor, versão por recurso e ETag da oportunidade, conflitos preservam preenchimento, permissões de gestão existentes, confirmação/motivo para exclusão lógica/restauro, retenção de binários, snapshots cifrados anterior/novo. Trigger proíbe eliminação física. Ligações a local/comprovativo impedem exclusão inadvertida do recurso usado. | Restauração não retoma automaticamente capa/principal/ordem; responsável deve reconciliar a seleção. Comparação visual detalhada dos snapshots e RBAC especializado permanecem no workflow futuro. |
|
||||
| §20/21/24–28 | Guardar, preparar derivados e conferência distinguidos de validar/submeter/aprovar/publicar. Mesma origem e relações mantidas. | Submissão, revisão segregada, aprovação/publicação transacional com capa autorizada, módulos especializados e critérios integrais REQ/DT continuam pendentes. |
|
||||
| Fonte | Implementado e testado | Lacuna concreta |
|
||||
| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| §11 — localizações | Coleção até 50 itens; hierarquia província/distrito/posto/localidade; múltiplos papéis/unidades; localização principal; áreas/unidades/distribuição; fonte/data; endereço; fundamento multidistrito; implantação/contexto/impacto/abrangência separados. Locais sem coordenadas guardados e recuperados. | Grelha/cartografia interativa integral, unidades de catálogo pesquisáveis e ligação a documento/página por seleção ainda pendentes. Requisitos finais são pendências visíveis, não bloqueiam rascunho. |
|
||||
| §11 — coerência territorial | Duplicação por hierarquia/papel/unidade rejeitada; principal duplicada rejeitada. Resumo confere exatamente uma principal, soma de distribuição 100% ±0,01, âmbito derivado, lacunas e fundamento multidistrito. | Compatibilidade espacial com limites oficiais ausentes mantém-se indeterminada; não reabre aceitação das fontes oficiais. |
|
||||
| §11 — geometrias | GeoJSON Point, LineString, Polygon/MultiPolygon EPSG:4326; PostGIS verifica validade, vazio e limites de coordenadas. Consulta por metadados; coordenadas não são inventadas. | Sem limites correspondentes, não declara compatibilidade territorial. Área poligonal/requisitos finais completos e desenho no mapa pendentes. |
|
||||
| §13 — documentos | PDF/DOCX/XLSX/PNG/JPEG, conteúdo/MIME e limites, checksum, original cifrado, categoria/emissor/edição/data/validade/classificação, secção/afirmação; substituição gera outro documento, preservando o anterior. | Evidências com proprietário/data de verificação e associação por campo, catálogos completos e workflow de aprovação documental pendentes. Fonte pendente não invalida um documento oficial já aceite. |
|
||||
| §16 — imagens | JPEG/PNG/WebP, dimensões mínimas 400×400, conteúdo básico, deteção de animação/código, checksum e repetição na mesma oportunidade; título/legenda/alt/autor/data/direitos/comprovativo/visibilidade/ordem/capa e ligação a localização. | Descodificação integral ocorre no processador GD; revisão humana de dados pessoais/direitos e aprovação não foram simuladas. Aviso de duplicados entre oportunidades, catálogo pesquisável e edição por arrastar pendentes. |
|
||||
| §16.1 — derivados | Processador GD explícito após scan do original; WebP responsivo sem metadados originais, sem deformar ou ampliar; originais preservados. Cada derivada recebe o próprio documento/hash/cifragem e scan independente. Pré-visualização autenticada com URL assinada por dez minutos. | GD não está carregado no PHP ativo; validação do processador feita apenas em processo QA com extensão carregada. ClamD real indisponível; nenhum ficheiro real declarado limpo. |
|
||||
| §15.2/15.3 — ciclo/versionamento | Recuperação no servidor, versão por recurso e ETag da oportunidade, conflitos preservam preenchimento, permissões de gestão existentes, confirmação/motivo para exclusão lógica/restauro, retenção de binários, snapshots cifrados anterior/novo. Trigger proíbe eliminação física. Ligações a local/comprovativo impedem exclusão inadvertida do recurso usado. | Restauração não retoma automaticamente capa/principal/ordem; responsável deve reconciliar a seleção. Comparação visual detalhada dos snapshots e RBAC especializado permanecem no workflow futuro. |
|
||||
| §20/21/24–28 | Guardar, preparar derivados e conferência distinguidos de validar/submeter/aprovar/publicar. Mesma origem e relações mantidas. | Submissão, revisão segregada, aprovação/publicação transacional com capa autorizada, módulos especializados e critérios integrais REQ/DT continuam pendentes. |
|
||||
|
||||
A seleção de `asset`, `product` ou `evidence` numa imagem é rascunho; associação ao módulo correspondente ainda aparece pendente. Não declara a entidade ligada por semelhança. Metadados de consulta, situação documental e uso em regras/cálculos continuam independentes. Nada ativa um cálculo fiscal.
|
||||
|
||||
|
||||
@@ -4,19 +4,19 @@
|
||||
|
||||
## Resultados demonstrados e lacunas
|
||||
|
||||
| Módulo / rota | Ação e resultado demonstrado nesta revisão | Correção / persistência | Lacuna restante |
|
||||
| --- | --- | --- | --- |
|
||||
| Perfil `/investidor/profile` | Guardar residência, mensagem visível, HTTP 303, recarregar; nova sessão móvel sem localStorage recupera PT; pesquisar Portugal | ISO comum, país de residência explícito, payload privado cifrado e versão existentes | País no cadastro inicial e restantes perfis ainda por reconciliar |
|
||||
| Entidades `/investidor/companies` | QA de servidor: guardar constituição MZ; recuperar no contexto da conta; negar acesso de outra conta | País de constituição distinto; valor histórico conservado; sem concessão de representação | Novo percurso completo de criação/edição de entidade no navegador ainda por demonstrar |
|
||||
| Manifestações `/investidor/manifestacoes/{id}` | QA HTTP: guardar/recuperar três países diferentes; rejeitar ZZ com 422 sem alterar versão/payload; submissão só em QA conserva origem no pedido | A constituição da entidade deixa de substituir o país do perfil; origem explícita no payload, revisão e metadata do mesmo pedido | Teste de todos os passos da manifestação com os novos dropdowns no navegador; os endpoints públicos/legados ainda não recolhem ISO específico |
|
||||
| Balcão `/balcao-virtual/painel` e `/pedidos/{id}` | QA HTTP: origem de rascunho recuperada pelo proprietário; outra conta negada; 422 preserva rascunho; nenhum pedido ativo submetido | Seletores mostram nomes dos investimentos/percursos da conta; título reutilizado quando disponível, sem substituir título corrigido; origem não inferida do perfil | Comprovar no navegador o percurso de reutilização de projeto, pedido e responsável; primeiro pedido real continua pendente |
|
||||
| CRM `/management/crm/leads` | QA: estatísticas e filtro de origem autorizados, acesso não autorizado rejeitado; pedido antigo com país Moçambique e sem origem continua «não informado» | Contagens separadas de manifestações e pedidos em acompanhamento; filtro por país/não informado; sem somar como investidores únicos ou exportar contactos | Verificação das contagens e do filtro no navegador; cobertura dos endpoints legados |
|
||||
| Catálogo `/oportunidades` | Navegador móvel: dimensão Cluster oculta filtros incompatíveis; pesquisa Maputo devolve opção do cadastro | Troca de dimensão limpa filtros incompatíveis; pesquisa no seletor reutilizado | Guião de preferências integrado e percurso completo oportunidade → localização → acompanhamento ainda por demonstrar |
|
||||
| Mapa `/oportunidades?view=map` | Navegador: fichas de estruturas territoriais acessíveis dentro do percurso do mapa | API inclui contexto territorial independente das seis oportunidades, com links de ficheiro; não cria coordenadas nem associações | Desenhar corredores/âncoras/ZEE/ZFI/parques exige geometrias existentes; a base ativa tem zero. Lista consultável não equivale a cartografia completa |
|
||||
| Recursos `/management/opportunities/{id}/resources` | Navegador desktop/móvel: múltiplos locais, PDF/imagem, recuperação, exclusão lógica/restauro; falta de GD visível, preparação desativada | Integra 9d6176f; metadados e rascunhos continuam guardáveis; originais conservados; scan por ficheiro independente | Instalação ativa pendente, ClamD real, GD no PHP web e revisão/publicação final |
|
||||
| Educação `/educacao`, `/management/education` | Testes HTTP existentes executados com a revisão; regras de lacuna preservadas | `/educacao` é catálogo de investimentos educativos; a gestão de procura/capacidade é outra rota | Fluxo educativo integral solicitado, recuperação dos seus rascunhos, painéis por ator e aceitação funcional permanecem abertos; testes existentes não certificam a especificação inteira |
|
||||
| Simulador | Correções do incremento anterior preservadas | Nenhum cálculo fiscal alterado ou ativado pela introdução de países | Nova revisão transversal do simulador ainda não demonstrada nesta frente; não conclui ClamD, fontes institucionais ou pedido real |
|
||||
| Bolsa, serviços, carteira, negócios, fundiário e mapas de zonas | Inventário de consumidores territoriais abaixo | Componentes e entidades existentes preservados | Ações de criar/editar/recuperar por rota e cobertura completa dos países permanecem abertas |
|
||||
| Módulo / rota | Ação e resultado demonstrado nesta revisão | Correção / persistência | Lacuna restante |
|
||||
| --------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Perfil `/investidor/profile` | Guardar residência, mensagem visível, HTTP 303, recarregar; nova sessão móvel sem localStorage recupera PT; pesquisar Portugal | ISO comum, país de residência explícito, payload privado cifrado e versão existentes | País no cadastro inicial e restantes perfis ainda por reconciliar |
|
||||
| Entidades `/investidor/companies` | QA de servidor: guardar constituição MZ; recuperar no contexto da conta; negar acesso de outra conta | País de constituição distinto; valor histórico conservado; sem concessão de representação | Novo percurso completo de criação/edição de entidade no navegador ainda por demonstrar |
|
||||
| Manifestações `/investidor/manifestacoes/{id}` | QA HTTP: guardar/recuperar três países diferentes; rejeitar ZZ com 422 sem alterar versão/payload; submissão só em QA conserva origem no pedido | A constituição da entidade deixa de substituir o país do perfil; origem explícita no payload, revisão e metadata do mesmo pedido | Teste de todos os passos da manifestação com os novos dropdowns no navegador; os endpoints públicos/legados ainda não recolhem ISO específico |
|
||||
| Balcão `/balcao-virtual/painel` e `/pedidos/{id}` | QA HTTP: origem de rascunho recuperada pelo proprietário; outra conta negada; 422 preserva rascunho; nenhum pedido ativo submetido | Seletores mostram nomes dos investimentos/percursos da conta; título reutilizado quando disponível, sem substituir título corrigido; origem não inferida do perfil | Comprovar no navegador o percurso de reutilização de projeto, pedido e responsável; primeiro pedido real continua pendente |
|
||||
| CRM `/management/crm/leads` | QA: estatísticas e filtro de origem autorizados, acesso não autorizado rejeitado; pedido antigo com país Moçambique e sem origem continua «não informado» | Contagens separadas de manifestações e pedidos em acompanhamento; filtro por país/não informado; sem somar como investidores únicos ou exportar contactos | Verificação das contagens e do filtro no navegador; cobertura dos endpoints legados |
|
||||
| Catálogo `/oportunidades` | Navegador móvel: dimensão Cluster oculta filtros incompatíveis; pesquisa Maputo devolve opção do cadastro | Troca de dimensão limpa filtros incompatíveis; pesquisa no seletor reutilizado | Guião de preferências integrado e percurso completo oportunidade → localização → acompanhamento ainda por demonstrar |
|
||||
| Mapa `/oportunidades?view=map` | Navegador: fichas de estruturas territoriais acessíveis dentro do percurso do mapa | API inclui contexto territorial independente das seis oportunidades, com links de ficheiro; não cria coordenadas nem associações | Desenhar corredores/âncoras/ZEE/ZFI/parques exige geometrias existentes; a base ativa tem zero. Lista consultável não equivale a cartografia completa |
|
||||
| Recursos `/management/opportunities/{id}/resources` | Navegador desktop/móvel: múltiplos locais, PDF/imagem, recuperação, exclusão lógica/restauro; falta de GD visível, preparação desativada | Integra 9d6176f; metadados e rascunhos continuam guardáveis; originais conservados; scan por ficheiro independente | Instalação ativa pendente, ClamD real, GD no PHP web e revisão/publicação final |
|
||||
| Educação `/educacao`, `/management/education` | Testes HTTP existentes executados com a revisão; regras de lacuna preservadas | `/educacao` é catálogo de investimentos educativos; a gestão de procura/capacidade é outra rota | Fluxo educativo integral solicitado, recuperação dos seus rascunhos, painéis por ator e aceitação funcional permanecem abertos; testes existentes não certificam a especificação inteira |
|
||||
| Simulador | Correções do incremento anterior preservadas | Nenhum cálculo fiscal alterado ou ativado pela introdução de países | Nova revisão transversal do simulador ainda não demonstrada nesta frente; não conclui ClamD, fontes institucionais ou pedido real |
|
||||
| Bolsa, serviços, carteira, negócios, fundiário e mapas de zonas | Inventário de consumidores territoriais abaixo | Componentes e entidades existentes preservados | Ações de criar/editar/recuperar por rota e cobertura completa dos países permanecem abertas |
|
||||
|
||||
## Continuação — filtro das estatísticas de origem
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -29,6 +29,7 @@ void createInertiaApp({
|
||||
case name.startsWith('portfolio/'):
|
||||
case name.startsWith('land-assistance/'):
|
||||
case name.startsWith('desk/'):
|
||||
case name.startsWith('investor-path/'):
|
||||
return PortalNavigation;
|
||||
case name.startsWith('auth/'):
|
||||
return [PortalNavigation, AuthLayout];
|
||||
|
||||
@@ -179,11 +179,17 @@ export function AppHeader({ breadcrumbs = [] }: Props) {
|
||||
<div className="ml-auto flex items-center space-x-2">
|
||||
<div className="relative flex items-center space-x-1">
|
||||
<Button
|
||||
asChild
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="group h-9 w-9 cursor-pointer"
|
||||
>
|
||||
<Search className="!size-5 opacity-80 group-hover:opacity-100" />
|
||||
<Link
|
||||
href="/oportunidades"
|
||||
aria-label="Pesquisar oportunidades"
|
||||
>
|
||||
<Search className="!size-5 opacity-80 group-hover:opacity-100" />
|
||||
</Link>
|
||||
</Button>
|
||||
<div className="ml-1 hidden gap-1 lg:flex">
|
||||
{rightNavItems.map((item) => (
|
||||
|
||||
@@ -1,20 +1,79 @@
|
||||
import { useState } from 'react';
|
||||
import { useId, useState } from 'react';
|
||||
|
||||
export type Country = { code: string; name: string; name_en: string };
|
||||
|
||||
export default function CountrySelect({ countries, value, onChange, id, disabled = false }: {
|
||||
countries: Country[]; value: string; onChange: (value: string) => void; id: string; disabled?: boolean;
|
||||
export default function CountrySelect({
|
||||
countries,
|
||||
value,
|
||||
onChange,
|
||||
id,
|
||||
disabled = false,
|
||||
label = 'País',
|
||||
required = false,
|
||||
allowLegacyValue = false,
|
||||
}: {
|
||||
countries: Country[];
|
||||
value: string;
|
||||
onChange: (value: string) => void;
|
||||
id?: string;
|
||||
disabled?: boolean;
|
||||
label?: string;
|
||||
required?: boolean;
|
||||
allowLegacyValue?: boolean;
|
||||
}) {
|
||||
const generatedId = useId();
|
||||
const [search, setSearch] = useState('');
|
||||
const matches = countries.filter((country) => country.code === value ||
|
||||
`${country.name} ${country.name_en} ${country.code}`.normalize('NFD').replace(/\p{Diacritic}/gu, '').toLowerCase()
|
||||
.includes(search.normalize('NFD').replace(/\p{Diacritic}/gu, '').toLowerCase()));
|
||||
return <div className="space-y-2">
|
||||
<input disabled={disabled} className="w-full rounded border p-2" aria-label="Pesquisar país" value={search} onChange={(event) => setSearch(event.target.value)} placeholder="Pesquisar nome ou código do país" />
|
||||
<select disabled={disabled} id={id} className="w-full rounded border p-2" value={value} onChange={(event) => onChange(event.target.value)}>
|
||||
<option value="">Não informado</option>
|
||||
{matches.map((country) => <option key={country.code} value={country.code}>{country.name} ({country.code})</option>)}
|
||||
</select>
|
||||
{matches.length === 0 && <p role="status">Nenhum país corresponde à pesquisa.</p>}
|
||||
</div>;
|
||||
const matches = countries.filter(
|
||||
(country) =>
|
||||
country.code === value ||
|
||||
`${country.name} ${country.name_en} ${country.code}`
|
||||
.normalize('NFD')
|
||||
.replace(/\p{Diacritic}/gu, '')
|
||||
.toLowerCase()
|
||||
.includes(
|
||||
search
|
||||
.normalize('NFD')
|
||||
.replace(/\p{Diacritic}/gu, '')
|
||||
.toLowerCase(),
|
||||
),
|
||||
);
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
<input
|
||||
disabled={disabled}
|
||||
className="w-full rounded border p-2"
|
||||
aria-label={`Pesquisar ${label.toLowerCase()}`}
|
||||
maxLength={100}
|
||||
value={search}
|
||||
onChange={(event) => setSearch(event.target.value)}
|
||||
placeholder="Pesquisar nome ou código do país"
|
||||
/>
|
||||
<select
|
||||
disabled={disabled}
|
||||
id={id ?? generatedId}
|
||||
aria-label={label}
|
||||
required={required}
|
||||
className="w-full rounded border p-2"
|
||||
value={value}
|
||||
onChange={(event) => onChange(event.target.value)}
|
||||
>
|
||||
<option value="">Não informado</option>
|
||||
{allowLegacyValue &&
|
||||
value &&
|
||||
!countries.some((country) => country.code === value) && (
|
||||
<option value={value}>
|
||||
{value} (valor anterior conservado)
|
||||
</option>
|
||||
)}
|
||||
{matches.map((country) => (
|
||||
<option key={country.code} value={country.code}>
|
||||
{country.name} ({country.code})
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
{matches.length === 0 && (
|
||||
<p role="status">Nenhum país corresponde à pesquisa.</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ export type InvestmentMapFeature = {
|
||||
};
|
||||
};
|
||||
export type InvestmentMapArea = {
|
||||
purpose?: string;
|
||||
geometry: GeoJsonObject;
|
||||
title: string;
|
||||
source_reference?: string | null;
|
||||
@@ -30,9 +31,11 @@ const noAreas: InvestmentMapArea[] = [];
|
||||
export default function InteractiveInvestmentMap({
|
||||
points,
|
||||
areas = noAreas,
|
||||
contextOnly = false,
|
||||
}: {
|
||||
points: InvestmentMapFeature[] | null;
|
||||
areas?: InvestmentMapArea[];
|
||||
contextOnly?: boolean;
|
||||
}) {
|
||||
const element = useRef<HTMLDivElement>(null);
|
||||
const map = useRef<LeafletMap | null>(null);
|
||||
@@ -73,8 +76,19 @@ export default function InteractiveInvestmentMap({
|
||||
const bounds: [number, number][] = [];
|
||||
for (const area of areas) {
|
||||
const label = document.createElement('p');
|
||||
label.textContent = `${area.title} · Polígono cadastrado, limites oficiais por verificar · Fonte: ${area.source_reference ?? 'Não indicada'} · Data: ${area.source_date ?? 'Não documentada'}`;
|
||||
const layer = L.geoJSON(area.geometry)
|
||||
label.textContent = `${area.title} · ${area.purpose === 'administrative_boundary' ? 'Limite administrativo da edição indicada; não representa um local de investimento' : 'Polígono cadastrado, limites oficiais por verificar'} · Fonte: ${area.source_reference ?? 'Não indicada'} · Data: ${area.source_date ?? 'Não documentada'}`;
|
||||
const layer = L.geoJSON(
|
||||
area.geometry,
|
||||
area.purpose === 'administrative_boundary'
|
||||
? {
|
||||
style: {
|
||||
color: '#2563eb',
|
||||
dashArray: '5 5',
|
||||
fillOpacity: 0.06,
|
||||
},
|
||||
}
|
||||
: {},
|
||||
)
|
||||
.bindPopup(label)
|
||||
.addTo(instance);
|
||||
const extent = layer.getBounds();
|
||||
@@ -160,12 +174,22 @@ export default function InteractiveInvestmentMap({
|
||||
return (
|
||||
<section
|
||||
className="space-y-3 rounded-xl border bg-white p-4 text-slate-900"
|
||||
aria-label="Mapa interactivo dos investimentos"
|
||||
aria-label={
|
||||
contextOnly
|
||||
? 'Mapa dos limites administrativos'
|
||||
: 'Mapa interactivo dos investimentos'
|
||||
}
|
||||
>
|
||||
<h2 className="text-xl font-bold">Mapa dos investimentos</h2>
|
||||
<h2 className="text-xl font-bold">
|
||||
{contextOnly
|
||||
? 'Contexto administrativo'
|
||||
: 'Mapa dos investimentos'}
|
||||
</h2>
|
||||
<p>
|
||||
Arraste para navegar; use +/− para ampliar. Pode seleccionar um
|
||||
investimento na lista para o localizar.
|
||||
{contextOnly
|
||||
? 'limite cadastrado para consultar a sua edição.'
|
||||
: 'investimento na lista para o localizar.'}
|
||||
</p>
|
||||
{error && <p role="status">{error}</p>}
|
||||
<div
|
||||
@@ -177,7 +201,9 @@ export default function InteractiveInvestmentMap({
|
||||
<p role="status">A carregar localizações…</p>
|
||||
) : (
|
||||
<p role="status">
|
||||
{points.length} locais com coordenadas disponíveis.
|
||||
{contextOnly
|
||||
? `${areas.length} limites administrativos disponíveis.`
|
||||
: `${points.length} locais com coordenadas disponíveis.`}
|
||||
</p>
|
||||
)}
|
||||
<ul className="grid gap-2 md:grid-cols-2">
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useEffect, useState } from "react";
|
||||
import TerritoryGeometryPreview from "./territory-geometry-preview";
|
||||
import InteractiveInvestmentMap, {
|
||||
type InvestmentMapFeature,
|
||||
type InvestmentMapArea,
|
||||
} from './interactive-investment-map';
|
||||
} from "./interactive-investment-map";
|
||||
|
||||
export default function InvestmentMapPanel({
|
||||
filters,
|
||||
territoryId,
|
||||
}: {
|
||||
filters: Record<string, string | number>;
|
||||
territoryId?: string;
|
||||
}) {
|
||||
const key = JSON.stringify(filters);
|
||||
const [points, setPoints] = useState<InvestmentMapFeature[] | null>(null);
|
||||
const [missing, setMissing] = useState<
|
||||
{ id: number; title: string; url: string }[]
|
||||
>([]);
|
||||
const [error, setError] = useState('');
|
||||
const [error, setError] = useState("");
|
||||
const [areas, setAreas] = useState<InvestmentMapArea[]>([]);
|
||||
useEffect(() => {
|
||||
const controller = new AbortController();
|
||||
@@ -23,10 +26,10 @@ export default function InvestmentMapPanel({
|
||||
setAreas([]);
|
||||
fetch(`/api/v1/investment/map?${params}`, {
|
||||
signal: controller.signal,
|
||||
headers: { Accept: 'application/json' },
|
||||
headers: { Accept: "application/json" },
|
||||
})
|
||||
.then(async (response) => {
|
||||
if (!response.ok) throw new Error('Mapa indisponível.');
|
||||
if (!response.ok) throw new Error("Mapa indisponível.");
|
||||
return response.json();
|
||||
})
|
||||
.then((data) => {
|
||||
@@ -36,8 +39,8 @@ export default function InvestmentMapPanel({
|
||||
setMissing(data.unlocated ?? []);
|
||||
setError(
|
||||
data.truncated
|
||||
? 'Cobertura limitada: refine os filtros.'
|
||||
: '',
|
||||
? "Cobertura limitada: refine os filtros."
|
||||
: "",
|
||||
);
|
||||
})
|
||||
.catch((e) => {
|
||||
@@ -49,6 +52,19 @@ export default function InvestmentMapPanel({
|
||||
<section className="space-y-3">
|
||||
{error && <p role="alert">{error}</p>}
|
||||
<InteractiveInvestmentMap points={points} areas={areas} />
|
||||
<TerritoryGeometryPreview
|
||||
territoryId={
|
||||
territoryId ||
|
||||
String(
|
||||
filters.locality_id ||
|
||||
filters.admin_post_id ||
|
||||
filters.district_id ||
|
||||
filters.province_id ||
|
||||
filters.geo_location_id ||
|
||||
"",
|
||||
)
|
||||
}
|
||||
/>
|
||||
{missing.length > 0 && (
|
||||
<div>
|
||||
<p>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useEffect, useId, useState } from 'react';
|
||||
import { api } from '@/pages/investment/shared';
|
||||
import { replaceTerritoryPath } from '@/lib/territory-path.js';
|
||||
import TerritoryGeometryPreview from './territory-geometry-preview';
|
||||
|
||||
export type TerritoryOption = {
|
||||
id: string;
|
||||
@@ -38,51 +39,77 @@ export function ProvinceSelect({
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState('');
|
||||
const [retry, setRetry] = useState(0);
|
||||
const [search, setSearch] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
const controller = new AbortController();
|
||||
setLoading(true);
|
||||
setError('');
|
||||
fetch(`${endpoint}?type=province&page=1`, {
|
||||
signal: controller.signal,
|
||||
headers: { Accept: 'application/json' },
|
||||
})
|
||||
.then(async (response) => {
|
||||
if (!response.ok)
|
||||
throw new Error('Não foi possível carregar as províncias.');
|
||||
return response.json();
|
||||
})
|
||||
.then((data) => setOptions(data.data))
|
||||
.catch((cause) => {
|
||||
if (!controller.signal.aborted)
|
||||
setError(
|
||||
cause instanceof Error
|
||||
? cause.message
|
||||
: 'Erro de ligação.',
|
||||
);
|
||||
})
|
||||
.finally(() => {
|
||||
if (!controller.signal.aborted) setLoading(false);
|
||||
});
|
||||
return () => controller.abort();
|
||||
}, [endpoint, retry]);
|
||||
const timer = setTimeout(
|
||||
() =>
|
||||
fetch(
|
||||
`${endpoint}?${new URLSearchParams({ type: 'province', page: '1', q: search })}`,
|
||||
{
|
||||
signal: controller.signal,
|
||||
headers: { Accept: 'application/json' },
|
||||
},
|
||||
)
|
||||
.then(async (response) => {
|
||||
if (!response.ok)
|
||||
throw new Error(
|
||||
'Não foi possível carregar as províncias.',
|
||||
);
|
||||
return response.json();
|
||||
})
|
||||
.then((data) => {
|
||||
if (!controller.signal.aborted) setOptions(data.data);
|
||||
})
|
||||
.catch((cause) => {
|
||||
if (!controller.signal.aborted)
|
||||
setError(
|
||||
cause instanceof Error
|
||||
? cause.message
|
||||
: 'Erro de ligação.',
|
||||
);
|
||||
})
|
||||
.finally(() => {
|
||||
if (!controller.signal.aborted) setLoading(false);
|
||||
}),
|
||||
250,
|
||||
);
|
||||
return () => {
|
||||
clearTimeout(timer);
|
||||
controller.abort();
|
||||
};
|
||||
}, [endpoint, retry, search]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<input
|
||||
className={className}
|
||||
aria-label={`Pesquisar ${label}`}
|
||||
maxLength={100}
|
||||
placeholder="Pesquisar nome ou código"
|
||||
value={search}
|
||||
onChange={(event) => setSearch(event.target.value)}
|
||||
/>
|
||||
<select
|
||||
id={id}
|
||||
aria-label={label}
|
||||
className={className}
|
||||
required={required}
|
||||
value={
|
||||
options.some((option) => option.name === value) ? value : ''
|
||||
}
|
||||
value={value}
|
||||
disabled={loading || Boolean(error)}
|
||||
onChange={(event) => onChange(event.target.value)}
|
||||
>
|
||||
<option value="">
|
||||
{loading ? 'A carregar províncias…' : placeholder}
|
||||
</option>
|
||||
{value && !options.some((option) => option.name === value) && (
|
||||
<option value={value}>
|
||||
{value} (seleção guardada; conferir cadastro)
|
||||
</option>
|
||||
)}
|
||||
{options.map((option) => (
|
||||
<option key={option.id} value={option.name}>
|
||||
{option.name}
|
||||
@@ -108,10 +135,12 @@ export function TerritoryFields({
|
||||
initial = emptyTerritoryPath,
|
||||
onChange,
|
||||
endpoint = '/api/v1/investment/territory-options',
|
||||
disabled = false,
|
||||
}: {
|
||||
initial?: TerritoryOption[];
|
||||
onChange?: (path: TerritoryOption[]) => void;
|
||||
endpoint?: string;
|
||||
disabled?: boolean;
|
||||
}) {
|
||||
const [path, setPath] = useState(initial);
|
||||
useEffect(() => setPath(initial), [initial]);
|
||||
@@ -132,6 +161,7 @@ export function TerritoryFields({
|
||||
value={path[index]?.id ?? ''}
|
||||
/>
|
||||
<TerritoryLevel
|
||||
disabled={disabled}
|
||||
index={index}
|
||||
parent={path[index - 1]?.id ?? ''}
|
||||
selected={path[index]}
|
||||
@@ -148,6 +178,10 @@ export function TerritoryFields({
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
<TerritoryGeometryPreview
|
||||
territoryId={path.at(-1)?.id}
|
||||
management={endpoint.startsWith('/management/')}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -159,6 +193,7 @@ export function TerritoryLevel({
|
||||
onChange,
|
||||
endpoint = '/management/territory-options',
|
||||
fieldError,
|
||||
disabled = false,
|
||||
}: {
|
||||
index: number;
|
||||
parent: string;
|
||||
@@ -166,6 +201,7 @@ export function TerritoryLevel({
|
||||
onChange: (value?: Option) => void;
|
||||
endpoint?: string;
|
||||
fieldError?: string;
|
||||
disabled?: boolean;
|
||||
}) {
|
||||
const id = useId();
|
||||
const [page, setPage] = useState(1);
|
||||
@@ -175,8 +211,11 @@ export function TerritoryLevel({
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [retry, setRetry] = useState(0);
|
||||
const [search, setSearch] = useState('');
|
||||
const enabled = index === 0 || Boolean(parent);
|
||||
useEffect(() => { setPage(1); setSearch(''); }, [parent, index]);
|
||||
const enabled = !disabled && (index === 0 || Boolean(parent));
|
||||
useEffect(() => {
|
||||
setPage(1);
|
||||
setSearch('');
|
||||
}, [parent, index]);
|
||||
useEffect(() => {
|
||||
setOptions([]);
|
||||
setMore(false);
|
||||
@@ -224,7 +263,18 @@ export function TerritoryLevel({
|
||||
<label htmlFor={id} className="font-medium">
|
||||
{labels[index]}
|
||||
</label>
|
||||
<input className={control} aria-label={`Pesquisar ${labels[index]}`} disabled={!enabled} maxLength={100} value={search} onChange={(event) => { setSearch(event.target.value); setPage(1); }} placeholder={`Pesquisar ${labels[index].toLowerCase()}`} />
|
||||
<input
|
||||
className={control}
|
||||
aria-label={`Pesquisar ${labels[index]}`}
|
||||
disabled={!enabled}
|
||||
maxLength={100}
|
||||
value={search}
|
||||
onChange={(event) => {
|
||||
setSearch(event.target.value);
|
||||
setPage(1);
|
||||
}}
|
||||
placeholder={`Pesquisar ${labels[index].toLowerCase()}`}
|
||||
/>
|
||||
<select
|
||||
id={id}
|
||||
aria-invalid={Boolean(fieldError)}
|
||||
@@ -345,6 +395,10 @@ export default function InvestmentTerritory({
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<TerritoryGeometryPreview
|
||||
territoryId={path.at(-1)?.id}
|
||||
management
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
className="bg-primary text-primary-foreground rounded px-4 py-2 disabled:opacity-50"
|
||||
|
||||
@@ -4,10 +4,15 @@ import type { Guidance } from './investor-guidance';
|
||||
|
||||
/** Carries only an account-scoped case identifier between modules; never a contact/document payload. */
|
||||
export function JourneyCompanion() {
|
||||
const { props, url } = usePage<{ auth: { user: { id: number } | null } }>();
|
||||
const { props, url } = usePage<{
|
||||
auth: { user: { id: number } | null };
|
||||
investorPathEnabled?: boolean;
|
||||
}>();
|
||||
const actor = props.auth?.user?.id;
|
||||
const [open, setOpen] = useState(false);
|
||||
const [cases, setCases] = useState<{ id: string; title: string }[]>([]);
|
||||
const [cases, setCases] = useState<
|
||||
{ id: string; title: string; path_supported?: boolean }[]
|
||||
>([]);
|
||||
const [active, setActive] = useState('');
|
||||
const [guidance, setGuidance] = useState<Guidance | null>(null);
|
||||
const [message, setMessage] = useState('');
|
||||
@@ -19,15 +24,27 @@ export function JourneyCompanion() {
|
||||
if (!actor) return;
|
||||
try {
|
||||
const key = `investmoz-guidance-case:${actor}`;
|
||||
const routeId = url.match(
|
||||
/^\/balcao-virtual\/dossiers\/([a-f0-9-]{36})/i,
|
||||
)?.[1];
|
||||
const context = new URL(
|
||||
url,
|
||||
'https://investmoz.invalid',
|
||||
).searchParams.get('context');
|
||||
const pathId = props.investorPathEnabled
|
||||
? url.match(/^\/investimentos\/([a-f0-9-]{36})/i)?.[1]
|
||||
: null;
|
||||
const routeId =
|
||||
pathId ??
|
||||
(props.investorPathEnabled &&
|
||||
context &&
|
||||
/^[a-f0-9-]{36}$/i.test(context)
|
||||
? context
|
||||
: null) ??
|
||||
url.match(/^\/balcao-virtual\/dossiers\/([a-f0-9-]{36})/i)?.[1];
|
||||
if (routeId) sessionStorage.setItem(key, routeId);
|
||||
setActive(routeId ?? sessionStorage.getItem(key) ?? '');
|
||||
} catch {
|
||||
setMessage('Selecção de contexto disponível apenas nesta página.');
|
||||
}
|
||||
}, [actor, url]);
|
||||
}, [actor, url, props.investorPathEnabled]);
|
||||
useEffect(() => {
|
||||
if (!open || !actor) return;
|
||||
const controller = new AbortController();
|
||||
@@ -42,7 +59,11 @@ export function JourneyCompanion() {
|
||||
'Acompanhamento em preparação; os pedidos anteriores continuam no Balcão Virtual.',
|
||||
);
|
||||
return r.json() as Promise<{
|
||||
cases: { id: string; title: string }[];
|
||||
cases: {
|
||||
id: string;
|
||||
title: string;
|
||||
path_supported?: boolean;
|
||||
}[];
|
||||
}>;
|
||||
})
|
||||
.then((data) => setCases(data.cases))
|
||||
@@ -110,6 +131,25 @@ export function JourneyCompanion() {
|
||||
</p>
|
||||
) : (
|
||||
<>
|
||||
{props.investorPathEnabled && (
|
||||
<Link
|
||||
className="block underline"
|
||||
href="/investimentos"
|
||||
>
|
||||
Os meus investimentos e próxima acção
|
||||
</Link>
|
||||
)}
|
||||
{cases.some(
|
||||
(item) =>
|
||||
item.id === active && item.path_supported,
|
||||
) && (
|
||||
<Link
|
||||
className="block font-semibold underline"
|
||||
href={`/investimentos/${active}`}
|
||||
>
|
||||
Voltar ao percurso deste investimento
|
||||
</Link>
|
||||
)}
|
||||
<label className="block">
|
||||
Contexto do projecto
|
||||
<select
|
||||
|
||||
@@ -63,10 +63,10 @@ import {
|
||||
} from '@/lib/simulation-api';
|
||||
|
||||
type Choice = { id: string; label: string };
|
||||
const draftKey = 'investmoz-simulation-draft-v1';
|
||||
const idempotencyStorageKey = 'investmoz-simulation-idempotency-v1';
|
||||
const draftCreateKey = 'investmoz-simulation-draft-create-key-v1';
|
||||
const draftIdKey = 'investmoz-simulation-draft-id-v1';
|
||||
const legacyDraftKey = 'investmoz-simulation-draft-v1';
|
||||
const legacyIdempotencyStorageKey = 'investmoz-simulation-idempotency-v1';
|
||||
const legacyDraftCreateKey = 'investmoz-simulation-draft-create-key-v1';
|
||||
const legacyDraftIdKey = 'investmoz-simulation-draft-id-v1';
|
||||
const idempotencyKey = () => crypto.randomUUID();
|
||||
|
||||
function csrfToken(): string {
|
||||
@@ -397,6 +397,26 @@ function useChoices(
|
||||
let url: URL;
|
||||
if (source === 'sector') {
|
||||
url = new URL('/api/v1/sectors', window.location.origin);
|
||||
} else if (source === 'country') {
|
||||
url = new URL(
|
||||
'/api/v1/catalogs/countries',
|
||||
window.location.origin,
|
||||
);
|
||||
url.searchParams.set('q', query);
|
||||
url.searchParams.set('per_page', '100');
|
||||
} else if (
|
||||
['province', 'district', 'admin_post', 'locality'].includes(
|
||||
source,
|
||||
)
|
||||
) {
|
||||
url = new URL(
|
||||
'/api/v1/investment/territory-options',
|
||||
window.location.origin,
|
||||
);
|
||||
url.searchParams.set('type', source);
|
||||
url.searchParams.set('q', query);
|
||||
if (source !== 'province')
|
||||
url.searchParams.set('parent_id', parent);
|
||||
} else {
|
||||
url = new URL(
|
||||
'/api/v1/catalogs/' +
|
||||
@@ -427,6 +447,7 @@ function useChoices(
|
||||
'Não foi possível carregar as opções. Tente novamente.',
|
||||
);
|
||||
const payload = await readSimulationApiJson(response);
|
||||
if (controller.signal.aborted) return;
|
||||
setChoices(simulationCatalogChoices(payload));
|
||||
} catch (cause) {
|
||||
if (!controller.signal.aborted)
|
||||
@@ -489,12 +510,15 @@ function SearchChoice({
|
||||
retry,
|
||||
} = useChoices(source, query, parent, !disabled && open);
|
||||
const chosen = Array.isArray(value) ? value : value ? [value] : [];
|
||||
const searchText = (text: string) =>
|
||||
text
|
||||
.normalize('NFD')
|
||||
.replace(/\p{Diacritic}/gu, '')
|
||||
.toLocaleLowerCase();
|
||||
const filtered = choices.filter(
|
||||
(option) =>
|
||||
option.label
|
||||
.toLocaleLowerCase()
|
||||
.includes(query.toLocaleLowerCase()) ||
|
||||
option.id.toLocaleLowerCase().includes(query.toLocaleLowerCase()),
|
||||
searchText(option.label).includes(searchText(query)) ||
|
||||
searchText(option.id).includes(searchText(query)),
|
||||
);
|
||||
useEffect(() => {
|
||||
if (open) activeOptionRef.current?.scrollIntoView({ block: 'nearest' });
|
||||
@@ -746,6 +770,28 @@ export function SimulationForm() {
|
||||
const { auth } = usePage<{
|
||||
auth: { user: { email_verified_at?: string | null } | null };
|
||||
}>().props;
|
||||
const pageUrl = usePage().url;
|
||||
const draftContext = useMemo(() => {
|
||||
const params = new URL(pageUrl, 'https://investmoz.invalid')
|
||||
.searchParams;
|
||||
return {
|
||||
context: params.get('context'),
|
||||
requestedDraft: params.get('draft'),
|
||||
};
|
||||
}, [pageUrl]);
|
||||
const contextId = draftContext.context;
|
||||
const storageScope = contextId
|
||||
? `:case:${contextId}`
|
||||
: draftContext.requestedDraft
|
||||
? `:draft:${draftContext.requestedDraft}`
|
||||
: '';
|
||||
const draftKey = legacyDraftKey + storageScope;
|
||||
const draftCreateKey = legacyDraftCreateKey + storageScope;
|
||||
const draftIdKey = legacyDraftIdKey + storageScope;
|
||||
const idempotencyStorageKey = legacyIdempotencyStorageKey + storageScope;
|
||||
const currentDraftUrl = contextId
|
||||
? `/api/v1/simulation-drafts/current?context=${encodeURIComponent(contextId)}`
|
||||
: '/api/v1/simulation-drafts/current';
|
||||
const canSavePersonalData = Boolean(auth?.user);
|
||||
const canAssociateDraft = Boolean(auth?.user?.email_verified_at);
|
||||
const [draft, setDraft] = useState<SimulationDraft>({});
|
||||
@@ -1123,9 +1169,9 @@ export function SimulationForm() {
|
||||
}
|
||||
try {
|
||||
const response = await fetch(
|
||||
requestedDraftId
|
||||
requestedDraftId && !contextId
|
||||
? `/api/v1/simulation-drafts/${encodeURIComponent(requestedDraftId)}`
|
||||
: '/api/v1/simulation-drafts/current',
|
||||
: currentDraftUrl,
|
||||
{
|
||||
credentials: 'same-origin',
|
||||
headers: {
|
||||
@@ -1140,7 +1186,7 @@ export function SimulationForm() {
|
||||
throw new Error(
|
||||
'O servidor devolveu um rascunho com formato inválido.',
|
||||
);
|
||||
if (canSavePersonalData) {
|
||||
if (canSavePersonalData && !contextId) {
|
||||
const [listResponse, previewResponse] =
|
||||
await Promise.all([
|
||||
fetch('/api/v1/simulation-drafts', {
|
||||
@@ -1222,9 +1268,19 @@ export function SimulationForm() {
|
||||
if (storedId) sessionStorage.removeItem(draftIdKey);
|
||||
setDraft(local);
|
||||
}
|
||||
} else if (contextId || requestedDraftId) {
|
||||
saveConflictRef.current = true;
|
||||
setHasSaveConflict(true);
|
||||
setSaveStatus(
|
||||
'Dossier indisponível para esta conta. Nenhum outro rascunho foi aberto.',
|
||||
);
|
||||
} else if (!canSavePersonalData && Object.keys(local).length)
|
||||
setDraft(local);
|
||||
} catch {
|
||||
if (contextId || requestedDraftId) {
|
||||
saveConflictRef.current = true;
|
||||
setHasSaveConflict(true);
|
||||
}
|
||||
if (!canSavePersonalData && Object.keys(local).length)
|
||||
setDraft(local);
|
||||
setSaveStatus(
|
||||
@@ -1236,7 +1292,7 @@ export function SimulationForm() {
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [canSavePersonalData]);
|
||||
}, [canSavePersonalData, contextId, currentDraftUrl, draftIdKey, draftKey]);
|
||||
useEffect(() => {
|
||||
if (!ready || !draft.purpose) return;
|
||||
const timer = window.setTimeout(() => {
|
||||
@@ -1268,15 +1324,12 @@ export function SimulationForm() {
|
||||
'X-XSRF-TOKEN': csrfToken(),
|
||||
};
|
||||
if (!draftIdRef.current) {
|
||||
const currentResponse = await fetch(
|
||||
'/api/v1/simulation-drafts/current',
|
||||
{
|
||||
credentials: 'same-origin',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
},
|
||||
const currentResponse = await fetch(currentDraftUrl, {
|
||||
credentials: 'same-origin',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
},
|
||||
);
|
||||
});
|
||||
const currentPayload: unknown = currentResponse.ok
|
||||
? await readSimulationApiJson(currentResponse)
|
||||
: { data: null };
|
||||
@@ -1313,7 +1366,12 @@ export function SimulationForm() {
|
||||
...headers,
|
||||
'If-Match': draftEtagRef.current,
|
||||
},
|
||||
body: JSON.stringify(snapshots),
|
||||
body: JSON.stringify({
|
||||
...snapshots,
|
||||
...(contextId
|
||||
? { context: contextId }
|
||||
: {}),
|
||||
}),
|
||||
},
|
||||
);
|
||||
} else {
|
||||
@@ -1326,7 +1384,10 @@ export function SimulationForm() {
|
||||
method: 'POST',
|
||||
credentials: 'same-origin',
|
||||
headers: { ...headers, 'Idempotency-Key': key },
|
||||
body: JSON.stringify(snapshots),
|
||||
body: JSON.stringify({
|
||||
...snapshots,
|
||||
...(contextId ? { context: contextId } : {}),
|
||||
}),
|
||||
});
|
||||
}
|
||||
if (response.status === 412 || response.status === 428) {
|
||||
@@ -1401,7 +1462,87 @@ export function SimulationForm() {
|
||||
});
|
||||
}, 450);
|
||||
return () => window.clearTimeout(timer);
|
||||
}, [draft, ready, canSavePersonalData, accountDrafts]);
|
||||
}, [
|
||||
draft,
|
||||
ready,
|
||||
canSavePersonalData,
|
||||
accountDrafts,
|
||||
contextId,
|
||||
currentDraftUrl,
|
||||
draftCreateKey,
|
||||
draftIdKey,
|
||||
draftKey,
|
||||
]);
|
||||
|
||||
async function returnToInvestment() {
|
||||
if (!contextId || !draftIdRef.current) return;
|
||||
setContinuityError('');
|
||||
try {
|
||||
await saveQueueRef.current;
|
||||
const current = await fetch(
|
||||
`/api/v1/simulation-drafts/${draftIdRef.current}`,
|
||||
{
|
||||
headers: { Accept: 'application/json' },
|
||||
credentials: 'same-origin',
|
||||
},
|
||||
);
|
||||
const saved: unknown = await readSimulationApiJson(current);
|
||||
if (
|
||||
!current.ok ||
|
||||
!isApiSimulationDraftReadResponseV1(saved) ||
|
||||
!saved.data
|
||||
)
|
||||
throw new Error(
|
||||
'Não foi possível recuperar o rascunho guardado.',
|
||||
);
|
||||
if (
|
||||
saved.data.economic_snapshot.financial_tools_snapshot !==
|
||||
draft.financial_tools_snapshot
|
||||
)
|
||||
throw new Error(
|
||||
'Aguarde a gravação das entradas da ferramenta e tente novamente.',
|
||||
);
|
||||
const dossier = await fetch(`/investimentos/${contextId}`, {
|
||||
headers: { Accept: 'application/json' },
|
||||
credentials: 'same-origin',
|
||||
});
|
||||
if (!dossier.ok)
|
||||
throw new Error('Dossier indisponível para esta conta.');
|
||||
const view = (await dossier.json()) as {
|
||||
case: { version: number };
|
||||
};
|
||||
const response = await fetch(
|
||||
`/investimentos/${contextId}/resultados`,
|
||||
{
|
||||
method: 'POST',
|
||||
credentials: 'same-origin',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
'X-XSRF-TOKEN': csrfToken(),
|
||||
},
|
||||
body: JSON.stringify({
|
||||
version: view.case.version,
|
||||
draft_id: saved.data.id,
|
||||
draft_version: saved.data.version_no,
|
||||
}),
|
||||
},
|
||||
);
|
||||
if (!response.ok)
|
||||
throw new Error(
|
||||
response.status === 409
|
||||
? 'O dossier mudou. Recupere a versão actual antes de devolver o resultado.'
|
||||
: 'Não foi possível devolver as entradas financeiras guardadas ao dossier.',
|
||||
);
|
||||
window.location.assign(`/investimentos/${contextId}`);
|
||||
} catch (cause) {
|
||||
setContinuityError(
|
||||
cause instanceof Error
|
||||
? cause.message
|
||||
: 'Erro ao devolver o resultado.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function openOwnedDraft(id: string) {
|
||||
setContinuityError('');
|
||||
@@ -2264,6 +2405,32 @@ export function SimulationForm() {
|
||||
id={draftIdRef.current}
|
||||
/>
|
||||
)}
|
||||
{contextId && (
|
||||
<section
|
||||
className="rounded-lg border p-4"
|
||||
aria-label="Contexto do investimento"
|
||||
>
|
||||
<p>
|
||||
Ferramenta ligada ao dossier actual. As entradas são
|
||||
guardadas no rascunho deste investimento.
|
||||
</p>
|
||||
<button
|
||||
type="button"
|
||||
className="mt-2 rounded border px-3 py-2"
|
||||
disabled={!ready || hasSaveConflict || !draftVersionNo}
|
||||
onClick={() => void returnToInvestment()}
|
||||
>
|
||||
Guardar resultado financeiro e voltar ao dossier
|
||||
</button>
|
||||
{continuityError && <p role="alert">{continuityError}</p>}
|
||||
<a
|
||||
className="ml-3 underline"
|
||||
href={`/investimentos/${contextId}`}
|
||||
>
|
||||
Ver dossier
|
||||
</a>
|
||||
</section>
|
||||
)}
|
||||
<div className="flex flex-wrap items-start justify-between gap-3">
|
||||
<div>
|
||||
<h2
|
||||
@@ -2465,6 +2632,7 @@ export function SimulationForm() {
|
||||
</section>
|
||||
)}
|
||||
{canSavePersonalData &&
|
||||
!contextId &&
|
||||
!showDraftChoice &&
|
||||
accountDrafts.length > 0 && (
|
||||
<section
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import InteractiveInvestmentMap, {
|
||||
type InvestmentMapArea,
|
||||
} from './interactive-investment-map';
|
||||
|
||||
const noPoints: [] = [];
|
||||
type Context = {
|
||||
selected_geometry_available: boolean;
|
||||
context_geometry_count: number;
|
||||
areas: InvestmentMapArea[];
|
||||
truncated: boolean;
|
||||
};
|
||||
export default function TerritoryGeometryPreview({
|
||||
territoryId,
|
||||
management = false,
|
||||
}: {
|
||||
territoryId?: string;
|
||||
management?: boolean;
|
||||
}) {
|
||||
const [context, setContext] = useState<Context | null>(null);
|
||||
const [error, setError] = useState('');
|
||||
useEffect(() => {
|
||||
setContext(null);
|
||||
setError('');
|
||||
if (!territoryId) return;
|
||||
const controller = new AbortController();
|
||||
const endpoint = management
|
||||
? '/management/territory-geometries'
|
||||
: '/api/v1/investment/territory-geometries';
|
||||
void fetch(
|
||||
`${endpoint}?${new URLSearchParams({ territory_id: territoryId })}`,
|
||||
{
|
||||
signal: controller.signal,
|
||||
headers: { Accept: 'application/json' },
|
||||
},
|
||||
)
|
||||
.then(async (response) => {
|
||||
if (!response.ok)
|
||||
throw new Error(
|
||||
'Não foi possível consultar os limites administrativos.',
|
||||
);
|
||||
return response.json() as Promise<Context>;
|
||||
})
|
||||
.then((data) => {
|
||||
if (!controller.signal.aborted) setContext(data);
|
||||
})
|
||||
.catch((e: unknown) => {
|
||||
if (!controller.signal.aborted)
|
||||
setError(
|
||||
e instanceof Error ? e.message : 'Erro de ligação.',
|
||||
);
|
||||
});
|
||||
return () => controller.abort();
|
||||
}, [territoryId, management]);
|
||||
if (!territoryId) return null;
|
||||
return (
|
||||
<section
|
||||
className="space-y-2 md:col-span-full"
|
||||
aria-label="Cobertura cartográfica da seleção"
|
||||
>
|
||||
<p>Território selecionado no cadastro.</p>
|
||||
{error && <p role="alert">{error}</p>}
|
||||
{!context && !error && <p role="status">A consultar geometria…</p>}
|
||||
{context && (
|
||||
<>
|
||||
<p role="status">
|
||||
{context.selected_geometry_available
|
||||
? 'Limite administrativo disponível para este território.'
|
||||
: 'Sem limite administrativo disponível para este território.'}
|
||||
</p>
|
||||
<p>
|
||||
{context.context_geometry_count} limites disponíveis na
|
||||
hierarquia selecionada. São contexto administrativo, não
|
||||
perímetro nem disponibilidade de investimento. A edição
|
||||
e a atualidade jurídica são informações distintas.
|
||||
</p>
|
||||
{context.truncated && (
|
||||
<p role="alert">
|
||||
Exibidos os primeiros 100 limites; cobertura
|
||||
incompleta.
|
||||
</p>
|
||||
)}
|
||||
{context.areas.length > 0 && (
|
||||
<InteractiveInvestmentMap
|
||||
points={noPoints}
|
||||
areas={context.areas}
|
||||
contextOnly
|
||||
/>
|
||||
)}
|
||||
<ul>
|
||||
{context.areas.map((area, index) => (
|
||||
<li key={index}>
|
||||
{area.title} · Fonte:{' '}
|
||||
{area.source_reference ?? 'Não indicada'} ·
|
||||
Edição: {area.source_date ?? 'Não indicada'}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</>
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -36,6 +36,7 @@ const names: Record<string, string> = {
|
||||
'/manifestar-interesse': 'Manifestar interesse',
|
||||
'/carteira': 'Corredores, clusters e projectos',
|
||||
'/investidor': 'O meu painel',
|
||||
'/investimentos': 'Os meus investimentos',
|
||||
'/login': 'Entrar',
|
||||
'/register': 'Criar conta',
|
||||
'/dashboard': 'Painel',
|
||||
@@ -60,6 +61,7 @@ export default function PortalNavigation({
|
||||
'investment/',
|
||||
'portfolio/',
|
||||
'desk/',
|
||||
'investor-path/',
|
||||
'auth/',
|
||||
'land-assistance/',
|
||||
].some((prefix) => component.startsWith(prefix));
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
import {
|
||||
calculateBreakEven,
|
||||
calculateFundingGap,
|
||||
restoreFinancialToolsSnapshot,
|
||||
} from './financial-calculators.ts';
|
||||
|
||||
export const pathStates: Record<string, string> = {
|
||||
not_started: 'Por iniciar',
|
||||
preparing: 'Em preparação',
|
||||
ready_to_submit: 'Pronto para submeter',
|
||||
submitted: 'Submetido',
|
||||
reviewing: 'Validação interna',
|
||||
correction_required: 'Correcção pedida',
|
||||
waiting_external: 'Aguarda informação externa',
|
||||
approved: 'Acto externo favorável documentado',
|
||||
rejected: 'Acto externo desfavorável documentado',
|
||||
dispensed: 'Preparação dispensada pelo promotor',
|
||||
completed: 'Concluído',
|
||||
expired: 'Acto externo expirado',
|
||||
};
|
||||
export type PathResult = {
|
||||
id: string;
|
||||
financial_snapshot: string;
|
||||
currency: string | null;
|
||||
draft_id: string;
|
||||
draft_version: number;
|
||||
engine: string;
|
||||
recorded_at: string;
|
||||
};
|
||||
export function recoverPathResult(result: PathResult) {
|
||||
if (result.engine !== 'financial-calculators:v1')
|
||||
throw new Error(
|
||||
'Versão do cálculo indisponível; as entradas foram preservadas.',
|
||||
);
|
||||
const snapshot = restoreFinancialToolsSnapshot(result.financial_snapshot);
|
||||
if (!snapshot)
|
||||
throw new Error(
|
||||
'Entradas incompatíveis; a evidência original foi preservada.',
|
||||
);
|
||||
const independent = <T>(
|
||||
run: () => T,
|
||||
): { value: T | null; error: string | null } => {
|
||||
try {
|
||||
return { value: run(), error: null };
|
||||
} catch (error) {
|
||||
return {
|
||||
value: null,
|
||||
error:
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: 'Cálculo indeterminado',
|
||||
};
|
||||
}
|
||||
};
|
||||
return {
|
||||
breakEven: independent(() =>
|
||||
calculateBreakEven(
|
||||
snapshot.breakEven.fixed,
|
||||
snapshot.breakEven.price,
|
||||
snapshot.breakEven.variable,
|
||||
),
|
||||
),
|
||||
funding: independent(() =>
|
||||
calculateFundingGap(
|
||||
snapshot.funding.total,
|
||||
snapshot.funding.secured,
|
||||
),
|
||||
),
|
||||
};
|
||||
}
|
||||
@@ -72,6 +72,7 @@ export type Filters = {
|
||||
};
|
||||
|
||||
export type InterestFormData = {
|
||||
declared_origin_country_code?: string;
|
||||
name: string;
|
||||
email: string;
|
||||
phone: string;
|
||||
@@ -195,6 +196,7 @@ export function newSubmissionKey(): string {
|
||||
export function fieldErrors(error: PortalApiError): FormErrors {
|
||||
const result: FormErrors = {};
|
||||
const fields: (keyof InterestFormData)[] = [
|
||||
'declared_origin_country_code',
|
||||
'name',
|
||||
'email',
|
||||
'phone',
|
||||
|
||||
@@ -3,6 +3,7 @@ import { router } from '@inertiajs/react';
|
||||
import { PortalMenu } from '@/layouts/portal-navigation';
|
||||
import { ProvinceSelect } from '@/components/investment-territory';
|
||||
import { MATURITY_LEVELS } from '@/lib/investment-maturity';
|
||||
import CountrySelect, { type Country } from '@/components/country-select';
|
||||
import type { Dispatch, FormEvent, ReactNode, SetStateAction } from 'react';
|
||||
import type { LucideIcon } from 'lucide-react';
|
||||
import { usePortalQuery } from '@/hooks/use-portal-query';
|
||||
@@ -668,9 +669,11 @@ function OpportunityDetail({
|
||||
function InterestForm({
|
||||
preselected,
|
||||
onSubmitted,
|
||||
countries,
|
||||
}: {
|
||||
preselected: Opportunity | null;
|
||||
onSubmitted: () => void;
|
||||
countries: Country[];
|
||||
}) {
|
||||
const sectors = useContext(SectorContext);
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
@@ -682,7 +685,8 @@ function InterestForm({
|
||||
email: '',
|
||||
phone: '',
|
||||
investorType: '',
|
||||
country: 'Moçambique',
|
||||
country: '',
|
||||
declared_origin_country_code: '',
|
||||
sectorInterest: preselected?.sectorName ?? '',
|
||||
opportunityReference: preselected ? preselected.reference : '',
|
||||
investmentRange: '',
|
||||
@@ -857,13 +861,32 @@ function InterestForm({
|
||||
</Field>
|
||||
|
||||
<Field label="País" error={errors.country}>
|
||||
<input
|
||||
className="input"
|
||||
<CountrySelect
|
||||
countries={countries}
|
||||
value={form.country}
|
||||
onChange={(e) => update('country', e.target.value)}
|
||||
onChange={(value) => update('country', value)}
|
||||
required
|
||||
allowLegacyValue
|
||||
/>
|
||||
</Field>
|
||||
|
||||
<Field
|
||||
label="País de origem declarado desta solicitação"
|
||||
error={errors.declared_origin_country_code}
|
||||
>
|
||||
<CountrySelect
|
||||
countries={countries}
|
||||
value={form.declared_origin_country_code ?? ''}
|
||||
onChange={(value) =>
|
||||
update('declared_origin_country_code', value)
|
||||
}
|
||||
/>
|
||||
<p className="text-sm">
|
||||
Origem opcional; não é deduzida do país acima nem do
|
||||
IP.
|
||||
</p>
|
||||
</Field>
|
||||
|
||||
<Field
|
||||
label="Sector de interesse"
|
||||
error={errors.sectorInterest}
|
||||
@@ -1013,12 +1036,14 @@ export default function PortalInvestidorApp({
|
||||
initialSector = '',
|
||||
initialQuery = '',
|
||||
essentialResources = [],
|
||||
countries = [],
|
||||
}: {
|
||||
initialView?: View;
|
||||
initialOpportunity?: OpportunityRecord;
|
||||
initialSector?: string;
|
||||
initialQuery?: string;
|
||||
essentialResources?: { id: number; title: string }[];
|
||||
countries?: Country[];
|
||||
}) {
|
||||
const view = initialView;
|
||||
const home = usePortalQuery<HomeResponse>('/api/v1/home');
|
||||
@@ -1299,6 +1324,7 @@ export default function PortalInvestidorApp({
|
||||
<InterestForm
|
||||
key={selected?.reference ?? 'general'}
|
||||
preselected={selected}
|
||||
countries={countries}
|
||||
onSubmitted={() => setRequestCount((c) => c + 1)}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Form, Head } from '@inertiajs/react';
|
||||
import { Form, Head, usePage } from '@inertiajs/react';
|
||||
import InputError from '@/components/input-error';
|
||||
import PasswordInput from '@/components/password-input';
|
||||
import TextLink from '@/components/text-link';
|
||||
@@ -19,13 +19,32 @@ import PasskeyVerify from '@/components/passkey-verify';
|
||||
type Props = {
|
||||
status?: string;
|
||||
canResetPassword: boolean;
|
||||
qaAccount?: { id: number; email: string };
|
||||
};
|
||||
|
||||
export default function Login({ status, canResetPassword }: Props) {
|
||||
export default function Login({ status, canResetPassword, qaAccount }: Props) {
|
||||
// A redirect from another page (e.g. MFA) creates a new Form with empty local errors.
|
||||
const pageErrors = usePage<{ errors: { email?: string } }>().props.errors;
|
||||
return (
|
||||
<>
|
||||
<Head title="Log in" />
|
||||
|
||||
{qaAccount && (
|
||||
<aside
|
||||
className="mb-4 rounded border border-amber-300 bg-amber-50 p-3 text-sm text-slate-900"
|
||||
aria-label="Conta de ensaio QA"
|
||||
>
|
||||
<p className="font-semibold">
|
||||
Ambiente QA — conta {qaAccount.id}
|
||||
</p>
|
||||
<p>
|
||||
Para os cenários A/B: {qaAccount.email}. Use a password e
|
||||
o autenticador desta conta. Outros perfis devem usar as
|
||||
respetivas contas sintéticas QA.
|
||||
</p>
|
||||
</aside>
|
||||
)}
|
||||
|
||||
{/* @chisel-passkeys */}
|
||||
<PasskeyVerify />
|
||||
{/* @end-chisel-passkeys */}
|
||||
@@ -49,8 +68,11 @@ export default function Login({ status, canResetPassword }: Props) {
|
||||
tabIndex={1}
|
||||
autoComplete="email"
|
||||
placeholder="email@example.com"
|
||||
defaultValue={qaAccount?.email}
|
||||
/>
|
||||
<InputError
|
||||
message={errors.email ?? pageErrors.email}
|
||||
/>
|
||||
<InputError message={errors.email} />
|
||||
</div>
|
||||
|
||||
<div className="grid gap-2">
|
||||
|
||||
@@ -12,7 +12,11 @@ import {
|
||||
import { OTP_MAX_LENGTH } from '@/hooks/use-two-factor-auth';
|
||||
import { store } from '@/routes/two-factor/login';
|
||||
|
||||
export default function TwoFactorChallenge() {
|
||||
export default function TwoFactorChallenge({
|
||||
qaAccount,
|
||||
}: {
|
||||
qaAccount?: { id: number; email: string };
|
||||
}) {
|
||||
const [showRecoveryInput, setShowRecoveryInput] = useState<boolean>(false);
|
||||
const [code, setCode] = useState<string>('');
|
||||
|
||||
@@ -53,6 +57,16 @@ export default function TwoFactorChallenge() {
|
||||
<>
|
||||
<Head title="Two-factor authentication" />
|
||||
|
||||
{qaAccount && (
|
||||
<p
|
||||
className="mb-4 rounded border border-amber-300 bg-amber-50 p-3 text-sm text-slate-900"
|
||||
role="status"
|
||||
>
|
||||
MFA da conta QA {qaAccount.id}: {qaAccount.email}. Confirme
|
||||
com o autenticador desta conta.
|
||||
</p>
|
||||
)}
|
||||
|
||||
<div className="space-y-6">
|
||||
<Form
|
||||
{...store.form()}
|
||||
|
||||
@@ -23,6 +23,7 @@ export default function Leads({
|
||||
originStatistics: {
|
||||
interests: { code: string | null; name: string; count: number }[];
|
||||
desk: { code: string | null; name: string; count: number }[];
|
||||
businesses: { code: string | null; name: string; count: number }[];
|
||||
};
|
||||
}) {
|
||||
const form = useForm({
|
||||
@@ -91,12 +92,14 @@ export default function Leads({
|
||||
Este filtro aplica-se apenas às contagens de solicitações. A
|
||||
lista de leads mantém os filtros abaixo.
|
||||
</p>
|
||||
{(['interests', 'desk'] as const).map((group) => (
|
||||
{(['interests', 'desk', 'businesses'] as const).map((group) => (
|
||||
<section key={group}>
|
||||
<h2>
|
||||
{group === 'interests'
|
||||
? 'Manifestações recebidas'
|
||||
: 'Pedidos do Balcão em acompanhamento'}
|
||||
: group === 'desk'
|
||||
? 'Pedidos do Balcão em acompanhamento'
|
||||
: 'Negócios submetidos (rascunhos excluídos)'}
|
||||
</h2>
|
||||
{originStatistics[group].length ? (
|
||||
<ul>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Head, Link } from '@inertiajs/react';
|
||||
import { dashboard } from '@/routes';
|
||||
import type { InvestmentContext } from '@/pages/investor-path/index';
|
||||
|
||||
type Summary = {
|
||||
requestsByStatus: Record<string, number>;
|
||||
@@ -23,7 +24,23 @@ const states: Record<string, string> = {
|
||||
const card =
|
||||
'rounded-xl border p-5 transition-colors hover:bg-muted focus-visible:outline-2 focus-visible:outline-primary';
|
||||
|
||||
export default function Dashboard({ summary }: { summary: Summary | null }) {
|
||||
export default function Dashboard({
|
||||
summary,
|
||||
investorPath,
|
||||
}: {
|
||||
summary: Summary | null;
|
||||
investorPath?: {
|
||||
contexts: InvestmentContext[];
|
||||
current: {
|
||||
id: string;
|
||||
next: { code: string; title: string } | null;
|
||||
pending: number;
|
||||
documents: number;
|
||||
results: number;
|
||||
tasks: number;
|
||||
} | null;
|
||||
} | null;
|
||||
}) {
|
||||
return (
|
||||
<main className="space-y-8 p-4 md:p-8">
|
||||
<Head title="Painel" />
|
||||
@@ -160,6 +177,60 @@ export default function Dashboard({ summary }: { summary: Summary | null }) {
|
||||
</Link>
|
||||
</nav>
|
||||
</>
|
||||
) : investorPath ? (
|
||||
<section className="space-y-4 rounded-xl border p-6">
|
||||
<h2 className="text-lg font-semibold">
|
||||
Os meus investimentos
|
||||
</h2>
|
||||
{investorPath.current && (
|
||||
<div className="space-y-2">
|
||||
<p>
|
||||
{investorPath.current.pending} etapas pendentes
|
||||
· {investorPath.current.documents} documentos ·{' '}
|
||||
{investorPath.current.results} resultados ·{' '}
|
||||
{investorPath.current.tasks} tarefas
|
||||
</p>
|
||||
{investorPath.current.next && (
|
||||
<Link
|
||||
className="underline"
|
||||
href={`/investimentos/${investorPath.current.id}#${investorPath.current.next.code}`}
|
||||
>
|
||||
Próxima acção:{' '}
|
||||
{investorPath.current.next.code} ·{' '}
|
||||
{investorPath.current.next.title}
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{investorPath.contexts.map((item, index) => (
|
||||
<div className="rounded border p-4" key={item.id}>
|
||||
<p>
|
||||
{index === 0
|
||||
? 'Investimento actualizado mais recentemente'
|
||||
: 'Outro investimento'}
|
||||
</p>
|
||||
<Link
|
||||
className="font-semibold underline"
|
||||
href={`/investimentos/${item.id}`}
|
||||
>
|
||||
{item.title}
|
||||
</Link>
|
||||
<p>
|
||||
Percurso, pendências, documentos, resultados e
|
||||
próxima acção no dossier.
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
{!investorPath.contexts.length && (
|
||||
<p>
|
||||
Comece pela sua ideia e prepare as etapas ao seu
|
||||
ritmo.
|
||||
</p>
|
||||
)}
|
||||
<Link className="underline" href="/investimentos">
|
||||
Preparar ou escolher um investimento
|
||||
</Link>
|
||||
</section>
|
||||
) : (
|
||||
<section className="max-w-2xl space-y-4 rounded-xl border p-6">
|
||||
<h2 className="text-lg font-semibold">
|
||||
|
||||
@@ -13,6 +13,10 @@ export default function Install({
|
||||
scanner,
|
||||
rollback,
|
||||
databaseReady,
|
||||
baseDeskInstalled,
|
||||
pathInstalled,
|
||||
pathEnabled,
|
||||
pathQaVerified,
|
||||
}: {
|
||||
hash: string;
|
||||
installed: boolean;
|
||||
@@ -26,6 +30,10 @@ export default function Install({
|
||||
scanner: { available: boolean; reason_code: string | null };
|
||||
rollback: string;
|
||||
databaseReady: boolean;
|
||||
baseDeskInstalled: boolean;
|
||||
pathInstalled: boolean;
|
||||
pathEnabled: boolean;
|
||||
pathQaVerified: boolean;
|
||||
}) {
|
||||
const form = useForm({ hash, confirm: false });
|
||||
const service = useForm({ code: 'project-preparation', confirm: false });
|
||||
@@ -51,10 +59,18 @@ export default function Install({
|
||||
))}
|
||||
</ul>
|
||||
<p>
|
||||
Serão criadas as tabelas internas do Balcão; acrescentadas
|
||||
associações opcionais ao dossier e às tarefas existentes.
|
||||
Não se migram ou apagam pedidos anteriores, não se publicam
|
||||
serviços nem se enviam dados externos.
|
||||
Balcão existente:{' '}
|
||||
{baseDeskInstalled ? 'Instalado' : 'Pendente'}. Apenas as
|
||||
migrations ausentes serão executadas; nenhuma instalação já
|
||||
registada será repetida.
|
||||
</p>
|
||||
<p>
|
||||
Extensão do percurso:{' '}
|
||||
{pathInstalled ? 'Instalada' : 'Pendente'}.
|
||||
Disponibilização:{' '}
|
||||
{pathEnabled ? 'Configurada' : 'Desativada'}. Instalar não
|
||||
disponibiliza o percurso, não converte dossiers antigos nem
|
||||
apaga dados ou publica serviços.
|
||||
</p>
|
||||
<ul>
|
||||
{changes.map((c) => (
|
||||
@@ -70,6 +86,13 @@ export default function Install({
|
||||
Compatibilidade e reversão em cópia restaurada:{' '}
|
||||
{compatibilityVerified ? 'Verificadas' : 'Pendentes'}.
|
||||
</p>
|
||||
<p>
|
||||
Percursos A/B completos na interface desta versão:{' '}
|
||||
{pathQaVerified
|
||||
? 'Demonstrados'
|
||||
: 'Pendentes — API ou build não substituem a demonstração visual'}
|
||||
.
|
||||
</p>
|
||||
<p>
|
||||
Permissões da conexão para criar o esquema e estender
|
||||
tarefas:{' '}
|
||||
@@ -120,6 +143,7 @@ export default function Install({
|
||||
!backupVerified ||
|
||||
!qaVerified ||
|
||||
!compatibilityVerified ||
|
||||
!pathQaVerified ||
|
||||
!databaseReady
|
||||
}
|
||||
>
|
||||
@@ -132,7 +156,7 @@ export default function Install({
|
||||
))}
|
||||
</form>
|
||||
)}
|
||||
{installed && (
|
||||
{baseDeskInstalled && (
|
||||
<form
|
||||
className={card + ' space-y-3'}
|
||||
onSubmit={(e) => {
|
||||
|
||||
@@ -67,9 +67,16 @@ export default function Panel({
|
||||
journey_id: ['Percurso territorial existente', journeys],
|
||||
} as const;
|
||||
const derivedTitle = useRef('');
|
||||
const contextTitle = journeys.find((item) => item.id === form.data.journey_id)?.name ?? submissions.find((item) => item.id === form.data.submission_id)?.name ?? companies.find((item) => item.id === form.data.company_id)?.name ?? '';
|
||||
const contextTitle =
|
||||
journeys.find((item) => item.id === form.data.journey_id)?.name ??
|
||||
submissions.find((item) => item.id === form.data.submission_id)?.name ??
|
||||
companies.find((item) => item.id === form.data.company_id)?.name ??
|
||||
'';
|
||||
useEffect(() => {
|
||||
if ((!form.data.title || form.data.title === derivedTitle.current) && contextTitle) {
|
||||
if (
|
||||
(!form.data.title || form.data.title === derivedTitle.current) &&
|
||||
contextTitle
|
||||
) {
|
||||
form.setData('title', contextTitle.slice(0, 200));
|
||||
derivedTitle.current = contextTitle.slice(0, 200);
|
||||
}
|
||||
@@ -110,7 +117,12 @@ export default function Panel({
|
||||
</section>
|
||||
<details className={card}>
|
||||
<summary>Preparar acompanhamento de um projecto</summary>
|
||||
<p>Selecione um percurso ou investimento da sua conta. O título é recuperado do registo existente quando disponível; pode corrigi-lo antes de guardar. A associação requer a sua autorização abaixo.</p>
|
||||
<p>
|
||||
Selecione um percurso ou investimento da sua conta. O título
|
||||
é recuperado do registo existente quando disponível; pode
|
||||
corrigi-lo antes de guardar. A associação requer a sua
|
||||
autorização abaixo.
|
||||
</p>
|
||||
<form
|
||||
className="mt-4 space-y-3"
|
||||
onSubmit={(e) => {
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { Link, useForm } from '@inertiajs/react';
|
||||
import { Frame, card, input, button } from '@/pages/investment/shared';
|
||||
import CountrySelect, { type Country } from '@/components/country-select';
|
||||
import {
|
||||
TerritoryFields,
|
||||
type TerritoryOption,
|
||||
} from '@/components/investment-territory';
|
||||
import {
|
||||
DocumentReview,
|
||||
RequestOperations,
|
||||
@@ -28,7 +32,7 @@ export default function RequestPage({
|
||||
findings,
|
||||
messages,
|
||||
analysts,
|
||||
territories,
|
||||
territoryPaths,
|
||||
events,
|
||||
documents,
|
||||
payments,
|
||||
@@ -71,7 +75,7 @@ export default function RequestPage({
|
||||
created_at: string;
|
||||
}[];
|
||||
analysts: { id: number; name: string }[];
|
||||
territories: { id: string; name: string }[];
|
||||
territoryPaths: Record<string, TerritoryOption[]>;
|
||||
documents: DeskDocument[];
|
||||
payments: DeskPayment[];
|
||||
caseVersion: number;
|
||||
@@ -168,97 +172,182 @@ export default function RequestPage({
|
||||
form.put(`/balcao-virtual/pedidos/${request.id}`);
|
||||
}}
|
||||
>
|
||||
<label className="block" htmlFor="declared-origin-country">País de origem declarado desta solicitação</label>
|
||||
<CountrySelect id="declared-origin-country" countries={countries} value={form.data.payload.declared_origin_country_code ?? ''} disabled={!canEdit || form.processing || (request.status === 'returned' && !request.editable_fields.includes('declared_origin_country_code'))} onChange={(value) => form.setData('payload', { ...form.data.payload, declared_origin_country_code: value })} />
|
||||
<p>A origem não é deduzida do IP nem do país de residência. Pedidos antigos sem declaração mantêm “não informado”.</p>
|
||||
{form.errors['payload.declared_origin_country_code'] && <p role="alert">{form.errors['payload.declared_origin_country_code']}</p>}
|
||||
<label className="block" htmlFor="request-country">
|
||||
País do requerente (opcional)
|
||||
</label>
|
||||
<CountrySelect
|
||||
id="request-country"
|
||||
countries={countries}
|
||||
value={form.data.payload.country ?? ''}
|
||||
allowLegacyValue
|
||||
onChange={(value) =>
|
||||
form.setData('payload', {
|
||||
...form.data.payload,
|
||||
country: value,
|
||||
})
|
||||
}
|
||||
disabled={
|
||||
!canEdit ||
|
||||
(request.status === 'returned' &&
|
||||
!request.editable_fields.includes('country'))
|
||||
}
|
||||
/>
|
||||
{form.errors['payload.country'] && (
|
||||
<p role="alert">{form.errors['payload.country']}</p>
|
||||
)}
|
||||
<label className="block" htmlFor="declared-origin-country">
|
||||
País de origem declarado desta solicitação
|
||||
</label>
|
||||
<CountrySelect
|
||||
id="declared-origin-country"
|
||||
countries={countries}
|
||||
value={form.data.payload.declared_origin_country_code ?? ''}
|
||||
disabled={
|
||||
!canEdit ||
|
||||
form.processing ||
|
||||
(request.status === 'returned' &&
|
||||
!request.editable_fields.includes(
|
||||
'declared_origin_country_code',
|
||||
))
|
||||
}
|
||||
onChange={(value) =>
|
||||
form.setData('payload', {
|
||||
...form.data.payload,
|
||||
declared_origin_country_code: value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<p>
|
||||
A origem não é deduzida do IP nem do país de residência.
|
||||
Pedidos antigos sem declaração mantêm “não informado”.
|
||||
</p>
|
||||
{form.errors['payload.declared_origin_country_code'] && (
|
||||
<p role="alert">
|
||||
{form.errors['payload.declared_origin_country_code']}
|
||||
</p>
|
||||
)}
|
||||
{Object.entries(definition.fields)
|
||||
.filter(
|
||||
([, f]) =>
|
||||
!f.when ||
|
||||
form.data.payload[f.when.field] === f.when.equals,
|
||||
)
|
||||
.map(([key, f]) => (
|
||||
<label className="block" key={key}>
|
||||
{f.label}
|
||||
{f.required ? ' *' : ''}
|
||||
{f.type === 'select' || f.type === 'territory' ? (
|
||||
<select
|
||||
className={input}
|
||||
.map(([key, f]) =>
|
||||
f.type === 'territory' ? (
|
||||
<fieldset
|
||||
key={key}
|
||||
className="space-y-2 rounded border p-3"
|
||||
>
|
||||
<legend>
|
||||
{f.label}
|
||||
{f.required ? ' *' : ''}
|
||||
</legend>
|
||||
<TerritoryFields
|
||||
initial={territoryPaths[key]}
|
||||
disabled={
|
||||
!canEdit ||
|
||||
form.processing ||
|
||||
(request.status === 'returned' &&
|
||||
!request.editable_fields.includes(
|
||||
key,
|
||||
))
|
||||
}
|
||||
value={form.data.payload[key] ?? ''}
|
||||
onChange={(e) =>
|
||||
onChange={(path) =>
|
||||
form.setData('payload', {
|
||||
...form.data.payload,
|
||||
[key]: e.target.value,
|
||||
})
|
||||
}
|
||||
>
|
||||
<option value="">Por preencher</option>
|
||||
{(f.type === 'territory'
|
||||
? territories.map((t) => [t.id, t.name])
|
||||
: Object.entries(f.options ?? {})
|
||||
).map(([v, l]) => (
|
||||
<option key={v} value={v}>
|
||||
{l}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
) : f.type === 'textarea' ? (
|
||||
<textarea
|
||||
className={input}
|
||||
disabled={
|
||||
!canEdit ||
|
||||
(request.status === 'returned' &&
|
||||
!request.editable_fields.includes(
|
||||
key,
|
||||
))
|
||||
}
|
||||
value={form.data.payload[key] ?? ''}
|
||||
onChange={(e) =>
|
||||
form.setData('payload', {
|
||||
...form.data.payload,
|
||||
[key]: e.target.value,
|
||||
[key]: path.at(-1)?.id ?? '',
|
||||
})
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<input
|
||||
type={
|
||||
f.type === 'date'
|
||||
? 'date'
|
||||
: f.type === 'number'
|
||||
? 'number'
|
||||
: 'text'
|
||||
}
|
||||
step={
|
||||
f.type === 'number' ? '0.01' : undefined
|
||||
}
|
||||
className={input}
|
||||
disabled={
|
||||
!canEdit ||
|
||||
(request.status === 'returned' &&
|
||||
!request.editable_fields.includes(
|
||||
key,
|
||||
))
|
||||
}
|
||||
value={form.data.payload[key] ?? ''}
|
||||
onChange={(e) =>
|
||||
form.setData('payload', {
|
||||
...form.data.payload,
|
||||
[key]: e.target.value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</label>
|
||||
))}
|
||||
{form.errors[`payload.${key}`] && (
|
||||
<p role="alert">
|
||||
{form.errors[`payload.${key}`]}
|
||||
</p>
|
||||
)}
|
||||
</fieldset>
|
||||
) : (
|
||||
<label className="block" key={key}>
|
||||
{f.label}
|
||||
{f.required ? ' *' : ''}
|
||||
{f.type === 'select' ? (
|
||||
<select
|
||||
className={input}
|
||||
disabled={
|
||||
!canEdit ||
|
||||
(request.status === 'returned' &&
|
||||
!request.editable_fields.includes(
|
||||
key,
|
||||
))
|
||||
}
|
||||
value={form.data.payload[key] ?? ''}
|
||||
onChange={(e) =>
|
||||
form.setData('payload', {
|
||||
...form.data.payload,
|
||||
[key]: e.target.value,
|
||||
})
|
||||
}
|
||||
>
|
||||
<option value="">Por preencher</option>
|
||||
{Object.entries(f.options ?? {}).map(
|
||||
([v, l]) => (
|
||||
<option key={v} value={v}>
|
||||
{l}
|
||||
</option>
|
||||
),
|
||||
)}
|
||||
</select>
|
||||
) : f.type === 'textarea' ? (
|
||||
<textarea
|
||||
className={input}
|
||||
disabled={
|
||||
!canEdit ||
|
||||
(request.status === 'returned' &&
|
||||
!request.editable_fields.includes(
|
||||
key,
|
||||
))
|
||||
}
|
||||
value={form.data.payload[key] ?? ''}
|
||||
onChange={(e) =>
|
||||
form.setData('payload', {
|
||||
...form.data.payload,
|
||||
[key]: e.target.value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<input
|
||||
type={
|
||||
f.type === 'date'
|
||||
? 'date'
|
||||
: f.type === 'number'
|
||||
? 'number'
|
||||
: 'text'
|
||||
}
|
||||
step={
|
||||
f.type === 'number'
|
||||
? '0.01'
|
||||
: undefined
|
||||
}
|
||||
className={input}
|
||||
disabled={
|
||||
!canEdit ||
|
||||
(request.status === 'returned' &&
|
||||
!request.editable_fields.includes(
|
||||
key,
|
||||
))
|
||||
}
|
||||
value={form.data.payload[key] ?? ''}
|
||||
onChange={(e) =>
|
||||
form.setData('payload', {
|
||||
...form.data.payload,
|
||||
[key]: e.target.value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</label>
|
||||
),
|
||||
)}
|
||||
{canEdit && (
|
||||
<>
|
||||
<label>
|
||||
@@ -368,7 +457,13 @@ export default function RequestPage({
|
||||
{decision.data.status === 'returned' && (
|
||||
<fieldset>
|
||||
<legend>Campos autorizados para correcção</legend>
|
||||
{Object.entries(definition.fields).map(([k, f]) => (
|
||||
{Object.entries({
|
||||
...definition.fields,
|
||||
country: { label: 'País do requerente' },
|
||||
declared_origin_country_code: {
|
||||
label: 'Origem declarada da solicitação',
|
||||
},
|
||||
}).map(([k, f]) => (
|
||||
<label className="block" key={k}>
|
||||
<input
|
||||
type="checkbox"
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Link } from '@inertiajs/react';
|
||||
import type { FormEvent } from 'react';
|
||||
import { newSubmissionKey } from '@/lib/portal-api';
|
||||
import { Frame, Field, button, card, input } from './shared';
|
||||
import CountrySelect, { type Country } from '@/components/country-select';
|
||||
|
||||
type Opportunity = {
|
||||
id: string;
|
||||
@@ -10,8 +11,14 @@ type Opportunity = {
|
||||
title: string;
|
||||
sector?: { name: string } | null;
|
||||
};
|
||||
type Props = { record: Opportunity; modalities: string[]; returnUrl?: string };
|
||||
type Props = {
|
||||
record: Opportunity;
|
||||
modalities: string[];
|
||||
returnUrl?: string;
|
||||
countries: Country[];
|
||||
};
|
||||
type Form = {
|
||||
declared_origin_country_code: string;
|
||||
fullName: string;
|
||||
email: string;
|
||||
phone: string;
|
||||
@@ -29,13 +36,15 @@ export default function BusinessInterest({
|
||||
record,
|
||||
modalities,
|
||||
returnUrl = '/negocios',
|
||||
countries,
|
||||
}: Props) {
|
||||
const [form, setForm] = useState<Form>({
|
||||
declared_origin_country_code: '',
|
||||
fullName: '',
|
||||
email: '',
|
||||
phone: '',
|
||||
investorType: 'empresa',
|
||||
country: 'MZ',
|
||||
country: '',
|
||||
sectorInterest: record.sector?.name ?? '',
|
||||
modality: modalities[0] ?? '',
|
||||
investmentRange: '',
|
||||
@@ -114,6 +123,19 @@ export default function BusinessInterest({
|
||||
</section>
|
||||
) : (
|
||||
<form className={`${card} space-y-4`} onSubmit={submit}>
|
||||
<Field label="País de origem declarado desta solicitação">
|
||||
<CountrySelect
|
||||
countries={countries}
|
||||
value={form.declared_origin_country_code}
|
||||
onChange={(value) =>
|
||||
update('declared_origin_country_code', value)
|
||||
}
|
||||
/>
|
||||
<p className="text-sm">
|
||||
Origem opcional e independente do país do
|
||||
investidor.
|
||||
</p>
|
||||
</Field>
|
||||
<Field label="Nome ou denominação">
|
||||
<input
|
||||
className={input}
|
||||
@@ -161,12 +183,12 @@ export default function BusinessInterest({
|
||||
</select>
|
||||
</Field>
|
||||
<Field label="País">
|
||||
<input
|
||||
className={input}
|
||||
<CountrySelect
|
||||
countries={countries}
|
||||
required
|
||||
maxLength={100}
|
||||
allowLegacyValue
|
||||
value={form.country}
|
||||
onChange={(e) => update('country', e.target.value)}
|
||||
onChange={(value) => update('country', value)}
|
||||
/>
|
||||
</Field>
|
||||
<Field label="Sector de interesse">
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { router } from '@inertiajs/react';
|
||||
import CountrySelect, { type Country } from '@/components/country-select';
|
||||
import { Frame, Field, input, button, card, api } from './shared';
|
||||
import type { Business } from './business-types';
|
||||
import { businessModalities } from './business-types';
|
||||
@@ -27,6 +28,7 @@ export type FormSchema = Record<
|
||||
}
|
||||
>;
|
||||
type Props = {
|
||||
countries: Country[];
|
||||
record: Business;
|
||||
modalities: string[];
|
||||
formSchema: FormSchema;
|
||||
@@ -207,6 +209,7 @@ function opportunityTypeFor(modality: string): string {
|
||||
}
|
||||
|
||||
export default function BusinessWizard({
|
||||
countries,
|
||||
record,
|
||||
formSchema,
|
||||
objects,
|
||||
@@ -706,6 +709,18 @@ export default function BusinessWizard({
|
||||
*
|
||||
</span>
|
||||
</span>
|
||||
) : field.type === 'country' ? (
|
||||
<CountrySelect
|
||||
countries={countries}
|
||||
value={payload[key] ?? ''}
|
||||
allowLegacyValue={key === 'country'}
|
||||
onChange={(value) =>
|
||||
update(key, value)
|
||||
}
|
||||
label={
|
||||
english ? field.en : field.pt
|
||||
}
|
||||
/>
|
||||
) : field.type === 'territory' ? (
|
||||
<TerritoryField
|
||||
name={english ? field.en : field.pt}
|
||||
|
||||
@@ -9,8 +9,10 @@ import BusinessVerifications from './business-verifications';
|
||||
import type { BusinessVerification } from './business-verifications';
|
||||
import BusinessWizard from './business-wizard';
|
||||
import type { FormSchema } from './business-wizard';
|
||||
import type { Country } from '@/components/country-select';
|
||||
|
||||
type Props = {
|
||||
countries: Country[];
|
||||
formSchema: FormSchema;
|
||||
sectors: { id: number; name: string }[];
|
||||
record: Business;
|
||||
|
||||
@@ -3,11 +3,14 @@ import { useState } from 'react';
|
||||
import { Frame, Field, input, button, card, api } from './shared';
|
||||
import { businessModalities, businessStates } from './business-types';
|
||||
import type { Business } from './business-types';
|
||||
import CountrySelect, { type Country } from '@/components/country-select';
|
||||
|
||||
export default function Businesses({
|
||||
records,
|
||||
management,
|
||||
modalities,
|
||||
filters,
|
||||
countries,
|
||||
}: {
|
||||
records: {
|
||||
data: Business[];
|
||||
@@ -16,11 +19,15 @@ export default function Businesses({
|
||||
};
|
||||
management: boolean;
|
||||
modalities: string[];
|
||||
countries: Country[];
|
||||
filters: { country?: string; origin?: string };
|
||||
}) {
|
||||
const [title, setTitle] = useState('');
|
||||
const [modality, setModality] = useState(modalities[0]);
|
||||
const [error, setError] = useState('');
|
||||
const [busy, setBusy] = useState(false);
|
||||
const [country, setCountry] = useState(filters.country ?? '');
|
||||
const [origin, setOrigin] = useState(filters.origin ?? '');
|
||||
return (
|
||||
<Frame title={management ? 'Revisão de negócios' : 'Os meus negócios'}>
|
||||
<p>
|
||||
@@ -28,6 +35,43 @@ export default function Businesses({
|
||||
titularidade, validade ou transmissibilidade do negócio, activo
|
||||
ou direito.
|
||||
</p>
|
||||
<form
|
||||
className={`${card} flex flex-wrap gap-3`}
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
router.get(
|
||||
management
|
||||
? '/management/negocios'
|
||||
: '/investidor/negocios',
|
||||
{ country, origin },
|
||||
);
|
||||
}}
|
||||
>
|
||||
<CountrySelect
|
||||
countries={countries}
|
||||
value={country}
|
||||
onChange={setCountry}
|
||||
label="Filtrar país do proponente"
|
||||
/>
|
||||
<label>
|
||||
Origem declarada
|
||||
<select
|
||||
aria-label="Filtrar origem declarada"
|
||||
className={input}
|
||||
value={origin}
|
||||
onChange={(e) => setOrigin(e.target.value)}
|
||||
>
|
||||
<option value="">Todas</option>
|
||||
<option value="unknown">Não informada</option>
|
||||
{countries.map((c) => (
|
||||
<option key={c.code} value={c.code}>
|
||||
{c.name} ({c.code})
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
<button className={button}>Filtrar negócios</button>
|
||||
</form>
|
||||
{!management && (
|
||||
<form
|
||||
className={`${card} space-y-4`}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Link, router, useForm, usePage } from '@inertiajs/react';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import Map from '@/components/interactive-investment-map';
|
||||
import TerritoryGeometryPreview from '@/components/territory-geometry-preview';
|
||||
import type { InvestmentMapArea } from '@/components/interactive-investment-map';
|
||||
import {
|
||||
TerritoryLevel,
|
||||
@@ -98,7 +99,9 @@ export default function Catalogue({
|
||||
{ id: number; title: string; location: string; url: string }[]
|
||||
>([]);
|
||||
const [truncated, setTruncated] = useState(false);
|
||||
const [mapContext, setMapContext] = useState<{ id: string; title: string; kind: string; url: string }[]>([]);
|
||||
const [mapContext, setMapContext] = useState<
|
||||
{ id: string; title: string; kind: string; url: string }[]
|
||||
>([]);
|
||||
const [error, setError] = useState('');
|
||||
const [suggestions, setSuggestions] = useState<
|
||||
{ title: string; slug: string }[]
|
||||
@@ -230,7 +233,14 @@ export default function Catalogue({
|
||||
const dimensionUrl = (dimension: string) => {
|
||||
const params = new URLSearchParams(query());
|
||||
params.set('dimension', dimension);
|
||||
['cluster_id', 'corridor_id', 'zee_id', 'zfi_id', 'park_id', 'project_id'].forEach((key) => params.delete(key));
|
||||
[
|
||||
'cluster_id',
|
||||
'corridor_id',
|
||||
'zee_id',
|
||||
'zfi_id',
|
||||
'park_id',
|
||||
'project_id',
|
||||
].forEach((key) => params.delete(key));
|
||||
params.delete('page');
|
||||
return `${catalogueUrl}?${params}`;
|
||||
};
|
||||
@@ -391,28 +401,39 @@ export default function Catalogue({
|
||||
['zfi_id', 'zfi', 'ZFI'],
|
||||
['park_id', 'industrial_park', 'Parque industrial'],
|
||||
] as const
|
||||
).filter(([field]) => !form.data.dimension || field === `${form.data.dimension}_id` || !!form.data[field]).map(([field, category, label]) => (
|
||||
<Field key={field} label={label}>
|
||||
<select
|
||||
className={input}
|
||||
value={form.data[field]}
|
||||
onChange={(e) =>
|
||||
form.setData(field, e.target.value)
|
||||
}
|
||||
>
|
||||
<option value="">Todos</option>
|
||||
{(references.zones ?? [])
|
||||
.filter(
|
||||
(zone) => zone.category === category,
|
||||
)
|
||||
.map((zone) => (
|
||||
<option key={zone.id} value={zone.id}>
|
||||
{zone.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</Field>
|
||||
))}
|
||||
)
|
||||
.filter(
|
||||
([field]) =>
|
||||
!form.data.dimension ||
|
||||
field === `${form.data.dimension}_id` ||
|
||||
!!form.data[field],
|
||||
)
|
||||
.map(([field, category, label]) => (
|
||||
<Field key={field} label={label}>
|
||||
<select
|
||||
className={input}
|
||||
value={form.data[field]}
|
||||
onChange={(e) =>
|
||||
form.setData(field, e.target.value)
|
||||
}
|
||||
>
|
||||
<option value="">Todos</option>
|
||||
{(references.zones ?? [])
|
||||
.filter(
|
||||
(zone) =>
|
||||
zone.category === category,
|
||||
)
|
||||
.map((zone) => (
|
||||
<option
|
||||
key={zone.id}
|
||||
value={zone.id}
|
||||
>
|
||||
{zone.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</Field>
|
||||
))}
|
||||
{(['clusters', 'corridors', 'projects'] as const).map(
|
||||
(group, index) => {
|
||||
const key = (
|
||||
@@ -429,7 +450,12 @@ export default function Catalogue({
|
||||
'Projecto âncora',
|
||||
] as const
|
||||
)[index];
|
||||
if (form.data.dimension && key !== `${form.data.dimension}_id` && !form.data[key]) return null;
|
||||
if (
|
||||
form.data.dimension &&
|
||||
key !== `${form.data.dimension}_id` &&
|
||||
!form.data[key]
|
||||
)
|
||||
return null;
|
||||
return (
|
||||
<Field key={group} label={label}>
|
||||
<select
|
||||
@@ -1091,11 +1117,47 @@ export default function Catalogue({
|
||||
</div>
|
||||
{error && <p role="alert">{error}</p>}
|
||||
{!error && <Map points={points} areas={areas} />}
|
||||
{['map', 'combined'].includes(view) && !error && mapContext.length > 0 && <section className={card} aria-label="Estruturas territoriais consultáveis">
|
||||
<h2 className="text-xl font-bold">Estruturas territoriais e projetos</h2>
|
||||
<p>Estas fichas continuam consultáveis independentemente de terem coordenadas. A lista não atribui implantação às oportunidades nem cria pontos no mapa. Até 30 fichas por conjunto; refine a localização para pesquisar.</p>
|
||||
<ul>{mapContext.map((record) => <li key={record.id}><Link className="underline" href={record.url}>{record.kind}: {record.title}</Link></li>)}</ul>
|
||||
</section>}
|
||||
{['map', 'combined'].includes(view) && (
|
||||
<TerritoryGeometryPreview
|
||||
territoryId={
|
||||
form.data.locality_id ||
|
||||
form.data.admin_post_id ||
|
||||
form.data.district_id ||
|
||||
form.data.province_id
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{['map', 'combined'].includes(view) &&
|
||||
!error &&
|
||||
mapContext.length > 0 && (
|
||||
<section
|
||||
className={card}
|
||||
aria-label="Estruturas territoriais consultáveis"
|
||||
>
|
||||
<h2 className="text-xl font-bold">
|
||||
Estruturas territoriais e projetos
|
||||
</h2>
|
||||
<p>
|
||||
Estas fichas continuam consultáveis
|
||||
independentemente de terem coordenadas. A lista não
|
||||
atribui implantação às oportunidades nem cria pontos
|
||||
no mapa. Até 30 fichas por conjunto; refine a
|
||||
localização para pesquisar.
|
||||
</p>
|
||||
<ul>
|
||||
{mapContext.map((record) => (
|
||||
<li key={record.id}>
|
||||
<Link
|
||||
className="underline"
|
||||
href={record.url}
|
||||
>
|
||||
{record.kind}: {record.title}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
)}
|
||||
{truncated && (
|
||||
<p role="alert">
|
||||
O mapa atingiu o limite de 1.000 registos; refine os
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { Link, router, usePage } from '@inertiajs/react';
|
||||
import { useState } from 'react';
|
||||
import InvestmentMapPanel from '@/components/investment-map-panel';
|
||||
import { Link, router, usePage } from "@inertiajs/react";
|
||||
import { useState } from "react";
|
||||
import InvestmentMapPanel from "@/components/investment-map-panel";
|
||||
import StructureGeographyPanel, {
|
||||
LocationList,
|
||||
} from '@/components/structure-geography';
|
||||
import PartnershipSourceLinks from '@/components/partnership-source-links';
|
||||
import TerritorialSources from '@/components/territorial-source-evidence';
|
||||
import { Frame, card, button, money, groupLabels } from './shared';
|
||||
import type { Opportunity, Context } from './shared';
|
||||
} from "@/components/structure-geography";
|
||||
import PartnershipSourceLinks from "@/components/partnership-source-links";
|
||||
import TerritorialSources from "@/components/territorial-source-evidence";
|
||||
import { Frame, card, button, money, groupLabels } from "./shared";
|
||||
import type { Opportunity, Context } from "./shared";
|
||||
export default function Detail({
|
||||
record: r,
|
||||
context: c,
|
||||
zone_origin,
|
||||
returnUrl = '/oportunidades',
|
||||
returnUrl = "/oportunidades",
|
||||
dossierOrigin,
|
||||
}: {
|
||||
record: Opportunity;
|
||||
@@ -22,7 +22,7 @@ export default function Detail({
|
||||
dossierOrigin?: { id: string; title: string } | null;
|
||||
}) {
|
||||
const { auth } = usePage<{ auth: { user: unknown } }>().props;
|
||||
const [sharing, setSharing] = useState('');
|
||||
const [sharing, setSharing] = useState("");
|
||||
return (
|
||||
<Frame title={r.title}>
|
||||
<PartnershipSourceLinks type="investment" id={r.id} />
|
||||
@@ -52,7 +52,7 @@ export default function Detail({
|
||||
)}
|
||||
<p className="text-xl">{r.summary}</p>
|
||||
<TerritorialSources sources={c.source_evidence} />
|
||||
<section className={card + ' space-y-3'}>
|
||||
<section className={card + " space-y-3"}>
|
||||
<h2 className="text-xl font-bold">
|
||||
Implantação declarada da oportunidade
|
||||
</h2>
|
||||
@@ -70,15 +70,18 @@ export default function Detail({
|
||||
</p>
|
||||
)}
|
||||
</section>
|
||||
<InvestmentMapPanel filters={{ opportunity_id: r.id }} />
|
||||
<InvestmentMapPanel
|
||||
filters={{ opportunity_id: r.id }}
|
||||
territoryId={c.primary_territory_path?.at(-1)?.id}
|
||||
/>
|
||||
{c.primary_territory_path &&
|
||||
c.primary_territory_path.length > 0 && (
|
||||
<p>
|
||||
Território principal cadastrado (implantação por
|
||||
confirmar):{' '}
|
||||
confirmar):{" "}
|
||||
{c.primary_territory_path
|
||||
.map((node) => node.name)
|
||||
.join(' → ')}
|
||||
.join(" → ")}
|
||||
</p>
|
||||
)}
|
||||
<div className="flex flex-wrap gap-4">
|
||||
@@ -86,12 +89,12 @@ export default function Detail({
|
||||
<button
|
||||
className={button}
|
||||
onClick={() =>
|
||||
router.post('/investidor/manifestacoes', {
|
||||
router.post("/investidor/manifestacoes", {
|
||||
opportunity_id: r.id,
|
||||
...(zone_origin
|
||||
? {
|
||||
zone_id: zone_origin.id,
|
||||
intent: 'interest',
|
||||
intent: "interest",
|
||||
}
|
||||
: {}),
|
||||
})
|
||||
@@ -115,16 +118,16 @@ export default function Detail({
|
||||
onClick={() => {
|
||||
if (!navigator.clipboard) {
|
||||
setSharing(
|
||||
'Copie a ligação na barra de endereço do navegador.',
|
||||
"Copie a ligação na barra de endereço do navegador.",
|
||||
);
|
||||
return;
|
||||
}
|
||||
navigator.clipboard
|
||||
.writeText(window.location.href)
|
||||
.then(() => setSharing('Ligação copiada.'))
|
||||
.then(() => setSharing("Ligação copiada."))
|
||||
.catch(() =>
|
||||
setSharing(
|
||||
'Copie a ligação na barra de endereço do navegador.',
|
||||
"Copie a ligação na barra de endereço do navegador.",
|
||||
),
|
||||
);
|
||||
}}
|
||||
@@ -145,11 +148,11 @@ export default function Detail({
|
||||
href={`/zonas?category=${z.category}&q=${encodeURIComponent(z.name)}`}
|
||||
>
|
||||
{z.name}
|
||||
</Link>{' '}
|
||||
·{' '}
|
||||
{z.association_type === 'official'
|
||||
? 'Associação documental validada'
|
||||
: 'Relação ' + z.association_type}{' '}
|
||||
</Link>{" "}
|
||||
·{" "}
|
||||
{z.association_type === "official"
|
||||
? "Associação documental validada"
|
||||
: "Relação " + z.association_type}{" "}
|
||||
· Fonte: {z.source_reference}
|
||||
</p>
|
||||
))}
|
||||
@@ -161,42 +164,42 @@ export default function Detail({
|
||||
)}
|
||||
<div className="grid gap-6 lg:grid-cols-3">
|
||||
<section
|
||||
className={card + ' whitespace-pre-line lg:col-span-2'}
|
||||
className={card + " whitespace-pre-line lg:col-span-2"}
|
||||
>
|
||||
<h2 className="mb-3 text-xl font-bold">O investimento</h2>
|
||||
{r.description || 'Descrição por completar.'}
|
||||
{r.description || "Descrição por completar."}
|
||||
</section>
|
||||
<dl className={card + ' space-y-4'}>
|
||||
<dl className={card + " space-y-4"}>
|
||||
{[
|
||||
['Promotor', r.promoter_name],
|
||||
['Investimento', money(r)],
|
||||
['Maturidade', r.maturity_label],
|
||||
['Parceria', r.financing_modality],
|
||||
['Impacto', r.expected_impact],
|
||||
['Calendário', c.profile?.target_date],
|
||||
["Promotor", r.promoter_name],
|
||||
["Investimento", money(r)],
|
||||
["Maturidade", r.maturity_label],
|
||||
["Parceria", r.financing_modality],
|
||||
["Impacto", r.expected_impact],
|
||||
["Calendário", c.profile?.target_date],
|
||||
].map(([key, value]) => (
|
||||
<div key={key}>
|
||||
<dt className="font-bold">{key}</dt>
|
||||
<dd>{value || 'Não indicado'}</dd>
|
||||
<dd>{value || "Não indicado"}</dd>
|
||||
</div>
|
||||
))}
|
||||
</dl>
|
||||
</div>
|
||||
{c.profile && (
|
||||
<section className={card + ' space-y-4'}>
|
||||
<section className={card + " space-y-4"}>
|
||||
<h2 className="text-xl font-bold">
|
||||
Viabilidade e preparação
|
||||
</h2>
|
||||
{[
|
||||
['Modelo de negócio', c.profile.business_model],
|
||||
['Requisitos', c.profile.requirements],
|
||||
['Riscos', c.profile.risks],
|
||||
['Fonte', c.profile.source_reference],
|
||||
["Modelo de negócio", c.profile.business_model],
|
||||
["Requisitos", c.profile.requirements],
|
||||
["Riscos", c.profile.risks],
|
||||
["Fonte", c.profile.source_reference],
|
||||
].map(([label, text]) => (
|
||||
<div key={label}>
|
||||
<h3 className="font-bold">{label}</h3>
|
||||
<p className="whitespace-pre-line">
|
||||
{text || 'Não indicado'}
|
||||
{text || "Não indicado"}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
@@ -209,16 +212,16 @@ export default function Detail({
|
||||
)}
|
||||
<section className="grid gap-4 md:grid-cols-4">
|
||||
{(
|
||||
['clusters', 'corridors', 'projects', 'locations'] as const
|
||||
["clusters", "corridors", "projects", "locations"] as const
|
||||
).map((key, i) => (
|
||||
<div className={card} key={key}>
|
||||
<h2 className="font-bold">
|
||||
{
|
||||
[
|
||||
'Clusters',
|
||||
'Corredores',
|
||||
'Projectos âncora',
|
||||
'Territórios',
|
||||
"Clusters",
|
||||
"Corredores",
|
||||
"Projectos âncora",
|
||||
"Territórios",
|
||||
][i]
|
||||
}
|
||||
</h2>
|
||||
@@ -238,14 +241,14 @@ export default function Detail({
|
||||
<Link
|
||||
className="underline"
|
||||
href={
|
||||
'/oportunidades?' +
|
||||
"/oportunidades?" +
|
||||
[
|
||||
'cluster_id',
|
||||
'corridor_id',
|
||||
'project_id',
|
||||
'geo_location_id',
|
||||
"cluster_id",
|
||||
"corridor_id",
|
||||
"project_id",
|
||||
"geo_location_id",
|
||||
][i] +
|
||||
'=' +
|
||||
"=" +
|
||||
entity.id
|
||||
}
|
||||
>
|
||||
@@ -257,7 +260,7 @@ export default function Detail({
|
||||
</div>
|
||||
))}
|
||||
</section>
|
||||
{(['projects', 'clusters'] as const).flatMap((key) =>
|
||||
{(["projects", "clusters"] as const).flatMap((key) =>
|
||||
c[key]
|
||||
.filter(
|
||||
(entity) => entity.geography && entity.dossiers?.length,
|
||||
@@ -266,7 +269,7 @@ export default function Detail({
|
||||
<StructureGeographyPanel
|
||||
key={`${key}-${entity.id}`}
|
||||
geography={entity.geography!}
|
||||
cluster={key === 'clusters'}
|
||||
cluster={key === "clusters"}
|
||||
dossierId={entity.dossiers![0].id}
|
||||
/>
|
||||
)),
|
||||
|
||||
@@ -127,7 +127,10 @@ function Editor({
|
||||
const form = useForm({
|
||||
version: record.version,
|
||||
payload: Object.fromEntries(
|
||||
[...fields, 'country'].map((key) => [key, record.payload[key] ?? '']),
|
||||
[...fields, 'country'].map((key) => [
|
||||
key,
|
||||
record.payload[key] ?? '',
|
||||
]),
|
||||
),
|
||||
});
|
||||
return (
|
||||
@@ -146,33 +149,56 @@ function Editor({
|
||||
}}
|
||||
>
|
||||
<div className="grid gap-4 md:grid-cols-2">
|
||||
{record.payload.country && <p>País anteriormente registado: {record.payload.country}. Conservado sem atribuir automaticamente residência, constituição ou origem da solicitação.</p>}
|
||||
{record.payload.country && (
|
||||
<p>
|
||||
País anteriormente registado: {record.payload.country}.
|
||||
Conservado sem atribuir automaticamente residência,
|
||||
constituição ou origem da solicitação.
|
||||
</p>
|
||||
)}
|
||||
{fields.map((key) => (
|
||||
<Field key={key} label={labels[key]}>
|
||||
{key.endsWith('_country_code') ? <CountrySelect id={key + (record.id ?? 'account')} countries={countries} value={form.data.payload[key]} onChange={(value) => form.setData('payload', { ...form.data.payload, [key]: value })} /> :
|
||||
<input
|
||||
className={input}
|
||||
value={form.data.payload[key]}
|
||||
required={
|
||||
isCompany &&
|
||||
['name', 'country', 'role'].includes(key)
|
||||
}
|
||||
maxLength={
|
||||
key === 'description' || key === 'experience'
|
||||
? 2000
|
||||
: key === 'investment_capacity'
|
||||
? 1000
|
||||
: 200
|
||||
}
|
||||
onChange={(e) =>
|
||||
form.setData('payload', {
|
||||
...form.data.payload,
|
||||
[key]: e.target.value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
}
|
||||
{form.errors[`payload.${key}`] && <p role="alert" className="text-red-700">{form.errors[`payload.${key}`]}</p>}
|
||||
{key.endsWith('_country_code') ? (
|
||||
<CountrySelect
|
||||
id={key + (record.id ?? 'account')}
|
||||
countries={countries}
|
||||
value={form.data.payload[key]}
|
||||
onChange={(value) =>
|
||||
form.setData('payload', {
|
||||
...form.data.payload,
|
||||
[key]: value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<input
|
||||
className={input}
|
||||
value={form.data.payload[key]}
|
||||
required={
|
||||
isCompany &&
|
||||
['name', 'country', 'role'].includes(key)
|
||||
}
|
||||
maxLength={
|
||||
key === 'description' ||
|
||||
key === 'experience'
|
||||
? 2000
|
||||
: key === 'investment_capacity'
|
||||
? 1000
|
||||
: 200
|
||||
}
|
||||
onChange={(e) =>
|
||||
form.setData('payload', {
|
||||
...form.data.payload,
|
||||
[key]: e.target.value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{form.errors[`payload.${key}`] && (
|
||||
<p role="alert" className="text-red-700">
|
||||
{form.errors[`payload.${key}`]}
|
||||
</p>
|
||||
)}
|
||||
</Field>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -358,12 +358,57 @@ function Editor({
|
||||
{text('full_name', 'Nome completo', true)}
|
||||
{text('email', 'Email', true, 'email')}
|
||||
{text('phone', 'Telefone')}
|
||||
{form.data.payload.country && <p>País anteriormente registado: {form.data.payload.country}. Não foi convertido em residência, constituição ou origem.</p>}
|
||||
{(['residence_country_code', 'incorporation_country_code', 'declared_origin_country_code'] as const).map((key) => <Field key={key} label={{ residence_country_code: 'País de residência', incorporation_country_code: 'País de constituição da entidade', declared_origin_country_code: 'País de origem declarado desta solicitação' }[key]}>
|
||||
<CountrySelect disabled={readonly} id={key} countries={countries} value={form.data.payload[key] ?? ''} onChange={(value) => form.setData('payload', { ...form.data.payload, [key]: value })} />
|
||||
{form.errors[`payload.${key}`] && <p role="alert">{form.errors[`payload.${key}`]}</p>}
|
||||
</Field>)}
|
||||
<p>A origem da solicitação é uma declaração sua; não é deduzida da residência, da entidade ou do endereço IP.</p>
|
||||
{form.data.payload.country && (
|
||||
<p>
|
||||
País anteriormente registado:{' '}
|
||||
{form.data.payload.country}. Não foi convertido
|
||||
em residência, constituição ou origem.
|
||||
</p>
|
||||
)}
|
||||
{(
|
||||
[
|
||||
'residence_country_code',
|
||||
'incorporation_country_code',
|
||||
'declared_origin_country_code',
|
||||
] as const
|
||||
).map((key) => (
|
||||
<Field
|
||||
key={key}
|
||||
label={
|
||||
{
|
||||
residence_country_code:
|
||||
'País de residência',
|
||||
incorporation_country_code:
|
||||
'País de constituição da entidade',
|
||||
declared_origin_country_code:
|
||||
'País de origem declarado desta solicitação',
|
||||
}[key]
|
||||
}
|
||||
>
|
||||
<CountrySelect
|
||||
disabled={readonly}
|
||||
id={key}
|
||||
countries={countries}
|
||||
value={form.data.payload[key] ?? ''}
|
||||
onChange={(value) =>
|
||||
form.setData('payload', {
|
||||
...form.data.payload,
|
||||
[key]: value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
{form.errors[`payload.${key}`] && (
|
||||
<p role="alert">
|
||||
{form.errors[`payload.${key}`]}
|
||||
</p>
|
||||
)}
|
||||
</Field>
|
||||
))}
|
||||
<p>
|
||||
A origem da solicitação é uma declaração sua; não é
|
||||
deduzida da residência, da entidade ou do endereço
|
||||
IP.
|
||||
</p>
|
||||
{option(
|
||||
'profile_id',
|
||||
'investor_profile',
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user