where('id', $this->uploadId)->first(); if (! $upload || (string) $upload->status !== 'draft') { return; } $this->advanceProcessingState('scanning', ['pending_scan', 'scanning']); $files = DB::table('upload_files') ->where('upload_id', $this->uploadId) ->whereIn('type', ['main', 'screenshot']) ->get(['path']); foreach ($files as $file) { $path = (string) ($file->path ?? ''); if ($path === '' || ! Storage::disk('local')->exists($path)) { continue; } $absolute = Storage::disk('local')->path($path); $result = $scanner->scan($absolute); if (! $result->ok) { DB::table('uploads')->where('id', $this->uploadId)->update([ 'status' => 'rejected', 'processing_state' => 'rejected', 'updated_at' => now(), ]); Storage::disk('local')->deleteDirectory('tmp/drafts/' . $this->uploadId); return; } } DB::table('uploads')->where('id', $this->uploadId)->update([ 'is_scanned' => true, 'updated_at' => now(), ]); $this->advanceProcessingState('generating_preview', ['pending_scan', 'scanning', 'generating_preview']); PreviewGenerationJob::dispatch($this->uploadId); } /** * @param array $allowedCurrentStates */ private function advanceProcessingState(string $targetState, array $allowedCurrentStates): void { DB::table('uploads') ->where('id', $this->uploadId) ->where('status', 'draft') ->where(function ($query) use ($allowedCurrentStates): void { $query->whereNull('processing_state') ->orWhereIn('processing_state', $allowedCurrentStates); }) ->update([ 'processing_state' => $targetState, 'updated_at' => now(), ]); } }