Ma façon de construire

Un plan, repris de projet en projet

Un seul document : dix décisions par ordre d'importance, une carte d'architecture, des invariants numérotés, et une liste de ce qui ne doit jamais arriver. Il est sorti d'une plateforme de production sous vraie charge. Chaque nouveau projet en part et consigne là où il a divergé.

Ce qui se reporte partout

Des frontières et des habitudes dont je sais qu'elles tiennent, donc je ne les redécide pas au début d'un nouveau projet.

Un seul endroit où chaque règle s'applique

Les préoccupations transversales passent par un seul wrapper de route ou une seule chaîne de guards. Un nouvel endpoint est protégé parce que le développeur n'a rien fait, pas parce qu'il s'en est souvenu.

Refus par défaut

Une route qui ne déclare aucune permission est fermée. Un pair non authentifié, dans le cas pair-à-pair, échoue au handshake cryptographique avant qu'un octet ne soit parsé comme une commande.

La logique de domaine vit hors du framework

Un paquet cœur appelable depuis une route, un job de fond, ou un script — testable sans démarrer l'application, sans socket, sans savoir qu'une interface existe.

Un outbox transactionnel, pas des effets de bord en ligne

L'événement « ça doit arriver » est écrit dans la même transaction que le changement d'état. Un dispatcher séparé le livre et réessaie. Rien n'est silencieusement perdu parce qu'une API tierce a eu cinq mauvaises secondes.

Des machines à états explicites

Les transitions légales sont des données, vérifiées par un seul validateur. Aucun changement de statut ne se fait par une mise à jour ad hoc éparpillée dans les handlers.

Un seul client typé est la seule porte de l'interface vers l'API

Aucun écran n'ouvre un socket, ne lit le store, ni ne fait une vérification de permission directement. Tout passe par un seul endroit, pour qu'une mauvaise base-URL casse toutes les apps de la même façon plutôt qu'une à la fois.

La direction des dépendances est à sens unique, imposée par le compilateur quand c'est possible

En Rust, une violation de découpage en couches est une erreur de build. En TypeScript, c'est un lint plus un diagramme vérifié contre les imports réels, parce qu'un diagramme que personne n'a vérifié ne fait que décrire une intention.

Rien n'est fait tant qu'on ne l'a pas vu fonctionner

Parcouru de bout en bout, en tant que rôle utilisateur réel, dans l'application en fonctionnement, avec la preuve écrite en regard d'une date. Compiler ne compte pas. Des tests qui passent ne comptent pas.

Là où les projets ont cassé le moule

Ce qui garde la réutilisation honnête : chaque projet consigne ce qu'il a gardé, changé, abandonné, et ajouté parce que le plan n'avait jamais rencontré ce problème.

OpenDerja_TN

La base n'est pas qu'un actif — c'est l'actif.

Le code peut être réécrit en un week-end. Des mois d'annotation communautaire, non. Chaque raccourci de schéma détruit de l'information de manière permanente, alors les décisions de schéma reçoivent le soin que le code reçoit d'habitude.

Ferry

Il n'y a pas de tiers de confiance, donc chaque règle est imposée par la machine qui s'en soucie.

L'outbox est passé d'un filet de sécurité à l'abstraction centrale, parce qu'un pair hors ligne est le cas normal ici. Le refus par défaut est descendu jusqu'au handshake Noise. « Rien ne supprime définitivement » a été délibérément inversé pour les secrets à brûler après lecture. Et « fait » est devenu plus strict : deux vraies machines sur un vrai réseau.

Ferry

Le contrôle CI de dérive de schéma et le rituel de sauvegarde de la base ont été abandonnés.

Ils protègent un actif que Ferry n'a pas. Ce soin a été redirigé vers le trousseau de clés de l'OS, qui contient la chose qui vraiment ne peut pas être perdue.

La seule ligne

Rien n'est fait tant qu'on ne l'a pas vu fonctionner.

Tout le reste — le registre de vérification, tester en tant que chaque rôle réel, lire le corps de la réponse et pas le code de statut — n'est que cette phrase, appliquée. Le dernier chapitre du récit parle d'où elle vient.