146 lines
8.3 KiB
PHP
146 lines
8.3 KiB
PHP
<?php
|
|
/** EM Webhooks V2: docx case study + stripe + cloudflare + video + nonreg */
|
|
header("Content-Type: application/json");
|
|
$action = $_GET["action"] ?? $_POST["action"] ?? "";
|
|
|
|
$DB = ["pgsql:host=127.0.0.1;port=5432;dbname=adx_system", "admin", "admin123"];
|
|
try { $pdo = new PDO($DB[0], $DB[1], $DB[2], [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); }
|
|
catch (Exception $e) { http_response_code(500); echo json_encode(["error"=>"db-unreachable"]); exit; }
|
|
|
|
$secrets = [];
|
|
if (file_exists("/etc/weval/secrets.env")) {
|
|
foreach (file("/etc/weval/secrets.env", FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES) as $l) {
|
|
if (preg_match('/^([A-Z_]+)=(.+)$/', $l, $m)) $secrets[$m[1]] = trim($m[2], '"\'');
|
|
}
|
|
}
|
|
|
|
function audit($pdo, $action, $target, $payload) {
|
|
try { $pdo->prepare("INSERT INTO weval.audit_log (tenant_id, actor, action, target, payload, ip) VALUES (?,?,?,?,?,?)")->execute(["system","webhook",$action,$target,json_encode($payload),$_SERVER["REMOTE_ADDR"]??""]); } catch (Exception $e) {}
|
|
}
|
|
|
|
switch ($action) {
|
|
|
|
case "stripe":
|
|
$payload = file_get_contents("php://input");
|
|
$event = json_decode($payload, true);
|
|
if (!$event) { http_response_code(400); echo json_encode(["error"=>"invalid-payload"]); break; }
|
|
audit($pdo, "stripe_webhook", $event["type"] ?? "unknown", ["id"=>$event["id"]??""]);
|
|
if (($event["type"] ?? "") === "checkout.session.completed") {
|
|
$sess = $event["data"]["object"] ?? [];
|
|
$email = $sess["customer_details"]["email"] ?? "demo@example.com";
|
|
$name = $sess["metadata"]["company"] ?? "New Client";
|
|
$plan = $sess["metadata"]["plan"] ?? "mvp";
|
|
$tenant_id = "em_" . substr(md5($email . time()), 0, 10);
|
|
$pdo->prepare("INSERT INTO weval.tenants (tenant_id, name, plan_code, phase, contact_email) VALUES (?,?,?,?,?) ON CONFLICT (tenant_id) DO UPDATE SET phase=EXCLUDED.phase")->execute([$tenant_id, $name, $plan, $plan, $email]);
|
|
$n = $plan === "enterprise" ? 15 : ($plan === "mvp" ? 5 : 1);
|
|
$pdo->prepare("INSERT INTO weval.vsm_dept (tenant_id, dept_code, dept_name, icon, supplier, input, process, output, customer, kpis, agents) SELECT ?, dept_code, dept_name, icon, supplier, input, process, output, customer, kpis, agents FROM weval.vsm_dept WHERE tenant_id='weval' LIMIT ? ON CONFLICT DO NOTHING")->execute([$tenant_id, $n]);
|
|
audit($pdo, "stripe_checkout_complete", $tenant_id, ["plan"=>$plan]);
|
|
echo json_encode(["ok"=>true,"tenant_id"=>$tenant_id,"plan"=>$plan]);
|
|
} else {
|
|
echo json_encode(["received"=>true,"type"=>$event["type"] ?? "unknown"]);
|
|
}
|
|
break;
|
|
|
|
case "cloudflare-dns":
|
|
$raw = json_decode(file_get_contents("php://input"), true) ?? $_POST;
|
|
$tenant = $raw["tenant"] ?? "demo";
|
|
$target_ip = "204.168.152.13";
|
|
$zone_id = $secrets["CF_ZONE_WEVUP"] ?? "53e067fbc5c532a1";
|
|
$cf_key = $secrets["CF_API_KEY"] ?? "";
|
|
$cf_email = $secrets["CF_EMAIL"] ?? "";
|
|
$dns_record = ["type"=>"A","name"=>"wevia-$tenant.wevup.app","content"=>$target_ip,"ttl"=>3600,"proxied"=>true];
|
|
if (!$cf_key) {
|
|
audit($pdo, "dns_create_stub", $tenant, $dns_record);
|
|
echo json_encode(["stub"=>true,"tenant"=>$tenant,"would_create"=>$dns_record]);
|
|
break;
|
|
}
|
|
$ch = curl_init("https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records");
|
|
curl_setopt_array($ch, [CURLOPT_POST=>1, CURLOPT_POSTFIELDS=>json_encode($dns_record), CURLOPT_HTTPHEADER=>["Content-Type: application/json", "X-Auth-Email: $cf_email", "X-Auth-Key: $cf_key"], CURLOPT_RETURNTRANSFER=>1, CURLOPT_TIMEOUT=>15]);
|
|
$resp = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
|
|
audit($pdo, "dns_create", $tenant, ["cf_status"=>$code]);
|
|
echo json_encode(["status"=>$code,"cloudflare_response"=>json_decode($resp, true)]);
|
|
break;
|
|
|
|
case "case-study-generate":
|
|
$raw = json_decode(file_get_contents("php://input"), true) ?? $_GET;
|
|
$tenant = $raw["tenant"] ?? "weval";
|
|
$vs = $raw["vs"] ?? null;
|
|
$arg = escapeshellarg($tenant);
|
|
if ($vs) $arg .= " " . escapeshellarg($vs);
|
|
$out = shell_exec("timeout 30 python3 /usr/local/bin/weval-case-study-generator.py $arg 2>&1");
|
|
if (preg_match('|OK (/var[^\s]+\.docx)|', $out, $mm)) {
|
|
$file = $mm[1];
|
|
audit($pdo, "case_study_generate", $tenant, ["vs"=>$vs,"file"=>$file,"format"=>"docx"]);
|
|
echo json_encode(["ok"=>true,"file"=>$file,"size"=>filesize($file),"format"=>"docx","download_path"=>$file]);
|
|
} else {
|
|
http_response_code(500);
|
|
echo json_encode(["error"=>"docx-generation-failed","log"=>substr($out, 0, 500)]);
|
|
}
|
|
break;
|
|
|
|
case "video-tour":
|
|
$raw = json_decode(file_get_contents("php://input"), true) ?? $_GET;
|
|
$tenant = $raw["tenant"] ?? "weval";
|
|
$cmd = "timeout 180 /usr/local/bin/weval-video-tour.sh " . escapeshellarg($tenant) . " >/var/log/weval-video-tour.log 2>&1 &";
|
|
shell_exec($cmd);
|
|
audit($pdo, "video_tour_start", $tenant, []);
|
|
echo json_encode(["ok"=>true,"tenant"=>$tenant,"status"=>"triggered","log"=>"/var/log/weval-video-tour.log","output_dir"=>"/var/www/weval/deliverables/$tenant/"]);
|
|
break;
|
|
|
|
case "nonreg-tenant":
|
|
$tenant = $_GET["tenant"] ?? "weval";
|
|
$checks = [];
|
|
$stmt = $pdo->prepare("SELECT COUNT(*) FROM weval.vsm_dept WHERE tenant_id=?");
|
|
$stmt->execute([$tenant]);
|
|
$checks[] = ["name"=>"vsm_depts","value"=>$stmt->fetchColumn(),"pass"=>true];
|
|
$stmt = $pdo->prepare("SELECT COUNT(*) FROM weval.dmaic_cycles WHERE tenant_id=?");
|
|
$stmt->execute([$tenant]);
|
|
$checks[] = ["name"=>"dmaic_cycles","value"=>$stmt->fetchColumn(),"pass"=>true];
|
|
$stmt = $pdo->prepare("SELECT COUNT(*) FROM weval.kaizen_events WHERE tenant_id=?");
|
|
$stmt->execute([$tenant]);
|
|
$checks[] = ["name"=>"kaizen","value"=>$stmt->fetchColumn(),"pass"=>true];
|
|
$stmt = $pdo->prepare("SELECT COUNT(*) FROM weval.muda_entries WHERE tenant_id=?");
|
|
$stmt->execute([$tenant]);
|
|
$checks[] = ["name"=>"muda","value"=>$stmt->fetchColumn(),"pass"=>true];
|
|
$stmt = $pdo->prepare("SELECT 1 FROM weval.tenants WHERE tenant_id=?");
|
|
$stmt->execute([$tenant]);
|
|
$exists = $stmt->fetchColumn() ? 1 : 0;
|
|
$checks[] = ["name"=>"tenant_exists","value"=>$exists,"pass"=>$exists===1];
|
|
$passed = count(array_filter($checks, fn($c)=>$c["pass"]));
|
|
echo json_encode(["tenant"=>$tenant,"checks"=>$checks,"pass"=>$passed,"total"=>count($checks),"score"=>round($passed/count($checks)*100)]);
|
|
break;
|
|
|
|
case "em-nonreg":
|
|
// Full EM NonReg - all APIs + core URLs
|
|
$results = [];
|
|
foreach (["plans","vsm","agents-registry","bpmn-routines","dmaic/weval","kpi/live","erp-connectors","ai-providers","industry-templates","scalability","muda","poka-yoke","kaizen","lean6sigma-dashboard"] as $ep) {
|
|
$ch = curl_init("https://weval-consulting.com/api/em/$ep");
|
|
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>1, CURLOPT_SSL_VERIFYPEER=>0, CURLOPT_FOLLOWLOCATION=>1, CURLOPT_TIMEOUT=>5]);
|
|
curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
|
|
$results[] = ["endpoint"=>"/api/em/$ep","http"=>$code,"pass"=>$code==200];
|
|
}
|
|
foreach (["vsm-hub.html","brain-center-tenant.html","dmaic-workbench.html","kpi-live-dashboard.html","onboarding-em.html","bpmn-studio-live.html","integrations-marketplace.html","lean6sigma-dashboard.html"] as $page) {
|
|
$ch = curl_init("https://weval-consulting.com/$page");
|
|
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>1, CURLOPT_SSL_VERIFYPEER=>0, CURLOPT_TIMEOUT=>5]);
|
|
curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
|
|
$results[] = ["endpoint"=>"/$page","http"=>$code,"pass"=>in_array($code,[200,302])];
|
|
}
|
|
$passed = count(array_filter($results, fn($r)=>$r["pass"]));
|
|
$total = count($results);
|
|
echo json_encode(["category"=>"EM","pass"=>$passed,"total"=>$total,"score"=>round($passed/$total*100),"fail"=>$total-$passed,"details"=>$results]);
|
|
break;
|
|
|
|
default:
|
|
echo json_encode([
|
|
"service" => "EM Webhooks V2",
|
|
"endpoints" => [
|
|
"POST /api/em-webhooks.php?action=stripe",
|
|
"POST /api/em-webhooks.php?action=cloudflare-dns",
|
|
"POST /api/em-webhooks.php?action=case-study-generate (docx)",
|
|
"POST /api/em-webhooks.php?action=video-tour",
|
|
"GET /api/em-webhooks.php?action=nonreg-tenant&tenant=X",
|
|
"GET /api/em-webhooks.php?action=em-nonreg"
|
|
]
|
|
]);
|
|
}
|