TenantAtlas/apps/platform/app/Services/TenantConfiguration/ExchangePowerShellEvidenceNormalizer.php
ahmido a09cc6ca8d Spec 435: Exchange structured output readiness (#502)
## Summary

- Add Spec 435 backend-only Exchange structured output envelope and target normalizer readiness helpers for transportRule, remoteDomain, and inboundConnector.
- Add deterministic hash input/readiness handling and no-promotion guard coverage.
- Add Spec 435 spec, plan, tasks, checklist, and implementation report artifacts.

## Validation

- git diff --cached --check
- cd apps/platform && php artisan test --filter=Spec435 --compact

## Product Surface / Deployment

- Livewire v4 compliance unchanged.
- Filament provider registration unchanged under apps/platform/bootstrap/providers.php.
- Global search unchanged; no resources added or modified.
- Destructive/high-impact actions: none.
- Asset strategy: none; no filament:assets requirement for this slice.
- Browser proof: N/A - no rendered UI surface changed.
- Deployment impact: no env vars, migrations, queues, scheduler, storage, assets, or Dokploy runtime behavior changes.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #502
2026-07-08 14:33:23 +00:00

55 lines
1.8 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Services\TenantConfiguration;
final class ExchangePowerShellEvidenceNormalizer
{
/**
* @var list<string>
*/
public const INCLUDED_TYPES = [
'transportRule',
'remoteDomain',
'inboundConnector',
];
public function __construct(
private readonly ExchangeTransportRuleEvidenceNormalizer $transportRules,
private readonly ExchangeRemoteDomainEvidenceNormalizer $remoteDomains,
private readonly ExchangeInboundConnectorEvidenceNormalizer $inboundConnectors,
) {}
public function evaluate(ExchangePowerShellStructuredOutputEnvelope $envelope): ExchangePowerShellNormalizerReadiness
{
return match ($envelope->resourceType) {
'transportRule' => $this->transportRules->evaluate($envelope),
'remoteDomain' => $this->remoteDomains->evaluate($envelope),
'inboundConnector' => $this->inboundConnectors->evaluate($envelope),
default => ExchangePowerShellNormalizerReadiness::blocked(
resourceType: $envelope->resourceType,
definition: [
'resource_type' => $envelope->resourceType,
'source_surface' => ExchangePowerShellCommandContracts::SOURCE_SURFACE,
'included_types' => self::INCLUDED_TYPES,
],
blockers: ['blocked_target_not_ready'],
itemCount: $envelope->itemCount,
),
};
}
/**
* @return array<string, array<string, mixed>>
*/
public function definitions(): array
{
return [
'transportRule' => $this->transportRules->definition(),
'remoteDomain' => $this->remoteDomains->definition(),
'inboundConnector' => $this->inboundConnectors->definition(),
];
}
}