db()->query("SHOW TABLES LIKE 'radar_threads'")->getRowArray(); return !empty($row); } public function listExceptions(): array { return $this->db()->table('radar_exceptions') ->where('active', 1) ->orderBy('kind', 'ASC') ->orderBy('value', 'ASC') ->get() ->getResultArray(); } public function listThreads(): array { $rows = $this->db()->table('radar_threads') ->orderBy('received_at', 'DESC') ->orderBy('id', 'DESC') ->get() ->getResultArray(); if ($rows === []) { return []; } $ids = array_column($rows, 'id'); $skillRows = $this->db()->table('radar_thread_skills') ->whereIn('thread_id', $ids) ->get() ->getResultArray(); $byThread = []; foreach ($skillRows as $s) { $byThread[(int) $s['thread_id']][] = $s['skill']; } foreach ($rows as &$row) { $id = (int) $row['id']; $row['skills'] = $byThread[$id] ?? []; $row['client_url'] = !empty($row['client_id']) ? '/index.php/clients/form/' . (int) $row['client_id'] : ''; $row['projet_url'] = !empty($row['projet_id']) ? '/index.php/projets/form/' . (int) $row['projet_id'] : ''; } unset($row); return $rows; } /** * Insert ou met à jour un fil (dédup gmail_thread_id). Retourne insert|update. * * @param array $data * @param list $skills */ public function upsertThread(array $data, array $skills = []): string { $db = $this->db(); $existing = $db->table('radar_threads') ->where('gmail_thread_id', $data['gmail_thread_id']) ->get() ->getRowArray(); if ($existing) { $db->table('radar_threads') ->where('id', $existing['id']) ->update([ 'mailbox' => $data['mailbox'], 'subject' => $data['subject'], 'from_email' => $data['from_email'], 'from_name' => $data['from_name'], 'gmail_url' => $data['gmail_url'], 'summary' => $data['summary'], 'status' => $data['status'], 'confidence' => $data['confidence'], 'received_at' => $data['received_at'], 'is_example' => 0, ]); $threadId = (int) $existing['id']; $op = 'update'; } else { $db->table('radar_threads')->insert([ 'gmail_thread_id' => $data['gmail_thread_id'], 'mailbox' => $data['mailbox'], 'subject' => $data['subject'], 'from_email' => $data['from_email'], 'from_name' => $data['from_name'], 'gmail_url' => $data['gmail_url'], 'summary' => $data['summary'], 'status' => $data['status'], 'confidence' => $data['confidence'], 'is_example' => (int) ($data['is_example'] ?? 0), 'received_at' => $data['received_at'], 'proposed_client_no' => $data['proposed_client_no'] ?? '', ]); $threadId = (int) $db->insertID(); $op = 'insert'; } foreach ($skills as $skill) { $skill = strtolower(trim($skill)); if ($skill === '') { continue; } $exists = $db->table('radar_thread_skills') ->where('thread_id', $threadId) ->where('skill', $skill) ->countAllResults(); if ($exists === 0) { $db->table('radar_thread_skills')->insert([ 'thread_id' => $threadId, 'skill' => $skill, ]); } } return $op; } }