Aller au contenu
Retour aux projets

Pro2025

AutoInit et customisation de Streamline for Invoices chez ITESOFT

J'ai créé AutoInit, un workflow n8n qui automatise de bout en bout l'initialisation des plateformes clientes : environ 2 heures de manipulations sur cinq outils remplacées par un formulaire d'une minute, adopté par toute l'équipe. En parallèle, customisation et support en production de Streamline for Invoices pour des grands comptes.

Durée
Septembre 2025 à aujourd'hui (alternance)
Équipe
Équipe Delivery de Streamline for Invoices (32 personnes)
Mon rôle
Assistant ingénieur développement et projet : créateur d'AutoInit, customisation, support et diagnostic en production
Technologiesn8nDockerAzure DevOpsNode.jsJavaAngularJSPostgreSQLSSH / SFTPGrafanaGit
AutoInit et customisation de Streamline for Invoices chez ITESOFT

Contexte

ITESOFT est un éditeur de logiciels français spécialisé dans l'automatisation et la dématérialisation des processus métiers. Sa solution Streamline for Invoices automatise le traitement des factures fournisseurs de grands comptes, de la capture jusqu'à l'intégration dans l'ERP, en passant par le rapprochement avec les commandes et les circuits d'approbation.

J'y suis en alternance depuis septembre 2025 dans l'équipe Delivery, d'abord pendant ma dernière année de BUT Informatique (parcours DACS), puis dans le cadre de mon cycle ingénieur spécialité DevOps à Polytech Montpellier. Le rôle de l'équipe : adapter la solution standard aux besoins de chaque client, la déployer et en assurer le support.

Le contexte est exigeant. La réforme de la facturation électronique, en vigueur au 1er septembre 2026, multiplie les projets de déploiement, et l'entreprise est certifiée ISO 27001 : accès nominatifs aux environnements clients, bastion SSH audité, comptes de service à permissions limitées. Toutes mes réalisations ont dû s'inscrire dans ce cadre.

Ces travaux sont confidentiels. Je ne peux pas montrer le code, les écrans ni entrer davantage dans le détail ici, mais je suis ouvert à la discussion sur le sujet et j'en parle volontiers en entretien.

Objectifs

Mon alternance s'articule autour de deux projets :

  1. 01AutoInit, automatiser l'initialisation des plateformes : créer une nouvelle plateforme client demandait environ deux heures de manipulations réparties sur cinq outils (dépôt Git créé depuis l'archétype, branches et fichiers de configuration, pipeline de build, installation sur la machine virtuelle, déploiement, frontal web, transmission des accès), avec à chaque étape un risque d'erreur. L'objectif, que je me suis fixé moi-même : réduire tout cela à la saisie d'un formulaire.
  1. 02Customisation et support de Streamline for Invoices : faire entrer les règles de gestion propres à chaque grand compte dans un produit standard sans casser la compatibilité avec ses évolutions, et diagnostiquer les incidents de production.

Approche technique

AutoInit : un workflow n8n de bout en bout. Le projet est né d'une initiative personnelle, après avoir fait plusieurs initialisations à la main. Sans cahier des charges, j'ai formalisé moi-même les besoins : un formulaire (client, alias DNS, environnement, modules), puis la création et la configuration du dépôt Git du client, la construction du livrable, l'installation et le déploiement sur la machine virtuelle, l'exposition sur le frontal web, et enfin la notification de l'équipe avec les accès.

J'ai choisi n8n, hébergé en interne dans Docker, plutôt que de simples scripts : il apporte un formulaire web, un historique visuel de chaque exécution et des notifications. Le workflow enchaîne une dizaine d'étapes. Côté Azure DevOps, il reproduit fidèlement le processus de l'équipe : branche dédiée et merge requests fusionnées par un compte de service, pour garder l'historique et les garde-fous du git flow. Comme la machine virtuelle cliente et le serveur Azure DevOps ne peuvent pas communiquer, n8n sert aussi de pont : il récupère l'artefact de build par l'API puis le pousse en SFTP à travers le bastion.

Des choix guidés par la fiabilité. Les connexions SSH passent par une librairie (node-ssh) appelée dans des nœuds de code, car l'utilisateur change selon le client. Le déroulement est volontairement séquentiel : plus lent d'une dizaine de minutes, mais stable. Et le workflow ne se fie pas aux codes de retour des scripts d'installation : il vérifie l'état réel de la plateforme en comptant les conteneurs Docker démarrés.

Customisation de Streamline for Invoices. Chaque projet client est un dépôt Git qui ajoute une surcouche à un archétype standard : règles métier en JavaScript exécutées par un moteur de règles Node.js, règles Java côté backend, scripts SQL, connecteurs SFTP et tâches cron. Exemple : une facture pouvait être validée sans ses axes analytiques obligatoires. En croisant la spécification contractuelle et le code d'une règle voisine, j'ai trouvé la cause racine (l'état d'attente existait mais aucune règle n'y menait) et ajouté une règle de routage qui interroge le référentiel en RSQL, appliquée de façon homogène sur les six versions concernées de l'archétype.

Diagnostic en production. Face à un rapprochement de facture bloqué, je suis reparti des données brutes plutôt que du symptôme décrit : la quantité n'était pas nulle mais négative, et les métadonnées de la réception prouvaient que la valeur aberrante venait de l'import. Les plateformes tournent sous forme de dizaines de conteneurs Docker, supervisées avec Grafana et des outils internes.

Architecture

AutoInit

  • Entrée : un formulaire n8n (client, alias DNS, environnement, modules).
  • Orchestrateur : n8n dans un conteneur Docker sur un serveur interne, seul point qui accède à la fois à Azure DevOps et aux machines virtuelles clientes.
  • Azure DevOps : création du dépôt depuis l'archétype, branche de configuration, merge requests fusionnées par un compte de service, déclenchement du pipeline de build, récupération de l'artefact par l'API REST.
  • Machine virtuelle cliente (Azure) : dépôt de l'artefact en SFTP, installation et déploiement en SSH, le tout à travers un bastion qui authentifie et journalise chaque session.
  • Vérification : comptage des conteneurs Docker réellement démarrés, puis configuration du frontal web.
  • Notifications : accès envoyés à l'équipe, et un workflow d'erreur dédié publie une alerte dans Teams avec l'étape et le message en cas d'échec.

Plateforme Streamline for Invoices : frontend AngularJS, backend Java (API REST, moteur de workflow BPMN), moteur de règles Node.js pour les customisations, base PostgreSQL, échanges de fichiers en SFTP, le tout en conteneurs Docker sur une machine virtuelle dédiée par client. Cycle de livraison : développement, merge request relue, staging pour la recette client, production.

Compétences développées

Automatisation et orchestration (n8n)

Conception d'un workflow n8n de bout en bout avec nœuds de code JavaScript, gestion d'erreur explicite, workflow d'alerte et configuration du serveur n8n en Docker (variables d'environnement, délais d'exécution, modules autorisés).

Chaîne de build et de déploiement

Rétro-ingénierie d'une chaîne non documentée à partir d'un pipeline existant, pilotage d'Azure DevOps par API (dépôts, merge requests, pipelines, artefacts), déploiement SSH/SFTP à travers un bastion.

Customisation d'un produit standard

Règles métier JavaScript et Java, requêtes RSQL sur les référentiels, scripts SQL et tâches cron, sans casser la compatibilité avec les évolutions du standard.

Diagnostic en production

Investigation dans les conteneurs Docker, les journaux (Grafana), les bases PostgreSQL et les flux SFTP, en raisonnant sur les données plutôt que sur le symptôme décrit.

Sécurité ISO 27001

Moindre privilège appliqué à l'automatisation : aucun compte personnel, compte de service limité aux projets concernés, sessions SSH authentifiées et journalisées par le bastion.

Git flow et revue de code

Branches feature, release et hotfix, merge requests systématiquement relues, convention de commits, et rôle de relecteur pour décharger les seniors des erreurs évidentes.

Extraits de code

Utilitaire SSH d'AutoInit dans un nœud de code n8n (simplifié)
javascript
1// Exécute une commande sur la VM cible et échoue clairement si le résultat
2// n'est pas celui attendu. L'utilisateur SSH est construit à chaque appel,
3// car il dépend du client et de l'environnement.
4const { NodeSSH } = require("node-ssh");
5
6async function run(target, command, { expectCode = 0 } = {}) {
7  const ssh = new NodeSSH();
8  await ssh.connect({
9    host: target.bastionHost,
10    username: `${target.user}@${target.vm}`,
11    privateKey: target.privateKey,
12  });
13  try {
14    const res = await ssh.execCommand(command);
15    if (res.code !== expectCode) {
16      throw new Error(
17        `[${target.vm}] "${command}" a renvoyé ${res.code}\n${res.stdout}\n${res.stderr}`
18      );
19    }
20    return res.stdout;
21  } finally {
22    ssh.dispose();
23  }
24}
25
26// On ne se fie pas au code retour de l'installation : on vérifie l'état réel.
27const running = await run(target, "docker ps -q | wc -l");
28if (Number(running) < target.expectedContainers) {
29  throw new Error(`Seulement ${running} conteneurs démarrés`);
30}

Ce petit utilitaire a mis fin aux étapes « faussement réussies ». Ma deuxième version modifiait les identifiants SSH de n8n en cours d'exécution, mais n8n les met en cache au démarrage de chaque nœud : le workflow se connectait parfois au mauvais serveur. Construire l'utilisateur à chaque appel et lever une erreur explicite avec toute la sortie a rendu chaque échec visible et compréhensible.

Résultats & bilan

  • Environ 2 heures de manipulations remplacées par un formulaire d'une minute, suivi de 40 à 45 minutes d'exécution automatique qui ne mobilisent plus personne.
  • Adopté immédiatement : dès le lendemain de la mise en service, l'équipe m'a demandé d'initialiser des projets avec, et une vingtaine de plateformes ont été initialisées par AutoInit depuis, par moi comme par mes collègues.
  • Validé de bout en bout sur les environnements de développement et de staging, du formulaire jusqu'à la plateforme accessible sur son adresse publique. Une version suivante a supprimé la dernière action manuelle grâce à l'API du bastion.
  • Repris par l'entreprise : l'outil continue d'évoluer (démarrage automatique de la VM, stockage des identifiants dans un coffre-fort).
  • Customisations en production chez de nombreux clients, qui traitent des factures réelles chaque jour. Certains clients ont même rouvert un ticket simplement pour remercier du travail livré.

Réflexion & apprentissages

AutoInit est ce qui m'a fait choisir le DevOps. Ce que j'ai préféré cette année, l'automatisation, les pipelines, Docker et le travail au contact des plateformes de production, correspond exactement à ce champ, d'où ma poursuite en cycle ingénieur spécialité DevOps, toujours chez ITESOFT.

Les leçons que je garde :

  1. 01Après une opération asynchrone, vérifier l'état obtenu plutôt que la réponse de l'appel. La fusion d'une merge request par API est asynchrone : en enchaînant trop vite, le workflow construisait parfois le livrable du mauvais client.
  2. 02Préférer la fiabilité à la vitesse. Paralléliser aurait fait gagner dix minutes mais rendait les exécutions instables.
  3. 03Partir de ce qui marche quand rien n'est documenté. Analyser le pipeline de migration existant a corrigé plusieurs hypothèses fausses de mes premières versions.
  4. 04Identifier un irritant, proposer, construire proprement et faire adopter. C'est ce que l'équipe attend d'un ingénieur au-delà des tickets, et c'est la démarche que je veux continuer à développer.
Projet suivantTamaStat pour TamaBox