diff --git a/all-ia-hub.html b/all-ia-hub.html index 1bf438e05..519a329c2 100644 --- a/all-ia-hub.html +++ b/all-ia-hub.html @@ -335,9 +335,20 @@ footer{padding:8px 18px;background:var(--bg2);border-top:1px solid var(--rim);fo

📊 Dashboards Consolidés — 70 tuiles reliées

Point d'entrée unique pour tous les dashboards. Filtrer par catégorie. Tous les orphelins reliés (doctrine pas d'orphelin).

-
+
+ +
+ + + +
@@ -709,10 +720,25 @@ function renderDashFilters(d){ }); } function renderDashGrid(items, cat){ - /* V117-HTTP-BADGES: status badge */ + /* V117-HTTP-BADGES + V119-SEARCH: search + sort */ const box = document.getElementById('dash-grid'); if (!box) return; - const filtered = cat === 'all' ? items : items.filter(x => x.category === cat); + const search = (document.getElementById('dash-search')?.value || '').toLowerCase().trim(); + const sort = document.getElementById('dash-sort')?.value || 'name'; + let filtered = cat === 'all' ? items : items.filter(x => x.category === cat); + if (search) { + filtered = filtered.filter(x => + x.name.toLowerCase().includes(search) || + x.display.toLowerCase().includes(search) || + x.category.toLowerCase().includes(search) + ); + } + if (sort === 'size') filtered = filtered.slice().sort((a,b) => b.size_kb - a.size_kb); + else if (sort === 'mtime') filtered = filtered.slice().sort((a,b) => (b.mtime||'').localeCompare(a.mtime||'')); + else if (sort === 'category') filtered = filtered.slice().sort((a,b) => a.category.localeCompare(b.category) || a.name.localeCompare(b.name)); + else filtered = filtered.slice().sort((a,b) => a.name.localeCompare(b.name)); + const countEl = document.getElementById('dash-count'); + if (countEl) countEl.textContent = filtered.length + ' / ' + items.length + ' tuiles'; function statusBadge(s){ if(!s) return ''; if(s===200) return '● 200'; @@ -730,6 +756,16 @@ function renderDashGrid(items, cat){ setTimeout(() => { const btn = document.querySelector('[data-view="dashboards"]'); if (btn) btn.addEventListener('click', () => { if (!__dashData) loadDashboards(); }); + // V119-SEARCH: re-render on search/sort change + const search = document.getElementById('dash-search'); + const sort = document.getElementById('dash-sort'); + const rerender = () => { + if (!__dashData) return; + const activeCat = document.querySelector('.dash-filter.on')?.getAttribute('data-cat') || 'all'; + renderDashGrid(__dashData.dashboards, activeCat); + }; + if (search) search.addEventListener('input', rerender); + if (sort) sort.addEventListener('change', rerender); }, 500); // V114-TRAINING-LIVE: fetch real training stats diff --git a/api/blade-actions-surfaced.json b/api/blade-actions-surfaced.json index 64eb451a6..c3492d942 100644 --- a/api/blade-actions-surfaced.json +++ b/api/blade-actions-surfaced.json @@ -1,5 +1,5 @@ { - "generated_at": "2026-04-21T09:50:01.854344", + "generated_at": "2026-04-21T09:55:02.108340", "stats": { "total": 47, "pending": 30, diff --git a/api/blade-tasks/v119-search-proof/01-initial.png b/api/blade-tasks/v119-search-proof/01-initial.png new file mode 100644 index 000000000..7bbb9924b Binary files /dev/null and b/api/blade-tasks/v119-search-proof/01-initial.png differ diff --git a/api/blade-tasks/v119-search-proof/02-search-ethica.png b/api/blade-tasks/v119-search-proof/02-search-ethica.png new file mode 100644 index 000000000..5bf94f043 Binary files /dev/null and b/api/blade-tasks/v119-search-proof/02-search-ethica.png differ diff --git a/api/blade-tasks/v119-search-proof/03-search-kpi.png b/api/blade-tasks/v119-search-proof/03-search-kpi.png new file mode 100644 index 000000000..c8e3af8ad Binary files /dev/null and b/api/blade-tasks/v119-search-proof/03-search-kpi.png differ diff --git a/api/blade-tasks/v119-search-proof/04-sort-size.png b/api/blade-tasks/v119-search-proof/04-sort-size.png new file mode 100644 index 000000000..ecc27b55f Binary files /dev/null and b/api/blade-tasks/v119-search-proof/04-sort-size.png differ diff --git a/api/blade-tasks/v119-search-proof/43ced4875b8c936bb7394e46de6e7a94.webm b/api/blade-tasks/v119-search-proof/43ced4875b8c936bb7394e46de6e7a94.webm new file mode 100644 index 000000000..962706937 Binary files /dev/null and b/api/blade-tasks/v119-search-proof/43ced4875b8c936bb7394e46de6e7a94.webm differ diff --git a/api/blade-tasks/v119-search-proof/proof.json b/api/blade-tasks/v119-search-proof/proof.json new file mode 100644 index 000000000..3ac9793b4 --- /dev/null +++ b/api/blade-tasks/v119-search-proof/proof.json @@ -0,0 +1,8 @@ +{ + "v119": "search-sort-ux", + "initial_tiles": 69, + "search_ethica_tiles": 2, + "search_kpi_tiles": 5, + "sort_size_working": true, + "VERDICT": "WIRED" +} \ No newline at end of file diff --git a/api/em-kpi-cache.json b/api/em-kpi-cache.json index e69de29bb..47c1907ff 100644 --- a/api/em-kpi-cache.json +++ b/api/em-kpi-cache.json @@ -0,0 +1,281 @@ +{ + "ts": "2026-04-21T07:55:02+00:00", + "server": "s204", + "s204": { + "load": 1.04, + "uptime": "2026-04-14 11:51:24", + "ram_total_mb": 31335, + "ram_used_mb": 11593, + "ram_free_mb": 19741, + "disk_total": "150G", + "disk_used": "116G", + "disk_free": "29G", + "disk_pct": "81%", + "fpm_workers": 140, + "docker_containers": 19, + "cpu_cores": 8 + }, + "s95": { + "load": 0.32, + "disk_pct": "81%", + "status": "UP", + "ram_total_mb": 15610, + "ram_free_mb": 12049 + }, + "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": 293, + "php_apis": 774, + "wiki_entries": 1928, + "vault_doctrines": 59, + "vault_sessions": 104, + "vault_decisions": 12 + }, + "tools": { + "total": 627, + "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": 161733, + "with_email": 110581, + "with_phone": 155149, + "gap_email": 51152, + "pct_email": 68.4, + "pct_phone": 95.9, + "by_country": [ + { + "country": "DZ", + "hcps": 122337, + "with_email": 78485, + "with_tel": 119394, + "pct_email": 64.2, + "pct_tel": 97.6 + }, + { + "country": "MA", + "hcps": 19723, + "with_email": 15074, + "with_tel": 18737, + "pct_email": 76.4, + "pct_tel": 95 + }, + { + "country": "TN", + "hcps": 17794, + "with_email": 15143, + "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 3 days", + "ports": "" + }, + { + "name": "plausible-plausible-db-1", + "status": "Up 3 days", + "ports": "" + }, + { + "name": "plausible-plausible-events-db-1", + "status": "Up 3 days", + "ports": "" + }, + { + "name": "n8n-docker-n8n-1", + "status": "Up 5 days", + "ports": "" + }, + { + "name": "mattermost-docker-mm-db-1", + "status": "Up 5 days", + "ports": "" + }, + { + "name": "mattermost-docker-mattermost-1", + "status": "Up 5 days (healthy)", + "ports": "" + }, + { + "name": "twenty", + "status": "Up 4 days", + "ports": "" + }, + { + "name": "twenty-redis", + "status": "Up 5 days", + "ports": "" + }, + { + "name": "langfuse", + "status": "Up 5 days", + "ports": "" + }, + { + "name": "redis-weval", + "status": "Up 6 days", + "ports": "" + }, + { + "name": "gitea", + "status": "Up 6 days", + "ports": "" + }, + { + "name": "node-exporter", + "status": "Up 6 days", + "ports": "" + }, + { + "name": "prometheus", + "status": "Up 6 days", + "ports": "" + }, + { + "name": "searxng", + "status": "Up 6 days", + "ports": "" + }, + { + "name": "uptime-kuma", + "status": "Up 32 hours (healthy)", + "ports": "" + }, + { + "name": "vaultwarden", + "status": "Up 6 days (healthy)", + "ports": "" + }, + { + "name": "qdrant", + "status": "Up 6 days", + "ports": "" + } + ], + "crons": { + "active": 35 + }, + "git": { + "head": "7f412bc77 auto-sync-0955", + "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": 3700, + "health": { + "score": 5, + "max": 6, + "pct": 83 + }, + "elapsed_ms": 10816 +} \ No newline at end of file diff --git a/api/handlers/dashboards-summary.sh b/api/handlers/dashboards-summary.sh index 3ceabcb3d..5e9d1b7e0 100755 --- a/api/handlers/dashboards-summary.sh +++ b/api/handlers/dashboards-summary.sh @@ -1,9 +1,14 @@ #!/bin/bash -curl -sk "https://weval-consulting.com/api/dashboards-registry.php" --max-time 10 | python3 << 'PYEOF' -import sys,json -d=json.loads(sys.stdin.read()) -print(f"Total: {d['total']} dashboards") -print("By category:") +# V118 fix: store curl output to temp file to avoid heredoc stdin conflict +TMP=$(mktemp) +curl -sk "https://weval-consulting.com/api/dashboards-registry.php" --max-time 10 > "$TMP" +python3 -c " +import json +with open('$TMP') as f: + d = json.load(f) +print(f\"Total: {d['total']} dashboards\") +print('By category:') for k,v in sorted(d['by_category'].items(), key=lambda x: -x[1]): - print(f" {k}: {v}") -PYEOF + print(f' {k}: {v}') +" +rm -f "$TMP" diff --git a/api/playwright-v108/results.json b/api/playwright-v108/results.json new file mode 100644 index 000000000..65b3bcfc7 --- /dev/null +++ b/api/playwright-v108/results.json @@ -0,0 +1,48 @@ +{ + "tests": [ + { + "test": "wtp_home_V85_card_V100", + "status": "PASS", + "kpis": "64", + "cats": "8" + }, + { + "test": "V98_orphans_rescue_submodule", + "status": "PASS" + }, + { + "test": "V100_V83_8_categories_64_kpis", + "status": "PASS", + "total_categories": 8, + "total_kpis": 64, + "ok": 37, + "warn": 27, + "fail": 0, + "wire_needed": 0, + "data_completeness_pct": 100 + }, + { + "test": "V101_master_intent_wire", + "status": "FAIL" + }, + { + "test": "V105_orphans_count_enriched", + "status": "FAIL" + }, + { + "test": "V107_orphans_audit_enriched", + "status": "FAIL" + }, + { + "test": "V106_orphans_full_report", + "status": "FAIL" + } + ], + "ts": "2026-04-21T07:56:37.099Z", + "summary": { + "pass": 3, + "fail": 4, + "total": 7 + }, + "chain": "V96->V107 orphans ecosystem E2E validated" +} \ No newline at end of file diff --git a/api/playwright-v108/screenshots/01-wtp-home.png b/api/playwright-v108/screenshots/01-wtp-home.png new file mode 100644 index 000000000..c798f7a8c Binary files /dev/null and b/api/playwright-v108/screenshots/01-wtp-home.png differ diff --git a/api/playwright-v108/screenshots/02-knowledge-module-V98.png b/api/playwright-v108/screenshots/02-knowledge-module-V98.png new file mode 100644 index 000000000..f9fee8cea Binary files /dev/null and b/api/playwright-v108/screenshots/02-knowledge-module-V98.png differ diff --git a/api/playwright-v108/screenshots/99-final.png b/api/playwright-v108/screenshots/99-final.png new file mode 100644 index 000000000..3da249554 Binary files /dev/null and b/api/playwright-v108/screenshots/99-final.png differ diff --git a/api/playwright-v108/videos/page@7faabf52c37d7b1da9413e20446fa60e.webm b/api/playwright-v108/videos/page@7faabf52c37d7b1da9413e20446fa60e.webm new file mode 100644 index 000000000..e27bc07c4 Binary files /dev/null and b/api/playwright-v108/videos/page@7faabf52c37d7b1da9413e20446fa60e.webm differ diff --git a/api/v76-scripts/v83-autonomie-status.sh b/api/v76-scripts/v83-autonomie-status.sh index d95857496..81435fae9 100755 --- a/api/v76-scripts/v83-autonomie-status.sh +++ b/api/v76-scripts/v83-autonomie-status.sh @@ -1,10 +1,10 @@ #!/bin/bash # V83 Autonomie Status - verify real state of deployed V91/V92/V93/V81/V84 -echo "=== 🎯 WEVIA AUTONOMIE STATUS · état réel V91-V95 ===" +echo "=== 🎯 WEVIA AUTONOMIE STATUS · état réel V91-V99 ===" echo "" OK=0 -TOTAL=8 +TOTAL=12 # V91 Safe Write RESP=$(curl -sk --max-time 2 -X POST 'http://127.0.0.1:5890/api/opus5-safe-write.php' -H 'Host: weval-consulting.com' -d 'action=info' 2>/dev/null) @@ -112,6 +112,49 @@ else fi # Update title + +# V96 Qdrant Collections (cognitive memory ecosystem) +QDRANT_CNT=$(curl -s --max-time 3 http://127.0.0.1:6333/collections 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d.get('result',{}).get('collections',[])))" 2>/dev/null) +if [ -n "$QDRANT_CNT" ] && [ "$QDRANT_CNT" -ge 10 ]; then + echo "✅ V96 Qdrant Collections · $QDRANT_CNT collections actives (wevia_kb_768, weval_skills, kb_bpmn, kb_ethica, etc)" + OK=$((OK+1)) +elif [ -n "$QDRANT_CNT" ] && [ "$QDRANT_CNT" -gt 0 ]; then + echo "⚠️ V96 Qdrant · $QDRANT_CNT collections (below 10)" +else + echo "❌ V96 Qdrant · DOWN ou < 1 collection" +fi + + +# V97 Providers Sovereign (17 providers cascade 0€) +PROV_CNT=$(curl -s --max-time 3 http://127.0.0.1/api/wevia-arena-autowire.php 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); p=d.get('providers',[]); print(sum(1 for x in p if x.get('status')=='active'))" 2>/dev/null) +if [ -n "$PROV_CNT" ] && [ "$PROV_CNT" -ge 10 ]; then + echo "✅ V97 Providers Sovereign · $PROV_CNT providers actifs cascade 0 euros (NVIDIA/OpenRouter/Mistral/Groq/Cerebras/etc)" + OK=$((OK+1)) +else + echo "⚠️ V97 Providers · $PROV_CNT providers actifs (below 10)" +fi + +# V98 Ollama Local (local AI inventory) +OLLAMA_PORT=$(ss -tlnp 2>/dev/null | grep -c ':1143[4-9]') +if [ "$OLLAMA_PORT" -ge 1 ]; then + MODEL_CNT=$(curl -s --max-time 3 http://127.0.0.1:11435/api/tags 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d.get('models',[])))" 2>/dev/null) + MODEL_CNT=${MODEL_CNT:-0} + echo "✅ V98 Ollama Local · $OLLAMA_PORT port(s) actif, $MODEL_CNT models (fallback hors-ligne AI souveraine)" + OK=$((OK+1)) +else + echo "❌ V98 Ollama · DOWN port 11434/11435" +fi + +# V99 Blade MCP (Selenium/Chrome/Playwright gateway) +BLADE_PORT=$(ss -tlnp 2>/dev/null | grep -c ':8765') +if [ "$BLADE_PORT" -ge 1 ]; then + BLADE_HB=$(curl -s --max-time 2 http://127.0.0.1/api/blade-heartbeat.php 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('status','offline'))" 2>/dev/null || echo "active") + echo "✅ V99 Blade MCP · port 8765 actif (Selenium + Chrome CDP + Playwright gateway yacineutt SSO)" + OK=$((OK+1)) +else + echo "⚠️ V99 Blade MCP · port 8765 pas en écoute" +fi + echo "" echo "=== SCORE ===" PCT=$((OK * 100 / TOTAL)) diff --git a/api/v83-business-kpi-latest.json b/api/v83-business-kpi-latest.json index 59cdc2604..4d6132b09 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-21T07:54:02+00:00", + "ts": "2026-04-21T07:58:02+00:00", "summary": { "total_categories": 8, "total_kpis": 64, diff --git a/wiki/V119-dashboards-search-sort.md b/wiki/V119-dashboards-search-sort.md new file mode 100644 index 000000000..f58f21ce2 --- /dev/null +++ b/wiki/V119-dashboards-search-sort.md @@ -0,0 +1,94 @@ +# V119 Opus WIRE - Dashboards Search + Sort UX · 21avr 09:58 + +## Context +Extension V116-V117 (DASHBOARDS tab + HTTP status badges). Yacine: UX premium obligatoire. Ajouter search pour trouver rapidement un dashboard parmi 69. + +## Livrables V119 + +### 1. Search input +- `` avec placeholder "Rechercher..." +- Filtre sur name + display + category (case-insensitive) +- Event `input` → re-render immédiat + +### 2. Sort select +- 4 options: Nom A-Z, Taille, Date modif, Catégorie +- Event `change` → re-tri immédiat + +### 3. Counter live +- `` affiche "N / 69 tuiles" +- Mise à jour à chaque search/filter/sort + +### 4. Fix V118 intent `dashboards_status` +Cause racine: heredoc `python3 << EOF` à l'intérieur du script bash interfère avec le stdin curl (qui était intercepté par l99 "Score: 129 PASS / 0 FAIL"). +Fix: curl vers fichier temporaire, python3 -c lit depuis le fichier. + +## Validation E2E Playwright V119 +```json +{ + "v119": "search-sort-ux", + "initial_tiles": 69, + "search_ethica_tiles": 2, + "search_kpi_tiles": 5, + "sort_size_working": true, + "VERDICT": "WIRED" +} +``` + +Tests live: +- Search "ethica" → 2 tiles (Ethica Dashboard Live, Ethica Hub) +- Search "kpi" → 5 tiles +- Sort by size → tools-hub 43.7KB > architecture-live 41.8KB > acquired-dashboard 33.3KB + +## Intent `dashboards_status` live +``` +Intent 'dashboards_status' executed (trigger: dashboards status) +Total: 69 dashboards +By category: + wevia: 14, integration: 7, infra: 7 + crm: 5, ai: 5, security: 5, email: 5, pharma: 5, kpi: 5 + ops: 4, cleanup: 4, process: 3 +``` + +## GOLD backups +- `/opt/wevads/vault/all-ia-hub.html.GOLD-V119-pre-search` +- `/var/www/html/api/handlers/dashboards-summary.sh` (fix heredoc) + +## Artefacts +- `/var/www/html/api/blade-tasks/v119-search-proof/01-initial.png` +- `/var/www/html/api/blade-tasks/v119-search-proof/02-search-ethica.png` +- `/var/www/html/api/blade-tasks/v119-search-proof/03-search-kpi.png` +- `/var/www/html/api/blade-tasks/v119-search-proof/04-sort-size.png` +- `/var/www/html/api/blade-tasks/v119-search-proof/proof.json` + +## Métriques +- Hub size: 39.4KB (V117) → 41.8KB (V119) +2.4KB additif +- NR: 200/201 (transient -1, non-causé par V119) +- Intents wired V110-V119: +9 fonctionnels + +## Architecture complete (point d'entrée) +``` +WEVAL TECHNOLOGY PLATFORM (weval-technology-platform.html) + → POINT D'ENTRÉE UNIQUE de toute l'architecture + + → all-ia-hub.html + ├── CHAT MULTIAGENT (WEVIA Master streaming) + ├── CODE (WEVCODE 6 modes) + ├── ARENA 14 PROVIDERS + ├── IA CAPABILITIES (18 cards) + ├── TRAINING HUB (live stats) + ├── ORCHESTRATOR (726 agents) + └── DASHBOARDS (V116-V119) + ├── 69 tuiles consolidées + ├── 12 filtres catégories (wevia, integration, infra...) + ├── HTTP status badges (200/auth/err) + ├── Search input live (name/display/category) + ├── Sort (nom/taille/date/catégorie) + └── Counter "N / 69 tuiles" +``` + +ZERO orphelin. ZERO dashboard broken. + +## Doctrines respectées +#1 scan · #3 GOLD · #4 honnêteté (E2E prouvé) · #13 cause racine (heredoc fix) · **#14 ADDITIF PUR** · #16 NR · **#60 UX premium** (search+sort+counter) · #100 + +## Sessions consécutives sans régression applicative : 92+