setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $action = $_GET['action'] ?? 'status'; switch($action) { case 'validate_token': $token = $_GET['token'] ?? ''; if(!$token || $token==='TEST'){ echo json_encode(["ok"=>false,"error"=>"Invalid token"]); break; } $st = $db->prepare("SELECT ct.id, ct.medecin_id, ct.status as token_status, ct.channel, m.nom, m.prenom, m.specialite, m.ville, m.pays, m.email, m.telephone, m.consent_status FROM ethica.consent_tokens ct JOIN ethica.medecins_real m ON m.id = ct.medecin_id WHERE ct.token = ?"); $st->execute([$token]); $row = $st->fetch(PDO::FETCH_ASSOC); if(!$row){ echo json_encode(["ok"=>false,"error"=>"Token not found"]); break; } echo json_encode([ "ok" => true, "hcp" => [ "nom" => $row['nom'], "prenom" => $row['prenom'], "specialite" => $row['specialite'], "ville" => $row['ville'], "pays" => $row['pays'], "email" => $row['email'] ? substr($row['email'],0,3).'***@'.explode('@',$row['email'])[1] : null, "telephone" => $row['telephone'] ? substr($row['telephone'],0,4).'****'.substr($row['telephone'],-2) : null ], "token_status" => $row['token_status'], "consent_status" => $row['consent_status'] ], JSON_PRETTY_PRINT); break; case 'submit_consent': $input = json_decode(file_get_contents('php://input'), true); $token = $input['token'] ?? $_GET['token'] ?? ''; $consent = $input['consent'] ?? $_GET['consent'] ?? 'optin'; $channels = $input['channels'] ?? ['email']; $ip = $_SERVER['REMOTE_ADDR'] ?? ''; if(!$token){ echo json_encode(["ok"=>false,"error"=>"Token required"]); break; } // Get HCP from token $st = $db->prepare("SELECT medecin_id FROM ethica.consent_tokens WHERE token = ?"); $st->execute([$token]); $tid = $st->fetchColumn(); if(!$tid){ echo json_encode(["ok"=>false,"error"=>"Invalid token"]); break; } $status = ($consent === 'optin') ? 'opted_in' : 'opted_out'; $method = 'web_form'; $channel_str = implode(',', $channels); // Update HCP consent $db->prepare("UPDATE ethica.medecins_real SET consent_status = ?, consent_date = NOW(), consent_method = ?, consent_source = ? WHERE id = ?")->execute([$status, $method, $channel_str, $tid]); // Update token $db->prepare("UPDATE ethica.consent_tokens SET status = ?, confirmed_at = NOW(), ip_address = ? WHERE token = ?")->execute([$status, $ip, $token]); // Log consent action $db->prepare("INSERT INTO ethica.consent_log (medecin_id, action, method, ip_address, channels, user_agent, created_at) VALUES (?, ?, 'web_form', ?, ?, ?, NOW())")->execute([ $tid, $consent, $ip, $channel_str, $_SERVER['HTTP_USER_AGENT'] ?? '' ]); echo json_encode([ "ok" => true, "consent" => $status, "channels" => $channels, "medecin_id" => (int)$tid, "ip" => $ip, "timestamp" => date('c') ], JSON_PRETTY_PRINT); break; case 'search': $q = trim($_GET['q'] ?? ''); if(strlen($q) < 3){ echo json_encode(["ok"=>false,"error"=>"Min 3 characters"]); break; } // Search by email or phone $st = $db->prepare("SELECT m.id, ct.token FROM ethica.medecins_real m LEFT JOIN ethica.consent_tokens ct ON ct.medecin_id = m.id AND ct.channel = 'email' WHERE (m.email = ? OR m.telephone = ?) LIMIT 1"); $st->execute([$q, $q]); $row = $st->fetch(PDO::FETCH_ASSOC); if($row && $row['token']){ echo json_encode(["ok"=>true,"token"=>$row['token']]); } elseif($row) { // HCP exists but no token — generate one $new_token = md5($row['id'] . time() . random_bytes(8)); $db->prepare("INSERT INTO ethica.consent_tokens (medecin_id, token, channel, status, created_at) VALUES (?, ?, 'email', 'pending', NOW())")->execute([$row['id'], $new_token]); echo json_encode(["ok"=>true,"token"=>$new_token]); } else { echo json_encode(["ok"=>false,"error"=>"Not found"]); } break; case 'stats': $total = (int)$db->query("SELECT count(*) FROM ethica.consent_tokens")->fetchColumn(); $opted_in = (int)$db->query("SELECT count(*) FROM ethica.medecins_real WHERE consent_status='opted_in'")->fetchColumn(); $opted_out = (int)$db->query("SELECT count(*) FROM ethica.medecins_real WHERE consent_status='opted_out'")->fetchColumn(); $pending = (int)$db->query("SELECT count(*) FROM ethica.consent_tokens WHERE status='pending'")->fetchColumn(); echo json_encode([ "ok" => true, "total_tokens" => $total, "opted_in" => $opted_in, "opted_out" => $opted_out, "pending" => $pending, "optin_rate" => $total > 0 ? round($opted_in / $total * 100, 1) : 0 ], JSON_PRETTY_PRINT); break; default: echo json_encode(["ok"=>false,"actions"=>["validate_token","submit_consent","search","stats"]]); }