targets(); if ($verifications->isEmpty()) { $this->info('Nenhuma verificacao para reconciliar.'); return self::SUCCESS; } $this->info("Verificacoes a reconciliar: {$verifications->count()}"); if ($this->option('dry-run')) { $this->table( ['id', 'session_id', 'status', 'usuario', 'iniciada em'], $verifications->map(fn (IdentityVerification $v) => [ $v->id, $v->session_id, $v->didit_status, $v->user_id, (string) $v->started_at, ])->all(), ); return self::SUCCESS; } $reconciled = 0; $unchanged = 0; $failed = 0; foreach ($verifications as $verification) { try { $decision = $this->sessionService->getDecision($verification->session_id); $status = (string) data_get($decision, 'status'); if ($status === '' || $status === $verification->didit_status) { $unchanged++; continue; } // Mesmo caminho do webhook: o payload real tambem traz o decision inteiro. $this->decisionService->handleWebhook([ 'session_id' => $verification->session_id, 'webhook_type' => 'status.updated', 'status' => $status, 'vendor_data' => (string) $verification->user_id, 'workflow_id' => $verification->workflow_id, 'decision' => $decision, ]); $this->line(" #{$verification->id} {$verification->didit_status} -> {$status}"); $reconciled++; } catch (Throwable $e) { $failed++; $this->error(" #{$verification->id}: {$e->getMessage()}"); Log::channel('didit')->error('Falha ao reconciliar sessao', [ 'session_id' => $verification->session_id, 'exception' => $e->getMessage(), ]); } } $this->newLine(); $this->info("Reconciliadas: {$reconciled} | sem mudanca: {$unchanged} | falhas: {$failed}"); return $failed > 0 ? self::FAILURE : self::SUCCESS; } // /** @return \Illuminate\Support\Collection */ private function targets() { $query = IdentityVerification::query(); if ($sessionId = $this->argument('session_id')) { return $query->where('session_id', $sessionId)->get(); } return $query ->whereIn('didit_status', ['Not Started', 'In Progress']) ->where('started_at', '<=', now()->subHours((int) $this->option('stale-hours'))) ->orderBy('started_at') ->limit((int) $this->option('limit')) ->get(); } }