Guide utilisateur
Votre guide Visit Manager
1. Préparer Mon compte
Renseignez le domicile et vos lieux secondaires. Saisissez une adresse : une liste IGN/BAN apparaît après une courte pause. Sélectionnez une proposition puis double-cliquez dessus pour remplir les champs, ou utilisez Entrée / Valider cette adresse. Vérifiez le numéro, la commune et le code postal ; un résultat à la rue demande de compléter le numéro. Le complément bâtiment/cabinet reste saisi par vos soins. Les coordonnées GPS sont fournies pour les lieux et les comptes, pas inventées.
Définissez les jours de terrain, télétravail et repos, les horaires et la pause déjeuner. Choisissez une durée de visite par défaut de 5 à 480 minutes. Les modifications des paramètres peuvent retirer les visites futures et créer une sauvegarde ; les rendez-vous confirmés sont protégés. Lisez le message avant de modifier votre organisation.
2. Constituer le portefeuille
Filtrez par commune, nom ou priorité. Double-cliquez une ligne ou utilisez Modifier pour ouvrir la fiche. Enregistrez l'adresse, la dernière visite, les observations, la priorité, l'intérêt et la fréquence. Pour la durée : 0 reprend la durée de Mon compte ; une durée positive personnalise cette visite. Cochez Ne pas proposer de visite pour exclure un compte. Enregistrez la fiche. L'import CSV ajoute des lignes : vérifiez les doublons.
3. Simuler puis valider
Choisissez l'horizon et le mode automatique ou une sélection de comptes. Calculez la proposition et vérifiez les trajets, rendez-vous non placés et sources de calcul. Les comptes à la même adresse sont regroupés. Une estimation peut remplacer un trajet IGN indisponible. Les durées ne tiennent pas compte du trafic en direct.
La simulation ne modifie pas l'agenda. Utilisez le transfert explicite pour ajouter les rendez-vous ou remplacer ceux de l'horizon. Les rendez-vous confirmés ou réalisés sont protégés et les conflits doivent être résolus. Les rendez-vous transférés apparaissent aussi dans les fiches de comptes.
4. Utiliser l'agenda
Passez entre jour, semaine et mois. Faites défiler horizontalement les semaines et verticalement les horaires : l'en-tête reste visible. Double-cliquez une zone libre pour adapter une journée. Double-cliquez un rendez-vous pour voir compte, adresse, date, heures, durée et statut.
Confirmez un rendez-vous, retirez sa confirmation, enregistrez sa réalisation avec durée réelle et compte rendu, signalez une absence/indisponibilité ou annulez-le. Une absence ouvre la réorganisation. Une visite future ne peut pas être réalisée. Les simulations et archives sont consultables sans modification. Une annulation retire le rendez-vous planifié du compte ; les réalisations demeurent dans l'historique. Les visites passées non réalisées peuvent être annulées en groupe.
5. Sauvegarder et exporter
Sauvegardez un horizon depuis l'agenda pour conserver un instantané. Choisissez une sauvegarde pour la consulter. Pour ICS, sélectionnez les dates de début et de fin puis exportez. Importez le fichier dans votre calendrier habituel ; le comportement de remplacement dépend du logiciel destinataire. Il ne s'agit pas d'une synchronisation automatique. Les exports et impressions de tournées sont également disponibles.
6. Aide et limites
L'application reste sur le Mac local. Une session peut rester active 12 heures ; utilisez Déconnexion sur un poste partagé. Les abonnements et factures sont en préparation. Aucun paiement n'est activé. Si IGN est indisponible, réessayez ou saisissez manuellement et vérifiez la localisation avant de planifier. Contact éditeur : xtr-conseil@orange.fr. Le prompt de régénération accompagne cette version, mais Git reste la référence pour restaurer exactement le code.
Identité et connexion
Cliquez sur les initiales en haut à droite pour accéder à Mon compte et renseigner prénom/nom. Ces informations ne changent pas votre planning. Dans un autre navigateur, connectez-vous avec le compte existant ; ne recréez pas un compte avec la même adresse e-mail.
Sur téléphone
Utilisez Menu pour ouvrir une rubrique ou vous déconnecter. Les initiales donnent accès à Mon compte. Les tableaux et semaines d’agenda se parcourent horizontalement ; les formulaires s’adaptent à la largeur.
Mot de passe oublié
Sur la connexion, cliquez sur Mot de passe oublié, indiquez votre e-mail et demandez un code à l’administrateur local. Aucun e-mail automatique n’est envoyé. Saisissez le code reçu et deux fois le nouveau mot de passe (12 caractères minimum). Le code expire en 30 minutes ; toutes vos sessions seront fermées.
Tri et heure préférentielle
Tri du portefeuille : nom, commune, dernière visite ou prochaine visite planifiée, croissant/décroissant ; valeurs absentes toujours à la fin. La prochaine visite est un rendez-vous à venir de l’agenda validé, pas une échéance théorique. Heure préférentielle optionnelle par compte : le début doit respecter ± la tolérance du profil (30 min par défaut, 0 à 240). Les horaires d’ouverture, déjeuner et retour restent prioritaires ; si aucune place ne convient, le compte reste non planifié. Les anciennes tournées ne changent pas : régénérer la simulation. Aucun expéditeur XTR Conseil actif confirmé ; récupération locale conservée.
Tests à distance
La préproduction doit être activée par l’administrateur avant de disposer d’un lien. Utilisez le lien HTTPS et les identifiants individuels remis en privé. Le bandeau Préproduction signale les données fictives ; ne saisissez aucune donnée réelle. La création libre de comptes y est désactivée.
Rendez-vous fixes — version 0.12.0
Dans Mon agenda, double-cliquez sur une journée puis utilisez Ajouter un rendez-vous fixe. Saisissez l’intitulé, le début, la fin et le lieu (domicile ou localisation secondaire enregistrée dans Mon compte, avec recherche IGN/BAN). Plusieurs créneaux sont possibles, jusqu’à 24 par journée. Enregistrez la journée puis régénérez votre simulation.
Ces rendez-vous restent à leurs heures et lieux : le calcul réserve le temps nécessaire pour les rejoindre et repartir. Les visites commerciales sont proposées autour. Un itinéraire impossible produit une erreur ; aucun rendez-vous fixe n’est déplacé. Les créneaux doivent être dans les horaires de la journée, sans chevauchement entre eux ni avec le déjeuner : adaptez explicitement le déjeuner si nécessaire. Les journées non commerciales restent exclues des tournées.
Les créneaux apparaissent en couleur ocre dans l’agenda, même sans tournée, et sont inclus dans l’export ICS et les archives. Ils persistent après annulation des visites et rétablissement des paramètres par défaut. Pour les retirer, ouvrez la journée, utilisez Supprimer ce créneau, puis enregistrez. Comme les autres réglages journaliers, l’enregistrement archive et retire la tournée du jour à recalculer ; les visites confirmées restent protégées. Les rendez-vous fixes ne comptent pas comme visites de comptes et ne modifient pas leur dernière visite.
Portefeuille et entreprise — version 0.13.0
Le filtre « Visite » propose « Visiter », « Ne pas visiter » et « Tous ». Il se combine avec la recherche, la commune, la priorité et le statut. « Masquer les filtres » libère de la place sans supprimer les critères ni la sélection ; « Afficher les filtres » les réouvre. Mon compte comporte un champ Entreprise, facultatif, enregistré avec l’identité personnelle sans modifier l’agenda.
Le portefeuille de test a été complété à partir de l’extraction publique RPPS du 17 septembre 2026 : 1 717 fiches d’exercice, 1 542 praticiens, 127 communes de Haute-Garonne. Une fiche correspond à un praticien et une structure ; plusieurs lieux d’exercice produisent plusieurs comptes. Cette couverture dépend des données publiées, sans garantie d’exhaustivité terrain. Les comptes existants, observations et historiques sont conservés. Les données nominatives restent locales et hors Git.
Pour ce jeu de test, le secteur Est signifie : à l’est de l’Ariège, puis de la Garonne en aval de leur confluence, sans rayon de limitation. Les comptes localisés dans ce secteur sont cochés « Ne pas visiter ». Les exclusions existantes ailleurs sont conservées. Les adresses non résolues ne sont pas classées géographiquement et doivent être vérifiées ; une localisation à la rue reste approximative. La case d’exclusion reste modifiable dans chaque fiche.
Lieux et import calendrier — version 0.14.0
Dans Mon compte → Mes lieux, utilisez Ajouter un lieu, renseignez un nom (Bureau, Agence Sud, Domicile 2…), recherchez l’adresse IGN/BAN et validez une proposition pour remplir les champs complets et coordonnées. Enregistrez les paramètres. Le nom du lieu apparaît dans les sélections de départ, retour, déjeuner et rendez-vous fixe.
Dans un rendez-vous fixe, choisissez un lieu enregistré ou Autre lieu. Pour un lieu ponctuel, saisissez son nom et recherchez puis validez son adresse. Il appartient uniquement à ce rendez-vous et ne modifie pas vos lieux habituels. Les trajets utilisent ses coordonnées. Saisissez les heures au format HH:MM (9:30 est également accepté et enregistré 09:30). Les erreurs sont visibles dans la fenêtre : fin après début, horaires compris dans la journée, absence de chevauchement avec le déjeuner ou un autre rendez-vous fixe. Ajustez la pause de la journée si nécessaire.
Mon agenda → Importer un calendrier .ics permet de prévisualiser puis importer des rendez-vous fixes. Vérifiez les lieux, choisissez un lieu enregistré ou une adresse ponctuelle pour chaque ligne ; supprimez les lignes à ignorer. L’import est atomique : un conflit bloque tout le lot, sans ajout partiel. Les rendez-vous déjà importés avec la même identité et date de début sont ignorés. Les tournées non confirmées des jours concernés sont archivées puis retirées pour être recalculées ; les visites confirmées sont protégées.
Limites actuelles : fichier de 500 Ko et 200 rendez-vous maximum ; 24 créneaux fixes par jour. Import d’occurrences datées avec début et fin le même jour, à la minute, converties en Europe/Paris. Sans fuseau, l’heure est interprétée en Europe/Paris. Les séries récurrentes, journées entières et événements traversant minuit sont refusés explicitement : exporter des occurrences individuelles. Ce n’est pas une synchronisation directe avec Google, Apple ou Outlook. Une modification ultérieure du calendrier source ne met pas automatiquement à jour les événements importés.
Sauvegarde personnelle — version 0.15.0
Mon compte → Sauvegarder et restaurer mes données propose Exporter mes données et Importer une sauvegarde. Toutes les catégories disponibles sont cochées par défaut : paramètres/identité/lieux, comptes, agenda/congés/archives, visites réalisées/reports, simulations, facturation/abonnement. Décochez les catégories inutiles. L’export télécharge un fichier JSON Visit Manager ; le CSV reste destiné à l’import de comptes seulement.
L’import accepte une sauvegarde de votre espace actuel, pas celle d’un autre utilisateur. Sélectionnez le fichier et les catégories, puis Vérifier avant restauration. Le récapitulatif indique le nombre d’enregistrements par catégorie. Cochez la confirmation puis restaurez. Les catégories sélectionnées sont remplacées, même si leur contenu dans le fichier est vide ; les autres sont conservées. Une catégorie absente du fichier ne peut pas être sélectionnée. Les comptes avec des visites ou plannings associés exigent la restauration conjointe des catégories liées ; les paramètres nécessitent agenda et simulations si ces données existent. L’application refuse les dépendances incohérentes au lieu de perdre les liens.
Une copie complète de l’espace avant restauration est conservée localement dans data/.user-backups, avec accès restreint. Elle peut être réimportée pour revenir en arrière. La restauration est atomique et les autres utilisateurs restent intacts. Les mots de passe, sessions, codes de réinitialisation et caches techniques sont exclus ; l’adresse de connexion n’est pas modifiée. Les fichiers contiennent des données personnelles : conservez vos téléchargements dans un emplacement privé. Limite : 50 Mo par fichier. La sauvegarde locale automatique ne remplace pas une copie téléchargée hors de l’ordinateur.
Propriétaire du compte — version 0.16.0
Chaque fiche comporte un propriétaire commercial facultatif (150 caractères), visible dans la liste et inclus dans la recherche, l’import CSV via la colonne owner et les sauvegardes JSON. Ce libellé n’accorde aucun accès utilisateur. Dans le jeu de test Haute-Garonne, les comptes géolocalisés à l’ouest de l’Ariège puis de la Garonne sont attribués par défaut à Magalie Rousselin ; un propriétaire déjà renseigné est conservé. Les comptes Est et ceux sans coordonnées ne sont pas attribués automatiquement. Le préchargement RPPS applique la même règle.
Historique durable des rendez-vous — version 0.17.0
Dans Historique et visites, la rubrique Historique des rendez-vous passés permet de consulter une période. Elle conserve le nom et l’adresse connus au moment de l’archivage, les horaires, le type de rendez-vous, son statut et le compte rendu lorsqu’il existe. Les rendez-vous fixes sont inclus. Les rendez-vous prévus ou confirmés sans réalisation restent explicitement non renseignés ; le passage du temps ne les transforme jamais en visites réalisées.
Un registre historique dédié est conservé dans la base locale, séparément du planning actif. Il est alimenté au démarrage, à l’ouverture de l’espace et autour des modifications. Les anciennes versions d’un rendez-vous sont conservées ; la liste affiche son dernier état connu. Une remise à zéro, annulation ou recalcul ne supprime pas ce registre. Les anciens rendez-vous sont repris depuis les plannings, réalisations et archives encore disponibles ; les données déjà supprimées sans archive ne peuvent pas être reconstituées.
Le registre appartient à chaque utilisateur et fait partie de la catégorie Visites réalisées et reports des sauvegardes. Les sauvegardes JSON version 2 le contiennent ; les fichiers version 1 restent acceptés. Une restauration explicitement confirmée de cette catégorie remplace aussi son historique, avec la copie de sécurité préalable habituelle.
Préproduction accessible sur https://visit-manager.fr depuis le 17 septembre 2026. Déploiement OVH VPS avec Caddy HTTPS, service Python limité à la boucle locale, base de démonstration séparée et inscriptions publiques désactivées. Accès par identifiants individuels remis en privé ; portefeuille réel importable uniquement sur autorisation explicite. Sauvegarde SQLite quotidienne, conservation de 14 copies sur le VPS, en complément du backup OVH. La récupération automatique par e-mail reste non configurée.
Mise à jour bêta : sur demande explicite du propriétaire, le portefeuille réel peut être transféré vers son compte individuel. Exiger VISIT_STAGING_ACK=authorized-real-data et le marqueur staging_meta purpose=authorized-real-data correspondant ; demo-only reste le défaut pour les bases fictives. Conserver HTTPS, isolation par utilisateur et inscriptions fermées. Sauvegarder la base avant import et préserver les champs des comptes. Le bandeau indique désormais « Bêta privée ». Aucun secret ni export de données ne doit être déposé dans Git.
Présentation : en-tête de l’espace commercial réorganisé en deux groupes, navigation à gauche et langue/compte à droite. Espacements explicites, séparateur et adaptation sur deux lignes pour téléphone ; libellés français et anglais.
Version 0.18 — Rendez-vous à la même adresse
À chaque calcul de simulation ou recalcul après report, répondez à « Grouper les rendez-vous des comptes à la même adresse ? ». Accepter partage une seule durée standard de Mon compte entre les comptes éligibles dont la durée spécifique est zéro. Refuser conserve la durée complète de chaque visite. Trois comptes standards de 45 minutes prennent chacun 15 minutes ; deux standards prennent 23 et 22 minutes, plus la durée intégrale de tout compte personnalisé. L’arrondi à la minute conserve exactement le total. Une durée personnalisée reste individuelle même si elle est égale à la durée standard.
Les rendez-vous gardent leur compte, leur statut et leur historique individuels. Seuls les comptes sélectionnés, à visiter et disponibles sont inclus. Les heures d’ouverture, heures préférentielles, déjeuner et rendez-vous fixes restent respectés ; si le créneau commun est incompatible, les visites restent individuelles. Les groupes sont limités au nombre de minutes du créneau pour éviter une durée nulle. La réponse est conservée avec la simulation pour son enregistrement et son transfert à l’agenda, puis redemandée au prochain calcul.
Version 0.18.1 — Statut par double-clic
Dans l’agenda actuel, double-cliquez sur une visite puis choisissez son statut dans la liste : Planifié, Confirmé par le compte, Réalisé, Absent / à reprogrammer ou Annulé. Cliquez sur Enregistrer le statut. Réalisé ouvre la saisie de durée réelle et compte rendu et n’est disponible qu’à partir du jour du rendez-vous. Une absence ouvre la reprogrammation et une annulation demande confirmation. Les erreurs restent visibles dans la fiche. Simulations et archives restent en consultation ; les visites terminées conservent leur historique.
Version 0.18.2 — Lisibilité des trajets
Les trajets occupent la largeur disponible dans la colonne du jour, au lieu d’une bande de 16 pixels. Leurs heures de début et de fin apparaissent en premier, puis leur durée et leur adresse selon la hauteur disponible. Un trajet très court garde une hauteur proportionnelle à sa durée ; le survol ou le focus développe son détail. Les horaires et les données ne changent pas.
Version 0.18.3 — Sauvegarde des lieux
Dans Mon compte, « Sauvegarder mes lieux et paramètres » reste visible pendant le défilement ; un second bouton est disponible en bas. La saisie, l’ajout de lieu et le choix d’adresse IGN sont suivis comme modifications non sauvegardées. Quitter la rubrique, suivre un lien dans le même onglet ou se déconnecter demande confirmation : Non conserve la saisie, Oui abandonne. Échap équivaut à Non. Un nouvel appui sur Mon compte ne réinitialise pas le formulaire. Actualisation/fermeture : avertissement natif du navigateur, avec son propre texte. La protection disparaît après une sauvegarde réussie, reste après erreur et protège les changements effectués pendant un enregistrement. Elle concerne le formulaire des lieux et horaires ; les autres formulaires ont leur propre enregistrement.
Version 0.19 — Sauvegarde automatique
Les lieux et horaires de Mon compte sont sauvegardés en brouillon sur le serveur une seconde après la dernière modification. Une adresse incomplète est conservée sans être validée ; « Sauvegarder mes lieux et paramètres » applique explicitement le formulaire et conserve les contrôles habituels. Le brouillon revient à la prochaine ouverture de Mon compte. L’indicateur confirme la sauvegarde automatique ; en cas d’erreur réseau, gardez la page ouverte et réessayez en modifiant un champ. Une fermeture avant la fin de la sauvegarde déclenche l’avertissement du navigateur. Abandonner explicitement supprime le brouillon.
Chaque calcul réussi conserve automatiquement la dernière simulation par utilisateur. Elle est restaurée au chargement et consultable dans Agenda de simulation ; elle ne publie aucun rendez-vous. Vérifiez-la avant transfert, notamment après changement de paramètres. Les simulations nommées restent disponibles séparément. Les brouillons sont inclus dans les sauvegardes complètes du serveur, pas dans les exports JSON par catégorie. Un import utilisateur efface les brouillons pour éviter des références obsolètes. Deux onglets modifiant le même brouillon suivent la règle du dernier enregistrement ; utilisez un seul onglet de saisie.
Version 0.20 — Coordonnées des comptes
Les fiches et la liste du portefeuille affichent Téléphone professionnel, Mobile professionnel et E-mail professionnel, modifiables par compte. Le modèle CSV ajoute phone, mobile et professional_email sans renommer les colonnes existantes. Les sauvegardes JSON conservent ces champs.
Enrichissement administratif : scripts/enrich_contacts.py utilise l’Annuaire Santé RPPS (identifiant RPPS + structure) et Ameli (nom complet + voie normalisée + code postal + commune). Il complète uniquement les champs vides à partir de valeurs publiques non ambiguës, classe les numéros français 06/07 comme mobiles professionnels publiés, conserve les saisies et trace la source et la date de vérification par champ. Aucun e-mail déduit, aucune messagerie MSSanté ajoutée pour le contact commercial. Mode prévisualisation par défaut ; --apply crée une sauvegarde SQLite puis met à jour uniquement l’utilisateur sélectionné, sans modifier son agenda, ses notes ou ses propriétaires. Fichiers sources et bases privés, exclus de Git. Sources : https://www.data.gouv.fr/datasets/annuaire-sante-ameli et https://www.data.gouv.fr/datasets/annuaire-sante-extractions-des-donnees-en-libre-acces-des-professionnels-intervenant-dans-le-systeme-de-sante-rpps.
Version 0.21.0 — licences équipe et listes professionnelles IA
La page /licence présente les abonnements individuels et deux packs exclusivement annuels : jusqu’à 5 utilisateurs, titulaire inclus, à 699 € TTC proposés ; jusqu’à 10 à 1 199 € TTC proposés. Ces prix restent à valider commercialement avant activation. Au-delà de 10 utilisateurs, le site invite à contacter XTR Conseil. Le titulaire ajoute ou retire des utilisateurs déjà inscrits. Les espaces restent privés et séparés. Le contrôle du nombre de places est effectué côté serveur. Les tarifs et descriptions FR/EN se modifient dans l’administration ; un prix zéro masque l’offre.
La page /administration est réservée aux e-mails administrateurs configurés sur le serveur. Elle présente utilisateurs, blocage, attribution gratuite, réinitialisation de mot de passe, estimation du stockage, consultations de l’espace, commandes, factures, tarifs et listes IA. Une attribution gratuite n’émet pas de facture acquittée. Les paiements manuels demandent une référence et une confirmation de réception. Les factures PDF sont générées depuis un instantané de commande et restent conservées ; les données JSON préparent le raccordement à une plateforme agréée de facturation électronique, sans réaliser cette transmission.
Pour constituer une liste IA : choisir une profession et une zone, définir 1 à 100 résultats, fournir si nécessaire un texte public, construire et modifier le prompt, puis le mémoriser. Dans Fournisseurs, enregistrer le modèle exact et la clé API OpenAI, Claude, DeepSeek ou Gemini. La clé est chiffrée côté serveur et n’est jamais renvoyée à l’interface. Le lancement demande confirmation d’un appel potentiellement facturable. OpenAI utilise la recherche web si le modèle l’accepte ; les trois autres connecteurs analysent le texte source fourni sans navigation web dans cette version. Un résultat peut être vide et n’est jamais présenté comme exhaustif ou certifié.
Les résultats restent dans une liste à vérifier. Ouvrir les sources, vérifier les coordonnées, sélectionner les comptes et choisir l’espace utilisateur destinataire, puis confirmer l’import. Les lignes sans source ne sont pas importables. Les doublons nom/adresse et les réimports du même résultat sont évités. Aucune latitude ou longitude produite par l’IA n’est acceptée : utiliser la validation d’adresse avant de planifier les visites. Aucun portefeuille ni agenda n’est automatiquement envoyé à un fournisseur IA.
État de livraison : développement local, connecteurs testés avec réponses simulées ; aucun appel IA réel sans clés. Paiement Stripe et messagerie no-reply@visit-manager.fr nécessitent leur configuration et une vérification de bout en bout. Les ventes aux particuliers restent désactivées. Le sous-domaine d’administration et l’ouverture commerciale ne sont pas annoncés comme déployés par cette version préparatoire. Les données existantes sont préservées. Ne pas activer les contrôles de licences sur les bêta-testeurs sans leur attribuer au préalable un accès adapté.
Version 0.21.1 — recherche officielle de sociétés
Dans la création/modification d’un compte, les coordonnées de facturation de Mon compte et la commande de licence, saisir un nom, SIREN ou SIRET dans « Rechercher une société française ». La liste se met à jour après une courte pause ; chaque établissement indique son SIRET, son adresse, son statut et s’il est le siège. Sélectionner le bon résultat préremplit nom, adresse, SIREN, SIRET, TVA disponible, code APE/NAF et catégorie juridique. Vérifier puis enregistrer le formulaire : la sélection seule ne sauvegarde pas. Les champs restent modifiables et la saisie manuelle reste possible en cas d’indisponibilité. L’API publique Recherche d’entreprises peut omettre les entités non diffusibles. Aucun numéro de TVA n’est calculé : celui renvoyé par l’API n’est pas une validation VIES. Seul le texte de recherche est transmis au service officiel. Les suggestions périmées sont écartées, les requêtes limitées et l’accès authentifié. Le SIRET et la TVA sont conservés avec le compte ou les coordonnées de facturation.
Présentation des licences : titres et prix plus discrets, cinq offres alignées sur grand écran, répartition adaptée sur tablette et téléphone, formulaire de connexion centré et compact.
Version 0.22.0 — Accueil, souscription et contact
Les offres payantes et l’essai sont présentés sur l’accueil, avec prix provenant du catalogue. Le choix est conservé dans le parcours de création de compte ou de connexion, puis dans les coordonnées de facturation. La case « J’ai lu les conditions générales de vente et je les accepte » est obligatoire avant Stripe ; sa version et la date d’acceptation sont enregistrées. Aucun paiement n’est lancé lorsque Stripe ou les autorisations commerciales ne sont pas configurés. Les inscriptions privées et les ventes aux particuliers restent protégées par leurs verrous existants.
Le formulaire public Contact propose information, technique, licence/facturation, suggestion, confidentialité et autre thème libre. Chaque demande reçoit une référence VM-année-numéro ; les répétitions du même envoi ne créent pas de doublon. L’administration affiche les 200 dernières demandes et permet les statuts nouvelle/en cours/clôturée. Les messages destinés à xtr-conseil@orange.fr et les accusés de réception sont conservés dans la file d’envoi. L’expéditeur souhaité est no-reply.xtr-conseil@orange.fr, confirmé existant par l’éditeur. Sa configuration SMTP reste nécessaire ; sans elle, l’enregistrement reste possible mais aucun e-mail n’est envoyé.
Les CGV et la confidentialité précisent l’absence de prospection ou d’exploitation commerciale, les sauvegardes sur l’infrastructure OVHcloud et la recommandation d’exports personnels. Elles distinguent l’absence de consultation des portefeuilles dans l’administration et la possibilité d’accès technique au serveur : aucune garantie de chiffrement de bout en bout n’est annoncée. Communications limitées au service, au contrat et aux réponses aux sollicitations.
Version 0.22.1 — Historique des demandes
L’administration conserve les messages reçus avec un historique daté des actions et de leur auteur. Deux suivis distincts : dossier Nouveau / En cours / Clôturé ; réponse À répondre / Répondu / Réponse non nécessaire. Une note interne est obligatoire lors du passage à Répondu ou Réponse non nécessaire. Elle décrit la réponse effectuée ailleurs ou le motif ; l’enregistrement ne transmet aucun e-mail. L’accusé automatique ne vaut pas réponse. Les messages originaux et les anciennes notes ne sont pas écrasés.
Recherche par référence, nom, e-mail ou objet ; filtres par statut et réponse. Les demandes sont chargées par pages de 50, avec accès aux plus anciennes. Les demandes existantes gardent leur statut et reçoivent un point de départ d’historique, sans inventer de réponse passée. Un contrôle de révision refuse les modifications concurrentes devenues obsolètes.
Mentions légales / Legal notice (18/09/2026) : préserver la page bilingue mentions-legales.html, legal.css et les liens depuis les pages publiques ; éditeur XTR Conseil et hébergeur OVH pour les instances hébergées. Keep the bilingual public legal notice and links, separately from service-specific terms and privacy. See docs/MENTIONS_LEGALES.md.
Version 0.22.2 — Sécurité de l’administration
L’onglet Sécurité permet de changer son propre mot de passe : mot de passe actuel, nouveau mot de passe (12 à 256 caractères), confirmation. Seul un administrateur connecté peut effectuer cette action. Cinq tentatives de vérification maximum sur quinze minutes ; les erreurs sont traduites. Les mots de passe sont hachés et ne figurent pas dans l’historique. Toutes les sessions et les codes de réinitialisation de ce compte sont invalidés après succès ; une nouvelle connexion est obligatoire. Les autres utilisateurs ne sont pas modifiés.
Prise en charge préparée pour admin.visit-manager.fr : définir VISIT_ADMIN_ORIGIN=https://admin.visit-manager.fr, ajouter son DNS et le site Caddy fourni dans deploy/staging/admin.Caddyfile.example, puis vérifier HTTPS. Préserver l’en-tête Host du sous-domaine. Les origines sont vérifiées séparément pour chaque hôte ; les cookies restent propres à chaque hôte. L’API du sous-domaine refuse les accès non administratifs. Sous-domaine activé le 18 septembre 2026 : DNS OVH, certificat HTTPS et accès administrateur vérifiés. L’administration existante conserve son chemin /administration.
Le portefeuille adopte une barre d’actions alignée, des filtres répartis sur plusieurs colonnes et une liste plus compacte. Sur téléphone, les commandes se réorganisent ; le tableau conserve son défilement horizontal. Les boutons Masquer/Afficher les filtres restent disponibles.
Le bouton Modèle CSV télécharge les en-têtes dans la langue active, avec une deuxième ligne fictive à remplacer ou supprimer. Formats du modèle ouvre l’aide de chaque colonne (dates AAAA-MM-JJ, heures HH:MM, durées en minutes, codes et téléphones à importer comme texte). L’import accepte les en-têtes français, anglais et techniques historiques, indépendamment de la langue affichée. Les virgules décimales sont acceptées pour les coordonnées. Les doublons d’en-têtes et les lignes mal formées sont rejetés avant ajout.
Création d’utilisateur et accès temporaire (12 heures)
L’administrateur crée le compte, choisit sa langue et reçoit un mot de passe temporaire affiché une seule fois. Il peut le transmettre directement ou utiliser « Envoyer un mot de passe temporaire » : ce bouton génère un nouveau secret, invalide le précédent et envoie les instructions par e-mail. L’utilisateur doit choisir un mot de passe différent dès la première connexion, avant tout accès aux données. Après 12 heures, une nouvelle invitation est nécessaire. Aucun mot de passe en clair n’est conservé dans les journaux ni les files d’envoi. Vérifier le résultat SMTP ; un échec ou résultat incertain est signalé. Aucun envoi automatique à la création.
Documentation fonctionnelle
Visit Manager 0.17.0
English documentation (README_EN.md)
Application locale de planification des tournées commerciales. Interface français/anglais, inspirée de la suite XTR / AO Manager.
Démarrer
Python 3.10 ou supérieur, sans dépendance Python externe.
python3 server.py
Accueil : http://127.0.0.1:8790/ ; espace commercial : http://127.0.0.1:8790/app.
Sur Mac, launch.command ouvre l'accueil et démarre le serveur. Créer un compte de connexion depuis l'espace commercial. Données persistantes dans data/visit.sqlite ; chaque utilisateur possède son propre portefeuille, ses simulations et son historique.
Français et anglais
Le sélecteur FR/EN fonctionne sur l'accueil et tous les écrans. Le choix est mémorisé dans le navigateur. Les liens /?lang=fr, /?lang=en, /app?lang=fr et /app?lang=en permettent un accès direct. Les noms et observations des comptes restent dans leur langue d'origine. Les contrôles natifs du navigateur (sélecteur de date, choix de fichier) suivent sa propre langue.
Les libellés et messages sont dans web/messages.json, les erreurs serveur dans translations.py. Les exports CSV de tournées et les descriptions ICS suivent la langue choisie ; les modèles CSV sont localisés, avec compatibilité des anciens en-têtes techniques. Toutes les futures évolutions doivent comporter FR et EN (voir AGENTS.md).
Portefeuille
Le portefeuille affiche directement les filtres et la liste. « Nouveau compte » ouvre le formulaire ; « Modifier » ouvre la fiche sélectionnée. L'enregistrement ou « Fermer » ramène à la liste.
Chaque fiche comporte nom, adresse complète/structurée, priorité, intérêt, fréquence, durée, créneau journalier, dernière visite déclarée, observations et exclusion des propositions. La recherche automatique IGN/BAN remplit les champs après sélection et validation d'une suggestion. Une modification de l'adresse efface les coordonnées pour éviter de conserver une ancienne localisation.
L'import CSV est additif et ne déduplique pas. Les colonnes du modèle suivent la langue active ; les anciens en-têtes techniques restent acceptés. Les métadonnées RPPS et coordonnées professionnelles importées restent conservées lors d'une modification. Les CSV de travail du dossier exports/ restent locaux et ne sont pas suivis sur GitHub.
Planification et reports
Mode automatique périodique ou sélection manuelle par filtres. En manuel, une visite par compte sur l'horizon, même avant sa prochaine échéance. Les scénarios peuvent être enregistrés, repris, modifiés et supprimés sans effacer le réalisé.
Sur une tournée, « Absence / indisponibilité » ouvre le report. La même action est accessible dans « Visites réalisées ». Renseigner la date initiale, le motif, la nouvelle date de disponibilité et une observation facultative. L'absence ne peut pas être déclarée dans le futur ; une indisponibilité future est autorisée.
Le compte est exclu de la date initiale incluse jusqu'à la nouvelle disponibilité exclue. Le report ne crée aucune visite réalisée. L'application recalcule une proposition sur la partie actuelle/future de l'horizon, en respectant les règles de disponibilité et de retour. Si les coordonnées de départ manquent, elle enregistre le report puis invite à les compléter. Si la reprise dépasse l'horizon, elle demande de prolonger celui-ci. Les visites impossibles à placer sont explicitées.
Une visite effectivement réalisée clôture les reports antérieurs de ce compte. Les simulations enregistrées restent des instantanés : celles qui contiennent une visite reportée sont signalées et leurs exports sont bloqués jusqu'à régénération. Le nouveau résultat doit être enregistré pour conserver une nouvelle simulation.
Sécurité et limites
Prototype local, serveur lié exclusivement à 127.0.0.1. Mots de passe scrypt, sessions aléatoires dont seule l'empreinte est stockée, expiration, cookie HttpOnly/SameSite, protection CSRF/origine/Host, contrôle des ressources par utilisateur et limiteurs persistants. Recherche IGN à endpoint HTTPS fixe, vérification TLS, délai et taille bornés ; seule l'adresse recherchée est envoyée au service officiel.
Pas encore de version SaaS : récupération de mot de passe, MFA, organisations/rôles, recette SaaS générale restent à réaliser. Routage IGN sans trafic en direct, avec estimation géographique de secours (vol d’oiseau × 1,3 à 50 km/h). Heuristique sans garantie d'optimum. Aucune confirmation automatique auprès des comptes ; les rendez-vous confirmés sont protégés.
ICS en UTC à partir du fuseau Europe/Paris avec identifiants stables ; la gestion des doublons dépend du calendrier destinataire. Impression/PDF via le navigateur. Le changement FR/EN conserve les valeurs des formulaires et la sélection.
Vérifier
python3 -m unittest discover -s tests -v
node --check web/app.js
node --check web/i18n.js
Les tests couvrent notamment la périodicité, les 300 comptes, les contraintes, les exclusions, les imports, le réalisé, l'isolation, CSRF, les reports, les dates et la couverture bilingue. La recette navigateur a vérifié accueil EN/FR, portefeuille sans formulaire ouvert, sélection manuelle et report avec recalcul. Une CI GitHub exécute les tests à chaque push et pull request.
Agenda et lieux — version 0.4
Dans Mon compte, renseignez Mon domicile, puis vos lieux secondaires (bureau, hôtel, etc.). La recherche officielle IGN permet de sélectionner une adresse et ses coordonnées. Les lieux de départ, de retour et de déjeuner sont indépendants ; le domicile est proposé par défaut au départ et au retour, et le déjeuner est sans lieu fixe par défaut. Définissez les horaires de journée, l’heure et la durée du déjeuner (0 pour désactiver la pause). Sans lieu fixe pour le déjeuner, choisissez le dernier rendez-vous ou le prochain ; en l’absence de prochain rendez-vous, la pause utilise le dernier lieu atteint.
Mon agenda propose les vues jour, semaine et mois. Double-cliquez sur la journée pour modifier les lieux, les horaires ou la durée de pause de cette seule journée, ou rétablir les valeurs par défaut. Les trajets vers le déjeuner et le retour sont inclus dans les estimations. Les horaires de pause sont réservés : les visites et les déplacements ne les chevauchent pas. Le moteur utilise une heuristique, avec routage IGN et estimation de secours (voir version 0.6).
L’export ICS de l’agenda porte sur les tournées ajoutées dans l’horizon choisi (367 jours maximum) : visites, déplacements, déjeuner, départ et retour. Les statuts des événements reflètent les confirmations, réalisations et annulations. Les heures Europe/Paris sont exportées en UTC, avec gestion de l’heure d’été/hiver, identifiants stables et repliage UTF-8. Importez le fichier dans Calendrier Apple ou Outlook ; aucune synchronisation automatique bidirectionnelle n’est fournie. Les journées sans tournée affichent leurs réglages mais ne produisent pas d’événements ICS.
Les profils, exceptions et tournées d’agenda sont isolés par utilisateur, protégés par session et CSRF. La migration ajoute trois tables sans modifier les comptes existants. Les adresses saisies sont recherchées auprès d’IGN ; les autres données du profil restent locales.
Le filtre Commune est une liste alphabétique des communes présentes dans votre portefeuille, sans doublons et actualisée après import ou modification. Toutes les communes réinitialise ce filtre. Dans Mon compte, chaque lieu dispose des champs numéro, voie, complément, code postal, commune, code INSEE et pays. La validation d’une proposition IGN remplit ces champs ainsi que latitude/longitude ; les coordonnées proviennent du géocodage officiel. Une modification manuelle de l’adresse géographique efface les coordonnées précédentes pour imposer une nouvelle localisation. Le complément seul ne les efface pas. Les anciennes adresses libres restent utilisables.
Si aucun domicile n’est enregistré, les champs d’adresse et la recherche IGN apparaissent directement dans la fenêtre de la journée, sans quitter Mon agenda. L’enregistrement conserve le domicile et les réglages de cette journée ensemble. Le clavier Entrée/Espace sur l’en-tête du jour ouvre aussi la fenêtre.
La simulation ne demande plus l’adresse ni les coordonnées du départ : elle utilise les lieux de Mon agenda. Si aucun lieu n’est défini, configurez-le en double-cliquant sur une journée.
Les comptes géocodés peuvent conserver la source IGN, la date, le libellé trouvé, le type et le score. Une localisation à la rue ou au lieu-dit porte la mention « Localisation approximative ». Les adresses non résolues conservent leurs coordonnées vides et restent à localiser. Les données et bilans de géocodage restent locaux et ne sont pas déposés dans Git.
Les horaires « Départ » et « Retour souhaité » ne sont plus saisis dans la simulation. Le calcul reprend les horaires par défaut de l’agenda et les exceptions de chaque journée.
Agenda, historique et licences — version 0.5
La semaine habituelle se configure dans Mon compte : terrain, travail à domicile ou repos pour chaque jour. Les jours fériés nationaux de France métropolitaine sont neutralisés par défaut. Les congés se saisissent par période dans Mon agenda et empêchent les propositions de déplacement. Les horaires et lieux restent modifiables pour une journée. Les paramètres personnels de test sont enregistrés uniquement dans la base locale.
Une proposition ouvre un agenda de simulation distinct. Choisissez explicitement de remplacer les visites prévues sur son horizon ou de les ajouter. L’ajout conserve les rendez-vous existants, déduplique les comptes d’une même journée et refuse les conflits de visite, trajet, déjeuner ou retour. Les visites effectuées sont préservées. Un instantané est sauvegardé avant transfert, changement de paramètres ou ajout de congés. Vous pouvez également nommer et sauvegarder un agenda passé, le consulter en lecture seule et exporter son horizon en ICS. Changer les paramètres généraux conserve les journées passées et invalide les tournées futures.
L’onglet À propos présente XTR Conseil, son logo, ses coordonnées et la version. L’espace abonnement prépare les licences individuelles mensuelles ou annuelles et les coordonnées de facturation. Les tarifs restent à définir ; le paiement est désactivé. Le document téléchargeable est un aperçu de facture non émise, sans numéro ni montant. Aucun abonnement payant n’est activé. Le branchement du prestataire de paiement, la confirmation serveur des règlements et l’émission des factures définitives restent à réaliser après validation commerciale.
Les CGV bilingues (web/cgv.html) sont un projet à compléter avant commercialisation, avec les prix, les conditions de renouvellement/résiliation, le périmètre professionnel ou consommateur et les modalités de traitement des données. Voir la préparation des CGV (docs/CGV_PREPARATION.md).
Les comptes éligibles partageant une même adresse sont privilégiés à la suite : aucun trajet ni délai d’installation supplémentaire entre deux visites consécutives sur place. Les durées et suivis restent individuels. Les disponibilités, exclusions, échéances et pauses restent prioritaires ; les comptes non sélectionnés manuellement ne sont pas ajoutés. La comparaison ignore casse, accents et ponctuation ; une commune seule ou des coordonnées identiques ne suffisent pas. Régénérez les anciennes simulations pour appliquer le regroupement.
Calcul routier — version 0.6
Le moteur IGN / Géoplateforme est actif par défaut, sans clé API. Le profil voiture utilise le réseau BD TOPO et recherche le trajet le plus rapide, ou le plus court en mode kilométrage. Il fournit des durées routières modélisées, sans trafic en direct. Seules les coordonnées des extrémités sont envoyées à https://data.geopf.fr/navigation/itineraire ; aucun nom ni observation n’est transmis. Le mode estimation géographique permet de travailler hors ligne.
L’heuristique propose des étapes puis affine les trajets retenus avec l’IGN et recalcule les contraintes horaires, déjeuner et retour (jusqu’à quatre passes). Ce n’est pas une optimisation exhaustive de toutes les paires de comptes. Le cache directionnel local dure 30 jours ; il est exclu de Git. Les appels sont espacés d’au moins 260 ms et chaque calcul est limité à 60 nouveaux trajets et environ 25 secondes de réseau. Les trajets non obtenus restent géographiques : l’agenda, les propositions et les exports indiquent IGN, mixte ou estimation. Relancer une simulation permet de réutiliser le cache et de compléter un grand horizon. L’ajout à un agenda vérifie les trajets depuis le cache, avec indication des estimations restantes. Les anciennes simulations doivent être régénérées.
Documentation du service : https://cartes.gouv.fr/aide/fr/guides-utilisateur/utiliser-les-services-de-la-geoplateforme/calcul-itineraire/
La plage d’affichage de l’agenda se règle dans Mon compte (par défaut 07:30–19:30). Les heures sont alignées entre les jours ; seules les heures choisies apparaissent en vue jour/semaine. Ce réglage personnel conserve les tournées et les horaires de travail. Les événements hors plage restent disponibles en vue mois et dans les exports.
Les fiches et la liste des comptes affichent les rendez-vous issus de l’agenda actuel validé, avec date et horaires. Les simulations et archives ne renseignent pas cette indication. Une visite réalisée le même jour retire le rendez-vous de cette liste. Annulation individuelle, RAZ sur un horizon et proposition d’annulation des rendez-vous passés non réalisés sont disponibles avec confirmation. Chaque annulation sauvegarde le planning ; les visites réalisées restent conservées. Les autres rendez-vous gardent leurs horaires. Les trajets sont recalculés après annulation, avec alerte en cas de conflit (voir version 0.8).
La vue semaine propose un défilement horizontal sur neuf semaines (quatre avant et quatre après la semaine choisie). Le bandeau mois/année et les dates suivent la semaine parcourue ; les flèches permettent de continuer la navigation. Les en-têtes présentent séparément le jour, son numéro et le mois. L’export .ics, placé au-dessus de la grille, porte sur les dates saisies et sur la source sélectionnée (agenda actuel, simulation ou archive), indépendamment de la semaine visible.
Les réponses API réussies sont envoyées après validation de la transaction en base, pour que la session et les modifications soient disponibles dès la requête suivante. Un test reproduit un retard de validation afin de détecter cette condition de concurrence.
Suivi des rendez-vous et recalcul — version 0.8
L’agenda distingue Proposé (simulation), Planifié (transfert validé), Confirmé par le compte, Réalisé, Absent et Annulé, avec couleurs et libellés. Double-cliquez sur un rendez-vous de l’agenda actuel pour confirmer, retirer sa confirmation, saisir la visite réalisée, signaler une absence ou annuler. Confirmer est une action explicite de l’utilisateur ; aucun message n’est envoyé au compte. Les archives et simulations restent en lecture seule.
Après annulation ou absence, les autres rendez-vous gardent leurs heures et leurs statuts. Les trajets sont recalculés automatiquement (IGN, avec repli géographique signalé), en respectant déjeuner et retour. Une incompatibilité conserve les rendez-vous, retire les trajets obsolètes et affiche une alerte avec un bouton de recalcul. L’absence ne supprime plus les journées entières des autres comptes. Les lieux du planning sont conservés dans chaque nouvelle tournée pour les recalculs ultérieurs.
Un transfert ne peut pas déplacer ou supprimer silencieusement un rendez-vous confirmé ou réalisé. Un changement de paramètres, de journée ou des congés touchant un rendez-vous confirmé est refusé tant que sa confirmation n’est pas retirée. Une annulation explicite reste possible. Les rendez-vous annulés/absents restent visibles comme historique, sans compter parmi les visites à effectuer ; une replanification du même compte le même jour remplace cet historique. Les exports ICS distinguent TENTATIVE, CONFIRMED et CANCELLED ; leur application lors d’un import dépend du logiciel destinataire. Les visites réalisées restent la seule source du réalisé commercial.
En vue jour/semaine, l’en-tête de chaque journée reste visible pendant le défilement vertical interne du calendrier. Il suit sa colonne lors du défilement horizontal.
Double-cliquez sur un rendez-vous de l’agenda courant pour afficher son détail et ses actions. Au clavier, utilisez Entrée ou Espace sur le rendez-vous.
Le détail affiche le compte, l’adresse, la date, les horaires, la durée prévue et le statut. La visite réalisée peut être enregistrée dans cette fenêtre avec sa durée réelle et son compte rendu. Les simulations et archives sont consultables en lecture seule.
La recherche IGN/BAN se déclenche automatiquement après 650 ms sans saisie pour les adresses des comptes, du domicile, des lieux secondaires et de facturation. Choisissez une proposition pour confirmer et préremplir les champs (avec GPS pour les comptes et les lieux). Les réponses dépassées sont ignorées. Une absence de résultat ou une panne ne vaut pas validation : la saisie manuelle reste possible, notamment hors de France. Les champs distincts de complément, de nom et d’observations ne sont pas envoyés dans ces recherches.
Dans le portefeuille, double-cliquez sur une ligne pour modifier le compte. Le bouton Modifier reste disponible, notamment au clavier et sur mobile. Les cases de sélection conservent leur fonctionnement.
Version 0.9.0 : listes d’adresses à double-clic, durée zéro héritée de Mon compte, documentation utilisateur/fonctionnelle/technique et prompt de régénération sur /docs-fr.html. Régénérer avec python3 scripts/build_docs.py avant chaque dépôt.
Connexion : une adresse déjà inscrite invite à Se connecter, sans recréer ni remplacer le compte. La pastille en haut à droite ouvre Mon compte. Prénom et nom déterminent les initiales ; à défaut, celles-ci proviennent de l’e-mail. L’identité est enregistrée séparément sans modifier le planning.
Sur téléphone, la connexion utilise un en-tête compact sans navigation métier. Après connexion, Menu ouvre les rubriques et la déconnexion ; choisir une rubrique referme le menu. Les champs tactiles utilisent une police de 16 px, les formulaires étroits une colonne et les tableaux conservent leur défilement horizontal.
Mot de passe oublié : une demande locale est enregistrée sans révéler si le compte existe. L’administrateur exécute python3 password_reset.py adresse@example.fr puis remet le code par un canal privé. Aucun e-mail automatique. Code haché, valable 30 minutes et utilisable une seule fois. Le changement invalide toutes les sessions du compte.
Tri du portefeuille : nom, commune, dernière visite ou prochaine visite planifiée, croissant/décroissant ; valeurs absentes toujours à la fin. La prochaine visite est un rendez-vous à venir de l’agenda validé, pas une échéance théorique. Heure préférentielle optionnelle par compte : le début doit respecter ± la tolérance du profil (30 min par défaut, 0 à 240). Les horaires d’ouverture, déjeuner et retour restent prioritaires ; si aucune place ne convient, le compte reste non planifié. Les anciennes tournées ne changent pas : régénérer la simulation. Aucun expéditeur XTR Conseil actif confirmé ; récupération locale conservée.
Préproduction 0.17 : instance isolée déployée sur https://visit-manager.fr. Voir docs/PREPRODUCTION.md. Mode HTTPS explicite, base démonstration obligatoire, inscription désactivée et comptes testeurs individuels générés par script. Le mode local et ses utilisateurs restent inchangés.
Rendez-vous fixes — version 0.12.0
Dans Mon agenda, double-cliquez sur une journée puis utilisez Ajouter un rendez-vous fixe. Saisissez l’intitulé, le début, la fin et le lieu (domicile ou localisation secondaire enregistrée dans Mon compte, avec recherche IGN/BAN). Plusieurs créneaux sont possibles, jusqu’à 24 par journée. Enregistrez la journée puis régénérez votre simulation.
Ces rendez-vous restent à leurs heures et lieux : le calcul réserve le temps nécessaire pour les rejoindre et repartir. Les visites commerciales sont proposées autour. Un itinéraire impossible produit une erreur ; aucun rendez-vous fixe n’est déplacé. Les créneaux doivent être dans les horaires de la journée, sans chevauchement entre eux ni avec le déjeuner : adaptez explicitement le déjeuner si nécessaire. Les journées non commerciales restent exclues des tournées.
Les créneaux apparaissent en couleur ocre dans l’agenda, même sans tournée, et sont inclus dans l’export ICS et les archives. Ils persistent après annulation des visites et rétablissement des paramètres par défaut. Pour les retirer, ouvrez la journée, utilisez Supprimer ce créneau, puis enregistrez. Comme les autres réglages journaliers, l’enregistrement archive et retire la tournée du jour à recalculer ; les visites confirmées restent protégées. Les rendez-vous fixes ne comptent pas comme visites de comptes et ne modifient pas leur dernière visite.
Portefeuille et entreprise — version 0.13.0
Le filtre « Visite » propose « Visiter », « Ne pas visiter » et « Tous ». Il se combine avec la recherche, la commune, la priorité et le statut. « Masquer les filtres » libère de la place sans supprimer les critères ni la sélection ; « Afficher les filtres » les réouvre. Mon compte comporte un champ Entreprise, facultatif, enregistré avec l’identité personnelle sans modifier l’agenda.
Le portefeuille de test a été complété à partir de l’extraction publique RPPS du 17 septembre 2026 : 1 717 fiches d’exercice, 1 542 praticiens, 127 communes de Haute-Garonne. Une fiche correspond à un praticien et une structure ; plusieurs lieux d’exercice produisent plusieurs comptes. Cette couverture dépend des données publiées, sans garantie d’exhaustivité terrain. Les comptes existants, observations et historiques sont conservés. Les données nominatives restent locales et hors Git.
Pour ce jeu de test, le secteur Est signifie : à l’est de l’Ariège, puis de la Garonne en aval de leur confluence, sans rayon de limitation. Les comptes localisés dans ce secteur sont cochés « Ne pas visiter ». Les exclusions existantes ailleurs sont conservées. Les adresses non résolues ne sont pas classées géographiquement et doivent être vérifiées ; une localisation à la rue reste approximative. La case d’exclusion reste modifiable dans chaque fiche.
Lieux et import calendrier — version 0.14.0
Dans Mon compte → Mes lieux, utilisez Ajouter un lieu, renseignez un nom (Bureau, Agence Sud, Domicile 2…), recherchez l’adresse IGN/BAN et validez une proposition pour remplir les champs complets et coordonnées. Enregistrez les paramètres. Le nom du lieu apparaît dans les sélections de départ, retour, déjeuner et rendez-vous fixe.
Dans un rendez-vous fixe, choisissez un lieu enregistré ou Autre lieu. Pour un lieu ponctuel, saisissez son nom et recherchez puis validez son adresse. Il appartient uniquement à ce rendez-vous et ne modifie pas vos lieux habituels. Les trajets utilisent ses coordonnées. Saisissez les heures au format HH:MM (9:30 est également accepté et enregistré 09:30). Les erreurs sont visibles dans la fenêtre : fin après début, horaires compris dans la journée, absence de chevauchement avec le déjeuner ou un autre rendez-vous fixe. Ajustez la pause de la journée si nécessaire.
Mon agenda → Importer un calendrier .ics permet de prévisualiser puis importer des rendez-vous fixes. Vérifiez les lieux, choisissez un lieu enregistré ou une adresse ponctuelle pour chaque ligne ; supprimez les lignes à ignorer. L’import est atomique : un conflit bloque tout le lot, sans ajout partiel. Les rendez-vous déjà importés avec la même identité et date de début sont ignorés. Les tournées non confirmées des jours concernés sont archivées puis retirées pour être recalculées ; les visites confirmées sont protégées.
Limites actuelles : fichier de 500 Ko et 200 rendez-vous maximum ; 24 créneaux fixes par jour. Import d’occurrences datées avec début et fin le même jour, à la minute, converties en Europe/Paris. Sans fuseau, l’heure est interprétée en Europe/Paris. Les séries récurrentes, journées entières et événements traversant minuit sont refusés explicitement : exporter des occurrences individuelles. Ce n’est pas une synchronisation directe avec Google, Apple ou Outlook. Une modification ultérieure du calendrier source ne met pas automatiquement à jour les événements importés.
Sauvegarde personnelle — version 0.15.0
Mon compte → Sauvegarder et restaurer mes données propose Exporter mes données et Importer une sauvegarde. Toutes les catégories disponibles sont cochées par défaut : paramètres/identité/lieux, comptes, agenda/congés/archives, visites réalisées/reports, simulations, facturation/abonnement. Décochez les catégories inutiles. L’export télécharge un fichier JSON Visit Manager ; le CSV reste destiné à l’import de comptes seulement.
L’import accepte une sauvegarde de votre espace actuel, pas celle d’un autre utilisateur. Sélectionnez le fichier et les catégories, puis Vérifier avant restauration. Le récapitulatif indique le nombre d’enregistrements par catégorie. Cochez la confirmation puis restaurez. Les catégories sélectionnées sont remplacées, même si leur contenu dans le fichier est vide ; les autres sont conservées. Une catégorie absente du fichier ne peut pas être sélectionnée. Les comptes avec des visites ou plannings associés exigent la restauration conjointe des catégories liées ; les paramètres nécessitent agenda et simulations si ces données existent. L’application refuse les dépendances incohérentes au lieu de perdre les liens.
Une copie complète de l’espace avant restauration est conservée localement dans data/.user-backups, avec accès restreint. Elle peut être réimportée pour revenir en arrière. La restauration est atomique et les autres utilisateurs restent intacts. Les mots de passe, sessions, codes de réinitialisation et caches techniques sont exclus ; l’adresse de connexion n’est pas modifiée. Les fichiers contiennent des données personnelles : conservez vos téléchargements dans un emplacement privé. Limite : 50 Mo par fichier. La sauvegarde locale automatique ne remplace pas une copie téléchargée hors de l’ordinateur.
Propriétaire du compte — version 0.16.0
Chaque fiche comporte un propriétaire commercial facultatif (150 caractères), visible dans la liste et inclus dans la recherche, l’import CSV via la colonne owner et les sauvegardes JSON. Ce libellé n’accorde aucun accès utilisateur. Dans le jeu de test Haute-Garonne, les comptes géolocalisés à l’ouest de l’Ariège puis de la Garonne sont attribués par défaut à Magalie Rousselin ; un propriétaire déjà renseigné est conservé. Les comptes Est et ceux sans coordonnées ne sont pas attribués automatiquement. Le préchargement RPPS applique la même règle.
Historique durable des rendez-vous — version 0.17.0
Dans Historique et visites, la rubrique Historique des rendez-vous passés permet de consulter une période. Elle conserve le nom et l’adresse connus au moment de l’archivage, les horaires, le type de rendez-vous, son statut et le compte rendu lorsqu’il existe. Les rendez-vous fixes sont inclus. Les rendez-vous prévus ou confirmés sans réalisation restent explicitement non renseignés ; le passage du temps ne les transforme jamais en visites réalisées.
Un registre historique dédié est conservé dans la base locale, séparément du planning actif. Il est alimenté au démarrage, à l’ouverture de l’espace et autour des modifications. Les anciennes versions d’un rendez-vous sont conservées ; la liste affiche son dernier état connu. Une remise à zéro, annulation ou recalcul ne supprime pas ce registre. Les anciens rendez-vous sont repris depuis les plannings, réalisations et archives encore disponibles ; les données déjà supprimées sans archive ne peuvent pas être reconstituées.
Le registre appartient à chaque utilisateur et fait partie de la catégorie Visites réalisées et reports des sauvegardes. Les sauvegardes JSON version 2 le contiennent ; les fichiers version 1 restent acceptés. Une restauration explicitement confirmée de cette catégorie remplace aussi son historique, avec la copie de sécurité préalable habituelle.
Préproduction accessible sur https://visit-manager.fr depuis le 17 septembre 2026. Déploiement OVH VPS avec Caddy HTTPS, service Python limité à la boucle locale, base de démonstration séparée et inscriptions publiques désactivées. Accès par identifiants individuels remis en privé ; portefeuille réel importable uniquement sur autorisation explicite. Sauvegarde SQLite quotidienne, conservation de 14 copies sur le VPS, en complément du backup OVH. La récupération automatique par e-mail reste non configurée.
Mise à jour bêta : sur demande explicite du propriétaire, le portefeuille réel peut être transféré vers son compte individuel. Exiger VISIT_STAGING_ACK=authorized-real-data et le marqueur staging_meta purpose=authorized-real-data correspondant ; demo-only reste le défaut pour les bases fictives. Conserver HTTPS, isolation par utilisateur et inscriptions fermées. Sauvegarder la base avant import et préserver les champs des comptes. Le bandeau indique désormais « Bêta privée ». Aucun secret ni export de données ne doit être déposé dans Git.
Présentation : en-tête de l’espace commercial réorganisé en deux groupes, navigation à gauche et langue/compte à droite. Espacements explicites, séparateur et adaptation sur deux lignes pour téléphone ; libellés français et anglais.
Version 0.18 — Rendez-vous à la même adresse
À chaque calcul de simulation ou recalcul après report, répondez à « Grouper les rendez-vous des comptes à la même adresse ? ». Accepter partage une seule durée standard de Mon compte entre les comptes éligibles dont la durée spécifique est zéro. Refuser conserve la durée complète de chaque visite. Trois comptes standards de 45 minutes prennent chacun 15 minutes ; deux standards prennent 23 et 22 minutes, plus la durée intégrale de tout compte personnalisé. L’arrondi à la minute conserve exactement le total. Une durée personnalisée reste individuelle même si elle est égale à la durée standard.
Les rendez-vous gardent leur compte, leur statut et leur historique individuels. Seuls les comptes sélectionnés, à visiter et disponibles sont inclus. Les heures d’ouverture, heures préférentielles, déjeuner et rendez-vous fixes restent respectés ; si le créneau commun est incompatible, les visites restent individuelles. Les groupes sont limités au nombre de minutes du créneau pour éviter une durée nulle. La réponse est conservée avec la simulation pour son enregistrement et son transfert à l’agenda, puis redemandée au prochain calcul.
Version 0.18.1 — Statut par double-clic
Dans l’agenda actuel, double-cliquez sur une visite puis choisissez son statut dans la liste : Planifié, Confirmé par le compte, Réalisé, Absent / à reprogrammer ou Annulé. Cliquez sur Enregistrer le statut. Réalisé ouvre la saisie de durée réelle et compte rendu et n’est disponible qu’à partir du jour du rendez-vous. Une absence ouvre la reprogrammation et une annulation demande confirmation. Les erreurs restent visibles dans la fiche. Simulations et archives restent en consultation ; les visites terminées conservent leur historique.
Version 0.18.2 — Lisibilité des trajets
Les trajets occupent la largeur disponible dans la colonne du jour, au lieu d’une bande de 16 pixels. Leurs heures de début et de fin apparaissent en premier, puis leur durée et leur adresse selon la hauteur disponible. Un trajet très court garde une hauteur proportionnelle à sa durée ; le survol ou le focus développe son détail. Les horaires et les données ne changent pas.
Version 0.18.3 — Sauvegarde des lieux
Dans Mon compte, « Sauvegarder mes lieux et paramètres » reste visible pendant le défilement ; un second bouton est disponible en bas. La saisie, l’ajout de lieu et le choix d’adresse IGN sont suivis comme modifications non sauvegardées. Quitter la rubrique, suivre un lien dans le même onglet ou se déconnecter demande confirmation : Non conserve la saisie, Oui abandonne. Échap équivaut à Non. Un nouvel appui sur Mon compte ne réinitialise pas le formulaire. Actualisation/fermeture : avertissement natif du navigateur, avec son propre texte. La protection disparaît après une sauvegarde réussie, reste après erreur et protège les changements effectués pendant un enregistrement. Elle concerne le formulaire des lieux et horaires ; les autres formulaires ont leur propre enregistrement.
Version 0.19 — Sauvegarde automatique
Les lieux et horaires de Mon compte sont sauvegardés en brouillon sur le serveur une seconde après la dernière modification. Une adresse incomplète est conservée sans être validée ; « Sauvegarder mes lieux et paramètres » applique explicitement le formulaire et conserve les contrôles habituels. Le brouillon revient à la prochaine ouverture de Mon compte. L’indicateur confirme la sauvegarde automatique ; en cas d’erreur réseau, gardez la page ouverte et réessayez en modifiant un champ. Une fermeture avant la fin de la sauvegarde déclenche l’avertissement du navigateur. Abandonner explicitement supprime le brouillon.
Chaque calcul réussi conserve automatiquement la dernière simulation par utilisateur. Elle est restaurée au chargement et consultable dans Agenda de simulation ; elle ne publie aucun rendez-vous. Vérifiez-la avant transfert, notamment après changement de paramètres. Les simulations nommées restent disponibles séparément. Les brouillons sont inclus dans les sauvegardes complètes du serveur, pas dans les exports JSON par catégorie. Un import utilisateur efface les brouillons pour éviter des références obsolètes. Deux onglets modifiant le même brouillon suivent la règle du dernier enregistrement ; utilisez un seul onglet de saisie.
Version 0.20 — Coordonnées des comptes
Les fiches et la liste du portefeuille affichent Téléphone professionnel, Mobile professionnel et E-mail professionnel, modifiables par compte. Le modèle CSV ajoute phone, mobile et professional_email sans renommer les colonnes existantes. Les sauvegardes JSON conservent ces champs.
Enrichissement administratif : scripts/enrich_contacts.py utilise l’Annuaire Santé RPPS (identifiant RPPS + structure) et Ameli (nom complet + voie normalisée + code postal + commune). Il complète uniquement les champs vides à partir de valeurs publiques non ambiguës, classe les numéros français 06/07 comme mobiles professionnels publiés, conserve les saisies et trace la source et la date de vérification par champ. Aucun e-mail déduit, aucune messagerie MSSanté ajoutée pour le contact commercial. Mode prévisualisation par défaut ; --apply crée une sauvegarde SQLite puis met à jour uniquement l’utilisateur sélectionné, sans modifier son agenda, ses notes ou ses propriétaires. Fichiers sources et bases privés, exclus de Git. Sources : https://www.data.gouv.fr/datasets/annuaire-sante-ameli et https://www.data.gouv.fr/datasets/annuaire-sante-extractions-des-donnees-en-libre-acces-des-professionnels-intervenant-dans-le-systeme-de-sante-rpps.
Version 0.21.0 — licences équipe et listes professionnelles IA
La page /licence présente les abonnements individuels et deux packs exclusivement annuels : jusqu’à 5 utilisateurs, titulaire inclus, à 699 € TTC proposés ; jusqu’à 10 à 1 199 € TTC proposés. Ces prix restent à valider commercialement avant activation. Au-delà de 10 utilisateurs, le site invite à contacter XTR Conseil. Le titulaire ajoute ou retire des utilisateurs déjà inscrits. Les espaces restent privés et séparés. Le contrôle du nombre de places est effectué côté serveur. Les tarifs et descriptions FR/EN se modifient dans l’administration ; un prix zéro masque l’offre.
La page /administration est réservée aux e-mails administrateurs configurés sur le serveur. Elle présente utilisateurs, blocage, attribution gratuite, réinitialisation de mot de passe, estimation du stockage, consultations de l’espace, commandes, factures, tarifs et listes IA. Une attribution gratuite n’émet pas de facture acquittée. Les paiements manuels demandent une référence et une confirmation de réception. Les factures PDF sont générées depuis un instantané de commande et restent conservées ; les données JSON préparent le raccordement à une plateforme agréée de facturation électronique, sans réaliser cette transmission.
Pour constituer une liste IA : choisir une profession et une zone, définir 1 à 100 résultats, fournir si nécessaire un texte public, construire et modifier le prompt, puis le mémoriser. Dans Fournisseurs, enregistrer le modèle exact et la clé API OpenAI, Claude, DeepSeek ou Gemini. La clé est chiffrée côté serveur et n’est jamais renvoyée à l’interface. Le lancement demande confirmation d’un appel potentiellement facturable. OpenAI utilise la recherche web si le modèle l’accepte ; les trois autres connecteurs analysent le texte source fourni sans navigation web dans cette version. Un résultat peut être vide et n’est jamais présenté comme exhaustif ou certifié.
Les résultats restent dans une liste à vérifier. Ouvrir les sources, vérifier les coordonnées, sélectionner les comptes et choisir l’espace utilisateur destinataire, puis confirmer l’import. Les lignes sans source ne sont pas importables. Les doublons nom/adresse et les réimports du même résultat sont évités. Aucune latitude ou longitude produite par l’IA n’est acceptée : utiliser la validation d’adresse avant de planifier les visites. Aucun portefeuille ni agenda n’est automatiquement envoyé à un fournisseur IA.
État de livraison : développement local, connecteurs testés avec réponses simulées ; aucun appel IA réel sans clés. Paiement Stripe et messagerie no-reply@visit-manager.fr nécessitent leur configuration et une vérification de bout en bout. Les ventes aux particuliers restent désactivées. Le sous-domaine d’administration et l’ouverture commerciale ne sont pas annoncés comme déployés par cette version préparatoire. Les données existantes sont préservées. Ne pas activer les contrôles de licences sur les bêta-testeurs sans leur attribuer au préalable un accès adapté.
Version 0.21.1 — recherche officielle de sociétés
Dans la création/modification d’un compte, les coordonnées de facturation de Mon compte et la commande de licence, saisir un nom, SIREN ou SIRET dans « Rechercher une société française ». La liste se met à jour après une courte pause ; chaque établissement indique son SIRET, son adresse, son statut et s’il est le siège. Sélectionner le bon résultat préremplit nom, adresse, SIREN, SIRET, TVA disponible, code APE/NAF et catégorie juridique. Vérifier puis enregistrer le formulaire : la sélection seule ne sauvegarde pas. Les champs restent modifiables et la saisie manuelle reste possible en cas d’indisponibilité. L’API publique Recherche d’entreprises peut omettre les entités non diffusibles. Aucun numéro de TVA n’est calculé : celui renvoyé par l’API n’est pas une validation VIES. Seul le texte de recherche est transmis au service officiel. Les suggestions périmées sont écartées, les requêtes limitées et l’accès authentifié. Le SIRET et la TVA sont conservés avec le compte ou les coordonnées de facturation.
Présentation des licences : titres et prix plus discrets, cinq offres alignées sur grand écran, répartition adaptée sur tablette et téléphone, formulaire de connexion centré et compact.
Version 0.22.0 — Accueil, souscription et contact
Les offres payantes et l’essai sont présentés sur l’accueil, avec prix provenant du catalogue. Le choix est conservé dans le parcours de création de compte ou de connexion, puis dans les coordonnées de facturation. La case « J’ai lu les conditions générales de vente et je les accepte » est obligatoire avant Stripe ; sa version et la date d’acceptation sont enregistrées. Aucun paiement n’est lancé lorsque Stripe ou les autorisations commerciales ne sont pas configurés. Les inscriptions privées et les ventes aux particuliers restent protégées par leurs verrous existants.
Le formulaire public Contact propose information, technique, licence/facturation, suggestion, confidentialité et autre thème libre. Chaque demande reçoit une référence VM-année-numéro ; les répétitions du même envoi ne créent pas de doublon. L’administration affiche les 200 dernières demandes et permet les statuts nouvelle/en cours/clôturée. Les messages destinés à xtr-conseil@orange.fr et les accusés de réception sont conservés dans la file d’envoi. L’expéditeur souhaité est no-reply.xtr-conseil@orange.fr, confirmé existant par l’éditeur. Sa configuration SMTP reste nécessaire ; sans elle, l’enregistrement reste possible mais aucun e-mail n’est envoyé.
Les CGV et la confidentialité précisent l’absence de prospection ou d’exploitation commerciale, les sauvegardes sur l’infrastructure OVHcloud et la recommandation d’exports personnels. Elles distinguent l’absence de consultation des portefeuilles dans l’administration et la possibilité d’accès technique au serveur : aucune garantie de chiffrement de bout en bout n’est annoncée. Communications limitées au service, au contrat et aux réponses aux sollicitations.
Version 0.22.1 — Historique des demandes
L’administration conserve les messages reçus avec un historique daté des actions et de leur auteur. Deux suivis distincts : dossier Nouveau / En cours / Clôturé ; réponse À répondre / Répondu / Réponse non nécessaire. Une note interne est obligatoire lors du passage à Répondu ou Réponse non nécessaire. Elle décrit la réponse effectuée ailleurs ou le motif ; l’enregistrement ne transmet aucun e-mail. L’accusé automatique ne vaut pas réponse. Les messages originaux et les anciennes notes ne sont pas écrasés.
Recherche par référence, nom, e-mail ou objet ; filtres par statut et réponse. Les demandes sont chargées par pages de 50, avec accès aux plus anciennes. Les demandes existantes gardent leur statut et reçoivent un point de départ d’historique, sans inventer de réponse passée. Un contrôle de révision refuse les modifications concurrentes devenues obsolètes.
Mentions légales / Legal notice
Les mentions légales XTR Conseil sont accessibles depuis les pages du site, en français et en anglais, sans connexion. Voir le dossier de mentions (docs/MENTIONS_LEGALES.md). Les CGV, la confidentialité propre au service et les accès existants sont conservés.
The XTR Conseil legal notice is publicly accessible from site pages in French and English. See legal notice documentation (docs/MENTIONS_LEGALES.md). Existing terms, service-specific privacy information and access controls are preserved.
Version 0.22.2 — Sécurité de l’administration
L’onglet Sécurité permet de changer son propre mot de passe : mot de passe actuel, nouveau mot de passe (12 à 256 caractères), confirmation. Seul un administrateur connecté peut effectuer cette action. Cinq tentatives de vérification maximum sur quinze minutes ; les erreurs sont traduites. Les mots de passe sont hachés et ne figurent pas dans l’historique. Toutes les sessions et les codes de réinitialisation de ce compte sont invalidés après succès ; une nouvelle connexion est obligatoire. Les autres utilisateurs ne sont pas modifiés.
Prise en charge préparée pour admin.visit-manager.fr : définir VISIT_ADMIN_ORIGIN=https://admin.visit-manager.fr, ajouter son DNS et le site Caddy fourni dans deploy/staging/admin.Caddyfile.example, puis vérifier HTTPS. Préserver l’en-tête Host du sous-domaine. Les origines sont vérifiées séparément pour chaque hôte ; les cookies restent propres à chaque hôte. L’API du sous-domaine refuse les accès non administratifs. Sous-domaine activé le 18 septembre 2026 : DNS OVH, certificat HTTPS et accès administrateur vérifiés. L’administration existante conserve son chemin /administration.
Le portefeuille adopte une barre d’actions alignée, des filtres répartis sur plusieurs colonnes et une liste plus compacte. Sur téléphone, les commandes se réorganisent ; le tableau conserve son défilement horizontal. Les boutons Masquer/Afficher les filtres restent disponibles.
Le bouton Modèle CSV télécharge les en-têtes dans la langue active, avec une deuxième ligne fictive à remplacer ou supprimer. Formats du modèle ouvre l’aide de chaque colonne (dates AAAA-MM-JJ, heures HH:MM, durées en minutes, codes et téléphones à importer comme texte). L’import accepte les en-têtes français, anglais et techniques historiques, indépendamment de la langue affichée. Les virgules décimales sont acceptées pour les coordonnées. Les doublons d’en-têtes et les lignes mal formées sont rejetés avant ajout.
Création d’utilisateur et accès temporaire (12 heures)
L’administrateur crée le compte, choisit sa langue et reçoit un mot de passe temporaire affiché une seule fois. Il peut le transmettre directement ou utiliser « Envoyer un mot de passe temporaire » : ce bouton génère un nouveau secret, invalide le précédent et envoie les instructions par e-mail. L’utilisateur doit choisir un mot de passe différent dès la première connexion, avant tout accès aux données. Après 12 heures, une nouvelle invitation est nécessaire. Aucun mot de passe en clair n’est conservé dans les journaux ni les files d’envoi. Vérifier le résultat SMTP ; un échec ou résultat incertain est signalé. Aucun envoi automatique à la création.
Version 0.23.0 — Accès temporaires et portefeuille
Création administrateur avec mot de passe valable 12 heures, changement obligatoire, envoi explicite traduit ; modèle CSV bilingue et mise en page compacte. Les comptes, paramètres et agendas existants sont conservés.
Documentation technique
Présentation : en-tête de l’espace commercial réorganisé en deux groupes, navigation à gauche et langue/compte à droite. Espacements explicites, séparateur et adaptation sur deux lignes pour téléphone ; libellés français et anglais.
Mise à jour bêta : sur demande explicite du propriétaire, le portefeuille réel peut être transféré vers son compte individuel. Exiger VISIT_STAGING_ACK=authorized-real-data et le marqueur staging_meta purpose=authorized-real-data correspondant ; demo-only reste le défaut pour les bases fictives. Conserver HTTPS, isolation par utilisateur et inscriptions fermées. Sauvegarder la base avant import et préserver les champs des comptes. Le bandeau indique désormais « Bêta privée ». Aucun secret ni export de données ne doit être déposé dans Git.
Préproduction accessible sur https://visit-manager.fr depuis le 17 septembre 2026. Déploiement OVH VPS avec Caddy HTTPS, service Python limité à la boucle locale, base de démonstration séparée et inscriptions publiques désactivées. Accès par identifiants individuels remis en privé ; données réelles sur autorisation explicite. Sauvegarde SQLite quotidienne, conservation de 14 copies sur le VPS, en complément du backup OVH. La récupération automatique par e-mail reste non configurée.
Version 0.17 : appointment_journal est un registre append-only par utilisateur, event_key et jour, avec date de capture, empreinte et JSON instantané. appointment_journal.py récupère les archives puis le planning courant et les annulations ; les réalisations priment. Capture limitée aux rendez-vous passés (Europe/Paris), sauf réalisation déclarée le jour courant. Ne pas supprimer le planning actif lors de la capture. Une nouvelle version est insérée seulement si le dernier état diffère ; les états précédents restent stockés. Synchroniser au démarrage, lors de /api/state et avant/après les écritures authentifiées, hors prévisualisation de sauvegarde et géocodage. La liste publique par utilisateur présente le dernier état de chaque événement ; filtres de période côté interface. Inclure le registre dans history des sauvegardes v2, remapper client_id/event_key lors de restauration et accepter v1 sans ce registre. Tester conservation après suppression du planning, non-duplication, reprise des archives, réalisation et isolation.
Version 0.16 : propriété clients.data.owner facultative, validée à 150 caractères, préservée à l’édition et dans les sauvegardes. Afficher et rechercher le propriétaire ; colonne CSV owner ajoutée sans renommer les colonnes existantes. Préchargement RPPS : si eastern_sector vaut exactement False et owner est vide, attribuer Magalie Rousselin. Ne pas confondre absence de coordonnées et Ouest, ni propriétaire commercial et accès utilisateur.
Version 0.15.0
user_backup.py définit un format JSON versionné et six groupes de tables en liste blanche, sans identifiants d’authentification. Empreinte SHA-256 des sections pour détecter une altération accidentelle (ce n’est pas une signature), empreinte du compte propriétaire ; restriction à ce même compte. POST /api/backup-export utilise une lecture transactionnelle. /api/backup-preview restaure sous SAVEPOINT puis annule ; /api/backup-import exige confirmed=true et écrit une sauvegarde privée avant validation finale. Liste blanche des colonnes, contrôles des dépendances, références client remappées en cas de collision d’identifiants, clés globales recréées, vérification des lieux et contrôle des références privées. Toutes les opérations restent soumises à session/CSRF/Origin. Limite requête 51 Mo uniquement pour prévisualisation/restauration ; export limité à 50 Mo. Copie préalable : data/.user-backups, fichiers mode 0600. Interface web/backup.js ; tests/test_backup.py couvre isolation, intégrité, confirmation, prévisualisation, remplacement, collisions et rollback.
Version 0.14.0
Les lieux du profil conservent nom, champs structurés et coordonnées. fixed_appointments accepte soit location_id du profil, soit location embarquée validée avec les règles d’adresse du profil. fixed_events utilise cette localisation pour les trajets et exports. source_uid identifie une occurrence ICS importée. calendar_import.py fournit un parseur borné (dépliage de lignes, échappements, UTC/TZID/Europe/Paris, rejet des séries et journées entières). POST /api/calendar-preview retourne les occurrences ; POST /api/calendar-import valide tous les jours avant écriture, protège les visites confirmées, archive et invalide les tournées affectées, déduplique sans toucher les jours inchangés. Les deux endpoints restent authentifiés, CSRF et isolés par utilisateur. Tests : tests/test_calendar_import.py.
Version 0.13.0
Migration additive user_identity.company TEXT NOT NULL DEFAULT ''. /api/identity accepte 200 caractères, conserve l’entreprise si absente de la requête, et isole par user_id. Aucun effet sur les tournées. Les filtres de visite et de visibilité sont appliqués côté navigateur ; masquer ne réinitialise pas les critères.
scripts/import_rpps_department.py prépare les lignes RPPS (profession 40, commune département 31), déduplique par RPPS + identifiant de structure, puis précharge uniquement l’utilisateur demandé avec sauvegarde SQLite, transaction et préservation des données existantes. --raw attend un tableau JSON issu de l’extraction officielle ; --records désigne le fichier préparé. Exemple : python3 scripts/import_rpps_department.py --raw /tmp/rpps31.json --date 2026-09-17 --records /tmp/records.json. Enrichir les coordonnées via IGN avec concordance commune/voie/numéro avant --records /tmp/records.json --db data/visit.sqlite --user-id ID --apply. L’import ne géocode pas lui-même. Les adresses manquantes restent non résolues ; ne pas fabriquer de coordonnées. eastern_sector utilise le tracé connecté Ariège puis Garonne (resources/ariege-garonne.geojson), fermé vers l’est hors du département, et un test point-dans-polygone. Source : relations OpenStreetMap 1104538 et 70423, © contributeurs OpenStreetMap, ODbL 1.0. Ne jamais inclure les jeux de données ou sauvegardes dans Git. Tests : tests/test_department.py, tests/test_identity.py et tests/portfolio_filters.js.
Comptes : preferred_time au format HH:MM ou vide ; profil : preferred_time_tolerance entier 0–240 (défaut 30). Le moteur applique la fenêtre au début de visite avant et après le déjeuner. Le tri JS utilise la locale, un départage par identifiant et place les valeurs absentes en dernier.
Serveur : server.py assure API JSON, fichiers statiques explicitement autorisés, sessions, accès SQLite et transactions. Base locale data/visit.sqlite, chemin configurable par VISIT_DB ; port par VISIT_PORT. Python 3.10+ sans dépendance tierce serveur. Démarrer avec python3 server.py ; usage local uniquement. Ne pas copier une base active sans sauvegarde SQLite cohérente.
Données : user_identity (prénom/nom par utilisateur, /api/identity), users, sessions, attempts ; comptes stockés en JSON et isolés par user_id ; visits pour les réalisations ; scenarios pour simulations ; profiles et agenda_days pour préférences ; agenda_routes pour rendez-vous ; calendar_leave, calendar_archives et appointment_history pour congés, snapshots et annulations ; profils de facturation séparés. Les schémas CREATE TABLE et migrations dans server.py font autorité. Les dumps utilisateur ne font pas partie du dépôt.
Modules : planner.py (heuristique), routing.py (IGN et cache), geocoding.py (normalisation IGN/BAN), agenda.py (profils, contexte, ICS), working_calendar.py (jours ouvrés/fériés), appointments.py (statuts/annulations), agenda_history.py (archives/fusion), commerce.py (éditeur/version/licences), translations.py (erreurs). Interface : app.js, agenda.js, lifecycle.js, i18n.js, messages.json ; CSS et logo locaux.
API : /api/register, login, logout, state ; client, import, visit ; addresses ; profile, agenda-day ; agenda-publish, agenda-export, agenda-simulation-export ; appointment-status, appointments-cancel, agenda-recalculate ; subscription-profile et subscription-invoice-preview. Pour la liste exhaustive des chemins et leurs validations, consulter l'annexe automatique des endpoints. Écritures protégées par session, jeton CSRF et Origin ; ressources privées filtrées par utilisateur.
Sécurité : mots de passe scrypt ; cookies HttpOnly/SameSite ; expiration de session 12 h ; rate limiting ; HTTP local, pas de SaaS public validé. Le passage en production nécessite TLS, exploitation, sauvegardes, supervision et configuration des paiements. Les abonnements/factures sont des espaces préparatoires, pas une facturation opérationnelle.
Durées : compte à zéro ou non renseigné => visit_duration du profil ; valeur positive de 5 à 480 minutes. Les rendez-vous déjà publiés gardent leur durée. Le profil antérieur sans visit_duration utilise 45 minutes. L'enregistrement des paramètres conserve les protections et règles d'archivage existantes.
Livraison : python3 -m unittest discover -s tests -v ; node --check pour chaque fichier web/*.js ; python3 scripts/build_docs.py puis --check. Le générateur produit deux portails HTML autonomes stylés avec logo et quatre rubriques. Le manifeste SHA-256 permet de détecter une documentation non régénérée après changement de source. Le contenu rédactionnel doit aussi être relu : un hash ne prouve pas son exhaustivité. Restaurer le code depuis un commit et les données depuis une sauvegarde séparée.
Version 0.21.0 — licences équipe et listes professionnelles IA
La page /licence présente les abonnements individuels et deux packs exclusivement annuels : jusqu’à 5 utilisateurs, titulaire inclus, à 699 € TTC proposés ; jusqu’à 10 à 1 199 € TTC proposés. Ces prix restent à valider commercialement avant activation. Au-delà de 10 utilisateurs, le site invite à contacter XTR Conseil. Le titulaire ajoute ou retire des utilisateurs déjà inscrits. Les espaces restent privés et séparés. Le contrôle du nombre de places est effectué côté serveur. Les tarifs et descriptions FR/EN se modifient dans l’administration ; un prix zéro masque l’offre.
La page /administration est réservée aux e-mails administrateurs configurés sur le serveur. Elle présente utilisateurs, blocage, attribution gratuite, réinitialisation de mot de passe, estimation du stockage, consultations de l’espace, commandes, factures, tarifs et listes IA. Une attribution gratuite n’émet pas de facture acquittée. Les paiements manuels demandent une référence et une confirmation de réception. Les factures PDF sont générées depuis un instantané de commande et restent conservées ; les données JSON préparent le raccordement à une plateforme agréée de facturation électronique, sans réaliser cette transmission.
Pour constituer une liste IA : choisir une profession et une zone, définir 1 à 100 résultats, fournir si nécessaire un texte public, construire et modifier le prompt, puis le mémoriser. Dans Fournisseurs, enregistrer le modèle exact et la clé API OpenAI, Claude, DeepSeek ou Gemini. La clé est chiffrée côté serveur et n’est jamais renvoyée à l’interface. Le lancement demande confirmation d’un appel potentiellement facturable. OpenAI utilise la recherche web si le modèle l’accepte ; les trois autres connecteurs analysent le texte source fourni sans navigation web dans cette version. Un résultat peut être vide et n’est jamais présenté comme exhaustif ou certifié.
Les résultats restent dans une liste à vérifier. Ouvrir les sources, vérifier les coordonnées, sélectionner les comptes et choisir l’espace utilisateur destinataire, puis confirmer l’import. Les lignes sans source ne sont pas importables. Les doublons nom/adresse et les réimports du même résultat sont évités. Aucune latitude ou longitude produite par l’IA n’est acceptée : utiliser la validation d’adresse avant de planifier les visites. Aucun portefeuille ni agenda n’est automatiquement envoyé à un fournisseur IA.
État de livraison : développement local, connecteurs testés avec réponses simulées ; aucun appel IA réel sans clés. Paiement Stripe et messagerie no-reply@visit-manager.fr nécessitent leur configuration et une vérification de bout en bout. Les ventes aux particuliers restent désactivées. Le sous-domaine d’administration et l’ouverture commerciale ne sont pas annoncés comme déployés par cette version préparatoire. Les données existantes sont préservées. Ne pas activer les contrôles de licences sur les bêta-testeurs sans leur attribuer au préalable un accès adapté.
Version 0.21.1 — recherche officielle de sociétés
Dans la création/modification d’un compte, les coordonnées de facturation de Mon compte et la commande de licence, saisir un nom, SIREN ou SIRET dans « Rechercher une société française ». La liste se met à jour après une courte pause ; chaque établissement indique son SIRET, son adresse, son statut et s’il est le siège. Sélectionner le bon résultat préremplit nom, adresse, SIREN, SIRET, TVA disponible, code APE/NAF et catégorie juridique. Vérifier puis enregistrer le formulaire : la sélection seule ne sauvegarde pas. Les champs restent modifiables et la saisie manuelle reste possible en cas d’indisponibilité. L’API publique Recherche d’entreprises peut omettre les entités non diffusibles. Aucun numéro de TVA n’est calculé : celui renvoyé par l’API n’est pas une validation VIES. Seul le texte de recherche est transmis au service officiel. Les suggestions périmées sont écartées, les requêtes limitées et l’accès authentifié. Le SIRET et la TVA sont conservés avec le compte ou les coordonnées de facturation.
Présentation des licences : titres et prix plus discrets, cinq offres alignées sur grand écran, répartition adaptée sur tablette et téléphone, formulaire de connexion centré et compact.
Prompt de régénération
Présentation : en-tête de l’espace commercial réorganisé en deux groupes, navigation à gauche et langue/compte à droite. Espacements explicites, séparateur et adaptation sur deux lignes pour téléphone ; libellés français et anglais.
Mise à jour bêta : sur demande explicite du propriétaire, le portefeuille réel peut être transféré vers son compte individuel. Exiger VISIT_STAGING_ACK=authorized-real-data et le marqueur staging_meta purpose=authorized-real-data correspondant ; demo-only reste le défaut pour les bases fictives. Conserver HTTPS, isolation par utilisateur et inscriptions fermées. Sauvegarder la base avant import et préserver les champs des comptes. Le bandeau indique désormais « Bêta privée ». Aucun secret ni export de données ne doit être déposé dans Git.
Préproduction accessible sur https://visit-manager.fr depuis le 17 septembre 2026. Déploiement OVH VPS avec Caddy HTTPS, service Python limité à la boucle locale, base de démonstration séparée et inscriptions publiques désactivées. Accès par identifiants individuels remis en privé ; données réelles sur autorisation explicite. Sauvegarde SQLite quotidienne, conservation de 14 copies sur le VPS, en complément du backup OVH. La récupération automatique par e-mail reste non configurée.
Version 0.17 : appointment_journal est un registre append-only par utilisateur, event_key et jour, avec date de capture, empreinte et JSON instantané. appointment_journal.py récupère les archives puis le planning courant et les annulations ; les réalisations priment. Capture limitée aux rendez-vous passés (Europe/Paris), sauf réalisation déclarée le jour courant. Ne pas supprimer le planning actif lors de la capture. Une nouvelle version est insérée seulement si le dernier état diffère ; les états précédents restent stockés. Synchroniser au démarrage, lors de /api/state et avant/après les écritures authentifiées, hors prévisualisation de sauvegarde et géocodage. La liste publique par utilisateur présente le dernier état de chaque événement ; filtres de période côté interface. Inclure le registre dans history des sauvegardes v2, remapper client_id/event_key lors de restauration et accepter v1 sans ce registre. Tester conservation après suppression du planning, non-duplication, reprise des archives, réalisation et isolation.
Version 0.16 : propriété clients.data.owner facultative, validée à 150 caractères, préservée à l’édition et dans les sauvegardes. Afficher et rechercher le propriétaire ; colonne CSV owner ajoutée sans renommer les colonnes existantes. Préchargement RPPS : si eastern_sector vaut exactement False et owner est vide, attribuer Magalie Rousselin. Ne pas confondre absence de coordonnées et Ouest, ni propriétaire commercial et accès utilisateur.
Version 0.15 : ajouter sauvegarde/restauration JSON de l’espace personnel avec six catégories (paramètres, comptes, agenda, historique, simulations, facturation), toutes cochées par défaut. Prévisualiser les catégories présentes avant confirmation explicite du remplacement. Conserver les catégories non sélectionnées ; refuser les dépendances incohérentes. Copie privée automatique préalable, restauration atomique, remappage des références comptes, refus des sauvegardes d’un autre utilisateur, exclusion des secrets et sessions. Reproduire les limites et contrôles décrits dans TECHNIQUE.md et les tests de sauvegarde.
Version 0.14 : conserver des lieux nommés et adresses complètes dans Mon compte. Permettre un lieu embarqué spécifique à un rendez-vous fixe sans l’ajouter au profil. Heures HH:MM avec erreurs visibles dans le dialogue. Ajouter prévisualisation puis import atomique ICS, sélection/validation des lieux, déduplication des occurrences, protection des visites confirmées et recalcul nécessaire des tournées. Respecter les limites et fuseaux documentés dans les guides, sans ignorer silencieusement les événements non pris en charge.
Ajouter entreprise facultative à l’identité (200 caractères), filtre Visite à trois valeurs et filtres repliables sans perdre les critères. Prévoir un import administratif RPPS Haute-Garonne idempotent, par utilisateur, avec sauvegarde et conservation des notes/historiques. Le secteur Est de test est défini dans TECHNIQUE.md ; ne pas classer les coordonnées absentes. Ne pas distribuer de données nominatives dans le dépôt.
Ajouter tri du portefeuille par nom, commune, dernière/prochaine visite planifiée en deux sens, valeurs absentes en dernier. Respecter l’heure préférentielle du compte avec une tolérance de profil de 0 à 240 minutes, y compris après insertion du déjeuner.
Reconstruis Visit Manager pour XTR Conseil en suivant l'ensemble des spécifications fonctionnelles et techniques ci-dessous. Livre un projet exécutable localement, sans secrets ni données personnelles, avec interface et documentation FR/EN, tests et sources. Le résultat doit reproduire les comportements décrits ; aucune identité parfaite du code généré n'est garantie. Pour restaurer exactement une version, utiliser le commit Git correspondant.
Utilise Python 3.10+, la bibliothèque standard, SQLite et HTTPServer, HTML/CSS/JavaScript sans framework. Lis README.md, README_EN.md, AGENTS.md et tous les tests. Implémente comptes individuels, scrypt, sessions hachées de 12 heures, CSRF, contrôle Host/Origin, limitation des connexions, isolation par utilisateur et commit avant réponse HTTP réussie. Écoute uniquement sur localhost par défaut.
Ajoute une identité prénom/nom isolée par utilisateur et une pastille d’initiales ouvrant Mon compte, sans invalider le planning lors de sa mise à jour. Explique le doublon d’inscription et invite à se connecter. Fournis accueil, portefeuille filtrable/import CSV, fiches de comptes éditables au double-clic, agenda jour/semaine/mois avec défilement horizontal et en-têtes fixes, simulations distinctes, visites réalisées, Mon compte, À propos, licences en préparation et documentation. Utilise le logo XTR Conseil fourni dans web/xtr-conseil.svg ; n'invente aucun tarif ou paiement actif. Conserve les contrôles d'accès, les données existantes et les migrations compatibles.
Reproduis les modèles, validations, endpoints et modules décrits dans TECHNIQUE.md. Respecte le cycle des visites, la protection des rendez-vous confirmés, les archives et exports. Tous les textes doivent être FR/EN, y compris erreurs serveur et exports ; ne traduis jamais les données saisies. Génère les en-têtes CSV en FR/EN selon la langue ; accepte aussi les anciens en-têtes techniques lors de l’import. La durée d'un compte à zéro utilise la durée du profil utilisateur (45 minutes par défaut). L'adresse doit être recherchée via IGN/BAN après 650 ms de saisie inactive, avec rejet des réponses dépassées, sélection par double-clic ou validation clavier/bouton ; récupérer numéro, voie, code postal, commune, code INSEE, pays et coordonnées disponibles, conserver les compléments.
Planifie par heuristique gloutonne chronologique avec priorités, intérêt, échéance, contraintes horaires, jours ouvrés, congés, jours fériés français, pauses déjeuner, lieux de départ/retour et durée. Regroupe les comptes partageant une adresse. Utilise IGN pour les trajets automobiles, cache directionnel de 30 jours et budgets réseau ; indique les estimations de secours et l'absence de trafic en temps réel. Ne promets pas d'optimum global.
Implémente propositions, transfert ajout/remplacement explicite, confirmation, réalisation avec compte rendu, annulation, absence/report, annulation proposée des visites passées non réalisées. Ne compte que les réalisations dans la dernière visite. Conserve les horaires des autres rendez-vous lors d'une annulation ; signale les conflits de trajets. Exporte ICS en UTC depuis Europe/Paris avec UID stables, statuts et pliage UTF-8, sur horizon sélectionné. Les simulations/archives sont en lecture seule.
Avant livraison : tests unitaires sur bases temporaires, syntaxe de chaque JS, vérification FR/EN et documentation générée. Inclure documentation utilisateur, technique, fonctionnelle, ce prompt et manifeste de sources. Ne publier ni data/, exports/, .backups/, clés ou secrets. Ouvrir chaque nouvelle version dans le navigateur externe. À chaque dépôt, actualiser les documents, régénérer via scripts/build_docs.py, vérifier le CI du commit publié.
Version 0.21.0 — licences équipe et listes professionnelles IA
La page /licence présente les abonnements individuels et deux packs exclusivement annuels : jusqu’à 5 utilisateurs, titulaire inclus, à 699 € TTC proposés ; jusqu’à 10 à 1 199 € TTC proposés. Ces prix restent à valider commercialement avant activation. Au-delà de 10 utilisateurs, le site invite à contacter XTR Conseil. Le titulaire ajoute ou retire des utilisateurs déjà inscrits. Les espaces restent privés et séparés. Le contrôle du nombre de places est effectué côté serveur. Les tarifs et descriptions FR/EN se modifient dans l’administration ; un prix zéro masque l’offre.
La page /administration est réservée aux e-mails administrateurs configurés sur le serveur. Elle présente utilisateurs, blocage, attribution gratuite, réinitialisation de mot de passe, estimation du stockage, consultations de l’espace, commandes, factures, tarifs et listes IA. Une attribution gratuite n’émet pas de facture acquittée. Les paiements manuels demandent une référence et une confirmation de réception. Les factures PDF sont générées depuis un instantané de commande et restent conservées ; les données JSON préparent le raccordement à une plateforme agréée de facturation électronique, sans réaliser cette transmission.
Pour constituer une liste IA : choisir une profession et une zone, définir 1 à 100 résultats, fournir si nécessaire un texte public, construire et modifier le prompt, puis le mémoriser. Dans Fournisseurs, enregistrer le modèle exact et la clé API OpenAI, Claude, DeepSeek ou Gemini. La clé est chiffrée côté serveur et n’est jamais renvoyée à l’interface. Le lancement demande confirmation d’un appel potentiellement facturable. OpenAI utilise la recherche web si le modèle l’accepte ; les trois autres connecteurs analysent le texte source fourni sans navigation web dans cette version. Un résultat peut être vide et n’est jamais présenté comme exhaustif ou certifié.
Les résultats restent dans une liste à vérifier. Ouvrir les sources, vérifier les coordonnées, sélectionner les comptes et choisir l’espace utilisateur destinataire, puis confirmer l’import. Les lignes sans source ne sont pas importables. Les doublons nom/adresse et les réimports du même résultat sont évités. Aucune latitude ou longitude produite par l’IA n’est acceptée : utiliser la validation d’adresse avant de planifier les visites. Aucun portefeuille ni agenda n’est automatiquement envoyé à un fournisseur IA.
État de livraison : développement local, connecteurs testés avec réponses simulées ; aucun appel IA réel sans clés. Paiement Stripe et messagerie no-reply@visit-manager.fr nécessitent leur configuration et une vérification de bout en bout. Les ventes aux particuliers restent désactivées. Le sous-domaine d’administration et l’ouverture commerciale ne sont pas annoncés comme déployés par cette version préparatoire. Les données existantes sont préservées. Ne pas activer les contrôles de licences sur les bêta-testeurs sans leur attribuer au préalable un accès adapté.
Version 0.21.1 — recherche officielle de sociétés
Dans la création/modification d’un compte, les coordonnées de facturation de Mon compte et la commande de licence, saisir un nom, SIREN ou SIRET dans « Rechercher une société française ». La liste se met à jour après une courte pause ; chaque établissement indique son SIRET, son adresse, son statut et s’il est le siège. Sélectionner le bon résultat préremplit nom, adresse, SIREN, SIRET, TVA disponible, code APE/NAF et catégorie juridique. Vérifier puis enregistrer le formulaire : la sélection seule ne sauvegarde pas. Les champs restent modifiables et la saisie manuelle reste possible en cas d’indisponibilité. L’API publique Recherche d’entreprises peut omettre les entités non diffusibles. Aucun numéro de TVA n’est calculé : celui renvoyé par l’API n’est pas une validation VIES. Seul le texte de recherche est transmis au service officiel. Les suggestions périmées sont écartées, les requêtes limitées et l’accès authentifié. Le SIRET et la TVA sont conservés avec le compte ou les coordonnées de facturation.
Présentation des licences : titres et prix plus discrets, cinq offres alignées sur grand écran, répartition adaptée sur tablette et téléphone, formulaire de connexion centré et compact.
Préproduction
Mise à jour bêta : sur demande explicite du propriétaire, le portefeuille réel peut être transféré vers son compte individuel. Exiger VISIT_STAGING_ACK=authorized-real-data et le marqueur staging_meta purpose=authorized-real-data correspondant ; demo-only reste le défaut pour les bases fictives. Conserver HTTPS, isolation par utilisateur et inscriptions fermées. Sauvegarder la base avant import et préserver les champs des comptes. Le bandeau indique désormais « Bêta privée ». Aucun secret ni export de données ne doit être déposé dans Git.
Préproduction accessible sur https://visit-manager.fr depuis le 17 septembre 2026. Déploiement OVH VPS avec Caddy HTTPS, service Python limité à la boucle locale, base de démonstration séparée et inscriptions publiques désactivées. Accès par identifiants individuels remis en privé ; données réelles sur autorisation explicite. Sauvegarde SQLite quotidienne, conservation de 14 copies sur le VPS, en complément du backup OVH. La récupération automatique par e-mail reste non configurée. Ce dossier ne déploie ni n'achète automatiquement un serveur. Le serveur HTTP Python reste lié à 127.0.0.1 ; une instance Caddy sur le même hôte fournit HTTPS. Ce dispositif est destiné à une recette restreinte, pas à une exploitation SaaS générale. Une validation TLS et réseau sur le serveur cible reste obligatoire.
Isolation et comptes
Ne jamais copier la base locale complète. Transférer uniquement les comptes explicitement autorisés. Déployer le code seul dans /opt/visit-manager-staging sur un serveur Linux administré, sous un utilisateur système dédié visit-staging. Réserver /var/lib/visit-manager-staging (propriétaire visit-staging, permissions 700). Prévoir Python 3.10+ et Caddy maintenus à jour. Aucun changement des services AO Manager existants sans revue des ports et domaines.
Créer les comptes sous cet utilisateur avec :
python3 scripts/create_demo_tester.py --db /var/lib/visit-manager-staging/visit.sqlite --email adresse-du-testeur@example.fr
Le script refuse une base locale, une base non identifiée comme démonstration et un compte existant. Il crée 12 comptes commerciaux fictifs par testeur. Le mot de passe aléatoire est affiché une seule fois : le remettre individuellement par canal privé, ne pas le placer dans Git ou un journal partagé. Chaque testeur dispose de son espace et d'un secret distinct. Les inscriptions publiques sont désactivées. Les données de démonstration sont volontairement fictives ; les trajets IGN restent indicatifs. Aucun e-mail automatique n'est envoyé.
Configuration du serveur
Adapter deploy/staging/environment.example avec le domaine exact et installer ses valeurs dans /etc/visit-manager-staging.conf (droits 600). Installer l'unité systemd fournie après revue. VISIT_MODE=staging exige un domaine HTTPS, une base absolue hors data/ et l'acquittement demo-only ; un marqueur de base démonstration est contrôlé au démarrage. Les paramètres locaux ne changent pas.
Ajouter le bloc deploy/staging/Caddyfile au proxy existant, sans remplacer sa configuration. Définir STAGING_HOST dans l'environnement du service Caddy avec le même nom que VISIT_PUBLIC_ORIGIN, sans https://. Vérifier caddy validate --config /etc/caddy/Caddyfile avant rechargement. La directive reverse_proxy conserve une origine externe autorisée vers le serveur local. Caddy gère les certificats HTTPS ; les ports publics nécessaires sont 80/443, jamais 8791. Faire pointer uniquement le sous-domaine approuvé vers l'hôte ; vérifier les éventuels enregistrements IPv6. Voir https://caddyserver.com/docs/caddyfile/directives/reverse_proxy.
Recette avant partage
Vérifier : certificat valide sur le sous-domaine ; inscription refusée ; connexion avec deux testeurs distincts ; isolation des données ; cookie Secure/HttpOnly/SameSite ; refus des origines étrangères ; formulaires, simulation et ICS ; inaccessible directement sur 8791 depuis Internet ; aucune donnée réelle dans la base. Les tests automatisés locaux ne remplacent pas ces contrôles externes. Tenir une sauvegarde SQLite cohérente séparée et un journal de version. Pour suspendre les tests, retirer le site Caddy puis arrêter seulement l'unité visit-manager-staging. Ne pas toucher aux autres sites.
Décisions attendues
Serveur, domaine et premier testeur configurés. Contrôles externes réussis : certificat HTTPS valide, connexion et lecture du portefeuille de démonstration. Durée de recette et conservation des données à préciser. Le service MX 5 est indépendant de cet hébergement.
Préparation de production
Modules : production.py (licences, sièges, commandes, TVA, factures et audit), business_api.py (droits et routes), professional_lists.py (prompts et connecteurs), invoice_pdf.py (PDF XTR Conseil), mail_delivery.py (file d’envoi), web/business.html/js/css (portail bilingue). Installer requirements.txt dans l’environnement Python du service. Les migrations ne suppriment aucune donnée ; les tables métier sont créées au démarrage. Les clés IA sont exclues des sauvegardes utilisateur et des retours API, mais les chiffrés font partie de la sauvegarde SQLite serveur.
Paramètres serveur, conservés hors Git et hors des exports : VISIT_ADMIN_EMAILS (liste explicite, compte précréé avant ouverture des inscriptions), VISIT_PRODUCTION=1 pour les contrôles de licence et inscriptions publiques, VISIT_PRICES_APPROVED=1, VISIT_TEAM_PRICES_APPROVED=1 après validation des prix packs, VISIT_VAT_CONFIRMED=1, VISIT_STRIPE_SECRET, VISIT_STRIPE_WEBHOOK_SECRET. Le mode HTTPS existant reste VISIT_MODE=staging tant que le déploiement est préparatoire. Ne pas activer VISIT_PRODUCTION avant revue du parcours, migration des droits bêta et vérification de la facturation. L’accès administrateur doit être provisionné avec un secret individuel fort ; aucun mot de passe partagé de test.
Clés IA : définir VISIT_AI_MASTER_KEY, clé Fernet aléatoire générée sur le serveur. La conserver dans un fichier de service protégé, sauvegardé séparément de la base. Sans cette clé, les clés API sauvegardées sont irrécupérables ; la rotation nécessite de les ressaisir ou une migration de chiffrement. Les clés API saisies dans l’administration sont chiffrées. Aucun appel réel n’a été effectué pendant les tests. Les destinations API sont fixes et HTTPS, les redirections refusées, les réponses limitées à 2 Mo. Les exceptions du fournisseur ne sont jamais retournées brutes. Les modèles sont configurables, sans substitution automatique. Les appels sont limités à 12 000 jetons de sortie et à une génération simultanée par administrateur sur la fenêtre de travail ; les limites financières sont à définir chez le fournisseur. Un échec n’est jamais relancé automatiquement. Les coordonnées IA sont rejetées. Import uniquement après validation explicite, avec source et dédoublonnage. Les résultats sont persistants et lisibles seulement par les administrateurs.
Paiement : /api/payment-webhook vérifie la signature Stripe avec tolérance de cinq minutes, le montant, la devise, la session et le mode test/réel. L’activation et la création de facture sont transactionnelles et idempotentes. Un retour navigateur ne suffit jamais. Les sièges incluent le titulaire ; une réduction de pack est refusée tant que trop de membres subsistent. Les espaces de données ne sont pas fusionnés. Les factures JSON sont des données préparatoires, pas du Factur-X ni une transmission agréée. La correction comptable/avoir et le raccordement à une plateforme agréée restent à finaliser avant exploitation commerciale complète.
Messagerie : VISIT_SMTP_HOST, VISIT_SMTP_PORT (465 TLS implicite ou port STARTTLS), VISIT_SMTP_USER, VISIT_SMTP_PASSWORD. Expéditeur fixe no-reply@visit-manager.fr : existence et autorisation d’envoi OVH à vérifier avant activation. Exécuter scripts/deliver_business_mail.py via un service dédié avec le même environnement et la même base, quotidiennement. Il prépare les rappels J-14, J-7, J-1 et traite les factures en attente. Sans SMTP configuré, aucun message n’est envoyé. Un envoi incertain est marqué à vérifier, jamais réessayé automatiquement. Les rappels utilisent la dernière langue FR/EN enregistrée lors de la consultation de l’espace ou de la page licence (français par défaut). Le parcours d’oubli de mot de passe existant n’envoie pas encore ces codes par SMTP ; l’administrateur fournit un code privé valable une heure. Ne jamais envoyer le mot de passe lui-même.
Ventes consommateurs : désactivées. VISIT_MEDIATOR_NAME et VISIT_CONSUMER_SALES_APPROVED sont des verrous de configuration, pas une preuve de conformité. Ne pas activer avant la désignation du médiateur, le formulaire et la fonction de rétractation en ligne, la confirmation durable des conditions et la validation complète du parcours légal. Les CGV bilingues sont une préparation à relire avant ouverture commerciale. Les données de facturation sont limitées à la France dans ce périmètre.
Compteurs : consultations = lectures authentifiées de l’état applicatif, pas visiteurs uniques du site. Stockage = somme des tailles des JSON utilisateurs et PDF, estimation logique hors sauvegardes et index. Le sous-domaine administration.visit-manager.fr exige encore une configuration DNS/TLS et une politique d’origine dédiée ; utiliser /administration dans l’environnement de développement. Pas de modification DNS ou d’ouverture de production effectuée par cette livraison locale.
API · 0.23.0
/api/account
/api/addresses
/api/admin-
/api/agenda-archive
/api/agenda-archive-read
/api/agenda-day
/api/agenda-export
/api/agenda-leave
/api/agenda-leave-delete
/api/agenda-publish
/api/agenda-recalculate
/api/agenda-simulation-export
/api/appointment-status
/api/appointments-cancel
/api/backup-export
/api/backup-import
/api/backup-preview
/api/billing-
/api/billing-offers
/api/calendar-display
/api/calendar-holidays
/api/calendar-import
/api/calendar-preview
/api/client
/api/company-search
/api/config
/api/contact
/api/contact-token
/api/delete-scenario
/api/identity
/api/import
/api/login
/api/logout
/api/password-forgot
/api/password-reset
/api/payment-webhook
/api/plan
/api/profile
/api/profile-draft
/api/register
/api/reschedule
/api/save
/api/scenario
/api/state
/api/subscription-checkout
/api/subscription-invoice-preview
/api/subscription-profile
/api/visit
SHA-256
{
"AGENTS.md": "ecab08fab5db51a714cc8a4a463e1fc47b7b79a9b593915244c0bde1ceaaf878",
"README.md": "2e8f023b486aa6149a02587cb181ebaf676d77bdf40b69efb3349f6d8e94701d",
"README_EN.md": "349edf05f21152aa5d30a083a7ec1c6f52894a2061b4d9ccc119ad5558996f22",
"agenda.py": "cc7ee53bd88aaaf2edba7fa191ee484881e6b9dc4f9a4ff1a1eec9384821757c",
"agenda_history.py": "a956d5de7f6871d81adabf3a6ef5487e0658d2a7bb5c17119249829ba68b6669",
"appointment_journal.py": "ee215aeffa6a851f35abec89fac13cb8107ac59119c5e0d09cd624e9d30dd095",
"appointments.py": "d4da86f82c0519b1e4722232cac2b91e90b5301a8ed13e8faa5728ef847cc868",
"business_api.py": "eeffa7a5079937975b3631a5c650cde842b87d5480f8bea9d9d06f26e5fd7f6e",
"calendar_import.py": "6b8b478e0f6623e9bf0bda3e324f01b5471f1f7a62efc6bd7e8ad9d6c612137d",
"commerce.py": "e7b78663e689c4c535649860428db759a0487eefe537f8ba46f6275523af95e2",
"companies.py": "2b3918565e4d083e23d86848889070fcd9f1abab14cacfd4f1242d0248aec1a2",
"contact.py": "61e4bb53386d115cb01f755da6c0874177de6238f7349e6a14f175453796fd1c",
"csv_accounts.py": "54a1e30b3b407271d7e0a5894a7d75537a0b354ece7b356adc6c5323693c7279",
"deploy/staging/Caddyfile": "9c0bd5855965f56c9343c3eb79f08de14eedd58c6cc8b1aefedddc70834b51af",
"deploy/staging/admin.Caddyfile.example": "4d5144d5a4a94c2e94e887aaa5bf38d1d99dcadb6455329a99f6443453406c9b",
"deploy/staging/environment.example": "0785ae06eb012cc2f5b57192716c7f0d8d319ee8a4ba2acbd983c1b30d6b4ada",
"deploy/staging/visit-manager-staging.service": "2f13639dbd2720479419378af201ac92bca558d0347b6268bb06b36c3e2c3f2c",
"deployment.py": "91c780f20fb162b85eda9bccc4a364935cd84e170e591c6c7d1d1781ca06f3cb",
"docs/CGV_PREPARATION.md": "4f070d692caedcf80719447b49670c24f5dec21cc72ec5144e715c5e4f93b821",
"docs/MENTIONS_LEGALES.md": "cb7a5b63f607dbfc8ea37de9f434232776c71f9a0da71aece7a1fa91f18af71a",
"docs/PREPRODUCTION.md": "354bfb22cac2647beb11ccfbbf4d815898de65d812adf5aa6a47e752386decb7",
"docs/PRODUCTION.md": "a3fa9235ba59f26b895fbbe3d3857c2c0e7ea2860fb7e40ae48f610be8948c67",
"docs/REGENERATION.md": "2b169960d3c49d5045ec77f9df14141469845936f39a2195ac8e31d4ef00dee9",
"docs/TECHNIQUE.md": "9e97f96ad00d7a4ef1cf14c5e1a4e75c924bfa98fb4c00db3decfe4312c5928b",
"docs/UTILISATEUR_EN.md": "3450de3cdf2cccc27dddf6be45d0c28fe1956434f22345ddc4a4e080b852dd53",
"docs/UTILISATEUR_FR.md": "a88d3ff25844f28fbcdbebb3512b2d4df68335e80a37bf7e73494421f720cd15",
"drafts.py": "b17a442f9101f9fda25110e774acdf834ecebf2d44fdc4190e0bd90f595aabb3",
"geocoding.py": "336ff982739c63be2ea02548c24f3fd966208df7746c076c82443d68287e4651",
"invoice_pdf.py": "dd393d49a5c9ceb409eeaf8b0cfdf1dc20da11594bbbdb98712854e5bc4db908",
"mail_delivery.py": "1abe23f29f6663e5d45246d4e73baba189017eb5efad7cf475df749b62498f6b",
"password_reset.py": "3979092887cd6720d32f133520a51a678ec51e02576b7f29dd2c95ce785a1784",
"planner.py": "901798400d520be768f176c60ca40789e72a80db91e6f5303b3e44e7f4b8812f",
"production.py": "c1ff35dc40c305c98efc6e1f2156143619463b7581b22ebf3b70a521d2e10519",
"professional_lists.py": "1a36d25f90a2ffafb295a9c7230eb8de1b0aad94f32a600c944d0ed508e5cc69",
"requirements.txt": "3737c6f7ec7effbc9b6e5f8efa6dcd6540cd51cedcfa4d13c192d4e91664ee70",
"resources/ariege-garonne.geojson": "3ebbacc78366c8d2e0f02982dc98d1127ff341fc4ec8661bca0a25b9feae23e9",
"routing.py": "2121945a22d08b45b4df1f5227a40555ec9fe2349fb7ae357edd51f2e4a30bf3",
"scripts/build_docs.py": "9074075c9fe85f3b9d6d7e8eaa898f3e06960c37935bba9fb3cf749a1dbc3ac2",
"scripts/create_demo_tester.py": "468642479b05f0df1a604ea26c3616d23f9b6f2093d43478ef7230a3f531eceb",
"scripts/deliver_business_mail.py": "2026f9c5a7c88cdee781d43fbc7d4e02864f2857b1585a0dd67d7f80355972c5",
"scripts/enrich_contacts.py": "b1c30f16fc3ce9e978939db62073d9f3af8ecfa479378f625253dd42b7773c2f",
"scripts/import_rpps_department.py": "560adc889030df327939ddc370add1a28df4c2338036505905277b4a6270027c",
"server.py": "2666eae872d5641bea08dcb403267883d7d496f30b54e266ce015fd2ff272611",
"temporary_access.py": "7bbf51bf695461c31c47f66ea8c68c3587eb70242527efc8a468364e7efaf05e",
"tests/appointment_status.js": "31698b8b44e96225341a19f9aeab81aa49c31b56eadc79e7d9d3dd1946a016d3",
"tests/portfolio_filters.js": "ba2f2e1131cd90c0971acf455a60503a9df797b11cf942dd6a7b10387c7ff07c",
"tests/profile_guard.js": "333cb2d35d5660d55ec4f99ee61d868df967fb4caa8b1b60b74c1f387f0f2592",
"tests/test_account_owner.py": "16129eda488a053330d5432cc50d6509833a09d2ed06ef2b6faf3a1458ac7645",
"tests/test_accounts.py": "946afb1a09b831c2d56281bd49e8904c85429405d8dc6449d4fb9abb92889c06",
"tests/test_agenda.py": "45ac4276d9601555f9ba37f485fc50c60a8513d7819f2b6fab9050b556e26f30",
"tests/test_app.py": "4bd09fcfd1a3b0341835aabdb8f9590b834701ed9dce401279cb819270a57442",
"tests/test_backup.py": "6f46421509ac8b21ae3cd49617b407a772188e7ca50f3c851733709d019bac15",
"tests/test_business.py": "56aa3b831dbb132a33ab166ebd8e9307ed4dadff04cd79055de62de704fff91f",
"tests/test_calendar_import.py": "72d2e0413b3ba7d340f432489b76f33d22744a8a4f0b9c8e4ed8ba3916351667",
"tests/test_companies.py": "67a5188d1fd5658c7b7e99db01d295f2f9e4a928f7b14def1dbc2b4e4a7ff2df",
"tests/test_contact_purchase.py": "fef7f08277fffebff6b358fd7ed728bd6e1e62938e90af208b94d6b7edafcff6",
"tests/test_contacts.py": "c25b51e5740679777546dbd7e1b8eb4122a5190dda473cd39eed55b059e60a3f",
"tests/test_csv_localized.py": "d67c7ff1b6abdfa3f953ee9a4eb2983f0822899b869baab34b6af4e99716ec2b",
"tests/test_department.py": "16f2aac8c7606c4bde592b8a0a70f72c95c00f1502315a667b5f89224b6deece",
"tests/test_drafts.py": "9409f7e99c7e1bb0ceb72a125c0661663a8b9fa86e71cd3740c13b13d25f8aea",
"tests/test_duration_defaults.py": "fe39824eded3023ae4815cf41fe6ffa7891baebdbd4a7a4340beb58740af6129",
"tests/test_fixed.py": "864b3b58db7f5e215dd665240d5e1bfbd43a2131dd1c06ce9f5d8451abd7f079",
"tests/test_grouping.py": "84ff0abae371402721939999228af3f5df24059d9dd31ac80ceced3b4d5137cb",
"tests/test_identity.py": "54a19bd4de8fcb08cb88e9cf344f8a81d1a7a32dd91be2871245359dde34f863",
"tests/test_journal.py": "98bff9001a66df64ab746bce843446a319f208c2a11d7425f9094eea2c446be0",
"tests/test_lifecycle.py": "02cc86246851a586d64b5e3caefb3eb9ee71c7446bd3537dac144ed0b1c9d8c1",
"tests/test_password_reset.py": "b1d0837834b0092d7c5cedabc1649681c6cc2efaeba10ae53fbdeb15ad0364eb",
"tests/test_preferred_time.py": "f18d1f8a21b483fab425496eabb27a2c3e600dc2b8cdd56978fdf80f658df990",
"tests/test_routing.py": "145997f9b85331e7b6bdf5193836281cf50c4174809805dade95761e60245570",
"tests/test_staging.py": "e4d0add5af1a55dc0ce1d34adead00527d0e184d619cd35774e1bdeed1cb5504",
"tests/test_temporary_access.py": "6d51a1c2603b22bf25cfc6272933de2b5b4978ef2c078a59b683ba5cb88edd19",
"tests/test_ui_status.py": "d4ef3c16b6f78748625127358f42c261c95050330698d7ce33827312e38f0fd6",
"tests/test_v03.py": "c96b3b1f31da79b494a5fed7d7d2df41e525a1e567680080e00efbc186e0e034",
"translations.py": "e9566b41fd32c4fedf1f47841ec9fefc1d6788cae7b997271c8ea78d81cfc527",
"user_backup.py": "7223b14135887fbbfa0ecfedc839eab338bea30fbb157d016bbab8f583551b35",
"web/agenda.js": "6e1566c6c2286806a0d9fc5ca9273da96a3e8f8afe3d884462948d9ae3e4ddd3",
"web/app.js": "46f151b7af3189de3db4a3b0a9b220035ecb8169930cf03d63c759fbea58544c",
"web/backup.js": "8d08776a0da4d4368a7bd34b5bfb18d746be757d6bfc81862217b02344bee9b9",
"web/business.css": "b506b8417351b64feb548fb14247bc1e908231467473b7c8253f1f549089771c",
"web/business.html": "62ea51465194aa4063834dcbed3728eb65b803d51758f031fa1dfce519cd4bb6",
"web/business.js": "3ae7dfc51b056c0731da1e572625698a622a5d0f83ef31bb9c3af324a82f68a6",
"web/calendar.css": "cd56e01a4ef8d1130957ae4fdcf58bcae7962b6f2be1e8c4b999413b9fcfa8b0",
"web/cgv.css": "aa465b6b8eae0e20c58ab41aeb3addc37f5ed5c91c58e35225c010d1ba1e40c4",
"web/cgv.html": "d86962bda5730d98ce8cbd8bc5478eb6a896cd1c18ca4a33f7015736f478cdb8",
"web/company-search.css": "5ef8179ac613602b0290133fae9f784502a0dea9dd47b94981435864561724e8",
"web/company-search.js": "d4e8e03292dcd0dae7ed24fcb487819988ecf4190632b6c96358ec67b0cdbd28",
"web/contact.html": "4044e7f921b33b912c0724217677fe75e8437a0bd80072c85e09f8b398608fd3",
"web/contact.js": "315c5a14e3e8f7e805a07ee0152bfb8ef96f1beb9fd314490e2192bf614b4f45",
"web/csv-columns.json": "24d13d00c14348009b7a8c148223baa296f093b7db415923151de2bfba873a0a",
"web/home.html": "6aefaf4bcb2a44e1bce41077289a229085d031c7652d16a4a23a70f8772ba7f6",
"web/home.js": "7581d6dee01dfb6c9f07a587706f3157e79290b48347567746a3bdfb9524a417",
"web/i18n.js": "f9bf85dcbc4c1978c064c31af0be70634a045716b98a128b11e223dc56895727",
"web/index.html": "c67ee016e81e748c713527fdaf10bf848df904c6c60fe5798d6f164a0fcfb5ad",
"web/legal.css": "0e5996ad463b1c9d5d3fc8ca3d757babcac43e18dc83690f5ab32ba074bb1047",
"web/lifecycle.js": "0d530851ec3ffe18edccc567c38e0ca64a7cd4c914e31192ed05fd1ef5346502",
"web/mentions-legales.html": "a9b478f8794fcd96ff0e14202d9ccddecc564dd6071251d331fbe2bac3ae6fca",
"web/messages.json": "452f4bea89f23b4f3dcf086fcae6256583c3b9a74ae4959f98be00c52e3f8484",
"web/privacy.html": "f991cdc491505363bfc5cea81a9ec6940d4a77b549f489f475a79e865ff85bf0",
"web/public.css": "4826751197685238b1cd7ad5d518d7f09b0c52c5054c69fb2b4fa567bf95a4c2",
"web/style.css": "a56a673a6788b74dee287004b971480b3c6ede62485935e31ee78456c61d1206",
"web/xtr-conseil.svg": "83915e751749e5bb754dcab42b595a6c3c3ba4e7a2ab7fb721483995c5183ae3",
"working_calendar.py": "3bf3b01180657f58b765771d71a1bdf0f47d36678928b007ae8d0fe9318e5c5a"
}