diff --git a/app/Http/Controllers/DemographyController.php b/app/Http/Controllers/DemographyController.php index 4060a4a9..1845e2f3 100644 --- a/app/Http/Controllers/DemographyController.php +++ b/app/Http/Controllers/DemographyController.php @@ -20,11 +20,14 @@ final class DemographyController extends Controller { $data = $request->validate(['territories' => 'nullable|array|max:4', 'territories.*' => 'required|uuid|distinct', 'start_year' => 'nullable|integer|between:1900,2100', 'end_year' => 'nullable|integer|between:1900,2100|gte:start_year', - 'sector' => 'nullable|in:'.implode(',', array_keys(DemographicEvidence::sectors())), 'edition' => 'nullable|uuid']); + 'sector' => 'nullable|in:'.implode(',', array_keys(DemographicEvidence::sectors())), 'edition' => 'nullable|uuid', 'investment_context' => 'nullable|boolean']); $start = (int) ($data['start_year'] ?? date('Y')); $end = (int) ($data['end_year'] ?? $start); abort_unless($end >= $start && $end - $start <= 50, 422, 'Escolha um horizonte até 50 anos.'); $evidence = $service->analyse($data['territories'] ?? [], $start, $end, $data['sector'] ?? 'general', $data['edition'] ?? null); + if (! empty($data['investment_context']) && count($data['territories'] ?? []) === 1) { + $evidence = $service->investmentContext($data['territories'][0], $start, $end, $data['sector'] ?? 'general', $data['edition'] ?? null); + } if ($request->expectsJson()) { return response()->json($evidence); } diff --git a/app/Http/Controllers/FundingProgrammeController.php b/app/Http/Controllers/FundingProgrammeController.php index fba4684d..5ddddd25 100644 --- a/app/Http/Controllers/FundingProgrammeController.php +++ b/app/Http/Controllers/FundingProgrammeController.php @@ -150,31 +150,37 @@ final class FundingProgrammeController extends Controller 'category' => ['nullable', Rule::in(array_keys(FundingInstitutionClassification::CATEGORIES))], 'institution_type' => ['nullable', Rule::in(array_keys(FundingInstitutionClassification::TYPES))], 'location_mode' => 'nullable|in:physical,coverage', 'include_historical' => 'nullable|boolean', 'need' => ['nullable', Rule::in(array_keys(FundingInstitutionDetails::NEEDS))], 'context' => 'nullable|uuid', 'opportunity' => 'nullable|string|max:150', + 'province_id' => 'nullable|uuid', 'district_id' => 'nullable|uuid', 'admin_post_id' => 'nullable|uuid', 'locality_id' => 'nullable|uuid', 'territory' => ['nullable', 'uuid', Rule::in(app(InvestmentGeography::class)->publicReferences()->pluck('id')->all())], 'sector' => ['nullable', 'integer', Rule::in(Sector::choices()->whereNotNull('published_at')->pluck('id')->all())], 'certainty' => 'nullable|in:include_unknown,documented', 'state' => 'nullable|in:open,closed,upcoming,unknown']); $filters = array_filter($filters, fn ($value) => $value !== null && $value !== ''); $dossier = $request->user() && ! empty($filters['context']) ? app(FundingDossierPreparation::class)->context($request->user(), $filters['context'], $filters['opportunity'] ?? null) : null; - if ($dossier && empty($filters['territory']) && $dossier['territory']) { + $explicitLocation = $request->hasAny(['territory', 'province_id', 'district_id', 'admin_post_id', 'locality_id']); + if ($dossier && ! $explicitLocation && empty($filters['territory']) && $dossier['territory']) { $filters['territory'] = $dossier['territory']; } - $query = $service->catalogueQuery($filters); - if (! empty($filters['q'])) { - $term = '%'.str_replace(['\\', '%', '_'], ['\\\\', '\\%', '\\_'], $filters['q']).'%'; - $query->where(fn ($q) => $q->whereRaw("v.payload->>'title' ilike ?", [$term])->orWhereRaw("v.payload->>'summary' ilike ?", [$term])->orWhereRaw("(v.payload->'aliases')::text ilike ?", [$term])->orWhereRaw("EXISTS (SELECT 1 FROM jsonb_array_elements(COALESCE(v.payload->'locations','[]'::jsonb)) l WHERE l->>'label' ilike ? OR l->>'address' ilike ? OR l->>'location_text' ilike ?)", [$term, $term, $term])); + $geography = app(InvestmentGeography::class); + $criteriaErrors = []; + $territorySelection = []; + try { + $filters = $geography->interestSelection($filters); + $territorySelection = ! empty($filters['territory']) ? $geography->path($filters['territory']) : []; + $query = $service->catalogueQuery($filters); + $items = $query->orderByDesc('v.published_at')->orderBy('p.id')->paginate(20, ['p.id', 'p.code', 'v.id as version_id', 'v.version', 'v.payload', 'v.published_at'])->withQueryString(); + } catch (\Illuminate\Validation\ValidationException $error) { + if ($request->expectsJson()) throw $error; + $criteriaErrors = $error->errors(); + $items = new \Illuminate\Pagination\LengthAwarePaginator([], 0, 20, 1, ['path' => '/fundos', 'query' => $request->query()]); } - if (! empty($filters['kind'])) { - $query->whereRaw("v.payload->>'kind' = ?", [$filters['kind']]); - } - $items = $query->orderByDesc('v.published_at')->orderBy('p.id')->paginate(20, ['p.id', 'p.code', 'v.id as version_id', 'v.version', 'v.payload', 'v.published_at'])->withQueryString(); $items->through(function ($row) use ($service, $filters) { $record = $service->present($row); return [...$record, 'filter_explanation' => $service->filterExplanation($record, $filters)]; }); - return tap(Inertia::render('funding/index', ['items' => $items, 'filters' => $filters, 'categories' => FundingInstitutionClassification::CATEGORIES, 'institutionTypes' => FundingInstitutionClassification::TYPES, 'kinds' => FundingProgrammes::KINDS, 'needs' => FundingInstitutionDetails::NEEDS, 'dossier' => $dossier, - 'options' => ['territories' => app(InvestmentGeography::class)->publicReferences()->orderBy('name')->get(['id', 'name']), + return tap(Inertia::render('funding/index', ['criteriaErrors' => $criteriaErrors, 'territorySelection' => $territorySelection, 'categoryTypes' => FundingInstitutionClassification::CATEGORY_TYPES, 'items' => $items, 'filters' => $filters, 'categories' => FundingInstitutionClassification::CATEGORIES, 'institutionTypes' => FundingInstitutionClassification::TYPES, 'kinds' => FundingProgrammes::KINDS, 'needs' => FundingInstitutionDetails::NEEDS, 'dossier' => $dossier, + 'options' => ['territories' => $territorySelection, 'sectors' => Sector::choices()->whereNotNull('published_at')->orderBy('name')->get(['id', 'name'])], 'management' => $service->access($request->user())]) ->toResponse($request), static fn (\Symfony\Component\HttpFoundation\Response $response) => $response->headers->set('Cache-Control', 'private, no-store')); } @@ -183,7 +189,7 @@ final class FundingProgrammeController extends Controller { $request->validate(['context' => 'nullable|uuid', 'opportunity' => 'nullable|string|max:150', 'need' => ['nullable', Rule::in(array_keys(FundingInstitutionDetails::NEEDS))], 'territory' => 'nullable|uuid', 'category' => 'nullable|string|max:80', 'institution_type' => 'nullable|string|max:80', 'location_mode' => 'nullable|in:physical,coverage']); $dossier = $request->user() && $request->filled('context') ? app(FundingDossierPreparation::class)->context($request->user(), $request->string('context')->toString(), $request->query('opportunity')) : null; - if ($dossier && ! $request->filled('territory') && $dossier['territory']) { + if ($dossier && ! $request->has('territory') && $dossier['territory']) { $request->merge(['territory' => $dossier['territory']]); } $record = $service->published($id); @@ -204,7 +210,7 @@ final class FundingProgrammeController extends Controller $saved = $request->user() ? DB::table('funding_programme_interests as i')->join('funding_programme_versions as v', 'v.id', '=', 'i.version_id') ->where('i.programme_id', $id)->where('i.user_id', $request->user()->id)->whereNull('i.removed_at')->first(['v.version', 'i.saved_at']) : null; - return tap(Inertia::render('funding/show', ['record' => $record, 'saved' => $saved, 'authenticated' => $request->user() !== null, 'dossier' => $dossier, 'selection' => [...$request->only(['need', 'territory', 'context', 'opportunity', 'category', 'institution_type', 'location_mode']), 'territory_label' => app(InvestmentGeography::class)->publicReferences()->where('id', $request->query('territory'))->value('name') ?? 'Local por seleccionar'], 'needs' => FundingInstitutionDetails::NEEDS, 'destinations' => $destinations]) + return tap(Inertia::render('funding/show', ['record' => $record, 'saved' => $saved, 'authenticated' => $request->user() !== null, 'dossier' => $dossier, 'selection' => [...$request->only(['q', 'kind', 'sector', 'certainty', 'state', 'include_historical', 'province_id', 'district_id', 'admin_post_id', 'locality_id', 'page', 'need', 'territory', 'context', 'opportunity', 'category', 'institution_type', 'location_mode']), 'territory_label' => app(InvestmentGeography::class)->publicReferences()->where('id', $request->query('territory'))->value('name') ?? 'Local por seleccionar'], 'needs' => FundingInstitutionDetails::NEEDS, 'destinations' => $destinations]) ->toResponse($request), static fn (\Symfony\Component\HttpFoundation\Response $response) => $response->headers->set('Cache-Control', 'private, no-store')); } diff --git a/app/Http/Controllers/InvestmentWorkspaceController.php b/app/Http/Controllers/InvestmentWorkspaceController.php index 97cafe15..258705a3 100644 --- a/app/Http/Controllers/InvestmentWorkspaceController.php +++ b/app/Http/Controllers/InvestmentWorkspaceController.php @@ -12,6 +12,7 @@ use App\Services\InvestmentGeography; use App\Services\InvestmentOpportunityAlerts; use App\Services\InvestmentProfileCommands; use App\Services\InvestmentWorkspace; +use App\Services\VirtualDesk; use App\Services\OpportunityManagement; use App\Services\OrganizationCountry; use App\Services\Procurement; @@ -28,6 +29,8 @@ class InvestmentWorkspaceController extends Controller { public function profile(Request $request, InvestmentWorkspace $workspace): \Symfony\Component\HttpFoundation\Response { + $entry = $request->validate(['dossier' => 'nullable|uuid']); + $continuation = ! empty($entry['dossier']) ? app(VirtualDesk::class)->case($request->user(), $entry['dossier']) : null; $data = ['actorId' => $request->user()->id, 'organizationCountryAvailable' => app(OrganizationCountry::class)->available(), 'organizations' => app(OrganizationCountry::class)->represented($request->user()), '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); @@ -36,6 +39,13 @@ class InvestmentWorkspaceController extends Controller return $company; })]; + $data['continuation'] = $continuation ? ['id' => $continuation->id, 'title' => $continuation->title, 'href' => '/investimentos/'.$continuation->id.'#entidade-promotora'] : null; + $forms = config('company-comparison.forms'); + abort_unless(is_array($forms), 503, 'As formas jurídicas estão temporariamente indisponíveis.'); + $data['legalForms'] = []; + foreach ($forms as $code => $form) { + $data['legalForms'][] = ['value' => $code, 'label' => $form['title']]; + } Inertia::encryptHistory(); $response = $request->expectsJson() ? response()->json($data) : Inertia::render('investment/profile', $data)->toResponse($request); @@ -77,7 +87,8 @@ class InvestmentWorkspaceController extends Controller public function company(Request $request, ?string $id = null): RedirectResponse|JsonResponse { $data = $request->validate(['version' => ['required', 'integer', 'min:0'], 'operation_key' => ['sometimes', 'required', 'uuid'], - 'payload' => ['required', 'array:name,country,incorporation_country_code,registration,sector,role,description'], + 'payload' => ['required', 'array:name,country,incorporation_country_code,registration,legal_form,sector,role,description'], + 'payload.legal_form' => ['nullable', \Illuminate\Validation\Rule::in(array_keys(config('company-comparison.forms')))], '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'], diff --git a/app/Http/Controllers/InvestorContextController.php b/app/Http/Controllers/InvestorContextController.php index e2a394ac..5df189d0 100644 --- a/app/Http/Controllers/InvestorContextController.php +++ b/app/Http/Controllers/InvestorContextController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers; use App\Models\InvestmentSubmission; +use App\Models\Sector; use App\Services\InvestmentComplements; use App\Services\InvestmentCorridorContext; use App\Services\InvestmentGeography; @@ -19,6 +20,27 @@ use Inertia\Response; final class InvestorContextController extends Controller { + /** Explicit choices only; a title never assigns an activity or amount. + * @return array + */ + private function ideaEntry(Request $request): array + { + $entry = $request->validate([ + 'project_title' => 'nullable|string|max:200', + 'sector_id' => 'nullable|integer|exists:sectors,id', + 'sector' => 'nullable|string|max:100|exists:sectors,slug', + 'investment_budget_min' => 'nullable|numeric|min:0', + 'investment_budget_max' => ['nullable', 'numeric', 'min:0', Rule::when($request->filled('investment_budget_min'), 'gte:investment_budget_min')], + 'currency' => 'nullable|regex:/^[A-Z]{3}$/D', + ]); + if (empty($entry['sector_id']) && ! empty($entry['sector'])) { + $entry['sector_id'] = (string) Sector::where('slug', $entry['sector'])->value('id'); + } + unset($entry['sector']); + + return $entry; + } + /** * @return array */ @@ -82,17 +104,21 @@ final class InvestorContextController extends Controller public function options(Request $r, InvestorContext $context): JsonResponse { - $d = $r->validate(['q' => 'nullable|string|max:120']); + $d = $r->validate(['q' => 'nullable|string|max:120', 'sector_id' => 'nullable|integer|exists:sectors,id', 'province_id' => 'nullable|uuid', 'district_id' => 'nullable|uuid', 'admin_post_id' => 'nullable|uuid', 'locality_id' => 'nullable|uuid']); + $filters = array_intersect_key($d, array_flip(['province_id', 'district_id', 'admin_post_id', 'locality_id'])); + if (! empty($d['sector_id'])) { + $filters['sector'] = Sector::whereKey($d['sector_id'])->firstOrFail()->slug; + } - return response()->json($context->options($d['q'] ?? '')); + return response()->json($context->options($d['q'] ?? '', $filters)); } public function corridorOptions(Request $r): JsonResponse { - $data = $r->validate(['corridor' => ['nullable', Rule::in(array_keys(config('investment_corridors')))], 'territory' => 'nullable|uuid']); + $data = $r->validate(['corridor' => ['nullable', Rule::in(array_keys(config('investment_corridors')))], 'territory' => 'nullable|uuid', 'include_corridors' => 'nullable|boolean']); $service = app(InvestmentCorridorContext::class); - return response()->json(['corridors' => collect(Config::array('investment_corridors'))->map(fn ($entry, $key) => ['key' => $key, 'name' => $entry['name'], 'provinces' => $service->provinces($key)])->values(), + return response()->json(['corridors' => ($data['include_corridors'] ?? true) ? collect(Config::array('investment_corridors'))->map(fn ($entry, $key) => ['key' => $key, 'name' => $entry['name'], 'provinces' => $service->provinces($key)])->values() : [], 'parks' => $service->parks($data['corridor'] ?? null, $data['territory'] ?? null)]); } @@ -101,6 +127,16 @@ final class InvestorContextController extends Controller return response()->json($context->saveDraft($r->user(), $id, $r->all())); } + public function supplyAggregate(Request $r, string $id, InvestorContext $context): JsonResponse + { + return response()->json($context->saveSupplyAggregate($r->user(), $id, $r->all()))->header('Cache-Control', 'private, no-store'); + } + + public function promoter(Request $r, string $id, InvestorContext $context): JsonResponse + { + return response()->json($r->isMethod('GET') ? $context->promoter($r->user(), $id) : $context->setPromoter($r->user(), $id, $r->all()))->header('Cache-Control', 'private, no-store'); + } + public function edit(Request $r, string $id, InvestorContext $context): Response { $data = $context->view($r->user(), $id); @@ -133,8 +169,8 @@ final class InvestorContextController extends Controller } } $complements = isset($draft['complements']) ? app(InvestmentComplements::class)->resolve($draft['complements'], $data['context']['complements'] ?? []) : ($data['context']['complements'] ?? []); - $entryTerritory = null; - if (($source['kind'] ?? null) === 'portfolio') { + $entryTerritory = ($source['kind'] ?? '') === 'territory' ? $source : null; + if ($r->hasAny(['province_id', 'district_id', 'admin_post_id', 'locality_id'])) { $path = app(InvestmentGeography::class)->selection($r->validate(['province_id' => 'nullable|uuid', 'district_id' => 'nullable|uuid', 'admin_post_id' => 'nullable|uuid', 'locality_id' => 'nullable|uuid'])); if ($path) { $entryTerritory = $context->reference('territory:'.$path[array_key_last($path)]->id); @@ -148,7 +184,7 @@ final class InvestorContextController extends Controller } } - return Inertia::render('investor-path/context', ['entryTerritory' => $entryTerritory, 'entryComplements' => $complements, 'entryLocationDifferences' => $differences, 'entrySources' => $entrySources, 'draft' => $draft, 'requestedChoices' => $choices, 'initial' => $data, 'options' => $context->options(), 'source' => $source, 'territorySelection' => isset($data['context']['selection']['territory']) ? app(InvestmentGeography::class)->path($data['context']['selection']['territory']['id']) : ($entryTerritory ? app(InvestmentGeography::class)->path($entryTerritory['id']) : [])]); + return Inertia::render('investor-path/context', ['entryIdea' => $this->ideaEntry($r), 'entryTerritory' => $entryTerritory, 'entryComplements' => $complements, 'entryLocationDifferences' => $differences, 'entrySources' => $entrySources, 'draft' => $draft, 'requestedChoices' => $choices, 'initial' => $data, 'options' => $context->options(), 'source' => $source, 'territorySelection' => isset($data['context']['selection']['territory']) ? app(InvestmentGeography::class)->path($data['context']['selection']['territory']['id']) : ($entryTerritory ? app(InvestmentGeography::class)->path($entryTerritory['id']) : [])]); } public function preview(Request $r, string $id, InvestorContext $context): JsonResponse @@ -175,7 +211,7 @@ final class InvestorContextController extends Controller $choices = $this->entryChoices($r, $context); - return Inertia::render('investor-path/context-start', ['entrySubmission' => $entrySubmission, 'entryComplements' => $this->entryComplements($r), 'entryQuery' => $r->only(['complement_origin', 'complement_code', 'complement_target', 'complement_territory', 'from_dossier', 'province_id', 'district_id', 'admin_post_id', 'locality_id']), 'opportunityChoices' => $choices, 'contexts' => $path->contexts($r->user()), 'source' => $ref, 'step' => $d['step'] ?? null]); + return Inertia::render('investor-path/context-start', ['entrySubmission' => $entrySubmission, 'entryComplements' => $this->entryComplements($r), 'entryQuery' => [...$this->ideaEntry($r), ...$r->only(['complement_origin', 'complement_code', 'complement_target', 'complement_territory', 'from_dossier', 'province_id', 'district_id', 'admin_post_id', 'locality_id'])], 'opportunityChoices' => $choices, 'contexts' => $path->contexts($r->user()), 'source' => $ref, 'step' => $d['step'] ?? null]); } public function installation(Request $r, InvestorContextInstallation $install): JsonResponse|Response diff --git a/app/Http/Requests/StoreSimulationFormDraftRequest.php b/app/Http/Requests/StoreSimulationFormDraftRequest.php index 26af44bf..6001e799 100644 --- a/app/Http/Requests/StoreSimulationFormDraftRequest.php +++ b/app/Http/Requests/StoreSimulationFormDraftRequest.php @@ -37,13 +37,14 @@ class StoreSimulationFormDraftRequest extends FormRequest 'contact_province', 'contact_district', 'preferred_channel', ]; $economic = [ + 'preparation_step', 'planning_assumptions_snapshot', 'initial_budget_snapshot', 'fiscal_tools_selection', 'planned_funding', 'requested_funding', 'approved_funding', 'planning_loan', 'context_opportunity', 'context_applicability_snapshot', 'investment_regime', 'context_reuse', 'compatible_fields_snapshot', 'published_iva_base', 'published_iva_currency', 'published_iva_date', 'published_iva_scope', 'monthly_iva_settings', 'monthly_iva_snapshot', 'modelo_a_snapshot', 'journey_type', 'detail_level', 'business_plan_snapshot', 'financial_tools_snapshot', 'cashflow_snapshot', 'project_team_snapshot', 'project_execution_snapshot', 'purpose', 'manifestation_type', 'preferred_language', 'project_title', 'project_summary', 'project_problem', 'target_customers', 'value_proposition', 'market_assumption', 'market_source', 'project_milestones', 'selection_labels', 'project_type', 'competitor_assumption', 'sales_channel_assumption', 'marketing_approach', 'location_rationale', 'project_risk_responses_snapshot', 'project_questionnaire_version', 'customer_validation_status', 'cost_estimate_status', 'location_assessment_status', 'funding_status', 'receivables_timing_status', 'project_type_other', 'sector_id', 'activity_id', 'products_services', 'maturity_stage', 'expected_start_date', 'project_duration_years', 'existing_project_id', 'province_id', 'district_id', 'admin_post_id', 'locality_id', 'site_known', 'latitude', 'longitude', 'area_required', 'area_unit', 'special_zone_id', 'land_status', - 'infrastructure_needs', 'currency', 'total_investment', 'own_capital', 'domestic_debt', 'foreign_debt', + 'infrastructure_needs', 'investment_budget_min', 'investment_budget_max', 'currency', 'total_investment', 'own_capital', 'domestic_debt', 'foreign_debt', 'grants', 'secured_amount', 'sought_amount', 'annual_revenue', 'annual_operating_costs', 'expected_profit', 'financing_term_months', 'funds_origin_countries', 'direct_jobs', 'indirect_jobs', 'national_jobs', 'foreign_jobs', 'skills_needed', 'local_content_percentage', 'exports_value', 'import_substitution_value', @@ -69,6 +70,15 @@ class StoreSimulationFormDraftRequest extends FormRequest 'economic_snapshot.purpose' => ['required', 'in:simulate_only,own_investment,seek_investor,seek_partner,present_opportunity,request_facilitation'], 'economic_snapshot.journey_type' => ['nullable', 'in:personal,small_business,company,investor'], 'economic_snapshot.detail_level' => ['nullable', 'in:simple,advanced'], + 'economic_snapshot.preparation_step' => ['nullable', 'in:purpose,market,investment,financial,operating,cashflow,tax,review,promoter,identity,project,location,impact,opportunity,documents,team,scenarios,procedures'], + 'economic_snapshot.initial_budget_snapshot' => ['nullable', 'string', 'max:12000'], + 'economic_snapshot.planning_assumptions_snapshot' => ['nullable', 'string', 'max:12000'], + 'economic_snapshot.fiscal_tools_selection' => ['nullable', 'array', 'max:80'], + 'economic_snapshot.fiscal_tools_selection.*' => ['string', 'max:100', 'regex:/^(tax|iva|irpc):[a-z_]+$/'], + 'economic_snapshot.planned_funding' => ['nullable', 'numeric', 'min:0'], + 'economic_snapshot.requested_funding' => ['nullable', 'numeric', 'min:0'], + 'economic_snapshot.approved_funding' => ['nullable', 'numeric', 'min:0'], + 'economic_snapshot.planning_loan' => ['nullable', 'in:yes,no,unknown'], 'economic_snapshot.business_plan_snapshot' => ['nullable', 'string', 'max:60000'], 'economic_snapshot.financial_tools_snapshot' => ['nullable', 'string', 'max:30000'], 'economic_snapshot.cashflow_snapshot' => ['nullable', 'string', 'max:20000'], @@ -126,6 +136,8 @@ class StoreSimulationFormDraftRequest extends FormRequest 'economic_snapshot.publication_authorisation' => ['nullable', 'in:yes,no'], 'economic_snapshot.public_fields_confirmation' => ['nullable', 'in:yes,no'], 'economic_snapshot.validation_acknowledged' => ['nullable', 'in:yes,no'], + 'economic_snapshot.investment_budget_min' => ['nullable', 'numeric', 'min:0'], + 'economic_snapshot.investment_budget_max' => ['nullable', 'numeric', 'min:0', \Illuminate\Validation\Rule::when($this->filled('economic_snapshot.investment_budget_min'), 'gte:economic_snapshot.investment_budget_min')], 'economic_snapshot.currency' => ['nullable', 'string', 'regex:/^[A-Z]{3}$/'], 'economic_snapshot.opportunity_currency' => ['nullable', 'string', 'regex:/^[A-Z]{3}$/'], 'economic_snapshot.rate' => ['nullable', 'numeric', 'between:0,100'], @@ -288,6 +300,7 @@ class StoreSimulationFormDraftRequest extends FormRequest $allowedLabels = [ 'economic_snapshot.selection_labels' => ['journey_type', 'detail_level', 'purpose', 'manifestation_type', 'preferred_language', 'project_type', 'maturity_stage', 'sector_id', 'activity_id', + 'customer_validation_status', 'location_assessment_status', 'cost_estimate_status', 'receivables_timing_status', 'funding_status', 'planning_loan', 'province_id', 'district_id', 'admin_post_id', 'locality_id', 'site_known', 'land_status', 'infrastructure_needs', 'area_unit', 'required_documents', 'opportunity_currency', 'currency', 'funds_origin_countries', 'environmental_category', 'tax_calculation', 'fiscal_scenario_mode', 'offer_or_demand', @@ -303,7 +316,7 @@ class StoreSimulationFormDraftRequest extends FormRequest $labels = is_array($label) ? $label : [$label]; if (! is_string($field) || ! in_array($field, $allowedFields, true) || count($labels) > 100 || collect($labels)->contains(fn ($value) => ! is_string($value) || mb_strlen($value) > 255)) { - $validator->errors()->add($path, 'Os rótulos de selecção não são válidos.'); + $validator->errors()->add($path.'.'.(is_string($field) ? $field : 'draft'), 'Não foi possível guardar a opção apresentada neste campo. Volte a seleccioná-la; os outros dados do rascunho foram preservados.'); break 2; } } diff --git a/app/Services/CompanyComparison.php b/app/Services/CompanyComparison.php index a1d508a8..e71fc127 100644 --- a/app/Services/CompanyComparison.php +++ b/app/Services/CompanyComparison.php @@ -139,7 +139,8 @@ final class CompanyComparison public function view(User $actor, string $id, array $input): array { $case = $this->desk->case($actor, $id); - $saved = $this->desk->decode($case->payload)['company_comparison'] ?? null; + $payload = $this->desk->decode($case->payload); + $saved = $payload['company_comparison'] ?? null; $v = Validator::make($input, ['revision' => 'nullable|uuid', 'history_before' => 'nullable|integer|min:1'])->validate(); if (! empty($v['revision'])) { if (array_key_exists('answers', $input)) { @@ -160,7 +161,7 @@ final class CompanyComparison return ['id' => $row->id, 'revision' => $snapshot['revision'], 'at' => $snapshot['at'], 'engine_version' => $snapshot['result']['engine_version']]; })->all(); - return ['case' => ['id' => $id, 'title' => $case->title, 'version' => (int) $case->version], + return ['entity_kind' => $payload['investor_path']['context']['promoter_entity']['kind'] ?? ($case->company_id ? 'company' : 'undetermined'), 'case' => ['id' => $id, 'title' => $case->title, 'version' => (int) $case->version], 'canWrite' => ! $case->closed_at && $this->desk->owns($actor, $case), 'answers' => $answers, 'result' => $result, 'saved' => $saved, 'history' => $history, 'historyNext' => $events->count() > 25 ? $events[24]->event_order : null, 'historical' => ! empty($v['revision']), 'workingCopy' => array_key_exists('answers', $input)]; @@ -171,7 +172,7 @@ final class CompanyComparison public function save(User $actor, string $id, array $input): array { $this->desk->case($actor, $id, true); - $v = Validator::make($input, ['version' => 'required|integer|min:1', 'operation_key' => 'required|uuid'])->validate(); + $v = Validator::make($input, ['version' => 'required|integer|min:1', 'operation_key' => 'required|uuid', 'continue_preparation' => 'nullable|boolean'])->validate(); $v['version'] = (int) $v['version']; return DB::transaction(function () use ($actor, $id, $v, $input) { @@ -180,19 +181,23 @@ final class CompanyComparison $data = $this->desk->decode($event->payload); if ($data['operation_key'] === $v['operation_key']) { $answers = $this->normalize($input, $data['snapshot']['result']['questions']); - $hash = hash('sha256', json_encode([$v['version'], $answers], JSON_THROW_ON_ERROR)); + $hash = hash('sha256', json_encode(! empty($v['continue_preparation']) ? [$v['version'], $answers, 'continue_preparation'] : [$v['version'], $answers], JSON_THROW_ON_ERROR)); abort_unless(hash_equals($data['request_hash'], $hash), 409, 'Esta operação já guardou respostas diferentes. Reabra a comparação.'); return ['saved' => true, 'replayed' => true, 'revision' => $data['snapshot']['revision']]; } } $answers = $this->answers($input); - $hash = hash('sha256', json_encode([$v['version'], $answers], JSON_THROW_ON_ERROR)); + $hash = hash('sha256', json_encode(! empty($v['continue_preparation']) ? [$v['version'], $answers, 'continue_preparation'] : [$v['version'], $answers], JSON_THROW_ON_ERROR)); abort_if($case->closed_at || (int) $case->version !== (int) $v['version'], 409, 'O dossier mudou ou foi fechado. Conserve as respostas e recupere a versão actual antes de guardar.'); $payload = $this->desk->decode($case->payload); + if (! empty($v['continue_preparation'])) { + abort_if(in_array($payload['investor_path']['context']['promoter_entity']['kind'] ?? '', ['company', 'organization'], true), 422, 'A entidade existente pode continuar a viabilidade sem preparar nova constituição.'); + abort_if(($answers['preferred'] ?? 'unknown') === 'unknown', 422, 'Escolha a alternativa que pretende preparar.'); + } $result = $this->evaluate($answers); $previous = $payload['company_comparison'] ?? null; - if ($previous !== null && $previous['answers'] === $answers && $previous['result'] === $result) { + if (empty($v['continue_preparation']) && $previous !== null && $previous['answers'] === $answers && $previous['result'] === $result) { return ['saved' => true, 'replayed' => false, 'unchanged' => true, 'revision' => $previous['revision']]; } $snapshot = ['revision' => (int) ($payload['company_comparison']['revision'] ?? 0) + 1, 'answers' => $answers, @@ -201,6 +206,9 @@ final class CompanyComparison $case->version++; DB::table('desk_cases')->where('id', $id)->update(['payload' => $this->desk->encode($payload), 'version' => $case->version, 'updated_at' => now()]); $this->desk->event($case, $actor, self::EVENT, ['operation_key' => $v['operation_key'], 'request_hash' => $hash, 'snapshot' => $snapshot]); + if (! empty($v['continue_preparation'])) { + app(InvestorContext::class)->setPromoter($actor, $id, ['version' => $case->version, 'operation_key' => (string) \Illuminate\Support\Str::uuid(), 'kind' => 'being_formed']); + } return ['saved' => true, 'replayed' => false, 'revision' => $snapshot['revision']]; }); diff --git a/app/Services/CompanyPreparation.php b/app/Services/CompanyPreparation.php index 4a21d138..f9cbca8a 100644 --- a/app/Services/CompanyPreparation.php +++ b/app/Services/CompanyPreparation.php @@ -23,7 +23,7 @@ final class CompanyPreparation return ['version' => self::VERSION, 'forms' => config('company-comparison.forms'), 'roles' => ['subscriber' => 'Titular, sócio ou accionista', 'administrator' => 'Administrador ou gerente', 'representative' => 'Representante', 'beneficial_owner' => 'Beneficiário efectivo declarado'], 'source' => config('company-comparison.source'), - 'template_status' => 'source_pending', 'template_notice' => 'Os sete exemplares referidos no complemento ainda não foram fornecidos. Esta ficha prepara dados para revisão; não é uma minuta contratual, assinatura, registo ou licença.']; + 'template_status' => 'source_pending', 'template_notice' => 'Os modelos contratuais não estão disponíveis nesta preparação. Prepare os dados para revisão; esta preparação não é uma minuta contratual, assinatura, registo ou licença.']; } /** Reuse only the already-authorized, frozen dossier values, never a fresh master lookup. @@ -36,8 +36,8 @@ final class CompanyPreparation $sources['case_proponent'] = ['name' => $payload['name'], 'kind' => 'person', 'reference' => $case->id, 'version' => $payload['reuse_consent']['date'] ?? 'creation', 'origin' => 'Proponente conservado na criação do dossier']; } - if ($case->company_id && ! empty($payload['company']['name'])) { - $sources['case_company'] = ['name' => $payload['company']['name'], 'kind' => 'entity', 'reference' => $case->company_id, + if (($case->company_id || ! empty($payload['investor_path']['context']['promoter_entity']['id'])) && ! empty($payload['company']['name'])) { + $sources['case_company'] = ['name' => $payload['company']['name'], 'kind' => 'entity', 'reference' => $case->company_id ?? $payload['investor_path']['context']['promoter_entity']['id'], 'version' => $payload['company_version'] ?? null, 'origin' => 'Declaração de empresa conservada no dossier']; } @@ -220,7 +220,7 @@ final class CompanyPreparation { $case = $this->desk->case($actor, $id); $payload = $this->desk->decode($case->payload); - $v = Validator::make($input, ['revision' => 'nullable|uuid', 'history_before' => 'nullable|integer|min:1'])->validate(); + $v = Validator::make($input, ['revision' => 'nullable|uuid', 'history_before' => 'nullable|integer|min:1', 'form' => ['nullable', Rule::in(array_keys(config('company-comparison.forms')))]])->validate(); $saved = $payload['company_preparation'] ?? null; if (! empty($v['revision'])) { $event = DB::table('desk_events')->where('case_id', $id)->where('action', self::EVENT)->where('id', $v['revision'])->first(); @@ -228,11 +228,22 @@ final class CompanyPreparation $saved = $this->desk->decode($event->payload)['snapshot']; } $facts = $saved['facts'] ?? $this->facts(['facts' => []]); + $entity = $payload['investor_path']['context']['promoter_entity'] ?? null; + $context = app(InvestorContext::class)->state($case)['fields']; + $existingEntity = in_array($entity['kind'] ?? '', ['company', 'organization'], true); + if (! $saved && empty($v['revision'])) { + foreach (['currency' => 'currency', 'activities' => 'products_services', 'seat' => 'location'] as $target => $source) { + if (empty($facts[$target]) && ! empty($context[$source])) $facts[$target] = $context[$source]; + } + $facts['proposed_name'] = $entity['snapshot']['name'] ?? $facts['proposed_name']; + $knownForm = $entity['snapshot']['legal_form'] ?? null; + $facts['form'] = $existingEntity ? $knownForm : ($v['form'] ?? $facts['form']); + } $events = DB::table('desk_events')->where('case_id', $id)->where('action', self::EVENT) ->when(! empty($v['history_before']), fn ($q) => $q->where('event_order', '<', $v['history_before'])) ->orderByDesc('event_order')->limit(26)->get(['id', 'payload', 'event_order']); - return ['case' => ['id' => $id, 'title' => $case->title, 'version' => (int) $case->version], + return ['entity' => $entity, 'proposedForm' => ! $existingEntity ? ($v['form'] ?? null) : null, 'case' => ['id' => $id, 'title' => $case->title, 'version' => (int) $case->version], 'canWrite' => ! $case->closed_at && $this->desk->owns($actor, $case), 'historical' => ! empty($v['revision']), 'definition' => $saved['definition'] ?? $this->definition(), 'facts' => $facts, 'review' => $saved['review'] ?? $this->review($facts), 'saved' => $saved, 'sources' => $this->sources($case), 'history' => $events->take(25)->map(function ($e) { @@ -265,6 +276,11 @@ final class CompanyPreparation $hash = hash('sha256', json_encode([(int) $v['version'], $facts], JSON_THROW_ON_ERROR)); abort_if($case->closed_at || (int) $case->version !== (int) $v['version'], 409, 'O dossier mudou ou foi fechado. Os dados continuam no formulário; recupere a versão antes de guardar.'); $payload = $this->desk->decode($case->payload); + $entity = $payload['investor_path']['context']['promoter_entity'] ?? null; + $registeredForm = $entity['snapshot']['legal_form'] ?? null; + if (in_array($entity['kind'] ?? '', ['company', 'organization'], true) && $registeredForm) { + abort_unless($facts['form'] === $registeredForm, 422, 'A forma jurídica da entidade existente não é alterada nesta preparação. Use o percurso próprio de alteração do cadastro.'); + } $previous = $payload['company_preparation'] ?? null; $resolved = $this->resolve($facts, $this->sources($case), $previous); $definition = $this->definition(); diff --git a/app/Services/DemographicEvidence.php b/app/Services/DemographicEvidence.php index f8e30c85..8f27fa8a 100644 --- a/app/Services/DemographicEvidence.php +++ b/app/Services/DemographicEvidence.php @@ -34,6 +34,29 @@ final class DemographicEvidence return ['commerce' => 'Comércio e serviços', 'industry' => 'Indústria', 'agriculture' => 'Agricultura e agro-indústria', 'education' => 'Educação', 'health' => 'Saúde', 'general' => 'Contexto geral']; } + /** Broader administrative evidence stays labelled as context, never local data. + * @return array + */ + public function investmentContext(string $territory, int $start, int $end, string $sector = 'general', ?string $edition = null): array + { + $path = app(InvestmentGeography::class)->path($territory); + $requested = collect($path)->last(); + $result = $this->analyse([], $start, $end, $sector, $edition); + foreach (array_reverse($path) as $node) { + if (! in_array($node->location_type, ['district', 'province'], true)) { + continue; + } + $result = $this->analyse([$node->id], $start, $end, $sector, $edition); + if ($result['state'] === 'available') { + break; + } + } + $result['requested_territory'] = $requested ? ['id' => $requested->id, 'name' => $requested->name, 'level' => $requested->location_type] : null; + $result['broader_context'] = $requested && count($result['territories']) && $requested->id !== $result['territories'][0]['id']; + + return $result; + } + /** @param list $territories * @return array */ public function analyse(array $territories, int $start, int $end, string $sector = 'general', ?string $edition = null): array diff --git a/app/Services/FundingInstitutionClassification.php b/app/Services/FundingInstitutionClassification.php index e2616a0e..80784467 100644 --- a/app/Services/FundingInstitutionClassification.php +++ b/app/Services/FundingInstitutionClassification.php @@ -13,6 +13,29 @@ final class FundingInstitutionClassification public const TYPES = ['commercial_bank' => 'Banco comercial', 'investment_bank' => 'Banco de investimento', 'bank' => 'Banco (tipo não especificado)', 'microbank' => 'Microbanco', 'cooperative' => 'Cooperativa de crédito', 'savings' => 'Organização de poupança e empréstimo', 'investment_manager' => 'Gestora de fundos de investimento', 'investment_company' => 'Sociedade de investimento', 'pension_manager' => 'Gestora de fundos de pensões', 'insurer' => 'Seguradora', 'reinsurer' => 'Resseguradora', 'microinsurer' => 'Micro-seguradora', 'broker' => 'Corretora de seguros', 'agent' => 'Agente de seguros', 'reinsurance_broker' => 'Corretor de resseguro', 'exchange_house' => 'Casa de câmbio', 'electronic_money' => 'Instituição de moeda electrónica', 'interbank' => 'Serviços interbancários', 'supervisor' => 'Supervisor', 'other' => 'Outro tipo documentado']; + // Category/type semantics in the supplied, accepted institutional reference. + public const CATEGORY_TYPES = ['banking' => ['commercial_bank', 'investment_bank', 'bank'], 'credit' => ['microbank', 'cooperative', 'savings'], + 'investment' => ['investment_manager', 'investment_company'], 'pensions' => ['pension_manager', 'insurer'], 'insurance' => ['insurer', 'reinsurer', 'microinsurer', 'pension_manager'], + 'intermediation' => ['broker', 'agent', 'reinsurance_broker'], 'exchange' => ['exchange_house'], 'payments' => ['electronic_money', 'interbank'], 'supervision' => ['supervisor'], 'other' => ['other']]; + + /** Structural validity is independent of whether matching records exist. + * @param array $filters + */ + public function validateFilters(array $filters): void + { + $v = Validator::make($filters, ['category' => ['nullable', Rule::in(array_keys(self::CATEGORIES))], 'institution_type' => ['nullable', Rule::in(array_keys(self::TYPES))], + 'kind' => ['nullable', Rule::in(array_keys(FundingProgrammes::KINDS))], 'location_mode' => 'nullable|in:physical,coverage'])->validate(); + $errors = []; + if (! empty($v['category']) && $v['category'] !== 'other' && ! empty($v['institution_type']) && $v['institution_type'] !== 'other' && ! in_array($v['institution_type'], self::CATEGORY_TYPES[$v['category']], true)) { + $errors['institution_type'] = 'O tipo de instituição não pertence à categoria escolhida. Reveja esse critério; isto não é uma pesquisa sem resultados.'; + } + if (! empty($v['kind']) && $v['kind'] !== 'institution') { + if (! empty($v['category']) || ! empty($v['institution_type'])) $errors['kind'] = 'Categoria e tipo de instituição aplicam-se à consulta de instituições. Um fundo ou programa é um registo distinto.'; + if (($v['location_mode'] ?? '') === 'physical') $errors['location_mode'] = 'Sede e balcões aplicam-se a instituições. Para fundos e programas, escolha a cobertura do financiamento.'; + } + if ($errors) throw \Illuminate\Validation\ValidationException::withMessages($errors); + } + /** @param array $input * @return array */ public function normalize(array $input): array @@ -31,6 +54,7 @@ final class FundingInstitutionClassification /** @param array $filters */ public function filter(Builder $query, array $filters): void { + $this->validateFilters($filters); foreach (['category' => 'institution_categories', 'institution_type' => 'institution_types'] as $key => $field) { if (! empty($filters[$key])) { $query->whereRaw('v.payload->? @> ?::jsonb', [$field, json_encode([$filters[$key]], JSON_THROW_ON_ERROR)]); diff --git a/app/Services/FundingInstitutionDetails.php b/app/Services/FundingInstitutionDetails.php index 5afccee7..0aa9414f 100644 --- a/app/Services/FundingInstitutionDetails.php +++ b/app/Services/FundingInstitutionDetails.php @@ -113,7 +113,7 @@ final class FundingInstitutionDetails public function match(array $product, array $filters): bool { $unknown = ($filters['certainty'] ?? 'include_unknown') === 'include_unknown'; - if ($product['availability'] === 'closed') { + if ($product['availability'] === 'closed' && ($filters['state'] ?? '') !== 'closed') { return false; } if (! $unknown && $product['availability'] === 'unknown') { @@ -122,7 +122,7 @@ final class FundingInstitutionDetails if (! empty($filters['need']) && ! in_array($filters['need'], $product['needs'], true) && ! ($unknown && $product['needs'] === [])) { return false; } - if (empty($filters['territory'])) { + if (empty($filters['territory']) || ($filters['location_mode'] ?? '') === 'physical') { return true; } if ($product['coverage'] === 'national') { @@ -150,7 +150,7 @@ final class FundingInstitutionDetails return; } $unknown = ($filters['certainty'] ?? 'include_unknown') === 'include_unknown'; - $conditions = ["p->>'availability' <> 'closed'"]; + $conditions = [($filters['state'] ?? '') === 'closed' ? "p->>'availability' IN ('documented','closed','unknown')" : "p->>'availability' <> 'closed'"]; $bindings = []; if (! $unknown) { $conditions[] = "p->>'availability' <> 'unknown'"; diff --git a/app/Services/FundingProgrammes.php b/app/Services/FundingProgrammes.php index b442568c..3ce6a51d 100644 --- a/app/Services/FundingProgrammes.php +++ b/app/Services/FundingProgrammes.php @@ -68,7 +68,17 @@ final class FundingProgrammes /** @param array $filters */ public function catalogueQuery(array $filters): Builder { + Validator::make($filters, ['q' => 'nullable|string|max:150', 'state' => 'nullable|in:open,closed,upcoming,unknown', 'certainty' => 'nullable|in:include_unknown,documented', + 'sector' => ['nullable', 'integer', Rule::in(Sector::choices()->whereNotNull('published_at')->pluck('id')->all())], 'need' => ['nullable', Rule::in(array_keys(FundingInstitutionDetails::NEEDS))], 'include_historical' => 'nullable|boolean'])->validate(); + $filters = app(InvestmentGeography::class)->interestSelection($filters); $query = $this->publicQuery(); + if (! empty($filters['q'])) { + $term = '%'.str_replace(['\\', '%', '_'], ['\\\\', '\\%', '\\_'], $filters['q']).'%'; + $query->where(fn ($q) => $q->whereRaw("v.payload->>'title' ilike ?", [$term])->orWhereRaw("v.payload->>'summary' ilike ?", [$term])->orWhereRaw("(v.payload->'aliases')::text ilike ?", [$term])->orWhereRaw("EXISTS (SELECT 1 FROM jsonb_array_elements(COALESCE(v.payload->'locations','[]'::jsonb)) l WHERE l->>'label' ilike ? OR l->>'address' ilike ? OR l->>'location_text' ilike ?)", [$term, $term, $term])); + } + if (! empty($filters['kind'])) { + $query->whereRaw("v.payload->>'kind' = ?", [$filters['kind']]); + } app(FundingInstitutionDetails::class)->applyFilters($query, $filters); $includeUnknown = ($filters['certainty'] ?? 'include_unknown') === 'include_unknown'; if (! empty($filters['sector'])) { @@ -94,22 +104,43 @@ final class FundingProgrammes }); } if (! empty($filters['state'])) { - $today = today()->toDateString(); - $state = $filters['state']; - if ($state === 'unknown') { - $query->whereRaw("(jsonb_array_length(v.payload->'windows') = 0 OR EXISTS (SELECT 1 FROM jsonb_array_elements(v.payload->'windows') w WHERE w->>'mode' = 'unknown'))"); - } elseif ($state === 'closed') { - $query->whereRaw("EXISTS (SELECT 1 FROM jsonb_array_elements(v.payload->'windows') w WHERE w->>'mode' = 'closed' OR (w->>'mode' = 'dated' AND w->>'end_on' < ?))", [$today]); - } elseif ($state === 'upcoming') { - $query->whereRaw("EXISTS (SELECT 1 FROM jsonb_array_elements(v.payload->'windows') w WHERE w->>'mode' = 'dated' AND w->>'start_on' > ?)", [$today]); - } else { - $query->whereRaw("EXISTS (SELECT 1 FROM jsonb_array_elements(v.payload->'windows') w WHERE w->>'mode' IN ('dated','rolling') AND COALESCE(NULLIF(w->>'start_on',''),?) <= ? AND COALESCE(NULLIF(w->>'end_on',''),?) >= ?)", [$today, $today, $today, $today]); - } + [$windowSql, $windowBindings] = $this->windowFilter($filters); + $query->whereRaw("EXISTS (SELECT 1 FROM jsonb_array_elements(COALESCE(v.payload->'windows','[]'::jsonb)) w WHERE ".$windowSql.')', $windowBindings); } return $query; } + /** Window dates and geographical scope concern the same documented window. + * @param array $filters + * @return array{literal-string,list} + */ + private function windowFilter(array $filters): array + { + $today = today()->toDateString(); + $state = $filters['state']; + $bindings = []; + if ($state === 'unknown') $sql = "w->>'mode' = 'unknown'"; + elseif ($state === 'closed') { $sql = "(w->>'mode' = 'closed' OR (w->>'mode' = 'dated' AND w->>'end_on' < ?))"; $bindings = [$today]; } + elseif ($state === 'upcoming') { $sql = "w->>'mode' = 'dated' AND w->>'start_on' > ?"; $bindings = [$today]; } + else { $sql = "w->>'mode' IN ('dated','rolling') AND COALESCE(NULLIF(w->>'start_on',''),?) <= ? AND COALESCE(NULLIF(w->>'end_on',''),?) >= ?"; $bindings = [$today, $today, $today, $today]; } + if (! empty($filters['territory']) && ($filters['location_mode'] ?? '') !== 'physical') { + $path = array_column(app(InvestmentGeography::class)->path($filters['territory']), 'id'); + $window = ["EXISTS (SELECT 1 FROM jsonb_array_elements(COALESCE(w->'territory_paths','[]'::jsonb)) t WHERE t @> ?::jsonb)"]; + $scopeBindings = [json_encode([['id' => $filters['territory']]], JSON_THROW_ON_ERROR)]; + foreach ($path as $id) { $window[] = "w->'territory_ids' @> ?::jsonb"; $scopeBindings[] = json_encode([$id], JSON_THROW_ON_ERROR); } + $parent = ["v.payload->>'coverage'='national'", "v.payload->'territory_ancestor_ids' @> ?::jsonb"]; + $scopeBindings[] = json_encode([$filters['territory']], JSON_THROW_ON_ERROR); + foreach ($path as $id) { $parent[] = "v.payload->'territory_ids' @> ?::jsonb"; $scopeBindings[] = json_encode([$id], JSON_THROW_ON_ERROR); } + if (($filters['certainty'] ?? 'include_unknown') === 'include_unknown') $parent[] = "v.payload->>'coverage'='unknown'"; + $scope = "(w->>'coverage'='national' OR (w->>'coverage'='territorial' AND (".implode(' OR ', $window).")) OR (w->>'coverage'='programme' AND (".implode(' OR ', $parent).')))'; + if (($filters['certainty'] ?? 'include_unknown') === 'include_unknown') $scope = '('.$scope." OR w->>'coverage'='unknown')"; + $sql = '('.$sql.') AND '.$scope; + $bindings = [...$bindings, ...$scopeBindings]; + } + return [$sql, $bindings]; + } + /** @param array $record * @param array $filters * @return array */ diff --git a/app/Services/InvestmentCorridorContext.php b/app/Services/InvestmentCorridorContext.php index 32d8204d..ba28ad14 100644 --- a/app/Services/InvestmentCorridorContext.php +++ b/app/Services/InvestmentCorridorContext.php @@ -66,11 +66,16 @@ final class InvestmentCorridorContext */ public function parks(?string $key, ?string $territory): array { - if (! $key || ! $territory) { + if (! $territory) { return []; } - abort_unless($this->compatible($key, $territory), 422, 'A localização não pertence ao corredor escolhido.'); + if ($key) { + abort_unless($this->compatible($key, $territory), 422, 'A localização não pertence ao corredor escolhido.'); + } $selectedPath = array_column(app(InvestmentGeography::class)->path($territory), 'id'); + if ($selectedPath === []) { + return []; + } $candidates = app(InvestmentZones::class)->visible()->whereIn('category', ['industrial_park', 'zee', 'zfi'])->orderBy('name')->get(); $result = []; foreach ($candidates as $zone) { @@ -83,7 +88,7 @@ final class InvestmentCorridorContext } foreach ($ids as $link) { $id = $link->geo_location_id; - if (! $this->compatible($key, $id)) { + if ($key && ! $this->compatible($key, $id)) { continue; } $path = array_column(app(InvestmentGeography::class)->path($id), 'id'); diff --git a/app/Services/InvestmentGeography.php b/app/Services/InvestmentGeography.php index cdc072e8..294e4134 100644 --- a/app/Services/InvestmentGeography.php +++ b/app/Services/InvestmentGeography.php @@ -245,6 +245,30 @@ final class InvestmentGeography return $path; } + /** Canonical selection for a place-of-interest filter, including legacy links. + * @param array $filters + * @return array + */ + public function interestSelection(array $filters): array + { + $location = \Illuminate\Support\Facades\Validator::make($filters, ['territory' => 'nullable|uuid', 'province_id' => 'nullable|uuid', 'district_id' => 'nullable|uuid', 'admin_post_id' => 'nullable|uuid', 'locality_id' => 'nullable|uuid'])->validate(); + if (array_intersect(array_keys(self::FIELDS), array_keys($location))) { + $path = $this->selection($location); + $territory = $path ? $path[array_key_last($path)]->id : null; + if (! empty($location['territory']) && $location['territory'] !== $territory) { + throw ValidationException::withMessages(['territory' => 'O local de interesse não corresponde à hierarquia seleccionada.']); + } + if ($territory) $filters['territory'] = $territory; + else unset($filters['territory']); + } + if (! empty($filters['territory'])) { + $path = $this->path($filters['territory']); + if (! $path) throw ValidationException::withMessages(['territory' => 'Seleccione um local disponível no cadastro.']); + foreach ($path as $node) $filters[$node->location_type.'_id'] = $node->id; + } + return $filters; + } + /** @return list */ public function descendants(string $id, bool $includeNonPublic = false): array { diff --git a/app/Services/InvestmentOpportunityChoices.php b/app/Services/InvestmentOpportunityChoices.php index c16bb331..4bf8d668 100644 --- a/app/Services/InvestmentOpportunityChoices.php +++ b/app/Services/InvestmentOpportunityChoices.php @@ -74,7 +74,7 @@ final class InvestmentOpportunityChoices $old = collect($previous)->first(fn ($row) => $row['opportunity']['key'] === $ref['key']); $origins = $this->portfolioOrigins($choice['portfolio_origins'] ?? array_column($old['portfolio_origins'] ?? [], 'id'), (int) $record->id); $corridors = app(InvestmentCorridorContext::class); - $corridor = $choice['corridor_key'] ?? $old['corridor_key'] ?? $corridors->key($record); + $corridor = array_key_exists('corridor_key', $choice) ? $choice['corridor_key'] : ($old['corridor_key'] ?? $corridors->key($record)); $provinces = $corridor ? $corridors->provinces($corridor) : []; $documented = $record->primary_territory_id; $territory = array_key_exists('territory', $choice) ? $choice['territory'] : ($documented ? 'territory:'.$documented : null); diff --git a/app/Services/InvestorContext.php b/app/Services/InvestorContext.php index 70239db0..797e0227 100644 --- a/app/Services/InvestorContext.php +++ b/app/Services/InvestorContext.php @@ -24,7 +24,7 @@ final class InvestorContext public const SOURCE = 'investor-context'; - public const FIELDS = ['project_title', 'project_summary', 'sector_id', 'sector', 'province_id', 'district_id', 'admin_post_id', 'locality_id', 'province', 'district', 'location', 'currency', 'expected_start_date', 'fiscal_period', 'fiscal_periodicity', 'fiscal_month', 'investor_origin', 'person_type', 'entity_stage', 'tax_residency_country', 'fiscal_residency_country', 'activity_id', 'project_type', 'maturity_stage', 'special_zone_id', 'investment_regime', ...PrivateInvestmentPreparation::FIELDS]; + public const FIELDS = ['promoter_entity_key', 'legal_name', 'legal_form', 'registration_number', 'products_services', 'investment_budget_min', 'investment_budget_max', 'project_title', 'project_summary', 'sector_id', 'sector', 'province_id', 'district_id', 'admin_post_id', 'locality_id', 'province', 'district', 'location', 'currency', 'expected_start_date', 'fiscal_period', 'fiscal_periodicity', 'fiscal_month', 'investor_origin', 'person_type', 'entity_stage', 'tax_residency_country', 'fiscal_residency_country', 'activity_id', 'project_type', 'maturity_stage', 'special_zone_id', 'investment_regime', ...PrivateInvestmentPreparation::FIELDS]; public function __construct(private readonly VirtualDesk $desk) {} @@ -51,7 +51,7 @@ final class InvestorContext $entrySources = Validator::make($input, ['entry_sources' => 'sometimes|array|max:200', 'entry_sources.*' => 'string|max:100'])->validate()['entry_sources'] ?? []; unset($input['draft_sequence'],$input['entry_sources']); abort_unless($sequence > 0, 422); - $data = $this->input($input); + $data = $this->input($input, true); if (isset($data['complements'])) { app(InvestmentComplements::class)->resolve($data['complements'], $this->state($case)['complements'] ?? []); } @@ -69,7 +69,7 @@ final class InvestorContext abort_unless($ref['kind'] === 'opportunity', 422); $record = Opportunity::whereKey($ref['id'])->firstOrFail(); app(InvestmentOpportunityChoices::class)->portfolioOrigins($choice['portfolio_origins'] ?? [], (int) $record->id); - $key = $choice['corridor_key'] ?? app(InvestmentCorridorContext::class)->key($record); + $key = array_key_exists('corridor_key', $choice) ? $choice['corridor_key'] : app(InvestmentCorridorContext::class)->key($record); if (! empty($choice['territory'])) { $location = $this->reference($choice['territory']); abort_unless($location['kind'] === 'territory', 422); @@ -114,6 +114,112 @@ final class InvestorContext return Schema::hasTable('investor_navigation_preferences'); } + /** Existing identity records only; these choices never change dossier ownership. + * @return array + */ + public function promoter(User $actor, string $id): array + { + $case = $this->desk->case($actor, $id); + abort_unless((int) $case->user_id === $actor->id, 403); + $payload = $this->desk->decode($case->payload); + $companies = DB::table('investment_company_declarations')->where('user_id', $actor->id)->orderByDesc('created_at')->get(['id', 'version', 'payload'])->map(function ($row) { + $f = $this->desk->decode($row->payload); + return ['id' => $row->id, 'version' => $row->version, 'name' => $f['name'] ?? 'Empresa declarada', 'legal_form' => $f['legal_form'] ?? null]; + })->all(); + return ['version' => $case->version, 'selected' => $payload['investor_path']['context']['promoter_entity'] ?? ($case->company_id ? ['kind' => 'company', 'id' => $case->company_id, 'snapshot' => $payload['company'] ?? []] : ['kind' => 'undetermined']), + 'companies' => $companies, 'organizations' => $this->desk->representedOrganizations($actor), 'can_write' => $case->organization_id === null && ! $case->closed_at]; + } + + /** Attach an authorised identity snapshot while retaining the case owner and ACL. + * @param array $input + * @return array + */ + public function setPromoter(User $actor, string $id, array $input): array + { + $v = Validator::make($input, ['version' => 'required|integer|min:1', 'operation_key' => 'required|uuid', 'kind' => 'required|in:company,organization,being_formed,undetermined', 'id' => 'nullable|uuid', 'source_version' => 'nullable|integer|min:1'])->validate(); + return DB::transaction(function () use ($actor, $id, $v): array { + $case = $this->desk->case($actor, $id, true, true); + abort_unless((int) $case->user_id === $actor->id && $case->organization_id === null, 403); + $this->desk->assertOpen($case); + $payload = $this->desk->decode($case->payload); + $hash = hash('sha256', json_encode($v, JSON_THROW_ON_ERROR)); + foreach ($payload['investor_path']['promoter_history'] ?? [] as $entry) { + if (($entry['operation_key'] ?? null) === $v['operation_key']) { + abort_unless(hash_equals($entry['request_hash'], $hash), 409); + return ['saved' => true, 'replayed' => true, 'continue' => '/investimentos/'.$id]; + } + } + abort_unless((int) $case->version === (int) $v['version'], 409, 'O dossier mudou; recupere os dados antes de alterar a entidade.'); + $snapshot = []; + $sourceVersion = null; + if ($v['kind'] === 'company') { + $company = DB::table('investment_company_declarations')->where('id', $v['id'] ?? null)->where('user_id', $actor->id)->lockForUpdate()->first(); + abort_unless($company !== null, 404); + $snapshot = $this->desk->decode($company->payload); + $sourceVersion = $company->version; + } elseif ($v['kind'] === 'organization') { + DB::table('memberships')->where('organization_id', $v['id'] ?? null)->where('user_id', $actor->id)->whereNull('deleted_at')->lockForUpdate()->get(); + abort_unless($this->desk->represents($actor, $v['id'] ?? '', false), 403); + $organization = collect($this->desk->representedOrganizations($actor))->firstWhere('id', $v['id']); + abort_unless($organization !== null, 403); + $snapshot = ['name' => $organization['name'], 'incorporation_country_code' => $organization['country']]; + $sourceVersion = $organization['version']; + } + abort_if(isset($v['source_version']) && (int) $v['source_version'] !== (int) $sourceVersion, 409, 'O cadastro da entidade mudou. Recupere a associação antes de continuar.'); + $entity = ['kind' => $v['kind'], 'id' => in_array($v['kind'], ['company', 'organization'], true) ? $v['id'] : null, 'source_version' => $sourceVersion, 'snapshot' => $snapshot, 'recorded_at' => now()->toIso8601String()]; + $stage = in_array($v['kind'], ['company', 'organization'], true) ? 'existing' : ($v['kind'] === 'being_formed' ? 'being_formed' : ''); + $declarations = ['entity_stage' => $stage, 'promoter_entity_key' => $v['kind'].':'.($entity['id'] ?? '').'@'.($sourceVersion ?? '')]; + $existingFields = $this->state($case)['fields']; + foreach (['legal_name' => 'name', 'legal_form' => 'legal_form', 'registration_number' => 'registration'] as $field => $key) { + if (empty($existingFields[$field]) && ! empty($snapshot[$key])) $declarations[$field] = $snapshot[$key]; + } + $body = ['version' => $case->version, 'selection' => [], 'declarations' => $declarations]; + $plan = $this->preview($actor, $id, $body); + $this->commit($actor, $id, [...$body, 'preview_hash' => $plan['preview_hash'], 'confirm' => true, 'operation_key' => $v['operation_key']]); + $current = $this->desk->case($actor, $id, true, true); + $next = $this->desk->decode($current->payload); + $previous = $payload['investor_path']['context']['promoter_entity'] ?? ($case->company_id ? ['kind' => 'company', 'id' => $case->company_id, 'snapshot' => $payload['company'] ?? []] : ['kind' => 'undetermined']); + $next['investor_path']['context']['promoter_entity'] = $entity; + $next['investor_path']['promoter_history'][] = ['before' => $previous, 'after' => $entity, 'operation_key' => $v['operation_key'], 'request_hash' => $hash]; + $next['company'] = $snapshot; + $next['company_version'] = $sourceVersion; + DB::table('desk_cases')->where('id', $id)->update(['company_id' => $v['kind'] === 'company' ? $v['id'] : null, 'payload' => $this->desk->encode($next)]); + $this->desk->event($current, $actor, 'investment_promoter_associated', ['before' => $previous, 'after' => $entity, 'ownership_unchanged' => true]); + return ['saved' => true, 'replayed' => false, 'continue' => $v['kind'] === 'being_formed' ? '/investimentos/'.$id.'/preparar-empresa' : '/investimentos/'.$id]; + }); + } + + /** Explicit consultation saved in the existing encrypted dossier, with optimistic locking. + * @param array $input + * @return array + */ + public function saveSupplyAggregate(User $actor, string $id, array $input): array + { + abort_unless(config('investor-path.aggregate_supply_qa_enabled') && \App\Support\IsolatedQaDatabase::allowsSchemaChanges(), 404); + $control = Validator::make($input, ['version' => 'required|integer|min:1', 'operation_key' => 'required|uuid'])->validate(); + return DB::transaction(function () use ($actor, $id, $control): array { + $case = $this->desk->case($actor, $id, true, true); + abort_unless((int) $case->user_id === $actor->id, 403); + $this->desk->assertOpen($case); + $payload = $this->desk->decode($case->payload); + $history = $payload['investor_path']['supply_aggregates'] ?? []; + foreach ($history as $saved) { + if ($saved['operation_key'] === $control['operation_key']) return ['version' => $case->version, 'analysis' => $saved, 'replayed' => true]; + } + abort_unless((int) $case->version === (int) $control['version'], 409, 'O dossier mudou. Recupere-o antes de consultar.'); + $context = $this->state($case); + abort_if(count($context['opportunity_choices'] ?? []) > 1, 422, 'Esta consulta agregada de QA utiliza apenas o contexto comum de uma ideia própria.'); + $f = $context['fields']; + $territory = $f['locality_id'] ?? $f['admin_post_id'] ?? $f['district_id'] ?? $f['province_id'] ?? null; + abort_unless($territory, 422, 'Guarde primeiro a localização conhecida no dossier.'); + $analysis = [...app(ProactiveSupply::class)->aggregate($actor, $territory), 'context_revision' => $context['revision'], 'recorded_at' => now()->toIso8601String(), 'operation_key' => $control['operation_key']]; + $payload['investor_path']['supply_aggregates'] = [...$history, $analysis]; + DB::table('desk_cases')->where('id', $id)->update(['payload' => $this->desk->encode($payload), 'version' => $case->version + 1, 'updated_at' => now()]); + $this->desk->event($this->desk->case($actor, $id), $actor, 'investment_supply_aggregate_saved', ['context_revision' => $context['revision'], 'territory_id' => $territory, 'aggregate_only' => true]); + return ['version' => $case->version + 1, 'analysis' => $analysis, 'replayed' => false]; + }); + } + /** * @return array */ @@ -327,17 +433,18 @@ final class InvestorContext return $fields; } - /** - * @return array + /** @param array $filters + * @return array */ - public function options(string $query = ''): array + public function options(string $query = '', array $filters = []): array { $query = mb_substr(trim($query), 0, 120); $items = []; - foreach (Opportunity::published()->when($query, fn ($q) => $q->where('title', 'ilike', '%'.$query.'%'))->orderBy('title')->limit(51)->get(['id', 'title']) as $o) { - $items[] = ['key' => 'opportunity:'.$o->id, 'title' => $o->title, 'kind' => 'opportunity']; + $public = $filters ? app(InvestmentCatalogue::class)->query([...$filters, 'q' => $query]) : Opportunity::published()->when($query, fn ($q) => $q->where('title', 'ilike', '%'.$query.'%')); + foreach ($public->orderBy('title')->limit(51)->get(['opportunities.id', 'opportunities.title']) as $o) { + $items[] = ['key' => 'opportunity:'.$o->id, 'title' => $o->title, 'kind' => 'opportunity', 'relevance' => $filters ? 'Corresponde aos critérios explicitamente seleccionados.' : 'Correspondência com a pesquisa; confirme a pertinência antes de associar.']; } - if (request()->user()) { + if (request()->user() && (! $filters || $query !== '')) { $private = app(PortalProfileAccess::class)->scope(Opportunity::query(), request()->user())->where('status', '!=', 'published')->where('status', '!=', 'archived')->when($query, fn ($q) => $q->where('title', 'ilike', '%'.$query.'%'))->orderBy('title')->limit(51)->get(); foreach ($private as $o) { if (app(PortalProfileAccess::class)->canView(request()->user(), $o)) { @@ -345,13 +452,13 @@ final class InvestorContext } } } - if (config('existing-business.enabled')) { + if (config('existing-business.enabled') && (! $filters || $query !== '')) { foreach (ExistingBusiness::published()->when($query, fn ($q) => $q->where('public_title', 'ilike', '%'.$query.'%'))->orderBy('public_title')->limit(51)->get(['id', 'public_title']) as $o) { $items[] = ['key' => 'business:'.$o->id, 'title' => $o->public_title, 'kind' => 'business']; } } - return ['opportunities' => $items, 'search_limited' => count($items) > 50, 'sectors' => Sector::choices()->orderBy('name')->get(['id', 'name', 'slug']), + return ['opportunities' => $items, 'countries' => app(CountryCatalogue::class)->all(), 'search_limited' => count($items) > 50, 'sectors' => Sector::choices()->orderBy('name')->get(['id', 'name', 'slug']), 'parks' => app(InvestmentZones::class)->visible()->whereIn('category', ['industrial_park', 'zee', 'zfi'])->orderBy('name')->get(['id', 'name', 'category', 'version_no'])]; } @@ -414,7 +521,7 @@ final class InvestorContext * @param array $input * @return array */ - private function input(array $input): array + private function input(array $input, bool $draft = false): array { abort_if(array_diff(array_keys($input), ['complements', 'opportunity_choices', 'version', 'selection', 'declarations', 'replace_fields', 'preview_hash', 'operation_key', 'confirm', 'document_links', '_token']) !== [], 422, 'Campo de controlo desconhecido.'); @@ -440,8 +547,10 @@ final class InvestorContext 'opportunity_choices.*.source' => 'required|string|distinct|max:100', 'opportunity_choices.*.territory' => 'nullable|string|max:100', 'opportunity_choices.*.location_reason' => 'nullable|string|max:2000', 'opportunity_choices.*.confirm_location_change' => 'sometimes|boolean', 'version' => 'required|integer|min:1', 'selection' => 'present|array:portfolio,opportunity,sector,territory,park', - 'selection.*' => 'nullable|string|max:100', 'declarations' => 'nullable|array:project_title,project_summary,currency,expected_start_date,investor_origin,person_type,entity_stage,tax_residency_country,fiscal_residency_country,project_type,maturity_stage,'.implode(',', PrivateInvestmentPreparation::FIELDS), 'declarations.project_title' => 'nullable|string|max:200', 'declarations.project_summary' => 'nullable|string|max:5000', - 'declarations.currency' => 'nullable|regex:/^[A-Z]{3}$/', 'declarations.expected_start_date' => 'nullable|date_format:Y-m-d', 'declarations.investor_origin' => 'nullable|in:national,foreign,mixed', 'declarations.person_type' => 'nullable|in:singular,collective,sole_trader,consortium', 'declarations.entity_stage' => 'nullable|in:existing,being_formed', 'declarations.tax_residency_country' => ['nullable', 'string', app(CountryCatalogue::class)->rule()], 'declarations.fiscal_residency_country' => ['nullable', 'string', app(CountryCatalogue::class)->rule()], 'declarations.project_type' => 'nullable|string|max:100', 'declarations.maturity_stage' => 'nullable|string|max:100', + 'selection.*' => 'nullable|string|max:100', 'declarations' => 'nullable|array:promoter_entity_key,legal_name,legal_form,registration_number,products_services,investment_budget_min,investment_budget_max,project_title,project_summary,currency,expected_start_date,investor_origin,person_type,entity_stage,tax_residency_country,fiscal_residency_country,project_type,maturity_stage,'.implode(',', PrivateInvestmentPreparation::FIELDS), 'declarations.promoter_entity_key' => 'nullable|string|max:160', 'declarations.legal_name' => 'nullable|string|max:250', 'declarations.legal_form' => 'nullable|string|max:100', 'declarations.registration_number' => 'nullable|string|max:100', + 'declarations.products_services' => 'nullable|string|max:2000', 'declarations.project_title' => 'nullable|string|max:200', 'declarations.project_summary' => 'nullable|string|max:5000', + 'declarations.investment_budget_min' => 'nullable|numeric|min:0', 'declarations.investment_budget_max' => ['nullable', 'numeric', 'min:0', ...(! empty($input['declarations']['investment_budget_min']) ? ['gte:declarations.investment_budget_min'] : [])], + 'declarations.currency' => $draft ? 'nullable|regex:/^[A-Za-z]{0,3}$/D' : 'nullable|regex:/^[A-Z]{3}$/D', 'declarations.expected_start_date' => 'nullable|date_format:Y-m-d', 'declarations.investor_origin' => 'nullable|in:national,foreign,mixed', 'declarations.person_type' => 'nullable|in:singular,collective,sole_trader,consortium', 'declarations.entity_stage' => 'nullable|in:existing,being_formed', 'declarations.tax_residency_country' => ['nullable', 'string', app(CountryCatalogue::class)->rule()], 'declarations.fiscal_residency_country' => ['nullable', 'string', app(CountryCatalogue::class)->rule()], 'declarations.project_type' => 'nullable|string|max:100', 'declarations.maturity_stage' => 'nullable|string|max:100', 'replace_fields' => 'nullable|array', 'replace_fields.*' => 'string|in:'.implode(',', self::FIELDS)])->validate(); } @@ -480,7 +589,9 @@ final class InvestorContext $choices = app(InvestmentOpportunityChoices::class)->resolve($data['opportunity_choices'], $choices); $data['selection']['opportunity'] = $choices[0]['opportunity']['key'] ?? null; // Shared fields concern the first identified opportunity; other sites remain separate. + if ($choices !== []) { $data['selection']['territory'] = $choices[0]['territory']['key'] ?? null; + } if (array_key_exists('park', $data['opportunity_choices'][0] ?? [])) { $data['selection']['park'] = $choices[0]['park']['key'] ?? null; } @@ -511,7 +622,7 @@ final class InvestorContext } $selection[$slot] = $ref; } - $corridor = $choices[0]['corridor_key'] ?? (isset($selection['opportunity']) && $selection['opportunity']['kind'] === 'opportunity' + $corridor = array_key_exists('corridor_key', $choices[0] ?? []) ? $choices[0]['corridor_key'] : (isset($selection['opportunity']) && $selection['opportunity']['kind'] === 'opportunity' ? app(InvestmentCorridorContext::class)->key(Opportunity::whereKey($selection['opportunity']['id'])->firstOrFail()) : null); if ($corridor && isset($selection['territory'])) { abort_unless(app(InvestmentCorridorContext::class)->compatible($corridor, $selection['territory']['id']), 422, 'A localização não pertence ao corredor escolhido.'); @@ -579,9 +690,12 @@ final class InvestorContext $fields['special_zone_id'] = $selection['park']['id'] ?? ''; $fields['investment_regime'] = $selection['park']['fields']['investment_regime'] ?? 'general'; } + if (isset($fields['investment_budget_min'], $fields['investment_budget_max']) && $fields['investment_budget_min'] !== '' && $fields['investment_budget_max'] !== '') { + Validator::make(['declarations' => $fields], ['declarations.investment_budget_max' => 'numeric|gte:declarations.investment_budget_min'])->validate(); + } $replaced = []; foreach (array_unique([...array_keys($old['fields']), ...array_keys($fields)]) as $key) { - if (($old['fields'][$key] ?? null) !== ($fields[$key] ?? null)) { + if (($old['fields'][$key] ?? '') !== ($fields[$key] ?? '')) { $replaced[] = ['field' => $key, 'before' => $old['fields'][$key] ?? null, 'after' => $fields[$key] ?? null]; } } @@ -764,7 +878,7 @@ final class InvestorContext $original = $ctx; $ctx = app(InvestmentConsumerScope::class)->context($ctx, $opportunity); $f = $ctx['fields']; - $sim = Arr::except(Arr::only($f, self::FIELDS), ['sector', 'province', 'district', 'location', ...array_diff(PrivateInvestmentPreparation::FIELDS, ['total_investment', 'area_required', 'area_unit'])]); + $sim = Arr::except(Arr::only($f, self::FIELDS), ['promoter_entity_key', 'sector', 'province', 'district', 'location', ...array_diff(PrivateInvestmentPreparation::FIELDS, ['total_investment', 'area_required', 'area_unit'])]); // Entering this tool from an investment dossier selects the existing investment-analysis route. // The reconciliation preserves any purpose deliberately chosen in an existing simulator draft. $sim += ['journey_type' => 'investor', 'journey_type_label' => 'Avaliar o meu investimento', 'purpose' => 'simulate_only', 'purpose_label' => 'Apenas simular']; @@ -790,6 +904,7 @@ final class InvestorContext 'version' => 1, 'context_revision' => $ctx['revision'], 'consumer_opportunity' => $ctx['consumer_opportunity']['opportunity']['key'] ?? null, 'portfolio_origin' => $ctx['selection']['portfolio'] ?? null, + 'promoter_entity' => $ctx['promoter_entity'] ?? null, 'zone' => $zone ? Arr::only($zone, ['id', 'title', 'href', 'version', 'sha256', 'fields', 'analysis']) : null, 'provenance' => $ctx['provenance'], // Retain dossier options as provenance when no consumer is selected; scoped fields remain empty. diff --git a/app/Services/InvestorPath.php b/app/Services/InvestorPath.php index 319fb466..d415d25c 100644 --- a/app/Services/InvestorPath.php +++ b/app/Services/InvestorPath.php @@ -162,6 +162,7 @@ final class InvestorPath } $preparationTaskKeys = $opportunity !== null && ($owner || $manager) && app(PrivateInvestmentPreparation::class)->available() ? app(InvestmentPreparationWorkspace::class)->taskKeys($actor, $id, $opportunity) : null; + $supplyEnabled = (int) $case->user_id === $actor->id && config('investor-path.aggregate_supply_qa_enabled') && \App\Support\IsolatedQaDatabase::allowsSchemaChanges(); return ['funding_selections' => ($owner || $manager) ? array_values(array_filter($path['funding_selections'] ?? [], fn ($row) => ($row['opportunity'] ?? null) === $opportunity)) : [], 'preparation_action' => ($owner || $manager) && app(PrivateInvestmentPreparation::class)->available() ? app(InvestmentPreparationWorkspace::class)->continuation($actor, $id, $opportunity, request()->query('swot_action')) : null, 'private_investment' => $preparation, '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'], @@ -171,7 +172,9 @@ final class InvestorPath '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['href'] ?? '#'.$next['code']] : null, 'investment_context' => ($owner || $manager) ? [...$context, 'opportunity_choices' => $opportunity ? $context['opportunity_choices'] : $allChoices] : null, + 'can_set_promoter' => (int) $case->user_id === $actor->id && $case->organization_id === null && ! $case->closed_at, 'results' => $results, 'requests' => $requests, 'documents' => $documents, + 'supply_aggregate_enabled' => $supplyEnabled, 'supply_aggregates' => $supplyEnabled ? ($path['supply_aggregates'] ?? []) : [], 'fiscal_reports' => (int) $case->user_id === $actor->id && (count($allChoices) < 2 || $opportunity !== null) ? app(SimulationFormDrafts::class)->dossierReportSources($actor, $id, $opportunity) : [], 'land_report' => $landCase ? ['id' => $landCase->id, 'version' => $landCase->version, 'updated_at' => $landCase->updated_at?->toIso8601String(), @@ -324,6 +327,7 @@ final class InvestorPath 'snapshot_sha256' => $draft->snapshot_sha256, 'financial_snapshot' => $snapshot, 'context_opportunity' => $opportunity, 'currency' => $economic['currency'] ?? null, 'engine' => 'financial-calculators:v1', + 'preparation_snapshot' => Arr::only($economic, ['total_investment', 'secured_amount', 'planned_funding', 'requested_funding', 'approved_funding', 'planning_loan', 'annual_revenue', 'annual_operating_costs', 'investment_budget_min', 'investment_budget_max', 'initial_budget_snapshot', 'planning_assumptions_snapshot']), 'kind' => 'local_calculation_inputs', 'context_state' => 'current', 'context_revision' => $context['revision'], 'context_dependency_hash' => $context['dependency_hash'] ?? app(InvestorContext::class)->dependencyHash([]), '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.'); diff --git a/app/Services/ProactiveSupply.php b/app/Services/ProactiveSupply.php index 06b46823..215cbf1c 100644 --- a/app/Services/ProactiveSupply.php +++ b/app/Services/ProactiveSupply.php @@ -36,6 +36,39 @@ final class ProactiveSupply }); } + /** No names, contacts, row identifiers or free-text activity descriptions leave this boundary. + * @return array + */ + public function aggregate(User $actor, string $territory): array + { + abort_unless(config('investor-path.aggregate_supply_qa_enabled') && \App\Support\IsolatedQaDatabase::allowsSchemaChanges(), 404); + $path = app(InvestmentGeography::class)->path($territory); + abort_if($path === [], 422, 'Confirme primeiro a localização do dossier.'); + return $this->read($actor, function () use ($path, $territory): array { + $labels = app(EconomicReferenceCatalog::class)->activities()->groupBy('code')->map(fn ($rows) => $rows->pluck('label_pt_mz')->unique()->count() === 1 ? $rows->first()->label_pt_mz : null); + $scope = collect($path)->last(); + $query = function (string $id): Builder { + return DB::table('proactive_supply_observations as o')->whereIn('o.territory_id', app(InvestmentGeography::class)->descendants($id)); + }; + $base = $query($territory); + if (! (clone $base)->exists() && in_array($scope->location_type, ['locality', 'admin_post'], true)) { + $district = collect($path)->firstWhere('location_type', 'district'); + if ($district && $query($district->id)->exists()) { + $scope = $district; + $base = $query($district->id); + } + } + $counts = (clone $base)->selectRaw("count(DISTINCT entity_key) FILTER (WHERE duplicate_of IS NULL AND NOT identity_conflict) AS entities, count(*) FILTER (WHERE duplicate_of IS NOT NULL) AS repeated, count(*) FILTER (WHERE identity_conflict) AS uncertain")->first(); + $code = "CASE WHEN cae ~ '^[0-9.]{1,10}$' THEN cae ELSE '' END"; + $groups = (clone $base)->whereNull('duplicate_of')->where('identity_conflict', false)->selectRaw($code." AS code, count(DISTINCT entity_key) AS total, min(substring(source_date from '(19[0-9]{2}|20[0-9]{2})')) AS first_year, max(substring(source_date from '(19[0-9]{2}|20[0-9]{2})')) AS last_year") + ->groupByRaw($code)->orderByRaw($code)->limit(101)->get()->map(fn ($row) => ['code' => $row->code, 'label' => $row->code ? ($labels->get($row->code) ?? 'CAE '.$row->code.' — descrição por confirmar') : 'Actividade por classificar', 'total' => (int) $row->total, 'first_year' => $row->first_year, 'last_year' => $row->last_year])->all(); + return ['requested_territory' => ['id' => $territory, 'name' => collect($path)->last()->name], 'scope' => ['id' => $scope->id, 'name' => $scope->name, 'level' => $scope->location_type], + 'broader_context' => $scope->id !== $territory, 'entities' => (int) $counts->entities, 'repeated' => (int) $counts->repeated, 'uncertain' => (int) $counts->uncertain, + 'groups' => array_slice($groups, 0, 100), 'truncated' => count($groups) > 100, 'coverage_unknown' => true, 'limitations' => self::LIMITATIONS, + 'interpretation' => 'Os grupos ajudam a investigar actividades similares e complementares. A relação deve ser fundamentada; não demonstra concorrência efectiva, clientes, capacidade ou receitas. Uma entidade pode constar em vários grupos; não some os grupos.']; + }); + } + /** * @param array $input * @return array diff --git a/app/Services/VirtualDesk.php b/app/Services/VirtualDesk.php index bddd44b1..d9158c45 100644 --- a/app/Services/VirtualDesk.php +++ b/app/Services/VirtualDesk.php @@ -47,6 +47,16 @@ class VirtualDesk return $case->organization_id ? $this->represents($actor, $case->organization_id, $write) : (int) $case->user_id === $actor->id; } + /** The same effective membership used by dossier access; identity does not depend on country configuration. + * @return list> + */ + public function representedOrganizations(User $actor): array + { + return array_values(DB::table('memberships as m')->join('organizations as o', 'o.id', '=', 'm.organization_id')->where('m.user_id', $actor->id) + ->whereNull('m.deleted_at')->whereNull('o.deleted_at')->get(['o.id', 'o.name', 'o.version_no', ...(Schema::hasColumn('organizations', 'incorporation_country_code') ? ['o.incorporation_country_code'] : [])]) + ->unique('id')->map(fn ($row) => ['id' => $row->id, 'name' => $row->name, 'version' => $row->version_no, 'country' => $row->incorporation_country_code ?? null])->values()->all()); + } + public function case(User $actor, string $id, bool $write = false, bool $lock = false): \stdClass { $case = DB::table('desk_cases')->where('id', $id)->when($lock, fn ($q) => $q->lockForUpdate())->first(); diff --git a/config/investor-path.php b/config/investor-path.php index 5e11d35f..16876c41 100644 --- a/config/investor-path.php +++ b/config/investor-path.php @@ -4,5 +4,7 @@ return [ // Explicit opt-in after authenticated installation; never infer activation from schema/ready. 'private_preparation' => env('PRIVATE_INVESTMENT_PREPARATION_ENABLED', false), 'enabled' => env('INVESTOR_PATH_ENABLED', false), + // Owner-authorised aggregate experiment: isolated testing database only. + 'aggregate_supply_qa_enabled' => env('INVESTOR_AGGREGATE_SUPPLY_QA_ENABLED', false), 'definition_id' => '61000919-0000-4000-8000-000000000001', ]; diff --git a/docs/investmoz/unification/traceability-and-manual.md b/docs/investmoz/unification/traceability-and-manual.md index 2fb85c3d..5132f9ad 100644 --- a/docs/investmoz/unification/traceability-and-manual.md +++ b/docs/investmoz/unification/traceability-and-manual.md @@ -1,3 +1,7 @@ +## 15/11/2026 — entrega delimitada em preparação + +Dashboard existente e correcções transversais: autorizados para homologação. Delta Ofertas: excluído por conferência visual/móvel e interface editorial ainda pendentes. Preservar o módulo instalado em 13497892, sem novas entradas, fotografias L1 ou formulário imobiliário da Etapa B. A entrega é derivada directamente da revisão servida; 142 testes de interface, Wayfinder, build e tipos passaram. As 15 provas transversais aceites são reutilizadas. Backup/restauro actualizado conferiu 219 tabelas e 417 ficheiros. Integração e instalação continuam por executar; ver o mesmo relatório de apresentação/contexto para a delimitação e os recibos posteriores. + ## 14/11/2026 — hierarquia Administração/Dashboard corrigida e instalada em 96f51096 Revisão servida **`96f510965f70581a4b41dd94463f598b77dd7cf5`**, instalada pelo executor Git como correcção da organização expressamente pedida pela Tempo. **Administração** reúne os grupos Dashboard, Conteúdos e oportunidades, Cadastros e investimento, Pedidos e acompanhamento e Acessos e configuração. Os grupos sem destinos autorizados são omitidos. **Dashboard** contém as funções dos painéis, com `/dashboard` como visão geral; os cadastros administrativos permanecem nos outros grupos. O circuito editorial conserva nome e URL próprios. Operações administrativas foram retiradas de Mais/Área de trabalho sem perder destinos; funções pessoais mantêm o seu âmbito. diff --git a/docs/investmoz/v2/auditoria-portal/apresentacao-contexto-qa-20261115.md b/docs/investmoz/v2/auditoria-portal/apresentacao-contexto-qa-20261115.md new file mode 100644 index 00000000..6bbae560 --- /dev/null +++ b/docs/investmoz/v2/auditoria-portal/apresentacao-contexto-qa-20261115.md @@ -0,0 +1,226 @@ +## Entrega delimitada autorizada — 15/11/2026 + +**Estado: preparação concluída; integração/instalação ainda não executadas neste registo.** A autorização permite instalar dashboard e correcções transversais; Ofertas só poderia entrar com demonstração integral. Conferidos os recibos existentes: critérios 5/6 da Etapa B têm prova HTTP, mas a interface editorial e o critério 7 visual/móvel continuam não verificados. Por isso, **o delta de Ofertas foi excluído**, sem transformar quatro critérios anteriormente aceites em aceitação integral. + +Preparada a entrega no ramo `delivery/dashboard-transversal-20261115`, directamente sobre a revisão servida `13497892`, por selecção do conteúdo compatível de `8806312f`, `8c6ed625` e `7810ffc8`; não por integração integral dos seus antecessores de Ofertas. Preservados os ficheiros próprios de Ofertas, recursos/fotografias, contratos, rotas, mapas privados e navegação na versão instalada. O formulário canónico partilhado com esse módulo também fica preservado. O dashboard existente é mantido; não se presume outro incremento de dashboard ausente do delta. + +As dependências partilhadas foram conferidas separadamente. `TerritoryFields` mantém quatro níveis e mapa por defeito; só os consumidores financeiros usam as opções adicionais. Os rótulos de modalidade usados por Ofertas mantêm-se. Fontes/demografia/contexto recebem a correcção comum, sem alterar as permissões ou o contrato privado de Ofertas. O manifesto `outputs/transversal-install-20261115/scope-separation.json` regista as exclusões e os hashes dos ficheiros protegidos, a comparar no destino. + +Provas da separação: **142 testes de interface, zero falhas; geração Wayfinder real, compilação normal e tipos aprovados**. O leitor de testes demográficos foi adaptado para resolver o componente partilhado real, sem simular a sua saída. Reutilizadas as 15 provas autenticadas dos percursos transversais cujo código foi preservado. A consulta empresarial agregada mantém a guarda exclusivamente QA e não alarga acesso a dados internos na homologação. + +Backup actualizado concluído: 219 tabelas e 417 ficheiros. Restauro isolado conferido: contagens/checksums iguais, rede `none`, base separada na porta 55441, ficheiros e chaves/envelopes MFA recuperáveis. Zero migrações previstas; nenhuma alteração de dados, permissões, publicação ou notificações externas. Janela de instalação reservada pelo lock existente; `main` só pode avançar por fast-forward para a revisão separada, após reconferência. + +O histórico QA abaixo conserva o seu âmbito; não demonstra instalação de Ofertas nem autoriza publicação pública. + +--- + +# Apresentação e continuidade das consultas — candidata QA, 15/11/2026 + +Estado: **candidata QA com execução autenticada do saldo V01–V15; resultados por ecrã/largura abaixo, sujeitos à aceitação da experiência pelo responsável**. Base original `42fba8ba`, ramo `qa/public-context-20261115`. Sem instalação, publicação, alterações de permissões ou escrita em dados operacionais. Os testes posteriores usam exclusivamente a nova base sintética isolada `investor_intent_20261115_test`, em `127.0.0.1:55441`, incluindo a sua estrutura de teste. O trabalho concorrente da pasta principal e a conferência de Ofertas permanecem separados. + +## Condição de entrega — conferência dos consumidores afectados + +Decisão expressa do responsável: a instalação depende de cobertura consolidada dos ecrãs e percursos afectados. Um componente aprovado não aprova automaticamente os seus consumidores. A autorização existente continua limitada a implementação e validação em QA. + +Na mesma matriz, cada consumidor deve conservar o seu estado **alinhado, corrigido, divergente ou não verificado**, com versão, ambiente, evidência e limite da prova. «Corrigido» identifica uma alteração demonstrada; não substitui a aceitação integral do percurso. Sem prova individual suficiente, o estado é «não verificado». + +Conferir intenção; etapas e ajuda; próxima acção; reutilização de entidade/localização/moeda/orçamento; selectores e filtros no cliente e servidor; pertinência dos resultados; coerência dos valores; gravação/recuperação/regresso/recarregamento/retoma autenticada; isolamento de contas/separadores/oportunidades; computador e telemóvel; preservação de dados, funcionalidades, permissões e históricos. + +As tabelas históricas abaixo descrevem provas dirigidas, não uma declaração de alinhamento de todos os ecrãs. A candidata não pode ser disponibilizada como correcção transversal enquanto existirem divergências ou verificações pendentes deste âmbito. Decisões jurídicas, dependências externas e funcionalidades futuras ficam separadas e não ampliam esta conferência. + +Quando a conferência visual autenticada estiver impedida, registar o erro e disponibilizar uma prévia QA à equipa, com os percursos e operações a executar. Renderização sintética, testes automáticos e capturas de componentes não substituem essa prova. Não instalar para obter a conferência sem autorização expressa. + +### Conferência dirigida dos quatro percursos — 15/11/2026 + +Esta passagem actualiza as linhas existentes MASTER-600240dd-0001/0018, MASTER-e1169a77-0026 e INE-DEMO-01; não cria outro inventário. «Corrigido» abaixo refere-se apenas ao comportamento e à evidência indicados. As colunas visuais não herdam a aprovação do componente nem da API. + +Tabela de partida, anterior às conferências autenticadas registadas abaixo. **Não usar os seus «não verificado» como pedido para repetir provas entretanto obtidas. O saldo actual é a tabela «Execução do saldo V01–V15»**, que substitui as pendências genéricas desta tabela, sem eliminar o histórico. + +| Percurso / ecrã | Estado funcional no recorte | Evidência disponível | Computador autenticado | Telemóvel autenticado / retoma | +| --- | --- | --- | --- | --- | +| Hotel — entrada e editor de contexto (`/investimentos/iniciar`, `/{id}/contexto/editar`) | Corrigido: ideia própria com sector confirmado, orçamento em intervalo e localização independente de anúncios/corredores | `InvestorIntentContinuityTest`, `preparation-intent.test.mjs`, renderização do editor em `public-information.test.mjs` | Não verificado; prévia sintética anterior em 1280 px | Não verificado; prévia sintética anterior em 360 px, sem gravação | +| Hotel — entidade existente no dossier (`/investimentos/{id}#entidade-promotora`) | Corrigido: associação autorizada, versão da fonte, dados recuperados; sem duplicar empresa, alterar dono ou membros | `InvestorPromoterContinuityTest`, incluindo isolamento, fonte alterada e organização com representação revogada | Não verificado | Não verificado | +| Hotel — comparação opcional (`/{id}/forma-juridica`) | Corrigido: guardar alternativa e continuar na preparação da mesma entidade; distinção entre entidade existente e por constituir recuperada do payload | `InvestorPromoterContinuityTest`; PHPStan detectou variável não inicializada, corrigida nesta passagem | Não verificado | Não verificado | +| Hotel — preparar empresa (`/{id}/preparar-empresa`) | Corrigido no servidor: recupera dados, preserva notas e forma deliberada; não altera a forma da empresa constituída | `InvestorPromoterContinuityTest`; regressões `company-preparation` e `company-comparison` | Não verificado | Não verificado | +| Hotel — simulador, percurso assistido | Divergente: a estrutura financeira ainda reúne ferramentas e tratamentos; sete ecrãs assistidos, ajuda por actividade e retoma da etapa ainda não demonstrados | Leitura delimitada de `simulation-form.tsx`: ferramentas e oito blocos fiscais partilham condições `financial`/`tax`. Não classificar essa etapa como alinhada | Não verificado | Não verificado | +| Hotel — calculadora e origem do financiamento | Corrigido no recorte: detecta divergências sem arredondar valores nem assumir desconhecido como zero; escolha explícita de origem; CSV e retorno impedidos com divergência; valores demonstrativos retirados dos novos rascunhos | `planning-finance-context.test.mjs`; tipos; histórico guardado conservado | Não verificado | Não verificado | +| Hotel — guardar e recuperar cenário / devolver ao dossier | Corrigido no recorte API: cenário explicitamente declarado, intervalo separado, mesma evidência recuperada e retorno repetível sem duplicação | `InvestorIntentContinuityTest`: snapshot financeiro exacto, resultado único, moeda e isolamento da leitura do rascunho | Não verificado; não equivale a clicar em guardar/retomar | Não verificado, incluindo retoma após autenticação | +| Hotel — relatório | Não verificado integralmente; testes do gerador preservam intervalo e resultados; não demonstram o relatório completo da sessão autenticada | `investor-dossier-report.test.mjs`; saldos da preparação assistida e períodos fiscais continuam abertos | Não verificado | Não verificado | +| Agronegócio — Matola Rio–Sede / Boane / Maputo Província | Corrigido no recorte API: hierarquia sintética identificada, 1–5 milhões MZN, sem oportunidade, corredor ou total inferido | `InvestorIntentContinuityTest`, dois sectores; todos os dados do ensaio são sintéticos | Não verificado | Não verificado | +| Agronegócio — consulta empresarial agregada no dossier | Corrigido no recorte QA: totais por actividade/localização, âmbito distrital identificado, repetidos e incertos separados; nomes/contactos/origem reservados não transferidos | `InvestorIntentContinuityTest`; flag privada desactivada por defeito e guarda da base QA; histórico por dossier | Não verificado | Não verificado | +| Agronegócio — simulação e retoma | Corrigido no recorte API: valores declarados e snapshot recuperados, resultado devolvido ao mesmo dossier sem duplicação. Percurso assistido completo continua divergente como em Hotel | `InvestorIntentContinuityTest`; teste não substitui utilização do simulador no navegador | Não verificado | Não verificado | +| Instituições — lista (`/fundos`) | Corrigido no recorte: Banca/Banco comercial, incompatibilidade estrutural, vazio válido, desconhecido/documentado, presença/cobertura e janela | `FundingCriteriaCoherenceTest`; consulta partilhada e resposta HTML/API testadas | Não verificado | Não verificado | +| Instituições — filtros de categoria/tipo e alteração de critérios | Corrigido: opções dependentes; preservação dos critérios válidos; resultados anteriores separados até nova pesquisa; incompatibilidade corrigida só por escolha explícita | `funding-journey-coherence.test.mjs`, executa handlers da página real com transporte simulado | Não verificado | Não verificado | +| Instituições — locais de interesse | Corrigido no recorte: distrito sem província não abre consulta nacional; consumidor usa hierarquia comum; servidor rejeita hierarquia contraditória | `FundingCriteriaCoherenceTest`; `territory-search-select.test.mjs`; componente usado no consumidor confirmado, sem presumir prova visual | Não verificado | Não verificado | +| Instituições — detalhe e regresso (`/fundos/{id}`) | Corrigido nesta passagem: retorno preserva pesquisa, sector, estado, certeza, tipo, hierarquia e página; limpeza territorial explícita não herda o dossier | `FundingCriteriaCoherenceTest`: selecção recebida pelo detalhe comparada com todos os critérios enviados | Não verificado | Não verificado | +| Instituições — guardar interesse / continuar dossier | Não verificado neste delta; testes dos filtros não demonstram esta operação | Reutilizar provas anteriores compatíveis; executar selecção e retoma da candidata antes do fecho | Não verificado | Não verificado | +| Demografia — síntese e série (`/localizacoes/demografia`) | Corrigido no recorte: fonte/edição/período separados; originais preservados; grupos incompletos e anos ausentes sem valores inventados | Provas de reconciliação `21ac7eb`, `public-information.test.mjs`; prévia de componentes anterior em computador/360/390 px | Não verificado na página autenticada da candidata | Não verificado integralmente | +| Demografia — contexto do editor/dossier/simulador | Corrigido no recorte API: ausência local recupera distrito com âmbito explícito, sem converter população distrital em local; respostas tardias isoladas | `InvestorIntentContinuityTest` e testes dirigidos do componente | Não verificado individualmente nos três consumidores | Não verificado individualmente nos três consumidores | +| Demografia — continuar para ideia e recuperar | Corrigido na construção do URL; intenção territorial transportada sem filtros comerciais. Utilização completa não verificada | `public-information.test.mjs`, `preparation-intent.test.mjs`; gravação da ideia testada separadamente, não como prova de clique ponta a ponta | Não verificado | Não verificado | + +**Recibos desta passagem:** `outputs/investor-intent-20261115/backend.log` — 12 testes / 412 asserções; `frontend.log` — 137 testes; `phpstan.log` — aprovado, zero erros. Os testes de API usam transacções revertidas na base sintética identificada acima. As provas são específicas dos comportamentos descritos, não 149 percursos completos. + +**Impedimento visual observado:** inventário do conector devolveu `Browsers: Error: The browser access host is unavailable`. O controlo nativo do Edge funciona e leu o URL da janela separada: `file:///C:/laragon/www/portal-investidor-public-context-qa-20261115/outputs/investor-intent-20261115/editor-preview.html`. Essa prévia declara que não tem autenticação, gravação, consultas nem cartografia real. A sessão do portal com alterações por guardar foi preservada. Não se atribui o impedimento ao portal ou ao navegador; não se repetiram reinícios nem alterações de configuração. + +**Saldo que impede a entrega transversal:** concluir a divergência da preparação financeira assistida e o contrato de retoma da etapa; conferir ajuda e pressupostos por actividade, período/cobertura fiscal e relatório no mesmo percurso; executar os ecrãs acima numa sessão QA da candidata em computador e telemóvel, incluindo regresso, recarregamento e nova autenticação. Os testes de isolamento no servidor não demonstram, por si só, isolamento entre separadores na interface. Nenhuma instalação ou aceitação funcional integral resulta desta passagem. + +## Execução do saldo V01–V15 — resultados na mesma candidata + +Actualização após a interrupção final do controlo Windows. **Instalação suspensa.** Não houve nova tentativa de navegador nesta actualização documental. O erro observado foi: `Computer Use has been stopped for this turn because it could not determine the current browser URL on Windows with enough confidence to enforce policy.` O controlo interrompeu o clique em «Voltar aos fundos e programas»; não foi observada a página de destino. Isto não demonstra erro do portal, perda de filtros ou falha de MFA. + +Candidata local: `C:/laragon/www/portal-investidor-public-context-qa-20261115`, base Git `8c6ed625` **mais o delta QA ainda não consolidado em novo commit**; URL `http://127.0.0.3:18715`. Build servido: `build-qa-opportunities/assisted-mobile`, entrada `assets/app-f0MgDyAw.js`; SHA256 do manifesto `709989dd62b65b72eefb4b0394f776adbf0a1e340a7487a2d013170fe4e6cf03`. O SHA base, sozinho, não identifica esta candidata. Conferir esta identidade antes da execução manual; não instalar nem substituir pela homologação. Usar a conta sintética habitual, sem registar credenciais. + +**Provas preservadas, fora da repetição:** Hotel com empresa existente, orçamento 2 milhões, mobilizado 1 milhão, diferença 1 milhão, receita anual 7,5 milhões, custo anual 2 milhões, gravação/recarga/retorno e HTML descarregado; escolha explícita de modelo/estimativas; bloqueio de cobertura 2027/2026; edição e continuação móvel de Receitas → Tesouraria. Agronegócio com entidade por constituir, actividade/localização/intervalo recuperados, modelo agrícola e recarga/retorno. Banca/Banco comercial com um resultado compatível, referência/produto/versão conservados no mesmo dossier. Demografia distrital identificada no dossier, incluindo leitura móvel, sem atribuição à localidade. A largura dos selectores financeiros foi corrigida e reconferida a 390 × 844. Limpar província desactivou os níveis inferiores e separou resultados anteriores dos critérios por aplicar. Estas provas não encerram as acções diferentes abaixo. + +Cada linha refere-se a requisitos já existentes; **V01–V15 são identificadores de passos de verificação, não novos requisitos ou outra auditoria**. Executar só o saldo, em computador e em 390 × 844 quando a linha indicar ambos. «NÃO VERIFICADO» não equivale a «FALHOU». + +| Passo / requisito existente | Ecrã | Acção verificada | Critério esperado | Resultado executado e evidência | +| --- | --- | --- | --- | --- | +| V01 · MASTER-e1169a77-0026 | `/fundos` → `/fundos/{id}` → «Voltar aos fundos e programas» | Na pesquisa A, escolher explicitamente critérios válidos (categoria/tipo, tipo de registo, presença/cobertura, território, sector, necessidade, certeza, janela, históricos, palavra-chave e página quando existirem). Abrir o resultado e clicar no retorno da própria página. Repetir o retorno em largura móvel. | Recuperar exactamente os critérios efectivamente escolhidos e a página aplicável; resultado corresponde à pesquisa A. Nenhum critério novo herdado do dossier ou de outra pesquisa. Critérios sem resultados não são alargados silenciosamente. | Critérios e resultado bancário recuperados no retorno real do detalhe. 1440 px: **APROVADO**, 2026-11-15T15:41:27.944Z, evidência `V01-1440-1794757287944`; 390 px: **APROVADO**, 2026-11-15T15:41:54.875Z, evidência `V01-390-1794757314875` | +| V02 · MASTER-e1169a77-0026 / MASTER-600240dd-0018 | Duas abas de `/fundos`, detalhe e regresso | Manter A no contexto agrícola e abrir B com categoria/localização diferentes, escolhidas explicitamente. Voltar ao detalhe/lista de A e recarregar A; conferir também B. | Cada URL e formulário conserva os seus critérios; não entram tipos, distritos, sector, janela ou contexto de B em A. A selecção guardada no dossier não altera a pesquisa alheia. | Pesquisas A/B conservaram critérios e contextos separados após retorno e recarga. 1440 px: **APROVADO**, 2026-11-15T16:28:25.029Z, evidência `V02-1440-1794760105052`; 390 px: **APROVADO**, 2026-11-15T16:29:13.443Z, evidência `V02-390-1794760153468` | +| V03 · MASTER-e1169a77-0026 | `/fundos`, computador e móvel | Pela interface, tentar uma combinação estruturalmente contraditória e uma combinação válida sem registos; alterar categoria e conferir resolução do tipo incompatível. | Mensagens distintas para combinação inválida e zero resultados válido. Sem banco apresentado como fundo por inferência, sem corretoras como correspondência, sem perda de critérios independentes. | Combinação contraditória distinta do vazio válido; mudança de categoria resolveu apenas o tipo dependente. 1440 px: **APROVADO**, 2026-11-15T15:41:50.001Z, evidência `V03-1440-1794757310001`; 390 px: **APROVADO**, 2026-11-15T15:43:11.560Z, evidência `V03-390-1794757391560` | +| V04 · MASTER-600240dd-0018 | `/simulador-fiscal?context={dossier}` e dossier Hotel/Agronegócio | Guardar a etapa de cada dossier; sair e autenticar normalmente a mesma conta sintética; reabrir cada dossier e continuar. | Recuperar etapa, valores, modelo, ordem das escolhas e contexto próprios; sem exemplos, nova pergunta sobre dados já válidos ou duplicação de resultados. | Logout/login normal recuperou Hotel 7,5 milhões e Agronegócio 2 milhões, respectivos modelos e etapa. 1440 px: **APROVADO**, 2026-11-15T15:45:04.572Z, evidência `V04-1440-1794757504572`; 390 px: **APROVADO**, 2026-11-15T16:15:11.676Z, evidência `V04-390-1794759311711` | +| V05 · MASTER-600240dd-0018 | Hotel e Agronegócio em duas abas; acesso de segunda conta QA autorizada | Editar um pressuposto sintético de A, manter B aberto, regressar/recarregar; usar uma segunda conta QA já autorizada para tentar os URLs privados directos de A. Não criar permissões. | Sem mistura entre dossiers/abas; divergência de versão tratada sem sobrescrever edição deliberada; segunda conta sem acesso a rascunho, relatório ou documento privado alheio. | Edição concorrente recusada com 412 e entrada local conservada; dossiers separados; segunda conta sem acesso ao dossier ou rascunho privados. 1440 px: **APROVADO**, 2026-11-15T16:24:03.041Z, evidência `V05-1440-1794759843064` | +| V06 · MASTER-600240dd-0001 / MASTER-600240dd-0018 | Dossier Hotel sintético adicional → entidade por constituir → `/preparar-empresa` → simulador → relatório | Verificar a variante Hotel com entidade por constituir, usando nova preparação sintética e preservando o Hotel existente com empresa associada. Guardar e retomar dados propostos e continuar até relatório. | Sem cadastro legal fictício, repetição da comparação obrigatória ou transferência do dono; forma escolhida e dados recuperados no mesmo novo dossier; valores do Hotel existente preservados. | Hotel por constituir guardou entidade, pressupostos, recuperação e relatório no mesmo dossier. 1440 px: **APROVADO**, 2026-11-15T16:03:54.766Z, evidência `V06-1440-1794758634766` | +| V07 · MASTER-600240dd-0018 | Agronegócio → Receitas/Tesouraria/Revisão → relatórios do mesmo dossier | Em móvel, recuperar o modelo agrícola e os pressupostos já guardados; concluir revisão e gerar/consultar o relatório agrícola. Não redigitar nem adoptar números novos por rotina. | Modelo agrícola, receita 2 milhões e intervalo 1–5 milhões MZN recuperados; total e financiamento desconhecidos não se tornam zero ou valor único. Relatório pertence ao dossier agrícola, sem pressupostos do Hotel. | Relatório agrícola descarregado com receita 2 milhões, intervalo 1–5 milhões e custos desconhecidos preservados. 1440 px: **APROVADO**, 2026-11-15T15:45:15.049Z, evidência `V07-1440-1794757515049`; 390 px: **APROVADO**, 2026-11-15T15:45:59.234Z, evidência `V07-390-1794757559234` | +| V08 · MASTER-600240dd-0001 | Associação de entidade, comparação jurídica opcional e preparação de empresa | Conferir estes controlos em móvel. Na comparação, recuperar escolha anterior e usar «continuar preparação»; em empresa existente, não alterar a forma jurídica do cadastro. | Controlos utilizáveis, comparação opcional, dados e edições deliberadas preservados; regresso ao dossier/viabilidade executável. | Comparação opcional e entidade utilizáveis em móvel; forma/nome recuperados; cadastro da empresa existente não substituído. 390 px: **APROVADO**, 2026-11-15T16:00:27.433Z, evidência `V08-390-1794758427433` | +| V09 · MASTER-600240dd-0018 | Novo rascunho QA → acção de retorno antes de Financiamento | Verificar a orientação acrescentada «Conferir financiamento», seguir a acção, deixar montantes desconhecidos e guardar/voltar. | Próxima acção executável na etapa correcta, sem exigir inventar montantes; contrato de gravação e versão continua aplicado. | Orientação abriu Financiamento; gravação e retorno concluídos sem inventar montantes desconhecidos. 1440 px: **APROVADO**, 2026-11-15T16:04:46.409Z, evidência `V09-1440-1794758686409` | +| V10 · MASTER-600240dd-0001 | `/investimentos/{id}/preparar-empresa` | Reabrir a preparação guardada e conferir a mensagem sobre modelos, em computador/móvel, sem alterar os dados. | Sem referência interna aos «sete exemplares/complemento»; indisponibilidade de modelos e distinção entre preparação e registo continuam claras; dados anteriores conservados. | Aviso histórico apresentado sem referência aos sete exemplares; nome e sede anteriores preservados. 1440 px: **APROVADO**, 2026-11-15T16:05:10.181Z, evidência `V10-1440-1794758710181`; 390 px: **APROVADO**, 2026-11-15T16:06:43.704Z, evidência `V10-390-1794758803704` | +| V11 · MASTER-600240dd-0018 | Simulador → Enquadramento fiscal → Revisão | Conferir em móvel pesquisa, adição/retirada de uma operação e preservação dos dados. Na revisão, conferir síntese, diferenças reais e próxima acção. Se demonstrar cálculo, escolher explicitamente período coberto e valores sintéticos; não substituir o cenário 2027 guardado. | Só operações escolhidas montadas; restantes pesquisáveis; dados retirados da análise mantidos no histórico; sem códigos internos, exemplos automáticos ou comparação vazio→vazio. Separar rascunho de cálculo guardado e manter coerência com relatório. | Operação fiscal pesquisada, retirada e reposta sem perder entradas; 2027 recuperado; referência técnica fechada no detalhe da versão. 390 px: **APROVADO**, 2026-11-15T16:24:32.637Z, evidência `V11-390-1794759872659` | +| V12 · MASTER-600240dd-0018 | Dossier agrícola → «Consultar e guardar análise agregada» | Abrir/guardar a análise com a localização existente, recarregar e recuperar a mesma evidência; conferir em móvel. | Totais/actividades e âmbito conhecidos ou cobertura desconhecida explícitos; duplicados separados; nenhum nome, contacto ou lista interna exposto; ausência de registos não significa ausência de oferta. | Análise agregada guardada e recuperada com cobertura desconhecida explícita, sem nomes/contactos internos. 1440 px: **APROVADO**, 2026-11-15T15:45:22.425Z, evidência `V12-1440-1794757522425`; 390 px: **APROVADO**, 2026-11-15T15:46:06.294Z, evidência `V12-390-1794757566294` | +| V13 · INE-DEMO-01 | `/localizacoes/demografia` e detalhe de originais; consulta no editor e simulador | Na consulta completa, seleccionar explicitamente Boane QA e 2026–2027; abrir evolução e originais. Conferir os consumidores editor/simulador, em computador e móvel, sem repetir a síntese do dossier. | 12.345→12.600, diferença de período 255 (não taxa anual); fonte/edição/unidade/projecção explícitas, originais preservados. Localidade sem observações não recebe população distrital sem aviso. Anos/parcelas ausentes continuam sem dados. | 12.345→12.600 e diferença de período 255; originais conservados; contexto distrital identificado no editor e simulador; rótulos e selector dependente reconferidos. 1440 px: **APROVADO**, 2026-11-15T16:18:31.360Z, evidência `V13-1440-1794759511387`; 390 px: **APROVADO**, 2026-11-15T16:20:49.768Z, evidência `V13-390-1794759649790`; rótulos: V13-labels-1440-1794759923605, V13-labels-390-1794759934158 | +| V14 · INE-DEMO-01 / MASTER-600240dd-0001 | Demografia → preparar ideia → contexto/dossier → simulador | Usar a acção territorial da consulta, confirmar sector/intenção e guardar/retomar a preparação sintética nos dois tamanhos. No percurso, conferir os selectores de país/moeda/localização efectivamente usados (lista directa, prefixo de três caracteres, acentos e código curto MZ). | Território explícito transportado sem filtros financeiros/comerciais alheios; sector proposto confirmado, anúncio/zona opcionais; hierarquia pode parar no nível conhecido, códigos canónicos e edições mantidos. Continuação no dossier sem perguntas repetidas. | Origem Boane transportada até ao simulador; país por MZ, moeda por prefixo e nível distrital guardados e recuperados. 1440 px: **APROVADO**, 2026-11-15T16:19:56.796Z, evidência `V14-1440-1794759596823`; 390 px: **APROVADO**, 2026-11-15T16:22:14.914Z, evidência `V14-390-1794759734939` | +| V15 · MASTER-600240dd-0001 / MASTER-600240dd-0018 | Página inicial → «Criar investimento» → `/investimentos/iniciar` → editor de contexto | Nos dois tamanhos, entrar pela intenção de criar, escolher sector/localização/intervalo/moeda e guardar uma preparação sintética nova; distinguir da acção «Procurar oportunidades». Conferir regresso e edição do contexto. | Abre preparação da ideia, nunca exige procurar/associar anúncio ou escolher corredor/zona; reutiliza apenas escolhas explícitas e conserva o intervalo. Contexto alterável sem apagar valores deliberados. | Entrada Criar investimento abriu preparação própria sem anúncio ou zona, preservando localização e intervalo orçamental. 1440 px: **APROVADO**, 2026-11-15T15:49:14.009Z, evidência `V15-1440-1794757754009`; 390 px: **APROVADO**, 2026-11-15T15:55:37.546Z, evidência `V15-390-1794758137546` | + +### Registo da execução técnica + +O Codex executa estas linhas através de Playwright local autorizado, sem depender da recuperação do conector. Para cada V01–V15, os recibos conservam **executante, data/hora, identidade da candidata/build, ecrã/largura, acção efectivamente realizada, resultado observado e evidência**, passando a APROVADO, FALHOU ou mantendo NÃO VERIFICADO com impedimento concreto. A equipa mantém a avaliação de negócio e a aceitação da experiência. Uma captura de um componente não encerra os outros consumidores da linha. Não colocar credenciais, códigos MFA ou dados reais no registo. + +Fecho condicionado: não iniciar outra auditoria, refazer provas acima preservadas ou instalar para obter a conferência. Uma falha nova deve indicar causa delimitada e correcção indispensável; verificar apenas os efeitos afectados. **A instalação permanece suspensa até encerrar as divergências de orientação/mensagem e todas as verificações deste saldo**, com aceitação do responsável. Dependências jurídicas ou funcionalidades futuras permanecem fora deste saldo de apresentação/continuidade. + + +### Execução técnica do saldo — Playwright local + +Executante: Codex, autenticação normal com contas sintéticas, exclusivamente em `http://127.0.0.3:18715` e na base `investor_intent_20261115_test`. Chromium local, controlador Playwright 1.65.1; contextos novos, sem perfil operacional, permissões novas ou controlos de segurança desactivados. Computador 1440 × 1000; móvel **emulado** 390 × 844, sem ensaio em dispositivo físico. + +A tabela V01–V15 acima contém o resultado executado por largura. Recibos e capturas: `outputs/investor-intent-20261115/browser-acceptance/*-results.json` e respectivos PNG/TXT. As tentativas anteriores permanecem nos recibos; o estado apresentado usa a última execução de cada passo/largura. Não confundir erros de sincronização do ensaio com defeitos comprovados do produto. + +Candidata: ramo `qa/public-context-20261115`, base Git `8c6ed625`. O delta QA e este relatório identificam a revisão preparada para apreciação. Provas iniciais no build `assisted-mobile`; correcções de mensagem em `acceptance-corrections`; build actualmente servido `build-qa-opportunities/acceptance-labels`, manifesto SHA256 `c0c8eb36c0b531613367d4c1c154aa59ab154289b0e459ef57393a3cd3ed8790`. Os recibos posteriores também identificam os assets usados. Nenhuma instalação no activo. + +Correcções delimitadas: apresentação de aviso histórico da preparação da empresa sem modificar a definição guardada; erro de leitura do rascunho distingue limite de pedidos/sessão/servidor de edição concorrente, preservando o bloqueio de escrita; comparação demográfica usa o selector pesquisável existente com distrito dependente da província, preservando quatro locais; origem territorial da demografia recupera a hierarquia no editor sem substituir localização guardada; referência técnica do questionário conservada num detalhe fechado do resumo. Regressão territorial dirigida: 1 teste/33 asserções; selector: 1 teste; aviso empresarial: 7 testes. Tipos, lint, PHPStan dirigido e compilação passaram. As provas técnicas aceites anteriores não foram repetidas por rotina. + +Saldo executado: 15/15 passos aprovados nas larguras previstas. O ensaio adicional de falha de leitura `V04-recovery-error` comprovou mensagem específica, ausência de gravações durante a falha e recuperação dos valores originais. Os testes exercitam a interface real autenticada; a apreciação de negócio e a autorização de instalação continuam separadas. + +**Saldo técnico V01–V15 encerrado nas condições indicadas; instalação não autorizada e continua suspensa.** A avaliação de negócio e a aceitação da experiência cabem ao responsável. Não equivale a aceitação integral do portal nem a teste num dispositivo móvel físico. Limitações jurídicas e futuras funcionalidades continuam fora deste saldo. + + +## Causas e correcções + +### Incremento da preparação assistida — evidência do anexo de 15/11/2026 + +O anexo `7a2b72ba-ccbb-4aad-a55b-3f30739e78c7/Pasted text.txt`, identificado pelo responsável como «Texto colado(7).txt», fica associado à divergência já aberta. SHA256 `489473c1e3fdc69ff7cc786dcedb33184ddd74b4a6c9fb97d99f130ae0a2e943`. O texto mostra oito etapas anteriores, empréstimo demonstrativo, tratamentos indiscriminados e códigos internos. Não se atribui esse ecrã a uma revisão exacta sem evidência da origem. + +**Implementação desta passagem, apenas QA:** o percurso simples de investimento passa a oito ecrãs: intenção/entidade/localização; mercado; investimento inicial; financiamento; receitas/custos; tesouraria/cenários; enquadramento fiscal; resultados/próximos passos. Investimento inicial e financiamento ficam separados conforme a sequência do novo anexo; os dois primeiros ecrãs conservam a preparação contextual anterior. O modo avançado e os restantes tipos de percurso conservam as capacidades existentes, sem se presumir a sua aceitação visual por esta alteração. + +- `simulationFieldsForSection` serve a apresentação, validação e revisão do percurso simples. Factos financeiros desconhecidos não impedem continuar uma preparação privada; cálculos continuam sujeitos às suas condições. `preparation_step` é gravado no contrato existente e recuperado com o rascunho. Mudança deliberada de percurso reinicia a navegação, conservando os valores. +- O orçamento inicial reutiliza a aritmética decimal existente para instalações, equipamento, preparação e fundo de maneio, sem valores demonstrativos. A soma só substitui o total do cenário por escolha explícita; o intervalo original fica separado. Financiamento previsto, solicitado, aprovado e mobilizado têm campos distintos; os três primeiros não são somados ao montante mobilizado. +- A ajuda de receitas/custos exige escolher o modelo. Hotel usa quartos, preço/noite, ocupação e dias anuais; Agronegócio usa unidades vendáveis, preço e ciclos anuais. São pressupostos editáveis, guardados e adoptados apenas pela acção «Usar». Custos incompletos não se tornam zero. A simulação de empréstimo no percurso simples depende da pergunta «Pretende estudar um empréstimo neste cenário?». +- A etapa de financiamento deixa de montar os componentes fiscais. O percurso simples apresenta as operações fiscais por escolha explícita; o componente de IVA preserva 32 tratamentos e o de IRPC nove operações complementares através do selector pesquisável comum «Adicionar outra operação». Retirar uma operação da análise não elimina os respectivos dados e históricos. Não se deduz aplicabilidade pelo título ou sector. +- O IVA mensal recusa divergência entre ano fiscal e primeiro mês da projecção; mantém a cobertura documentada de 2026. IRPC normal e ISPC trimestral sinalizam divergência entre o ano do enquadramento e o da preparação; a correspondência exige escolha explícita e os validadores de cobertura mantêm-se. A estimativa anual de IRPC não oferece o recorte de 2026 para outro ano. Nenhum ano é alterado automaticamente. +- O histórico distingue rascunho guardado de simulação calculada e guardada. O retorno ao dossier identifica «pressupostos financeiros», em consonância com o tipo de evidência existente. O resultado preserva uma selecção dos pressupostos económicos autorizados, orçamento discriminado e modelo de receitas/custos para o relatório privado, sem copiar identidade ou outros campos pessoais para essa selecção. Filtragem por dossier/oportunidade e exportadores Word/impressão existentes são conservados. +- Códigos do desenvolvimento retirados dos títulos afectados de importações, apuramento de aquisições e estimativa anual; fontes detalhadas de importação ficam no componente comum de evidência. Não se declara revisto todo o texto de todas as operações avançadas. + +**Estado de aceitação:** implementado e com provas dirigidas; **não verificado integralmente na interface**. Os testes dos controlos reais de orçamento, ajuda de receitas e selector fiscal usam estado/eventos React e transporte simulado; não equivalem a uma sessão de navegador. Os testes de relatório conferem pressupostos, valores desconhecidos, histórico e exclusão de dados de outra oportunidade. + +**Retoma posterior à interrupção por Esc:** provas técnicas preservadas, sem nova execução. A prévia local foi ligada ao build assistido já compilado em `public/build-qa-opportunities/assisted-current`, conservando os assets anteriores; não houve alteração do produto nem instalação no activo nesta retoma. O controlo nativo leu `http://127.0.0.3:18715/login`; a abertura directa do dossier sintético Hotel regressou a esse login. Não foi observada a sessão autenticada que o responsável indicou ter aberto. A enumeração mantém as duas janelas Edge existentes; o Firefox está minimizado e a leitura devolveu `window is minimized; call activate_window, refresh with get_window, then retry get_window_state`. Não foram invocadas APIs não documentadas nem alteradas portas/configurações dos navegadores. + +As tentativas de repor a vista normal não permitiram demonstrar as operações do investidor; essa frente foi interrompida sem reinícios adicionais. Foi pedido apenas o URL do painel aberto para identificar a sessão correcta, sem palavras-passe ou códigos. Não se atribui a causa ao portal, ao navegador ou ao MFA. Hotel, Agronegócio, retorno de filtros financeiros e continuidade demográfica mantêm a conferência autenticada/móvel **NÃO VERIFICADA**; a interrupção não reabre nem invalida as provas técnicas aceites. + +**Retoma seguinte — acesso recuperado e primeiras operações reais:** foi observado o dossier sintético Hotel autenticado em `http://127.0.0.3:18715/investimentos/6bdc2ac6-2a40-497c-831d-31c9c08372ed`. Pela interface foi pesquisada a «Empresa hoteleira sintética QA», seleccionada e guardada a associação; o resumo do dossier passou a mostrar essa empresa. A acção «Continuar a viabilidade» abriu o simulador do mesmo dossier. Foram observados título, actividade, sector, hierarquia Matola Rio–Sede/Boane/Maputo Província e intervalo de 1–5 milhões MZN recuperados, sem anúncio associado. Foram preenchidos uma descrição sintética e o idioma e utilizada a acção Continuar para chegar a Mercado. As capturas nativas disponíveis na conversa demonstram este recorte em computador, não o percurso integral ou a utilização móvel. + +A conferência identificou duas divergências concretas antes do fecho: a navegação focava o cabeçalho geral, afastando as perguntas da etapa; orçamento, parcerias/apoio, contexto e histórico acumulavam-se antes delas. Aplicada correcção localizada em `simulation-form.tsx`: foco no título da etapa com margem para o menu fixo; apresentação progressiva dos blocos acessórios, mantendo os componentes montados, as ligações e os erros de contexto visíveis; ajuda aberta quando uma resposta da etapa é «Não sei». Tipos e lint dirigidos aprovados; reconferência visual desta alteração permanece por executar até observação efectiva. As baterias fiscais e de persistência já aceites não foram repetidas por esta correcção de apresentação. + +**Conferência posterior no mesmo QA — Hotel, computador e emulação móvel:** o acesso autenticado foi recuperado sem alterar a segurança. A navegação passou a focar a etapa efectiva; o recarregamento recuperou Mercado, Financiamento e Receitas e custos. «Por determinar» abriu a ajuda da etapa. Pela interface foram introduzidas instalações 1.000.000, equipamentos 500.000, preparação 200.000 e fundo de maneio 300.000 MZN; a soma de 2.000.000 MZN só foi adoptada por botão explícito. O intervalo original de 1–5 milhões permaneceu separado. + +Foram encontrados e corrigidos três defeitos demonstráveis: (1) a calculadora conservava um campo mobilizado vazio apesar de o investimento indicar 1.000.000, e mostrava erros de ferramentas não utilizadas; agora acompanha a origem comum quando não há edição conhecida divergente, preservando conflitos reais para escolha explícita; (2) receitas/custos anuais estavam ocultos pela regra de campos avançados; agora são editáveis na etapa pertinente; (3) o retorno ao dossier confundia ausência de oportunidade em campo vazio com `null` normalizado pelo servidor. A comparação canónica passou a tratar esses vazios como equivalentes, sem equiparar desconhecido a zero nem aceitar alterações reais de montante ou oportunidade. A pesquisa fiscal inicialmente vazia passou a explicar que é necessário escolher a componente, em vez de aparentar ausência de operações. + +Nova conferência real: investimento 2.000.000, mobilizado 1.000.000 e diferença 1.000.000 MZN coerentes após recarregar; sem erros dos grupos ocultos ou empréstimo demonstrativo. Hotel escolhido explicitamente; 10 quartos × 300 dias × 50% × 5.000 MZN gerou 7.500.000 MZN anuais, adoptados por escolha explícita. Recarregar recuperou os quatro pressupostos, fundamento e total anual. Em emulação Edge **390 × 844**, a interface autenticada apresentou uma coluna; foi editado o custo anual para 2.000.000 e usado Continuar até Tesouraria. Não é prova num aparelho físico nem aprovação móvel de todos os ecrãs. Em 2027, seleccionar IVA à taxa geral apresentou o limite de cobertura de 2026, sem mudar o ano ou calcular silenciosamente. + +O botão de retorno, após a correcção do vazio, guardou os pressupostos no **mesmo dossier Hotel**, agora versão 6. A interface preparou e descarregou o HTML consolidado; o ficheiro efectivamente descarregado conserva descrição, empresa/contexto, intervalo, orçamento inicial, receita 7.500.000, custo 2.000.000, mobilizado 1.000.000, diferença 1.000.000 MZN e pressupostos/fundamento. Evidência local: `outputs/investor-intent-20261115/hotel-browser-report.html`. Não foi apresentado imposto calculado fora da cobertura nem aprovada a viabilidade comercial. Recibos dirigidos adicionais: `financial-source-ui.log` (5/5), `visual-followup-tests.log` (8/8), `return-fingerprint-tests.log` (8/8, baterias sobrepostas), tipos e builds incrementais. Capturas nativas disponíveis na conversa; não inventar caminhos de screenshots. + +**Saldo desta conferência:** Hotel tem prova autenticada de associação de empresa existente, preparação/estimativa explícita, gravação, recuperação, retorno e geração do relatório, com o recorte móvel descrito. Permanecem NÃO VERIFICADOS o percurso integral com entidade por constituir, Agronegócio na interface, retorno dos filtros financeiros, continuidade demográfica autenticada e retoma após nova autenticação/isolamento entre separadores. Os restantes consumidores da tabela não ficam aprovados por partilharem componentes. A candidata e as correcções continuam exclusivamente em QA, sem instalação autorizada. + +**Agronegócio e consultas — continuação da mesma conferência:** no dossier `bd830c95-a3bc-4342-84e2-df8e1dccb614`, seleccionada entidade por constituir; a preparação recuperou sede e actividade e guardou uma denominação sintética, continuando para o simulador. Mantiveram-se sector, hierarquia e intervalo de 1–5 milhões MZN, sem anúncio/zona obrigatórios. O modelo agrícola, escolhido explicitamente, conservou 20.000 unidades × 50 MZN × 2 ciclos = 2.000.000 anuais após recarregar, sem os valores do Hotel. Foram guardados pressupostos no mesmo dossier após conferir Financiamento, deixando total/mobilizado desconhecidos: o intervalo não foi convertido num montante único. A tentativa de retorno antes de percorrer Financiamento expôs a mensagem pouco orientadora «Guarde primeiro as entradas da ferramenta financeira»; permanece divergência de orientação, não uma perda de dados ou autorização para dispensar o contrato do servidor. + +Para provas positivas de consulta, acrescentados apenas à base isolada três registos financeiros e duas observações distritais **claramente sintéticos**, com recibo `outputs/investor-intent-20261115/consultation-fixtures.json`; nenhuma conta recebeu permissões persistentes, nenhuma instituição operacional foi publicada ou alterada. A consulta autenticada Banca → Banco comercial, presença física Boane e âmbito documentado apresentou apenas o banco, excluindo corretora/microsseguradora sintéticas. A ligação ao detalhe conserva os filtros na URL de retorno. Pela interface foram escolhidos necessidade Investimento/equipamento e produto, confirmada a conservação privada e aberto o mesmo dossier: instituição, versão consultada 1, produto, categoria e tipo recuperados. O clique efectivo de retorno à lista, combinações vazias/inválidas e a conferência móvel financeira ainda não ficam aprovados por esta prova. + +No dossier agrícola foi aberta «Demografia na análise de viabilidade» → «Consultar indicadores do ano actual». Apresentados 12.345 habitantes sintéticos, fonte/2026/projecção e **Boane QA — Distrito**, com aviso explícito de contexto administrativo mais amplo, que não representa a população da localidade. Estrutura etária/rural ausente continuou «Sem dados»; não foram inventados clientes ou rentabilidade. A consulta completa, evolução temporal, continuidade por nova ideia e versão móvel autenticada continuam abertas. Também foi identificada linguagem interna sobre «sete exemplares/complemento» na preparação da empresa, ainda por corrigir no âmbito de apresentação. Estas constatações não encerram a cobertura transversal. + +**Prévia autenticada preparada:** servidor de desenvolvimento local em `http://127.0.0.3:18715`, exclusivamente com a base `investor_intent_20261115_test`, guarda de identidade da base e conta/dossiers sintéticos sem novas permissões. O host e cookie próprios separam a sessão das outras prévias locais. Não é instalação na homologação. Não desactivar autenticação, MFA ou avisos do navegador para continuar. + +Para a conferência pendente, usar os dossiers sintéticos do Hotel e Agronegócio preparados nessa base: associar empresa existente ou preparar entidade por constituir; confirmar contexto; preencher só pressupostos conhecidos; adoptar orçamento e estimativa; guardar na etapa de receitas; recarregar e retomar a mesma etapa; escolher operações fiscais e testar 2027 sem substituição por 2026; guardar pressupostos no dossier e gerar relatório; repetir em largura móvel. Conferir também lista/detalhe/retorno de fundos e demografia/âmbito/continuar ideia. As quatro linhas da matriz mantêm a aceitação integral aberta até essas provas, sem apagar as provas anteriores ou transformar a prévia em instalação autorizada. + +- Proveniência apresentada como conteúdo principal: componente partilhado `EvidenceDetails` para consulta progressiva, mantendo referências, exemplares e hashes no detalhe. Limitações de utilização e períodos aplicáveis permanecem junto do conteúdo afectado. +- Retorno ao catálogo aceitava qualquer parâmetro e podia transportar critérios de outra família: lista explícita por destino, preservação da página válida, múltiplas facetas e alterações deliberadas no destino. Mudar/limpar um nível territorial não recupera descendentes incompatíveis. Não usa armazenamento global nem transfere contexto privado em `catalogue_query`. Menus de consulta não transportam o identificador de dossier para biblioteca, legislação ou outras famílias sem aplicação. +- A reutilização do componente de interesse podia escrever o formulário anterior na chave de outra oportunidade: estado associado à chave do recurso, preservando os formatos anteriores, as edições deliberadas, a autenticação normal e o funcionamento com armazenamento bloqueado. +- O resumo de dossier podia adoptar a escolha efectuada noutro separador: pista por conta em `sessionStorage`, sempre confrontada com a lista autorizada recebida do servidor. Um URL explícito prevalece. Um novo separador sem escolha continua a usar a preferência existente. Uma mudança deliberada recupera a versão actual do servidor antes da escrita normal com controlo de concorrência. Não altera a autoridade do servidor nem os dados do dossier. +- A consulta demográfica podia mostrar a localização anterior e aceitar uma resposta tardia: estado isolado pela localização, cancelamento da consulta e rejeição da resposta após desmontagem. A página de comparação identifica a consulta pelos filtros recebidos do servidor. + +## Cobertura demonstrada e limites por família + +| Família / consumidores | Alteração verificável | Evidência / excepções | +| --- | --- | --- | +| Catálogo, pesquisa, carteira e zonas | Retorno por família; filtros explícitos, página, facetas, contexto territorial; explicação do estado sem anúncios | Testes de URLs e navegação. Estado vazio distingue anúncios de empresas, recursos e potencial. Não altera o motor de pesquisa nem incorpora os deltas concorrentes de `FederatedSearch` da pasta principal. | +| Localização e demografia, incluindo consulta no catálogo/dossier | Síntese dos totais mais recentes **dentro do período consultado e de cada fonte**; ano, unidade e tipo junto do valor; dimensões, original, ficheiro e hash recuperáveis no detalhe | Renderização real dos componentes e teste de resposta tardia. Não soma faixas etárias, não combina fontes ou tipos estatísticos, não preenche anos ausentes nem infere procura. A síntese conserva advertências e unidades ausentes. **Comparação com `21ac7eb` pendente**, pois o objecto e o bundle não estão disponíveis localmente; não houve cherry-pick dessa candidata. | +| Sectores, Mineração/Energia, âncoras e clusters | Estado sem anúncios explicado; fontes territoriais em detalhe; campos vazios da análise de competitividade omitidos da apresentação | Renderização e testes de filtros de recursos, localização e continuidade no dossier, incluindo Energia e Mineração. Não reescreve descrições editoriais existentes nem altera geometrias, contratos ou relações. | +| Biblioteca e legislação | Identificação/fonte em detalhe; sem bloco de entidade desconhecida; período de aplicação e aviso de utilização visíveis; acções documentais conservadas | Renderização do consumidor comum e regressão dos filtros de biblioteca/legislação. Não altera decisões jurídicas, disponibilização ou acesso aos ficheiros. | +| Dossier, manifestações de interesse e simulador | Escolha por separador/conta, rascunho por oportunidade; fonte técnica do Modelo A em detalhe; cálculos e reutilização preservados | Integração do provider real com transporte simulado, testes de recuperação e autenticação, herança e regressões de Modelo A. Não representa conferência autenticada integral num navegador nem entrega real de email. | + +Estas provas cobrem componentes e consumidores identificados, não todos os ecrãs ou todas as combinações de módulos. A distinção entre oferta publicada, empresas existentes, indicadores e hipóteses é preservada; não se utiliza ausência de anúncios como prova de ausência de oferta empresarial ou viabilidade. + +## Verificação + +Recibos em `outputs/public-context-20261115/`: + +- `frontend.xml`: 82 testes, zero falhas, erros ou omissões; inclui componentes renderizados, pesquisa/navegação, biblioteca, recursos sectoriais, interesses, contexto e Modelo A. +- `navigation-context.xml`: 1 teste de integração do provider, com contexto por separador, recarregamento, URL explícito e versão concorrente do servidor. Dados exclusivamente sintéticos; transporte simulado. +- `types.log`: `tsc --noEmit`, aprovado. +- `lint.log`: lint dirigido a todos os ficheiros de produto/teste alterados, aprovado sem avisos. +- `build.log`: compilação QA aprovada. Aviso do plugin de fontes sobre a dependência opcional `fontaine`, com configuração já existente; não foi instalada nem alterada qualquer dependência para o eliminar. + +A skill de controlo Windows foi tentada sem reiniciar aplicações. A enumeração devolveu **`Computer Use native pipe is unavailable: failed to connect native pipe: O sistema não conseguiu localizar o ficheiro especificado. (os error 2)`**. Não existem screenshots aceites. Apresentação móvel, foco real, ausência de sobreposição e utilização autenticada destes deltas estão **NÃO VERIFICADOS**. Classes responsivas e testes de renderização não substituem essa conferência. + +Conferência manual quando houver prévia da candidata: catálogo → detalhe → voltar, incluindo alteração explícita de província; demografia com duas localizações/períodos e retorno; sector/âncora/cluster com e sem anúncios; biblioteca/legislação com aviso/período; dois dossiers em separadores distintos e recuperação de um interesse. Repetir em computador e janela de 390 × 844, verificando teclado, detalhes, tabelas e botões. Não utilizar a prévia das Ofertas como prova desta candidata: conserva o seu código anterior. + +## Compatibilidade e entrega + +Pacote Git com delta exclusivo sobre `42fba8ba`, testes e documentação. O manifesto indica SHA, pré-requisito e intersecção de caminhos com as alterações concorrentes detectadas na pasta principal. **Não aplicar uma substituição de pastas nem fazer push para `main`**. Integrar o delta revisto, preservando o trabalho concorrente e as actualizações da matriz/manual. O pacote não inclui credenciais, sessões, dados operacionais, dependências ou uma nova importação demográfica. + +As linhas existentes RF-MN-010, RF-GEO-009, INE-DEMO-01, MASTER-471012ab-0017 e M2-d0c06a75-0055 conservam o estado e o saldo anteriores; acrescenta-se apenas esta cobertura verificada. A candidata `21ac7eb`, os deltas concorrentes da pesquisa e a aceitação visual não são declarados integrados ou concluídos. + +O saldo acima corresponde à entrega `8806312f`. A actualização abaixo regista a reconciliação posterior; os recibos anteriores conservam-se como histórico. Nenhuma instalação está autorizada por esta entrega. + +## Reconciliação do bundle `21ac7eb` com `8806312f` + +O exemplar `\\Mac\Home\Downloads\demografia-leitura-21ac7eb.bundle` foi efectivamente recebido e verificado pelo Git. Contém `21ac7eb4fb9c0fd7dfbbf2db7ff8d6ab56249238`, com pré-requisito `13497892`. Não se efectuou cherry-pick integral. O hash do transporte e os recibos desta passagem ficam em `outputs/demography-reconciliation-20261115/`. + +| Parte da candidata recebida | Decisão e resultado | +| --- | --- | +| Síntese demográfica | A apresentação progressiva e os indicadores originais de `8806312f` foram preservados. Acrescentou-se uma síntese de população por fonte/edição, sem repetir o total nos cartões dos restantes indicadores. | +| Evolução temporal | Incorporado o helper de apresentação: extremos exactos do período escolhido, mesma unidade e tipo estatístico; diferença absoluta e percentual **do período**, nunca taxa anual. Anos intermédios ausentes permanecem «Sem dados». | +| Distribuição etária e rural | Incorporados os grupos indicados apenas quando existem todas as parcelas únicas e compatíveis. Percentagens rural/urbana exigem reconciliação com o total. Unidades desconhecidas, duplicações, tipos diferentes e parcelas ausentes não geram percentagens inventadas. São derivações para leitura, sem escrita sobre os valores originais ou cálculos fiscais. | +| Interpretação | Incorporadas orientações ligadas aos valores apresentados: verificar acessos/custos/serviços, capacidade instalada e rendimento; a população em idade activa não demonstra disponibilidade de trabalhadores. Não se deduz procura, rentabilidade ou lacuna de mercado. | +| Fontes, decimais e versões | Conservado o componente comum `EvidenceDetails`, tabela dos originais, hash, unidades, advertências e múltiplas fontes separadas. Não foram alterados lotes, dados, documentos ou geometrias. | +| Catálogo | Aproveitada a separação explícita entre estudo territorial e filtros comerciais, com os destinos existentes. Não se duplicou o aviso de ausência de anúncios já tratado pela solução comum. | +| Continuidade da análise | Incorporada a acção de preparar ideia a partir de cada território, transportando apenas `source=territory:ID`; sem importar filtros comerciais. Conservado o isolamento por URL e separador de `8806312f`. | +| Documentação e testes | Não se substituíram o manual nem as matrizes pelos exemplares antigos do bundle. Acrescenta-se esta actualização às referências existentes. Reutilizaram-se os testes dirigidos recebidos, adaptando apenas os imports aos componentes comuns e o carregamento ao mecanismo `compileFunction` já usado no projecto. | + +### Prova dirigida adicional e conferência visual + +Os testes adicionais verificam conservação dos decimais, grupos incompletos, zero, dimensões duplicadas, unidades/tipos incompatíveis, distribuições incoerentes, anos ausentes, extremos seleccionados, separação de edições, interpretação e ligação territorial. O exemplar de Báruè do bundle confirma os resultados de apresentação sem modificar os originais. Não se repetiram importações ou as baterias técnicas globais aceites. + +A captura nativa do Edge recuperou nesta passagem; o conector de abas continua a indicar `The browser access host is unavailable`. A janela existente no portal activo, com alterações por guardar, foi preservada. Abriu-se uma janela separada para `visual-components.html`: componentes reais renderizados com CSS compilado da candidata e dados explicitamente sintéticos, sem autenticação, API operacional ou publicação. + +Foram observados em computador e em emulação móvel (390 px e 360 × 844): cartões em uma coluna, leitura da variação temporal, abertura da série anual, ano ausente como «Sem dados» e recuperação do detalhe de fontes/originais. A primeira captura móvel detectou palavras comprimidas na tabela original; foi aplicada largura mínima com deslocamento interno, seguida de nova conferência. As capturas são evidência da **prévia de componentes**, não de aceitação autenticada integral ou de utilização num telefone físico. + +Continuam pendentes a conferência autenticada dos percursos completos e a aceitação do responsável. Sem instalação no activo, sem alteração do esquema ou de permissões e sem envio externo. A pendência de obter/comparar o bundle fica encerrada por esta reconciliação selectiva. diff --git a/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv b/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv index 2652cc23..347917c1 100644 --- a/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv +++ b/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv @@ -1,4 +1,4 @@ -ID,Pedido/trecho,Fonte/ocorrências,Módulo,Rotas,Implementação encontrada,Disponibilidade ativa,Evidência funcional,Estado,Lacuna,Dependência,Critério de aceitação,Prioridade,Versões divergentes,IDs das linhas de origem,Quantidade de linhas de origem,Critérios e versões por origem (JSON),Interface,API,Gravação,Recuperação,Resultado apresentado,Consolidação,Estado anterior — 12/10/2026,Disponibilidade ativa anterior,Fundamento do estado atual,Critérios restantes atuais,Componentes atuais a reutilizar,Dependências atuais,Decisão concreta atual,Tipo de trabalho atual,Esforço e pressupostos atuais,Evidências atuais verificadas,Grupo de execução,Revisão da auditoria,Correspondência de campo atual,Prova de campo atual,Lacuna anterior — 12/10/2026,Dependência anterior — 12/10/2026,Implementação encontrada anterior — 12/10/2026,Evidência funcional anterior — 12/10/2026,API anterior — 12/10/2026,Grupos de provas reutilizadas,Critérios cobertos pelas provas agrupadas,Limites das provas agrupadas,Esforço anterior à consolidação por lote,Categoria de feedback Tempo,Critério de revisão integrada,Estado da revisão integrada +ID,Pedido/trecho,Fonte/ocorrências,Módulo,Rotas,Implementação encontrada,Disponibilidade ativa,Evidência funcional,Estado,Lacuna,Dependência,Critério de aceitação,Prioridade,Versões divergentes,IDs das linhas de origem,Quantidade de linhas de origem,Critérios e versões por origem (JSON),Interface,API,Gravação,Recuperação,Resultado apresentado,Consolidação,Estado anterior — 12/10/2026,Disponibilidade ativa anterior,Fundamento do estado atual,Critérios restantes atuais,Componentes atuais a reutilizar,Dependências atuais,Decisão concreta atual,Tipo de trabalho atual,Esforço e pressupostos atuais,Evidências atuais verificadas,Grupo de execução,Revisão da auditoria,Correspondência de campo atual,Prova de campo atual,Lacuna anterior — 12/10/2026,Dependência anterior — 12/10/2026,Implementação encontrada anterior — 12/10/2026,Evidência funcional anterior — 12/10/2026,API anterior — 12/10/2026,Grupos de provas reutilizadas,Critérios cobertos pelas provas agrupadas,Limites das provas agrupadas,Esforço anterior à consolidação por lote,Categoria de feedback Tempo,Critério de revisão integrada,Estado da revisão integrada RF-AGR-001,"Classificar a oportunidade agrícola ou fundiária por natureza: exploração agrícola, agro-indústria, pecuária, silvicultura, irrigação, armazenagem, participação empresarial, activos e benfeitorias, parceria ou financiamento.",upgrade v4 SHA f0b9815…; p. 3089; requirements-audit.csv,oportunidades,/api/v1/business-opportunities; /api/v1/business-opportunities/{slug}; /investidor/terra-duat; /investidor/terra-duat/novo; /investidor/terra-duat/{id}; /investidor/terra-duat/{id}/actualizacoes; /investidor/terra-duat/{id}/documentos; /investidor/terra-duat/{id}/documentos/{attachment}; /investidor/terra-duat/{id}/editar; /investidor/terra-duat/{id}/imprimir; /investidor/terra-duat/{id}/solicitar-apoio; /management/opportunities,"OpportunityManagement, OpportunityCanonicalContract/Response, OpportunityReviewMateriality, PortalProfileAccess, OpportunityResources. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Reconciliar contrato/cláusula e provas por categoria; completar apenas falha/variante executável identificada. Response normativo não é completo. Critério individual original preservado; cobertura atual ainda não individualizada.,"030000→040000 já instalados; contratos/resources existentes, sessão/MFA, ClamD e worker para ficheiros; gates das seis categorias ON. Variantes modulares/offers continuam separadas. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","RF-AGR-001: A submissão exige pelo menos uma natureza; a opção seleccionada activa os campos, documentos e fluxo correspondentes; designações não admissíveis ficam bloqueadas.",P2,RF-AGR-001: Relatório 25/09 conservado; estado histórico não promove conclusão,RF-AGR-001,1,"[{""id"":""RF-AGR-001"",""pedido"":""Classificar a oportunidade agrícola ou fundiária por natureza: exploração agrícola, agro-indústria, pecuária, silvicultura, irrigação, armazenagem, participação empresarial, activos e benfeitorias, parceria ou financiamento."",""fontes"":[""upgrade v4 SHA f0b9815…; p. 3089; requirements-audit.csv""],""aceitacao"":""A submissão exige pelo menos uma natureza; a opção seleccionada activa os campos, documentos e fluxo correspondentes; designações não admissíveis ficam bloqueadas."",""estado"":""parcial"",""variantes"":""Relatório 25/09 conservado; estado histórico não promove conclusão"",""modulo"":""oportunidades""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.opportunities: 6 registos; public.opportunity_images: tabela ausente; public.opportunity_documents: tabela ausente; public.opportunity_location_drafts: tabela ausente,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Reconciliar contrato/cláusula e provas por categoria; completar apenas falha/variante executável identificada. Response normativo não é completo. Critério individual original preservado; cobertura atual ainda não individualizada.,"OpportunityManagement, OpportunityCanonicalContract/Response, OpportunityReviewMateriality, PortalProfileAccess, OpportunityResources","030000→040000 já instalados; contratos/resources existentes, sessão/MFA, ClamD e worker para ficheiros; gates das seis categorias ON. Variantes modulares/offers continuam separadas.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: oportunidades. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,oportunidades,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Services/OpportunityManagement.php; app/Services/OpportunityResources.php; resources/js/pages/management/opportunity-draft.tsx — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"OpportunityManagementTest, OpportunityResourcesTest, OpportunityOriginReviewTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, RF-AGR-002,Registar localização e extensão da área.,upgrade v4 SHA f0b9815…; p. 3093; requirements-audit.csv,oportunidades,/api/v1/business-opportunities; /api/v1/business-opportunities/{slug}; /investidor/terra-duat; /investidor/terra-duat/novo; /investidor/terra-duat/{id}; /investidor/terra-duat/{id}/actualizacoes; /investidor/terra-duat/{id}/documentos; /investidor/terra-duat/{id}/documentos/{attachment}; /investidor/terra-duat/{id}/editar; /investidor/terra-duat/{id}/imprimir; /investidor/terra-duat/{id}/solicitar-apoio; /management/opportunities,"OpportunityManagement, OpportunityCanonicalContract/Response, OpportunityReviewMateriality, PortalProfileAccess, OpportunityResources. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Reconciliar contrato/cláusula e provas por categoria; completar apenas falha/variante executável identificada. Response normativo não é completo. Critério individual original preservado; cobertura atual ainda não individualizada.,"030000→040000 já instalados; contratos/resources existentes, sessão/MFA, ClamD e worker para ficheiros; gates das seis categorias ON. Variantes modulares/offers continuam separadas. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","RF-AGR-002: Província, distrito, posto, localidade, área em hectares e localização principal são obrigatórios; coordenadas ou polígono são validados e só publicados após autorização.",P2,RF-AGR-002: Relatório 25/09 conservado; estado histórico não promove conclusão,RF-AGR-002,1,"[{""id"":""RF-AGR-002"",""pedido"":""Registar localização e extensão da área."",""fontes"":[""upgrade v4 SHA f0b9815…; p. 3093; requirements-audit.csv""],""aceitacao"":""Província, distrito, posto, localidade, área em hectares e localização principal são obrigatórios; coordenadas ou polígono são validados e só publicados após autorização."",""estado"":""parcial"",""variantes"":""Relatório 25/09 conservado; estado histórico não promove conclusão"",""modulo"":""oportunidades""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.opportunities: 6 registos; public.opportunity_images: tabela ausente; public.opportunity_documents: tabela ausente; public.opportunity_location_drafts: tabela ausente,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Reconciliar contrato/cláusula e provas por categoria; completar apenas falha/variante executável identificada. Response normativo não é completo. Critério individual original preservado; cobertura atual ainda não individualizada.,"OpportunityManagement, OpportunityCanonicalContract/Response, OpportunityReviewMateriality, PortalProfileAccess, OpportunityResources","030000→040000 já instalados; contratos/resources existentes, sessão/MFA, ClamD e worker para ficheiros; gates das seis categorias ON. Variantes modulares/offers continuam separadas.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: oportunidades. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,oportunidades,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Services/OpportunityManagement.php; app/Services/OpportunityResources.php; resources/js/pages/management/opportunity-draft.tsx — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"OpportunityManagementTest, OpportunityResourcesTest, OpportunityOriginReviewTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, RF-AGR-003,Registar situação de uso e aproveitamento da terra.,upgrade v4 SHA f0b9815…; p. 3097; requirements-audit.csv,oportunidades,/api/v1/business-opportunities; /api/v1/business-opportunities/{slug}; /investidor/terra-duat; /investidor/terra-duat/novo; /investidor/terra-duat/{id}; /investidor/terra-duat/{id}/actualizacoes; /investidor/terra-duat/{id}/documentos; /investidor/terra-duat/{id}/documentos/{attachment}; /investidor/terra-duat/{id}/editar; /investidor/terra-duat/{id}/imprimir; /investidor/terra-duat/{id}/solicitar-apoio; /management/opportunities,"OpportunityManagement, OpportunityCanonicalContract/Response, OpportunityReviewMateriality, PortalProfileAccess, OpportunityResources. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Reconciliar contrato/cláusula e provas por categoria; completar apenas falha/variante executável identificada. Response normativo não é completo. Critério individual original preservado; cobertura atual ainda não individualizada.,"030000→040000 já instalados; contratos/resources existentes, sessão/MFA, ClamD e worker para ficheiros; gates das seis categorias ON. Variantes modulares/offers continuam separadas. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","RF-AGR-003: O proponente informa referência, titular, finalidade, área, prazo, estado, entidade emissora, ónus e documento de suporte; divergência impede publicação.",P2,RF-AGR-003: Relatório 25/09 conservado; estado histórico não promove conclusão,RF-AGR-003,1,"[{""id"":""RF-AGR-003"",""pedido"":""Registar situação de uso e aproveitamento da terra."",""fontes"":[""upgrade v4 SHA f0b9815…; p. 3097; requirements-audit.csv""],""aceitacao"":""O proponente informa referência, titular, finalidade, área, prazo, estado, entidade emissora, ónus e documento de suporte; divergência impede publicação."",""estado"":""parcial"",""variantes"":""Relatório 25/09 conservado; estado histórico não promove conclusão"",""modulo"":""oportunidades""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.opportunities: 6 registos; public.opportunity_images: tabela ausente; public.opportunity_documents: tabela ausente; public.opportunity_location_drafts: tabela ausente,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Reconciliar contrato/cláusula e provas por categoria; completar apenas falha/variante executável identificada. Response normativo não é completo. Critério individual original preservado; cobertura atual ainda não individualizada.,"OpportunityManagement, OpportunityCanonicalContract/Response, OpportunityReviewMateriality, PortalProfileAccess, OpportunityResources","030000→040000 já instalados; contratos/resources existentes, sessão/MFA, ClamD e worker para ficheiros; gates das seis categorias ON. Variantes modulares/offers continuam separadas.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: oportunidades. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,oportunidades,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Services/OpportunityManagement.php; app/Services/OpportunityResources.php; resources/js/pages/management/opportunity-draft.tsx — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"OpportunityManagementTest, OpportunityResourcesTest, OpportunityOriginReviewTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, @@ -761,7 +761,7 @@ MASTER-e1169a77-0018,"A evolução do portal deve ser orientada por métricas de MASTER-e1169a77-0019,"Antes da construção dos novos módulos, deverá ser concluída a Fase Zero definida nas secções 4.8.3 e 4.8.6, que concentra as melhorias imediatas da versão existente e os respectivos critérios de entrega. Esta etapa não depende de integrações institucionais ainda não confirmadas.",portal do investidor\Portal V4\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 421 | portal do investidor\Portal V4\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 421,Balcão/orientação,/balcao-virtual/contextos; /balcao-virtual/dossiers; /balcao-virtual/dossiers/{id}; /balcao-virtual/dossiers/{id}/documentos; /balcao-virtual/dossiers/{id}/documentos/{document}; /balcao-virtual/dossiers/{id}/documentos/{document}/conferencia; /balcao-virtual/dossiers/{id}/etapas; /balcao-virtual/dossiers/{id}/fontes; /balcao-virtual/dossiers/{id}/orientacao; /balcao-virtual/dossiers/{id}/pedidos; /balcao-virtual/dossiers/{id}/pressupostos; /balcao-virtual/dossiers/{id}/recomendacoes,"VirtualDesk, pedidos/casos, anexos, contexto dossier e acompanhamento. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,"Pedido contextual→gravar→submeter→nova sessão→gestor→mensagem/documentos/resultado, reaproveitando A/B. Critério individual original preservado; cobertura atual ainda não individualizada.","Perfis próprios do Balcão; serviços/campos e decisões externas aplicáveis, sem inventar destinatário/prazo. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","MASTER-e1169a77-0019: Antes da construção dos novos módulos, deverá ser concluída a Fase Zero definida nas secções 4.8.3 e 4.8.6, que concentra as melhorias imediatas da versão existente e os respectivos critérios de entrega. Esta etapa não depende de integrações institucionais ainda não confirmadas. | MASTER-edece80c-0019: Antes da construção dos novos módulos, deverá ser concluída a Fase Zero definida nas secções 4.8.3 e 4.8.6, que concentra as melhorias imediatas da versão existente e os respectivos critérios de entrega. Esta etapa não depende de integrações institucionais ainda não confirmadas.",P2,MASTER-e1169a77-0019: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-edece80c-0019: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-e1169a77-0019 | MASTER-edece80c-0019,2,"[{""id"":""MASTER-e1169a77-0019"",""pedido"":""Antes da construção dos novos módulos, deverá ser concluída a Fase Zero definida nas secções 4.8.3 e 4.8.6, que concentra as melhorias imediatas da versão existente e os respectivos critérios de entrega. Esta etapa não depende de integrações institucionais ainda não confirmadas."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 421""],""aceitacao"":""Antes da construção dos novos módulos, deverá ser concluída a Fase Zero definida nas secções 4.8.3 e 4.8.6, que concentra as melhorias imediatas da versão existente e os respectivos critérios de entrega. Esta etapa não depende de integrações institucionais ainda não confirmadas."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""Balcão/orientação""},{""id"":""MASTER-edece80c-0019"",""pedido"":""Antes da construção dos novos módulos, deverá ser concluída a Fase Zero definida nas secções 4.8.3 e 4.8.6, que concentra as melhorias imediatas da versão existente e os respectivos critérios de entrega. Esta etapa não depende de integrações institucionais ainda não confirmadas."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 421""],""aceitacao"":""Antes da construção dos novos módulos, deverá ser concluída a Fase Zero definida nas secções 4.8.3 e 4.8.6, que concentra as melhorias imediatas da versão existente e os respectivos critérios de entrega. Esta etapa não depende de integrações institucionais ainda não confirmadas."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""Balcão/orientação""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.desk_cases: 1 registos; public.desk_requests: 0 registos; public.desk_institutional_links: 0 registos; public.desk_messages: 0 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.","Pedido contextual→gravar→submeter→nova sessão→gestor→mensagem/documentos/resultado, reaproveitando A/B. Critério individual original preservado; cobertura atual ainda não individualizada.","VirtualDesk, pedidos/casos, anexos, contexto dossier e acompanhamento","Perfis próprios do Balcão; serviços/campos e decisões externas aplicáveis, sem inventar destinatário/prazo.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: balcão. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,balcão,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Services/VirtualDesk.php; app/Services/Ai/InvestorGuidance.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,InvestorGuidanceTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, MASTER-e1169a77-0021,"A implementação deverá partir de um diagnóstico técnico e funcional da versão actual do portal, identificando componentes reutilizáveis, dívida técnica, limitações de conteúdo, integrações existentes, qualidade dos dados, desempenho, segurança, acessibilidade e cobertura dos fluxos. Esse diagnóstico deverá produzir uma matriz Conservar, Melhorar, Substituir ou Descontinuar, evitando a reconstrução de funcionalidades estáveis e preservando os investimentos já realizados.",portal do investidor\Portal V4\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 423 | portal do investidor\Portal V4\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 423,governação/outros,/api/v1/investment/admin/interests/{interest}/status; /management/history; /management/interests; /management/interests/{interest}; /management/interests/{interest}/consent/contact; /management/interests/{interest}/consent/proponent; /management/opportunities; /management/opportunities/create; /management/opportunities/drafts; /management/opportunities/{id}/draft; /management/opportunities/{id}/edit; /management/opportunities/{id}/lifecycle,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Localizar obrigação verificável e consumidores/contrato atuais antes de estimar implementação ou declarar conclusão. Critério individual original preservado; cobertura atual ainda não individualizada.,"Ler secção/versão correspondente; distinguir requisito funcional, decisão e exemplo. Fontes oficiais já aceites. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","MASTER-e1169a77-0021: A implementação deverá partir de um diagnóstico técnico e funcional da versão actual do portal, identificando componentes reutilizáveis, dívida técnica, limitações de conteúdo, integrações existentes, qualidade dos dados, desempenho, segurança, acessibilidade e cobertura dos fluxos. Esse diagnóstico deverá produzir uma matriz Conservar, Melhorar, Substituir ou Descontinuar, evitando a reconstrução de funcionalidades estáveis e preservando os investimentos já realizados. | MASTER-edece80c-0021: A implementação deverá partir de um diagnóstico técnico e funcional da versão actual do portal, identificando componentes reutilizáveis, dívida técnica, limitações de conteúdo, integrações existentes, qualidade dos dados, desempenho, segurança, acessibilidade e cobertura dos fluxos. Esse diagnóstico deverá produzir uma matriz Conservar, Melhorar, Substituir ou Descontinuar, evitando a reconstrução de funcionalidades estáveis e preservando os investimentos já realizados.",P2,MASTER-e1169a77-0021: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-edece80c-0021: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-e1169a77-0021 | MASTER-edece80c-0021,2,"[{""id"":""MASTER-e1169a77-0021"",""pedido"":""A implementação deverá partir de um diagnóstico técnico e funcional da versão actual do portal, identificando componentes reutilizáveis, dívida técnica, limitações de conteúdo, integrações existentes, qualidade dos dados, desempenho, segurança, acessibilidade e cobertura dos fluxos. Esse diagnóstico deverá produzir uma matriz Conservar, Melhorar, Substituir ou Descontinuar, evitando a reconstrução de funcionalidades estáveis e preservando os investimentos já realizados."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 423""],""aceitacao"":""A implementação deverá partir de um diagnóstico técnico e funcional da versão actual do portal, identificando componentes reutilizáveis, dívida técnica, limitações de conteúdo, integrações existentes, qualidade dos dados, desempenho, segurança, acessibilidade e cobertura dos fluxos. Esse diagnóstico deverá produzir uma matriz Conservar, Melhorar, Substituir ou Descontinuar, evitando a reconstrução de funcionalidades estáveis e preservando os investimentos já realizados."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""},{""id"":""MASTER-edece80c-0021"",""pedido"":""A implementação deverá partir de um diagnóstico técnico e funcional da versão actual do portal, identificando componentes reutilizáveis, dívida técnica, limitações de conteúdo, integrações existentes, qualidade dos dados, desempenho, segurança, acessibilidade e cobertura dos fluxos. Esse diagnóstico deverá produzir uma matriz Conservar, Melhorar, Substituir ou Descontinuar, evitando a reconstrução de funcionalidades estáveis e preservando os investimentos já realizados."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 423""],""aceitacao"":""A implementação deverá partir de um diagnóstico técnico e funcional da versão actual do portal, identificando componentes reutilizáveis, dívida técnica, limitações de conteúdo, integrações existentes, qualidade dos dados, desempenho, segurança, acessibilidade e cobertura dos fluxos. Esse diagnóstico deverá produzir uma matriz Conservar, Melhorar, Substituir ou Descontinuar, evitando a reconstrução de funcionalidades estáveis e preservando os investimentos já realizados."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,Requisito transversal; consultar estado-ativo-after.json,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Localizar obrigação verificável e consumidores/contrato atuais antes de estimar implementação ou declarar conclusão. Critério individual original preservado; cobertura atual ainda não individualizada.,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer","Ler secção/versão correspondente; distinguir requisito funcional, decisão e exemplo. Fontes oficiais já aceites.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: governação e demais cláusulas. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,governação e demais cláusulas,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",AGENTS.md — componentes do domínio encontrados; correspondência integral deste requisito não presumida,; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, MASTER-e1169a77-0023,"O upgrade deverá preservar, avaliar e aprofundar os cinco eixos informativos já apresentados no portal InvestMoz — “Porquê investir em Moçambique”, “Actividades económicas”, “Oportunidades de negócios”, “Áreas de investimento” e “Reguladores” — convertendo-os progressivamente de páginas predominantemente informativas numa jornada orientada à decisão e à conversão. Antes de substituir qualquer componente, a equipa deverá confirmar o seu uso, qualidade, dependências e possibilidade de reutilização. Cada conteúdo deverá conduzir o visitante da compreensão do mercado para a selecção de uma oportunidade, consulta de requisitos, manifestação de interesse e acompanhamento no CRM.",portal do investidor\Portal V4\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 437 | portal do investidor\Portal V4\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 437,oportunidades,/api/v1/business-opportunities; /api/v1/business-opportunities/{slug}; /investidor/terra-duat; /investidor/terra-duat/novo; /investidor/terra-duat/{id}; /investidor/terra-duat/{id}/actualizacoes; /investidor/terra-duat/{id}/documentos; /investidor/terra-duat/{id}/documentos/{attachment}; /investidor/terra-duat/{id}/editar; /investidor/terra-duat/{id}/imprimir; /investidor/terra-duat/{id}/solicitar-apoio; /management/opportunities,"OpportunityManagement, OpportunityCanonicalContract/Response, OpportunityReviewMateriality, PortalProfileAccess, OpportunityResources. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Reconciliar contrato/cláusula e provas por categoria; completar apenas falha/variante executável identificada. Response normativo não é completo. Critério individual original preservado; cobertura atual ainda não individualizada.,"030000→040000 já instalados; contratos/resources existentes, sessão/MFA, ClamD e worker para ficheiros; gates das seis categorias ON. Variantes modulares/offers continuam separadas. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","MASTER-e1169a77-0023: O upgrade deverá preservar, avaliar e aprofundar os cinco eixos informativos já apresentados no portal InvestMoz — “Porquê investir em Moçambique”, “Actividades económicas”, “Oportunidades de negócios”, “Áreas de investimento” e “Reguladores” — convertendo-os progressivamente de páginas predominantemente informativas numa jornada orientada à decisão e à conversão. Antes de substituir qualquer componente, a equipa deverá confirmar o seu uso, qualidade, dependências e possibilidade de reutilização. Cada conteúdo deverá conduzir o visitante da compreensão do mercado para a selecção de uma oportunidade, consulta de requisitos, manifestação de interesse e acompanhamento no CRM. | MASTER-edece80c-0023: O upgrade deverá preservar, avaliar e aprofundar os cinco eixos informativos já apresentados no portal InvestMoz — “Porquê investir em Moçambique”, “Actividades económicas”, “Oportunidades de negócios”, “Áreas de investimento” e “Reguladores” — convertendo-os progressivamente de páginas predominantemente informativas numa jornada orientada à decisão e à conversão. Antes de substituir qualquer componente, a equipa deverá confirmar o seu uso, qualidade, dependências e possibilidade de reutilização. Cada conteúdo deverá conduzir o visitante da compreensão do mercado para a selecção de uma oportunidade, consulta de requisitos, manifestação de interesse e acompanhamento no CRM.",P2,MASTER-e1169a77-0023: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-edece80c-0023: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-e1169a77-0023 | MASTER-edece80c-0023,2,"[{""id"":""MASTER-e1169a77-0023"",""pedido"":""O upgrade deverá preservar, avaliar e aprofundar os cinco eixos informativos já apresentados no portal InvestMoz — “Porquê investir em Moçambique”, “Actividades económicas”, “Oportunidades de negócios”, “Áreas de investimento” e “Reguladores” — convertendo-os progressivamente de páginas predominantemente informativas numa jornada orientada à decisão e à conversão. Antes de substituir qualquer componente, a equipa deverá confirmar o seu uso, qualidade, dependências e possibilidade de reutilização. Cada conteúdo deverá conduzir o visitante da compreensão do mercado para a selecção de uma oportunidade, consulta de requisitos, manifestação de interesse e acompanhamento no CRM."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 437""],""aceitacao"":""O upgrade deverá preservar, avaliar e aprofundar os cinco eixos informativos já apresentados no portal InvestMoz — “Porquê investir em Moçambique”, “Actividades económicas”, “Oportunidades de negócios”, “Áreas de investimento” e “Reguladores” — convertendo-os progressivamente de páginas predominantemente informativas numa jornada orientada à decisão e à conversão. Antes de substituir qualquer componente, a equipa deverá confirmar o seu uso, qualidade, dependências e possibilidade de reutilização. Cada conteúdo deverá conduzir o visitante da compreensão do mercado para a selecção de uma oportunidade, consulta de requisitos, manifestação de interesse e acompanhamento no CRM."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""oportunidades""},{""id"":""MASTER-edece80c-0023"",""pedido"":""O upgrade deverá preservar, avaliar e aprofundar os cinco eixos informativos já apresentados no portal InvestMoz — “Porquê investir em Moçambique”, “Actividades económicas”, “Oportunidades de negócios”, “Áreas de investimento” e “Reguladores” — convertendo-os progressivamente de páginas predominantemente informativas numa jornada orientada à decisão e à conversão. Antes de substituir qualquer componente, a equipa deverá confirmar o seu uso, qualidade, dependências e possibilidade de reutilização. Cada conteúdo deverá conduzir o visitante da compreensão do mercado para a selecção de uma oportunidade, consulta de requisitos, manifestação de interesse e acompanhamento no CRM."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 437""],""aceitacao"":""O upgrade deverá preservar, avaliar e aprofundar os cinco eixos informativos já apresentados no portal InvestMoz — “Porquê investir em Moçambique”, “Actividades económicas”, “Oportunidades de negócios”, “Áreas de investimento” e “Reguladores” — convertendo-os progressivamente de páginas predominantemente informativas numa jornada orientada à decisão e à conversão. Antes de substituir qualquer componente, a equipa deverá confirmar o seu uso, qualidade, dependências e possibilidade de reutilização. Cada conteúdo deverá conduzir o visitante da compreensão do mercado para a selecção de uma oportunidade, consulta de requisitos, manifestação de interesse e acompanhamento no CRM."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""oportunidades""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.opportunities: 6 registos; public.opportunity_images: tabela ausente; public.opportunity_documents: tabela ausente; public.opportunity_location_drafts: tabela ausente,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Reconciliar contrato/cláusula e provas por categoria; completar apenas falha/variante executável identificada. Response normativo não é completo. Critério individual original preservado; cobertura atual ainda não individualizada.,"OpportunityManagement, OpportunityCanonicalContract/Response, OpportunityReviewMateriality, PortalProfileAccess, OpportunityResources","030000→040000 já instalados; contratos/resources existentes, sessão/MFA, ClamD e worker para ficheiros; gates das seis categorias ON. Variantes modulares/offers continuam separadas.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: oportunidades. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,oportunidades,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Services/OpportunityManagement.php; app/Services/OpportunityResources.php; resources/js/pages/management/opportunity-draft.tsx — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"OpportunityManagementTest, OpportunityResourcesTest, OpportunityOriginReviewTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, -MASTER-e1169a77-0026,"A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo.",portal do investidor\Portal V4\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 474 | portal do investidor\Portal V4\upgrade do portal de investimentos v1.docx; SHA f70ce3075523c6278e00dce15b9c7acf2b690679e16959ae5f7d007e754cfc6e; w:p 131 | portal do investidor\Portal V4\upgrade do portal de investimentos v2.docx; SHA 51b8f0ad3296d1064a5c12b450874fc72640869f10a164319cd7f3153dd3a086; w:p 173 | portal do investidor\Portal V4\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 474,cartografia/relações,/api/v1/geo/drafts; /api/v1/geo/search; /api/v1/geo/sources; /api/v1/geo/sources/{id}/transitions; /api/v1/geo/territories; /api/v1/geo/territories/{id}; /api/v1/geo/territories/{id}/transitions; /api/v1/geo/territories/{type}/{id}; /api/v1/geo/{collection}; /api/v1/investment/compare; /api/v1/investment/export; /api/v1/investment/favourites/{id},"InvestmentGeography, campos TerritoryFields/ProvinceSelect, geo_locations/geo_geometries e importador autenticado. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","[INSTITUICOES-20261110]270instituições/operadores,393referências de localização e168contactos do documento fornecido, em QA. Nenhuma nova instalação/publicação activa. | Histórico anterior preservado: [ACT12-20261110] Directório financeiro/conteúdo fornecido em QA; não instalado/publicado. Homologação1c75a30a mantém zero fichas financeiras. | Histórico anterior preservado: Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados. Preparação editorial assistida em QA: selecção/conferência e publicação explícita separadas, MFA nativo, edições preservadas e repetição exacta. Disponibilização efectiva ainda pendente. Instalação ef24cbdc confirmada10/11/2026; backup/restauro190tabelas/369ficheiros; fontes33hashes. Conteúdo ainda0fichas/0publicações; entrada no editor confirmada, sem POST de preparação/publicação observado. ACT12 aberto até consulta efectiva, sem nova instalação exigida. Confirmação posterior10/11:32rascunhos persistidos/0publicações; continuação e publicação403 após expiraçãoMFA900s (21:31:43+02). Retoma autenticada idempotente conserva rascunhos. Instalaçãoef24cbdc preservada; ACT12 aberto. Confirmação seguinte:90rascunhos/0publicações, recusas403 apósMFA. CorrecçãoQA de retoma na mesma aba poractor/fontes, confirmação separada e recuperação exacta; selecção todas270/contadores/controlos visíveis. Revisãoactivaef24cbdc até recibo posterior. Retoma instalada4f3dbcf8/22:01+02,7hashes/HTTP200/backup-restauro190tabelas369ficheiros, guardasMFA mantidas.90rascunhos/0publicações; preparação/publicação autenticada e consulta efectiva ainda pendentes. ACT12 aberto. Diagnóstico posterior:loginMFAEdge22:03:53/dashboard200; editor403Safari/WebKit22:04 em sessão anterior. Não era expiração da nova sessãoEdge. Colar URL noEdge autenticado; nenhuma permissão/sessão/configuração alterada. Abertura/publicação efectiva por confirmar. Acesso reposto:editorEdgeHTTP200às22:11:21+02 na sessão correcta; sem nova instalação/permissão. Publicação/conteúdo consultável ainda por confirmar. ENTREGACONFIRMADA10/11/2026às22:54:31+02:270/270instituições do documento publicadas/270identidades/393locais168contactos; nenhuma em falta. CatálogoHTTP200total270incluindo histórico, filtroseguradora/Nampula6resultados eBCI/Absa/ArkoHTTP200. Cadastro/disponibilização do original concluídos emhomologação4f3dbcf8; continuidade dossierQA aceite reutilizada; visual separado. Cinco programas anteriores permanecem privados. Provaoutputs/funding-directory-20261110/institutions/publication-complete.json.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,"Demonstrar consumidor: pesquisar→selecionar→gravar→nova sessão→renderizar limite correto; conservar pai, código e fonte. Critério individual original preservado; cobertura atual ainda não individualizada.","QA408/581INE; ativo0geometrias;173correspondências por nome/edição/pai, Mandie ambíguo. Publicação é ação separada. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","MASTER-e1169a77-0026: A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo. | MASTER-f70ce307-0009: A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo. | MASTER-51b8f0ad-0009: A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo. | MASTER-edece80c-0026: A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo.",P2,MASTER-e1169a77-0026: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-f70ce307-0009: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-51b8f0ad-0009: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-edece80c-0026: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-e1169a77-0026 | MASTER-f70ce307-0009 | MASTER-51b8f0ad-0009 | MASTER-edece80c-0026,4,"[{""id"":""MASTER-e1169a77-0026"",""pedido"":""A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 474""],""aceitacao"":""A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""cartografia/relações""},{""id"":""MASTER-f70ce307-0009"",""pedido"":""A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v1.docx; SHA f70ce3075523c6278e00dce15b9c7acf2b690679e16959ae5f7d007e754cfc6e; w:p 131""],""aceitacao"":""A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""cartografia/relações""},{""id"":""MASTER-51b8f0ad-0009"",""pedido"":""A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v2.docx; SHA 51b8f0ad3296d1064a5c12b450874fc72640869f10a164319cd7f3153dd3a086; w:p 173""],""aceitacao"":""A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""cartografia/relações""},{""id"":""MASTER-edece80c-0026"",""pedido"":""A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 474""],""aceitacao"":""A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""cartografia/relações""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.geo_locations: 1990 registos; public.geo_geometries: 0 registos; public.project_locations: 28 registos; public.cluster_projects: 13 registos; public.opportunity_projects: 0 registos; public.opportunity_clusters: 0 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.","[INSTITUICOES-20261110] Local/categoria/tipo → banco e seguradora → fonte/contacto → mesmo dossier → actualização do processo/recuperação demonstrados; presença física e cobertura separadas, incertezas/histórico explícitos. Restam instalação, revisão/publicação editorial autenticada, consulta efectiva no destino e visual. Outros critérios desta linha não encerrados. | Histórico anterior preservado: [ACT12-20261110] Onze fichas fundamentadas (7instituições+4programas/fundos; BNI Capital como produto BNI), pesquisa local/necessidade no mesmo produto, condições/fontes/contactos e gravação/recuperação no mesmo dossier demonstradas. Restam instalação, preparação/revisão/publicação autenticada e consulta real no destino; visual pendente. Outros critérios desta linha não encerrados. | Histórico anterior preservado: Demonstrar consumidor: pesquisar→selecionar→gravar→nova sessão→renderizar limite correto; conservar pai, código e fonte. Critério individual original preservado; cobertura atual ainda não individualizada. Preparação editorial assistida em QA: selecção/conferência e publicação explícita separadas, MFA nativo, edições preservadas e repetição exacta. Disponibilização efectiva ainda pendente. Instalação ef24cbdc confirmada10/11/2026; backup/restauro190tabelas/369ficheiros; fontes33hashes. Conteúdo ainda0fichas/0publicações; entrada no editor confirmada, sem POST de preparação/publicação observado. ACT12 aberto até consulta efectiva, sem nova instalação exigida. Confirmação posterior10/11:32rascunhos persistidos/0publicações; continuação e publicação403 após expiraçãoMFA900s (21:31:43+02). Retoma autenticada idempotente conserva rascunhos. Instalaçãoef24cbdc preservada; ACT12 aberto. Confirmação seguinte:90rascunhos/0publicações, recusas403 apósMFA. CorrecçãoQA de retoma na mesma aba poractor/fontes, confirmação separada e recuperação exacta; selecção todas270/contadores/controlos visíveis. Revisãoactivaef24cbdc até recibo posterior. Retoma instalada4f3dbcf8/22:01+02,7hashes/HTTP200/backup-restauro190tabelas369ficheiros, guardasMFA mantidas.90rascunhos/0publicações; preparação/publicação autenticada e consulta efectiva ainda pendentes. ACT12 aberto. Diagnóstico posterior:loginMFAEdge22:03:53/dashboard200; editor403Safari/WebKit22:04 em sessão anterior. Não era expiração da nova sessãoEdge. Colar URL noEdge autenticado; nenhuma permissão/sessão/configuração alterada. Abertura/publicação efectiva por confirmar. Acesso reposto:editorEdgeHTTP200às22:11:21+02 na sessão correcta; sem nova instalação/permissão. Publicação/conteúdo consultável ainda por confirmar. ENTREGACONFIRMADA10/11/2026às22:54:31+02:270/270instituições do documento publicadas/270identidades/393locais168contactos; nenhuma em falta. CatálogoHTTP200total270incluindo histórico, filtroseguradora/Nampula6resultados eBCI/Absa/ArkoHTTP200. Cadastro/disponibilização do original concluídos emhomologação4f3dbcf8; continuidade dossierQA aceite reutilizada; visual separado. Cinco programas anteriores permanecem privados. Provaoutputs/funding-directory-20261110/institutions/publication-complete.json.","InvestmentGeography, campos TerritoryFields/ProvinceSelect, geo_locations/geo_geometries e importador autenticado","QA408/581INE; ativo0geometrias;173correspondências por nome/edição/pai, Mandie ambíguo. Publicação é ação separada.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: território. Esforço de código adicional só após lacuna reproduzida.,"[INSTITUICOES-20261110]outputs/funding-directory-20261110/institutions/{content,verification}.json e catalogo-qa.html/270fichas;5API/735asserções e28frontend dirigidos. Fonte Instituições financeiras em Moçambique.docx SHA119bb5514d2777849b70aebfec21d28a41885cbdc7d9827fbebd764fe994c108. | Histórico anterior preservado: [ACT12-20261110] outputs/funding-directory-20261110/{verification,content-qa,dossier-qa}.json e catalogo-qa.html/11fichas;3API/127asserções,13frontend; fonte benchmark de melhorias investeMoz.docx SHA065203aacfae766c62cf9c2c272ebacc61ff23bd4ff9e91535939fede87f7617. | Histórico anterior preservado: outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual. Preparação editorial assistida em QA: selecção/conferência e publicação explícita separadas, MFA nativo, edições preservadas e repetição exacta. Disponibilização efectiva ainda pendente. Instalação ef24cbdc confirmada10/11/2026; backup/restauro190tabelas/369ficheiros; fontes33hashes. Conteúdo ainda0fichas/0publicações; entrada no editor confirmada, sem POST de preparação/publicação observado. ACT12 aberto até consulta efectiva, sem nova instalação exigida. Confirmação posterior10/11:32rascunhos persistidos/0publicações; continuação e publicação403 após expiraçãoMFA900s (21:31:43+02). Retoma autenticada idempotente conserva rascunhos. Instalaçãoef24cbdc preservada; ACT12 aberto. Confirmação seguinte:90rascunhos/0publicações, recusas403 apósMFA. CorrecçãoQA de retoma na mesma aba poractor/fontes, confirmação separada e recuperação exacta; selecção todas270/contadores/controlos visíveis. Revisãoactivaef24cbdc até recibo posterior. Retoma instalada4f3dbcf8/22:01+02,7hashes/HTTP200/backup-restauro190tabelas369ficheiros, guardasMFA mantidas.90rascunhos/0publicações; preparação/publicação autenticada e consulta efectiva ainda pendentes. ACT12 aberto. Diagnóstico posterior:loginMFAEdge22:03:53/dashboard200; editor403Safari/WebKit22:04 em sessão anterior. Não era expiração da nova sessãoEdge. Colar URL noEdge autenticado; nenhuma permissão/sessão/configuração alterada. Abertura/publicação efectiva por confirmar. Acesso reposto:editorEdgeHTTP200às22:11:21+02 na sessão correcta; sem nova instalação/permissão. Publicação/conteúdo consultável ainda por confirmar. ENTREGACONFIRMADA10/11/2026às22:54:31+02:270/270instituições do documento publicadas/270identidades/393locais168contactos; nenhuma em falta. CatálogoHTTP200total270incluindo histórico, filtroseguradora/Nampula6resultados eBCI/Absa/ArkoHTTP200. Cadastro/disponibilização do original concluídos emhomologação4f3dbcf8; continuidade dossierQA aceite reutilizada; visual separado. Cinco programas anteriores permanecem privados. Provaoutputs/funding-directory-20261110/institutions/publication-complete.json.",território,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",resources/js/components/investment-territory.tsx; app/Http/Controllers/InvestmentTerritoryController.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"InvestmentTerritoryTest, TerritorialRegistryTest, InvestmentTerritorialTraceabilityTest, InvestmentZoneTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, +MASTER-e1169a77-0026,"A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo.",portal do investidor\Portal V4\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 474 | portal do investidor\Portal V4\upgrade do portal de investimentos v1.docx; SHA f70ce3075523c6278e00dce15b9c7acf2b690679e16959ae5f7d007e754cfc6e; w:p 131 | portal do investidor\Portal V4\upgrade do portal de investimentos v2.docx; SHA 51b8f0ad3296d1064a5c12b450874fc72640869f10a164319cd7f3153dd3a086; w:p 173 | portal do investidor\Portal V4\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 474,cartografia/relações,/api/v1/geo/drafts; /api/v1/geo/search; /api/v1/geo/sources; /api/v1/geo/sources/{id}/transitions; /api/v1/geo/territories; /api/v1/geo/territories/{id}; /api/v1/geo/territories/{id}/transitions; /api/v1/geo/territories/{type}/{id}; /api/v1/geo/{collection}; /api/v1/investment/compare; /api/v1/investment/export; /api/v1/investment/favourites/{id},"InvestmentGeography, campos TerritoryFields/ProvinceSelect, geo_locations/geo_geometries e importador autenticado. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","[INSTITUICOES-20261110]270instituições/operadores,393referências de localização e168contactos do documento fornecido, em QA. Nenhuma nova instalação/publicação activa. | Histórico anterior preservado: [ACT12-20261110] Directório financeiro/conteúdo fornecido em QA; não instalado/publicado. Homologação1c75a30a mantém zero fichas financeiras. | Histórico anterior preservado: Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados. Preparação editorial assistida em QA: selecção/conferência e publicação explícita separadas, MFA nativo, edições preservadas e repetição exacta. Disponibilização efectiva ainda pendente. Instalação ef24cbdc confirmada10/11/2026; backup/restauro190tabelas/369ficheiros; fontes33hashes. Conteúdo ainda0fichas/0publicações; entrada no editor confirmada, sem POST de preparação/publicação observado. ACT12 aberto até consulta efectiva, sem nova instalação exigida. Confirmação posterior10/11:32rascunhos persistidos/0publicações; continuação e publicação403 após expiraçãoMFA900s (21:31:43+02). Retoma autenticada idempotente conserva rascunhos. Instalaçãoef24cbdc preservada; ACT12 aberto. Confirmação seguinte:90rascunhos/0publicações, recusas403 apósMFA. CorrecçãoQA de retoma na mesma aba poractor/fontes, confirmação separada e recuperação exacta; selecção todas270/contadores/controlos visíveis. Revisãoactivaef24cbdc até recibo posterior. Retoma instalada4f3dbcf8/22:01+02,7hashes/HTTP200/backup-restauro190tabelas369ficheiros, guardasMFA mantidas.90rascunhos/0publicações; preparação/publicação autenticada e consulta efectiva ainda pendentes. ACT12 aberto. Diagnóstico posterior:loginMFAEdge22:03:53/dashboard200; editor403Safari/WebKit22:04 em sessão anterior. Não era expiração da nova sessãoEdge. Colar URL noEdge autenticado; nenhuma permissão/sessão/configuração alterada. Abertura/publicação efectiva por confirmar. Acesso reposto:editorEdgeHTTP200às22:11:21+02 na sessão correcta; sem nova instalação/permissão. Publicação/conteúdo consultável ainda por confirmar. ENTREGACONFIRMADA10/11/2026às22:54:31+02:270/270instituições do documento publicadas/270identidades/393locais168contactos; nenhuma em falta. CatálogoHTTP200total270incluindo histórico, filtroseguradora/Nampula6resultados eBCI/Absa/ArkoHTTP200. Cadastro/disponibilização do original concluídos emhomologação4f3dbcf8; continuidade dossierQA aceite reutilizada; visual separado. Cinco programas anteriores permanecem privados. Provaoutputs/funding-directory-20261110/institutions/publication-complete.json.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,"Demonstrar consumidor: pesquisar→selecionar→gravar→nova sessão→renderizar limite correto; conservar pai, código e fonte. Critério individual original preservado; cobertura atual ainda não individualizada.","QA408/581INE; ativo0geometrias;173correspondências por nome/edição/pai, Mandie ambíguo. Publicação é ação separada. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","MASTER-e1169a77-0026: A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo. | MASTER-f70ce307-0009: A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo. | MASTER-51b8f0ad-0009: A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo. | MASTER-edece80c-0026: A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo.",P2,MASTER-e1169a77-0026: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-f70ce307-0009: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-51b8f0ad-0009: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-edece80c-0026: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-e1169a77-0026 | MASTER-f70ce307-0009 | MASTER-51b8f0ad-0009 | MASTER-edece80c-0026,4,"[{""id"":""MASTER-e1169a77-0026"",""pedido"":""A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 474""],""aceitacao"":""A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""cartografia/relações""},{""id"":""MASTER-f70ce307-0009"",""pedido"":""A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v1.docx; SHA f70ce3075523c6278e00dce15b9c7acf2b690679e16959ae5f7d007e754cfc6e; w:p 131""],""aceitacao"":""A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""cartografia/relações""},{""id"":""MASTER-51b8f0ad-0009"",""pedido"":""A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v2.docx; SHA 51b8f0ad3296d1064a5c12b450874fc72640869f10a164319cd7f3153dd3a086; w:p 173""],""aceitacao"":""A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""cartografia/relações""},{""id"":""MASTER-edece80c-0026"",""pedido"":""A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 474""],""aceitacao"":""A plataforma deve manter um directório verificado de fornecedores locais, prestadores de serviços, operadores logísticos, consultores, instituições financeiras, centros de formação e parceiros tecnológicos. Cada projecto poderá publicar necessidades de aquisição e competências, enquanto fornecedores poderão apresentar capacidade, certificações, cobertura territorial e referências. O sistema deverá recomendar ligações entre investidores e fornecedores, medir contratos locais, emprego, formação e transferência de tecnologia e impedir que a recomendação seja apresentada como certificação ou garantia da Tempo."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""cartografia/relações""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.geo_locations: 1990 registos; public.geo_geometries: 0 registos; public.project_locations: 28 registos; public.cluster_projects: 13 registos; public.opportunity_projects: 0 registos; public.opportunity_clusters: 0 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.","[INSTITUICOES-20261110] Local/categoria/tipo → banco e seguradora → fonte/contacto → mesmo dossier → actualização do processo/recuperação demonstrados; presença física e cobertura separadas, incertezas/histórico explícitos. Restam instalação, revisão/publicação editorial autenticada, consulta efectiva no destino e visual. Outros critérios desta linha não encerrados. | Histórico anterior preservado: [ACT12-20261110] Onze fichas fundamentadas (7instituições+4programas/fundos; BNI Capital como produto BNI), pesquisa local/necessidade no mesmo produto, condições/fontes/contactos e gravação/recuperação no mesmo dossier demonstradas. Restam instalação, preparação/revisão/publicação autenticada e consulta real no destino; visual pendente. Outros critérios desta linha não encerrados. | Histórico anterior preservado: Demonstrar consumidor: pesquisar→selecionar→gravar→nova sessão→renderizar limite correto; conservar pai, código e fonte. Critério individual original preservado; cobertura atual ainda não individualizada. Preparação editorial assistida em QA: selecção/conferência e publicação explícita separadas, MFA nativo, edições preservadas e repetição exacta. Disponibilização efectiva ainda pendente. Instalação ef24cbdc confirmada10/11/2026; backup/restauro190tabelas/369ficheiros; fontes33hashes. Conteúdo ainda0fichas/0publicações; entrada no editor confirmada, sem POST de preparação/publicação observado. ACT12 aberto até consulta efectiva, sem nova instalação exigida. Confirmação posterior10/11:32rascunhos persistidos/0publicações; continuação e publicação403 após expiraçãoMFA900s (21:31:43+02). Retoma autenticada idempotente conserva rascunhos. Instalaçãoef24cbdc preservada; ACT12 aberto. Confirmação seguinte:90rascunhos/0publicações, recusas403 apósMFA. CorrecçãoQA de retoma na mesma aba poractor/fontes, confirmação separada e recuperação exacta; selecção todas270/contadores/controlos visíveis. Revisãoactivaef24cbdc até recibo posterior. Retoma instalada4f3dbcf8/22:01+02,7hashes/HTTP200/backup-restauro190tabelas369ficheiros, guardasMFA mantidas.90rascunhos/0publicações; preparação/publicação autenticada e consulta efectiva ainda pendentes. ACT12 aberto. Diagnóstico posterior:loginMFAEdge22:03:53/dashboard200; editor403Safari/WebKit22:04 em sessão anterior. Não era expiração da nova sessãoEdge. Colar URL noEdge autenticado; nenhuma permissão/sessão/configuração alterada. Abertura/publicação efectiva por confirmar. Acesso reposto:editorEdgeHTTP200às22:11:21+02 na sessão correcta; sem nova instalação/permissão. Publicação/conteúdo consultável ainda por confirmar. ENTREGACONFIRMADA10/11/2026às22:54:31+02:270/270instituições do documento publicadas/270identidades/393locais168contactos; nenhuma em falta. CatálogoHTTP200total270incluindo histórico, filtroseguradora/Nampula6resultados eBCI/Absa/ArkoHTTP200. Cadastro/disponibilização do original concluídos emhomologação4f3dbcf8; continuidade dossierQA aceite reutilizada; visual separado. Cinco programas anteriores permanecem privados. Provaoutputs/funding-directory-20261110/institutions/publication-complete.json. | 15/11/2026 - conferencia dirigida dos quatro percursos: ver apresentacao-contexto-qa-20261115.md, tabela por ecra/percurso. Hotel/Agronegocio: API de contexto, entidade, cenario e retorno ao mesmo dossier verificados; preparacao financeira assistida DIVERGENTE. Fundos: filtros e retorno corrigidos/testados. Demografia: sintese e ambito territorial testados. Computador/telemovel autenticados e retoma ponta a ponta NAO VERIFICADOS. QA apenas; entrega transversal nao aceite nem instalada. | Retoma visual após Esc — 15/11/2026: janela controlada em /login; dossier Hotel redirige para autenticação. Sessão do painel indicado pelo responsável não identificada; solicitado apenas o URL. Conferência autenticada/telemóvel NÃO VERIFICADA, sem repetir testes aceites, reiniciar navegadores ou instalar. Evidência no registo de apresentação/contexto existente. 15/11: acesso QA recuperado; Hotel demonstrado na interface com empresa existente, orçamento 2M, mobilizado 1M, receita 7,5M, custo 2M, retoma e relatório descarregado. Emulação 390x844: edição e continuação. Restantes percursos/retoma autenticada integral NÃO VERIFICADOS; sem instalação. Continuação QA: Agronegócio demonstrou entidade por constituir, modelo próprio/retoma/retorno sem converter intervalo em total; Banca/Banco comercial excluiu corretora/microsseguradora sintéticas e guardou referência/produto/versão no dossier; demografia apresentou Boane como contexto distrital. Emulação móvel: síntese legível e província limpa desactiva distritos, sem resultados antigos confundidos. Cobertura integral ainda aberta. [SALDO VISUAL QA 15/11 — PASSOS PENDENTES] Execução actual substitui o saldo anterior: V01: Critérios e resultado bancário recuperados no retorno real do detalhe. 1440 px: APROVADO, 2026-11-15T15:41:27.944Z, evidência V01-1440-1794757287944; 390 px: APROVADO, 2026-11-15T15:41:54.875Z, evidência V01-390-1794757314875 | V02: Pesquisas A/B conservaram critérios e contextos separados após retorno e recarga. 1440 px: APROVADO, 2026-11-15T16:28:25.029Z, evidência V02-1440-1794760105052; 390 px: APROVADO, 2026-11-15T16:29:13.443Z, evidência V02-390-1794760153468 | V03: Combinação contraditória distinta do vazio válido; mudança de categoria resolveu apenas o tipo dependente. 1440 px: APROVADO, 2026-11-15T15:41:50.001Z, evidência V03-1440-1794757310001; 390 px: APROVADO, 2026-11-15T15:43:11.560Z, evidência V03-390-1794757391560","InvestmentGeography, campos TerritoryFields/ProvinceSelect, geo_locations/geo_geometries e importador autenticado","QA408/581INE; ativo0geometrias;173correspondências por nome/edição/pai, Mandie ambíguo. Publicação é ação separada.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: território. Esforço de código adicional só após lacuna reproduzida.,"[INSTITUICOES-20261110]outputs/funding-directory-20261110/institutions/{content,verification}.json e catalogo-qa.html/270fichas;5API/735asserções e28frontend dirigidos. Fonte Instituições financeiras em Moçambique.docx SHA119bb5514d2777849b70aebfec21d28a41885cbdc7d9827fbebd764fe994c108. | Histórico anterior preservado: [ACT12-20261110] outputs/funding-directory-20261110/{verification,content-qa,dossier-qa}.json e catalogo-qa.html/11fichas;3API/127asserções,13frontend; fonte benchmark de melhorias investeMoz.docx SHA065203aacfae766c62cf9c2c272ebacc61ff23bd4ff9e91535939fede87f7617. | Histórico anterior preservado: outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual. Preparação editorial assistida em QA: selecção/conferência e publicação explícita separadas, MFA nativo, edições preservadas e repetição exacta. Disponibilização efectiva ainda pendente. Instalação ef24cbdc confirmada10/11/2026; backup/restauro190tabelas/369ficheiros; fontes33hashes. Conteúdo ainda0fichas/0publicações; entrada no editor confirmada, sem POST de preparação/publicação observado. ACT12 aberto até consulta efectiva, sem nova instalação exigida. Confirmação posterior10/11:32rascunhos persistidos/0publicações; continuação e publicação403 após expiraçãoMFA900s (21:31:43+02). Retoma autenticada idempotente conserva rascunhos. Instalaçãoef24cbdc preservada; ACT12 aberto. Confirmação seguinte:90rascunhos/0publicações, recusas403 apósMFA. CorrecçãoQA de retoma na mesma aba poractor/fontes, confirmação separada e recuperação exacta; selecção todas270/contadores/controlos visíveis. Revisãoactivaef24cbdc até recibo posterior. Retoma instalada4f3dbcf8/22:01+02,7hashes/HTTP200/backup-restauro190tabelas369ficheiros, guardasMFA mantidas.90rascunhos/0publicações; preparação/publicação autenticada e consulta efectiva ainda pendentes. ACT12 aberto. Diagnóstico posterior:loginMFAEdge22:03:53/dashboard200; editor403Safari/WebKit22:04 em sessão anterior. Não era expiração da nova sessãoEdge. Colar URL noEdge autenticado; nenhuma permissão/sessão/configuração alterada. Abertura/publicação efectiva por confirmar. Acesso reposto:editorEdgeHTTP200às22:11:21+02 na sessão correcta; sem nova instalação/permissão. Publicação/conteúdo consultável ainda por confirmar. ENTREGACONFIRMADA10/11/2026às22:54:31+02:270/270instituições do documento publicadas/270identidades/393locais168contactos; nenhuma em falta. CatálogoHTTP200total270incluindo histórico, filtroseguradora/Nampula6resultados eBCI/Absa/ArkoHTTP200. Cadastro/disponibilização do original concluídos emhomologação4f3dbcf8; continuidade dossierQA aceite reutilizada; visual separado. Cinco programas anteriores permanecem privados. Provaoutputs/funding-directory-20261110/institutions/publication-complete.json. | docs/investmoz/v2/auditoria-portal/apresentacao-contexto-qa-20261115.md (conferencia dirigida dos quatro percursos); outputs/investor-intent-20261115/backend.log (12 testes/412 assercoes); frontend.log (137 testes); phpstan.log (zero erros) | Conferência autenticada e recibos adicionais: apresentacao-contexto-qa-20261115.md; outputs/investor-intent-20261115/hotel-browser-report.html | Saldo actual V01–V15: apresentacao-contexto-qa-20261115.md#verificações-restantes--saldo-actual-para-execução-na-mesma-candidata",território,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",resources/js/components/investment-territory.tsx; app/Http/Controllers/InvestmentTerritoryController.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"InvestmentTerritoryTest, TerritorialRegistryTest, InvestmentTerritorialTraceabilityTest, InvestmentZoneTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,"Conferencia individual por ecra: intencao, reutilizacao, filtros, valores, gravacao/retoma, isolamento, computador e telemovel; sem inferir cobertura dos consumidores pelo componente. ","APROVADO no saldo QA deste requisito [EXECUÇÃO PLAYWRIGHT QA 15/11] Ver estados V executados na coluna de evidência e no mesmo relatório; sem instalação ou aceitação global do portal. [HISTÓRICO ANTERIOR] NAO VERIFICADO integralmente; preparacao financeira DIVERGENTE; correccoes dirigidas QA demonstradas. Sem instalacao. | Hotel: recorte demonstrado; aceitação transversal integral permanece não verificada. | Instalação suspensa; encerrar apenas os passos V associados, com executante/data/candidata/largura/evidência. Provas aceites preservadas; bloqueio do controlo de URL não demonstra falha do portal." MASTER-e1169a77-0035,"A análise de plataformas de promoção de investimento indica quatro modelos complementares. A Invest India e a India Investment Grid combinam inteligência sectorial, projectos pesquisáveis, manifestação de interesse, ligação a promotores, avaliação de localização e acompanhamento do investidor. A Invest Saudi integra promoção, oportunidades, registo do investidor, serviços electrónicos, incentivos e assistência antes, durante e depois da instalação. O Rwanda Development Board articula balcão único, registo do investimento, licenciamento, avaliação ambiental, procedimentos empresariais e acompanhamento pós-investimento com resolução de constrangimentos. A Estónia demonstra o valor da identidade digital, assinatura electrónica, constituição remota de empresas e acesso integrado a serviços públicos. Para alcançar um nível comparável, o InvestMoz deve combinar promoção, transacção assistida, identidade digital, interoperabilidade, acompanhamento pós-investimento e inteligência de mercado numa única experiência.",portal do investidor\Portal V4\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 485 | portal do investidor\Portal V4\upgrade do portal de investimentos v1.docx; SHA f70ce3075523c6278e00dce15b9c7acf2b690679e16959ae5f7d007e754cfc6e; w:p 142 | portal do investidor\Portal V4\upgrade do portal de investimentos v2.docx; SHA 51b8f0ad3296d1064a5c12b450874fc72640869f10a164319cd7f3153dd3a086; w:p 184 | portal do investidor\Portal V4\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 485,oportunidades,/api/v1/business-opportunities; /api/v1/business-opportunities/{slug}; /investidor/terra-duat; /investidor/terra-duat/novo; /investidor/terra-duat/{id}; /investidor/terra-duat/{id}/actualizacoes; /investidor/terra-duat/{id}/documentos; /investidor/terra-duat/{id}/documentos/{attachment}; /investidor/terra-duat/{id}/editar; /investidor/terra-duat/{id}/imprimir; /investidor/terra-duat/{id}/solicitar-apoio; /management/opportunities,"OpportunityManagement, OpportunityCanonicalContract/Response, OpportunityReviewMateriality, PortalProfileAccess, OpportunityResources. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Reconciliar contrato/cláusula e provas por categoria; completar apenas falha/variante executável identificada. Response normativo não é completo. Critério individual original preservado; cobertura atual ainda não individualizada.,"030000→040000 já instalados; contratos/resources existentes, sessão/MFA, ClamD e worker para ficheiros; gates das seis categorias ON. Variantes modulares/offers continuam separadas. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","MASTER-e1169a77-0035: A análise de plataformas de promoção de investimento indica quatro modelos complementares. A Invest India e a India Investment Grid combinam inteligência sectorial, projectos pesquisáveis, manifestação de interesse, ligação a promotores, avaliação de localização e acompanhamento do investidor. A Invest Saudi integra promoção, oportunidades, registo do investidor, serviços electrónicos, incentivos e assistência antes, durante e depois da instalação. O Rwanda Development Board articula balcão único, registo do investimento, licenciamento, avaliação ambiental, procedimentos empresariais e acompanhamento pós-investimento com resolução de constrangimentos. A Estónia demonstra o valor da identidade digital, assinatura electrónica, constituição remota de empresas e acesso integrado a serviços públicos. Para alcançar um nível comparável, o InvestMoz deve combinar promoção, transacção assistida, identidade digital, interoperabilidade, acompanhamento pós-investimento e inteligência de mercado numa única experiência. | MASTER-f70ce307-0018: A análise de plataformas de promoção de investimento indica quatro modelos complementares. A Invest India e a India Investment Grid combinam inteligência sectorial, projectos pesquisáveis, manifestação de interesse, ligação a promotores, avaliação de localização e acompanhamento do investidor. A Invest Saudi integra promoção, oportunidades, registo do investidor, serviços electrónicos, incentivos e assistência antes, durante e depois da instalação. O Rwanda Development Board articula balcão único, registo do investimento, licenciamento, avaliação ambiental, procedimentos empresariais e acompanhamento pós-investimento com resolução de constrangimentos. A Estónia demonstra o valor da identidade digital, assinatura electrónica, constituição remota de empresas e acesso integrado a serviços públicos. Para alcançar um nível comparável, o InvestMoz deve combinar promoção, transacção assistida, identidade digital, interoperabilidade, acompanhamento pós-investimento e inteligência de mercado numa única experiência. | MASTER-51b8f0ad-0018: A análise de plataformas de promoção de investimento indica quatro modelos complementares. A Invest India e a India Investment Grid combinam inteligência sectorial, projectos pesquisáveis, manifestação de interesse, ligação a promotores, avaliação de localização e acompanhamento do investidor. A Invest Saudi integra promoção, oportunidades, registo do investidor, serviços electrónicos, incentivos e assistência antes, durante e depois da instalação. O Rwanda Development Board articula balcão único, registo do investimento, licenciamento, avaliação ambiental, procedimentos empresariais e acompanhamento pós-investimento com resolução de constrangimentos. A Estónia demonstra o valor da identidade digital, assinatura electrónica, constituição remota de empresas e acesso integrado a serviços públicos. Para alcançar um nível comparável, o InvestMoz deve combinar promoção, transacção assistida, identidade digital, interoperabilidade, acompanhamento pós-investimento e inteligência de mercado numa única experiência. | MASTER-edece80c-0035: A análise de plataformas de promoção de investimento indica quatro modelos complementares. A Invest India e a India Investment Grid combinam inteligência sectorial, projectos pesquisáveis, manifestação de interesse, ligação a promotores, avaliação de localização e acompanhamento do investidor. A Invest Saudi integra promoção, oportunidades, registo do investidor, serviços electrónicos, incentivos e assistência antes, durante e depois da instalação. O Rwanda Development Board articula balcão único, registo do investimento, licenciamento, avaliação ambiental, procedimentos empresariais e acompanhamento pós-investimento com resolução de constrangimentos. A Estónia demonstra o valor da identidade digital, assinatura electrónica, constituição remota de empresas e acesso integrado a serviços públicos. Para alcançar um nível comparável, o InvestMoz deve combinar promoção, transacção assistida, identidade digital, interoperabilidade, acompanhamento pós-investimento e inteligência de mercado numa única experiência.",P2,MASTER-e1169a77-0035: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-f70ce307-0018: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-51b8f0ad-0018: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-edece80c-0035: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-e1169a77-0035 | MASTER-f70ce307-0018 | MASTER-51b8f0ad-0018 | MASTER-edece80c-0035,4,"[{""id"":""MASTER-e1169a77-0035"",""pedido"":""A análise de plataformas de promoção de investimento indica quatro modelos complementares. A Invest India e a India Investment Grid combinam inteligência sectorial, projectos pesquisáveis, manifestação de interesse, ligação a promotores, avaliação de localização e acompanhamento do investidor. A Invest Saudi integra promoção, oportunidades, registo do investidor, serviços electrónicos, incentivos e assistência antes, durante e depois da instalação. O Rwanda Development Board articula balcão único, registo do investimento, licenciamento, avaliação ambiental, procedimentos empresariais e acompanhamento pós-investimento com resolução de constrangimentos. A Estónia demonstra o valor da identidade digital, assinatura electrónica, constituição remota de empresas e acesso integrado a serviços públicos. Para alcançar um nível comparável, o InvestMoz deve combinar promoção, transacção assistida, identidade digital, interoperabilidade, acompanhamento pós-investimento e inteligência de mercado numa única experiência."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 485""],""aceitacao"":""A análise de plataformas de promoção de investimento indica quatro modelos complementares. A Invest India e a India Investment Grid combinam inteligência sectorial, projectos pesquisáveis, manifestação de interesse, ligação a promotores, avaliação de localização e acompanhamento do investidor. A Invest Saudi integra promoção, oportunidades, registo do investidor, serviços electrónicos, incentivos e assistência antes, durante e depois da instalação. O Rwanda Development Board articula balcão único, registo do investimento, licenciamento, avaliação ambiental, procedimentos empresariais e acompanhamento pós-investimento com resolução de constrangimentos. A Estónia demonstra o valor da identidade digital, assinatura electrónica, constituição remota de empresas e acesso integrado a serviços públicos. Para alcançar um nível comparável, o InvestMoz deve combinar promoção, transacção assistida, identidade digital, interoperabilidade, acompanhamento pós-investimento e inteligência de mercado numa única experiência."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""oportunidades""},{""id"":""MASTER-f70ce307-0018"",""pedido"":""A análise de plataformas de promoção de investimento indica quatro modelos complementares. A Invest India e a India Investment Grid combinam inteligência sectorial, projectos pesquisáveis, manifestação de interesse, ligação a promotores, avaliação de localização e acompanhamento do investidor. A Invest Saudi integra promoção, oportunidades, registo do investidor, serviços electrónicos, incentivos e assistência antes, durante e depois da instalação. O Rwanda Development Board articula balcão único, registo do investimento, licenciamento, avaliação ambiental, procedimentos empresariais e acompanhamento pós-investimento com resolução de constrangimentos. A Estónia demonstra o valor da identidade digital, assinatura electrónica, constituição remota de empresas e acesso integrado a serviços públicos. Para alcançar um nível comparável, o InvestMoz deve combinar promoção, transacção assistida, identidade digital, interoperabilidade, acompanhamento pós-investimento e inteligência de mercado numa única experiência."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v1.docx; SHA f70ce3075523c6278e00dce15b9c7acf2b690679e16959ae5f7d007e754cfc6e; w:p 142""],""aceitacao"":""A análise de plataformas de promoção de investimento indica quatro modelos complementares. A Invest India e a India Investment Grid combinam inteligência sectorial, projectos pesquisáveis, manifestação de interesse, ligação a promotores, avaliação de localização e acompanhamento do investidor. A Invest Saudi integra promoção, oportunidades, registo do investidor, serviços electrónicos, incentivos e assistência antes, durante e depois da instalação. O Rwanda Development Board articula balcão único, registo do investimento, licenciamento, avaliação ambiental, procedimentos empresariais e acompanhamento pós-investimento com resolução de constrangimentos. A Estónia demonstra o valor da identidade digital, assinatura electrónica, constituição remota de empresas e acesso integrado a serviços públicos. Para alcançar um nível comparável, o InvestMoz deve combinar promoção, transacção assistida, identidade digital, interoperabilidade, acompanhamento pós-investimento e inteligência de mercado numa única experiência."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""oportunidades""},{""id"":""MASTER-51b8f0ad-0018"",""pedido"":""A análise de plataformas de promoção de investimento indica quatro modelos complementares. A Invest India e a India Investment Grid combinam inteligência sectorial, projectos pesquisáveis, manifestação de interesse, ligação a promotores, avaliação de localização e acompanhamento do investidor. A Invest Saudi integra promoção, oportunidades, registo do investidor, serviços electrónicos, incentivos e assistência antes, durante e depois da instalação. O Rwanda Development Board articula balcão único, registo do investimento, licenciamento, avaliação ambiental, procedimentos empresariais e acompanhamento pós-investimento com resolução de constrangimentos. A Estónia demonstra o valor da identidade digital, assinatura electrónica, constituição remota de empresas e acesso integrado a serviços públicos. Para alcançar um nível comparável, o InvestMoz deve combinar promoção, transacção assistida, identidade digital, interoperabilidade, acompanhamento pós-investimento e inteligência de mercado numa única experiência."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v2.docx; SHA 51b8f0ad3296d1064a5c12b450874fc72640869f10a164319cd7f3153dd3a086; w:p 184""],""aceitacao"":""A análise de plataformas de promoção de investimento indica quatro modelos complementares. A Invest India e a India Investment Grid combinam inteligência sectorial, projectos pesquisáveis, manifestação de interesse, ligação a promotores, avaliação de localização e acompanhamento do investidor. A Invest Saudi integra promoção, oportunidades, registo do investidor, serviços electrónicos, incentivos e assistência antes, durante e depois da instalação. O Rwanda Development Board articula balcão único, registo do investimento, licenciamento, avaliação ambiental, procedimentos empresariais e acompanhamento pós-investimento com resolução de constrangimentos. A Estónia demonstra o valor da identidade digital, assinatura electrónica, constituição remota de empresas e acesso integrado a serviços públicos. Para alcançar um nível comparável, o InvestMoz deve combinar promoção, transacção assistida, identidade digital, interoperabilidade, acompanhamento pós-investimento e inteligência de mercado numa única experiência."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""oportunidades""},{""id"":""MASTER-edece80c-0035"",""pedido"":""A análise de plataformas de promoção de investimento indica quatro modelos complementares. A Invest India e a India Investment Grid combinam inteligência sectorial, projectos pesquisáveis, manifestação de interesse, ligação a promotores, avaliação de localização e acompanhamento do investidor. A Invest Saudi integra promoção, oportunidades, registo do investidor, serviços electrónicos, incentivos e assistência antes, durante e depois da instalação. O Rwanda Development Board articula balcão único, registo do investimento, licenciamento, avaliação ambiental, procedimentos empresariais e acompanhamento pós-investimento com resolução de constrangimentos. A Estónia demonstra o valor da identidade digital, assinatura electrónica, constituição remota de empresas e acesso integrado a serviços públicos. Para alcançar um nível comparável, o InvestMoz deve combinar promoção, transacção assistida, identidade digital, interoperabilidade, acompanhamento pós-investimento e inteligência de mercado numa única experiência."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 485""],""aceitacao"":""A análise de plataformas de promoção de investimento indica quatro modelos complementares. A Invest India e a India Investment Grid combinam inteligência sectorial, projectos pesquisáveis, manifestação de interesse, ligação a promotores, avaliação de localização e acompanhamento do investidor. A Invest Saudi integra promoção, oportunidades, registo do investidor, serviços electrónicos, incentivos e assistência antes, durante e depois da instalação. O Rwanda Development Board articula balcão único, registo do investimento, licenciamento, avaliação ambiental, procedimentos empresariais e acompanhamento pós-investimento com resolução de constrangimentos. A Estónia demonstra o valor da identidade digital, assinatura electrónica, constituição remota de empresas e acesso integrado a serviços públicos. Para alcançar um nível comparável, o InvestMoz deve combinar promoção, transacção assistida, identidade digital, interoperabilidade, acompanhamento pós-investimento e inteligência de mercado numa única experiência."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""oportunidades""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.opportunities: 6 registos; public.opportunity_images: tabela ausente; public.opportunity_documents: tabela ausente; public.opportunity_location_drafts: tabela ausente,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Reconciliar contrato/cláusula e provas por categoria; completar apenas falha/variante executável identificada. Response normativo não é completo. Critério individual original preservado; cobertura atual ainda não individualizada.,"OpportunityManagement, OpportunityCanonicalContract/Response, OpportunityReviewMateriality, PortalProfileAccess, OpportunityResources","030000→040000 já instalados; contratos/resources existentes, sessão/MFA, ClamD e worker para ficheiros; gates das seis categorias ON. Variantes modulares/offers continuam separadas.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: oportunidades. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,oportunidades,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Services/OpportunityManagement.php; app/Services/OpportunityResources.php; resources/js/pages/management/opportunity-draft.tsx — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"OpportunityManagementTest, OpportunityResourcesTest, OpportunityOriginReviewTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, MASTER-e1169a77-0040,"O portal deve disponibilizar um balcão único digital que apresente ao investidor um plano personalizado de instalação, com procedimentos, documentos, entidades, dependências, custos validados, prazos indicativos e estado de cada pedido. O investidor deve preencher os dados comuns uma única vez, autorizar a sua reutilização e acompanhar o processo num painel consolidado. A arquitectura deve adoptar APIs, webhooks e eventos de domínio para receber alterações dos sistemas das entidades competentes, evitando sincronizações manuais e pedidos repetidos de informação.",portal do investidor\Portal V4\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 521 | portal do investidor\Portal V4\upgrade do portal de investimentos v1.docx; SHA f70ce3075523c6278e00dce15b9c7acf2b690679e16959ae5f7d007e754cfc6e; w:p 178 | portal do investidor\Portal V4\upgrade do portal de investimentos v2.docx; SHA 51b8f0ad3296d1064a5c12b450874fc72640869f10a164319cd7f3153dd3a086; w:p 220 | portal do investidor\Portal V4\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 521,Balcão/orientação,/balcao-virtual/contextos; /balcao-virtual/dossiers; /balcao-virtual/dossiers/{id}; /balcao-virtual/dossiers/{id}/documentos; /balcao-virtual/dossiers/{id}/documentos/{document}; /balcao-virtual/dossiers/{id}/documentos/{document}/conferencia; /balcao-virtual/dossiers/{id}/etapas; /balcao-virtual/dossiers/{id}/fontes; /balcao-virtual/dossiers/{id}/orientacao; /balcao-virtual/dossiers/{id}/pedidos; /balcao-virtual/dossiers/{id}/pressupostos; /balcao-virtual/dossiers/{id}/recomendacoes,"VirtualDesk, pedidos/casos, anexos, contexto dossier e acompanhamento. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,"Pedido contextual→gravar→submeter→nova sessão→gestor→mensagem/documentos/resultado, reaproveitando A/B. Critério individual original preservado; cobertura atual ainda não individualizada.","Perfis próprios do Balcão; serviços/campos e decisões externas aplicáveis, sem inventar destinatário/prazo. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","MASTER-e1169a77-0040: O portal deve disponibilizar um balcão único digital que apresente ao investidor um plano personalizado de instalação, com procedimentos, documentos, entidades, dependências, custos validados, prazos indicativos e estado de cada pedido. O investidor deve preencher os dados comuns uma única vez, autorizar a sua reutilização e acompanhar o processo num painel consolidado. A arquitectura deve adoptar APIs, webhooks e eventos de domínio para receber alterações dos sistemas das entidades competentes, evitando sincronizações manuais e pedidos repetidos de informação. | MASTER-f70ce307-0023: O portal deve disponibilizar um balcão único digital que apresente ao investidor um plano personalizado de instalação, com procedimentos, documentos, entidades, dependências, custos validados, prazos indicativos e estado de cada pedido. O investidor deve preencher os dados comuns uma única vez, autorizar a sua reutilização e acompanhar o processo num painel consolidado. A arquitectura deve adoptar APIs, webhooks e eventos de domínio para receber alterações dos sistemas das entidades competentes, evitando sincronizações manuais e pedidos repetidos de informação. | MASTER-51b8f0ad-0023: O portal deve disponibilizar um balcão único digital que apresente ao investidor um plano personalizado de instalação, com procedimentos, documentos, entidades, dependências, custos validados, prazos indicativos e estado de cada pedido. O investidor deve preencher os dados comuns uma única vez, autorizar a sua reutilização e acompanhar o processo num painel consolidado. A arquitectura deve adoptar APIs, webhooks e eventos de domínio para receber alterações dos sistemas das entidades competentes, evitando sincronizações manuais e pedidos repetidos de informação. | MASTER-edece80c-0040: O portal deve disponibilizar um balcão único digital que apresente ao investidor um plano personalizado de instalação, com procedimentos, documentos, entidades, dependências, custos validados, prazos indicativos e estado de cada pedido. O investidor deve preencher os dados comuns uma única vez, autorizar a sua reutilização e acompanhar o processo num painel consolidado. A arquitectura deve adoptar APIs, webhooks e eventos de domínio para receber alterações dos sistemas das entidades competentes, evitando sincronizações manuais e pedidos repetidos de informação.",P2,MASTER-e1169a77-0040: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-f70ce307-0023: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-51b8f0ad-0023: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-edece80c-0040: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-e1169a77-0040 | MASTER-f70ce307-0023 | MASTER-51b8f0ad-0023 | MASTER-edece80c-0040,4,"[{""id"":""MASTER-e1169a77-0040"",""pedido"":""O portal deve disponibilizar um balcão único digital que apresente ao investidor um plano personalizado de instalação, com procedimentos, documentos, entidades, dependências, custos validados, prazos indicativos e estado de cada pedido. O investidor deve preencher os dados comuns uma única vez, autorizar a sua reutilização e acompanhar o processo num painel consolidado. A arquitectura deve adoptar APIs, webhooks e eventos de domínio para receber alterações dos sistemas das entidades competentes, evitando sincronizações manuais e pedidos repetidos de informação."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 521""],""aceitacao"":""O portal deve disponibilizar um balcão único digital que apresente ao investidor um plano personalizado de instalação, com procedimentos, documentos, entidades, dependências, custos validados, prazos indicativos e estado de cada pedido. O investidor deve preencher os dados comuns uma única vez, autorizar a sua reutilização e acompanhar o processo num painel consolidado. A arquitectura deve adoptar APIs, webhooks e eventos de domínio para receber alterações dos sistemas das entidades competentes, evitando sincronizações manuais e pedidos repetidos de informação."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""Balcão/orientação""},{""id"":""MASTER-f70ce307-0023"",""pedido"":""O portal deve disponibilizar um balcão único digital que apresente ao investidor um plano personalizado de instalação, com procedimentos, documentos, entidades, dependências, custos validados, prazos indicativos e estado de cada pedido. O investidor deve preencher os dados comuns uma única vez, autorizar a sua reutilização e acompanhar o processo num painel consolidado. A arquitectura deve adoptar APIs, webhooks e eventos de domínio para receber alterações dos sistemas das entidades competentes, evitando sincronizações manuais e pedidos repetidos de informação."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v1.docx; SHA f70ce3075523c6278e00dce15b9c7acf2b690679e16959ae5f7d007e754cfc6e; w:p 178""],""aceitacao"":""O portal deve disponibilizar um balcão único digital que apresente ao investidor um plano personalizado de instalação, com procedimentos, documentos, entidades, dependências, custos validados, prazos indicativos e estado de cada pedido. O investidor deve preencher os dados comuns uma única vez, autorizar a sua reutilização e acompanhar o processo num painel consolidado. A arquitectura deve adoptar APIs, webhooks e eventos de domínio para receber alterações dos sistemas das entidades competentes, evitando sincronizações manuais e pedidos repetidos de informação."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""Balcão/orientação""},{""id"":""MASTER-51b8f0ad-0023"",""pedido"":""O portal deve disponibilizar um balcão único digital que apresente ao investidor um plano personalizado de instalação, com procedimentos, documentos, entidades, dependências, custos validados, prazos indicativos e estado de cada pedido. O investidor deve preencher os dados comuns uma única vez, autorizar a sua reutilização e acompanhar o processo num painel consolidado. A arquitectura deve adoptar APIs, webhooks e eventos de domínio para receber alterações dos sistemas das entidades competentes, evitando sincronizações manuais e pedidos repetidos de informação."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v2.docx; SHA 51b8f0ad3296d1064a5c12b450874fc72640869f10a164319cd7f3153dd3a086; w:p 220""],""aceitacao"":""O portal deve disponibilizar um balcão único digital que apresente ao investidor um plano personalizado de instalação, com procedimentos, documentos, entidades, dependências, custos validados, prazos indicativos e estado de cada pedido. O investidor deve preencher os dados comuns uma única vez, autorizar a sua reutilização e acompanhar o processo num painel consolidado. A arquitectura deve adoptar APIs, webhooks e eventos de domínio para receber alterações dos sistemas das entidades competentes, evitando sincronizações manuais e pedidos repetidos de informação."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""Balcão/orientação""},{""id"":""MASTER-edece80c-0040"",""pedido"":""O portal deve disponibilizar um balcão único digital que apresente ao investidor um plano personalizado de instalação, com procedimentos, documentos, entidades, dependências, custos validados, prazos indicativos e estado de cada pedido. O investidor deve preencher os dados comuns uma única vez, autorizar a sua reutilização e acompanhar o processo num painel consolidado. A arquitectura deve adoptar APIs, webhooks e eventos de domínio para receber alterações dos sistemas das entidades competentes, evitando sincronizações manuais e pedidos repetidos de informação."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 521""],""aceitacao"":""O portal deve disponibilizar um balcão único digital que apresente ao investidor um plano personalizado de instalação, com procedimentos, documentos, entidades, dependências, custos validados, prazos indicativos e estado de cada pedido. O investidor deve preencher os dados comuns uma única vez, autorizar a sua reutilização e acompanhar o processo num painel consolidado. A arquitectura deve adoptar APIs, webhooks e eventos de domínio para receber alterações dos sistemas das entidades competentes, evitando sincronizações manuais e pedidos repetidos de informação."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""Balcão/orientação""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.desk_cases: 1 registos; public.desk_requests: 0 registos; public.desk_institutional_links: 0 registos; public.desk_messages: 0 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.","Pedido contextual→gravar→submeter→nova sessão→gestor→mensagem/documentos/resultado, reaproveitando A/B. Critério individual original preservado; cobertura atual ainda não individualizada.","VirtualDesk, pedidos/casos, anexos, contexto dossier e acompanhamento","Perfis próprios do Balcão; serviços/campos e decisões externas aplicáveis, sem inventar destinatário/prazo.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: balcão. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,balcão,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Services/VirtualDesk.php; app/Services/Ai/InvestorGuidance.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,InvestorGuidanceTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, MASTER-e1169a77-0041,"Decisão tecnológica: a arquitectura alvo manterá React no frontend e Laravel no backend, após actualização das versões, dependências, segurança, modularidade, desempenho e cobertura de testes. O PostgreSQL/PostGIS será a base de dados definitiva da nova versão, devido aos requisitos de corredores, polígonos, áreas de influência, proximidade, intersecções, inteligência territorial e relações geoespaciais. O MySQL permanecerá temporariamente como fonte legada durante a migração e não receberá novos domínios funcionais. A transição deverá ser incremental, reconciliável e reversível, com ensaios, critérios de corte, rollback, validação de integridade e desactivação formal das dependências antigas.",portal do investidor\Portal V4\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 522 | portal do investidor\Portal V4\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 522,cartografia/relações,/api/v1/geo/drafts; /api/v1/geo/search; /api/v1/geo/sources; /api/v1/geo/sources/{id}/transitions; /api/v1/geo/territories; /api/v1/geo/territories/{id}; /api/v1/geo/territories/{id}/transitions; /api/v1/geo/territories/{type}/{id}; /api/v1/geo/{collection}; /api/v1/investment/compare; /api/v1/investment/export; /api/v1/investment/favourites/{id},"InvestmentGeography, campos TerritoryFields/ProvinceSelect, geo_locations/geo_geometries e importador autenticado. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,"Demonstrar consumidor: pesquisar→selecionar→gravar→nova sessão→renderizar limite correto; conservar pai, código e fonte. Critério individual original preservado; cobertura atual ainda não individualizada.","QA408/581INE; ativo0geometrias;173correspondências por nome/edição/pai, Mandie ambíguo. Publicação é ação separada. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","MASTER-e1169a77-0041: Decisão tecnológica: a arquitectura alvo manterá React no frontend e Laravel no backend, após actualização das versões, dependências, segurança, modularidade, desempenho e cobertura de testes. O PostgreSQL/PostGIS será a base de dados definitiva da nova versão, devido aos requisitos de corredores, polígonos, áreas de influência, proximidade, intersecções, inteligência territorial e relações geoespaciais. O MySQL permanecerá temporariamente como fonte legada durante a migração e não receberá novos domínios funcionais. A transição deverá ser incremental, reconciliável e reversível, com ensaios, critérios de corte, rollback, validação de integridade e desactivação formal das dependências antigas. | MASTER-edece80c-0041: Decisão tecnológica: a arquitectura alvo manterá React no frontend e Laravel no backend, após actualização das versões, dependências, segurança, modularidade, desempenho e cobertura de testes. O PostgreSQL/PostGIS será a base de dados definitiva da nova versão, devido aos requisitos de corredores, polígonos, áreas de influência, proximidade, intersecções, inteligência territorial e relações geoespaciais. O MySQL permanecerá temporariamente como fonte legada durante a migração e não receberá novos domínios funcionais. A transição deverá ser incremental, reconciliável e reversível, com ensaios, critérios de corte, rollback, validação de integridade e desactivação formal das dependências antigas.",P2,MASTER-e1169a77-0041: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-edece80c-0041: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-e1169a77-0041 | MASTER-edece80c-0041,2,"[{""id"":""MASTER-e1169a77-0041"",""pedido"":""Decisão tecnológica: a arquitectura alvo manterá React no frontend e Laravel no backend, após actualização das versões, dependências, segurança, modularidade, desempenho e cobertura de testes. O PostgreSQL/PostGIS será a base de dados definitiva da nova versão, devido aos requisitos de corredores, polígonos, áreas de influência, proximidade, intersecções, inteligência territorial e relações geoespaciais. O MySQL permanecerá temporariamente como fonte legada durante a migração e não receberá novos domínios funcionais. A transição deverá ser incremental, reconciliável e reversível, com ensaios, critérios de corte, rollback, validação de integridade e desactivação formal das dependências antigas."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v6 programacao.docx; SHA e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e; w:p 522""],""aceitacao"":""Decisão tecnológica: a arquitectura alvo manterá React no frontend e Laravel no backend, após actualização das versões, dependências, segurança, modularidade, desempenho e cobertura de testes. O PostgreSQL/PostGIS será a base de dados definitiva da nova versão, devido aos requisitos de corredores, polígonos, áreas de influência, proximidade, intersecções, inteligência territorial e relações geoespaciais. O MySQL permanecerá temporariamente como fonte legada durante a migração e não receberá novos domínios funcionais. A transição deverá ser incremental, reconciliável e reversível, com ensaios, critérios de corte, rollback, validação de integridade e desactivação formal das dependências antigas."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""cartografia/relações""},{""id"":""MASTER-edece80c-0041"",""pedido"":""Decisão tecnológica: a arquitectura alvo manterá React no frontend e Laravel no backend, após actualização das versões, dependências, segurança, modularidade, desempenho e cobertura de testes. O PostgreSQL/PostGIS será a base de dados definitiva da nova versão, devido aos requisitos de corredores, polígonos, áreas de influência, proximidade, intersecções, inteligência territorial e relações geoespaciais. O MySQL permanecerá temporariamente como fonte legada durante a migração e não receberá novos domínios funcionais. A transição deverá ser incremental, reconciliável e reversível, com ensaios, critérios de corte, rollback, validação de integridade e desactivação formal das dependências antigas."",""fontes"":[""portal do investidor\\Portal V4\\upgrade do portal de investimentos v5 programacao.docx; SHA edece80c0519537244f8a8b86456af0aa92de1c526f791bb0ee9b85af7a7e8b2; w:p 522""],""aceitacao"":""Decisão tecnológica: a arquitectura alvo manterá React no frontend e Laravel no backend, após actualização das versões, dependências, segurança, modularidade, desempenho e cobertura de testes. O PostgreSQL/PostGIS será a base de dados definitiva da nova versão, devido aos requisitos de corredores, polígonos, áreas de influência, proximidade, intersecções, inteligência territorial e relações geoespaciais. O MySQL permanecerá temporariamente como fonte legada durante a migração e não receberá novos domínios funcionais. A transição deverá ser incremental, reconciliável e reversível, com ensaios, critérios de corte, rollback, validação de integridade e desactivação formal das dependências antigas."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""cartografia/relações""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.geo_locations: 1990 registos; public.geo_geometries: 0 registos; public.project_locations: 28 registos; public.cluster_projects: 13 registos; public.opportunity_projects: 0 registos; public.opportunity_clusters: 0 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.","Demonstrar consumidor: pesquisar→selecionar→gravar→nova sessão→renderizar limite correto; conservar pai, código e fonte. Critério individual original preservado; cobertura atual ainda não individualizada.","InvestmentGeography, campos TerritoryFields/ProvinceSelect, geo_locations/geo_geometries e importador autenticado","QA408/581INE; ativo0geometrias;173correspondências por nome/edição/pai, Mandie ambíguo. Publicação é ação separada.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: território. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,território,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",resources/js/components/investment-territory.tsx; app/Http/Controllers/InvestmentTerritoryController.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"InvestmentTerritoryTest, TerritorialRegistryTest, InvestmentTerritorialTraceabilityTest, InvestmentZoneTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, @@ -2924,7 +2924,7 @@ MASTER-fd787802-0151,Responsável Gestor de Recursos Humanos do projecto. Associ MASTER-fd787802-0152,Nível de confiança Médio — dependente da validação do cronograma de instalação. Justificar o nível e registar a próxima revisão.,..\..\..\..\..\..\Users\macbook\.codex\attachments\bf1d310a-d3a8-48fc-953f-0648622a6c85\Pasted text.txt; SHA fd7878021ae5d18c9d4a9a79073552c36876d59726b8fb2612752f2594080ca0; linha 582,governação/outros,/api/v1/investment/admin/interests/{interest}/status; /management/history; /management/interests; /management/interests/{interest}; /management/interests/{interest}/consent/contact; /management/interests/{interest}/consent/proponent; /management/opportunities; /management/opportunities/create; /management/opportunities/drafts; /management/opportunities/{id}/draft; /management/opportunities/{id}/edit; /management/opportunities/{id}/lifecycle,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Localizar obrigação verificável e consumidores/contrato atuais antes de estimar implementação ou declarar conclusão. Critério individual original preservado; cobertura atual ainda não individualizada.,"Ler secção/versão correspondente; distinguir requisito funcional, decisão e exemplo. Fontes oficiais já aceites. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.",MASTER-fd787802-0152: Nível de confiança Médio — dependente da validação do cronograma de instalação. Justificar o nível e registar a próxima revisão.,P2,MASTER-fd787802-0152: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-fd787802-0152,1,"[{""id"":""MASTER-fd787802-0152"",""pedido"":""Nível de confiança Médio — dependente da validação do cronograma de instalação. Justificar o nível e registar a próxima revisão."",""fontes"":[""..\\..\\..\\..\\..\\..\\Users\\macbook\\.codex\\attachments\\bf1d310a-d3a8-48fc-953f-0648622a6c85\\Pasted text.txt; SHA fd7878021ae5d18c9d4a9a79073552c36876d59726b8fb2612752f2594080ca0; linha 582""],""aceitacao"":""Nível de confiança Médio — dependente da validação do cronograma de instalação. Justificar o nível e registar a próxima revisão."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,Requisito transversal; consultar estado-ativo-after.json,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Localizar obrigação verificável e consumidores/contrato atuais antes de estimar implementação ou declarar conclusão. Critério individual original preservado; cobertura atual ainda não individualizada.,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer","Ler secção/versão correspondente; distinguir requisito funcional, decisão e exemplo. Fontes oficiais já aceites.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: governação e demais cláusulas. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,governação e demais cláusulas,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",AGENTS.md — componentes do domínio encontrados; correspondência integral deste requisito não presumida,; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, MASTER-fd787802-0153,Estado do registo Rascunho em validação interna. Não publicar nem usar no matching até aprovação.,..\..\..\..\..\..\Users\macbook\.codex\attachments\bf1d310a-d3a8-48fc-953f-0648622a6c85\Pasted text.txt; SHA fd7878021ae5d18c9d4a9a79073552c36876d59726b8fb2612752f2594080ca0; linha 584,governação/outros,/api/v1/investment/admin/interests/{interest}/status; /management/history; /management/interests; /management/interests/{interest}; /management/interests/{interest}/consent/contact; /management/interests/{interest}/consent/proponent; /management/opportunities; /management/opportunities/create; /management/opportunities/drafts; /management/opportunities/{id}/draft; /management/opportunities/{id}/edit; /management/opportunities/{id}/lifecycle,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Localizar obrigação verificável e consumidores/contrato atuais antes de estimar implementação ou declarar conclusão. Critério individual original preservado; cobertura atual ainda não individualizada.,"Ler secção/versão correspondente; distinguir requisito funcional, decisão e exemplo. Fontes oficiais já aceites. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.",MASTER-fd787802-0153: Estado do registo Rascunho em validação interna. Não publicar nem usar no matching até aprovação.,P1,MASTER-fd787802-0153: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-fd787802-0153,1,"[{""id"":""MASTER-fd787802-0153"",""pedido"":""Estado do registo Rascunho em validação interna. Não publicar nem usar no matching até aprovação."",""fontes"":[""..\\..\\..\\..\\..\\..\\Users\\macbook\\.codex\\attachments\\bf1d310a-d3a8-48fc-953f-0648622a6c85\\Pasted text.txt; SHA fd7878021ae5d18c9d4a9a79073552c36876d59726b8fb2612752f2594080ca0; linha 584""],""aceitacao"":""Estado do registo Rascunho em validação interna. Não publicar nem usar no matching até aprovação."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,Requisito transversal; consultar estado-ativo-after.json,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Localizar obrigação verificável e consumidores/contrato atuais antes de estimar implementação ou declarar conclusão. Critério individual original preservado; cobertura atual ainda não individualizada.,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer","Ler secção/versão correspondente; distinguir requisito funcional, decisão e exemplo. Fontes oficiais já aceites.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: governação e demais cláusulas. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,governação e demais cláusulas,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",AGENTS.md — componentes do domínio encontrados; correspondência integral deste requisito não presumida,; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, MASTER-bd55cac9-0001,"As extensões PostGIS e pgcrypto não são removidas, porque podem ser utilizadas por outros módulos. Em produção, a reversão deve preferir migrations inversas por incremento, em vez da eliminação integral do esquema.",..\..\..\..\..\..\Users\macbook\.codex\attachments\c1ac842e-1b98-4f18-82bf-5155dbddf288\Pasted text.txt; SHA bd55cac92926fd804e358921924740eb9c7e649af7a845fe85d2c3686ae2ef09; linha 80,governação/outros,/api/v1/investment/admin/interests/{interest}/status; /management/history; /management/interests; /management/interests/{interest}; /management/interests/{interest}/consent/contact; /management/interests/{interest}/consent/proponent; /management/opportunities; /management/opportunities/create; /management/opportunities/drafts; /management/opportunities/{id}/draft; /management/opportunities/{id}/edit; /management/opportunities/{id}/lifecycle,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Localizar obrigação verificável e consumidores/contrato atuais antes de estimar implementação ou declarar conclusão. Critério individual original preservado; cobertura atual ainda não individualizada.,"Ler secção/versão correspondente; distinguir requisito funcional, decisão e exemplo. Fontes oficiais já aceites. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","MASTER-bd55cac9-0001: As extensões PostGIS e pgcrypto não são removidas, porque podem ser utilizadas por outros módulos. Em produção, a reversão deve preferir migrations inversas por incremento, em vez da eliminação integral do esquema.",P2,MASTER-bd55cac9-0001: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-bd55cac9-0001,1,"[{""id"":""MASTER-bd55cac9-0001"",""pedido"":""As extensões PostGIS e pgcrypto não são removidas, porque podem ser utilizadas por outros módulos. Em produção, a reversão deve preferir migrations inversas por incremento, em vez da eliminação integral do esquema."",""fontes"":[""..\\..\\..\\..\\..\\..\\Users\\macbook\\.codex\\attachments\\c1ac842e-1b98-4f18-82bf-5155dbddf288\\Pasted text.txt; SHA bd55cac92926fd804e358921924740eb9c7e649af7a845fe85d2c3686ae2ef09; linha 80""],""aceitacao"":""As extensões PostGIS e pgcrypto não são removidas, porque podem ser utilizadas por outros módulos. Em produção, a reversão deve preferir migrations inversas por incremento, em vez da eliminação integral do esquema."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,Requisito transversal; consultar estado-ativo-after.json,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Localizar obrigação verificável e consumidores/contrato atuais antes de estimar implementação ou declarar conclusão. Critério individual original preservado; cobertura atual ainda não individualizada.,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer","Ler secção/versão correspondente; distinguir requisito funcional, decisão e exemplo. Fontes oficiais já aceites.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: governação e demais cláusulas. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,governação e demais cláusulas,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",AGENTS.md — componentes do domínio encontrados; correspondência integral deste requisito não presumida,; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, -MASTER-600240dd-0001,"Propomos desenvolver o InvesteMoz como uma plataforma contínua de apoio ao investimento e ao empreendedorismo. O utilizador começa com uma ideia ou um negócio existente, constrói o seu projecto e acompanha a execução num dossier único. O plano de negócio, as estatísticas, as competências, o financiamento e os procedimentos devem partilhar informação e indicar sempre a próxima acção útil.",..\..\..\..\..\..\Users\macbook\.codex\attachments\c6245408-7052-4478-8804-377b282e8203\Pasted text.txt; SHA 600240dd64b59b82bdb92e471b475f9efc96eab67f9cd532a432e1e7a324f0c9; linha 4,Balcão/orientação,/balcao-virtual/contextos; /balcao-virtual/dossiers; /balcao-virtual/dossiers/{id}; /balcao-virtual/dossiers/{id}/documentos; /balcao-virtual/dossiers/{id}/documentos/{document}; /balcao-virtual/dossiers/{id}/documentos/{document}/conferencia; /balcao-virtual/dossiers/{id}/etapas; /balcao-virtual/dossiers/{id}/fontes; /balcao-virtual/dossiers/{id}/orientacao; /balcao-virtual/dossiers/{id}/pedidos; /balcao-virtual/dossiers/{id}/pressupostos; /balcao-virtual/dossiers/{id}/recomendacoes,"VirtualDesk, pedidos/casos, anexos, contexto dossier e acompanhamento. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,"Pedido contextual→gravar→submeter→nova sessão→gestor→mensagem/documentos/resultado, reaproveitando A/B. Critério individual original preservado; cobertura atual ainda não individualizada.","Perfis próprios do Balcão; serviços/campos e decisões externas aplicáveis, sem inventar destinatário/prazo. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","MASTER-600240dd-0001: Propomos desenvolver o InvesteMoz como uma plataforma contínua de apoio ao investimento e ao empreendedorismo. O utilizador começa com uma ideia ou um negócio existente, constrói o seu projecto e acompanha a execução num dossier único. O plano de negócio, as estatísticas, as competências, o financiamento e os procedimentos devem partilhar informação e indicar sempre a próxima acção útil.",P1,MASTER-600240dd-0001: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-600240dd-0001,1,"[{""id"":""MASTER-600240dd-0001"",""pedido"":""Propomos desenvolver o InvesteMoz como uma plataforma contínua de apoio ao investimento e ao empreendedorismo. O utilizador começa com uma ideia ou um negócio existente, constrói o seu projecto e acompanha a execução num dossier único. O plano de negócio, as estatísticas, as competências, o financiamento e os procedimentos devem partilhar informação e indicar sempre a próxima acção útil."",""fontes"":[""..\\..\\..\\..\\..\\..\\Users\\macbook\\.codex\\attachments\\c6245408-7052-4478-8804-377b282e8203\\Pasted text.txt; SHA 600240dd64b59b82bdb92e471b475f9efc96eab67f9cd532a432e1e7a324f0c9; linha 4""],""aceitacao"":""Propomos desenvolver o InvesteMoz como uma plataforma contínua de apoio ao investimento e ao empreendedorismo. O utilizador começa com uma ideia ou um negócio existente, constrói o seu projecto e acompanha a execução num dossier único. O plano de negócio, as estatísticas, as competências, o financiamento e os procedimentos devem partilhar informação e indicar sempre a próxima acção útil."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""Balcão/orientação""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.desk_cases: 1 registos; public.desk_requests: 0 registos; public.desk_institutional_links: 0 registos; public.desk_messages: 0 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.","Pedido contextual→gravar→submeter→nova sessão→gestor→mensagem/documentos/resultado, reaproveitando A/B. Critério individual original preservado; cobertura atual ainda não individualizada.","VirtualDesk, pedidos/casos, anexos, contexto dossier e acompanhamento","Perfis próprios do Balcão; serviços/campos e decisões externas aplicáveis, sem inventar destinatário/prazo.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: balcão. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,balcão,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Services/VirtualDesk.php; app/Services/Ai/InvestorGuidance.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,InvestorGuidanceTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, +MASTER-600240dd-0001,"Propomos desenvolver o InvesteMoz como uma plataforma contínua de apoio ao investimento e ao empreendedorismo. O utilizador começa com uma ideia ou um negócio existente, constrói o seu projecto e acompanha a execução num dossier único. O plano de negócio, as estatísticas, as competências, o financiamento e os procedimentos devem partilhar informação e indicar sempre a próxima acção útil.",..\..\..\..\..\..\Users\macbook\.codex\attachments\c6245408-7052-4478-8804-377b282e8203\Pasted text.txt; SHA 600240dd64b59b82bdb92e471b475f9efc96eab67f9cd532a432e1e7a324f0c9; linha 4,Balcão/orientação,/balcao-virtual/contextos; /balcao-virtual/dossiers; /balcao-virtual/dossiers/{id}; /balcao-virtual/dossiers/{id}/documentos; /balcao-virtual/dossiers/{id}/documentos/{document}; /balcao-virtual/dossiers/{id}/documentos/{document}/conferencia; /balcao-virtual/dossiers/{id}/etapas; /balcao-virtual/dossiers/{id}/fontes; /balcao-virtual/dossiers/{id}/orientacao; /balcao-virtual/dossiers/{id}/pedidos; /balcao-virtual/dossiers/{id}/pressupostos; /balcao-virtual/dossiers/{id}/recomendacoes,"VirtualDesk, pedidos/casos, anexos, contexto dossier e acompanhamento. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,"Pedido contextual→gravar→submeter→nova sessão→gestor→mensagem/documentos/resultado, reaproveitando A/B. Critério individual original preservado; cobertura atual ainda não individualizada.","Perfis próprios do Balcão; serviços/campos e decisões externas aplicáveis, sem inventar destinatário/prazo. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","MASTER-600240dd-0001: Propomos desenvolver o InvesteMoz como uma plataforma contínua de apoio ao investimento e ao empreendedorismo. O utilizador começa com uma ideia ou um negócio existente, constrói o seu projecto e acompanha a execução num dossier único. O plano de negócio, as estatísticas, as competências, o financiamento e os procedimentos devem partilhar informação e indicar sempre a próxima acção útil.",P1,MASTER-600240dd-0001: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-600240dd-0001,1,"[{""id"":""MASTER-600240dd-0001"",""pedido"":""Propomos desenvolver o InvesteMoz como uma plataforma contínua de apoio ao investimento e ao empreendedorismo. O utilizador começa com uma ideia ou um negócio existente, constrói o seu projecto e acompanha a execução num dossier único. O plano de negócio, as estatísticas, as competências, o financiamento e os procedimentos devem partilhar informação e indicar sempre a próxima acção útil."",""fontes"":[""..\\..\\..\\..\\..\\..\\Users\\macbook\\.codex\\attachments\\c6245408-7052-4478-8804-377b282e8203\\Pasted text.txt; SHA 600240dd64b59b82bdb92e471b475f9efc96eab67f9cd532a432e1e7a324f0c9; linha 4""],""aceitacao"":""Propomos desenvolver o InvesteMoz como uma plataforma contínua de apoio ao investimento e ao empreendedorismo. O utilizador começa com uma ideia ou um negócio existente, constrói o seu projecto e acompanha a execução num dossier único. O plano de negócio, as estatísticas, as competências, o financiamento e os procedimentos devem partilhar informação e indicar sempre a próxima acção útil."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""Balcão/orientação""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.desk_cases: 1 registos; public.desk_requests: 0 registos; public.desk_institutional_links: 0 registos; public.desk_messages: 0 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.","Pedido contextual→gravar→submeter→nova sessão→gestor→mensagem/documentos/resultado, reaproveitando A/B. Critério individual original preservado; cobertura atual ainda não individualizada. | 15/11/2026 - conferencia dirigida dos quatro percursos: ver apresentacao-contexto-qa-20261115.md, tabela por ecra/percurso. Hotel/Agronegocio: API de contexto, entidade, cenario e retorno ao mesmo dossier verificados; preparacao financeira assistida DIVERGENTE. Fundos: filtros e retorno corrigidos/testados. Demografia: sintese e ambito territorial testados. Computador/telemovel autenticados e retoma ponta a ponta NAO VERIFICADOS. QA apenas; entrega transversal nao aceite nem instalada. | 15/11/2026 — incremento assistido do anexo Texto colado(7): oito ecrãs no percurso simples; orçamento inicial, financiamento, receitas/custos e tesouraria separados; ajuda com pressupostos explícitos; operações fiscais por selecção pesquisável; etapa e pressupostos recuperáveis; relatório privado preserva o recorte. Implementação QA com provas dirigidas, sem aceitação funcional/visual integral. Aguardar conferência autenticada em computador/telemóvel e retoma; homologação não autorizada. | Retoma visual após Esc — 15/11/2026: janela controlada em /login; dossier Hotel redirige para autenticação. Sessão do painel indicado pelo responsável não identificada; solicitado apenas o URL. Conferência autenticada/telemóvel NÃO VERIFICADA, sem repetir testes aceites, reiniciar navegadores ou instalar. Evidência no registo de apresentação/contexto existente. 15/11: acesso QA recuperado; Hotel demonstrado na interface com empresa existente, orçamento 2M, mobilizado 1M, receita 7,5M, custo 2M, retoma e relatório descarregado. Emulação 390x844: edição e continuação. Restantes percursos/retoma autenticada integral NÃO VERIFICADOS; sem instalação. Continuação QA: Agronegócio demonstrou entidade por constituir, modelo próprio/retoma/retorno sem converter intervalo em total; Banca/Banco comercial excluiu corretora/microsseguradora sintéticas e guardou referência/produto/versão no dossier; demografia apresentou Boane como contexto distrital. Emulação móvel: síntese legível e província limpa desactiva distritos, sem resultados antigos confundidos. Cobertura integral ainda aberta. [SALDO VISUAL QA 15/11 — PASSOS PENDENTES] Execução actual substitui o saldo anterior: V06: Hotel por constituir guardou entidade, pressupostos, recuperação e relatório no mesmo dossier. 1440 px: APROVADO, 2026-11-15T16:03:54.766Z, evidência V06-1440-1794758634766 | V08: Comparação opcional e entidade utilizáveis em móvel; forma/nome recuperados; cadastro da empresa existente não substituído. 390 px: APROVADO, 2026-11-15T16:00:27.433Z, evidência V08-390-1794758427433 | V10: Aviso histórico apresentado sem referência aos sete exemplares; nome e sede anteriores preservados. 1440 px: APROVADO, 2026-11-15T16:05:10.181Z, evidência V10-1440-1794758710181; 390 px: APROVADO, 2026-11-15T16:06:43.704Z, evidência V10-390-1794758803704 | V14: Origem Boane transportada até ao simulador; país por MZ, moeda por prefixo e nível distrital guardados e recuperados. 1440 px: APROVADO, 2026-11-15T16:19:56.796Z, evidência V14-1440-1794759596823; 390 px: APROVADO, 2026-11-15T16:22:14.914Z, evidência V14-390-1794759734939 | V15: Entrada Criar investimento abriu preparação própria sem anúncio ou zona, preservando localização e intervalo orçamental. 1440 px: APROVADO, 2026-11-15T15:49:14.009Z, evidência V15-1440-1794757754009; 390 px: APROVADO, 2026-11-15T15:55:37.546Z, evidência V15-390-1794758137546","VirtualDesk, pedidos/casos, anexos, contexto dossier e acompanhamento","Perfis próprios do Balcão; serviços/campos e decisões externas aplicáveis, sem inventar destinatário/prazo.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: balcão. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual. | docs/investmoz/v2/auditoria-portal/apresentacao-contexto-qa-20261115.md (conferencia dirigida dos quatro percursos); outputs/investor-intent-20261115/backend.log (12 testes/412 assercoes); frontend.log (137 testes); phpstan.log (zero erros) | Conferência autenticada e recibos adicionais: apresentacao-contexto-qa-20261115.md; outputs/investor-intent-20261115/hotel-browser-report.html | Saldo actual V01–V15: apresentacao-contexto-qa-20261115.md#verificações-restantes--saldo-actual-para-execução-na-mesma-candidata,balcão,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Services/VirtualDesk.php; app/Services/Ai/InvestorGuidance.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,InvestorGuidanceTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,"Conferencia individual por ecra: intencao, reutilizacao, filtros, valores, gravacao/retoma, isolamento, computador e telemovel; sem inferir cobertura dos consumidores pelo componente. ","APROVADO no saldo QA deste requisito [EXECUÇÃO PLAYWRIGHT QA 15/11] Ver estados V executados na coluna de evidência e no mesmo relatório; sem instalação ou aceitação global do portal. [HISTÓRICO ANTERIOR] NÃO VERIFICADO integralmente — incremento assistido em QA; conferência autenticada e consumidores afectados pendentes. | Hotel: recorte demonstrado; aceitação transversal integral permanece não verificada. | Instalação suspensa; encerrar apenas os passos V associados, com executante/data/candidata/largura/evidência. Provas aceites preservadas; bloqueio do controlo de URL não demonstra falha do portal." MASTER-600240dd-0002,Mantemos os doze critérios e os pesos do draft para permitir continuidade da análise. As competências passam a ser avaliadas na cobertura do percurso e na correspondência entre necessidades e recursos; as estatísticas incluem tanto consulta de fontes como produção de indicadores do portal.,..\..\..\..\..\..\Users\macbook\.codex\attachments\c6245408-7052-4478-8804-377b282e8203\Pasted text.txt; SHA 600240dd64b59b82bdb92e471b475f9efc96eab67f9cd532a432e1e7a324f0c9; linha 18,educação,/management/education; /management/education/catalog/{kind}; /management/education/demands/{id}/analysis; /management/education/demands/{id}/investment; /management/education/{kind}; /management/education/{kind}/{id}/review,"Cursos, necessidades/capacidades, atores, catálogo e políticas existentes. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Separar catálogo existente de procura/capacidade e painel por ator; preparar execução futura sem cadastros paralelos. Critério individual original preservado; cobertura atual ainda não individualizada.,Novas jornadas não são iniciadas nesta auditoria. Dados reais/perfis/rascunho incompleto pendentes. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,MASTER-600240dd-0002: Mantemos os doze critérios e os pesos do draft para permitir continuidade da análise. As competências passam a ser avaliadas na cobertura do percurso e na correspondência entre necessidades e recursos; as estatísticas incluem tanto consulta de fontes como produção de indicadores do portal.,P1,MASTER-600240dd-0002: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-600240dd-0002,1,"[{""id"":""MASTER-600240dd-0002"",""pedido"":""Mantemos os doze critérios e os pesos do draft para permitir continuidade da análise. As competências passam a ser avaliadas na cobertura do percurso e na correspondência entre necessidades e recursos; as estatísticas incluem tanto consulta de fontes como produção de indicadores do portal."",""fontes"":[""..\\..\\..\\..\\..\\..\\Users\\macbook\\.codex\\attachments\\c6245408-7052-4478-8804-377b282e8203\\Pasted text.txt; SHA 600240dd64b59b82bdb92e471b475f9efc96eab67f9cd532a432e1e7a324f0c9; linha 18""],""aceitacao"":""Mantemos os doze critérios e os pesos do draft para permitir continuidade da análise. As competências passam a ser avaliadas na cobertura do percurso e na correspondência entre necessidades e recursos; as estatísticas incluem tanto consulta de fontes como produção de indicadores do portal."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""educação""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.labour_demands: 0 registos; public.training_capacities: 0 registos; public.education_opportunities: 0 registos; public.education_investment_proposals: 0 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Separar catálogo existente de procura/capacidade e painel por ator; preparar execução futura sem cadastros paralelos. Critério individual original preservado; cobertura atual ainda não individualizada.,"Cursos, necessidades/capacidades, atores, catálogo e políticas existentes",Novas jornadas não são iniciadas nesta auditoria. Dados reais/perfis/rascunho incompleto pendentes.,Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: educação. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,educação,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Http/Controllers/EducationController.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"EducationTest, SkillsEducationSchemaTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, MASTER-600240dd-0003,Use 0 para ausência confirmada de uma função aplicável; 1 para apoio inicial; 2 para básico; 3 para adequado; 4 para avançado; 5 para referência demonstrada. Uma pontuação não deve ser inferida apenas da publicidade de uma plataforma.,..\..\..\..\..\..\Users\macbook\.codex\attachments\c6245408-7052-4478-8804-377b282e8203\Pasted text.txt; SHA 600240dd64b59b82bdb92e471b475f9efc96eab67f9cd532a432e1e7a324f0c9; linha 34,governação/outros,/api/v1/investment/admin/interests/{interest}/status; /management/history; /management/interests; /management/interests/{interest}; /management/interests/{interest}/consent/contact; /management/interests/{interest}/consent/proponent; /management/opportunities; /management/opportunities/create; /management/opportunities/drafts; /management/opportunities/{id}/draft; /management/opportunities/{id}/edit; /management/opportunities/{id}/lifecycle,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Localizar obrigação verificável e consumidores/contrato atuais antes de estimar implementação ou declarar conclusão. Critério individual original preservado; cobertura atual ainda não individualizada.,"Ler secção/versão correspondente; distinguir requisito funcional, decisão e exemplo. Fontes oficiais já aceites. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.",MASTER-600240dd-0003: Use 0 para ausência confirmada de uma função aplicável; 1 para apoio inicial; 2 para básico; 3 para adequado; 4 para avançado; 5 para referência demonstrada. Uma pontuação não deve ser inferida apenas da publicidade de uma plataforma.,P2,MASTER-600240dd-0003: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-600240dd-0003,1,"[{""id"":""MASTER-600240dd-0003"",""pedido"":""Use 0 para ausência confirmada de uma função aplicável; 1 para apoio inicial; 2 para básico; 3 para adequado; 4 para avançado; 5 para referência demonstrada. Uma pontuação não deve ser inferida apenas da publicidade de uma plataforma."",""fontes"":[""..\\..\\..\\..\\..\\..\\Users\\macbook\\.codex\\attachments\\c6245408-7052-4478-8804-377b282e8203\\Pasted text.txt; SHA 600240dd64b59b82bdb92e471b475f9efc96eab67f9cd532a432e1e7a324f0c9; linha 34""],""aceitacao"":""Use 0 para ausência confirmada de uma função aplicável; 1 para apoio inicial; 2 para básico; 3 para adequado; 4 para avançado; 5 para referência demonstrada. Uma pontuação não deve ser inferida apenas da publicidade de uma plataforma."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,Requisito transversal; consultar estado-ativo-after.json,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Localizar obrigação verificável e consumidores/contrato atuais antes de estimar implementação ou declarar conclusão. Critério individual original preservado; cobertura atual ainda não individualizada.,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer","Ler secção/versão correspondente; distinguir requisito funcional, decisão e exemplo. Fontes oficiais já aceites.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: governação e demais cláusulas. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,governação e demais cláusulas,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",AGENTS.md — componentes do domínio encontrados; correspondência integral deste requisito não presumida,; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, MASTER-600240dd-0004,"N/A significa que o critério não se aplica. NV significa não verificado: não é zero e não deve ser apresentado como falha. Ambos ficam fora do cálculo; NV reduz a cobertura da evidência, que deve ser apresentada separadamente.",..\..\..\..\..\..\Users\macbook\.codex\attachments\c6245408-7052-4478-8804-377b282e8203\Pasted text.txt; SHA 600240dd64b59b82bdb92e471b475f9efc96eab67f9cd532a432e1e7a324f0c9; linha 35,simuladores,/api/v1/questionnaires/{code}; /api/v1/simulation-drafts; /api/v1/simulation-drafts/claim; /api/v1/simulation-drafts/claim-preview; /api/v1/simulation-drafts/current; /api/v1/simulation-drafts/linkable-businesses; /api/v1/simulation-drafts/{id}; /api/v1/simulation-drafts/{id}/business-link; /api/v1/simulation-drafts/{id}/conversions; /api/v1/simulation-drafts/{id}/touch; /api/v1/simulations; /api/v1/simulations/history,"SimulationExecution, resultados/cenários/fontes, rascunhos e dossier existentes. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Cenário→cálculo→gravação→resultado/dossier correto→nova sessão→PDF/derivadas autorizadas. Sem aprovação/score inventado. Critério individual original preservado; cobertura atual ainda não individualizada.,"Regras financeiras/fiscais separadas; fonte oficial aceite, parâmetros/âmbito/período podem faltar; não substituir por0/taxa atual. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","MASTER-600240dd-0004: N/A significa que o critério não se aplica. NV significa não verificado: não é zero e não deve ser apresentado como falha. Ambos ficam fora do cálculo; NV reduz a cobertura da evidência, que deve ser apresentada separadamente.",P2,MASTER-600240dd-0004: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-600240dd-0004,1,"[{""id"":""MASTER-600240dd-0004"",""pedido"":""N/A significa que o critério não se aplica. NV significa não verificado: não é zero e não deve ser apresentado como falha. Ambos ficam fora do cálculo; NV reduz a cobertura da evidência, que deve ser apresentada separadamente."",""fontes"":[""..\\..\\..\\..\\..\\..\\Users\\macbook\\.codex\\attachments\\c6245408-7052-4478-8804-377b282e8203\\Pasted text.txt; SHA 600240dd64b59b82bdb92e471b475f9efc96eab67f9cd532a432e1e7a324f0c9; linha 35""],""aceitacao"":""N/A significa que o critério não se aplica. NV significa não verificado: não é zero e não deve ser apresentado como falha. Ambos ficam fora do cálculo; NV reduz a cobertura da evidência, que deve ser apresentada separadamente."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""simuladores""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.simulation_form_drafts: 22 registos; public.simulation_scenarios: 16 registos; public.simulations: 16 registos; public.simulation_tax_rules: tabela ausente,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Cenário→cálculo→gravação→resultado/dossier correto→nova sessão→PDF/derivadas autorizadas. Sem aprovação/score inventado. Critério individual original preservado; cobertura atual ainda não individualizada.,"SimulationExecution, resultados/cenários/fontes, rascunhos e dossier existentes","Regras financeiras/fiscais separadas; fonte oficial aceite, parâmetros/âmbito/período podem faltar; não substituir por0/taxa atual.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: simuladores. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,simuladores,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Services/SimulationTaxParameterResolver.php; resources/js/components/simulation-form.tsx — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"SimulationExecutionTest, SimulationFormDraftTest, SimulationDraftContinuityTest, SimulationTaxRuleGovernanceTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, @@ -2945,13 +2945,13 @@ MASTER-600240dd-0018,"O painel Meu projecto apresenta etapa actual, próxima ac [RECONCILIACAO-43-20261019] 3: Fluxos instalados; fechar observação com dossier legítimo quando disponível. Não reconstruir nem repetir percurso aceite.","Pedido contextual→gravar→submeter→nova sessão→gestor→mensagem/documentos/resultado, reaproveitando A/B. Critério individual original preservado; cobertura atual ainda não individualizada. | NAVEGACAO-QA-20261016: avaliação visual do protótipo pendente. Sem encerramento funcional global: vínculo genérico oportunidade/território, troca persistente e invalidação transversal, resumo integral de oportunidade/etapa e página Porquê investir por consolidar. Prévia não grava alterações de negócio. Manual aguarda avaliação e consolidação. | NAVEGACAO-CONSOLIDACAO-QA-20261016: os limites de persistência/entre dispositivos/Porquê investir do protótipo ficam superados neste recorte QA. A organização foi avaliada e ajustada tecnicamente; decisão visual e disponibilização pela Tempo continuam separadas. Não é prova volumétrica nem homologação fiscal/regulatória. Não encerra outros critérios deste requisito. Não repete os testes de navegação já aceites. | Cinco pontos do pedido consolidados neste recorte QA; confirmar da candidata funcional persiste, protótipo18534 fica histórico. Avaliação técnica visual executada, aceitação pela Tempo não presumida. Sem ativação. Não encerra outros critérios dos requisitos. Dois clientes simulados por sessões independentes, não dois equipamentos físicos. | RECTIFICAÇÃO: a revisão dos quatro formulários é parcial3/4. Preparar manifestação de interesse não mostra pré-preenchimento no percurso actual: manifestação não vinculada ao dossier. Presença de chaves na API/resumo global não encerra este critério. Resolver vínculo explícito/recuperável ao mesmo dossier e demonstrar o quarto formulário antes da decisão. Utilizador não abriu candidata nem conferiu novos anexos. | Actualização do critério anteriormente aberto da manifestação: concluído neste recorte QA; três formulários aceites conservam provas anteriores, sem repetição. Acesso directo sem dossier mantido; nenhum dossier/processo duplicado criado. Não encerra critérios globais nem presume conferência dos anexos pelo utilizador. Disponibilização separada. -[UTILIZACAO-HOMOLOGACAO-20261019] 3: Disponibilidade condicionada conforme limite registado — Início, contexto e navegação abrem; gravação/recuperação aceites em QA reutilizadas. Sem dossier real no destino.","VirtualDesk, pedidos/casos, anexos, contexto dossier e acompanhamento","Perfis próprios do Balcão; serviços/campos e decisões externas aplicáveis, sem inventar destinatário/prazo. | NAVEGACAO-QA-20261016: reutiliza cinco fases/19 etapas, permissões e dossiers existentes; base anterior dos parques130000, sem incorporar L1 pendente. Confirmação futura do escopo funcional e autorização ativa separadas; zero migrations/grants/publicação/alterações no ativo. L1, duplicados e Fintech mantêm estados. | NAVEGACAO-CONSOLIDACAO-QA-20261016: ação autenticada nominal 150000 preparada e demonstrada somente no clone55441 *_test; uma tabela de preferência por conta, associações no dossier existente. Manifesto/compilação e reversão parcial compatível preservam dados após utilização. Backup/restauro fresco do ativo e autorização de ativação continuam futuros. B, COUNTRY02, L1 dos parques, duplicados, regulação Fintech e demais estados preservados; origem das restrições: instrução expressa da Tempo e controlos de acesso aprovados, sem novos grants. | Candidata reconciliada com fonte L1 instalada, sem repetir140000; nenhuma alteração ativa.150000 permanece somenteQA. Pacotes/reversão anteriores não usar directamente no ativo actualizado: futura disponibilização requer decisão própria, hashes/preflight/backup-restauro fresco e reversão reconciliada. Sem nova regra organizacional; B/COUNTRY02/ficha integral e demais estados preservados. | Disponibilização parcial: apenas150000 pendente. Prévia confirma investemoz:5432/revisão correta; aplicação exige MFA nesta sessão e botão desativado. Sem POST/DDL150000; utilizador deve concluir autenticação habitual, sem nova autorização.140000/L1 preservada e sem reensaios. Reversão reconciliada comL1,20fontes/buildcompatível, dados/schema/histórico retidos. | Pendência MFA/instalação anterior resolvida; nenhuma ação restante para disponibilizar este recorte.140000 preservada uma vez; sem repetir L1 ou três formulários aceites. Reversão parcial compatível20fontes/build, schema/vínculos/histórico conservados. Critérios globais e ficha integral dos parques mantêm estado próprio.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: balcão. Esforço de código adicional só após lacuna reproduzida.,"outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual. | NAVEGACAO-QA-20261016: protótipo de organização em clone isolado, mapa52 ligações condicionais e vistas do catálogo; Descoberta/Realização/Suporte; área de trabalho separada; quatro entradas no mesmo UUID/v3, preenchimento autorizado preservando edição, cancelamento/confirmação apenas da prévia, novo login, teclado e móvel390. Evidência em outputs/investmoz-navegacao-QA-20261016/RELATORIO-QA.md. Origem: instrução expressa da Tempo nesta conversa; não é nova regra organizacional. | NAVEGACAO-CONSOLIDACAO-QA-20261016: substitui o saldo funcional da prévia histórica. Associações versionadas de oportunidade/sector/território no mesmo dossier encriptado; confirmação transacional com prévia e idempotência; foco/etapa recuperados entre sessões independentes; preservação de edições e preenchimento de vazios em formulários existentes; página Porquê investir dedicada. Prova positiva com cálculos locais reais (40 unidades; lacuna de financiamento 13000 MZN), duas submissões sintéticas reais pelo Balcão e recibo inalterado após troca. Resultados afetados conservados como históricos; rascunho anterior exige revisão explícita. Relatório: outputs/investmoz-navegacao-consolidacao-QA-20261016/RELATORIO-QA.md. | 18/10/2026: consolidação QA posterior ao protótipo revista; três menus com explicação/destinos, página Porquê investir dedicada melhorada, captura desktop/móvel390px e Escape/foco. Associações e contexto recuperados em duas sessões independentes autenticadas/MFA; quatro consumidores,19etapas, resultados para revisão e pedidos históricos recuperados. Provas transacionais40condições de16/10 reutilizadas. Relatório/pacote: outputs/investmoz-navegacao-consolidacao-20261018/para-revisao/. | Revisão visível18/10: candidata b1c98ec7140c, quatro entradas no mesmoUUID/próxima acção; prévia mantém/actualiza/revisão3resultados e9etapas, confirmação contexto3→4 e recuperação após logout/login/MFA observadas. Simulador, Terra/DUAT e Balcão mostram pré-preenchimento/comparação preservando edições. Relatório REVISAO-VISIVEL-DOC01.md e recibo em outputs/investmoz-navegacao-consolidacao-20261018/para-revisao/. | 18/10: integração da manifestação QA 73f8bd1347ca observada: vínculo opcional explícito no dossier existente, objectivo/localização preenchidos e sector editado preservado, recuperação em nova sessão/MFA, uma submissão e recibo IR-2026-01M576QMSKV91Q53GZCHKM61P0; dois reenvios com o mesmo protocolo.18 checksHTTP e15 de leitura;28 outros dossiers iguais. RELATORIO-MANIFESTACAO-QA.md na mesma entrega. | 18/10: Tempo autorizou disponibilização da candidata73f8bd1347ca. Código40fontes/build167 trocados por hash, manutenção terminada, cache de dados preservada. Backup fresco/restauro QA:295tabelas,31sequências,1320ficheiros, arranque/decifragem conferidos. Relatório operacional em outputs/investmoz-navegacao-ativacao-20261018/para-revisao/. | 18/10: disponibilização concluída73f8bd1347ca. MFA regularizado e150000 instalada pela conta2, reciboda1cae7b-a403-4256-9fd8-98ff2a69918d. Ledger/tabela=1, zero preferências importadas. Prévia e sucesso observados; Codex não repetiuPOST.290tabelas iguais ao backup e zero diferenças inesperadas. Relatório/recibo finais na mesma entrega. | Homologação teste-investidor 19/10/2026: Navegação contextual e manifestação de interesse=Ausente. Saldo derivado e limites em outputs/investmoz-disponibilizacao-integral-20261019/SALDO-E-ACTUALIZACAO-CONSOLIDADA.md. Não substitui estado/provas do activo; trecho documental encerrado, vínculo dossier aberto. | Proposta integral fdcb31f1b5b9: aplicação activa local completa + R2/DOC01/destino reconciliados; schema/build/recuperação de contexto e reversão de apresentação ensaiados no clone isolado. Não instalado remotamente. Inc. QA territoriais/Inhambane/programas separados. Limites e decisões em outputs/investmoz-disponibilizacao-integral-20261019/PROPOSTA-INTEGRAL-PARA-DECISAO.md. | Execução autorizada fdcb31f1b5b9 concluída em teste-investidor: Navegação contextual e manifestação de interesse=Disponível. 1080 hashes iguais, schema171/88, custódia/scan/recuperação reais. Sem publicação ou papéis novos. Vínculo dossier legítimo pendente; incrementos QA separados. Limites em outputs/investmoz-disponibilizacao-integral-20261019/RESULTADO-DISPONIBILIZACAO-INTEGRAL.md; não encerra critérios globais não demonstrados. +[UTILIZACAO-HOMOLOGACAO-20261019] 3: Disponibilidade condicionada conforme limite registado — Início, contexto e navegação abrem; gravação/recuperação aceites em QA reutilizadas. Sem dossier real no destino. | 15/11/2026 - conferencia dirigida dos quatro percursos: ver apresentacao-contexto-qa-20261115.md, tabela por ecra/percurso. Hotel/Agronegocio: API de contexto, entidade, cenario e retorno ao mesmo dossier verificados; preparacao financeira assistida DIVERGENTE. Fundos: filtros e retorno corrigidos/testados. Demografia: sintese e ambito territorial testados. Computador/telemovel autenticados e retoma ponta a ponta NAO VERIFICADOS. QA apenas; entrega transversal nao aceite nem instalada. | 15/11/2026 — incremento assistido do anexo Texto colado(7): oito ecrãs no percurso simples; orçamento inicial, financiamento, receitas/custos e tesouraria separados; ajuda com pressupostos explícitos; operações fiscais por selecção pesquisável; etapa e pressupostos recuperáveis; relatório privado preserva o recorte. Implementação QA com provas dirigidas, sem aceitação funcional/visual integral. Aguardar conferência autenticada em computador/telemóvel e retoma; homologação não autorizada. | Retoma visual após Esc — 15/11/2026: janela controlada em /login; dossier Hotel redirige para autenticação. Sessão do painel indicado pelo responsável não identificada; solicitado apenas o URL. Conferência autenticada/telemóvel NÃO VERIFICADA, sem repetir testes aceites, reiniciar navegadores ou instalar. Evidência no registo de apresentação/contexto existente. 15/11: acesso QA recuperado; Hotel demonstrado na interface com empresa existente, orçamento 2M, mobilizado 1M, receita 7,5M, custo 2M, retoma e relatório descarregado. Emulação 390x844: edição e continuação. Restantes percursos/retoma autenticada integral NÃO VERIFICADOS; sem instalação. Continuação QA: Agronegócio demonstrou entidade por constituir, modelo próprio/retoma/retorno sem converter intervalo em total; Banca/Banco comercial excluiu corretora/microsseguradora sintéticas e guardou referência/produto/versão no dossier; demografia apresentou Boane como contexto distrital. Emulação móvel: síntese legível e província limpa desactiva distritos, sem resultados antigos confundidos. Cobertura integral ainda aberta. [SALDO VISUAL QA 15/11 — PASSOS PENDENTES] Execução actual substitui o saldo anterior: V02: Pesquisas A/B conservaram critérios e contextos separados após retorno e recarga. 1440 px: APROVADO, 2026-11-15T16:28:25.029Z, evidência V02-1440-1794760105052; 390 px: APROVADO, 2026-11-15T16:29:13.443Z, evidência V02-390-1794760153468 | V04: Logout/login normal recuperou Hotel 7,5 milhões e Agronegócio 2 milhões, respectivos modelos e etapa. 1440 px: APROVADO, 2026-11-15T15:45:04.572Z, evidência V04-1440-1794757504572; 390 px: APROVADO, 2026-11-15T16:15:11.676Z, evidência V04-390-1794759311711 | V05: Edição concorrente recusada com 412 e entrada local conservada; dossiers separados; segunda conta sem acesso ao dossier ou rascunho privados. 1440 px: APROVADO, 2026-11-15T16:24:03.041Z, evidência V05-1440-1794759843064 | V06: Hotel por constituir guardou entidade, pressupostos, recuperação e relatório no mesmo dossier. 1440 px: APROVADO, 2026-11-15T16:03:54.766Z, evidência V06-1440-1794758634766 | V07: Relatório agrícola descarregado com receita 2 milhões, intervalo 1–5 milhões e custos desconhecidos preservados. 1440 px: APROVADO, 2026-11-15T15:45:15.049Z, evidência V07-1440-1794757515049; 390 px: APROVADO, 2026-11-15T15:45:59.234Z, evidência V07-390-1794757559234 | V09: Orientação abriu Financiamento; gravação e retorno concluídos sem inventar montantes desconhecidos. 1440 px: APROVADO, 2026-11-15T16:04:46.409Z, evidência V09-1440-1794758686409 | V11: Operação fiscal pesquisada, retirada e reposta sem perder entradas; 2027 recuperado; referência técnica fechada no detalhe da versão. 390 px: APROVADO, 2026-11-15T16:24:32.637Z, evidência V11-390-1794759872659 | V12: Análise agregada guardada e recuperada com cobertura desconhecida explícita, sem nomes/contactos internos. 1440 px: APROVADO, 2026-11-15T15:45:22.425Z, evidência V12-1440-1794757522425; 390 px: APROVADO, 2026-11-15T15:46:06.294Z, evidência V12-390-1794757566294 | V15: Entrada Criar investimento abriu preparação própria sem anúncio ou zona, preservando localização e intervalo orçamental. 1440 px: APROVADO, 2026-11-15T15:49:14.009Z, evidência V15-1440-1794757754009; 390 px: APROVADO, 2026-11-15T15:55:37.546Z, evidência V15-390-1794758137546","VirtualDesk, pedidos/casos, anexos, contexto dossier e acompanhamento","Perfis próprios do Balcão; serviços/campos e decisões externas aplicáveis, sem inventar destinatário/prazo. | NAVEGACAO-QA-20261016: reutiliza cinco fases/19 etapas, permissões e dossiers existentes; base anterior dos parques130000, sem incorporar L1 pendente. Confirmação futura do escopo funcional e autorização ativa separadas; zero migrations/grants/publicação/alterações no ativo. L1, duplicados e Fintech mantêm estados. | NAVEGACAO-CONSOLIDACAO-QA-20261016: ação autenticada nominal 150000 preparada e demonstrada somente no clone55441 *_test; uma tabela de preferência por conta, associações no dossier existente. Manifesto/compilação e reversão parcial compatível preservam dados após utilização. Backup/restauro fresco do ativo e autorização de ativação continuam futuros. B, COUNTRY02, L1 dos parques, duplicados, regulação Fintech e demais estados preservados; origem das restrições: instrução expressa da Tempo e controlos de acesso aprovados, sem novos grants. | Candidata reconciliada com fonte L1 instalada, sem repetir140000; nenhuma alteração ativa.150000 permanece somenteQA. Pacotes/reversão anteriores não usar directamente no ativo actualizado: futura disponibilização requer decisão própria, hashes/preflight/backup-restauro fresco e reversão reconciliada. Sem nova regra organizacional; B/COUNTRY02/ficha integral e demais estados preservados. | Disponibilização parcial: apenas150000 pendente. Prévia confirma investemoz:5432/revisão correta; aplicação exige MFA nesta sessão e botão desativado. Sem POST/DDL150000; utilizador deve concluir autenticação habitual, sem nova autorização.140000/L1 preservada e sem reensaios. Reversão reconciliada comL1,20fontes/buildcompatível, dados/schema/histórico retidos. | Pendência MFA/instalação anterior resolvida; nenhuma ação restante para disponibilizar este recorte.140000 preservada uma vez; sem repetir L1 ou três formulários aceites. Reversão parcial compatível20fontes/build, schema/vínculos/histórico conservados. Critérios globais e ficha integral dos parques mantêm estado próprio.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: balcão. Esforço de código adicional só após lacuna reproduzida.,"outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual. | NAVEGACAO-QA-20261016: protótipo de organização em clone isolado, mapa52 ligações condicionais e vistas do catálogo; Descoberta/Realização/Suporte; área de trabalho separada; quatro entradas no mesmo UUID/v3, preenchimento autorizado preservando edição, cancelamento/confirmação apenas da prévia, novo login, teclado e móvel390. Evidência em outputs/investmoz-navegacao-QA-20261016/RELATORIO-QA.md. Origem: instrução expressa da Tempo nesta conversa; não é nova regra organizacional. | NAVEGACAO-CONSOLIDACAO-QA-20261016: substitui o saldo funcional da prévia histórica. Associações versionadas de oportunidade/sector/território no mesmo dossier encriptado; confirmação transacional com prévia e idempotência; foco/etapa recuperados entre sessões independentes; preservação de edições e preenchimento de vazios em formulários existentes; página Porquê investir dedicada. Prova positiva com cálculos locais reais (40 unidades; lacuna de financiamento 13000 MZN), duas submissões sintéticas reais pelo Balcão e recibo inalterado após troca. Resultados afetados conservados como históricos; rascunho anterior exige revisão explícita. Relatório: outputs/investmoz-navegacao-consolidacao-QA-20261016/RELATORIO-QA.md. | 18/10/2026: consolidação QA posterior ao protótipo revista; três menus com explicação/destinos, página Porquê investir dedicada melhorada, captura desktop/móvel390px e Escape/foco. Associações e contexto recuperados em duas sessões independentes autenticadas/MFA; quatro consumidores,19etapas, resultados para revisão e pedidos históricos recuperados. Provas transacionais40condições de16/10 reutilizadas. Relatório/pacote: outputs/investmoz-navegacao-consolidacao-20261018/para-revisao/. | Revisão visível18/10: candidata b1c98ec7140c, quatro entradas no mesmoUUID/próxima acção; prévia mantém/actualiza/revisão3resultados e9etapas, confirmação contexto3→4 e recuperação após logout/login/MFA observadas. Simulador, Terra/DUAT e Balcão mostram pré-preenchimento/comparação preservando edições. Relatório REVISAO-VISIVEL-DOC01.md e recibo em outputs/investmoz-navegacao-consolidacao-20261018/para-revisao/. | 18/10: integração da manifestação QA 73f8bd1347ca observada: vínculo opcional explícito no dossier existente, objectivo/localização preenchidos e sector editado preservado, recuperação em nova sessão/MFA, uma submissão e recibo IR-2026-01M576QMSKV91Q53GZCHKM61P0; dois reenvios com o mesmo protocolo.18 checksHTTP e15 de leitura;28 outros dossiers iguais. RELATORIO-MANIFESTACAO-QA.md na mesma entrega. | 18/10: Tempo autorizou disponibilização da candidata73f8bd1347ca. Código40fontes/build167 trocados por hash, manutenção terminada, cache de dados preservada. Backup fresco/restauro QA:295tabelas,31sequências,1320ficheiros, arranque/decifragem conferidos. Relatório operacional em outputs/investmoz-navegacao-ativacao-20261018/para-revisao/. | 18/10: disponibilização concluída73f8bd1347ca. MFA regularizado e150000 instalada pela conta2, reciboda1cae7b-a403-4256-9fd8-98ff2a69918d. Ledger/tabela=1, zero preferências importadas. Prévia e sucesso observados; Codex não repetiuPOST.290tabelas iguais ao backup e zero diferenças inesperadas. Relatório/recibo finais na mesma entrega. | Homologação teste-investidor 19/10/2026: Navegação contextual e manifestação de interesse=Ausente. Saldo derivado e limites em outputs/investmoz-disponibilizacao-integral-20261019/SALDO-E-ACTUALIZACAO-CONSOLIDADA.md. Não substitui estado/provas do activo; trecho documental encerrado, vínculo dossier aberto. | Proposta integral fdcb31f1b5b9: aplicação activa local completa + R2/DOC01/destino reconciliados; schema/build/recuperação de contexto e reversão de apresentação ensaiados no clone isolado. Não instalado remotamente. Inc. QA territoriais/Inhambane/programas separados. Limites e decisões em outputs/investmoz-disponibilizacao-integral-20261019/PROPOSTA-INTEGRAL-PARA-DECISAO.md. | Execução autorizada fdcb31f1b5b9 concluída em teste-investidor: Navegação contextual e manifestação de interesse=Disponível. 1080 hashes iguais, schema171/88, custódia/scan/recuperação reais. Sem publicação ou papéis novos. Vínculo dossier legítimo pendente; incrementos QA separados. Limites em outputs/investmoz-disponibilizacao-integral-20261019/RESULTADO-DISPONIBILIZACAO-INTEGRAL.md; não encerra critérios globais não demonstrados. [UTILIZACAO-HOMOLOGACAO-20261019] Leitura nominal de contas/recursos no destino; saldo18/10; prévia29 sem escrita; comparação de hashes QA separados. outputs/investmoz-disponibilizacao-integral-20261019/UTILIZACAO-EFECTIVA-HOMOLOGACAO.md [RECONCILIACAO-43-20261019] Código e critérios confrontados com leitura READ ONLY fresca; PROVA-RECONCILIACAO-43-LEITURA.json, RECONCILIACAO-43-QA-FONTES.json, RECONCILIACAO-43-SCHEMA-QA.json. Não encerra critério funcional por inventário. -[PLANO-P1-P6-20261019] Plano Tempo: 27–46 h disponibilização; P7 e desenvolvimento separados. Inclusão 36–39 expressa para decisão; sem publicação automática. Revisão de proposta d87970e701f0. Roteiro no manual existente; não encerra critério por instalação.",balcão,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Services/VirtualDesk.php; app/Services/Ai/InvestorGuidance.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,InvestorGuidanceTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,," | Revisão visível sóQA; edição de Terra/Balcão em memória, sem submissão. Comparação de cliques estrutural documentada, sem ganho global/telemetria presumidos. Código exacto SHA256b1c98ec7140c2753a40d22b6b4f235ab7c4f7c5a43d322d55ba6c84a53a169d6. L1 encerrado no âmbito entregue, não reensaiado; ativo inalterado. | Cliques comparativos continuam estruturais. Nesta associação observados uma escolha no select + uma activação; submissão uma activação; sem total desde início/tempo/ganho global. Dois reenviosHTTP não contam como cliques.998 ficheiros ativos iguais; sem schema novo, sem repetir140000/L1; ficha integral aberta. | Não confundir código disponibilizado com instalação integral concluída. Nenhuma ficha guardada/publicada, fixture/grant ou submissão ativa.292tabelas iguais; só cache/sessões/remember_token variaram, zero diferenças inesperadas. Provas QA anteriores reutilizadas; conferência dos novos anexos pelo utilizador não presumida; ficha integral aberta. | Instalação nominal e conferência operacional por leitura; zero fichas guardadas/publicadas, fixtures/grants ou manifestações submetidas no ativo. Provas funcionais são as QA anteriores, não novo ensaio ativo. Autorização da Tempo não presume conferência dos novos anexos pelo utilizador; cliques estruturais não viram telemetria.","0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, +[PLANO-P1-P6-20261019] Plano Tempo: 27–46 h disponibilização; P7 e desenvolvimento separados. Inclusão 36–39 expressa para decisão; sem publicação automática. Revisão de proposta d87970e701f0. Roteiro no manual existente; não encerra critério por instalação. | docs/investmoz/v2/auditoria-portal/apresentacao-contexto-qa-20261115.md (conferencia dirigida dos quatro percursos); outputs/investor-intent-20261115/backend.log (12 testes/412 assercoes); frontend.log (137 testes); phpstan.log (zero erros) | Conferência autenticada e recibos adicionais: apresentacao-contexto-qa-20261115.md; outputs/investor-intent-20261115/hotel-browser-report.html | Saldo actual V01–V15: apresentacao-contexto-qa-20261115.md#verificações-restantes--saldo-actual-para-execução-na-mesma-candidata",balcão,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Services/VirtualDesk.php; app/Services/Ai/InvestorGuidance.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,InvestorGuidanceTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,," | Revisão visível sóQA; edição de Terra/Balcão em memória, sem submissão. Comparação de cliques estrutural documentada, sem ganho global/telemetria presumidos. Código exacto SHA256b1c98ec7140c2753a40d22b6b4f235ab7c4f7c5a43d322d55ba6c84a53a169d6. L1 encerrado no âmbito entregue, não reensaiado; ativo inalterado. | Cliques comparativos continuam estruturais. Nesta associação observados uma escolha no select + uma activação; submissão uma activação; sem total desde início/tempo/ganho global. Dois reenviosHTTP não contam como cliques.998 ficheiros ativos iguais; sem schema novo, sem repetir140000/L1; ficha integral aberta. | Não confundir código disponibilizado com instalação integral concluída. Nenhuma ficha guardada/publicada, fixture/grant ou submissão ativa.292tabelas iguais; só cache/sessões/remember_token variaram, zero diferenças inesperadas. Provas QA anteriores reutilizadas; conferência dos novos anexos pelo utilizador não presumida; ficha integral aberta. | Instalação nominal e conferência operacional por leitura; zero fichas guardadas/publicadas, fixtures/grants ou manifestações submetidas no ativo. Provas funcionais são as QA anteriores, não novo ensaio ativo. Autorização da Tempo não presume conferência dos novos anexos pelo utilizador; cliques estruturais não viram telemetria.","0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,"Conferencia individual por ecra: intencao, reutilizacao, filtros, valores, gravacao/retoma, isolamento, computador e telemovel; sem inferir cobertura dos consumidores pelo componente. ","APROVADO no saldo QA deste requisito [EXECUÇÃO PLAYWRIGHT QA 15/11] Ver estados V executados na coluna de evidência e no mesmo relatório; sem instalação ou aceitação global do portal. [HISTÓRICO ANTERIOR] NÃO VERIFICADO integralmente — incremento assistido em QA; conferência autenticada e consumidores afectados pendentes. | Hotel: recorte demonstrado; aceitação transversal integral permanece não verificada. | Instalação suspensa; encerrar apenas os passos V associados, com executante/data/candidata/largura/evidência. Provas aceites preservadas; bloqueio do controlo de URL não demonstra falha do portal." MASTER-600240dd-0019,"Cada ecrã deve permitir guardar e retomar, distinguir obrigatório de opcional, explicar erros e indicar a origem das recomendações. A falta de dados oficiais detalhados não impede usar uma hipótese declarada pelo promotor.",..\..\..\..\..\..\Users\macbook\.codex\attachments\c6245408-7052-4478-8804-377b282e8203\Pasted text.txt; SHA 600240dd64b59b82bdb92e471b475f9efc96eab67f9cd532a432e1e7a324f0c9; linha 121,Balcão/orientação,/balcao-virtual/contextos; /balcao-virtual/dossiers; /balcao-virtual/dossiers/{id}; /balcao-virtual/dossiers/{id}/documentos; /balcao-virtual/dossiers/{id}/documentos/{document}; /balcao-virtual/dossiers/{id}/documentos/{document}/conferencia; /balcao-virtual/dossiers/{id}/etapas; /balcao-virtual/dossiers/{id}/fontes; /balcao-virtual/dossiers/{id}/orientacao; /balcao-virtual/dossiers/{id}/pedidos; /balcao-virtual/dossiers/{id}/pressupostos; /balcao-virtual/dossiers/{id}/recomendacoes,"VirtualDesk, pedidos/casos, anexos, contexto dossier e acompanhamento. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,"Pedido contextual→gravar→submeter→nova sessão→gestor→mensagem/documentos/resultado, reaproveitando A/B. Critério individual original preservado; cobertura atual ainda não individualizada.","Perfis próprios do Balcão; serviços/campos e decisões externas aplicáveis, sem inventar destinatário/prazo. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","MASTER-600240dd-0019: Cada ecrã deve permitir guardar e retomar, distinguir obrigatório de opcional, explicar erros e indicar a origem das recomendações. A falta de dados oficiais detalhados não impede usar uma hipótese declarada pelo promotor.",P2,MASTER-600240dd-0019: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-600240dd-0019,1,"[{""id"":""MASTER-600240dd-0019"",""pedido"":""Cada ecrã deve permitir guardar e retomar, distinguir obrigatório de opcional, explicar erros e indicar a origem das recomendações. A falta de dados oficiais detalhados não impede usar uma hipótese declarada pelo promotor."",""fontes"":[""..\\..\\..\\..\\..\\..\\Users\\macbook\\.codex\\attachments\\c6245408-7052-4478-8804-377b282e8203\\Pasted text.txt; SHA 600240dd64b59b82bdb92e471b475f9efc96eab67f9cd532a432e1e7a324f0c9; linha 121""],""aceitacao"":""Cada ecrã deve permitir guardar e retomar, distinguir obrigatório de opcional, explicar erros e indicar a origem das recomendações. A falta de dados oficiais detalhados não impede usar uma hipótese declarada pelo promotor."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""Balcão/orientação""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.desk_cases: 1 registos; public.desk_requests: 0 registos; public.desk_institutional_links: 0 registos; public.desk_messages: 0 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.","Pedido contextual→gravar→submeter→nova sessão→gestor→mensagem/documentos/resultado, reaproveitando A/B. Critério individual original preservado; cobertura atual ainda não individualizada.","VirtualDesk, pedidos/casos, anexos, contexto dossier e acompanhamento","Perfis próprios do Balcão; serviços/campos e decisões externas aplicáveis, sem inventar destinatário/prazo.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: balcão. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,balcão,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Services/VirtualDesk.php; app/Services/Ai/InvestorGuidance.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,InvestorGuidanceTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, MASTER-600240dd-0020,"A entrada deve recolher título, problema, clientes, solução, sector e localização pretendida. Depois acrescentam-se mercado, concorrência, canais, fornecedores, capacidade de produção, recursos, equipa, riscos e necessidades de capital. O resumo executivo é produzido a partir das secções preenchidas e pode ser revisto pelo utilizador.",..\..\..\..\..\..\Users\macbook\.codex\attachments\c6245408-7052-4478-8804-377b282e8203\Pasted text.txt; SHA 600240dd64b59b82bdb92e471b475f9efc96eab67f9cd532a432e1e7a324f0c9; linha 126,governação/outros,/api/v1/investment/admin/interests/{interest}/status; /management/history; /management/interests; /management/interests/{interest}; /management/interests/{interest}/consent/contact; /management/interests/{interest}/consent/proponent; /management/opportunities; /management/opportunities/create; /management/opportunities/drafts; /management/opportunities/{id}/draft; /management/opportunities/{id}/edit; /management/opportunities/{id}/lifecycle,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Localizar obrigação verificável e consumidores/contrato atuais antes de estimar implementação ou declarar conclusão. Critério individual original preservado; cobertura atual ainda não individualizada.,"Ler secção/versão correspondente; distinguir requisito funcional, decisão e exemplo. Fontes oficiais já aceites. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","MASTER-600240dd-0020: A entrada deve recolher título, problema, clientes, solução, sector e localização pretendida. Depois acrescentam-se mercado, concorrência, canais, fornecedores, capacidade de produção, recursos, equipa, riscos e necessidades de capital. O resumo executivo é produzido a partir das secções preenchidas e pode ser revisto pelo utilizador.",P2,MASTER-600240dd-0020: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-600240dd-0020,1,"[{""id"":""MASTER-600240dd-0020"",""pedido"":""A entrada deve recolher título, problema, clientes, solução, sector e localização pretendida. Depois acrescentam-se mercado, concorrência, canais, fornecedores, capacidade de produção, recursos, equipa, riscos e necessidades de capital. O resumo executivo é produzido a partir das secções preenchidas e pode ser revisto pelo utilizador."",""fontes"":[""..\\..\\..\\..\\..\\..\\Users\\macbook\\.codex\\attachments\\c6245408-7052-4478-8804-377b282e8203\\Pasted text.txt; SHA 600240dd64b59b82bdb92e471b475f9efc96eab67f9cd532a432e1e7a324f0c9; linha 126""],""aceitacao"":""A entrada deve recolher título, problema, clientes, solução, sector e localização pretendida. Depois acrescentam-se mercado, concorrência, canais, fornecedores, capacidade de produção, recursos, equipa, riscos e necessidades de capital. O resumo executivo é produzido a partir das secções preenchidas e pode ser revisto pelo utilizador."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,Requisito transversal; consultar estado-ativo-after.json,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Localizar obrigação verificável e consumidores/contrato atuais antes de estimar implementação ou declarar conclusão. Critério individual original preservado; cobertura atual ainda não individualizada.,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer","Ler secção/versão correspondente; distinguir requisito funcional, decisão e exemplo. Fontes oficiais já aceites.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: governação e demais cláusulas. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,governação e demais cláusulas,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",AGENTS.md — componentes do domínio encontrados; correspondência integral deste requisito não presumida,; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, MASTER-600240dd-0021,"Filtrar por modalidade, finalidade, montante e moeda, fase do projecto, dimensão, sector, localização, estado e canal. Crédito, subvenção, garantia e participação no capital não são instrumentos equivalentes. Uma subvenção não deve ser apresentada como crédito a taxa zero.",..\..\..\..\..\..\Users\macbook\.codex\attachments\c6245408-7052-4478-8804-377b282e8203\Pasted text.txt; SHA 600240dd64b59b82bdb92e471b475f9efc96eab67f9cd532a432e1e7a324f0c9; linha 148,governação/outros,/api/v1/investment/admin/interests/{interest}/status; /management/history; /management/interests; /management/interests/{interest}; /management/interests/{interest}/consent/contact; /management/interests/{interest}/consent/proponent; /management/opportunities; /management/opportunities/create; /management/opportunities/drafts; /management/opportunities/{id}/draft; /management/opportunities/{id}/edit; /management/opportunities/{id}/lifecycle,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Localizar obrigação verificável e consumidores/contrato atuais antes de estimar implementação ou declarar conclusão. Critério individual original preservado; cobertura atual ainda não individualizada.,"Ler secção/versão correspondente; distinguir requisito funcional, decisão e exemplo. Fontes oficiais já aceites. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","MASTER-600240dd-0021: Filtrar por modalidade, finalidade, montante e moeda, fase do projecto, dimensão, sector, localização, estado e canal. Crédito, subvenção, garantia e participação no capital não são instrumentos equivalentes. Uma subvenção não deve ser apresentada como crédito a taxa zero.",P2,MASTER-600240dd-0021: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-600240dd-0021,1,"[{""id"":""MASTER-600240dd-0021"",""pedido"":""Filtrar por modalidade, finalidade, montante e moeda, fase do projecto, dimensão, sector, localização, estado e canal. Crédito, subvenção, garantia e participação no capital não são instrumentos equivalentes. Uma subvenção não deve ser apresentada como crédito a taxa zero."",""fontes"":[""..\\..\\..\\..\\..\\..\\Users\\macbook\\.codex\\attachments\\c6245408-7052-4478-8804-377b282e8203\\Pasted text.txt; SHA 600240dd64b59b82bdb92e471b475f9efc96eab67f9cd532a432e1e7a324f0c9; linha 148""],""aceitacao"":""Filtrar por modalidade, finalidade, montante e moeda, fase do projecto, dimensão, sector, localização, estado e canal. Crédito, subvenção, garantia e participação no capital não são instrumentos equivalentes. Uma subvenção não deve ser apresentada como crédito a taxa zero."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,Requisito transversal; consultar estado-ativo-after.json,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Localizar obrigação verificável e consumidores/contrato atuais antes de estimar implementação ou declarar conclusão. Critério individual original preservado; cobertura atual ainda não individualizada.,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer","Ler secção/versão correspondente; distinguir requisito funcional, decisão e exemplo. Fontes oficiais já aceites.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: governação e demais cláusulas. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,governação e demais cláusulas,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",AGENTS.md — componentes do domínio encontrados; correspondência integral deste requisito não presumida,; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, @@ -11125,7 +11125,7 @@ AUD-SIM-L1-P130,Transmissão de bens digitais,"Refinamento Tempo24/10 do saldoL1 AUD-SIM-L1-P131,"Facto gerador/exigibilidade: entrega, serviço, importação, instalação e operações continuadas",Refinamento Tempo24/10 do saldoL1; origemAUD-SIM-INT02; CIVA2016 PDF8–9 e alterações aplicáveis,Simulador/IVA — cobertura por operacao,/simulador,"G11A/P131 instalado e8b5ae43:goods_available,goods_transport,goods_installation,service_completed,service_early_charge,import_clearance,import_auction,continuous_period,contract_effects. Eventos7(1)a/b/c,7(2),7(3),7(7):disponibilização,início transporte,instalação/montagem concluída,serviço realizado/cobrado ou debitado antecipadamente pelo montante respectivo,desembaraço/arrematação/venda na importação,termo do período sucessivo,efeitos translativos com excepções3(3)a/b. Facto gerador separado de exigibilidade8;factura comercial não desloca evento aduaneiro.",Disponível na homologação e8b5ae43;delta instalado conferido,19frontend/API1/65rollback/tipos/build/EdgeCUA;provas anteriores reutilizadas.,"Demonstrado em QA e entregue na homologação e8b5ae43,no âmbito do ramo","Sem pendência neste recorte de eventos7/exigibilidade8 parametrizada;2026contexto;facto gerador7 e exigibilidade8 por data/âmbito;uma parcela de recebimento e restante por linha,ou parcelas de âmbitos distintos,sem agregação de totais entre linhas. Prazo de emissão é parâmetro legal identificado,não calendário presumido;importação segue7c. P104parcial não aplica câmbio fiscal.Sem nova base/IVA,taxa,dedução,campo11,regularização ou totaisModeloA;P133regimes suspensivos/viagens mantém âmbito separado.","Eventos7(1)a/b/c,7(2),7(3),7(7):disponibilização,início transporte,instalação/montagem concluída,serviço realizado/cobrado ou debitado antecipadamente pelo montante respectivo,desembaraço/arrematação/venda na importação,termo do período sucessivo,efeitos translativos com excepções3(3)a/b. Facto gerador separado de exigibilidade8;factura comercial não desloca evento aduaneiro.",Condicoes/fonte/periodo desta operacao -> calculo ou nao aplicacao explicada -> gravacao -> recuperacao -> relatorio coerentes; desconhecido nao e zero. Preservar oportunidade e historico.,Saldo L1; sequencia do incremento indicada,,AUD-SIM-INT02,1,,,,,,,,,,"P131/P132 entregue conjuntamente e8b5ae43 sobre92eaa935;backup/restauro174tabelas/369ficheiros e delta conferidos. | Histórico: QAconcluído7e6e462e. | Histórico: PreparaçãoQA P104/P131/P132;118fechos inventariados antes dos testes,sem perdas confirmadas. | Histórico: 25/10/2026 impedimento: Falta motor de eventos7/8 para entrega,serviço,importação,instalação e operações continuadas. | Operacao discriminada do saldo anterior; e desenvolvimento nao demonstrado, nao regressao ou perda de fonte aceite.",Manter encerrado no âmbito entregue;reutilizar provas e conferir apenas deltas afectados.,currencyEvents nosnapshot/API/dossier;convertCents existente exportado semmudarlógica,Backup/restauro/destino autenticado;sem schema/permissões alterados ou ensaios sintéticos no activo.,"CIVA Lei13/2016:7(1)–(7),PDF8/p1426(266);8,PDF9/p1426(267);15(8),PDF14/p1426(272),páginas visualmente conferidas.Lei22/2022 eLei10/2025 não alteram7/8;15(8)mantido.RIVADecreto7/2008,21,PDF4:regra histórica5dias úteis e excepções;prazo actual não automatizado,exige disposição/calendário/âmbito identificados.","Desenvolvimento,QA e entrega conjunta concluídos no recorte;L1aberto",Sem esforço funcional pendente neste recorte;não estimativa de todoL1.,"Cotejo documental e revisao do codigo; candidato544068e8 preservado. Sem ensaio funcional deste ramo. | C:\laragon\www\portal-investidor\outputs\iva-l1-currency-events-20261025\preservation-before-tests.json | docs\investmoz\simulations\iva-l1-currency-events-qa-20261025.json | iva_l1_currency_events_P131_P132_partial_P104_homologation_20261025:manifesto/24marcadores/5hashes/simuladorHTTP200,preservação174tabelas/369ficheiros/29fichas/28relações/408geometrias;QA individual reutilizada",G11A,25/10/2026 — entrega conjuntaP131/P132 e8b5ae43,"{""article"": ""7(1–3);8"", ""source"": ""CIVA2016 PDF8–9 e alterações aplicáveis"", ""scope"": ""2026 somente quando condicoes e periodo aplicavel forem determinados"", ""next_increment"": ""L1-R1P: período fiscal efectivo, distinto de mês orçamental""}",,,,,,,,,Nao confundir prova dos dez tratamentos anteriores com cobertura deste ramo.,,,,Entregue na homologação e8b5ae43;L1aberto AUD-SIM-L1-P132,"Exigibilidade em uso próprio,comissão,consignação e adiantamentos",Refinamento Tempo24/10 do saldoL1; origemAUD-SIM-INT02; CIVA2016 PDF8–9 e alterações aplicáveis,Simulador/IVA — cobertura por operacao,/simulador,"G11B/P132 instalado e8b5ae43:own_goods,own_services,commission_delivery,consignment_deadline,advance_payment. Eventos7(4)/(5)/(6) e8c:afectações/transmissões assimiladas3(3)e/f,serviços4(2),disponibilização pelo comissário,termo180dias de mercadorias à consignação3(3)d e pagamentos anteriores à factura. Corrigida remissão a consignação,não embalagensP102.8a/b/c separam parcela recebida e restante,sem dupla contagem.",Disponível na homologação e8b5ae43;delta instalado conferido,19frontend/API1/65rollback/tipos/build/EdgeCUA;provas anteriores reutilizadas.,"Demonstrado em QA e entregue na homologação e8b5ae43,no âmbito do ramo","Sem pendência neste recorte de eventos7/exigibilidade8 parametrizada;2026contexto;facto gerador7 e exigibilidade8 por data/âmbito;uma parcela de recebimento e restante por linha,ou parcelas de âmbitos distintos,sem agregação de totais entre linhas. Prazo de emissão é parâmetro legal identificado,não calendário presumido;importação segue7c. P104parcial não aplica câmbio fiscal.Sem nova base/IVA,taxa,dedução,campo11,regularização ou totaisModeloA;P133regimes suspensivos/viagens mantém âmbito separado.","Eventos7(4)/(5)/(6) e8c:afectações/transmissões assimiladas3(3)e/f,serviços4(2),disponibilização pelo comissário,termo180dias de mercadorias à consignação3(3)d e pagamentos anteriores à factura. Corrigida remissão a consignação,não embalagensP102.8a/b/c separam parcela recebida e restante,sem dupla contagem.",Condicoes/fonte/periodo desta operacao -> calculo ou nao aplicacao explicada -> gravacao -> recuperacao -> relatorio coerentes; desconhecido nao e zero. Preservar oportunidade e historico.,Saldo L1; sequencia do incremento indicada,,AUD-SIM-INT02,1,,,,,,,,,,"P131/P132 entregue conjuntamente e8b5ae43 sobre92eaa935;backup/restauro174tabelas/369ficheiros e delta conferidos. | Histórico: QAconcluído7e6e462e. | Histórico: PreparaçãoQA P104/P131/P132;118fechos inventariados antes dos testes,sem perdas confirmadas. | Histórico: 25/10/2026 impedimento: Falta exigibilidade dos eventos específicos de uso próprio/comissão/embalagens/adiantamentos. | Operacao discriminada do saldo anterior; e desenvolvimento nao demonstrado, nao regressao ou perda de fonte aceite.",Manter encerrado no âmbito entregue;reutilizar provas e conferir apenas deltas afectados.,currencyEvents nosnapshot/API/dossier;convertCents existente exportado semmudarlógica,Backup/restauro/destino autenticado;sem schema/permissões alterados ou ensaios sintéticos no activo.,"CIVA Lei13/2016:7(1)–(7),PDF8/p1426(266);8,PDF9/p1426(267);15(8),PDF14/p1426(272),páginas visualmente conferidas.Lei22/2022 eLei10/2025 não alteram7/8;15(8)mantido.RIVADecreto7/2008,21,PDF4:regra histórica5dias úteis e excepções;prazo actual não automatizado,exige disposição/calendário/âmbito identificados.","Desenvolvimento,QA e entrega conjunta concluídos no recorte;L1aberto",Sem esforço funcional pendente neste recorte;não estimativa de todoL1.,"Cotejo documental e revisao do codigo; candidato544068e8 preservado. Sem ensaio funcional deste ramo. | C:\laragon\www\portal-investidor\outputs\iva-l1-currency-events-20261025\preservation-before-tests.json | docs\investmoz\simulations\iva-l1-currency-events-qa-20261025.json | iva_l1_currency_events_P131_P132_partial_P104_homologation_20261025:manifesto/24marcadores/5hashes/simuladorHTTP200,preservação174tabelas/369ficheiros/29fichas/28relações/408geometrias;QA individual reutilizada",G11B,25/10/2026 — entrega conjuntaP131/P132 e8b5ae43,"{""article"": ""7(4–7)"", ""source"": ""CIVA2016 PDF8–9 e alterações aplicáveis"", ""scope"": ""2026 somente quando condicoes e periodo aplicavel forem determinados"", ""next_increment"": ""L1-R1P: período fiscal efectivo, distinto de mês orçamental""}",,,,,,,,,Nao confundir prova dos dez tratamentos anteriores com cobertura deste ramo.,,,,Entregue na homologação e8b5ae43;L1aberto AUD-SIM-L1-P133,Saída de regimes suspensivos e operações de viagens,Refinamento Tempo24/10 do saldoL1; origemAUD-SIM-INT02; CIVA2016 PDF8–9 e alterações aplicáveis,Simulador/IVA — cobertura por operacao,/simulador,"P133 instalado a48e9749: Cessação efectiva de regime7(8), distinta de mudança de armazém/transferência; viagens7(9)/RIVA40 pelo primeiro entre integral e início/primeiro serviço, sem subtrair dia nem inferir ordem intradiária. Exigibilidade8 por factura/recebimento separada, incluindo sinal e saldo integral sem dupla soma. Sem montante de imposto, desembaraço, direito ou ICE apurados.",Disponível na homologação a48e9749; delta instalado conferido no âmbito demonstrado.,29testes frontend; API privada1teste/68asserções; tipos/build; Edge gravação/recuperação/relatório;10operações/5períodos/12eventos.,"Demonstrado em QA e entregue na homologação a48e9749, no âmbito do ramo","Sem pendência de entrega neste recorte de margem/eventos. Sem cálculo de IVA devido ou dedução. Continuidade do apuramento/liquidação em AUD-SIM-INT02; deduções/regularizações nos lotes próprios, incluindoL2/L3, não encerradas. Factura/modelo oficial/regularização não executados.","Fontes do regime fiscal e evento específico cotejadas; moedaMZN para base, âmbito completo por operador/período, dados/datas/referências concretos. P104 não bloqueia classificação/eventos independentes.",Condicoes/fonte/periodo desta operacao -> calculo ou nao aplicacao explicada -> gravacao -> recuperacao -> relatorio coerentes; desconhecido nao e zero. Preservar oportunidade e historico.,Saldo L1; sequencia do incremento indicada,,AUD-SIM-INT02,1,,,,,,,,,,"P129/P133 entregues conjuntamente a48e9749 sobre df43aeb1;123fechos preservados; backup/restauro e delta conferidos; limitação ligada a AUD-SIM-INT02. | Histórico: P133 QA concluído no âmbito demonstrado,123fechos preservados,sem repetição de provas aceites. | Histórico: Preparação QA viagens/eventos:123fechos inventariados antes dos testes; nenhuma perda confirmada. | Histórico: 25/10/2026 impedimento: Falta motor de saída de regimes suspensivos e evento das viagens,no regime específico. | Operacao discriminada do saldo anterior; e desenvolvimento nao demonstrado, nao regressao ou perda de fonte aceite.","Manter encerrado no âmbito de margem/eventos demonstrado, reutilizando provas. Conservar ligação ao trabalho fiscal restante em AUD-SIM-INT02: apuramento/liquidação, deduções e regularizações próprias não concluídos por esta entrega.","Snapshot/API/dossier, moeda, datas UTC, histórico e motor de exigibilidade8 existentes; viagem classificada associada à mesma oportunidade, sem copiar edições deliberadas.","Destino autenticado e backup/restauro; sem migração, alteração de permissões, importação/publicação documental ou ensaio sintético no activo.","RIVA Decreto7/2008,38–46,acervoBR16-I16/04/2008PDF6–8/p104–106 (6/7 conferidas visualmente,46(2) texto extraídoPDF8). CIVA Lei13/2016,4(5)/5(2),PDF7/p1426(265);7(8)/(9)/8,PDF9/p1426(267);14(1),PDF13/p1426(271),páginas visualmente conferidas. CIVA17(1),Lei22/2022PDF3,16% usado no divisor da base;Lei10/2025não altera4/7/8/17. Não confundir regime fiscal com licenciamento turístico.","Desenvolvimento, QA e entrega conjunta concluídos no âmbito de margem/eventos; IVA devido/dedução não calculados e trabalho restante rastreável.",Sem esforço de entrega pendente neste recorte; não representa fecho ou estimativa do restante trabalho fiscal.,Cotejo documental e revisao do codigo; candidato544068e8 preservado. Sem ensaio funcional deste ramo. | C:\laragon\www\portal-investidor\outputs\iva-l1-travel-events-20261025\preservation-before-tests.json | docs\investmoz\simulations\iva-l1-travel-events-qa-20261025.json | iva_l1_travel_events_P129_P133_homologation_20261025:24marcadores/6hashes/simuladorHTTP200;174tabelas/369ficheiros/29fichas/28relações/408geometrias;provasQA reutilizadas;fiscal_continuity:AUD-SIM-INT02,Viagens e eventos P129/P133,25/10/2026 — entrega conjunta a48e9749,"{""article"": ""7(8–9)"", ""source"": ""CIVA2016 PDF8–9 e alterações aplicáveis"", ""scope"": ""2026 somente quando condicoes e periodo aplicavel forem determinados"", ""next_increment"": ""L1-R1P: período fiscal efectivo, distinto de mês orçamental""}",,,,,,,,,Nao confundir prova dos dez tratamentos anteriores com cobertura deste ramo.,,,,Entregue na homologação a48e9749 no âmbito demonstrado;L1 aberto -INE-DEMO-01,"Integração nacional de dados demográficos INE na viabilidade existente, importador em duas etapas, séries/versionamento, comparação territorial e adenda nacional.",Pedido colado pelo proprietário nesta sessão; execução expressamente confirmada; Macate/Vanduzi autorizados apenas em QA em 13/11/2026.,Território; viabilidade; percurso; SWOT; simulador,/localizacoes/demografia; /api/v1/investment/demography; /management/demography,DemographicImport; DemographicEvidence; leitor XLSX; cadastro/mapa/comparação/simulador e fontes SWOT existentes reutilizados.,"Homologação:4988ca89 instalado,erro500 de processos corrigido;preparaçõesCLI12/920456 privadas,por confirmaçãoMFA. Local:12lotes/920456 instalados e verificados.","154706 observações reais INE; três originais com scan real/hash; repetição sem duplicação; 72 reconciliações entre exemplares; comparação GONDOLA/GURO. Homologação: backup/restauro190 tabelas/369 ficheiros;11 tabelas de negócio preservadas;168 correspondências+15 distritos autorizados,sem pendências;HTTPS200 e revisão b20068d0 confirmada. Correcção df543a44:3testes/17asserções;HTTPS confirma revisão;ambos os titulares designados passam a autorização de leitura;nenhuma permissão alterada;hashes de código/configuração conferidos. Correcção500:2testes/20asserções sem proc_open;14testes/52asserções consumidores;8preparador;PHPStan aprovado. PHP-FPM real confirmou processos bloqueados,cacheCLI e antimalware disponíveis,hashes correctos,sem actor/sessão ou escrita de negócio;HTTPS confirma4988ca89.",Código instalado e verificado no PHP-FPM real;incorporação remota dos dados pendente da confirmação autenticada.,"Confirmar coortes initial/remaining/zambezia na sessão com MFA e conferir recibos,12 lotes/920456 observações e consulta territorial. Conferência visual administrativa pendente.",PostgreSQL/PostGIS QA; ClamAV; Python stdlib; autenticação e MFA existentes; nenhum novo aprovador.,"Três ficheiros associados aos territórios, valores exactos, séries 2017–2050, consulta sectorial/temporal, duas localizações, fontes/versões, inconsistências e acessos demonstrados em QA. Homologação manual restante registada no relatório.",Alta,,,,,"Consulta pública desktop/mobile conferida; visual administrativa pendente, testes HTTP aprovados.",11 testes de integração aprovados.,Três lotes QA; 154706 observações; idempotência e unicidade verificadas.,Consulta por território/ano/exemplar; desactivação/reaprovação preservam histórico.,"População/idade/residência, vitais, fontes e limitações; sem extrapolação, procura automática ou probabilidade de sucesso.",,,,,"Sem pendência de importação dos ficheiros provinciais fornecidos. Conferência visual administrativa,ressalvas/unidades ausentes e indicadores sem valores mantidos;outros ambientes não instalados por esta operação.","PortalProfileInstallation/MFA existentes; DemographicInstallation; DemographicImport; InvestmentGeography; simulador, mapa/comparação e fontes SWOT existentes.",,Proprietário executou a disponibilização autorizada de Zambezia.xlsx e cinco distritos;recibo autenticado e resultado confirmados sem repetição.,,,"outputs/demography-20261113/zambezia/installation-status.json e verification.json:recibo autenticado09:33:38UTC,hash/lote/count126684,total12lotes/920456,preservação11lotes e oito tabelas de negócio,série provincial e cinco distritos públicos. operational-status.json actualizado;ensaios e backup/restauro anteriores preservados.",demografia-ine,13/11/2026 — instalação autenticada concluída; conferência técnica de leitura sem repetição da operação,,,,,,,,,,,,,, +INE-DEMO-01,"Integração nacional de dados demográficos INE na viabilidade existente, importador em duas etapas, séries/versionamento, comparação territorial e adenda nacional.",Pedido colado pelo proprietário nesta sessão; execução expressamente confirmada; Macate/Vanduzi autorizados apenas em QA em 13/11/2026.,Território; viabilidade; percurso; SWOT; simulador,/localizacoes/demografia; /api/v1/investment/demography; /management/demography,DemographicImport; DemographicEvidence; leitor XLSX; cadastro/mapa/comparação/simulador e fontes SWOT existentes reutilizados.,"Homologação:4988ca89 instalado,erro500 de processos corrigido;preparaçõesCLI12/920456 privadas,por confirmaçãoMFA. Local:12lotes/920456 instalados e verificados.","154706 observações reais INE; três originais com scan real/hash; repetição sem duplicação; 72 reconciliações entre exemplares; comparação GONDOLA/GURO. Homologação: backup/restauro190 tabelas/369 ficheiros;11 tabelas de negócio preservadas;168 correspondências+15 distritos autorizados,sem pendências;HTTPS200 e revisão b20068d0 confirmada. Correcção df543a44:3testes/17asserções;HTTPS confirma revisão;ambos os titulares designados passam a autorização de leitura;nenhuma permissão alterada;hashes de código/configuração conferidos. Correcção500:2testes/20asserções sem proc_open;14testes/52asserções consumidores;8preparador;PHPStan aprovado. PHP-FPM real confirmou processos bloqueados,cacheCLI e antimalware disponíveis,hashes correctos,sem actor/sessão ou escrita de negócio;HTTPS confirma4988ca89.",Código instalado e verificado no PHP-FPM real;incorporação remota dos dados pendente da confirmação autenticada.,"Confirmar coortes initial/remaining/zambezia na sessão com MFA e conferir recibos,12 lotes/920456 observações e consulta territorial. Conferência visual administrativa pendente.",PostgreSQL/PostGIS QA; ClamAV; Python stdlib; autenticação e MFA existentes; nenhum novo aprovador.,"Três ficheiros associados aos territórios, valores exactos, séries 2017–2050, consulta sectorial/temporal, duas localizações, fontes/versões, inconsistências e acessos demonstrados em QA. Homologação manual restante registada no relatório.",Alta,,,,,"Consulta pública desktop/mobile conferida; visual administrativa pendente, testes HTTP aprovados.",11 testes de integração aprovados.,Três lotes QA; 154706 observações; idempotência e unicidade verificadas.,Consulta por território/ano/exemplar; desactivação/reaprovação preservam histórico.,"População/idade/residência, vitais, fontes e limitações; sem extrapolação, procura automática ou probabilidade de sucesso.",,,,,"Sem pendência de importação dos ficheiros provinciais fornecidos. Conferência visual administrativa,ressalvas/unidades ausentes e indicadores sem valores mantidos;outros ambientes não instalados por esta operação. | Apresentacao/contexto QA 15/11/2026: cobertura dirigida de catalogo/pesquisa, localizacao/demografia, sectores/ancoras/clusters, biblioteca/legislacao e dossier/simulador; sem fecho transversal. Filtros por familia, fontes em detalhe, sintese por fonte, estados vazios e contexto isolado. Visual/movel NAO VERIFICADO; candidata 21ac7eb pendente do bundle. Sem instalacao ou alteracao de dados. | Reconciliacao 21ac7eb/8806312f concluida em QA: evolucao temporal, leitura etaria/rural e ideia por territorio incorporadas selectivamente; originais e solucao comum preservados. Previa real de componentes sinteticos conferida no Edge em computador, 390 px e 360x844; tabela comprimida corrigida e reconferida. Percurso autenticado integral e telefone fisico continuam NAO VERIFICADOS; sem instalacao. | 15/11/2026 - conferencia dirigida dos quatro percursos: ver apresentacao-contexto-qa-20261115.md, tabela por ecra/percurso. Hotel/Agronegocio: API de contexto, entidade, cenario e retorno ao mesmo dossier verificados; preparacao financeira assistida DIVERGENTE. Fundos: filtros e retorno corrigidos/testados. Demografia: sintese e ambito territorial testados. Computador/telemovel autenticados e retoma ponta a ponta NAO VERIFICADOS. QA apenas; entrega transversal nao aceite nem instalada. | Retoma visual após Esc — 15/11/2026: janela controlada em /login; dossier Hotel redirige para autenticação. Sessão do painel indicado pelo responsável não identificada; solicitado apenas o URL. Conferência autenticada/telemóvel NÃO VERIFICADA, sem repetir testes aceites, reiniciar navegadores ou instalar. Evidência no registo de apresentação/contexto existente. 15/11: acesso QA recuperado; Hotel demonstrado na interface com empresa existente, orçamento 2M, mobilizado 1M, receita 7,5M, custo 2M, retoma e relatório descarregado. Emulação 390x844: edição e continuação. Restantes percursos/retoma autenticada integral NÃO VERIFICADOS; sem instalação. Continuação QA: Agronegócio demonstrou entidade por constituir, modelo próprio/retoma/retorno sem converter intervalo em total; Banca/Banco comercial excluiu corretora/microsseguradora sintéticas e guardou referência/produto/versão no dossier; demografia apresentou Boane como contexto distrital. Emulação móvel: síntese legível e província limpa desactiva distritos, sem resultados antigos confundidos. Cobertura integral ainda aberta. [SALDO VISUAL QA 15/11 — PASSOS PENDENTES] Execução actual substitui o saldo anterior: V13: 12.345→12.600 e diferença de período 255; originais conservados; contexto distrital identificado no editor e simulador; rótulos e selector dependente reconferidos. 1440 px: APROVADO, 2026-11-15T16:18:31.360Z, evidência V13-1440-1794759511387; 390 px: APROVADO, 2026-11-15T16:20:49.768Z, evidência V13-390-1794759649790; rótulos: V13-labels-1440-1794759923605, V13-labels-390-1794759934158 | V14: Origem Boane transportada até ao simulador; país por MZ, moeda por prefixo e nível distrital guardados e recuperados. 1440 px: APROVADO, 2026-11-15T16:19:56.796Z, evidência V14-1440-1794759596823; 390 px: APROVADO, 2026-11-15T16:22:14.914Z, evidência V14-390-1794759734939","PortalProfileInstallation/MFA existentes; DemographicInstallation; DemographicImport; InvestmentGeography; simulador, mapa/comparação e fontes SWOT existentes.",,Proprietário executou a disponibilização autorizada de Zambezia.xlsx e cinco distritos;recibo autenticado e resultado confirmados sem repetição.,,,"outputs/demography-20261113/zambezia/installation-status.json e verification.json:recibo autenticado09:33:38UTC,hash/lote/count126684,total12lotes/920456,preservação11lotes e oito tabelas de negócio,série provincial e cinco distritos públicos. operational-status.json actualizado;ensaios e backup/restauro anteriores preservados.; docs/investmoz/v2/auditoria-portal/apresentacao-contexto-qa-20261115.md; outputs/public-context-20261115/frontend.xml; navigation-context.xml; outputs/demography-reconciliation-20261115/qa-result.json; frontend.xml; visual-components.html; docs/investmoz/v2/auditoria-portal/apresentacao-contexto-qa-20261115.md (reconciliacao) | docs/investmoz/v2/auditoria-portal/apresentacao-contexto-qa-20261115.md (conferencia dirigida dos quatro percursos); outputs/investor-intent-20261115/backend.log (12 testes/412 assercoes); frontend.log (137 testes); phpstan.log (zero erros) | Conferência autenticada e recibos adicionais: apresentacao-contexto-qa-20261115.md; outputs/investor-intent-20261115/hotel-browser-report.html | Saldo actual V01–V15: apresentacao-contexto-qa-20261115.md#verificações-restantes--saldo-actual-para-execução-na-mesma-candidata",demografia-ine,13/11/2026 — instalação autenticada concluída; conferência técnica de leitura sem repetição da operação,,,,,,,,,,,,,"Conferencia individual por ecra: intencao, reutilizacao, filtros, valores, gravacao/retoma, isolamento, computador e telemovel; sem inferir cobertura dos consumidores pelo componente. ","APROVADO no saldo QA deste requisito [EXECUÇÃO PLAYWRIGHT QA 15/11] Ver estados V executados na coluna de evidência e no mesmo relatório; sem instalação ou aceitação global do portal. [HISTÓRICO ANTERIOR] NAO VERIFICADO integralmente; preparacao financeira DIVERGENTE; correccoes dirigidas QA demonstradas. Sem instalacao. | Hotel: recorte demonstrado; aceitação transversal integral permanece não verificada. | Instalação suspensa; encerrar apenas os passos V associados, com executante/data/candidata/largura/evidência. Provas aceites preservadas; bloqueio do controlo de URL não demonstra falha do portal." REL-DOSSIER-20261113,"Agrupar no dossier correspondente os relatórios produzidos pelas etapas, com versão, oportunidade e recuperação.",Pedido expresso do proprietário em 13/11/2026: «tem de ser resolvido».,Percurso do investidor; dossier; relatórios,/investimentos/{id}#relatorios; /investimentos/{id}/relatorios/fiscais/{reportId},"Índice e relatório consolidado no percurso existente; reutiliza os geradores Word/HTML, cálculos e cópias preservadas.",Homologação teste-investidor.tempo.co.mz instalada em 8854b292; /investimentos/{id}#relatorios.,"21 testes frontend; regressão servidor 4/168 asserções e caso final 45 asserções; tipos,lint,PHPStan e build aprovados. HTTPS e preservação conferidos na revisão instalada.",Instalado e conferido em 8854b292; resumos S01–S19 consultáveis e descarregáveis,QA: 19 consultas e 38 descargas Word/HTML; recuperação demonstrada. Instalação e consulta/descarga S01 conferidas na homologação. Saídas específicas ainda não produzidas mantêm o saldo próprio.,,"Mesmo dossier/oportunidade → índice por etapa → relatório Word/HTML → acesso a versões APIEX, fiscais e documentos → recuperação sem misturar oportunidades ou expor finanças a gestores.",Alta,,,,,Índice responsivo e exportação consolidada,"Descarga privada da cópia fiscal preservada, autorizada por titular e dossier","Reutiliza os registos existentes; associação fiscal nova conserva âmbito, sem reescrever fontes anteriores.",Aprovada em prova sintética; sem depender de acesso à simulação anónima original.,Versão/data/estado/origem; pendências e âmbito por confirmar explícitos.,,,,,,,,"Acrescentar índice e consolidar saídas existentes; sem módulo paralelo, publicação ou envio automático.",Resumos por etapa instalados e conferidos; originais específicos em falta mantêm o saldo próprio,,outputs/dossier-reports-20261113/verification.json; outputs/dossier-reports-20261113/homologation-installed.json; outputs/dossier-reports-20261113/stage-authenticated-download-verification.json; outputs/dossier-reports-20261113/stage-homologation-installed.json,,,,,,,,,,,,,,,, ACT-20261113-PESQUISA,Pesquisa rápida: contar corredores sem misturar referências; produtos físicos e financeiros separados por categoria e localização; como licenciar empresa.,Pedidos Tempo na conversa de 13/11/2026,Pesquisa rápida,/pesquisa; /,"SearchTerms::requestIntent, GlobalSearchController, FederatedSearch, portal/search, portal-hero; reutiliza catálogos publicados existentes.",Implementado em QA; nova candidata ainda não instalada.,"outputs/quick-search-20261113/: integration.log, regression.log, unit.log, frontend.log, types.log, analysis.log, build.log",QA implementado e testes focados aprovados; instalação e visual pendentes,Instalar após autorização concreta; conferir apresentação no navegador.,,Contagem tipada e zero distinto de falha; produtos separados com localização/cobertura e contexto nos links; licenciamento no roteiro/dossier existentes; só publicados; erros de fontes explícitos; paginação preservada.,Alta,,,,,,,,,,,,,,"Conferência visual e instalação desta candidata; pesquisa territorial é textual, sem inferir elegibilidade.",,,,Implementação QA concluída neste recorte; entrega preparada.,,,,,,,,,,,,,,,,,, ACT-20261113-EDITORIAL-F1,"Dashboard Colaborativo Fase 1: versões e autorizações; artigos, legislação, oportunidades e documentos; filas e notificações",Directiva Tempo 13/11/2026 nesta sessão; plano aprovado e autorização de implementação apenas em desenvolvimento/QA,Gestão editorial / conteúdos,/management/editorial; /management/editorial/resources/{id}; edições/anexos/notificações; editores e circuito nativo de oportunidades,"Edições privadas imutáveis no circuito; versão pública preservada; aprovação/publicação separadas; decisões ligadas a conteúdo/anexos; permissões e auditoria reutilizadas; notificações com acesso revogável [Complemento agrupado QA 14/11/2026] Designação jurídica explícita por configuração protegida, sem conceder gestão geral; nomeação recebida da Tempo. Adaptadores nativos na mesma caixa de notificações e contadores, com âmbito actual e deduplicação. [Apresentação QA 14/11] Administração principal → Dashboard com actividades autorizadas; painel agrupado em cartões por conteúdo/investimento/território, sem repetir oportunidades; navegação comum e expansão móvel preservam destinos e âmbito. [Correcção500 14/11] Estados editoriais partilhados extraídos da página para lib/editorial-states.ts, preservando a entrada dinâmica no manifesto; sem alteração de decisões, permissões ou dados. [Clarificação Tempo 14/11] Administração agrupa conteúdos/oportunidades, cadastros/investimento, pedidos/acompanhamento, acessos/configuração; submenu Dashboard reservado ao painel geral/trabalho/indicadores/filas/notificações. Cadastros fora de Dashboard; funções administrativas retiradas de Mais, destinos pessoais preservados.","Instalado 96f51096; Administração reúne as operações por grupos e Dashboard contém as funções dos painéis, segundo os âmbitos existentes; HTML dos dois painéis e manifesto conferidos","outputs/editorial-phase1-20261113: integração 11/223; oportunidades 6/116 + caso reforçado 1/20; unidade 1/6; frontend 12; PHPStan/tipos/build aprovados; instalação 14/11 d5c960b6: backup/restauro 193 tabelas, quatro alterações aditivas, 416 uploads preservados, HTTP público/privado conferido; CI 132 unitários e 1902 frontend; complemento outputs/editorial-completion-20261114: testes focados finais 28/361; regressão nativa 35/540; frontend 13; tipos/build aprovados; análise estática aprovada após correcções localizadas; duas alterações aditivas ensaiadas no QA55441, preservação e repetição recusada; instalação autorizada a4541298 em 14/11: restauro 195 tabelas, 192 tabelas inalteradas, cache/sessões reconciliadas, 416 uploads preservados, 270 instituições/12 lotes/920456 observações; CI 132/611 + frontend1906; HTTP e serviços conferidos; outputs/dashboard-navigation-20261114: frontend26, acesso4/32, análise estática/tipos/build aprovados; nenhuma escrita activa ou migração; entrega autorizada 73e1d7b9 em 14/11: backup/restauro195 tabelas, CI1910 interface/132 unitários, destinos autorizados e HTTP conferidos; 192 tabelas/416 uploads inalterados, cache/métricas/sessões expiradas reconciliadas; sem migrações, permissões ou configuração alteradas; erro reproduzido no manifesto anterior; HTTP HTML autenticado com build real QA1/8; frontend12; executor1911 interface/132 unitários; servidor HTML sintético com template real200 e assetHTTPS200; backup/restauro195, 193 tabelas/416 uploads preservados; outputs/editorial-dashboard-500-20261114; outputs/administration-dashboard-hierarchy-20261114: navegação25, secções4, acesso4/35, HTMLQA1/11; CI1914 interface,132 unitários; servidorHTML200 dos dois painéis, destinos administrativos separados, backup/restauro195 e preservação conferida","Instalado 96f51096; hierarquia corrigida, erro500 preservado como resolvido; conferência visual pendente","Conferência visual autenticada da hierarquia Administração → Dashboard e das restantes categorias administrativas, incluindo ecrã pequeno. Instalação concluída; sem nova preparação.",Instalação/schema concluídos; falta conferência visual; designação jurídica explícita para validação de novas versões legais,Editar preserva toda a publicação; JSON/prévias/anexos autorizados; conteúdo/anexos novos exigem nova decisão; aprovação distinta da publicação; filas e notificações isoladas; conflitos 409; histórico recuperável,Alta,,,,,"Fila, filtros, edição, histórico e notificações em QA","JSON nas mesmas rotas privadas, com as mesmas autorizações","Edições, decisões, notificações e auditoria; dados sintéticos revertidos pelos testes",Versões e publicação anterior recuperadas; isolamento/revogação demonstrados,Versão pública mantida durante edição e revisão; substituição só por publicação explícita,,,QA implementado; sem instalação operacional antes da entrega autorizada de 14/11/2026,96f51096 confirmado no URL servido. Separação de funções verificada no catálogo de navegação e nos destinos do actor; HTML dos dois painéis e configuração/dados preservados. Conferência visual não foi declarada executada.,"Conferência visual autenticada da hierarquia Administração → Dashboard e das restantes categorias administrativas, incluindo ecrã pequeno. Instalação concluída; sem nova preparação.","DocumentManagementAccess, PortalProfileAccess, EditorialReading, VerifiedDocumentBinary, auditoria e circuito nativo de oportunidades",Conector visual indisponível ou conferência manual pela equipa com os âmbitos existentes; nenhuma autorização ou instalação pendente deste delta,Implementar em desenvolvimento/QA; não intervir em produção,Conferência visual do delta instalado,,"Provas QA anteriores e outputs/editorial-agrupado-20261114/destination-installation-verified.json; recibos de backup, restauro, schema, activação e CI na mesma pasta",Dashboard Colaborativo Fase 1,"14/11/2026 — instalação agrupada autorizada, verificada e preservada",,,,,,,,"Reutilização dos testes nativos de oportunidade, permissão, prévias e integridade",Versão pública preservada; circuito editorial e decisões por versão/anexos; escopos de notificações e conteúdos,"Sem conferência visual autenticada; sem novos papéis, aprovação ou publicação de conteúdos; resíduos da Fase 2 mantidos; validação jurídica requer designação nominal",,Percursos editoriais e autorizações,Artigos → legislação/documentos → oportunidades reutilizadas → fila/painel/notificações,Instalado 96f51096; hierarquia de Administração/Dashboard corrigida; visual pendente diff --git a/outputs/transversal-install-20261115/scope-separation.json b/outputs/transversal-install-20261115/scope-separation.json new file mode 100644 index 00000000..3cfe5788 --- /dev/null +++ b/outputs/transversal-install-20261115/scope-separation.json @@ -0,0 +1,203 @@ +{ + "base": "13497892", + "source_candidate": "7810ffc8", + "excluded_candidate_files": [ + "docs/investmoz/unification/traceability-and-manual.md", + "docs/investmoz/v2/auditoria-portal/apresentacao-contexto-qa-20261115.md", + "docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv", + "outputs/demography-reconciliation-20261115/build.log", + "outputs/demography-reconciliation-20261115/frontend.xml", + "outputs/demography-reconciliation-20261115/lint.log", + "outputs/demography-reconciliation-20261115/qa-result.json", + "outputs/demography-reconciliation-20261115/types.log", + "outputs/demography-reconciliation-20261115/visual-components.html", + "outputs/public-context-20261115/build.log", + "outputs/public-context-20261115/final-consumers.xml", + "outputs/public-context-20261115/final-lint.log", + "outputs/public-context-20261115/frontend.xml", + "outputs/public-context-20261115/lint.log", + "outputs/public-context-20261115/navigation-context.xml", + "outputs/public-context-20261115/qa-result.json", + "outputs/public-context-20261115/types.log", + "resources/js/components/offer-particulars.tsx", + "resources/js/components/opportunity-canonical-fields.tsx", + "resources/js/pages/offers/preparation.tsx", + "tests/frontend/offer-rental-flow.test.mjs", + "tests/frontend/opportunity-screen-presentation.test.mjs", + "tests/frontend/portal-navigation.test.mjs" + ], + "offers_dependency_files": 60, + "changed_shared_dependencies": [ + "resources/js/components/demographic-context.tsx", + "resources/js/components/demographic-evidence.tsx", + "resources/js/components/dossier-navigation-context.tsx", + "resources/js/components/investment-territory.tsx", + "resources/js/components/opportunity-search-filters.tsx", + "resources/js/components/territorial-source-evidence.tsx", + "resources/js/lib/investor-context.ts" + ], + "selected_product_files": [ + "app/Http/Controllers/DemographyController.php", + "app/Http/Controllers/FundingProgrammeController.php", + "app/Http/Controllers/InvestmentWorkspaceController.php", + "app/Http/Controllers/InvestorContextController.php", + "app/Http/Requests/StoreSimulationFormDraftRequest.php", + "app/Services/CompanyComparison.php", + "app/Services/CompanyPreparation.php", + "app/Services/DemographicEvidence.php", + "app/Services/FundingInstitutionClassification.php", + "app/Services/FundingInstitutionDetails.php", + "app/Services/FundingProgrammes.php", + "app/Services/InvestmentCorridorContext.php", + "app/Services/InvestmentGeography.php", + "app/Services/InvestmentOpportunityChoices.php", + "app/Services/InvestorContext.php", + "app/Services/InvestorPath.php", + "app/Services/ProactiveSupply.php", + "app/Services/VirtualDesk.php", + "config/investor-path.php", + "resources/js/components/acquisition-closure.tsx", + "resources/js/components/catalogue-choice-select.tsx", + "resources/js/components/catalogue-navigation.tsx", + "resources/js/components/cluster-competitiveness-public.tsx", + "resources/js/components/country-select.tsx", + "resources/js/components/currency-select.tsx", + "resources/js/components/demographic-context.tsx", + "resources/js/components/demographic-evidence.tsx", + "resources/js/components/demographic-reading-summary.tsx", + "resources/js/components/dossier-navigation-context.tsx", + "resources/js/components/dossier-prefill.tsx", + "resources/js/components/evidence-details.tsx", + "resources/js/components/fiscal-l3-preparation.tsx", + "resources/js/components/fiscal-operation-picker.tsx", + "resources/js/components/investment-budget-range.tsx", + "resources/js/components/investment-initial-budget.tsx", + "resources/js/components/investment-operating-assistance.tsx", + "resources/js/components/investment-opportunity-choices.tsx", + "resources/js/components/investment-profile-editor.tsx", + "resources/js/components/investment-promoter.tsx", + "resources/js/components/investment-supply-aggregate.tsx", + "resources/js/components/investment-territory.tsx", + "resources/js/components/opportunity-search-filters.tsx", + "resources/js/components/portal-hero.tsx", + "resources/js/components/public-document-content.tsx", + "resources/js/components/published-opportunities-empty.tsx", + "resources/js/components/sector-content.tsx", + "resources/js/components/simulation-business-plan.tsx", + "resources/js/components/simulation-cashflow-planner.tsx", + "resources/js/components/simulation-financial-tools.tsx", + "resources/js/components/simulation-form.tsx", + "resources/js/components/simulation-irpc-annual.tsx", + "resources/js/components/simulation-irpc-normal.tsx", + "resources/js/components/simulation-ispc-quarter.tsx", + "resources/js/components/simulation-miners.tsx", + "resources/js/components/simulation-modelo-a.tsx", + "resources/js/components/simulation-monthly-iva.tsx", + "resources/js/components/simulation-remission-imports.tsx", + "resources/js/components/simulation-returnees.tsx", + "resources/js/components/territorial-source-evidence.tsx", + "resources/js/hooks/use-interest-draft.ts", + "resources/js/lib/catalogue-choice.ts", + "resources/js/lib/catalogue-context.ts", + "resources/js/lib/company-preparation.ts", + "resources/js/lib/demographic-reading.ts", + "resources/js/lib/financial-calculators.ts", + "resources/js/lib/investment-operating-assistance.ts", + "resources/js/lib/investor-context.ts", + "resources/js/lib/investor-dossier-report.ts", + "resources/js/lib/investor-path.ts", + "resources/js/lib/monthly-cashflow.ts", + "resources/js/lib/monthly-iva.ts", + "resources/js/lib/navigation-focus.ts", + "resources/js/lib/planning-finance-context.ts", + "resources/js/lib/preparation-intent.ts", + "resources/js/lib/project-dossier-report.ts", + "resources/js/lib/simulation-api.ts", + "resources/js/lib/simulation-form.ts", + "resources/js/pages/funding/index.tsx", + "resources/js/pages/investment/catalogue.tsx", + "resources/js/pages/investment/company-comparison.tsx", + "resources/js/pages/investment/company-preparation.tsx", + "resources/js/pages/investment/demography.tsx", + "resources/js/pages/investment/profile.tsx", + "resources/js/pages/investor-path/context-start.tsx", + "resources/js/pages/investor-path/context.tsx", + "resources/js/pages/investor-path/show.tsx", + "resources/js/pages/portal/search.tsx", + "resources/js/pages/portfolio/show.tsx", + "resources/js/pages/structures/editor.tsx", + "routes/investor-path.php", + "tests/Feature/FundingCriteriaCoherenceTest.php", + "tests/Feature/InvestorIntentContinuityTest.php", + "tests/Feature/InvestorPromoterContinuityTest.php", + "tests/Fixtures/demography/barue-2026.json", + "tests/frontend/catalogue-context.test.mjs", + "tests/frontend/company-preparation.test.mjs", + "tests/frontend/demographic-reading.test.mjs", + "tests/frontend/financial-calculators.test.mjs", + "tests/frontend/financial-tools-source.test.mjs", + "tests/frontend/fiscal-operation-picker.test.mjs", + "tests/frontend/funding-journey-coherence.test.mjs", + "tests/frontend/helpers/investment-profile-editor.mjs", + "tests/frontend/interest-draft-storage.test.mjs", + "tests/frontend/investment-assistance-controls.test.mjs", + "tests/frontend/investment-assisted-journey.test.mjs", + "tests/frontend/investment-profile-editor.test.mjs", + "tests/frontend/investor-dossier-report.test.mjs", + "tests/frontend/navigation-context-integration.test.mjs", + "tests/frontend/navigation-focus.test.mjs", + "tests/frontend/planning-finance-context.test.mjs", + "tests/frontend/preparation-intent.test.mjs", + "tests/frontend/public-information.test.mjs", + "tests/frontend/simulation-form.test.mjs" + ], + "migration_changes": [], + "protected_offers_files": { + "app/Http/Controllers/OfferPublicCatalogueController.php": "04034126a52660e10a6e64207a3aa4fb09a9b03aee045383b240d434477f03ca", + "app/Http/Controllers/PrivateOfferOperationsController.php": "15da904c466be9bb38fa9a673beff55816026caf72569bc4289d399c77f10cce", + "app/Http/Controllers/PrivateOfferPreparationController.php": "32415ac61a948a0bd53f440c728b5e99522017d765910101eb1a7df1d8b6d0d7", + "app/Services/OfferAvailability.php": "72f975c8c01c7a3ccd3cc00d372210b3546dc6bbae1c34d91514b341a7968adf", + "app/Services/OfferPublicCatalogue.php": "7eee7ab9864cc29c2de90b071ff2c3bf3cac093d3adde9e1937ded324b2223c6", + "app/Services/OpportunityResources.php": "e8bcd6f4f5b994b466005aace3601fcfc642550d6ebda227c6de7a498f95f1b5", + "app/Services/PrivateOfferConfidentiality.php": "17e02925c3cfe26a4853db272b6d3c2acd1095efac826371a517a603eaa429ca", + "app/Services/PrivateOfferDetails.php": "1253c5d3cb9e3a2ae422f813afc4eb5ee8ed3859b07e15a3b32b678d3a97a015", + "app/Services/PrivateOfferOperations.php": "1b6032e96712f9d19befe76029a47464c3bb52e4f018d858dcc6f8e605cf0cdc", + "app/Services/PrivateOfferPreparation.php": "442d7aa1093001630bdfc581fde3b9f16e4b5b76a4e8d028ba4b3da41b1cfe4d", + "resources/js/components/interactive-investment-map.tsx": "3a59970e926736a2dfc11f962130f38cc9602a07d994a49fa2fc301a918d8c7d", + "resources/js/components/offer-confidential-access.tsx": "5723e5e8eda7500fe24670e7676749a4f36ad294bd284224cf7b6919675bddc1", + "resources/js/components/offer-editorial-review.tsx": "c519fb77848d8760ea88556184201fbaef27bbf7f9b00adefcff04de191ba81e", + "resources/js/components/offer-navigation.tsx": "4676f4859f7d378ebca988bc5436629f97c0004abe32af6db8a6b40789b48874", + "resources/js/components/offer-operations.tsx": "ce4a32b422c7a8e33dade2002b9565d53b4294c44f051ab06022fa6fcfc5ee4e", + "resources/js/components/offer-particulars.tsx": "ef78a2a493705b6f4828addd0227fc7e91f511a48b2c7b12fbbe35c610fe5de0", + "resources/js/components/offer-private-resources.tsx": "cb2070aeb4fd8ebe4eac28b41501223d2a87a2b1213538ab66c9520ab244d9c9", + "resources/js/components/opportunity-canonical-fields.tsx": "70bba90799e6057024f09fc32b85282c46002b6c8274b970fc80a48a79a20bf5", + "resources/js/lib/offer-editorial.ts": "dc70169aaa746b9ae8063b0312a6601d0347d2927a7c0f4bfc58cfc1f31aae99", + "resources/js/lib/offer-navigation.ts": "94ec55b7bbbc800f57fd10a9b51a49398c6cdd23fa0df635ca20e949426aef13", + "resources/js/lib/portal-navigation.ts": "4fb7cbf0a508cf0964e7ea0dd2023bc00202236bf048f228822d7de6e1f44534", + "resources/js/pages/offers/catalogue.tsx": "a17dd461a9a0e15bf1d8d182f5b0ef5687b9b0c8237ad2d4082701b08ad3bb47", + "resources/js/pages/offers/confidentiality.tsx": "b31d2cd72b55eaa9d04a3e7ff03fcb0d4a18696c403f89f5b791f9dc050c4d68", + "resources/js/pages/offers/preparation-index.tsx": "1cdfe52e4ed8311f52e24caab32d83dc7611213e5b9d3cc477b61c6e6c996276", + "resources/js/pages/offers/preparation.tsx": "7503946ba28e71ff48e6fd955b1ed587494678df433b6a13492dd026b74ce1de", + "resources/js/pages/offers/public-detail.tsx": "387c8a9a0013920bf74c85853362671d76131849508a9b86fc2391622cb0c647", + "resources/js/pages/offers/report.tsx": "91f9e32e88c82b1af984226ae81ede188fddaff395743905b8ab8ce483a8f859", + "routes/web.php": "50dbec32d17dbbd334298eb0bf77585b15d98781c9368fcb3f398642b83b2168" + }, + "protected_offers_identical": true, + "offers_excluded_reason": "Etapa B: criterios 5/6 comprovados HTTP; criterio 7 visual/mobile ainda NAO VERIFICADO. Aceitacao anterior 4/7 preservada.", + "shared_dependencies_review": { + "investment-territory": "Defaults unchanged: four levels and map enabled; optional funding-only props.", + "opportunity-search-filters": "Ofertas imports unchanged modalityLabels only.", + "demographic-context/evidence,territorial-source-evidence,dossier-navigation-context,investor-context": "Shared transversal presentation/context; no private Ofertas contract or permission changed." + }, + "verification": { + "frontend_tests": 142, + "frontend_failures": 0, + "wayfinder": "passed", + "build": "passed", + "types": "passed", + "accepted_transversal_steps": 15 + }, + "migrations": 0, + "permissions_changed": false, + "operational_data_changed": false +} \ No newline at end of file diff --git a/resources/js/components/acquisition-closure.tsx b/resources/js/components/acquisition-closure.tsx index b80e9d6c..0da66d42 100644 --- a/resources/js/components/acquisition-closure.tsx +++ b/resources/js/components/acquisition-closure.tsx @@ -71,12 +71,14 @@ export function AcquisitionClosure({ ); return (
- L3-A/B — crédito,fecho e pagamentos por período + + IVA — crédito, apuramento e valores documentados por período +

- Reutiliza resultados congelados de L2. Crédito anterior,saldo - calculado,pagamento registado e transporte são distintos. - Identifique o âmbito fiscal da entidade,sem consolidar - oportunidades implicitamente. + Reutiliza os resultados guardados das aquisições. Crédito + anterior, saldo calculado,pagamento registado e transporte são + distintos. Identifique o âmbito fiscal da entidade,sem + consolidar oportunidades implicitamente.

Primeira declaração em prazo,2026/MZN e reporte integral ou diff --git a/resources/js/components/catalogue-choice-select.tsx b/resources/js/components/catalogue-choice-select.tsx new file mode 100644 index 00000000..54bd58ed --- /dev/null +++ b/resources/js/components/catalogue-choice-select.tsx @@ -0,0 +1,70 @@ +import { useId, useState } from 'react'; +import TerritorySearchSelect from './territory-search-select'; +import { matchesChoice } from '@/lib/catalogue-choice'; + +export type CatalogueChoice = { + value: string; + label: string; + keywords?: string[]; +}; +export default function CatalogueChoiceSelect({ + options, + value, + onChange, + label, + id, + disabled = false, + required = false, + error, + className, +}: { + options: CatalogueChoice[]; + value: string; + onChange: (value: string) => void; + label: string; + id?: string; + disabled?: boolean; + required?: boolean; + error?: string; + className?: string; +}) { + const generated = useId(); + const [search, setSearch] = useState(''); + const selected = options.find((o) => o.value === value); + return ( + + matchesChoice(search, [ + o.value, + o.label, + ...(o.keywords ?? []), + ]), + ) + .map((o) => ({ id: o.value, name: o.label }))} + onChange={(o) => onChange(o?.id ?? '')} + disabled={disabled} + required={required} + error={error} + className={ + className ?? + 'bg-background text-foreground w-full rounded border p-2' + } + placeholder={`Seleccionar ou pesquisar ${label.toLowerCase()}`} + /> + ); +} diff --git a/resources/js/components/catalogue-navigation.tsx b/resources/js/components/catalogue-navigation.tsx index e768a50b..dcb37e04 100644 --- a/resources/js/components/catalogue-navigation.tsx +++ b/resources/js/components/catalogue-navigation.tsx @@ -21,7 +21,8 @@ export default function CatalogueNavigation({ dimensionUrl ) return dimensionUrl(u.searchParams.get('dimension')!); - if (context) u.searchParams.set('context', context); + if (context && ['/oportunidades', '/educacao'].includes(u.pathname)) + u.searchParams.set('context', context); return searchTerritoryHref(u.pathname + u.search, url); }; const sections = { diff --git a/resources/js/components/cluster-competitiveness-public.tsx b/resources/js/components/cluster-competitiveness-public.tsx index d43f4a90..e37f4529 100644 --- a/resources/js/components/cluster-competitiveness-public.tsx +++ b/resources/js/components/cluster-competitiveness-public.tsx @@ -1,5 +1,6 @@ import { forceLabels, forces } from '@/lib/cluster-competitiveness'; import type { CompetitivenessDraft } from '@/lib/cluster-competitiveness'; +import EvidenceDetails from './evidence-details'; export type ApprovedCompetitiveness = { draft: CompetitivenessDraft; @@ -27,9 +28,13 @@ export default function ClusterCompetitivenessPublic({ Competitividade — cinco forças de Porter

- {analysis.draft.sector} · {analysis.draft.region} · Versão - aprovada {analysis.version} · {analysis.at} + {analysis.draft.sector} · {analysis.draft.region}

+ +

+ Versão aprovada {analysis.version} · {analysis.at} +

+

Apreciação qualitativa fundamentada nas fontes e períodos indicados. Não representa garantia de procura ou viabilidade. @@ -55,14 +60,18 @@ export default function ClusterCompetitivenessPublic({ 'Oportunidade e fundamento', ], ] as const - ).map(([field, label]) => ( -

-
{label}
-
- {row[field]} -
-
- ))} + ) + .filter(([field]) => row[field]?.trim()) + .map(([field, label]) => ( +
+
+ {label} +
+
+ {row[field]} +
+
+ ))}
); diff --git a/resources/js/components/country-select.tsx b/resources/js/components/country-select.tsx index 39052de2..50732e4d 100644 --- a/resources/js/components/country-select.tsx +++ b/resources/js/components/country-select.tsx @@ -1,7 +1,5 @@ -import { useId, useState } from 'react'; - +import CatalogueChoiceSelect from './catalogue-choice-select'; export type Country = { code: string; name: string; name_en: string }; - export default function CountrySelect({ countries, value, @@ -10,7 +8,6 @@ export default function CountrySelect({ disabled = false, label = 'País', required = false, - allowLegacyValue = false, error, }: { countries: Country[]; @@ -23,77 +20,20 @@ export default function CountrySelect({ allowLegacyValue?: boolean; error?: string; }) { - 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 ( -
- setSearch(event.target.value)} - placeholder="Pesquisar nome ou código do país" - /> - {search.trim() && ( -

- Países:{' '} - {matches.length - ? `${matches.length} opções disponíveis` - : 'Nenhuma opção encontrada'} -

- )} - - {error && ( - - )} -
+ ({ + value: c.code, + label: `${c.name} — ${c.code}`, + keywords: [c.name_en, c.code], + }))} + value={value} + onChange={onChange} + id={id} + label={label} + disabled={disabled} + required={required} + error={error} + /> ); } diff --git a/resources/js/components/currency-select.tsx b/resources/js/components/currency-select.tsx new file mode 100644 index 00000000..31481fff --- /dev/null +++ b/resources/js/components/currency-select.tsx @@ -0,0 +1,24 @@ +import CatalogueChoiceSelect from './catalogue-choice-select'; +import { currencyChoices } from '@/lib/catalogue-choice'; +export default function CurrencySelect({ + codes, + ...props +}: { + codes?: readonly string[]; + value: string; + onChange: (value: string) => void; + label?: string; + id?: string; + disabled?: boolean; + required?: boolean; + error?: string; + className?: string; +}) { + return ( + + ); +} diff --git a/resources/js/components/demographic-context.tsx b/resources/js/components/demographic-context.tsx index 98968b7a..d6d88fd4 100644 --- a/resources/js/components/demographic-context.tsx +++ b/resources/js/components/demographic-context.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import DemographicEvidence, { type DemographicAnalysis, } from './demographic-evidence'; @@ -8,10 +8,17 @@ export default function DemographicContext({ }: { territoryId?: string | null; }) { + if (!territoryId) return null; + // A change of territory resets this consultation, never the investor's dossier. + return ; +} + +function TerritoryDemography({ territoryId }: { territoryId: string }) { const [evidence, setEvidence] = useState(null); const [message, setMessage] = useState(''); const [busy, setBusy] = useState(false); - if (!territoryId) return null; + const pending = useRef(null); + useEffect(() => () => pending.current?.abort(), []); return (
Demografia na análise de viabilidade @@ -26,20 +33,35 @@ export default function DemographicContext({ onClick={async () => { setBusy(true); setMessage(''); + setEvidence(null); + pending.current?.abort(); + const controller = new AbortController(); + pending.current = controller; try { const response = await fetch( - `/api/v1/investment/demography?territories[]=${encodeURIComponent(territoryId)}`, - { headers: { Accept: 'application/json' } }, + `/api/v1/investment/demography?investment_context=1&territories[]=${encodeURIComponent(territoryId)}`, + { + headers: { Accept: 'application/json' }, + signal: controller.signal, + }, ); if (!response.ok) throw new Error('Consulta indisponível.'); - setEvidence(await response.json()); + const result = await response.json(); + if (!controller.signal.aborted) { + setEvidence(result); + if (result.broader_context) + setMessage( + 'Contexto administrativo mais amplo. Estes indicadores não representam a população da localidade escolhida.', + ); + } } catch { + if (controller.signal.aborted) return; setMessage( 'Não foi possível consultar a evidência demográfica.', ); } finally { - setBusy(false); + if (!controller.signal.aborted) setBusy(false); } }} > diff --git a/resources/js/components/demographic-evidence.tsx b/resources/js/components/demographic-evidence.tsx index 8fe41603..b9aab369 100644 --- a/resources/js/components/demographic-evidence.tsx +++ b/resources/js/components/demographic-evidence.tsx @@ -1,4 +1,8 @@ +import EvidenceDetails from './evidence-details'; +import DemographicReadingSummary from './demographic-reading-summary'; + export type DemographicAnalysis = { + sector?: string; state: string; start_year: number; end_year: number; @@ -59,6 +63,24 @@ const indicators: Record = { fertility_rate: 'Fecundidade', population_growth_rate: 'Crescimento populacional', }; +type Value = + DemographicAnalysis['territories'][number]['series'][number]['values'][number]; +export function demographicHighlights(values: Value[]): Value[] { + const totals = values.filter( + (v) => v.age_group === 'all' && v.residence === 'all', + ); + // Never add age groups, choose between sources or mix observed/projected values. + return totals.filter( + (v) => + !totals.some( + (other) => + other.indicator === v.indicator && + other.unit === v.unit && + other.data_kind === v.data_kind && + other.year > v.year, + ), + ); +} export default function DemographicEvidence({ evidence, }: { @@ -66,8 +88,17 @@ export default function DemographicEvidence({ }) { return (
+

+ Os indicadores demográficos não demonstram procura ou + rentabilidade. Cruze-os com oferta existente, acessos, custos e + procura documentada. +

{evidence.state !== 'available' && ( -

Sem séries demográficas aprovadas para esta selecção.

+

+ Sem indicadores disponíveis para esta selecção. Isto não + significa população inexistente nem ausência de potencial + económico. +

)} {evidence.territories.map((t) => (
Sem dados no período escolhido.

)} {t.series.map((s) => ( -
- - {s.source} · {s.version} · {s.file_name} - -

- SHA256: {s.sha256} -

+
+

{s.source}

+ + {demographicHighlights(s.values).some( + (v) => v.indicator !== 'population', + ) && ( + <> +

+ Outros indicadores mais recentes do + período +

+
+ {demographicHighlights(s.values) + .filter( + (v) => + v.indicator !== + 'population', + ) + .map((v) => ( +
+
+ {indicators[ + v.indicator + ] ?? v.indicator}{' '} + · {v.year} +
+
+ {v.original_value}{' '} + {v.unit === + 'unspecified' + ? '(unidade não indicada)' + : v.unit} +
+
+ {v.data_kind === + 'projected' + ? 'Projecção' + : 'Tipo estatístico não especificado'} +
+ {v.validation_status !== + 'valid' && ( +
+ Valor com + advertência na + fonte; consulte o + detalhe antes de o + utilizar. +
+ )} +
+ ))} +
+ + )} {s.missing_years.length > 0 && (

Anos sem dados: {s.missing_years.join(', ')} + . Não foram preenchidos por estimativa.

)} - {Object.keys(s.issue_counts).length > 0 && ( -
- Advertências da série -
-                                        {JSON.stringify(
-                                            s.issue_counts,
-                                            null,
-                                            2,
-                                        )}
-                                    
-
+ {(Object.keys(s.issue_counts).length > 0 || + s.values.some( + (v) => v.validation_status !== 'valid', + )) && ( +

+ Esta série contém advertências. Consulte-as + antes de comparar ou utilizar os valores. +

)} -
- - - - - {[ - 'Ano', - 'Indicador', - 'Idade', - 'Residência', - 'Valor', - 'Unidade', - 'Tipo', - 'Referência', - ].map((h) => ( - - ))} - - - - {s.values.map((v) => ( - - - - - - - - - + +

+ {s.version} · {s.file_name} +

+

+ SHA256: {s.sha256} +

+ {Object.keys(s.issue_counts).length > 0 && ( +
+ Advertências da série +
+                                            {JSON.stringify(
+                                                s.issue_counts,
+                                                null,
+                                                2,
+                                            )}
+                                        
+
+ )} +
+
- Valores originais por ano e dimensão — - versões apresentadas separadamente -
- {h} -
- {v.year} - - {indicators[v.indicator] ?? - v.indicator} - - {v.age_group === 'all' - ? 'Todas' - : v.age_group} - - { - { - all: 'Total', - urban: 'Urbana', - rural: 'Rural', - }[v.residence] - } - {v.original_value} - {v.unit === 'unspecified' - ? 'Não indicada na fonte' - : v.unit} - - {v.data_kind === 'projected' - ? 'Projecção' - : 'Não especificado'} - - {v.sheet}!{v.cell} -
+ + + + {[ + 'Ano', + 'Indicador', + 'Idade', + 'Residência', + 'Valor', + 'Unidade', + 'Tipo', + 'Referência', + ].map((h) => ( + + ))} - ))} - -
+ Valores originais por ano e dimensão + — versões apresentadas separadamente +
+ {h} +
-
-
+ + + {s.values.map((v) => ( + + + {v.year} + + + {indicators[ + v.indicator + ] ?? v.indicator} + + + {v.age_group === 'all' + ? 'Todas' + : v.age_group} + + + { + { + all: 'Total', + urban: 'Urbana', + rural: 'Rural', + }[v.residence] + } + + {v.original_value} + + {v.unit === + 'unspecified' + ? 'Não indicada na fonte' + : v.unit} + + + {v.data_kind === + 'projected' + ? 'Projecção' + : 'Não especificado'} + + + {v.sheet}!{v.cell} + + + ))} + + + + +
))} ))} diff --git a/resources/js/components/demographic-reading-summary.tsx b/resources/js/components/demographic-reading-summary.tsx new file mode 100644 index 00000000..d09d3173 --- /dev/null +++ b/resources/js/components/demographic-reading-summary.tsx @@ -0,0 +1,159 @@ +import type { DemographicAnalysis } from './demographic-evidence'; +import { + demographicReading, + populationLabel, + percentageLabel, +} from '@/lib/demographic-reading'; +export default function DemographicReadingSummary({ + series, + evidence, +}: { + series: DemographicAnalysis['territories'][number]['series'][number]; + evidence: DemographicAnalysis; +}) { + const reading = demographicReading( + series, + evidence.start_year, + evidence.end_year, + ); + const current = reading.last; + const sector = evidence.sector ?? 'general'; + return ( +
+

+ Retrato da população · {evidence.end_year} +

+

+ {series.source} ·{' '} + {current.kind === 'projected' + ? 'Projecção' + : 'Tipo de dado não especificado'} + . Valores de apresentação arredondados; os originais permanecem + disponíveis abaixo. +

+
+ {[ + [ + 'População total', + populationLabel(current.total), + 'pessoas', + ], + [ + 'População rural', + populationLabel(current.rural), + percentageLabel(current.ruralShare) + ' do total', + ], + [ + 'Menores de 15 anos', + populationLabel(current.under15), + percentageLabel(current.under15Share) + ' do total', + ], + [ + 'População de 15 a 64 anos', + populationLabel(current.age15to64), + percentageLabel(current.age15to64Share) + ' do total', + ], + ].map(([label, value, note]) => ( +
+
{label}
+
{value}
+
{note}
+
+ ))} +
+ {evidence.start_year === evidence.end_year ? ( +

+ Está a consultar um único ano. Escolha um ano final + posterior para conhecer a evolução projectada. +

+ ) : ( +
+

+ Evolução entre {evidence.start_year} e{' '} + {evidence.end_year} +

+ {reading.delta === null ? ( +

+ Faltam totais comparáveis nos anos extremos; não foi + calculado crescimento. +

+ ) : ( +

+ {populationLabel(reading.first.total)} →{' '} + {populationLabel(reading.last.total)} pessoas. + Variação no período:{' '} + {populationLabel(reading.delta)} pessoas ( + {percentageLabel(reading.growth)}). Não é uma taxa + anual. +

+ )} +
+ Série anual de população +
+ + + + + + + + + + + {reading.years.map((y) => ( + + + + + + + ))} + +
AnoTotalUrbanaRural
{y.year}{populationLabel(y.total)}{populationLabel(y.urban)}{populationLabel(y.rural)}
+
+
+
+ )} +
+

+ Como usar estes dados na ideia de investimento +

+ {current.ruralShare !== null && ( +

+ {percentageLabel(current.ruralShare)} da população está + em áreas rurais. Para avaliar distribuição, comércio ou + serviços, confronte essa dispersão com acessos, + distâncias, custos de entrega e oferta existente. +

+ )} + {current.under15Share !== null && + ['general', 'education', 'health'].includes(sector) && ( +

+ Os menores de 15 anos representam{' '} + {percentageLabel(current.under15Share)} do total. É + uma base para estudar serviços educativos e de + saúde, cruzando população-alvo, capacidade + instalada, acessibilidade e rendimento das famílias. +

+ )} + {current.age15to64 !== null && ( +

+ As {populationLabel(current.age15to64)} pessoas entre 15 + e 64 anos ajudam a dimensionar a população nessa faixa + etária. Para planear contratações, faltam qualificações, + participação no mercado de trabalho e disponibilidade. +

+ )} +

+ Próximo passo: comparar estes indicadores com empresas e + serviços existentes, infra-estruturas, preços e procura + documentada. Só essa comparação permite fundamentar uma + lacuna de mercado. +

+
+
+ ); +} diff --git a/resources/js/components/dossier-navigation-context.tsx b/resources/js/components/dossier-navigation-context.tsx index 8a1e16ee..586cf8dd 100644 --- a/resources/js/components/dossier-navigation-context.tsx +++ b/resources/js/components/dossier-navigation-context.tsx @@ -7,6 +7,10 @@ import { type ReactNode, } from 'react'; import { contextApi, type DossierContext } from '@/lib/investor-context'; +import { + readNavigationFocus, + rememberNavigationFocus, +} from '@/lib/navigation-focus'; export type NavigationView = { case: { id: string; title: string; version: number }; phases: Record; @@ -129,7 +133,15 @@ export function NavigationContextProvider({ new URL(url, 'https://context.invalid').searchParams.get( 'context', ); - let focus = pref.focus; + const localFocus = readNavigationFocus( + actor, + listing.contexts.map((c) => c.id), + ); + // The server preference seeds a new tab, but another tab cannot + // replace this tab's deliberate dossier choice on navigation/reload. + let focus = localFocus + ? { ...localFocus, version: pref.focus?.version ?? 0 } + : pref.focus; const code = /^#S(0[1-9]|1[0-9])$/.test(window.location.hash) ? window.location.hash.slice(1) : null; @@ -157,6 +169,7 @@ export function NavigationContextProvider({ ) : null; if (!stopped) { + rememberNavigationFocus(actor, focus); setLoaded({ actor, cases: listing.contexts, focus, view }); if (pref.message) setError(pref.message); } @@ -182,16 +195,22 @@ export function NavigationContextProvider({ if (!actor || !current?.cases.some((c) => c.id === id)) return; setBusy(true); setError(''); - void contextApi( + void contextApi<{ focus: Focus | null }>( '/investimentos/contexto-atual', - { - case_id: id, - step_code: step, - version: current.focus?.version ?? 0, - }, - 'PUT', ) - .then(() => { + .then((pref) => + contextApi<{ focus: Focus }>( + '/investimentos/contexto-atual', + { + case_id: id, + step_code: step, + version: pref.focus?.version ?? 0, + }, + 'PUT', + ), + ) + .then(({ focus }) => { + rememberNavigationFocus(actor, focus); const target = `/investimentos/${id}${step ? '#' + step : ''}`; if (url !== target) router.visit(target); else setReload((x) => x + 1); diff --git a/resources/js/components/dossier-prefill.tsx b/resources/js/components/dossier-prefill.tsx index a85ed9ec..9806ed3f 100644 --- a/resources/js/components/dossier-prefill.tsx +++ b/resources/js/components/dossier-prefill.tsx @@ -32,7 +32,7 @@ const empty = (v: unknown) => v === '' || (Array.isArray(v) && v.length === 0); const text = (v: unknown) => - typeof v === 'string' ? v : JSON.stringify(v ?? ''); + empty(v) ? '' : typeof v === 'string' ? v : JSON.stringify(v); function savedOpportunity(values: Record): string { if (values.context_opportunity) return inputText(values.context_opportunity); diff --git a/resources/js/components/evidence-details.tsx b/resources/js/components/evidence-details.tsx new file mode 100644 index 00000000..7292871e --- /dev/null +++ b/resources/js/components/evidence-details.tsx @@ -0,0 +1,20 @@ +import type { ReactNode } from 'react'; + +/** Keep provenance available without making it the investor's primary content. */ +export default function EvidenceDetails({ + children, + title = 'Fontes e detalhes da informação', +}: { + children: ReactNode; + title?: string; +}) { + if (!children) return null; + return ( +
+ + {title} + +
{children}
+
+ ); +} diff --git a/resources/js/components/fiscal-l3-preparation.tsx b/resources/js/components/fiscal-l3-preparation.tsx index f764a94f..07cd86cf 100644 --- a/resources/js/components/fiscal-l3-preparation.tsx +++ b/resources/js/components/fiscal-l3-preparation.tsx @@ -14,7 +14,7 @@ export function FiscalL3Preparation({ if (!forms.length) return null; return (
- Preparação dos quadros L3 e formalidades + Correspondência documental e formalidades

Reutiliza entradas e resultados congelados. Os campos com correspondência identificada ficam preparados para diff --git a/resources/js/components/fiscal-operation-picker.tsx b/resources/js/components/fiscal-operation-picker.tsx new file mode 100644 index 00000000..11573b45 --- /dev/null +++ b/resources/js/components/fiscal-operation-picker.tsx @@ -0,0 +1,86 @@ +import type { ReactNode } from 'react'; +import CatalogueChoiceSelect from '@/components/catalogue-choice-select'; + +export default function FiscalOperationPicker({ + family, + selected, + operations, + onChange, +}: { + family: string; + selected: unknown; + operations: { + id: string; + label: string; + description: string; + render: () => ReactNode; + }[]; + onChange: (selected: string[]) => void; +}) { + const saved = Array.isArray(selected) + ? selected.filter((id): id is string => typeof id === 'string') + : []; + const chosen = operations.filter((operation) => + saved.includes(`${family}:${operation.id}`), + ); + return ( +

+

Operações que pretende analisar

+

+ Acrescente apenas as operações que prevê realizar. Se não sabe + se uma operação se aplica, consulte a orientação e conserve-a + por confirmar; o sector, por si só, não determina o + enquadramento. +

+ + !saved.includes(`${family}:${operation.id}`), + ) + .map((operation) => ({ + value: operation.id, + label: operation.label, + keywords: [operation.description], + }))} + onChange={(id) => { + if (operations.some((operation) => operation.id === id)) + onChange([...saved, `${family}:${id}`]); + }} + /> + {!chosen.length && ( +

+ Nenhuma operação adicional escolhida. As preparações e os + resultados anteriormente guardados permanecem no rascunho e + no histórico. +

+ )} + {chosen.map((operation) => ( +
+
{operation.label}
+

{operation.description}

+ + {operation.render()} +
+ ))} +
+ ); +} diff --git a/resources/js/components/investment-budget-range.tsx b/resources/js/components/investment-budget-range.tsx new file mode 100644 index 00000000..80e967ef --- /dev/null +++ b/resources/js/components/investment-budget-range.tsx @@ -0,0 +1,63 @@ +import CurrencySelect from './currency-select'; + +/** A planning interval is not the amount used in a financial calculation. */ +export default function InvestmentBudgetRange({ + values, + onChange, +}: { + values: Record; + onChange?: (field: string, value: string) => void; +}) { + if ( + !onChange && + !values.investment_budget_min && + !values.investment_budget_max + ) + return null; + return ( +
+

Orçamento previsto

+ {onChange ? ( + <> +
+ {( + [ + 'investment_budget_min', + 'investment_budget_max', + ] as const + ).map((field, index) => ( + + ))} +
+ onChange('currency', value)} + /> + + ) : ( +

+ {values.investment_budget_min || 'Mínimo por indicar'} –{' '} + {values.investment_budget_max || 'Máximo por indicar'}{' '} + {values.currency} +

+ )} +

+ Este intervalo orienta a preparação. O valor de cada cenário de + investimento será indicado por si no simulador. +

+
+ ); +} diff --git a/resources/js/components/investment-initial-budget.tsx b/resources/js/components/investment-initial-budget.tsx new file mode 100644 index 00000000..44c30894 --- /dev/null +++ b/resources/js/components/investment-initial-budget.tsx @@ -0,0 +1,159 @@ +import { useState } from 'react'; +import { sumFinancialAmounts } from '@/lib/financial-calculators'; +type Row = { label: string; amount: string }; +const initialRows = (): Row[] => + [ + 'Instalações', + 'Equipamentos', + 'Preparação e arranque', + 'Fundo de maneio inicial', + ].map((label) => ({ label, amount: '' })); +export function restoreInitialBudget(snapshot: string): Row[] { + try { + const parsed = JSON.parse(snapshot); + if ( + parsed.version === 1 && + Array.isArray(parsed.rows) && + parsed.rows.length <= 30 && + parsed.rows.every( + (row: Row) => + typeof row?.label === 'string' && + row.label.length <= 120 && + typeof row.amount === 'string' && + row.amount.length <= 40, + ) + ) + return parsed.rows; + } catch { + /* Preserve the saved original; no invented amounts. */ + } + return initialRows(); +} +export default function InvestmentInitialBudget({ + snapshot, + currency, + onChange, +}: { + snapshot: string; + currency: string; + onChange: (key: string, value: string) => void; +}) { + const [rows, setRows] = useState(() => restoreInitialBudget(snapshot)); + const [message, setMessage] = useState(''); + const save = (next: Row[]) => { + setRows(next); + setMessage(''); + onChange( + 'initial_budget_snapshot', + JSON.stringify({ version: 1, rows: next }), + ); + }; + return ( +
+

+ Ajuda para construir o investimento inicial +

+

+ Liste apenas os custos iniciais aplicáveis. O fundo de maneio + cobre o arranque; não repita aqui custos já incluídos noutra + parcela. Um valor desconhecido fica em branco, não é zero. +

+ {rows.map((row, index) => ( +
+ + + +
+ ))} + + + {message &&

{message}

} +
+ ); +} diff --git a/resources/js/components/investment-operating-assistance.tsx b/resources/js/components/investment-operating-assistance.tsx new file mode 100644 index 00000000..4e533228 --- /dev/null +++ b/resources/js/components/investment-operating-assistance.tsx @@ -0,0 +1,267 @@ +import { useState } from 'react'; +import { + estimateOperatingCosts, + estimateOperatingRevenue, + restoreOperatingAssumptions, +} from '@/lib/investment-operating-assistance'; + +export default function InvestmentOperatingAssistance({ + snapshot, + currency, + onChange, +}: { + snapshot: string; + currency: string; + onChange: (key: string, value: string) => void; +}) { + const [data, setData] = useState(() => + restoreOperatingAssumptions(snapshot), + ); + const [message, setMessage] = useState(''); + const save = (next: typeof data) => { + setData(next); + setMessage(''); + onChange( + 'planning_assumptions_snapshot', + JSON.stringify({ version: 1, data: next }), + ); + }; + const field = ( + key: 'capacity' | 'price' | 'occupancy' | 'frequency', + label: string, + ) => ( + + ); + const adopt = (kind: 'revenue' | 'costs') => { + try { + if (!currency) + throw new Error( + 'Seleccione a moeda do investimento antes de utilizar a estimativa.', + ); + const value = + kind === 'revenue' + ? estimateOperatingRevenue(data) + : estimateOperatingCosts(data); + onChange( + kind === 'revenue' + ? 'annual_revenue' + : 'annual_operating_costs', + value, + ); + setMessage( + `Estimativa anual de ${kind === 'revenue' ? 'receitas' : 'custos'} adoptada por sua escolha: ${value} ${currency}. Pode alterá-la nos campos acima.`, + ); + } catch (error) { + setMessage( + error instanceof Error + ? error.message + : 'Confira os pressupostos.', + ); + } + }; + return ( +
+

+ Não sei estimar receitas ou custos +

+

+ Escolha a actividade e introduza os pressupostos que conhece. + Não são previsões de procura nem valores recomendados. Nenhuma + estimativa substitui os seus valores até clicar em Usar. +

+ + {data.model && ( + <> +
+ {field( + 'capacity', + data.model === 'hotel' + ? 'Quartos disponíveis' + : 'Unidades vendáveis por ciclo ou período', + )} + {field( + 'price', + data.model === 'hotel' + ? 'Preço por quarto/noite' + : 'Preço por unidade', + )} + {data.model === 'hotel' && + field('occupancy', 'Ocupação prevista (%)')} + {field( + 'frequency', + data.model === 'hotel' + ? 'Dias de funcionamento previstos no ano' + : 'Ciclos ou períodos no ano', + )} +
+

+ {data.model === 'hotel' + ? 'Receita anual = quartos × dias de funcionamento × ocupação ÷ 100 × preço. Considere sazonalidade ao escolher a ocupação e os dias.' + : 'Receita anual = unidades vendáveis × preço × ciclos. Considere perdas e sazonalidade nas unidades e ciclos declarados.'}{' '} + A facturação não equivale a recebimentos; a próxima + etapa trata a tesouraria. +

+