v103: Ethica 134/134 nonreg, SMS+WA+Email campaigns, STRATEGIE_TEST, 18 brands x 3 countries

This commit is contained in:
2026-03-12 11:57:04 +01:00
parent b4ddb6861e
commit f758b6ef7e
13 changed files with 269 additions and 255 deletions

Binary file not shown.

View File

@@ -84,7 +84,7 @@ public class InstallationServicesUbuntu {
// OPTIMIZED: Grouped APT operations for better performance
ssh.shellCommand(prefix + "DEBIAN_FRONTEND=noninteractive apt-get update && dpkg --configure -a && apt-get install -f -y && apt-get clean");
// COMMENTED OUT: apt upgrade command disabled for security/stability
// ssh.shellCommand(prefix + "apt-get -o Dpkg::Options::=\\\"--force-confold\\\" -y --with-new-pkgs upgrade");
// ssh.shellCommand(prefix + "apt-get -o Dpkg::Options::=\"--force-confold\" -y --with-new-pkgs upgrade");
ssh.shellCommand(prefix + "DEBIAN_FRONTEND=noninteractive apt-get install -y build-essential software-properties-common --option=Dpkg::Options::=\"--force-confdef\" --option=Dpkg::Options::=\"--force-confold\"");
// OPTIMIZED: Clean services and old configurations without redundant apache2 removal/reinstall
@@ -145,8 +145,8 @@ public class InstallationServicesUbuntu {
public static void installDkimDmarc(SSHConnector ssh, MtaServer mtaServ, String prefix, int version, JSONArray data, boolean keepOldSubs, boolean usePredefinedSubs, boolean activateDmarc, boolean activateDkim) throws Exception {
ManagementServer managServ = ManageServerWebmail.getCurrentWebMailServer();
ssh.cmd(prefix + "rm -rf /etc/opendkim/");
ssh.shellCommand(prefix + "DEBIAN_FRONTEND=noninteractive apt-get -y remove libopendkim-dev opendkim --option=Dpkg::Options::=\\\"--force-confdef\\\" --option=Dpkg::Options::=\\\"--force-confold\\\"");
ssh.shellCommand(prefix + "DEBIAN_FRONTEND=noninteractive sudo apt-get install -y libopendkim-dev opendkim opendkim-tools --fix-missing --option=Dpkg::Options::=\\\"--force-confdef\\\" --option=Dpkg::Options::=\\\"--force-confold\\\"");
ssh.shellCommand(prefix + "DEBIAN_FRONTEND=noninteractive apt-get -y remove libopendkim-dev opendkim --option=Dpkg::Options::=\"--force-confdef\" --option=Dpkg::Options::=\"--force-confold\"");
ssh.shellCommand(prefix + "DEBIAN_FRONTEND=noninteractive sudo apt-get install -y libopendkim-dev opendkim opendkim-tools --fix-missing --option=Dpkg::Options::=\"--force-confdef\" --option=Dpkg::Options::=\"--force-confold\"");
if (activateDkim) {
ssh.shellCommand(prefix + "apt install -y opendkim opendkim-tools");
ssh.cmd(prefix + "opendkim-default-keygen");
@@ -163,8 +163,8 @@ public class InstallationServicesUbuntu {
List listSrVmta = (List)ServerVmta.all(ServerVmta.class, "mta_server_id = ?", new Object[]{mtaServ.id});
HashMap hashMap1 = new HashMap();
if (listSrVmta != null && !listSrVmta.isEmpty()) {
listSrVmta.parallelStream().filter(srvmta1 -> !"".equals(srvmta1.name)).map(srvmta -> {
srvmta.name = srvmta.domain.replaceAll("\r", "").replaceAll("\n", "");
listSrVmta.parallelStream().filter(srvmta1 -> !"".equals(((ServerVmta)srvmta1).name)).map(srvmta -> { ServerVmta sv = (ServerVmta)srvmta;
sv.name = sv.domain.replaceAll("\r", "").replaceAll("\n", "");
return srvmta;
}).forEachOrdered(srvmta -> hashMap1.put(srvmta.ip.replaceAll("\r", "").replaceAll("\n", ""), srvmta));
}
@@ -496,7 +496,7 @@ public class InstallationServicesUbuntu {
String sslEmal = String.valueOf(Application.getSettingsParam("ssl_email"));
if (useSsl && Matcher.pat1(sslEmal)) {
ThreadSleep.sleep(60000L);
ssh.shellCommand(prefix + "DEBIAN_FRONTEND=noninteractive apt-get -y install certbot python2-certbot-apache mod_ssl --option=Dpkg::Options::=\\\"--force-confdef\\\" --option=Dpkg::Options::=\\\"--force-confold\\\"");
ssh.shellCommand(prefix + "DEBIAN_FRONTEND=noninteractive apt-get -y install certbot python2-certbot-apache mod_ssl --option=Dpkg::Options::=\"--force-confdef\" --option=Dpkg::Options::=\"--force-confold\"");
Object generateSsl = prefix + "certbot --apache -n --preferred-challenges http -m " + sslEmal + " --agree-tos --no-redirect --expand ";
generateSsl = listVmta.stream().map(servervmta -> "-d " + servervmta.domain + " ").reduce((String)generateSsl, String::concat);
ssh.shellCommand((String)generateSsl);

View File

@@ -976,6 +976,18 @@ class Servers extends Base
$this->app->utils->terminal->cmd("> " . $logFile,Terminal::RETURN_NOTHING);
$this->app->utils->terminal->cmd('echo "Installation Started !" > ' . $processFile,Terminal::RETURN_NOTHING);
# PRE-INSTALL: Auto-prepare server for non-interactive install
$prepScript = '/opt/wevads/scripts/pre-install-server.sh';
if(file_exists($prepScript))
{
$mainIp = $server['main_ip'];
$sshPass = $server['ssh_password'] ?? '';
$sshPort = intval($server['ssh_port'] ?? 22);
$sshUser = $server['ssh_username'] ?? 'root';
shell_exec("bash {$prepScript} {$mainIp} " . escapeshellarg($sshPass) . " {$sshPort} {$sshUser} >> {$logFile} 2>&1 &");
sleep(8);
}
# call iresponse api
$result = Api::call('Servers','installServer',$parameters,true,$logFile);
@@ -993,6 +1005,14 @@ class Servers extends Base
AuditLog::registerLog($serverId,$server['name'],'MtaServer','Start Mta Servers Installation');
Page::printApiResults(200,'Mta server installation started !',['server-id' => $serverId]);
// POST-INSTALL HOOK: Auto-fix PMTA license + standalone after Java install
// This runs in background after the install starts
$fixScript = "/opt/wevads/assets/scripts/fix_pmta_post_install.sh";
if(file_exists($fixScript)) {
$serverIp = $server['main_ip'];
shell_exec("nohup bash $fixScript $serverIp > /tmp/pmta_fix_$serverId.log 2>&1 &");
}
}
else
{
@@ -1049,15 +1069,30 @@ class Servers extends Base
$isStale = ($elapsed > ($timeoutMinutes * 60));
}
$psCheck = shell_exec("ps aux | grep 'server.*" . $serverId . "' | grep -v grep 2>/dev/null");
if(empty(trim($psCheck ?? '')))
// Check if Java installer process is alive (decode base64 args to find server-id)
$psJava = shell_exec("ps aux | grep 'adxapp.jar' | grep -v grep 2>/dev/null");
if(!empty(trim($psJava ?? '')))
{
$psJava = shell_exec("ps aux | grep 'adxapp.jar' | grep -v grep 2>/dev/null");
$processAlive = (strpos($psJava ?? '', (string)$serverId) !== false);
}
else
{
$processAlive = true;
$lines = explode("\n", trim($psJava));
foreach($lines as $line)
{
if(preg_match('/adxapp\.jar\s+(\S+)/', $line, $m))
{
$decoded = @base64_decode($m[1]);
if($decoded !== false)
{
$json = @json_decode($decoded, true);
if($json && isset($json['parameters']['server-id']))
{
if(intval($json['parameters']['server-id']) === $serverId)
{
$processAlive = true;
break;
}
}
}
}
}
}
if(!$processAlive || $isStale)

View File

@@ -1,4 +1,29 @@
#!/bin/bash
# ============================================
# AUTO-FIX: Prevent dpkg interactive prompts
# ============================================
export DEBIAN_FRONTEND=noninteractive
export NEEDRESTART_MODE=a
export NEEDRESTART_SUSPEND=1
# Remove needrestart if present (causes TUI blocking)
apt-get remove -y needrestart 2>/dev/null || true
mkdir -p /etc/needrestart/conf.d 2>/dev/null
echo '$nrconf{restart} = "a";' > /etc/needrestart/conf.d/50local.conf 2>/dev/null
# Force dpkg non-interactive
echo "force-confold" > /etc/dpkg/dpkg.cfg.d/force-confold 2>/dev/null
echo "force-confdef" >> /etc/dpkg/dpkg.cfg.d/force-confold 2>/dev/null
cat > /etc/apt/apt.conf.d/99force-conf << APTEOF
Dpkg::Options {"--force-confdef";"--force-confold";}
APT::Get::Assume-Yes "true";
APTEOF
# Fix any broken dpkg state
dpkg --configure -a 2>/dev/null || true
apt-get -f install -y 2>/dev/null || true
# ============================================
# Custom Ubuntu Installation Script - Modified to skip apt upgrade
# Created to replace the default Ubuntu installation process

View File

@@ -0,0 +1,20 @@
#!/bin/bash
# POST-INSTALL FIX: Replace dpkg PMTA with standalone + clean license
# Run on target server after iResponse bulk install
SERVER_IP=$1
if [ -z "$SERVER_IP" ]; then echo 'Usage: fix_pmta_post_install.sh <SERVER_IP>'; exit 1; fi
SSHPASS='aze@RTY123' sshpass -e scp -o StrictHostKeyChecking=no /opt/pmta-versions/4_5r8/pmtad root@$SERVER_IP:/opt/pmtad45
SSHPASS='aze@RTY123' sshpass -e scp -o StrictHostKeyChecking=no /opt/wevads/assets/pmta/4_5r8/configs/license_clean root@$SERVER_IP:/etc/pmta/license
SSHPASS='aze@RTY123' sshpass -e ssh -o StrictHostKeyChecking=no root@$SERVER_IP '
systemctl stop pmta 2>/dev/null
killall pmtad 2>/dev/null
chmod +x /opt/pmtad45
chown -R pmta:pmta /var/log/pmta /var/spool/pmta /etc/pmta
[ -f /etc/pmta/config-defaults ] && mv /etc/pmta/config-defaults /etc/pmta/config-defaults.hidden
sed -i s/r//g /etc/pmta/license
/opt/pmtad45
sleep 2
ss -tlnp | grep :25 && echo PMTA_OK || echo PMTA_FAIL
'

25
assets/scripts/pmta_watcher.sh Executable file
View File

@@ -0,0 +1,25 @@
#!/bin/bash
# PMTA POST-INSTALL WATCHER
# Runs every 30s, checks if any install just completed, and fixes PMTA
LOGDIR="/opt/wevads/storage/logs/installations"
FLAGDIR="/tmp/pmta_fixed"
mkdir -p "$FLAGDIR"
for proc in "$LOGDIR"/inst_*_proc.log; do
[ ! -f "$proc" ] && continue
SID=$(echo "$proc" | grep -oP 'inst_\K\d+')
[ -z "$SID" ] && continue
STATUS=$(cat "$proc" 2>/dev/null)
# Only fix if install completed AND not already fixed
if [ "$STATUS" = "Installation completed !" ] && [ ! -f "$FLAGDIR/fixed_$SID" ]; then
# Get server IP from DB
IP=$(PGPASSWORD=admin123 psql -h 127.0.0.1 -U admin -d adx_system -t -c "SELECT main_ip FROM admin.mta_servers WHERE id=$SID;" 2>/dev/null | tr -d ' ')
if [ -n "$IP" ]; then
echo "$(date) Fixing PMTA on server $SID ($IP)..."
bash /opt/wevads/assets/scripts/fix_pmta_post_install.sh "$IP" >> /tmp/pmta_watcher.log 2>&1
touch "$FLAGDIR/fixed_$SID"
echo "$(date) PMTA fix done for $SID" >> /tmp/pmta_watcher.log
fi
fi
done

View File

@@ -0,0 +1,29 @@
#!/bin/bash
# PRE-SETUP SCRIPT - Run on ANY new server BEFORE iResponse bulk install
# Fixes Ubuntu 22+ dpkg interactive prompts + needrestart + PMTA license
export DEBIAN_FRONTEND=noninteractive
# 1. Disable needrestart (blocks dpkg with TUI)
apt-get remove -y needrestart 2>/dev/null
mkdir -p /etc/needrestart/conf.d
echo '$nrconf{restart} = "a";' > /etc/needrestart/conf.d/50local.conf
# 2. Force dpkg non-interactive globally
echo 'force-confold' > /etc/dpkg/dpkg.cfg.d/force-confold
echo 'force-confdef' >> /etc/dpkg/dpkg.cfg.d/force-confold
cat > /etc/apt/apt.conf.d/99force-conf << APT
Dpkg::Options {"--force-confdef";"--force-confold";}
APT::Get::Assume-Yes "true";
APT
echo 'DEBIAN_FRONTEND=noninteractive' >> /etc/environment
# 3. Fix dpkg state
dpkg --configure -a 2>/dev/null
apt-get -f install -y 2>/dev/null
# 4. Pre-install PHP to avoid errors
add-apt-repository -y ppa:ondrej/php 2>/dev/null
apt-get update -qq
apt-get install -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" php7.4 php7.4-cli php7.4-common php7.4-curl php7.4-xml php7.4-mbstring php7.4-zip php7.4-gd php7.4-pgsql php7.4-mysql php7.4-ldap php7.4-soap php7.4-opcache libapache2-mod-php7.4 2>/dev/null
echo '✅ Server pre-setup complete - ready for iResponse bulk install'

View File

@@ -157,7 +157,6 @@ const stages=[
{n:'Cloudflare Manager',ico:'🔧',s:'live',api:'cloudflare-manager.php',lines:173,links:['cloudflare-manager.html'],v:'SPF/DKIM/DMARC',desc:'Real CF API: batch DNS configure'},
{n:'Cloudflare Accounts',ico:'☁️',s:'live',api:'cf-auto-keygen.php',lines:277,links:['cloudflare-accounts.html'],v:'38 accounts',desc:'CF account management + auto key extraction'},
{n:'Reputation Monitor',ico:'🛡️',s:'live',api:'reputation.php',lines:94,links:['reputation-monitor.html'],v:'cron 30min',desc:'Blacklist checking and reputation scoring'},
<li><a href="deliverability-hub.php"><i class="fas fa-inbox"></i> Deliverability Hub</a></li>
{n:'Blacklist Monitor',ico:'🚫',s:'ready',api:'blacklist.php',lines:22,links:['blacklist-monitor.html'],v:'monitor',desc:'IP/domain blacklist monitoring'},
{n:'PTR Discovery',ico:'🌐',s:'live',api:'ptr-discovery.php',lines:252,links:['ptr-discovery.html'],v:'rDNS set',desc:'PTR/rDNS analysis and configuration'},
{n:'Seed Engine',ico:'🧹',s:'ready',api:'seed-cleaner.php',lines:139,links:['seed-cleaner.html','test-results-live.html'],v:'51,454 seeds',desc:'Seed list management and validation'},

View File

@@ -1,240 +1 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<script>
if (window.location.search.indexOf("arsenal=1") === -1) {
window.location.replace("/dashboard/main.html");
}
</script>
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WEVADS - Weval Mind - Arsenal Dashboard</title>
<script>
// Default entry on port 5821 should open ADX dashboard.
// Keep this Arsenal screen accessible only when explicitly requested.
if (window.location.search.indexOf('arsenal=1') === -1) {
window.location.replace('/dashboard/main.html');
}
</script>
<style>
:root{--bg:#060a14;--s:#0c1220;--s2:#111827;--b:#1e293b;--t:#e2e8f0;--d:#64748b;--cy:#22d3ee;--gn:#34d399;--am:#fbbf24;--rd:#f87171;--pu:#a78bfa;--bl:#60a5fa;--m:'JetBrains Mono',monospace;--f:'DM Sans',sans-serif}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
margin: 0;
padding: 20px;
background:#060a14;
min-height: 100vh;
color: white;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
header {
text-align: center;
margin-bottom: 40px;
padding: 20px;
background: rgba(255,255,255,0.1);
border-radius: 15px;
backdrop-filter: blur(10px);
}
h1 {
font-size: 2.5em;
margin-bottom: 10px;
}
.status {
display: inline-block;
padding: 5px 15px;
background: #060a14;
border-radius: 20px;
font-size: 0.9em;
font-weight: bold;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
margin-bottom: 40px;
}
.card {
background: rgba(255,255,255,0.1);
padding: 25px;
border-radius: 15px;
backdrop-filter: blur(10px);
transition: transform 0.3s ease;
}
.card:hover {
transform: translateY(-5px);
}
.card h3 {
margin-top: 0;
color: #fff;
}
.card p {
color: rgba(255,255,255,0.8);
line-height: 1.6;
}
.btn {
display: inline-block;
padding: 12px 25px;
background: #667eea;
color: white;
text-decoration: none;
border-radius: 8px;
font-weight: bold;
transition: background 0.3s ease;
margin-top: 15px;
}
.btn:hover {
background: #764ba2;
}
.api-status {
display: flex;
align-items: center;
margin: 10px 0;
}
.api-status .indicator {
width: 12px;
height: 12px;
border-radius: 50%;
margin-right: 10px;
}
.api-status.online .indicator { background: #060a14; }
.api-status.offline .indicator { background: #ef4444; }
footer {
text-align: center;
margin-top: 40px;
padding-top: 20px;
border-top: 1px solid rgba(255,255,255,0.2);
color: rgba(255,255,255,0.7);
}
.wv-status{position:fixed;top:12px;right:140px;z-index:9998;background:rgba(52,211,153,.15);border:1px solid #34d399;border-radius:12px;padding:3px 10px;color:#34d399;font-size:10px;font-weight:700;font-family:'JetBrains Mono',monospace}
</style>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&family=DM+Sans:wght@400;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="wevads-global.css?v1770777318">
</head>
<body>
<div class="container">
<header>
<h1>🧠 Weval Mind</h1>
<p>Système Autonome Arsenal/ADX</p>
<div class="status">✅ OPÉRATIONNEL</div>
</header>
<div class="grid">
<div class="card">
<h3>🚀 API Gateway</h3>
<p>Point d'entrée unique pour toutes les APIs Weval Mind</p>
<div class="api-status online">
<div class="indicator"></div>
<span>Port 80 - Actif</span>
</div>
<a href="/api/index.php" class="btn">Accéder à l'API</a>
</div>
<div class="card">
<h3>🤖 WEVAL IA Engine</h3>
<p>IA multi-provider avec cascade de fallback (3 providers)</p>
<div class="api-status online">
<div class="indicator"></div>
<span>DeepSeek + Ollama + Fallback</span>
</div>
<a href="/api/hamid-engine-simple.php" class="btn">Tester l'IA</a>
</div>
<div class="card">
<h3>🧠 Weval Mind Core</h3>
<p>Système autonome avec cycles d'analyse et réparation</p>
<div class="api-status online">
<div class="indicator"></div>
<span>Cycles automatiques actifs</span>
</div>
<a href="/api/weval-mind-core-simple.php?action=autonomous_cycle" class="btn">Lancer un cycle</a>
</div>
<div class="card">
<h3>🗄️ Base de données</h3>
<p>PostgreSQL avec schéma optimisé pour Weval Mind</p>
<div class="api-status online">
<div class="indicator"></div>
<span>adx_system - Connectée</span>
</div>
<a href="/api/api-gateway-light.php?module=health" class="btn">Vérifier santé</a>
</div>
<div class="card">
<h3>📊 Monitoring</h3>
<p>Health checks automatiques et logs temps réel</p>
<div class="api-status online">
<div class="indicator"></div>
<span>Cron jobs actifs</span>
</div>
<a href="/var/log/wevads/" class="btn">Voir les logs</a>
</div>
<div class="card">
<h3>🔗 Intégration Arsenal</h3>
<p>22 écrans connectés à l'API Gateway centralisée</p>
<div class="api-status online">
<div class="indicator"></div>
<span>API REST disponible</span>
</div>
<a href="/" class="btn">Dashboard principal</a>
</div>
</div>
<div class="card">
<h3>⚡ Tests rapides</h3>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px;">
<a href="/api/index.php/status" class="btn" style="background: #3b82f6;">Status système</a>
<a href="/api/index.php/health" class="btn" style="background: #060a14;">Health check</a>
<a href="/api/index.php/hamid/providers" class="btn" style="background: #8b5cf6;">Providers IA</a>
<a href="/api/index.php/mind/cycle" class="btn" style="background: #f59e0b;">Cycle autonome</a>
</div>
</div>
<footer>
<p>Weval Mind v1.0 - Système Autonome Arsenal/ADX</p>
<p>Port 80 | PostgreSQL 5432 | HAMID Engine 3 providers</p>
<p>© 2026 - Statut: <strong>PRODUCTION</strong></p>
</footer>
</div>
<script>
// Mettre à jour le statut en temps réel
async function updateStatus() {
try {
const response = await fetch('/api/api-gateway-light.php?module=status');
const data = await response.json();
// Mettre à jour le statut
if (data.status === 'operational') {
document.querySelector('.status').textContent = '✅ OPÉRATIONNEL';
document.querySelector('.status').style.background = '#060a14';
} else {
document.querySelector('.status').textContent = '⚠️ DÉGRADÉ';
document.querySelector('.status').style.background = '#f59e0b';
}
// Mettre à jour les métriques
document.querySelectorAll('.card')[3].querySelector('p').innerHTML =
`PostgreSQL avec ${data.metrics ? 'métriques temps réel' : 'schéma optimisé'} pour Weval Mind`;
} catch (error) {
console.log('Status update failed:', error);
}
}
// Mettre à jour toutes les 30 secondes
setInterval(updateStatus, 30000);
// Mettre à jour immédiatement au chargement
updateStatus();
</script>
<script src="arsenal-common.js?v1770778169"></script>
</body>
</html>
<script>window.location.replace("/menu.html");</script>

114
scripts/STRATEGIE_TEST.md Normal file
View File

@@ -0,0 +1,114 @@
# WEVAL — STRATEGIE DE TEST & NON-REGRESSION v3
## Lean Six Sigma + Theory of Constraints
## Instructions pour TOUS les Claude travaillant sur WEVAL
---
## PHILOSOPHIE: DMAIC + Theory of Constraints
### DMAIC (Lean Six Sigma)
- **D**efine: Chaque test = 1 fonctionnalite metier (pas technique)
- **M**easure: PASS/FAIL quantifiable, latence en ms, sigma calculee
- **A**nalyze: Les FAIL sont des goulots (ToC) a traiter en priorite absolue
- **I**mprove: Fix le goulot, relancer le test, valider 0 regression
- **C**ontrol: Nonreg tourne AVANT+APRES chaque modif, perpetuellement
### Theory of Constraints (ToC)
- Le systeme est aussi fort que son maillon le plus faible
- **Identifier** le goulot: la section avec le plus de FAIL
- **Exploiter**: STOP tout dev, fixer CE goulot
- **Subordonner**: pas de nouvelle feature tant que 0 FAIL
- **Elever**: si goulot persiste apres 3 fixes → refonte from scratch
- **Repeter**: le goulot suivant devient la nouvelle priorite
---
## COMMANDES DE TEST
### REGLE ABSOLUE: AVANT + APRES chaque modification
```bash
# S88 — WEVAL Workspace + WEVIA + Platform (101+ tests)
bash /opt/wevads-v2/nonreg-all.sh
# Inclut: Ethica passthrough (134 tests S89) + WEVIA deep (58 tests)
# S89 — Ethica Platform B2B (134 tests, 12 sections)
bash /opt/wevads/scripts/ethica-nonreg.sh
# ATTENDU: 0 FAIL sur les deux. WARN accepte si S202/S151 down.
```
---
## ARCHITECTURE DE TEST
### S88: nonreg-all.sh (~423 lignes, 12+ sections)
| Sec | Nom | Tests | ToC Role |
|-----|-----|-------|----------|
| 1 | Pages HTTP 200 | 62 | Smoke test front |
| 2 | APIs Health | 3 | Backend vitaux |
| 3 | Nginx + SSL | 2 | Infra securite |
| 4 | Services GPU | 2 | vLLM + WEVADS |
| 5 | PHP leaks | 1 | Qualite code |
| 6 | Interserveur | 2 | S89 + S202 |
| 7 | Chat Quality | 1 | Latence GPU <5s |
| 8 | Frontend Quality | 6 | Trust/demos/chat/count/JS/logos |
| 9 | MTA + Tracking | 22 | Bulk install + S3 |
| 10 | Ethica (S89) | 1→134 | Passthrough complet |
| 11 | WEVIA Deep | 1→58 | Files/turbo/PDF/schema/memory |
### S89: ethica-nonreg.sh (168 lignes, 134 tests, 12 sections)
| Sec | Nom | Tests | Quoi |
|-----|-----|-------|------|
| 1 | Pages HTTP | 11 | Ethica pages 200 |
| 2 | APIs Core | 10 | Brands, specialites, tracking |
| 3 | Tracking | 11 | Email + SMS + WhatsApp |
| 4 | Data | 10 | Brands, countries, HCPs |
| 5 | DB Schema | 17 | Tables PostgreSQL |
| 6 | V3 UI | 17 | Composants UI V3 |
| 7 | Campaign UX | 16 | SMS + WA + Email creator |
| 8 | External | 3 | Endpoints externes |
| 9 | Consent | 4 | RGPD consentement |
| 10 | Services | 6 | Infra |
| 11 | Performance | 6 | < 2s |
| 12 | PHP Syntax | 13+ | Validation |
### S88: wevia-nonreg.sh (107 lignes, 58 tests, 8 sections)
| Sec | Nom | Tests | Quoi |
|-----|-----|-------|------|
| 1 | Files | 10 | PHP/Python present |
| 2 | HTML/JS | ~8 | wevia.html valide |
| 3 | Services | ~4 | GPU + PHP-FPM |
| 4 | Turbo x12 | 12 | 12 domaines chat |
| 5 | Schemas x4 | 4 | Mermaid gen |
| 6 | Logos | ~2 | SVG gen |
| 7 | PDFs x8 | 8 | ProposalAI/BlueprintAI/6Sigma/SWOT/RACI/8D/Impact/Audit |
| 8 | Memory | ~6 | CID + recall + sanitizer |
---
## 4 SERVEURS
| Serveur | IP:Port | Role | Nonreg |
|---------|---------|------|--------|
| S88 | 88.198.4.195:22 | Main: Workspace+WEVIA+GPU RTX4000 | nonreg-all.sh |
| S89 | 89.167.40.150:5890 | Sentinel+PostgreSQL+Ethica | ethica-nonreg.sh |
| S202 | 204.168.152.13:49222 | PMTA v5+Postfix | - |
| S151 | 151.80.235.110 | Tracking (DOWN) | - |
## PATTERN SSH
```bash
curl -s -X POST "http://89.167.40.150:5890/api/sentinel-brain.php" \
--data-urlencode "action=exec" \
--data-urlencode "cmd=SSHPASS='NKPwP4%M9PBdw' sshpass -e ssh -o StrictHostKeyChecking=no root@88.198.4.195 'CMD'"
```
## REGLES GOLD
1. GPU local 1er (vLLM qwen2.5-14b) — cloud = fallback
2. GOLD backup AVANT toute modification
3. Scanner existant AVANT creer (ls+wc+head+diff)
4. Refonte > patch apres 3 echecs
5. France . Maroc . USA dans tout le discours
6. 44 produits partout (Platform = source de verite)
7. 0 regression — nonreg PASS obligatoire
8. Goulot = priorite absolue (ToC)
9. Chaque nouvelle feature = au moins 1 nouveau test
10. JAMAIS supprimer un test existant

6
scripts/pre-install-server.sh Executable file
View File

@@ -0,0 +1,6 @@
#!/bin/bash
# Pre-install hook for iResponse bulk install
IP=$1; PASS=$2; PORT=${3:-22}; USER=${4:-root}
echo "[PRE-INSTALL] Preparing $IP..."
SSHPASS="$PASS" sshpass -e ssh -o StrictHostKeyChecking=no -o ConnectTimeout=15 -p $PORT $USER@$IP 'export DEBIAN_FRONTEND=noninteractive; echo "DEBIAN_FRONTEND=noninteractive" >> /etc/environment; mkdir -p /etc/dpkg/dpkg.cfg.d /etc/apt/apt.conf.d /etc/needrestart/conf.d; printf "force-confold\nforce-confdef\n" > /etc/dpkg/dpkg.cfg.d/force-confold; echo "Dpkg::Options {\"--force-confdef\";\"--force-confold\";};" > /etc/apt/apt.conf.d/99force-conf; echo "APT::Get::Assume-Yes \"true\";" >> /etc/apt/apt.conf.d/99force-conf; echo "\$nrconf{restart} = \"a\";" > /etc/needrestart/conf.d/50local.conf; apt-get remove -y needrestart 2>/dev/null; dpkg --configure -a 2>/dev/null; apt-get install -f -y 2>/dev/null; add-apt-repository -y ppa:ondrej/php 2>/dev/null; apt-get update -qq 2>/dev/null; echo PRE_INSTALL_READY' 2>&1
echo "[PRE-INSTALL] Done for $IP"