id.':'.$kind.':'.($record->workflow_context['content_revision'] ?? 1); $existing = DB::table('tasks')->where('source_system', 'opportunity-workflow')->where('external_id', $key)->first(); if ($existing) { return $existing->id; } $id = (string) Str::uuid(); DB::table('tasks')->insert(['id' => $id, 'source_system' => 'opportunity-workflow', 'external_id' => $key, 'correlation_id' => $record->management_creation_key, 'task_type' => $kind, 'title' => $title, 'status' => 'open', 'due_at' => null, 'assignee_user_id' => null, 'data_classification' => 'restricted']); return $id; } public function assign(Opportunity $record, string $taskId, User $subject): void { abort_unless(DB::table('tasks')->where('id', $taskId)->where('source_system', 'opportunity-workflow') ->where('external_id', 'like', 'portal-opportunity:'.$record->id.':%')->whereIn('status', ['open', 'in_progress'])->exists(), 409, 'Tarefa não pertence à versão aberta.'); DB::table('tasks')->where('id', $taskId)->update(['assignee_user_id' => $subject->id, 'status' => 'in_progress', 'version_no' => DB::raw('version_no+1')]); } public function complete(?string $taskId, string $outcome): void { if ($taskId) { DB::table('tasks')->where('id', $taskId)->where('source_system', 'opportunity-workflow')->whereIn('status', ['open', 'in_progress']) ->update(['status' => 'done', 'outcome' => $outcome, 'completed_at' => now(), 'version_no' => DB::raw('version_no+1')]); } } /** @return list<\stdClass> */ public function listing(Opportunity $record): array { return array_values(DB::table('tasks')->where('source_system', 'opportunity-workflow')->where('external_id', 'like', 'portal-opportunity:'.$record->id.':%') ->get(['id', 'task_type', 'status', 'title', 'assignee_user_id', 'due_at', 'completed_at', 'outcome'])->all()); } }