TenantAtlas/apps/platform/app/Services/Baselines/CurrentStateHashResolver.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

93 lines
2.5 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Services\Baselines;
use App\Models\Tenant;
use App\Services\Baselines\Evidence\ContentEvidenceProvider;
use App\Services\Baselines\Evidence\MetaEvidenceProvider;
use App\Services\Baselines\Evidence\ResolvedEvidence;
use Carbon\CarbonImmutable;
final class CurrentStateHashResolver
{
/**
* @var list<CurrentStateEvidenceProvider>
*/
private readonly array $providers;
public function __construct(
ContentEvidenceProvider $contentEvidenceProvider,
MetaEvidenceProvider $metaEvidenceProvider,
) {
$this->providers = [
$contentEvidenceProvider,
$metaEvidenceProvider,
];
}
/**
* Resolve best-available current-state evidence per subject using the ordered provider chain.
*
* First-non-null wins.
*
* @param list<array{policy_type: string, subject_external_id: string}> $subjects
* @return array<string, ResolvedEvidence|null> keyed by "policy_type|subject_external_id"
*/
public function resolveForSubjects(
Tenant $tenant,
array $subjects,
?CarbonImmutable $since = null,
?int $latestInventorySyncRunId = null,
): array {
$results = [];
$unresolved = [];
foreach ($subjects as $subject) {
$policyType = trim((string) ($subject['policy_type'] ?? ''));
$externalId = trim((string) ($subject['subject_external_id'] ?? ''));
if ($policyType === '' || $externalId === '') {
continue;
}
$key = $policyType.'|'.$externalId;
if (array_key_exists($key, $results)) {
continue;
}
$results[$key] = null;
$unresolved[$key] = [
'policy_type' => $policyType,
'subject_external_id' => $externalId,
];
}
foreach ($this->providers as $provider) {
if ($unresolved === []) {
break;
}
$resolved = $provider->resolve(
tenant: $tenant,
subjects: array_values($unresolved),
since: $since,
latestInventorySyncRunId: $latestInventorySyncRunId,
);
foreach ($resolved as $key => $evidence) {
if (! array_key_exists($key, $unresolved)) {
continue;
}
$results[$key] = $evidence;
unset($unresolved[$key]);
}
}
return $results;
}
}