fix(platform): resolve review and tenant review conflicts #314

Merged
ahmido merged 1 commits from platform-dev-session-1777625644 into platform-dev 2026-05-01 08:56:23 +00:00
3 changed files with 15 additions and 68 deletions
Showing only changes of commit b8b1d26a41 - Show all commits

View File

@ -8,12 +8,10 @@
use App\Models\EvidenceSnapshot; use App\Models\EvidenceSnapshot;
use App\Models\FindingException; use App\Models\FindingException;
use App\Models\Tenant; use App\Models\Tenant;
use App\Models\ReviewPack;
use App\Models\TenantReview; use App\Models\TenantReview;
use App\Models\User; use App\Models\User;
use App\Models\Workspace; use App\Models\Workspace;
use App\Services\Audit\WorkspaceAuditLogger; use App\Services\Audit\WorkspaceAuditLogger;
use App\Services\ReviewPackService;
use App\Services\TenantReviews\TenantReviewRegisterService; use App\Services\TenantReviews\TenantReviewRegisterService;
use App\Support\Audit\AuditActionId; use App\Support\Audit\AuditActionId;
use App\Support\Auth\Capabilities; use App\Support\Auth\Capabilities;
@ -21,7 +19,6 @@
use App\Support\Filament\TablePaginationProfiles; use App\Support\Filament\TablePaginationProfiles;
use App\Support\Governance\Controls\ComplianceEvidenceMappingV1; use App\Support\Governance\Controls\ComplianceEvidenceMappingV1;
use App\Support\Navigation\CanonicalNavigationContext; use App\Support\Navigation\CanonicalNavigationContext;
use App\Support\ReviewPackStatus;
use App\Support\Ui\ActionSurface\ActionSurfaceDeclaration; use App\Support\Ui\ActionSurface\ActionSurfaceDeclaration;
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceInspectAffordance; use App\Support\Ui\ActionSurface\Enums\ActionSurfaceInspectAffordance;
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceProfile; use App\Support\Ui\ActionSurface\Enums\ActionSurfaceProfile;
@ -180,11 +177,15 @@ public function table(Table $table): Table
->label(__('localization.review.recommended_next_action')) ->label(__('localization.review.recommended_next_action'))
->getStateUsing(fn (Tenant $record): string => $this->controlRecommendedNextAction($record)) ->getStateUsing(fn (Tenant $record): string => $this->controlRecommendedNextAction($record))
->wrap(), ->wrap(),
TextColumn::make('evidence_proof_state')
->label(__('localization.review.evidence_proof'))
->getStateUsing(fn (Tenant $record): string => $this->evidenceProofAvailability($record))
->wrap(),
TextColumn::make('published_at') TextColumn::make('published_at')
->label(__('localization.review.published')) ->label(__('localization.review.published'))
->getStateUsing(fn (Tenant $record): ?string => $this->latestPublishedAt($record)?->toDateTimeString()) ->getStateUsing(fn (Tenant $record): ?string => $this->latestPublishedAt($record)?->toDateTimeString())
->dateTime() ->dateTime()
->placeholder('—'), ->placeholder('—')
]) ])
->filters([ ->filters([
SelectFilter::make('tenant_id') SelectFilter::make('tenant_id')
@ -410,40 +411,6 @@ private function latestReviewUrl(Tenant $tenant): ?string
return $this->appendQuery(TenantReviewResource::tenantScopedUrl('view', ['record' => $review], $tenant, 'tenant'), $query); return $this->appendQuery(TenantReviewResource::tenantScopedUrl('view', ['record' => $review], $tenant, 'tenant'), $query);
} }
private function latestReviewPack(Tenant $tenant): ?ReviewPack
{
$review = $this->latestPublishedReview($tenant);
$pack = $review?->currentExportReviewPack;
return $pack instanceof ReviewPack ? $pack : null;
}
private function latestReviewPackDownloadUrl(Tenant $tenant): ?string
{
$user = auth()->user();
$pack = $this->latestReviewPack($tenant);
if (! $user instanceof User || ! $pack instanceof ReviewPack) {
return null;
}
if (! $user->can(Capabilities::REVIEW_PACK_VIEW, $tenant)) {
return null;
}
if ($pack->status !== ReviewPackStatus::Ready->value) {
return null;
}
if ($pack->expires_at !== null && $pack->expires_at->isPast()) {
return null;
}
return app(ReviewPackService::class)->generateDownloadUrl($pack, [
'source_surface' => self::SOURCE_SURFACE,
]);
}
private function latestPublishedAt(Tenant $tenant): ?\Illuminate\Support\Carbon private function latestPublishedAt(Tenant $tenant): ?\Illuminate\Support\Carbon
{ {
return $this->latestPublishedReview($tenant)?->published_at; return $this->latestPublishedReview($tenant)?->published_at;
@ -714,34 +681,6 @@ private function acceptedRiskSummary(Tenant $tenant): string
: $countSummary.' '.$accountability; : $countSummary.' '.$accountability;
} }
private function reviewPackAvailability(Tenant $tenant): string
{
if (! $this->latestPublishedReview($tenant) instanceof TenantReview) {
return __('localization.review.no_published_review_available');
}
$pack = $this->latestReviewPack($tenant);
$user = auth()->user();
if (! $pack instanceof ReviewPack) {
return __('localization.review.no_current_review_pack');
}
if (! $user instanceof User || ! $user->can(Capabilities::REVIEW_PACK_VIEW, $tenant)) {
return __('localization.review.review_pack_access_unavailable');
}
if ($pack->status !== ReviewPackStatus::Ready->value) {
return __('localization.review.review_pack_unavailable');
}
if ($pack->expires_at !== null && $pack->expires_at->isPast()) {
return __('localization.review.review_pack_expired');
}
return __('localization.review.review_pack_available');
}
private function evidenceProofAvailability(Tenant $tenant): string private function evidenceProofAvailability(Tenant $tenant): string
{ {
$review = $this->latestPublishedReview($tenant); $review = $this->latestPublishedReview($tenant);

View File

@ -206,7 +206,6 @@
'published_at' => now(), 'published_at' => now(),
'published_by_user_id' => (int) $user->getKey(), 'published_by_user_id' => (int) $user->getKey(),
])->save(); ])->save();
$this->actingAs($user); $this->actingAs($user);
setAdminPanelContext(); setAdminPanelContext();
session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);

View File

@ -14,7 +14,16 @@
$review = composeTenantReviewForTest($tenant, $user, $snapshot); $review = composeTenantReviewForTest($tenant, $user, $snapshot);
expect($review->evidence_snapshot_id)->toBe((int) $snapshot->getKey()) expect($review->evidence_snapshot_id)->toBe((int) $snapshot->getKey())
->and($review->sections)->toHaveCount(6) ->and($review->sections)->toHaveCount(7)
->and($review->sections->pluck('section_key')->all())->toBe([
'executive_summary',
'control_interpretation',
'open_risks',
'accepted_risks',
'permission_posture',
'baseline_drift_posture',
'operations_health',
])
->and($review->summary['evidence_basis']['snapshot_id'])->toBe((int) $snapshot->getKey()); ->and($review->summary['evidence_basis']['snapshot_id'])->toBe((int) $snapshot->getKey());
Finding::factory()->create([ Finding::factory()->create([