diff --git a/api/blade-actions-surfaced.json b/api/blade-actions-surfaced.json index a2423e9a5..87e3e4751 100644 --- a/api/blade-actions-surfaced.json +++ b/api/blade-actions-surfaced.json @@ -1,5 +1,5 @@ { - "generated_at": "2026-04-20T14:30:02.246896", + "generated_at": "2026-04-20T14:35:01.654450", "stats": { "total": 26, "pending": 20, diff --git a/api/em-kpi-cache.json b/api/em-kpi-cache.json index e69de29bb..5d0e09a96 100644 --- a/api/em-kpi-cache.json +++ b/api/em-kpi-cache.json @@ -0,0 +1,281 @@ +{ + "ts": "2026-04-20T12:35:01+00:00", + "server": "s204", + "s204": { + "load": 2.16, + "uptime": "2026-04-14 11:51:24", + "ram_total_mb": 31335, + "ram_used_mb": 12356, + "ram_free_mb": 18978, + "disk_total": "150G", + "disk_used": "112G", + "disk_free": "33G", + "disk_pct": "78%", + "fpm_workers": 110, + "docker_containers": 19, + "cpu_cores": 8 + }, + "s95": { + "load": 0.68, + "disk_pct": "82%", + "status": "UP", + "ram_total_mb": 15610, + "ram_free_mb": 11199 + }, + "pmta": [ + { + "name": "SER6", + "ip": "110.239.84.121", + "status": "DOWN" + }, + { + "name": "SER7", + "ip": "110.239.65.64", + "status": "DOWN" + }, + { + "name": "SER8", + "ip": "182.160.55.107", + "status": "DOWN" + }, + { + "name": "SER9", + "ip": "110.239.86.68", + "status": "DOWN" + } + ], + "assets": { + "html_pages": 285, + "php_apis": 746, + "wiki_entries": 1798, + "vault_doctrines": 58, + "vault_sessions": 87, + "vault_decisions": 12 + }, + "tools": { + "total": 626, + "registry_version": "?" + }, + "sovereign": { + "status": "UP", + "providers": [ + "Cerebras-fast", + "Cerebras-think", + "Groq", + "Cloudflare-AI", + "Gemini", + "SambaNova", + "NVIDIA-NIM", + "Mistral", + "Groq-OSS", + "HF-Space", + "HF-Router", + "OpenRouter", + "GitHub-Models" + ], + "active": 13, + "total": 13, + "primary": "Cerebras-fast", + "cost": "0€" + }, + "ethica": { + "total_hcps": 161730, + "with_email": 110437, + "with_phone": 155145, + "gap_email": 51293, + "pct_email": 68.3, + "pct_phone": 95.9, + "by_country": [ + { + "country": "DZ", + "hcps": 122337, + "with_email": 78354, + "with_tel": 119394, + "pct_email": 64, + "pct_tel": 97.6 + }, + { + "country": "MA", + "hcps": 19720, + "with_email": 15066, + "with_tel": 18733, + "pct_email": 76.4, + "pct_tel": 95 + }, + { + "country": "TN", + "hcps": 17794, + "with_email": 15138, + "with_tel": 17018, + "pct_email": 85.1, + "pct_tel": 95.6 + }, + { + "country": "INTL", + "hcps": 1879, + "with_email": 1879, + "with_tel": 0, + "pct_email": 100, + "pct_tel": 0 + } + ] + }, + "docker": [ + { + "name": "loki", + "status": "Up 4 days", + "ports": "" + }, + { + "name": "listmonk", + "status": "Up 4 days", + "ports": "" + }, + { + "name": "plausible-plausible-1", + "status": "Up 2 days", + "ports": "" + }, + { + "name": "plausible-plausible-db-1", + "status": "Up 2 days", + "ports": "" + }, + { + "name": "plausible-plausible-events-db-1", + "status": "Up 2 days", + "ports": "" + }, + { + "name": "n8n-docker-n8n-1", + "status": "Up 4 days", + "ports": "" + }, + { + "name": "mattermost-docker-mm-db-1", + "status": "Up 4 days", + "ports": "" + }, + { + "name": "mattermost-docker-mattermost-1", + "status": "Up 4 days (healthy)", + "ports": "" + }, + { + "name": "twenty", + "status": "Up 4 days", + "ports": "" + }, + { + "name": "twenty-redis", + "status": "Up 4 days", + "ports": "" + }, + { + "name": "langfuse", + "status": "Up 4 days", + "ports": "" + }, + { + "name": "redis-weval", + "status": "Up 5 days", + "ports": "" + }, + { + "name": "gitea", + "status": "Up 5 days", + "ports": "" + }, + { + "name": "node-exporter", + "status": "Up 5 days", + "ports": "" + }, + { + "name": "prometheus", + "status": "Up 5 days", + "ports": "" + }, + { + "name": "searxng", + "status": "Up 5 days", + "ports": "" + }, + { + "name": "uptime-kuma", + "status": "Up 12 hours (healthy)", + "ports": "" + }, + { + "name": "vaultwarden", + "status": "Up 5 days (healthy)", + "ports": "" + }, + { + "name": "qdrant", + "status": "Up 5 days", + "ports": "" + } + ], + "crons": { + "active": 35 + }, + "git": { + "head": "d475e1213 auto-sync-1435", + "dirty": 2, + "status": "DIRTY" + }, + "nonreg": { + "total": 153, + "passed": 153, + "score": "100%" + }, + "services": [ + { + "name": "DeerFlow", + "port": 3002, + "status": "UP" + }, + { + "name": "DeerFlow API", + "port": 8001, + "status": "UP" + }, + { + "name": "Qdrant", + "port": 6333, + "status": "UP" + }, + { + "name": "Ollama", + "port": 11434, + "status": "UP" + }, + { + "name": "Redis", + "port": 6379, + "status": "UP" + }, + { + "name": "Sovereign", + "port": 4000, + "status": "UP" + }, + { + "name": "SearXNG", + "port": 8080, + "status": "UP" + } + ], + "whisper": { + "binary": "COMPILED", + "model": "142MB" + }, + "grand_total": 3532, + "health": { + "score": 5, + "max": 6, + "pct": 83 + }, + "elapsed_ms": 10641 +} \ No newline at end of file diff --git a/api/office-app.php b/api/office-app.php index 79fc1a818..682f10a39 100644 --- a/api/office-app.php +++ b/api/office-app.php @@ -206,7 +206,7 @@ if ($action === "intents_wired" || $action === "intents_list") { if (strpos($f, ".gold") !== false || strpos($f, ".GOLD") !== false) continue; $content = @file_get_contents($f); $trigs = []; - if (preg_match_all('/preg_match\(['"]([^'"]+)['"]/', $content, $mm)) { + if (preg_match_all('/preg_match\([\'"]([^\'"]+)[\'"]/', $content, $mm)) { $trigs = array_slice($mm[1], 0, 3); } $intents[] = [ @@ -222,15 +222,13 @@ if ($action === "intents_wired" || $action === "intents_list") { // ============================================================================ -// V34 — WORKFLOW ACTIONS (rapatrié depuis /office-workflow.php stale) -// Pointe S95 source of truth (10.1.0.3) via $pdo existant +// V34 WORKFLOW ACTIONS - rapatrie depuis office-workflow.php stale, pointe S95 // ============================================================================ -$STEP_NAMES = ['Register', 'Verify Email', 'DNS Setup', 'Domain Verify', 'Exchange Config', 'AntiSpam', 'Warmup', 'Live', 'Done']; +$STEP_NAMES = ["Register", "Verify Email", "DNS Setup", "Domain Verify", "Exchange Config", "AntiSpam", "Warmup", "Live", "Done"]; if ($action === "workflow_overview") { - $by_step = $pdo->query(" - SELECT current_step, COUNT(*) AS total, + $q = "SELECT current_step, COUNT(*) AS total, COUNT(*) FILTER (WHERE LOWER(status)='active') AS active, COUNT(*) FILTER (WHERE LOWER(status)='warming') AS warming, COUNT(*) FILTER (WHERE LOWER(status)='suspended') AS suspended, @@ -238,16 +236,13 @@ if ($action === "workflow_overview") { COUNT(*) FILTER (WHERE LOWER(status)='pending' OR status IS NULL) AS pending FROM admin.office_accounts WHERE current_step IS NOT NULL - GROUP BY current_step ORDER BY current_step - ")->fetchAll(PDO::FETCH_ASSOC); + GROUP BY current_step ORDER BY current_step"; + $by_step = $pdo->query($q)->fetchAll(PDO::FETCH_ASSOC); foreach ($by_step as &$row) { $idx = (int)$row["current_step"]; - $row["step_name"] = $STEP_NAMES[$idx] ?? ("step $idx"); + $row["step_name"] = $STEP_NAMES[$idx] ?? ("step " . $idx); } - $by_status = $pdo->query(" - SELECT COALESCE(LOWER(status), 'null') AS status, COUNT(*) AS n - FROM admin.office_accounts GROUP BY 1 ORDER BY 2 DESC - ")->fetchAll(PDO::FETCH_ASSOC); + $by_status = $pdo->query("SELECT COALESCE(LOWER(status), 'null') AS status, COUNT(*) AS n FROM admin.office_accounts GROUP BY 1 ORDER BY 2 DESC")->fetchAll(PDO::FETCH_ASSOC); $total = (int)$pdo->query("SELECT COUNT(*) FROM admin.office_accounts")->fetchColumn(); echo json_encode([ "ok" => true, @@ -318,24 +313,10 @@ if ($action === "workflow_setstatus" && $_SERVER["REQUEST_METHOD"] === "POST") { } if ($action === "workflow_steps_stats") { - // Workflow steps table state $ws_count = (int)$pdo->query("SELECT COUNT(*) FROM admin.office_workflow_steps")->fetchColumn(); $ws_accounts = (int)$pdo->query("SELECT COUNT(DISTINCT account_id) FROM admin.office_workflow_steps")->fetchColumn(); - $steps = $ws_count > 0 ? $pdo->query(" - SELECT step_name, COUNT(*) AS total, - COUNT(*) FILTER (WHERE status IN ('Complete','complete','Completed')) AS done, - COUNT(*) FILTER (WHERE status='Pending') AS pending, - COUNT(*) FILTER (WHERE status IN ('Failed','Error')) AS failed - FROM admin.office_workflow_steps GROUP BY step_name ORDER BY 2 DESC - ")->fetchAll(PDO::FETCH_ASSOC) : []; - echo json_encode([ - "ok" => true, - "workflow_steps_table" => [ - "total_steps" => $ws_count, - "unique_accounts" => $ws_accounts, - "by_step_name" => $steps - ] - ]); + $steps = $ws_count > 0 ? $pdo->query("SELECT step_name, COUNT(*) AS total FROM admin.office_workflow_steps GROUP BY step_name ORDER BY 2 DESC")->fetchAll(PDO::FETCH_ASSOC) : []; + echo json_encode(["ok" => true, "workflow_steps_table" => ["total_steps" => $ws_count, "unique_accounts" => $ws_accounts, "by_step_name" => $steps]]); exit; } diff --git a/api/v83-business-kpi-latest.json b/api/v83-business-kpi-latest.json index 987ee350b..7faeb2b5e 100644 --- a/api/v83-business-kpi-latest.json +++ b/api/v83-business-kpi-latest.json @@ -1,7 +1,7 @@ { "ok": true, "version": "V83-business-kpi", - "ts": "2026-04-20T12:35:00+00:00", + "ts": "2026-04-20T12:35:44+00:00", "summary": { "total_categories": 7, "total_kpis": 56, diff --git a/api/wired-pending/intent-opus4-wevia_contact_sales.php b/api/wired-pending/intent-opus4-wevia_contact_sales.php index 0be7cfd02..c4d6e4737 100644 --- a/api/wired-pending/intent-opus4-wevia_contact_sales.php +++ b/api/wired-pending/intent-opus4-wevia_contact_sales.php @@ -3,7 +3,7 @@ return array ( 'name' => 'wevia_contact_sales', 'triggers' => array ( - 0 => 'contact', + 0 => 'contact weval', 1 => 'commercial', 2 => 'sales contact', 3 => 'demo request', @@ -15,4 +15,5 @@ return array ( 'status' => 'EXECUTED', 'created_at' => '2026-04-19T17:23:52+00:00', 'source' => 'opus4-autowire-early-v2', + 'fix' => 'trigger contact → contact weval (doctrine #13 cause racine - 20avr)', ); diff --git a/office-app.html b/office-app.html index 15f218a9f..1ee80971c 100644 --- a/office-app.html +++ b/office-app.html @@ -365,6 +365,7 @@ + @@ -487,6 +488,69 @@ + + +
| STEP # | +NAME | +TOTAL | +ACTIVE | +WARMING | +PENDING | +BLOCKED | +% | +ACTIONS | +
|---|---|---|---|---|---|---|---|---|
| Click Load workflow | ||||||||