mirror of
https://github.com/JMP-MS/ASPIC.git
synced 2026-10-27 14:57:09 +00:00
182 lines
7.9 KiB
PHP
182 lines
7.9 KiB
PHP
<?php
|
|
/**
|
|
* ASPIC — agent_notes.php
|
|
* (renommé le 2 septembre 2026, ex-lilou_notes.php — n'a plus de raison de
|
|
* porter le nom d'un seul agent maintenant que ASP_Agents en porte
|
|
* plusieurs, voir plus bas et journal section 27)
|
|
*
|
|
* Étape 1 du pilotage vocal, volontairement "sans interprétation" (1er
|
|
* septembre 2026, décision de Jean-Marc) : reçoit le texte dicté à un agent
|
|
* entre une phrase d'ouverture ("Lilou, ajoute une tâche...", "Viktor, un
|
|
* truc à faire...", "Lilou, note ça dans ma todolist...") et une phrase de
|
|
* clôture ("c'est tout Lilou") ou d'annulation ("Lilou annule"), et
|
|
* l'enregistre tel quel, ligne par ligne — aucune tentative de
|
|
* compréhension du CONTENU ici (demande explicite de Jean-Marc). Objectif :
|
|
* accumuler un vrai corpus d'essais réels avant de définir des règles
|
|
* d'interprétation (étape 2, envisagée via n8n, avec des règles modifiables
|
|
* par l'utilisateur — voir réflexions stratégiques, section 10).
|
|
*
|
|
* POST uniquement, corps JSON : { "agent": "...", "lignes": [...] }
|
|
*
|
|
* "agent" (ajouté le 2 septembre 2026, suite de ASP_Agents/CVX_AgentTraitant
|
|
* — voir journal section 27 et réflexions stratégiques) : nom de l'agent
|
|
* reconnu en tête de la phrase d'ouverture ("Viktor", "Matilda"...), un
|
|
* seul par lot puisqu'une notation entière s'adresse à un seul assistant.
|
|
* Copié tel quel dans CVX_AgentTraitant sur chaque ligne du lot (colonne
|
|
* plate, pas de table de lots séparée — cohérent avec le reste de cette
|
|
* table). Absent ou vide (compatibilité ascendante avec un micro.js pas
|
|
* encore au courant des autres agents) : on retombe sur l'agent marqué
|
|
* ASP_Agents.AGN_Defaut = 'O' — plus de nom d'agent figé en dur ici depuis
|
|
* le retrait de Lilou le 2 septembre 2026 (voir plus bas et journal
|
|
* section 27) : l'agent de repli peut changer sans toucher au code.
|
|
*
|
|
* Format de chaque entrée de "lignes" (évolution du 2 septembre 2026,
|
|
* demande de Jean-Marc) : soit un objet {"texte": "...", "type": "..."},
|
|
* soit une simple chaîne (compatibilité avec un ancien micro.js non
|
|
* redéployé — traitée alors comme une ligne de type "contenu"). Types
|
|
* possibles : "ouverture" (phrase déclenchante elle-même), "contenu"
|
|
* (dictée proprement dite), "cloture" ou "annulation" (phrase de fin,
|
|
* distinguées cette fois — contrairement au contenu, dont le traitement ne
|
|
* change pas selon clôture ou annulation, décision du 1er septembre
|
|
* inchangée). Objectif : qu'un futur robot sache, sans ré-analyser le texte
|
|
* brut, où commence/finit un lot, s'il doit être exécuté ou écarté, et à
|
|
* quel assistant le router (CVX_AgentTraitant).
|
|
*
|
|
* Stockage (2 septembre 2026, pivot décidé par Jean-Marc) : le fichier
|
|
* texte global (notes_lilou/dictees.txt) est abandonné — l'essai du matin
|
|
* même une fois le fichier créé manuellement à la racine n'a rien donné
|
|
* (voir journal, section 27), sans compter le souci de droits d'écriture
|
|
* sur notes_lilou/ jamais vraiment résolu. Chaque ligne est désormais
|
|
* enregistrée directement dans la table ASP_ConsignesVoix (une ligne =
|
|
* une consigne = une ligne de dictée), même pattern de connexion que les
|
|
* autres endpoints (todolist.php, contacts.php) via getDbConnection().
|
|
* Nom de table volontairement générique ("ConsignesVoix"), pas centré sur
|
|
* "Lilou" — l'assistante n'étant qu'une des interfaces possibles vers ce
|
|
* mécanisme.
|
|
*
|
|
* Session utilisateur : accès réservé aux utilisateurs identifiés, même
|
|
* principe que les autres endpoints (todolist.php, contacts.php...).
|
|
*/
|
|
|
|
session_start();
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
require __DIR__ . '/db.php';
|
|
|
|
if (empty($_SESSION['USR_Code'])) {
|
|
http_response_code(401);
|
|
echo json_encode(['error' => 'Non identifié — veuillez vous connecter.']);
|
|
exit;
|
|
}
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
http_response_code(405);
|
|
echo json_encode(['error' => 'Méthode non autorisée']);
|
|
exit;
|
|
}
|
|
|
|
$data = json_decode(file_get_contents('php://input'), true) ?? [];
|
|
$lignes = $data['lignes'] ?? [];
|
|
|
|
if (!is_array($lignes) || count($lignes) === 0) {
|
|
http_response_code(400);
|
|
echo json_encode(['error' => 'Aucune ligne à enregistrer']);
|
|
exit;
|
|
}
|
|
|
|
const TYPES_VALIDES = ['ouverture', 'contenu', 'cloture', 'annulation'];
|
|
|
|
try {
|
|
$pdo = getDbConnection();
|
|
} catch (PDOException $e) {
|
|
http_response_code(500);
|
|
echo json_encode(['error' => 'Connexion base de données impossible']);
|
|
exit;
|
|
}
|
|
|
|
$agent = trim((string) ($data['agent'] ?? ''));
|
|
if ($agent === '') {
|
|
// Agent par défaut piloté par la donnée (2 septembre 2026, décision de
|
|
// Jean-Marc : plus question de figer un nom d'agent en dur ici — après
|
|
// Lilou, retirée de ASP_Agents le même jour pour cause de confusions
|
|
// récurrentes, un prochain agent par défaut pourrait tout aussi bien
|
|
// changer). AGN_Defaut ('O'/'N') désigne l'agent de repli directement
|
|
// en base, modifiable par Jean-Marc sans toucher au code. Repli
|
|
// supplémentaire sur le premier agent de la table si aucun n'est
|
|
// marqué par défaut (ne devrait pas arriver en usage normal, simple
|
|
// filet de sécurité pour ne jamais laisser CVX_AgentTraitant vide).
|
|
try {
|
|
// AGN_Nom renommée AGN_Prenom en base (7 septembre 2026, nuit).
|
|
$stmtDefaut = $pdo->query(
|
|
"SELECT AGN_Prenom FROM ASP_Agents WHERE AGN_Defaut = 'O' ORDER BY AGN_Incr ASC LIMIT 1"
|
|
);
|
|
$agent = $stmtDefaut->fetchColumn();
|
|
if ($agent === false || $agent === '') {
|
|
$stmtPremier = $pdo->query('SELECT AGN_Prenom FROM ASP_Agents ORDER BY AGN_Incr ASC LIMIT 1');
|
|
$agent = $stmtPremier->fetchColumn();
|
|
}
|
|
} catch (PDOException $e) {
|
|
$agent = false;
|
|
}
|
|
if ($agent === false || $agent === '') {
|
|
$agent = 'Agent';
|
|
}
|
|
}
|
|
if (mb_strlen($agent) > 20) {
|
|
$agent = mb_substr($agent, 0, 20);
|
|
}
|
|
|
|
// Un seul horodatage pour tout le lot reçu dans cet appel (même principe
|
|
// que l'ancien fichier texte, qui datait le bloc entier plutôt que chaque
|
|
// ligne individuellement — les lignes d'un même lot ont été dictées à
|
|
// quelques secondes d'écart, la distinction n'aurait pas de sens).
|
|
$horodatage = date('Y-m-d H:i:s');
|
|
$codeUser = $_SESSION['USR_Code'];
|
|
|
|
$stmt = $pdo->prepare(
|
|
'INSERT INTO ASP_ConsignesVoix (CVX_Consigne, CVX_Type, CVX_DateHeure, CVX_CodeUser, CVX_AgentTraitant) VALUES (?, ?, ?, ?, ?)'
|
|
);
|
|
|
|
$enregistrees = 0;
|
|
try {
|
|
foreach ($lignes as $entree) {
|
|
// Accepte un objet {texte, type} (nouveau format) ou une simple
|
|
// chaîne (ancien format, avant l'ajout du type par ligne) —
|
|
// traitée alors comme une ligne de contenu ordinaire.
|
|
if (is_array($entree)) {
|
|
$texte = trim((string) ($entree['texte'] ?? ''));
|
|
$type = (string) ($entree['type'] ?? 'contenu');
|
|
} else {
|
|
$texte = trim((string) $entree);
|
|
$type = 'contenu';
|
|
}
|
|
|
|
if ($texte === '') {
|
|
continue;
|
|
}
|
|
if (!in_array($type, TYPES_VALIDES, true)) {
|
|
$type = 'contenu';
|
|
}
|
|
// CVX_Consigne est un varchar(200) : une dictée plus longue est
|
|
// tronquée plutôt que de faire échouer tout le lot (mb_substr pour
|
|
// ne pas couper un caractère accentué en deux) — pas de perte
|
|
// totale d'une ligne pour un dépassement de quelques caractères.
|
|
if (mb_strlen($texte) > 200) {
|
|
$texte = mb_substr($texte, 0, 200);
|
|
}
|
|
$stmt->execute([$texte, $type, $horodatage, $codeUser, $agent]);
|
|
$enregistrees++;
|
|
}
|
|
} catch (PDOException $e) {
|
|
http_response_code(500);
|
|
echo json_encode(['error' => 'Erreur base de données : ' . $e->getMessage()]);
|
|
exit;
|
|
}
|
|
|
|
if ($enregistrees === 0) {
|
|
http_response_code(400);
|
|
echo json_encode(['error' => 'Aucune ligne à enregistrer']);
|
|
exit;
|
|
}
|
|
|
|
echo json_encode(['success' => true, 'lignes_enregistrees' => $enregistrees]);
|