mirror of
https://github.com/JMP-MS/ASPIC.git
synced 2026-10-27 16:07:10 +00:00
V1.006 Suite de l'intégration de la voix
This commit is contained in:
+180
@@ -0,0 +1,180 @@
|
||||
<?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 {
|
||||
$stmtDefaut = $pdo->query(
|
||||
"SELECT AGN_Nom 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_Nom 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]);
|
||||
Reference in New Issue
Block a user