Carnet de voyage

Fonctionnement

Comment fonctionne le carnet

Une page, un petit serveur, deux téléphones et un assistant qui ne touche à rien sans accord. Voici chaque pièce, telle qu'elle est construite.

Vue d'ensemble

Le carnet est une seule page HTML : fiches par jour, carte, outils et documents. Un serveur la sert derrière un mot de passe avec les données courantes du plan, et relaie en direct ce que font les deux téléphones.

Les appels à l'assistant et les lectures de pages web pour vérifier un fait partent du serveur, jamais du téléphone.

Architecture du carnet Deux téléphones échangent avec le serveur en HTTPS et reçoivent un flux d'événements en direct. Le serveur garde le plan et ses versions, l'état partagé, les conversations et le coffre chiffré. Lui seul appelle le fournisseur d'IA et lit les sites officiels. Téléphone 1page et file d'envoi Téléphone 2page et file d'envoi HTTPS · flux SSE Serveur plan et versions · état partagé conversations · coffre chiffré depuis le serveur Fournisseur d'IAclé des voyageurs Sites officielslus pour vérifier
Les téléphones ne parlent qu'au serveur pour le plan et l'état ; seul le serveur appelle le fournisseur d'IA et lit les pages officielles.

Le plan

Tout le contenu du voyage vit dans vingt listes de données écrites dans la page elle-même. Le serveur garde la version courante, remplace ces listes au moment d'afficher la page et garde la page rendue en cache pour chaque version. Les photos sont servies à part et chargées à la demande.

ListeContenu
citiesVilles : coordonnées, hôtels, Airbnb, lieux, quartiers recommandés et à éviter
daysJours : nuit, villes, transports, étapes à cocher, notes
photosAttractions : nom en français et en japonais, recherche d'images, site officiel
dayAttrAttractions de chaque jour
cityAttrAttractions de chaque ville
wikiArticles Wikipédia des lieux sans photo
luggageMovesEnvois de valises : villes, jours, réception à l'hôtel ou en agence
luggageGuideGuide des valises : principes, bagage à garder, sources
bookings« À réserver » : quoi, avant quand, comment, lien
overviewAperçu : catégories, pass, festivals, sources
dayRoutesTrajets de chaque jour à ouvrir dans les apps
PHRASESPhrases à montrer, en japonais et en romaji
PACKINGListe de bagages
CAL_EVENTSRendez-vous à exporter vers le calendrier
APPSApplications à installer
UBERVilles où Uber fonctionne
PREP« Avant de partir » : formalités, échéances, cases par voyageur
CARDS« À montrer » : cartes en japonais, bordereau, lieu et plan
MESSAGESE-mails préparés, jamais envoyés par le site
FIELDSChamps de « Mes informations »

Chaque valeur a un type connu du moteur : texte simple, HTML limité à quelques balises, adresse web, valeur d'une liste fermée ou nombre. Une valeur qui ne correspond pas est refusée avant d'entrer dans le plan.

Sur le téléphone

  • Mode Direct, par défaut : pendant le voyage, la page s'ouvre sur le jour en cours, à l'heure du Japon. La fiche du jour réunit soleil, valises, météo à 16 jours, « Maintenant », trajets du jour, étapes à cocher, photos, lieux du jour avec « Y aller », logement, dépenses et notes.
  • Mode Complet : ajoute la carte de l'itinéraire, les onglets Valises, À réserver et Photos, la recherche dans tout le plan, les sources et les festivals.
  • Guide : étapes illustrées pour installer les apps utiles, ouvrir la page dans Safari et l'ajouter à l'écran d'accueil.
  • Outils : convertisseur ¥ / CHF, phrases à montrer, dépenses du voyage, liste de bagages, export du calendrier en .ics, réglages.
  • Documents : avant de partir, à montrer, messages à envoyer, mes informations, billets.

Les boutons d'app sont de simples liens web universels : sur l'iPhone, ils ouvrent l'application si elle est installée, sinon le site.

La synchronisation

Cocher une étape, écrire une note ou choisir un logement modifie l'état partagé. Le téléphone traduit ce changement en opération : ajout ou retrait dans une liste (étapes cochées, bagages, préparatifs), ou nouvelle valeur (note, logement, « Mes informations »).

  1. Les opérations sont regroupées quelques centaines de millisecondes, gardées dans une file sur le téléphone, puis envoyées au serveur.
  2. Le serveur les valide, les applique d'un bloc et avance le numéro de version de l'état.
  3. Il diffuse le changement à l'autre téléphone par un flux d'événements en direct (Server-Sent Events).
  4. L'autre téléphone met à jour la case ou la note à l'écran, sans recharger la page.

Sans réseau, la file reste sur le téléphone et repart toutes les cinq secondes jusqu'au retour de la connexion. À chaque reconnexion, le téléphone relit ce qui a changé depuis sa dernière version de l'état. Une opération déjà reçue n'est jamais appliquée deux fois.

Quand le plan lui-même change

Une modification du plan, et non de l'état, crée une nouvelle version. Les deux téléphones rechargent la page en gardant la vue ouverte ; si vous êtes en train d'écrire ou si l'assistant est ouvert, un bandeau « Plan mis à jour · Recharger » attend votre geste.

L'assistant

L'assistant fonctionne avec la clé API des voyageurs, saisie dans Outils › Réglages : Anthropic, OpenAI, DeepSeek ou tout serveur compatible OpenAI. La clé est chiffrée sur le serveur, et le téléphone n'en voit que les quatre derniers caractères.

Chaque tour de conversation s'exécute sur le serveur : il se termine même si le téléphone se verrouille, et les deux téléphones voient la même conversation, une par jour.

Cycle d'une proposition 1. Question : posée depuis l'un des deux téléphones. 2. Lecture : get_day, get_city, search_plan…. 3. Vérification : pages officielles lues par le serveur. 4. Proposition : patchs contrôlés, rien n'est encore écrit. 5. Appliquer : ou Ignorer : c'est vous qui décidez. 6. Nouvelle version : les deux téléphones rechargent le plan. 7. Annuler : patchs inverses, encore une nouvelle version. 1Questionposée depuis l'un des deux téléphones2Lectureget_day, get_city, search_plan…3Vérificationpages officielles lues par le serveur4Propositionpatchs contrôlés, rien n'est encore écrit5Appliquerou Ignorer : c'est vous qui décidez6Nouvelle versionles deux téléphones rechargent le plan7Annulerpatchs inverses, encore une nouvelle version
Une proposition ne touche au plan qu'au moment où un voyageur l'applique ; chaque étape suivante reste réversible.

Les outils

L'assistant ne reçoit jamais tout le plan d'un coup : il lit ce dont il a besoin, et chaque ligne lue commence par l'endroit exact où elle se trouve.

OutilRôle
get_dayLit un jour complet : étapes, trajets, attractions, réservations liées, état partagé.
get_cityLit une ville : hôtels, Airbnb, lieux, quartiers, logement retenu.
get_sectionLit une section : valises, réservations, aperçu, préparatifs, cartes, messages.
search_planCherche un mot dans tout le plan, avec l'endroit exact de chaque occurrence.
propose_changesEnregistre une proposition validée par le moteur, sans l'appliquer.
fetch_urlLit une page web ou un PDF depuis le serveur, derrière la garde anti-SSRF.
search_webRecherche web, pour les fournisseurs qui n'ont pas la leur (Anthropic utilise sa recherche intégrée).
get_weatherPrévision Open-Meteo pour une ville et une date dans les 16 jours.
set_stateCoche une étape, note une dépense ou un logement, sur demande explicite seulement.
list_documentsListe les billets déposés dans le coffre (métadonnées).
read_documentLit le texte d'un PDF, seulement s'il est marqué lisible par l'assistant.
load_skillCharge un mode d'emploi détaillé.

Les outils du coffre n'existent que sur le carnet hébergé. Les pages web lues sont marquées comme non fiables : leur contenu reste une donnée, jamais une consigne.

Les modes d'emploi

L'assistant dispose de 11 modes d'emploi courts ; il charge le détail de celui dont il a besoin avec load_skill.

  • verifier-un-fait
    Vérifier un horaire, un prix ou une règle sur une source officielle, puis dater et sourcer le résultat.
  • modifier-une-journee
    Changer une étape, un horaire, un transport ou une note sans casser la cohérence du jour.
  • ajouter-un-lieu
    Ajouter une attraction, un restaurant ou une boutique à tous les endroits où il doit figurer.
  • logement
    Hôtels, Airbnb, quartiers recommandés et à éviter, logement retenu.
  • reservations
    La liste « À réserver », les pass et les rendez-vous du calendrier.
  • valises
    Valises, envois takkyubin et retraits en agence.
  • preparatifs
    Formalités et démarches avant le départ, échéances et liens officiels.
  • documents-et-cartes
    Cartes à montrer en japonais, e-mails préparés, champs à remplir, billets déposés.
  • etat-et-depenses
    Cocher, noter une dépense ou un logement, seulement sur demande claire.
  • sources-et-festivals
    Sources conservées, festivals, illuminations et catégories de l'aperçu.
  • style
    Règles de rédaction et de typographie de toute chaîne écrite dans le plan.

La validation

Une proposition est une liste de patchs. Chaque patch désigne un endroit précis du plan par un pointeur JSON (par exemple /days/1/plan/2), porte la valeur actuelle attendue, la raison du changement et une source officielle.

Le moteur vérifie le chemin, le type de la valeur, le schéma, les règles de style (ni emoji ni point d'exclamation, « 17 h 30 », « 1 300 ¥ », étapes courtes) et les liens entre listes. Au moment d'appliquer, tout est revérifié contre la version courante : si le plan a changé entre-temps, la carte devient périmée et rien n'est écrit.

Jamais d'application automatique. Le plan ne change que lorsqu'un voyageur appuie sur Appliquer. L'assistant peut seulement cocher une étape, noter une dépense ou enregistrer un logement, et uniquement sur demande explicite ; ces changements sont journalisés.

Versions et annulation

Appliquer une proposition, l'annuler ou restaurer une ancienne version crée toujours une nouvelle version : rien n'est réécrit. Le serveur garde les 100 dernières, avec leur auteur, leur résumé et les patchs appliqués.

  • Annuler : le serveur applique les patchs inverses, et refuse si la valeur a changé depuis.
  • Restaurer (Outils › Réglages › Versions du plan) : copie d'une ancienne version en nouvelle version.
  • Les cases suivent : insérer ou retirer une étape renumérote les cases cochées dans la même version.

Documents et cartes

  • Avant de partir : formalités et démarches, échéances avec compte à rebours, une case par voyageur quand chacun doit le faire.
  • À montrer : cartes en japonais en grands caractères pour la réception, le guichet, le taxi ou l'agence de valises, avec bordereau, adresse à copier et plan du lieu.
  • Messages à envoyer : e-mails préparés, à copier ou à ouvrir dans l'app Mail. Le site n'envoie jamais rien.
  • Mes informations : noms, numéros et adresses remplis par les voyageurs, gardés dans l'état partagé et jamais dans le plan. L'assistant ne les lit pas.
  • Billets et documents : coffre chiffré en AES-256-GCM sur le serveur (PDF, JPEG, PNG, WebP ou HEIC, type vérifié d'après le contenu du fichier, 15 Mo par fichier). Les documents marqués « hors ligne » sont copiés sur le téléphone.

Les plans des cartes à montrer sont faits de tuiles 地理院タイル de l'Autorité d'information géospatiale du Japon (国土地理院), avec leur attribution sous chaque plan.

Hors ligne

  • Le service worker garde une copie de la page, des photos et des plans déjà vus : sans réseau, le carnet s'ouvre quand même, avec un bandeau « Hors ligne ».
  • Les changements faits hors ligne attendent dans la file et partent au retour du réseau.
  • Une copie HTML complète, photos et plans intégrés (environ 6 Mo), se télécharge depuis les réglages pour l'ordinateur.

Sécurité

  • Accès : un mot de passe partagé d'au moins 12 caractères, comparé à une empreinte scrypt ; délai croissant par adresse IP après chaque échec, et blocage général après une série d'échecs.
  • Session : jeton aléatoire dans un cookie HttpOnly, Secure et SameSite=Lax, valable 60 jours glissants ; toutes les sessions peuvent être fermées d'un coup.
  • Requêtes : contrôle d'origine sur toute écriture, taille des requêtes bornée.
  • Page : politique de sécurité du contenu (CSP) stricte, scripts en ligne autorisés par empreinte SHA-256, connexions limitées aux services nommés.
  • Clés et documents : chiffrés en AES-256-GCM ; les clés API ne sont jamais renvoyées au téléphone.
  • Lectures web : garde anti-SSRF sur chaque page lue pour l'assistant (hôtes publics seulement, adresse IP vérifiée après la résolution DNS, redirections revérifiées, taille et durée bornées).
  • Données : écritures atomiques, patchs validés contre le schéma, aucun code venu du modèle n'est exécuté.
  • Robots : en-tête noindex sur toutes les réponses.

Hébergement

Le serveur Node.js tourne dans un conteneur sur un petit serveur en Suisse, derrière un proxy Caddy qui assure le HTTPS. Les données vivent dans un volume sauvegardé chaque nuit, chiffré. Chaque mise à jour du code passe la suite de tests automatiques avant d'être déployée.

Ce que simule la démo

La démo publique montre le vrai carnet, sur un voyage fictif de cinq jours entre Kyoto, Himeji, Miyajima et Hiroshima.

Comme le vrai carnet

  • La page et le code des téléphones
  • La synchronisation en direct entre les deux téléphones
  • Le moteur de modifications, les versions, Appliquer et Annuler
  • Les cartes à montrer et leurs plans

Simulé ou désactivé

  • L'assistant suit des scénarios écrits à l'avance : aucune clé, aucun appel réseau, aucune page lue
  • Chaque visiteur a son bac à sable, effacé après 20 minutes sans activité et au plus tard après 90 minutes
  • Coffre à billets, compte, clé API et copie hors ligne sont désactivés
  • Les plans sont chargés directement depuis les serveurs de 国土地理院

Lancer la démo