TenantAtlas/apps/platform/app/Support/Navigation/CrossResourceNavigationMatrix.php
ahmido ce0615a9c1 Spec 182: relocate Laravel platform to apps/platform (#213)
## Summary
- move the Laravel application into `apps/platform` and keep the repository root for orchestration, docs, and tooling
- update the local command model, Sail/Docker wiring, runtime paths, and ignore rules around the new platform location
- add relocation quickstart/contracts plus focused smoke coverage for bootstrap, command model, routes, and runtime behavior

## Validation
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/PlatformRelocation`
- integrated browser smoke validated `/up`, `/`, `/admin`, `/admin/choose-workspace`, and tenant route semantics for `200`, `403`, and `404`

## Remaining Rollout Checks
- validate Dokploy build context and working-directory assumptions against the new `apps/platform` layout
- confirm web, queue, and scheduler processes all start from the expected working directory in staging/production
- verify no legacy volume mounts or asset-publish paths still point at the old root-level `public/` or `storage/` locations

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #213
2026-04-08 08:40:47 +00:00

83 lines
6.5 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Support\Navigation;
final class CrossResourceNavigationMatrix
{
public const string SURFACE_DETAIL_SECTION = 'detail_section';
public const string SURFACE_DETAIL_HEADER = 'detail_header';
public const string SURFACE_LIST_ROW = 'list_row';
public const string SOURCE_BACKUP_SET = 'backup_set';
public const string SOURCE_BASELINE_PROFILE = 'baseline_profile';
public const string SOURCE_BASELINE_SNAPSHOT = 'baseline_snapshot';
public const string SOURCE_FINDING = 'finding';
public const string SOURCE_OPERATION_RUN = 'operation_run';
public const string SOURCE_POLICY_VERSION = 'policy_version';
/**
* @return list<NavigationMatrixRule>
*/
public function rulesFor(string $sourceType, string $sourceSurface): array
{
return array_values(array_filter(
$this->rules(),
static fn (NavigationMatrixRule $rule): bool => $rule->sourceType === $sourceType
&& $rule->sourceSurface === $sourceSurface,
));
}
/**
* @return list<NavigationMatrixRule>
*/
private function rules(): array
{
return [
new NavigationMatrixRule(self::SOURCE_FINDING, self::SURFACE_DETAIL_SECTION, 'baseline_snapshot', 'baseline_snapshot', 'direct_record', 10, missingStatePolicy: 'show_reference_only'),
new NavigationMatrixRule(self::SOURCE_FINDING, self::SURFACE_DETAIL_SECTION, 'source_run', 'operation_run', 'canonical_page', 20, missingStatePolicy: 'show_reference_only'),
new NavigationMatrixRule(self::SOURCE_FINDING, self::SURFACE_DETAIL_SECTION, 'current_policy_version', 'policy_version', 'direct_record', 30, missingStatePolicy: 'show_reference_only'),
new NavigationMatrixRule(self::SOURCE_FINDING, self::SURFACE_DETAIL_SECTION, 'parent_policy', 'policy', 'direct_record', 40, missingStatePolicy: 'hide'),
new NavigationMatrixRule(self::SOURCE_FINDING, self::SURFACE_DETAIL_SECTION, 'baseline_profile', 'baseline_profile', 'direct_record', 50, missingStatePolicy: 'show_reference_only'),
new NavigationMatrixRule(self::SOURCE_FINDING, self::SURFACE_LIST_ROW, 'baseline_snapshot', 'baseline_snapshot', 'direct_record', 10, missingStatePolicy: 'hide'),
new NavigationMatrixRule(self::SOURCE_FINDING, self::SURFACE_LIST_ROW, 'source_run', 'operation_run', 'canonical_page', 20, missingStatePolicy: 'hide'),
new NavigationMatrixRule(self::SOURCE_POLICY_VERSION, self::SURFACE_DETAIL_SECTION, 'parent_policy', 'policy', 'direct_record', 10, missingStatePolicy: 'show_reference_only'),
new NavigationMatrixRule(self::SOURCE_POLICY_VERSION, self::SURFACE_DETAIL_SECTION, 'baseline_snapshot', 'baseline_snapshot', 'direct_record', 20, missingStatePolicy: 'hide'),
new NavigationMatrixRule(self::SOURCE_POLICY_VERSION, self::SURFACE_DETAIL_SECTION, 'baseline_profile', 'baseline_profile', 'direct_record', 30, missingStatePolicy: 'hide'),
new NavigationMatrixRule(self::SOURCE_POLICY_VERSION, self::SURFACE_DETAIL_SECTION, 'source_run', 'operation_run', 'canonical_page', 40, missingStatePolicy: 'hide'),
new NavigationMatrixRule(self::SOURCE_POLICY_VERSION, self::SURFACE_LIST_ROW, 'parent_policy', 'policy', 'direct_record', 10, missingStatePolicy: 'hide'),
new NavigationMatrixRule(self::SOURCE_POLICY_VERSION, self::SURFACE_LIST_ROW, 'baseline_snapshot', 'baseline_snapshot', 'direct_record', 20, missingStatePolicy: 'hide'),
new NavigationMatrixRule(self::SOURCE_BASELINE_SNAPSHOT, self::SURFACE_DETAIL_SECTION, 'baseline_profile', 'baseline_profile', 'direct_record', 10, missingStatePolicy: 'show_reference_only'),
new NavigationMatrixRule(self::SOURCE_BASELINE_SNAPSHOT, self::SURFACE_DETAIL_SECTION, 'source_run', 'operation_run', 'canonical_page', 20, missingStatePolicy: 'hide'),
new NavigationMatrixRule(self::SOURCE_BASELINE_SNAPSHOT, self::SURFACE_DETAIL_SECTION, 'policy_version', 'policy_version', 'direct_record', 30, missingStatePolicy: 'hide'),
new NavigationMatrixRule(self::SOURCE_BASELINE_SNAPSHOT, self::SURFACE_DETAIL_HEADER, 'baseline_profile', 'baseline_profile', 'direct_record', 10, missingStatePolicy: 'hide'),
new NavigationMatrixRule(self::SOURCE_BASELINE_SNAPSHOT, self::SURFACE_DETAIL_HEADER, 'source_run', 'operation_run', 'canonical_page', 20, missingStatePolicy: 'hide'),
new NavigationMatrixRule(self::SOURCE_BASELINE_SNAPSHOT, self::SURFACE_LIST_ROW, 'baseline_profile', 'baseline_profile', 'direct_record', 10, missingStatePolicy: 'hide'),
new NavigationMatrixRule(self::SOURCE_BACKUP_SET, self::SURFACE_DETAIL_SECTION, 'source_run', 'operation_run', 'canonical_page', 10, missingStatePolicy: 'hide'),
new NavigationMatrixRule(self::SOURCE_BACKUP_SET, self::SURFACE_DETAIL_SECTION, 'operations', 'operations', 'canonical_page', 20, missingStatePolicy: 'hide'),
new NavigationMatrixRule(self::SOURCE_BACKUP_SET, self::SURFACE_LIST_ROW, 'source_run', 'operation_run', 'canonical_page', 10, missingStatePolicy: 'hide'),
new NavigationMatrixRule(self::SOURCE_BACKUP_SET, self::SURFACE_LIST_ROW, 'operations', 'operations', 'canonical_page', 20, missingStatePolicy: 'hide'),
new NavigationMatrixRule(self::SOURCE_OPERATION_RUN, self::SURFACE_DETAIL_SECTION, 'backup_set', 'backup_set', 'direct_record', 10, missingStatePolicy: 'hide'),
new NavigationMatrixRule(self::SOURCE_OPERATION_RUN, self::SURFACE_DETAIL_SECTION, 'restore_run', 'restore_run', 'direct_record', 20, missingStatePolicy: 'hide'),
new NavigationMatrixRule(self::SOURCE_OPERATION_RUN, self::SURFACE_DETAIL_SECTION, 'baseline_profile', 'baseline_profile', 'direct_record', 30, missingStatePolicy: 'hide'),
new NavigationMatrixRule(self::SOURCE_OPERATION_RUN, self::SURFACE_DETAIL_SECTION, 'baseline_snapshot', 'baseline_snapshot', 'direct_record', 40, missingStatePolicy: 'hide'),
new NavigationMatrixRule(self::SOURCE_OPERATION_RUN, self::SURFACE_DETAIL_SECTION, 'parent_policy', 'policy', 'direct_record', 50, missingStatePolicy: 'hide'),
new NavigationMatrixRule(self::SOURCE_OPERATION_RUN, self::SURFACE_DETAIL_SECTION, 'operations', 'operations', 'canonical_page', 60, missingStatePolicy: 'hide'),
new NavigationMatrixRule(self::SOURCE_BASELINE_PROFILE, self::SURFACE_DETAIL_HEADER, 'baseline_snapshot', 'baseline_snapshot', 'direct_record', 10, missingStatePolicy: 'hide'),
];
}
}