Files
wevads-platform/scripts/api_domain-bridge.php
2026-02-26 04:53:11 +01:00

200 lines
9.7 KiB
PHP
Executable File

<?php
/**
* DOMAIN BRIDGE — Connects domains_pool (1183 domains) to ALL pipeline modules
* Links: Factory ↔ Brain ↔ Send ↔ Tracking ↔ Harvest
* Integrates: Cloudflare, FreeDNS, Namecheap, Office365
*/
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
try { $db = new PDO("pgsql:host=127.0.0.1;dbname=adx_system","postgres","");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(Exception $e) { die(json_encode(['error'=>$e->getMessage()])); }
$input = json_decode(file_get_contents('php://input'),true) ?: ($_POST ?: $_GET);
$action = $input['action'] ?? 'dashboard';
switch($action) {
case 'dashboard':
$pool = $db->query("SELECT status, COUNT(*) as c FROM admin.domains_pool GROUP BY status ORDER BY c DESC")->fetchAll(PDO::FETCH_ASSOC);
$providers = $db->query("SELECT provider, COUNT(*) as c FROM admin.domains_pool GROUP BY provider ORDER BY c DESC")->fetchAll(PDO::FETCH_ASSOC);
$office = intval($db->query("SELECT COUNT(DISTINCT split_part(admin_email,'@',2)) FROM admin.office_accounts WHERE status='active'")->fetchColumn());
$tracking = $db->query("SELECT COUNT(*) FROM admin.tracking_domains")->fetchColumn();
$total = $db->query("SELECT COUNT(*) FROM admin.domains_pool")->fetchColumn();
$dns_ok = $db->query("SELECT COUNT(*) FROM admin.domains_pool WHERE dns_complete=true")->fetchColumn();
echo json_encode([
'total_domains' => intval($total),
'dns_complete' => intval($dns_ok),
'by_status' => $pool,
'by_provider' => $providers,
'office_domains_active' => $office,
'tracking_domains' => intval($tracking),
'health' => intval($total) > 100 ? 'EXCELLENT' : (intval($total) > 10 ? 'GOOD' : 'LOW'),
'integration' => [
'cloudflare' => intval($db->query("SELECT COUNT(*) FROM admin.domains_pool WHERE zone_id IS NOT NULL AND zone_id!=''")->fetchColumn()),
'freedns' => intval($db->query("SELECT COUNT(*) FROM admin.domains_pool WHERE freedns_account_id IS NOT NULL")->fetchColumn()),
'office365' => intval($db->query("SELECT COUNT(*) FROM admin.domains_pool WHERE provider='office365'")->fetchColumn()),
]
]); break;
case 'select_for_send':
// Brain-aware domain selection for sending
$method = $input['method'] ?? 'o365_smtp';
$isp = $input['isp'] ?? '';
$exclude = $input['exclude_domains'] ?? [];
if(strpos($method,'o365') !== false) {
// Get O365 domain + matching active account
$sql = "SELECT dp.domain, oa.admin_email, oa.admin_password, oa.tenant_id
FROM admin.domains_pool dp
JOIN admin.office_accounts oa ON oa.id=dp.office_account_id
WHERE dp.status='ASSIGNED' AND dp.provider='office365' AND oa.status='active'";
if(!empty($exclude)) {
$placeholders = implode(',', array_fill(0, count($exclude), '?'));
$sql .= " AND dp.domain NOT IN ($placeholders)";
}
$sql .= " ORDER BY RANDOM() LIMIT 1";
$st = $db->prepare($sql);
$st->execute($exclude ?: []);
$d = $st->fetch(PDO::FETCH_ASSOC);
} else {
// PMTA / other: get any available domain
$d = $db->query("SELECT domain FROM admin.domains_pool WHERE status IN ('FREE','active','ACTIVE') ORDER BY RANDOM() LIMIT 1")->fetch(PDO::FETCH_ASSOC);
}
// Get matching persona
$persona = $db->query("SELECT first_name,last_name,email,country FROM admin.personas WHERE is_active=true ORDER BY RANDOM() LIMIT 1")->fetch(PDO::FETCH_ASSOC);
echo json_encode([
'domain' => $d ?? null,
'persona' => $persona,
'from_address' => ($persona && $d) ? strtolower($persona['first_name'].'.'.$persona['last_name']).'@'.($d['domain']??'') : ($d['email']??null),
'method' => $method
]); break;
case 'rotation_pool':
// Get N domains for batch sending (rotation)
$count = min(intval($input['count'] ?? 10), 50);
$method = $input['method'] ?? 'o365_smtp';
if(strpos($method,'o365') !== false) {
$domains = $db->query("SELECT dp.domain, oa.admin_email, oa.admin_password, oa.tenant_id
FROM admin.domains_pool dp
JOIN admin.office_accounts oa ON oa.id=dp.office_account_id
WHERE dp.status='ASSIGNED' AND oa.status='active'
ORDER BY RANDOM() LIMIT $count")->fetchAll(PDO::FETCH_ASSOC);
} else {
$domains = $db->query("SELECT domain FROM admin.domains_pool WHERE status IN ('FREE','active','ACTIVE') ORDER BY RANDOM() LIMIT $count")->fetchAll(PDO::FETCH_ASSOC);
}
// Get matching personas
$personas = $db->query("SELECT first_name,last_name,email,country FROM admin.personas WHERE is_active=true ORDER BY RANDOM() LIMIT $count")->fetchAll(PDO::FETCH_ASSOC);
echo json_encode([
'domains' => $domains,
'personas' => $personas,
'count' => count($domains),
'method' => $method
]); break;
case 'sync_inventory':
// Sync domains_pool stats into domain_inventory for backward compatibility
$db->exec("DELETE FROM admin.domain_inventory");
$db->exec("INSERT INTO admin.domain_inventory(name,status,registrar,dns_provider,created_at)
SELECT domain,
CASE WHEN status='ASSIGNED' THEN 'active' WHEN status='FREE' THEN 'available' ELSE lower(status) END,
CASE WHEN provider='office365' THEN 'namecheap' ELSE 'cloudflare' END,
CASE WHEN zone_id IS NOT NULL AND zone_id!='' THEN 'cloudflare' ELSE 'manual' END,
COALESCE(created_at, NOW())
FROM admin.domains_pool
WHERE status IN ('ASSIGNED','FREE','active','ACTIVE')
ON CONFLICT DO NOTHING");
$synced = $db->query("SELECT COUNT(*) FROM admin.domain_inventory")->fetchColumn();
echo json_encode(['synced'=>intval($synced),'status'=>'ok']); break;
case 'health_check':
// Full pipeline health check
$checks = [];
// Domain pool
$dp = intval($db->query("SELECT COUNT(*) FROM admin.domains_pool")->fetchColumn());
$checks['domain_pool'] = ['count'=>$dp, 'status'=>$dp>100?'OK':'LOW'];
// O365 accounts linked to domains
$linked = intval($db->query("SELECT COUNT(*) FROM admin.office_accounts oa WHERE oa.status='active' AND EXISTS(SELECT 1 FROM admin.domains_pool dp WHERE oa.id=dp.office_account_id)")->fetchColumn());
$total_o365 = intval($db->query("SELECT COUNT(*) FROM admin.office_accounts WHERE status='active'")->fetchColumn());
$checks['o365_domain_link'] = ['linked'=>$linked, 'total'=>$total_o365, 'status'=>$linked>0?'OK':'BROKEN'];
// Personas
$personas = intval($db->query("SELECT COUNT(*) FROM admin.personas WHERE is_active=true")->fetchColumn());
$checks['personas'] = ['count'=>$personas, 'status'=>$personas>=20?'OK':'LOW'];
// Brain configs
$winners = intval($db->query("SELECT COUNT(*) FROM admin.brain_send_configs WHERE is_winner=true")->fetchColumn());
$checks['brain_winners'] = ['count'=>$winners, 'status'=>$winners>5?'OK':'LOW'];
// Tracking
$tracking = intval($db->query("SELECT COUNT(*) FROM admin.tracking_domains")->fetchColumn());
$checks['tracking'] = ['count'=>$tracking, 'status'=>$tracking>0?'OK':'MISSING'];
// Send methods
$methods = intval($db->query("SELECT COUNT(*) FROM admin.send_methods WHERE is_active=true")->fetchColumn());
$checks['send_methods'] = ['active'=>$methods, 'status'=>$methods>2?'OK':'LOW'];
// Cloud providers
$clouds = intval($db->query("SELECT COUNT(*) FROM admin.cloud_providers WHERE is_active=true")->fetchColumn());
$checks['cloud_providers'] = ['count'=>$clouds, 'status'=>$clouds>5?'OK':'LOW'];
// N8N
$n8n = @file_get_contents("http://127.0.0.1:5678/healthz");
$checks['n8n'] = ['status'=>$n8n!==false?'OK':'DOWN'];
// PMTA
$pmta = @fsockopen('127.0.0.1', 25, $en, $es, 2);
$checks['pmta'] = ['status'=>$pmta?'OK':'DOWN'];
if($pmta) fclose($pmta);
$all_ok = !in_array('BROKEN', array_column($checks, 'status')) && !in_array('DOWN', array_column($checks, 'status'));
echo json_encode([
'pipeline_status' => $all_ok ? 'PRODUCTION_READY' : 'NEEDS_FIX',
'checks' => $checks,
'timestamp' => date('c')
]); break;
case 'providers':
// List all domain registrar/DNS integrations
echo json_encode([
'cloudflare' => [
'domains' => intval($db->query("SELECT COUNT(*) FROM admin.domains_pool WHERE zone_id IS NOT NULL AND zone_id!=''")->fetchColumn()),
'api' => 'https://api.cloudflare.com/client/v4/',
'actions' => ['dns_sync','zone_create','dns_add','dns_verify']
],
'freedns' => [
'domains' => intval($db->query("SELECT COUNT(*) FROM admin.domains_pool WHERE freedns_account_id IS NOT NULL")->fetchColumn()),
'api' => 'https://freedns.afraid.org/api/',
'actions' => ['subdomain_create','dns_update']
],
'namecheap' => [
'domains' => intval($db->query("SELECT COUNT(*) FROM admin.namecheap_domains")->fetchColumn()),
'api' => 'https://api.namecheap.com/xml.response',
'actions' => ['domain_purchase','dns_set','whois_guard']
],
'office365' => [
'domains' => intval($db->query("SELECT COUNT(*) FROM admin.domains_pool WHERE provider='office365'")->fetchColumn()),
'actions' => ['domain_verify','mx_setup','autodiscover','dkim_enable']
],
'n8n_workflows' => [
'dns_sync_cloudflare' => 'active',
'freedns_auto_creator' => 'active',
'o365_full_setup' => 'active'
]
]); break;
default:
echo json_encode(['actions'=>['dashboard','select_for_send','rotation_pool','sync_inventory','health_check','providers']]);
}
?>