126 entrées
Le journal technique
Les bugs rencontrés et les patterns gardés, datés et cherchables, pris directement du carnet que je tiens en construisant.
Comment ça a cassé
12 / 126 entrées
Commencer ici
Ce qu'un client a manqué pendant son absence
Socket.io brut te dit qu'un client s'est reconnecté. Il ne te dit pas s'il est à jour — et pour un écran sans surveillance, un trou silencieux est tout le problème.
devopsCe qu'un test de charge te dit vraiment
Les erreurs de mesure qui invalident discrètement un résultat, et ce que « les chiffres ont empiré sous plus de charge » s'est révélé signifier.
backendL'outbox transactionnel
Le problème de la double écriture, et le pattern vers lequel je vais maintenant sur chaque projet pour qu'un effet de bord ne puisse pas disparaître silencieusement.
securityMulti-tenant au niveau ligne, et le seul bug qui compte
Un schéma, un tenant_id sur chaque table, isolation imposée entièrement dans la logique applicative. Simple à exploiter, et exactement aussi solide que la discipline de chaque requête.
devopsNeuf Dockerfiles, et le retour à deux
Aucune mauvaise décision isolée — juste une douzaine de décisions individuellement raisonnables qui se cumulent. Comment l'installation Docker a proliféré, et la règle que j'en ai tirée.
backendpgBouncer, et le bug search_path qui a corrompu des données
Le pooling de connexions devient nécessaire à l'échelle — et le transaction pooling a un bord tranchant qui écrivait silencieusement sur le mauvais schéma.
backendRéparer l'état bloqué à chaque démarrage
Un processus qui meurt en plein workflow laisse quelque chose à moitié fini, et rien ne le fait transitionner — parce que la chose qui l'aurait fait a juste cessé d'exister. Lance une passe de récupération à chaque démarrage.
securityRévoquer un jeton qui est sans état par conception
Les JWT ne peuvent pas être repris une fois émis. Voici le trou que ça a créé, et le correctif à une colonne que je construis maintenant dès le premier jour.
securityUne borne n'est pas un utilisateur
Authentifier du matériel physique — une borne, un comptoir, un écran mural — comme sa propre classe d'identité, parce que le modèle de menace pour du matériel sans surveillance est vraiment différent.
backendUne synchro hors-ligne vraiment sûre à rejouer
Mettre les actions en file hors-ligne est la moitié facile. Les rejouer sans dupliquer le travail ni corrompre l'état est la moitié qui a besoin de deux couches d'idempotence.
Comment elles ont cassé
Classées par mode de défaillance plutôt que par la partie de la stack concernée, parce que c'est ça qui se reporte d'un projet à l'autre. 15 sur 73 tombent dans une seule catégorie : ça ne pouvait pas marcher.
Ça ne pouvait pas marcher
15Une course, un ordre, une colonne pour deux choses. La forme l'excluait avant même l'exécution.
Ça disait que ça marchait
13Vert, 200, enregistré, « déjà géré » — et faux. Aucune erreur sur laquelle s'appuyer.
Deux copies ont divergé
13Une idée tenue à la main à deux endroits — schéma et migration, dev et prod, app et app.
Le filet avait un trou
13Le test, le journal d'audit, le scanner, la CI — couvrant moins que je ne le supposais.
Visible seulement en s'en servant
11Invisible à la relecture du code. Trouvé en étant le vrai utilisateur, sur un vrai appareil, à une vraie largeur.
Construit, et rien ne s'en servait
8Livré, typé, injecté, inatteignable. Rien ne l'a jamais appelé.
Où vivent les bugs
Les deux tiers se trouvent hors de la logique applicative — dans l'infrastructure, l'intégrité des données, ou la couche d'authentification.
73 total
Notes par domaine
53 total
Quand ils ont été trouvés