$ok, 'message'=>$msg] + $extra); exit; } if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') out(false, 'Méthode invalide'); $praticien_id = (int)($_SESSION['reference_id'] ?? 0); $csrf = (string)($_POST['csrf'] ?? ''); if (!$praticien_id || !hash_equals($_SESSION['cl_csrf'] ?? '', $csrf)) { out(false, 'CSRF/Unauthorized'); } $note_id = (int)($_POST['note_id'] ?? 0); if ($note_id <= 0) out(false, 'Requête invalide'); try { // Vérifier que la note appartient bien au praticien $check = $pdo->prepare(" SELECT s.id, s.dossier_id FROM client_suivi s JOIN client_dossiers d ON d.id = s.dossier_id WHERE s.id = :id AND d.praticien_id = :p AND d.archived_at IS NULL LIMIT 1 "); $check->execute([':id'=>$note_id, ':p'=>$praticien_id]); $own = $check->fetch(PDO::FETCH_ASSOC); if (!$own) out(false, 'Accès refusé'); // Récupérer la liste des fichiers pour suppression disque après commit $files = []; $sf = $pdo->prepare("SELECT id, path FROM client_suivi_files WHERE entry_id = :e"); $sf->execute([':e'=>$note_id]); while ($row = $sf->fetch(PDO::FETCH_ASSOC)) { $files[] = (string)$row['path']; } $pdo->beginTransaction(); // Supprimer lignes fichiers BDD puis la note $pdo->prepare("DELETE FROM client_suivi_files WHERE entry_id = :e")->execute([':e'=>$note_id]); $pdo->prepare("DELETE FROM client_suivi WHERE id = :id")->execute([':id'=>$note_id]); $pdo->commit(); // Suppression physique (best-effort) après commit $root = rtrim((string)$_SERVER['DOCUMENT_ROOT'], '/'); foreach ($files as $rel) { $abs = $root.$rel; if (is_file($abs)) @unlink($abs); } out(true, 'Note supprimée'); } catch (Throwable $e) { if ($pdo->inTransaction()) $pdo->rollBack(); error_log('ajax_supprimer_note: '.$e->getMessage()); out(false, 'Erreur serveur'); }