workflow_state; $this->assertTransition((string) $collection->workflow_state, $nextWorkflow); $before = [ 'workflow_state' => $collection->workflow_state, 'program_key' => $collection->program_key, 'partner_key' => $collection->partner_key, 'experiment_key' => $collection->experiment_key, 'placement_eligibility' => (bool) $collection->placement_eligibility, ]; $collection->forceFill([ 'workflow_state' => $nextWorkflow !== '' ? $nextWorkflow : null, 'program_key' => array_key_exists('program_key', $attributes) ? ($attributes['program_key'] ?: null) : $collection->program_key, 'partner_key' => array_key_exists('partner_key', $attributes) ? ($attributes['partner_key'] ?: null) : $collection->partner_key, 'experiment_key' => array_key_exists('experiment_key', $attributes) ? ($attributes['experiment_key'] ?: null) : $collection->experiment_key, 'placement_eligibility' => array_key_exists('placement_eligibility', $attributes) ? (bool) $attributes['placement_eligibility'] : $collection->placement_eligibility, ])->save(); $fresh = $this->health->refresh($collection->fresh(), $actor, 'workflow'); app(CollectionHistoryService::class)->record( $fresh, $actor, 'workflow_updated', 'Collection workflow updated.', $before, [ 'workflow_state' => $fresh->workflow_state, 'program_key' => $fresh->program_key, 'partner_key' => $fresh->partner_key, 'experiment_key' => $fresh->experiment_key, 'placement_eligibility' => (bool) $fresh->placement_eligibility, ] ); return $fresh; } public function qualityRefresh(Collection $collection, ?User $actor = null): Collection { $collection = app(CollectionQualityService::class)->sync($collection->fresh()); $collection = $this->health->refresh($collection, $actor, 'quality-refresh'); $collection = app(CollectionRankingService::class)->refresh($collection); app(CollectionHistoryService::class)->record($collection, $actor, 'quality_refreshed', 'Collection quality and ranking refreshed.'); return $collection; } private function assertTransition(string $current, string $next): void { if ($next === '' || $next === $current) { return; } $allowed = [ '' => [Collection::WORKFLOW_DRAFT, Collection::WORKFLOW_APPROVED], Collection::WORKFLOW_DRAFT => [Collection::WORKFLOW_IN_REVIEW, Collection::WORKFLOW_APPROVED], Collection::WORKFLOW_IN_REVIEW => [Collection::WORKFLOW_DRAFT, Collection::WORKFLOW_APPROVED], Collection::WORKFLOW_APPROVED => [Collection::WORKFLOW_PROGRAMMED, Collection::WORKFLOW_ARCHIVED, Collection::WORKFLOW_IN_REVIEW], Collection::WORKFLOW_PROGRAMMED => [Collection::WORKFLOW_APPROVED, Collection::WORKFLOW_ARCHIVED], Collection::WORKFLOW_ARCHIVED => [Collection::WORKFLOW_APPROVED], ]; if (! in_array($next, $allowed[$current] ?? [], true)) { throw ValidationException::withMessages([ 'workflow_state' => 'This workflow transition is not allowed.', ]); } } }