V1.22.23 Passage à Claude Code et création du BackOffice

This commit is contained in:
2026-09-11 13:38:34 +00:00
parent a9af2a5213
commit 05df1c5a28
28 changed files with 2660 additions and 670 deletions
+70 -26
View File
@@ -7,34 +7,53 @@
* futurs utilisateurs, sur le même principe que dictees_test.php/
* contact_ia_test.html : un outil de mise au point réservé à Jean-Marc.
*
* Lit/écrit une nouvelle colonne AGN_Identite (texte libre : parcours de vie,
* expérience professionnelle, traits de caractère) sur ASP_Agents — même
* principe qu'AGN_Variantes/AGN_Photo, colonne éditée à la main par Jean-Marc
* en base avant tout premier essai :
* Lit/écrit deux colonnes texte libre sur ASP_Agents, éditées à la main par
* Jean-Marc en base avant tout premier essai — même principe qu'AGN_Variantes/
* AGN_Photo :
*
* ALTER TABLE ASP_Agents
* ADD COLUMN AGN_Identite TEXT NULL DEFAULT NULL AFTER AGN_Couleur;
*
* Colonne élargie de TEXT à MEDIUMTEXT le 10 septembre 2026 (soir), à la
* demande de Jean-Marc — ce texte est voué à s'enrichir avec l'usage réel de
* l'application (missions, réunions, compétences acquises...) plutôt qu'à
* rester une biographie figée écrite une fois, donc les 65 535 octets d'un
* TEXT auraient fini par devenir un plafond réel :
* - AGN_Identite : parcours de vie, expérience professionnelle, traits de
* caractère — écrit par Jean-Marc lui-même via "Construire une identité".
* - AGN_Experience (ajoutée le 10 septembre 2026, soir, réflexions
* stratégiques section 20 — "il commence à dériver un peu... mais surtout,
* je donne de vrais informations concernant mon projet et c'est un peu
* idiot de les perdre") : ce que le collaborateur retient au fil des
* discussions réelles eues avec lui via "Tester l'identité" — alimentée
* automatiquement, tour par tour, par collaborateur_experience_append.php
* pendant le dialogue ; "Modifier l'expérience" (même mécanique que
* "Construire une identité", voir plus bas) permet ensuite à Jean-Marc de
* faire le ménage dans ce texte brut (retirer ce qui concerne uniquement
* la mise au point de l'identité elle-même, pas un vrai contenu de projet).
*
* Colonne AGN_Identite élargie de TEXT à MEDIUMTEXT le 10 septembre 2026
* (soir), à la demande de Jean-Marc — ce texte est voué à s'enrichir avec
* l'usage réel de l'application (missions, réunions, compétences acquises...)
* plutôt qu'à rester une biographie figée écrite une fois, donc les 65 535
* octets d'un TEXT auraient fini par devenir un plafond réel :
*
* ALTER TABLE ASP_Agents
* MODIFY COLUMN AGN_Identite MEDIUMTEXT NULL DEFAULT NULL;
*
* AGN_Experience posée directement en MEDIUMTEXT dès sa création (même
* raisonnement, encore plus vrai pour un texte accumulé au fil des sessions) :
*
* ALTER TABLE ASP_Agents
* ADD COLUMN AGN_Experience MEDIUMTEXT NULL DEFAULT NULL AFTER AGN_Identite;
*
* (voir aussi TEXTE_IDENTITE_MAX_OCTETS dans ecran_fond.html, qui reflète
* cette même limite côté indicateur de saisie.)
* cette même limite côté indicateur de saisie — partagé par les deux champs.)
*
* Volontairement séparé d'agents.php : celui-ci reste l'endpoint de lecture
* publique consommé par ecran_fond.html (portraits, couleurs, rôles) — jamais
* question qu'AGN_Identite y transite, puisque cette donnée doit rester
* invisible d'un utilisateur ordinaire (décision explicite de Jean-Marc,
* réflexions stratégiques section 20 : l'identité de chaque collaborateur
* n'est pas consultable telle quelle, seule une présentation synthétisée par
* le collaborateur lui-même pourra un jour en être tirée, dans une future
* Mission — voir réflexions stratégiques section 18).
* question qu'AGN_Identite ou AGN_Experience y transitent, puisque ces deux
* données doivent rester invisibles d'un utilisateur ordinaire (décision
* explicite de Jean-Marc, réflexions stratégiques section 20 : l'identité de
* chaque collaborateur n'est pas consultable telle quelle, seule une
* présentation synthétisée par le collaborateur lui-même pourra un jour en
* être tirée, dans une future Mission — voir réflexions stratégiques section
* 18). Même principe pour AGN_Experience, par cohérence.
*
* Accès : simple session ouverte, même principe que tous les autres endpoints
* du projet (contacts.php, todolist.php...) — PAS de vérification renforcée
@@ -75,7 +94,7 @@ $method = $_SERVER['REQUEST_METHOD'];
if ($method === 'GET') {
try {
$stmt = $pdo->query(
'SELECT AGN_Incr, AGN_Prenom, AGN_Fonction, AGN_Photo, AGN_Couleur, AGN_Identite
'SELECT AGN_Incr, AGN_Prenom, AGN_Fonction, AGN_Photo, AGN_Couleur, AGN_Identite, AGN_Experience
FROM ASP_Agents ORDER BY AGN_OrdreAffichage ASC'
);
echo json_encode(['collaborateurs' => $stmt->fetchAll()]);
@@ -89,19 +108,42 @@ if ($method === 'GET') {
if ($method === 'PUT') {
$data = json_decode(file_get_contents('php://input'), true) ?? [];
$incr = (int) ($data['AGN_Incr'] ?? 0);
// Champ volontairement libre, sans limite de longueur imposée ici
// (MEDIUMTEXT côté base, voir en-tête) : une identité bien écrite peut
// dépasser largement la taille d'un champ de fiche habituel (Nom,
// Ville...) de ce projet, et grandira encore avec l'usage réel de
// l'application — le seul garde-fou vit côté front-end (voir
// TEXTE_IDENTITE_MAX_OCTETS/compteur-identite dans ecran_fond.html).
$identite = trim((string) ($data['AGN_Identite'] ?? ''));
// Un seul des deux champs à la fois dans le corps de la requête — jamais
// les deux ensemble côté front (voir champActif dans ecran_fond.html :
// "Construire une identité" édite AGN_Identite, "Modifier l'expérience"
// édite AGN_Experience, jamais les deux dans le même écran). Whitelist
// stricte plutôt qu'un nom de colonne construit depuis une clé arbitraire
// du JSON reçu, même si en pratique cette donnée ne vient jamais
// d'ailleurs que du front interne — même esprit défensif que le reste du
// projet (voir contacts.php, contact_ia_interprete.php).
$champsAutorises = ['AGN_Identite', 'AGN_Experience'];
$champ = null;
foreach ($champsAutorises as $c) {
if (array_key_exists($c, $data)) {
$champ = $c;
break;
}
}
if ($incr <= 0) {
http_response_code(400);
echo json_encode(['error' => 'AGN_Incr manquant ou invalide']);
exit;
}
if ($champ === null) {
http_response_code(400);
echo json_encode(['error' => 'Aucun champ à mettre à jour (AGN_Identite ou AGN_Experience attendu)']);
exit;
}
// Champ volontairement libre, sans limite de longueur imposée ici
// (MEDIUMTEXT côté base, voir en-tête) : une identité — ou une expérience
// accumulée — bien écrite peut dépasser largement la taille d'un champ de
// fiche habituel (Nom, Ville...) de ce projet, et grandira encore avec
// l'usage réel de l'application — le seul garde-fou vit côté front-end
// (voir TEXTE_IDENTITE_MAX_OCTETS/compteur-identite dans ecran_fond.html).
$valeur = trim((string) ($data[$champ] ?? ''));
try {
// Existence vérifiée par un SELECT séparé plutôt que sur rowCount() de
@@ -116,8 +158,10 @@ if ($method === 'PUT') {
exit;
}
$stmt = $pdo->prepare('UPDATE ASP_Agents SET AGN_Identite = ? WHERE AGN_Incr = ?');
$stmt->execute([$identite !== '' ? $identite : null, $incr]);
// $champ vient exclusivement de $champsAutorises ci-dessus, jamais
// directement de $data : interpolation sans risque d'injection.
$stmt = $pdo->prepare("UPDATE ASP_Agents SET {$champ} = ? WHERE AGN_Incr = ?");
$stmt->execute([$valeur !== '' ? $valeur : null, $incr]);
echo json_encode(['success' => true]);
} catch (PDOException $e) {
http_response_code(500);