Aller au contenu
Application desktop · outil interne2026en service

Bio Réactifs

Le catalogue de réactifs de laboratoire, sur le poste de travail. Sans internet, sans serveur, sans compte.

Signal reçu

Le catalogue technique vivait dans des classeurs Excel qui circulaient par email. Chaque commercial avait sa version, personne n'avait la bonne, et sortir une fiche technique pour un client demandait de retrouver le bon PDF fournisseur dans une arborescence réseau.

Signal émis

Une application de bureau qui tient tout le catalogue en local : recherche plein-texte instantanée, import Excel guidé qui ne détruit jamais une donnée, dépôt intelligent des fiches fournisseurs, impression silencieuse en lot, sauvegardes automatiques. Elle fonctionne dans un laboratoire sans connexion.

Résultats

0
serveur requis
100 %
hors ligne
6
services métier
34
canaux IPC

Démonstration interactive

Une cellule vide ne détruit jamais une donnée

Videz autant de cellules que vous voulez dans le fichier importé. Rien ne se perd.

ChampEn baseFichier ExcelAprès import
fournisseurERBAERBAvide ignoré
designationAlkaline PhosphataseAlkaline Phosphatase
conditionnement500 tests4 x 125 testsmodifié
nombre_tests500500
prix_reference12 40013 900modifié

Cliquez une cellule du fichier pour la vider. Quel que soit le nombre de cellules vidées, aucune valeur en base n'est perdue. Cette ligne serait classée modifiée dans l'aperçu, avec 2 champs réellement modifiés.

ON CONFLICT(reference) DO UPDATE SET
  fournisseur = COALESCE(NULLIF(excluded.fournisseur, ''), produits.fournisseur),
  ...

Mécanisme reconstruit pour ce site, ce n'est pas une capture du produit. Règle reprise de electron/services/ImportService.js, UPSERT_SQL et preview(). Une référence réelle du catalogue public, avec des valeurs d'exemple.

Flux de traitement

De l'interface jusqu'aux données

  1. Interface

    Écran unique, table virtualisée, recherche débouncée à 200 ms déléguée à SQLite - aucun filtrage côté client. Sept modales, raccourcis clavier en cascade.

  2. Pont IPC

    Isolation de contexte active, aucun accès Node dans le renderer. Le preload énumère explicitement la surface exposée : 34 canaux nommés domaine:action, pas d'ipcRenderer brut.

  3. Couche de services

    Six services dans le processus principal - produits, documents, import, export, impression, sauvegarde. L'enregistrement des canaux est séparé de leur implémentation.

  4. Stockage local

    SQLite en mode WAL, clés étrangères actives, index plein-texte FTS5 en trigrammes synchronisé par triggers. Prix stockés en centimes.

Décisions d'ingénierie

Les choix qui méritent d'être défendus, et pourquoi

01

Un import qui ne peut pas détruire une donnée

Le cœur du problème n'est pas de lire un fichier Excel, c'est de ne pas ruiner le catalogue avec. Trois garde-fous se superposent. D'abord l'assistant en quatre temps - choisir, mapper, prévisualiser, exécuter - où l'aperçu classe chaque ligne en nouveau, modifié, inchangé ou en erreur, et affiche pour les modifications un différentiel champ par champ avant/après. Ensuite l'écriture : une seule transaction pour tout l'import, et un UPSERT dont chaque champ est enveloppé de sorte qu'une cellule vide n'écrase jamais une valeur existante. Enfin un instantané de la base est pris avant chaque import, si bien qu'une exception laisse la base intacte et le chemin de la sauvegarde est renvoyé à l'utilisateur.

02

Le mapping des colonnes tolère l'à-peu-près humain

Les classeurs fournisseurs n'ont jamais deux fois les mêmes en-têtes : « Réf. », « reference », « REF PRODUIT ». Plutôt que d'imposer un gabarit, le mapping combine un dictionnaire de synonymes et une distance de Levenshtein avec un seuil proportionnel à la longueur du mot, accents et casse normalisés. Le mapping validé est ensuite mémorisé, donc le deuxième import du même fournisseur est immédiat. Une seule contrainte reste dure : il faut exactement une colonne référence, et l'assistant refuse d'avancer sans elle.

03

La recherche change de stratégie selon ce qu'on tape

Trois régimes. Champ vide, on liste. Moins de trois caractères, la recherche plein-texte n'est pas pertinente, on retombe sur une correspondance simple. Au-delà, on interroge un index FTS5 en trigrammes maintenu par triggers, trié par pertinence - la requête utilisateur étant échappée pour neutraliser la syntaxe FTS. Les filtres, eux, passent par une liste blanche vérifiée deux fois avant toute interpolation dans le SQL : c'est le seul endroit du code où une valeur externe approche d'une requête construite.

04

SQLite en synchrone, et c'est le bon choix

Une API synchrone semble contre-nature en Node. Mais dans le processus principal d'une application de bureau mono-utilisateur, il n'y a aucune concurrence à arbitrer : le synchrone supprime toute la machinerie de promesses pour un accès disque local qui se compte en microsecondes. Requêtes préparées en constructeur, transactions pour les opérations groupées, mode WAL. Le prix des dépendances natives se paie ailleurs - une recompilation contre l'ABI d'Electron à chaque installation.

05

Rapprocher automatiquement 600 PDF de leurs produits

Les fiches techniques arrivent en vrac. Un service analyse le dossier de dépôt et tente de rattacher chaque PDF à un produit : d'abord par le nom du sous-dossier, sinon par les jetons du nom de fichier après normalisation Unicode et passage en majuscules, avec un seuil de longueur minimale pour éviter les faux positifs sur les références courtes. Les produits déjà pourvus sont exclus. Rien n'est déplacé sans confirmation, et les dossiers vidés sont nettoyés récursivement.

06

L'impression, ce problème mal résolu sous Windows

Imprimer en silence, en lot, sans dépendre du lecteur PDF installé sur le poste, n'a pas de solution propre. La réponse : construire un document unique - une page de garde générée aux couleurs de la marque, puis les PDF fournisseurs concaténés page à page en ignorant le chiffrement, les fichiers illisibles étant comptés et signalés - puis invoquer un binaire portable embarqué. Ce n'est pas élégant, mais c'est déterministe. Et si le binaire manque, l'application le détecte et bascule proprement sur l'ouverture système plutôt que d'échouer en silence.

07

Les fichiers Excel exportés contiennent des formules, pas des résultats

La TVA et le prix TTC ne sont pas calculés puis figés : ils sont écrits comme de vraies formules Excel référençant les colonnes voisines. Le commercial qui change un prix dans le classeur voit le total suivre. Détail plus discret : les prix sont stockés en centimes dans la base - un entier, jamais un flottant, parce qu'un catalogue de prix ne tolère pas les arrondis binaires.

Pile technique

  • Electron 31
  • React 18
  • Vite 5
  • SQLite FTS5
  • better-sqlite3
  • ExcelJS
  • pdf-lib
  • Tailwind CSS

Ce que ce projet démontre

Trois points à retenir

01

Un import qui ne peut pas détruire une donnée

Le cœur du problème n'est pas de lire un fichier Excel, c'est de ne pas ruiner le catalogue avec.

02

Le mapping des colonnes tolère l'à-peu-près humain

Les classeurs fournisseurs n'ont jamais deux fois les mêmes en-têtes : « Réf.

03

La recherche change de stratégie selon ce qu'on tape

Trois régimes.

Un projet comparable ?

Ce dossier est la preuve des prestations suivantes