135 lines
4.2 KiB
PHP
135 lines
4.2 KiB
PHP
<?php
|
||
|
||
namespace App\Controllers;
|
||
|
||
use App\Libraries\Radar\RadarSyncService;
|
||
use App\Models\RadarModel;
|
||
use Config\Radar as RadarConfig;
|
||
|
||
/**
|
||
* IDEE-5 / MSOP-2 — proto écran Radar (CI4 / Raven).
|
||
* MSOP-4 — sync Gmail. MSOP-3 — analyse IA (route séparée).
|
||
*/
|
||
class Radar extends BaseController
|
||
{
|
||
public function index()
|
||
{
|
||
$model = new RadarModel();
|
||
$ready = $model->tablesExist();
|
||
$cfg = config(RadarConfig::class);
|
||
|
||
$syncMsg = session()->getFlashdata('radar_sync_msg');
|
||
if ($syncMsg === null || $syncMsg === '') {
|
||
$syncMsg = $this->request->getGet('sync_msg');
|
||
}
|
||
|
||
$pendingAi = 0;
|
||
if ($ready && $model->hasAnalysisColumns()) {
|
||
$pendingAi = $model->countThreadsNeedingDossardAnalysis();
|
||
}
|
||
|
||
return view('radar/index', [
|
||
'ready' => $ready,
|
||
'exceptions' => $ready ? $model->listExceptions() : [],
|
||
'threads' => $ready ? $model->listThreads() : [],
|
||
'feedUrl' => site_url('v4/radar/feed'),
|
||
'syncUrl' => site_url('v4/radar/sync'),
|
||
'analyzeUrl' => site_url('v4/radar/analyze'),
|
||
'pendingAi' => $pendingAi,
|
||
'allowlist' => $cfg->mailboxAllowlist,
|
||
'syncMsg' => is_string($syncMsg) ? $syncMsg : null,
|
||
]);
|
||
}
|
||
|
||
public function feed()
|
||
{
|
||
$model = new RadarModel();
|
||
if (! $model->tablesExist()) {
|
||
return $this->response->setJSON([
|
||
'ok' => false,
|
||
'threads' => [],
|
||
]);
|
||
}
|
||
|
||
return $this->response->setJSON([
|
||
'ok' => true,
|
||
'at' => date('c'),
|
||
'threads' => $model->listThreads(),
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* Sync Gmail → radar_* (rapide, sans LLM).
|
||
*/
|
||
public function sync()
|
||
{
|
||
$result = (new RadarSyncService())->sync();
|
||
|
||
if ($this->request->isAJAX() || $this->request->getGet('json') !== null) {
|
||
return $this->response->setJSON($result);
|
||
}
|
||
|
||
$msg = $result['ok'] ? 'Sync OK' : 'Sync en erreur';
|
||
if (! empty($result['error'])) {
|
||
$msg .= ' — ' . $result['error'];
|
||
}
|
||
foreach ($result['mailboxes'] as $row) {
|
||
if (! empty($row['ok'])) {
|
||
$msg .= sprintf(
|
||
' | %s: +%d / ~%d (lus %d)',
|
||
$row['mailbox'],
|
||
$row['inserted'] ?? 0,
|
||
$row['updated'] ?? 0,
|
||
$row['fetched'] ?? 0
|
||
);
|
||
} else {
|
||
$msg .= ' | ' . ($row['mailbox'] ?? '?') . ': ' . ($row['error'] ?? 'fail');
|
||
}
|
||
}
|
||
$msg .= ' — pour l’IA : bouton Analyser dossards';
|
||
|
||
return $this->redirectWithMsg($msg);
|
||
}
|
||
|
||
/**
|
||
* MSOP-3 — analyse IA des fils dossards en attente (peut prendre 1–2 min).
|
||
*/
|
||
public function analyze()
|
||
{
|
||
$result = (new RadarSyncService())->analyzePending();
|
||
|
||
if ($this->request->isAJAX() || $this->request->getGet('json') !== null) {
|
||
return $this->response->setJSON($result);
|
||
}
|
||
|
||
if (! empty($result['error'])) {
|
||
$msg = 'Analyse IA en erreur — ' . $result['error'];
|
||
} else {
|
||
$msg = sprintf(
|
||
'Analyse IA : %d fait(s), %d encore en attente [%s]',
|
||
(int) ($result['ran'] ?? 0),
|
||
(int) ($result['pending'] ?? 0),
|
||
(string) ($result['model'] ?? '')
|
||
);
|
||
if (! empty($result['errors'])) {
|
||
$msg .= ', ' . (int) $result['errors'] . ' erreur(s)';
|
||
}
|
||
if (! empty($result['note']) && (int) ($result['errors'] ?? 0) > 0) {
|
||
$msg .= ' (' . \mb_substr((string) $result['note'], 0, 120) . ')';
|
||
}
|
||
if ((int) ($result['pending'] ?? 0) > 0) {
|
||
$msg .= ' — recliquer Analyser pour continuer';
|
||
}
|
||
}
|
||
|
||
return $this->redirectWithMsg($msg);
|
||
}
|
||
|
||
private function redirectWithMsg(string $msg)
|
||
{
|
||
$q = rawurlencode(mb_substr($msg, 0, 800));
|
||
|
||
return redirect()->to(site_url('v4/radar') . '?sync_msg=' . $q)->with('radar_sync_msg', $msg);
|
||
}
|
||
}
|