200 lines
9.7 KiB
PHP
Executable File
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']]);
|
|
}
|
|
?>
|