auto-sync via WEVIA git_sync_all intent 2026-04-21T15:28:07+02:00
Some checks failed
WEVAL NonReg / nonreg (push) Has been cancelled

This commit is contained in:
opus
2026-04-21 15:28:07 +02:00
parent fea12bfe2d
commit 5060064915
12 changed files with 782 additions and 2 deletions

View File

@@ -0,0 +1,56 @@
<?php
/**
* ambre-early-doc-gen.php · AMBRE · priority intercept for file generation commands
* Included at top of master-api.php via @include.
* Detects: "Genere un PDF/Word/Excel/PPT sur: X" / "Genere un document" / "Genere une presentation"
* Action: call ambre-gen-pipeline → return response with file URL
*/
if (!isset($_mam) || empty($_mam)) return;
$__ad_msg = trim($_mam);
$__ad_lc = mb_strtolower($__ad_msg);
// Detection pattern: Genere + type + topic
if (!preg_match("/g[eé]n[eé]re?\s+(?:un|une|des|le|la)?\s*(pdf|pptx?|powerpoint|docx?|word|excel|xlsx?|pr[eé]sentation|presentation|document|tableau)[^:]*(?::|sur)\s*(.+)$/iu", $__ad_msg, $__ad_m)) return;
$__ad_raw_type = mb_strtolower($__ad_m[1]);
$__ad_topic = trim($__ad_m[2]);
$__ad_type_map = [
"pdf" => "pdf",
"pptx" => "pptx",
"ppt" => "pptx",
"powerpoint" => "pptx",
"presentation" => "pptx",
"présentation" => "pptx",
"docx" => "docx",
"doc" => "docx",
"word" => "docx",
"document" => "docx",
"xlsx" => "xlsx",
"excel" => "xlsx",
"tableau" => "xlsx",
];
$__ad_type = $__ad_type_map[$__ad_raw_type] ?? "pdf";
// XLSX not supported by pandoc directly → fallback to docx with table
if ($__ad_type === "xlsx") $__ad_type = "docx";
$__ad_url = "http://127.0.0.1/api/ambre-gen-pipeline.php?type=" . urlencode($__ad_type) . "&topic=" . urlencode($__ad_topic);
$__ad_ctx = stream_context_create(["http"=>["timeout"=>60, "header"=>"Host: weval-consulting.com\r\n"]]);
$__ad_out = @file_get_contents($__ad_url, false, $__ad_ctx);
if ($__ad_out && strlen($__ad_out) > 20) {
header("Content-Type: application/json");
echo json_encode([
"response" => $__ad_out,
"executed" => true,
"provider" => "ambre-doc-gen",
"intent" => "file_generation_real",
"type" => $__ad_type,
"topic" => $__ad_topic,
"source" => "ambre-early-doc-gen-v1",
], JSON_UNESCAPED_UNICODE);
exit;
}
// If pipeline failed, fall through to normal chat flow (no regression)

View File

@@ -0,0 +1,80 @@
<?php
/**
* ambre-gen-pipeline.php · AMBRE · pipeline complet chat → LLM markdown → pandoc file
* Usage: GET ?type=pdf|docx|pptx&topic=... (from chat intent cmd)
* Output: text response with file URL embedded
*/
header("Content-Type: text/plain; charset=utf-8");
$type = strtolower(trim($_GET["type"] ?? "pdf"));
$topic = trim($_GET["topic"] ?? "");
if (!$topic) { echo "❌ topic required"; exit; }
$allowed = ["pdf","docx","pptx","html","epub"];
if (!in_array($type, $allowed)) { echo "❌ type invalide, allowed: " . implode("|", $allowed); exit; }
// === 1. Call LLM to generate clean markdown ===
$sys_prompt = "Tu es un generateur de contenu professionnel. Réponds UNIQUEMENT en markdown pur, pas de preambule, pas de meta-commentaire. Pour les PPTX, utilise # pour chaque slide title. Français par défaut.";
$user_prompt = match($type) {
"pdf" => "Génère un document PDF professionnel, structuré, complet (2-3 pages) sur: $topic. Titres, sections, bullets.",
"docx" => "Génère un document Word professionnel, structuré sur: $topic. Titres, sections, tableaux si pertinent.",
"pptx" => "Génère une présentation de 5-7 slides sur: $topic. Chaque slide commence par # (titre slide). Bullets concises.",
"html" => "Génère un document HTML propre sur: $topic.",
default => "Génère un document sur: $topic.",
};
$llm_raw = @file_get_contents("http://127.0.0.1:4000/v1/chat/completions", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Content-Type: application/json\r\n",
"content" => json_encode([
"model" => "fast",
"messages" => [
["role"=>"system", "content"=>$sys_prompt],
["role"=>"user", "content"=>$user_prompt],
],
"max_tokens" => 2500,
"temperature" => 0.5,
"stream" => false,
]),
"timeout" => 30,
],
]));
$llm_d = @json_decode($llm_raw, true);
$md_content = $llm_d["choices"][0]["message"]["content"] ?? "";
if (!$md_content) { echo "❌ LLM failed to generate content"; exit; }
// === 2. Call ambre-doc-gen to create the file ===
$title = substr($topic, 0, 60);
$gen_ctx = stream_context_create([
"http" => [
"method" => "POST",
"header" => "Content-Type: application/json\r\n",
"content" => json_encode([
"type" => $type,
"title" => $title,
"content" => $md_content,
]),
"timeout" => 45,
],
]);
$gen_raw = @file_get_contents("http://127.0.0.1/api/ambre-doc-gen.php", false, $gen_ctx);
$gen_d = @json_decode($gen_raw, true);
if (!$gen_d || empty($gen_d["ok"])) {
echo "❌ Generation failed: " . ($gen_d["error"] ?? "unknown") . "\n";
echo "MD content was: " . substr($md_content, 0, 200);
exit;
}
// === 3. Output rich response ===
$icon = match($type) { "pdf"=>"📄", "docx"=>"📝", "pptx"=>"🎯", "html"=>"🌐", default=>"📎" };
echo "$icon **$title** généré\n\n";
echo "🔗 Télécharger: " . $gen_d["full_url"] . "\n";
echo "📦 Taille: " . $gen_d["size_human"] . " · ⚙️ " . $gen_d["elapsed_ms"] . "ms · engine: " . $gen_d["engine"] . "\n\n";
echo "---\n\nAperçu contenu:\n\n";
echo substr($md_content, 0, 800);
if (strlen($md_content) > 800) echo "\n\n... [document complet dans le fichier]";

View File

@@ -0,0 +1,281 @@
{
"ts": "2026-04-21T13:25:01+00:00",
"server": "s204",
"s204": {
"load": 1.16,
"uptime": "2026-04-14 11:51:24",
"ram_total_mb": 31335,
"ram_used_mb": 11894,
"ram_free_mb": 19440,
"disk_total": "150G",
"disk_used": "117G",
"disk_free": "27G",
"disk_pct": "82%",
"fpm_workers": 140,
"docker_containers": 19,
"cpu_cores": 8
},
"s95": {
"load": 0.93,
"disk_pct": "81%",
"status": "UP",
"ram_total_mb": 15610,
"ram_free_mb": 12029
},
"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": 315,
"php_apis": 797,
"wiki_entries": 1988,
"vault_doctrines": 69,
"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": 110609,
"with_phone": 155151,
"gap_email": 51124,
"pct_email": 68.4,
"pct_phone": 95.9,
"by_country": [
{
"country": "DZ",
"hcps": 122337,
"with_email": 78506,
"with_tel": 119396,
"pct_email": 64.2,
"pct_tel": 97.6
},
{
"country": "MA",
"hcps": 19723,
"with_email": 15077,
"with_tel": 18737,
"pct_email": 76.4,
"pct_tel": 95
},
{
"country": "TN",
"hcps": 17794,
"with_email": 15147,
"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 5 days",
"ports": ""
},
{
"name": "listmonk",
"status": "Up 5 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 5 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 37 hours (healthy)",
"ports": ""
},
{
"name": "vaultwarden",
"status": "Up 6 days (healthy)",
"ports": ""
},
{
"name": "qdrant",
"status": "Up 6 days",
"ports": ""
}
],
"crons": {
"active": 35
},
"git": {
"head": "a3812924a auto-sync-1525",
"dirty": 0,
"status": "CLEAN"
},
"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": 3815,
"health": {
"score": 6,
"max": 6,
"pct": 100
},
"elapsed_ms": 10428
}

View File

@@ -1,7 +1,7 @@
{
"ok": true,
"version": "V83-business-kpi",
"ts": "2026-04-21T13:23:43+00:00",
"ts": "2026-04-21T13:25:16+00:00",
"summary": {
"total_categories": 8,
"total_kpis": 64,

View File

@@ -1,6 +1,6 @@
<?php
$_RAW=file_get_contents("php://input");$_JIN=json_decode($_RAW,true);$_mam=$_JIN["message"]??"";
@include __DIR__ . '/wevia-opus-arch-early.php'; // V41 before Resolver
@include __DIR__ . '/wevia-opus-arch-early.php'; // V41 before Resolver\n@include __DIR__ . '/ambre-early-doc-gen.php'; // AMBRE 2026-04-21 file generation priority
// === OPUS4-AUTOWIRE-EARLY-v2 (17avr 02h20) ===
// Priority handler : master add/list intent bypass tout le pipeline (fast-path greedy cause racine)
// Zero regression : return silencieux si syntaxe pas matchee

View File

@@ -0,0 +1,99 @@
# contrat de service B2B
**CONTRAT DE SERVICE B2B**
**Entre**
* **Nom de l'entreprise du client** : [Nom de l'entreprise du client]
* **Adresse du client** : [Adresse du client]
* **Code postal du client** : [Code postal du client]
* **Ville du client** : [Ville du client]
* **Numéro de téléphone du client** : [Numéro de téléphone du client]
* **Adresse e-mail du client** : [Adresse e-mail du client]
**Et**
* **Nom de l'entreprise du prestataire** : [Nom de l'entreprise du prestataire]
* **Adresse du prestataire** : [Adresse du prestataire]
* **Code postal du prestataire** : [Code postal du prestataire]
* **Ville du prestataire** : [Ville du prestataire]
* **Numéro de téléphone du prestataire** : [Numéro de téléphone du prestataire]
* **Adresse e-mail du prestataire** : [Adresse e-mail du prestataire]
**Objet du contrat**
Le présent contrat a pour objet de définir les termes et conditions de la prestation de services entre [Nom de l'entreprise du prestataire] et [Nom de l'entreprise du client].
**Article 1 : Définitions**
* **Services** : Les services que [Nom de l'entreprise du prestataire] s'engage à fournir à [Nom de l'entreprise du client] sont définis dans la liste ci-dessous :
+ [Liste des services]
* **Période de prestation** : La période de prestation commence le [Date de début] et se termine le [Date de fin]
* **Tarifs** : Les tarifs sont fixés à [Tarif] par [Unité de mesure]
**Article 2 : Obligations du prestataire**
* **Fournir les services** : [Nom de l'entreprise du prestataire] s'engage à fournir les services définis dans l'article 1.
* **Rester à jour** : [Nom de l'entreprise du prestataire] s'engage à rester à jour sur les dernières technologies et méthodes pour assurer la qualité des services.
* **Résoudre les problèmes** : [Nom de l'entreprise du prestataire] s'engage à résoudre les problèmes techniques ou autres qui pourraient survenir pendant la prestation des services.
**Article 3 : Obligations du client**
* **Fournir les informations** : [Nom de l'entreprise du client] s'engage à fournir les informations nécessaires à la prestation des services.
* **Collaborer avec le prestataire** : [Nom de l'entreprise du client] s'engage à collaborer avec [Nom de l'entreprise du prestataire] pour assurer la réussite des services.
* **Payer les factures** : [Nom de l'entreprise du client] s'engage à payer les factures émises par [Nom de l'entreprise du prestataire] dans les délais fixés.
**Article 4 : Paiement**
* **Tarifs** : Les tarifs sont fixés à [Tarif] par [Unité de mesure].
* **Facturation** : Les factures seront émises par [Nom de l'entreprise du prestataire] et devront être payées par [Nom de l'entreprise du client] dans les 30 jours suivant la date de facture.
* **Pénalités** : En cas de retard de paiement, [Nom de l'entreprise du client] sera facturé des pénalités à hauteur de [Pourcentage] par mois.
**Article 5 : Confidentialité**
* **Non-divulgation** : Les parties s'engagent à ne pas divulguer les informations confidentielles échangées dans le cadre de la prestation des services.
* **Protection des données** : Les parties s'engagent à respecter les réglementations en vigueur concernant la protection des données personnelles.
**Article 6 : Droit applicable**
* **Loi applicable** : Le présent contrat est soumis à la loi française.
* **Juridiction** : Toute contestation résultant de l'interprétation ou de l'exécution du présent contrat sera soumise aux tribunaux compétents de [Ville].
**Article 7 : Durée**
* **Durée** : Le présent contrat est conclu pour une durée de [Durée] mois.
* **Renouvellement** : Le présent contrat sera automatiquement renouvelé pour une durée de [Durée] mois, sauf dénonciation par l'une des parties 30 jours avant la fin de la période de prestation.
**Article 8 : Désistement**
* **Désistement** : L'une des parties peut se retirer du présent contrat en informant l'autre partie par écrit 30 jours avant la fin de la période de prestation.
* **Résiliation** : En cas de non-respect des obligations, l'une des parties peut résilier le présent contrat immédiatement.
**Article 9 : Modification**
* **Modification** : Les parties peuvent modifier le présent contrat par écrit, en y annexant ou en y supprimant des dispositions.
* **Acceptation** : Les modifications seront considérées comme acceptées par l'autre partie si elle n'a pas expressément refusé dans les 15 jours suivant la réception de la proposition de modification.
**Article 10 : Acceptation**
* **Acceptation** : Le présent contrat sera considéré comme accepté par l'une des parties si elle n'a pas expressément refusé dans les 15 jours suivant la réception de la proposition de contrat.
**Article 11 : Signature**
* **Signature** : Le présent contrat a été signé en deux exemplaires originaux, l'un pour chaque partie.
---
**Signature du client**
* **Nom du représentant** : [Nom du représentant]
* **Fonction** : [Fonction]
* **Date** : [Date]
---
**Signature du prestataire**
* **Nom du représentant** : [Nom du représentant]
* **Fonction** : [Fonction]
* **Date** : [Date]

View File

@@ -0,0 +1,81 @@
# plan marketing WEVIA Q2 2026
# Plan Marketing WEVIA Q2 2026
## Introduction
Le plan marketing WEVIA Q2 2026 vise à renforcer la présence de l'entreprise sur le marché et à atteindre les objectifs de vente fixés pour la période. Ce plan est structuré en quatre axes principaux : communication, marketing numérique, événements et relations publiques.
### Objectifs
* Augmenter la visibilité de l'entreprise de 20% par rapport à la même période l'an passé
* Générer 30% de nouveaux leads potentiels
* Réduire le coût de acquisition de 15% par rapport à la même période l'an passé
## Communication
### Stratégie de Communication
* Renforcer la présence de l'entreprise sur les réseaux sociaux (LinkedIn, Twitter, Facebook)
* Lancer une campagne de communication interne pour sensibiliser les employés à l'importance de la communication externe
* Créer un contenu de qualité régulier (blog, vidéos, infographies)
### Bénéfices
* Augmenter la visibilité de l'entreprise
* Renforcer la marque WEVIA
* Améliorer la relation avec les clients et les prospects
## Marketing Numérique
### Stratégie de Marketing Numérique
* Lancer une campagne de marketing email pour les prospects et les clients existants
* Créer un contenu de qualité régulier pour les réseaux sociaux et le blog
* Améliorer la présence de l'entreprise sur Google Ads et LinkedIn Ads
### Bénéfices
* Augmenter la génération de leads
* Renforcer la présence de l'entreprise sur le marché
* Améliorer la rentabilité des campagnes de marketing
## Événements
### Stratégie d'Événements
* Organiser un événement de networking pour les clients et les prospects
* Participer à des événements professionnels pour renforcer la présence de l'entreprise
* Lancer une campagne de promotion pour les événements
### Bénéfices
* Renforcer la relation avec les clients et les prospects
* Augmenter la visibilité de l'entreprise
* Générer de nouveaux leads potentiels
## Relations Publiques
### Stratégie de Relations Publiques
* Lancer une campagne de communication pour les médias
* Créer un contenu de qualité régulier pour les médias
* Renforcer la présence de l'entreprise sur les plateformes de presse
### Bénéfices
* Augmenter la visibilité de l'entreprise
* Renforcer la marque WEVIA
* Améliorer la relation avec les médias
## Budget et Ressources
* Le budget alloué pour le plan marketing WEVIA Q2 2026 est de 150 000 €
* Les ressources allouées pour le plan marketing sont les suivantes :
+ Équipe de marketing : 2 personnes
+ Équipe de communication : 1 personne
+ Équipe de relations publiques : 1 personne
## Conclusion
Le plan marketing WEVIA Q2 2026 vise à renforcer la présence de l'entreprise sur le marché et à atteindre les objectifs de vente fixés pour la période. Ce plan est structuré en quatre axes principaux : communication, marketing numérique, événements et relations publiques. Les objectifs de ce plan sont clairs et les ressources allouées sont suffisantes pour atteindre ces objectifs. Nous sommes confiants que ce plan permettra à l'entreprise de réussir ses objectifs pour la période Q2 2026.

View File

@@ -0,0 +1,37 @@
# presentation SAP pour client pharma
# Présentation SAP pour Client Pharma
## Présentation de SAP
* Système d'information de gestion intégré (ERP)
* Développé par SAP SE
* Utilisé par plus de 437 000 clients dans le monde
* Intégration de toutes les fonctions de l'entreprise
## Avantages pour les entreprises pharmaceutiques
* Amélioration de la gestion des stocks et de la chaîne d'approvisionnement
* Meilleure gestion des données de qualité et de sécurité
* Amélioration de la conformité aux réglementations
* Augmentation de l'efficacité et de la productivité
## Fonctionnalités clés pour les entreprises pharmaceutiques
* Gestion des produits
* Gestion des stocks et de la chaîne d'approvisionnement
* Gestion des données de qualité et de sécurité
* Gestion des réglementations et des normes
* Gestion des relations avec les fournisseurs et les clients
## Intégration avec les systèmes existants
* Intégration avec les systèmes de gestion de la chaîne d'approvisionnement
* Intégration avec les systèmes de gestion des données de qualité et de sécurité
* Intégration avec les systèmes de gestion des réglementations et des normes
## Stratégie de déploiement
* Analyse des besoins et définition de la stratégie
* Développement d'un plan de déploiement
* Formation et support à la mise en œuvre
## Coûts et avantages
* Coûts de mise en œuvre et de maintenance
* Avantages en termes d'efficacité et de productivité
* Amélioration de la qualité et de la sécurité des produits

View File

@@ -3143,6 +3143,152 @@ if (typeof window.navigateTo === 'function'){
</script>
<!-- BETON-DOCTRINE-105 WTP Pilotage KPI Live widget - additif pur 21avr -->
<section id="wtp-erp-consolidated-wave208" data-added-by="opus-wave-208" style="margin:32px 16px 20px;padding:28px;background:radial-gradient(circle at 20% 20%,#1e1b4b,#0f172a 60%);border:1px solid #4c1d95;border-radius:14px;font-family:system-ui,sans-serif;box-shadow:0 10px 40px rgba(76,29,149,.25)">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:22px;flex-wrap:wrap;gap:14px">
<div>
<div style="display:flex;align-items:center;gap:10px;margin-bottom:4px">
<span style="font-size:22px">🧭</span>
<h2 style="margin:0;color:#e9d5ff;font-size:22px;font-weight:700;letter-spacing:.2px">Pilotage ERP Consolidé</h2>
<span style="padding:3px 10px;border-radius:12px;background:linear-gradient(135deg,#7c3aed,#22d3ee);color:#fff;font-size:10px;font-weight:700;letter-spacing:.6px">WAVE 208</span>
</div>
<p style="margin:0;color:#a78bfa;font-size:13px">Truth registry · 8 catégories KPI V83 · drill-down par clic · auto-refresh 45s</p>
</div>
<div id="wtp-erp-w208-status" style="padding:6px 14px;border-radius:20px;background:rgba(124,58,237,.2);color:#c4b5fd;font-size:12px;font-weight:600;border:1px solid rgba(124,58,237,.4)">CHARGEMENT...</div>
</div>
<!-- Hero: Truth Registry Autonomy -->
<div id="wtp-erp-w208-truth" style="display:grid;grid-template-columns:minmax(280px,1fr) repeat(auto-fit,minmax(140px,auto));gap:14px;margin-bottom:20px"></div>
<!-- 8 category donuts -->
<div style="font-size:11px;color:#a78bfa;text-transform:uppercase;letter-spacing:1px;margin-bottom:10px">Catégories V83 · clic pour drill-down</div>
<div id="wtp-erp-w208-cats" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px"></div>
<!-- Drill-down zone -->
<div id="wtp-erp-w208-drill" style="display:none;margin-top:18px;padding:18px;background:rgba(124,58,237,.08);border:1px solid rgba(124,58,237,.2);border-radius:10px"></div>
<script>
(function(){
var W208_API_V83_FULL = '/api/wevia-v83-business-kpi.php?action=full';
var W208_API_TRUTH = '/api/read_truth_registry.php';
var w208_state = { v83: null, truth: null };
function donutSVG(okPct, size){
size = size || 70;
var r = size/2 - 6;
var c = 2 * Math.PI * r;
var dash = (okPct/100) * c;
var color = okPct >= 80 ? '#10b981' : (okPct >= 50 ? '#f59e0b' : '#ef4444');
return '<svg width="'+size+'" height="'+size+'" viewBox="0 0 '+size+' '+size+'">'
+ '<circle cx="'+(size/2)+'" cy="'+(size/2)+'" r="'+r+'" fill="none" stroke="rgba(255,255,255,.08)" stroke-width="5"/>'
+ '<circle cx="'+(size/2)+'" cy="'+(size/2)+'" r="'+r+'" fill="none" stroke="'+color+'" stroke-width="5" stroke-dasharray="'+dash+' '+c+'" stroke-linecap="round" transform="rotate(-90 '+(size/2)+' '+(size/2)+')"/>'
+ '<text x="'+(size/2)+'" y="'+(size/2+5)+'" text-anchor="middle" fill="#e9d5ff" font-size="16" font-weight="700">'+Math.round(okPct)+'%</text>'
+ '</svg>';
}
function renderTruth(){
var el = document.getElementById('wtp-erp-w208-truth');
if (!el || !w208_state.truth) return;
var t = w208_state.truth;
var headlines = t.headlines || {};
var scalars = t.scalars || {};
var level = headlines.autonomy_level || '?';
var score = headlines.autonomy_score || 0;
var built = headlines.built_at || '';
var apis = scalars.apis_php_count || 0;
var levelColor = level === 'GODMODE' ? '#22d3ee' : (level === 'HIGH' ? '#10b981' : '#f59e0b');
el.innerHTML =
'<div style="padding:18px;background:linear-gradient(135deg,rgba(34,211,238,.12),rgba(124,58,237,.08));border:1px solid '+levelColor+';border-radius:10px">'
+'<div style="font-size:11px;color:#a5f3fc;text-transform:uppercase;letter-spacing:1px">Truth Registry · Autonomy</div>'
+'<div style="display:flex;align-items:baseline;gap:12px;margin-top:8px">'
+'<div style="font-size:32px;font-weight:800;color:'+levelColor+'">'+level+'</div>'
+'<div style="font-size:26px;font-weight:700;color:#e9d5ff">'+score+'<span style="font-size:15px;color:#a78bfa">/100</span></div>'
+'</div>'
+'<div style="font-size:11px;color:#67e8f9;margin-top:6px">Built '+(built.slice(0,10))+' · '+apis+' APIs PHP wired</div>'
+'</div>'
+'<div style="padding:16px;background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.1);border-radius:10px;min-width:130px">'
+'<div style="font-size:10px;color:#94a3b8;text-transform:uppercase;letter-spacing:.8px">Version</div>'
+'<div style="font-size:18px;font-weight:700;color:#e9d5ff;margin-top:4px">'+(scalars.version||'?')+'</div>'
+'</div>';
}
function renderCats(){
var el = document.getElementById('wtp-erp-w208-cats');
if (!el || !w208_state.v83) return;
var cats = w208_state.v83.by_category || {};
var html = '';
Object.keys(cats).forEach(function(key){
var c = cats[key];
var kpis = c.kpis || [];
var ok = 0, warn = 0, fail = 0;
kpis.forEach(function(k){
var s = (k.status||'').toLowerCase();
if (s === 'ok') ok++; else if (s === 'warn') warn++; else if (s === 'fail') fail++;
});
var total = kpis.length || c.count || 8;
var pct = total ? (ok/total*100) : 0;
html += '<div onclick="window.__wtpW208Drill(\''+key+'\')" style="cursor:pointer;padding:14px;background:rgba(255,255,255,.03);border:1px solid rgba(124,58,237,.18);border-radius:10px;display:flex;align-items:center;gap:12px;transition:all .2s" onmouseover="this.style.borderColor=\'#a855f7\';this.style.transform=\'translateY(-1px)\'" onmouseout="this.style.borderColor=\'rgba(124,58,237,.18)\';this.style.transform=\'translateY(0)\'">'
+ donutSVG(pct,64)
+ '<div style="flex:1;min-width:0">'
+ '<div style="font-size:13px;color:#e9d5ff;font-weight:600;margin-bottom:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">'+(c.title||key)+'</div>'
+ '<div style="font-size:11px;color:#94a3b8">OK '+ok+' · <span style="color:#fbbf24">warn '+warn+'</span>'+(fail?' · <span style="color:#ef4444">fail '+fail+'</span>':'')+'</div>'
+ '<div style="font-size:10px;color:#7c6bf0;margin-top:2px">'+total+' KPIs · clic drill-down</div>'
+ '</div>'
+ '</div>';
});
el.innerHTML = html || '<div style="padding:20px;color:#64748b;font-size:13px">(aucune catégorie chargée)</div>';
}
window.__wtpW208Drill = function(catKey){
var drill = document.getElementById('wtp-erp-w208-drill');
if (!drill || !w208_state.v83) return;
var cat = (w208_state.v83.by_category || {})[catKey];
if (!cat) return;
drill.style.display = 'block';
var kpis = cat.kpis || [];
var rows = kpis.map(function(k){
var s = (k.status||'').toLowerCase();
var col = s === 'ok' ? '#10b981' : (s === 'warn' ? '#fbbf24' : (s === 'fail' ? '#ef4444' : '#64748b'));
var value = k.value !== undefined ? k.value : (k.current !== undefined ? k.current : '?');
var unit = k.unit || '';
var name = k.name || k.kpi || k.id || '?';
return '<div style="padding:10px 12px;background:rgba(255,255,255,.02);border-left:3px solid '+col+';border-radius:4px;margin-bottom:6px;display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap">'
+ '<div style="flex:1;min-width:200px"><div style="font-size:12.5px;color:#e9d5ff;font-weight:600">'+name+'</div>'
+ (k.description?'<div style="font-size:10.5px;color:#94a3b8;margin-top:2px">'+k.description+'</div>':'')
+ '</div>'
+ '<div style="font-size:16px;font-weight:700;color:'+col+'">'+value+' <span style="font-size:11px;color:#94a3b8">'+unit+'</span></div>'
+ '<div style="padding:2px 8px;border-radius:10px;background:'+col+'22;color:'+col+';font-size:10px;font-weight:700;text-transform:uppercase">'+s+'</div>'
+ '</div>';
}).join('');
drill.innerHTML = '<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px"><h3 style="margin:0;color:#e9d5ff;font-size:15px">'+(cat.title||catKey)+' · '+kpis.length+' KPIs</h3><button onclick="document.getElementById(\'wtp-erp-w208-drill\').style.display=\'none\'" style="padding:4px 10px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.15);border-radius:14px;color:#c4b5fd;font-size:11px;cursor:pointer">Fermer</button></div>' + (rows || '<div style="color:#64748b;font-size:12px">Aucun KPI dans cette catégorie</div>');
drill.scrollIntoView({behavior:'smooth', block:'nearest'});
};
function refresh(){
var statusEl = document.getElementById('wtp-erp-w208-status');
if (statusEl) statusEl.textContent = 'SYNC...';
var ts = Date.now();
Promise.all([
fetch(W208_API_V83_FULL+'&cb='+ts).then(function(r){return r.json();}).catch(function(){return null;}),
fetch(W208_API_TRUTH+'?cb='+ts).then(function(r){return r.json();}).catch(function(){return null;}),
]).then(function(rs){
w208_state.v83 = rs[0];
w208_state.truth = rs[1];
renderTruth();
renderCats();
if (statusEl) {
statusEl.textContent = 'LIVE · ' + new Date().toLocaleTimeString('fr-FR');
statusEl.style.background = 'rgba(16,185,129,.2)';
statusEl.style.color = '#6ee7b7';
statusEl.style.borderColor = 'rgba(16,185,129,.4)';
}
});
}
refresh();
setInterval(refresh, 45000);
})();
</script>
</section>
<section id="wtp-pilotage-kpi-live" data-added-by="opus-doctrine-105" style="margin:32px 16px;padding:24px;background:linear-gradient(135deg,#0f172a,#1e293b);border:1px solid #334a7a;border-radius:12px;font-family:system-ui,sans-serif">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;flex-wrap:wrap;gap:12px">
<div>