Edouard LAINE
Expert en ingénierie du logiciel - Développeur Full Stack
Logo The Object

The Object

Un framework orienté "objet"

Présentation

"The Object" est un framework initié en 2022 avec un objectif principalement pédagogique et orienté prototypage, plutôt que la réponse à un besoin métier précis. Le projet repose sur MySQL, TypeORM et Node.js pour modéliser les données et générer automatiquement des entités ainsi que des endpoints d’API CRUD à partir d’un schéma unique. À terme, il vise aussi la génération de composants React liés automatiquement à l’API, une intégration dans Next.js pour proposer une base applicative cohérente et prête à l’emploi, et la génération de tests afin de renforcer la qualité et l’industrialisation du développement.

Contexte / Objectifs / Risques

"The Object" est un projet que j’ai entrepris en 2022 sans chercher à répondre à un besoin métier particulier, puisque l’intention initiale était avant tout pédagogique et orientée vers l’expérimentation. Je l’ai conçu comme un framework destiné principalement à des usages de prototypage, afin d’explorer de manière concrète la conception, le développement et l’industrialisation d’une application, tout en me donnant un cadre de travail structuré pour analyser les décisions techniques, leurs conséquences, et les compromis qu’elles impliquent.

Pour poser une base solide et cohérente, j’ai fait le choix d’une pile technique centrée sur TypeScript et l’écosystème JavaScript, avec MySQL pour la gestion des bases de données, TypeORM comme couche de mapping et d’accès aux données côté Node.js, et React pour la conception des composants d’interface et d’expérience utilisateur. Ce choix vise à conserver une continuité de langage et de paradigmes entre les différentes couches, tout en s’appuyant sur des outils largement utilisés qui facilitent la mise en œuvre d’une architecture CRUD classique, la manipulation d’entités persistées, et la construction d’interfaces modulaires.

À ce stade, le cœur du travail a surtout porté sur la définition d’une structure de données représentant un “objet” au sens de source de vérité, ainsi que sur la mise en place d’un algorithme capable d’analyser cette structure pour produire automatiquement des éléments techniques exploitables. Cet algorithme a pour objectif de générer les entités de type ORM afin de permettre l’interaction avec la base de données, de participer à la génération ou à l’initialisation du schéma, et de fournir les fondations nécessaires à l’exposition d’une API CRUD au travers d’endpoints capables de manipuler les ressources décrites par le schéma. Même si le niveau d’avancement est déjà significatif, le projet reste en évolution et des erreurs surviennent encore, ce qui implique une phase de stabilisation continue, autant sur la génération de code que sur la fiabilité des artefacts produits et leur compatibilité avec les contraintes réelles de la base de données et des flux API. Dans une logique d’amélioration et de sécurisation, l’un des chantiers identifiés comme prioritaire concerne la mise en place d’un chiffrement de bout en bout pour protéger les données. L’objectif est d’éviter que la sécurisation repose uniquement sur la couche transport ou sur des contrôles applicatifs classiques, et de renforcer la confidentialité des données sensibles en prévoyant une stratégie de chiffrement qui soit compatible avec l’architecture générée, avec les accès CRUD, et avec les contraintes d’exploitation. Cette évolution nécessite de définir précisément ce qui doit être chiffré, où le chiffrement et le déchiffrement doivent avoir lieu, comment les clés sont générées, stockées, renouvelées et protégées, et comment les opérations de recherche, d’indexation ou de filtrage sont gérées lorsque certaines données ne sont plus lisibles en clair dans la base.

Une fois ces améliorations apportées, l’étape suivante consiste à faire évoluer l’algorithme de génération pour qu’il ne se limite plus à la couche données et à l’API, mais qu’il produise également des composants React d’interface et d’expérience utilisateur à partir du schéma de l’objet. L’idée est que la description de l’objet devienne une source de vérité transversale capable de dicter non seulement la structure des entités et des endpoints, mais aussi la structure des formulaires, des vues, des composants de consultation et d’édition, ainsi que les comportements attendus en front-end. Dans cette perspective, la génération ne se limite pas à produire de l’UI statique, puisqu’elle vise aussi à relier automatiquement les composants aux endpoints pertinents lorsque la nécessité existe, afin de réduire les tâches répétitives, de limiter les incohérences entre front-end et back-end, et de conserver une logique d’ensemble unifiée.

Dans la continuité de cette démarche, je vise ensuite une intégration de The Object au sein de Next.js afin de faciliter le développement d’applications complètes à partir d’un socle de composants déjà définis et prêts à l’emploi. Cette intégration a pour ambition d’apporter une expérience de développement plus fluide, avec une cohérence UX et UI maintenue d’un composant à l’autre, une structuration homogène du projet, et une capacité à tirer parti des atouts de Next.js selon les besoins, notamment en matière de routage, de rendu, et d’organisation applicative. L’objectif général est de disposer d’un ensemble unifié où la génération, l’assemblage et l’utilisation des composants s’inscrivent dans une convention claire, afin que l’application résultante reste lisible, maintenable et cohérente, même lorsque le périmètre fonctionnel s’étend.

Parallèlement à la génération des couches techniques, je souhaite intégrer une dimension de qualité et d’industrialisation en automatisant la génération de différents types de tests, comme des tests unitaires, des tests d’intégrité et des tests d’intégration, afin d’assurer un bon fonctionnement de l’application et de sécuriser les évolutions. Cette approche a aussi une finalité pédagogique, car elle permet d’expliciter le rôle de chaque niveau de test, de mettre en évidence les points de fragilité d’une architecture générée, et d’introduire des garde-fous pour prévenir les régressions. L’automatisation des tests s’inscrit ainsi dans une logique plus large où la production du code ne constitue pas une fin en soi, mais où la fiabilité, la traçabilité des changements, et la validation du comportement deviennent des éléments aussi structurants que la génération des entités et des endpoints.

L’intérêt du projet réside aussi dans sa capacité à m’aider à m’organiser, puisque le fait de partir d’un objet de référence et de chercher à automatiser un processus complet me pousse à identifier les besoins, à les formuler clairement, à prioriser les chantiers, et à établir une roadmap fondée sur des dépendances réelles. Le projet sert ainsi de support de gestion de projet, car il oblige à clarifier ce qui doit être standardisé, ce qui doit rester extensible, ce qui relève d’une convention, et ce qui doit être configurable, tout en donnant une visibilité précise sur l’avancement et sur les prochaines étapes nécessaires pour atteindre un niveau d’industrialisation satisfaisant.

Cette ambition implique toutefois des risques qu’il est important d’anticiper dès maintenant, car ils peuvent impacter la sécurité, la maintenabilité et la stabilité du framework. Il existe un risque de sécurité si le chiffrement de bout en bout est mal conçu, notamment en cas de mauvaise gestion des clés, de stockage ou de manipulation insuffisamment protégée, ou de choix cryptographiques inadaptés, ce qui pourrait créer une illusion de protection tout en laissant des failles exploitables. Il existe également un risque de perte de données ou de corruption de schéma lorsque la génération et les migrations ne sont pas strictement maîtrisées, puisque des modifications automatiques non réversibles, des contraintes mal définies ou des changements de types peuvent provoquer des incohérences difficiles à rattraper, surtout lorsque le projet sort du cadre du prototype. Un autre risque important concerne la dette technique, car un code généré qui n’est pas suffisamment idiomatique, configurable ou lisible peut devenir plus difficile à maintenir que du code écrit manuellement, ce qui impose d’intégrer des conventions strictes, des validations, et une stratégie de versionnement des artefacts générés. Il existe aussi un risque d’incohérence entre le front-end et le back-end si la source de vérité n’est pas rigoureusement unique et si des divergences apparaissent entre le schéma, l’API et les composants, ce qui peut conduire à des comportements inattendus et à une complexité accrue lors du débogage. Enfin, il faut considérer des risques de performance et de scalabilité, car des requêtes générées de manière naïve, des relations mal optimisées, ou des patterns de chargement non maîtrisés peuvent créer des problèmes de latence ou de consommation de ressources, et ces problèmes deviennent généralement visibles précisément au moment où l’on cherche à industrialiser. Dans ce contexte, l’objectif de The Object peut se résumer comme une démarche globale qui vise à comprendre et à automatiser, autant que possible, le cycle de vie complet d’une application, depuis la conception et la modélisation, jusqu’à la génération du code, la structuration de l’interface, l’intégration dans un framework moderne, et la mise en place de garanties de qualité par le test. En partant d’un objet unique, je cherche à créer un processus automatisé et cohérent qui permette à la fois de produire rapidement des prototypes, d’apprendre de manière structurée, et de construire progressivement une base suffisamment robuste pour évoluer vers des usages plus exigeants, à condition de traiter méthodiquement la stabilisation, la sécurité, et la qualité du code généré.

Résultats

Travailler sur "The Object" me permet d’obtenir des résultats qui vont au-delà du framework lui-même, parce que ce projet est à la fois un outil concret, un "laboratoire" d’architecture et un support structurant pour ma progression. Le premier résultat tangible, c’est que je construis un socle capable de transformer une description unique d’un modèle en éléments techniques exploitables, puisque mon schéma devient une source de vérité à partir de laquelle je peux générer des entités ORM, créer ou faire évoluer un schéma de base de données, et exposer des endpoints CRUD cohérents. Concrètement, cela me fait gagner du temps sur toute la partie répétitive, cela limite les incohérences entre la couche données et la couche API, et cela me permet de me concentrer davantage sur la conception et la validation des choix plutôt que sur l’écriture de “plomberie”.

Un autre résultat important, c’est que ce projet améliore directement ma compréhension des compromis d’architecture, parce que la génération me force à formaliser des décisions que l’on laisse souvent implicites dans un projet classique. Quand je choisis comment représenter une relation, comment exprimer une contrainte, comment structurer une entité ou comment définir un endpoint, je suis obligé de trancher entre simplicité, flexibilité, performance, lisibilité et évolutivité. En pratique, j’apprends à mesurer l’impact réel de mes choix, parce que je vois immédiatement comment une décision prise au niveau du schéma se répercute sur l’ORM, sur la base, sur la manière d’écrire les requêtes, sur les réponses API et, plus tard, sur l’interface.

Le fait de viser un générateur ne me pousse pas seulement à produire du code, il me pousse aussi à produire de la robustesse, parce que je dois mettre en place des validations, des garde-fous et des messages d’erreur utiles pour éviter de générer quelque chose d’incohérent. Je suis donc amené à anticiper les cas limites, à détecter les configurations invalides tôt, et à rendre mon système plus fiable. Cela m’apporte une discipline d’ingénierie plus systématique, parce que je ne peux pas me contenter de faire “marcher un exemple”, je dois construire quelque chose qui tient dans la durée et qui supporte la variété des cas d’usage, même si le projet est aujourd’hui orienté prototypage.

Ce projet m’apporte également un vrai bénéfice en organisation et en gestion de projet, parce que l’objectif d’automatiser un cycle complet m’oblige à découper le travail en étapes logiques et dépendantes. Je dois prioriser, stabiliser d’abord la génération des entités et des endpoints, sécuriser ensuite les données, puis étendre la génération vers l’UI et les tests. Cette approche rend mon avancement mesurable, parce que je peux identifier clairement ce qui est prêt, ce qui est fragile, ce qui manque et ce qui bloque. En conséquence, je peux construire une roadmap plus réaliste, mieux formuler mes besoins, et décider plus lucidement des chantiers à mener en premier.

Sur le plan “produit”, je construis progressivement un accélérateur de création d’applications, parce que l’idée de partir d’un objet unique et de générer les couches techniques vise directement à réduire le coût d’amorçage d’un projet. À terme, si j’ajoute la génération de composants React puis l’intégration dans Next.js, j’obtiendrais une base applicative plus unifiée, avec des composants prêts à l’emploi, cohérents entre eux, et alignés avec les endpoints générés. Cela m’intéresse particulièrement parce que je veux pouvoir produire une UX et une UI homogènes sans devoir recoder les mêmes écrans et les mêmes conventions à chaque fois, tout en gardant une structure standardisée qui facilite la maintenance et l’évolution.

L’un des apports majeurs pour moi, c’est aussi la montée en compétence sur l’automatisation et l’outillage, parce qu’un projet de génération me met face à des problématiques qu’on rencontre dans des frameworks ou des plateformes internes. Je travaille sur l’analyse de schémas, sur la génération de code, sur la gestion de templates, sur l’assemblage de modules, sur la compatibilité des versions, et sur la reproductibilité des builds. En faisant cela, je ne développe pas uniquement une application, je développe une manière de produire des applications, et cela renforce ma capacité à concevoir des systèmes cohérents plutôt que des solutions ponctuelles.

La dimension sécurité est également un résultat structurant dans mon parcours, parce que le fait de vouloir mettre en place un chiffrement de bout en bout m’oblige à aborder des sujets avancés de façon concrète. Je dois réfléchir à la classification des données, à la gestion des secrets et des clés, aux contraintes de lecture et d’écriture, et aux impacts sur les fonctionnalités classiques comme la recherche ou le tri. Même avant d’avoir un résultat final parfait, le fait d’intégrer ce sujet dans le cœur du projet change ma manière de concevoir une architecture, parce que je pense la protection des données comme une contrainte de départ et non comme un ajout tardif.

Enfin, la génération de tests représente pour moi un résultat clé en matière de qualité et d’industrialisation, parce que produire des tests unitaires, d’intégration ou d’intégrité, même partiellement, m’oblige à définir clairement ce qui est “correct” et à rendre cette définition vérifiable automatiquement. Cela me donnera des garanties de non-régression, plus de confiance dans les évolutions, et un cadre clair pour stabiliser le framework. Sur le plan méthodologique, cela renforce aussi ma façon de travailler, parce que j’associe progressivement chaque fonctionnalité à des critères de validation, ce qui rend le projet plus solide et plus durable. Au final, "The Object" me sert à la fois d’outil et de démarche, parce que je construis un framework qui accélère le prototypage, mais je construis surtout une compréhension complète du cycle de vie d’une application, depuis la conception et la modélisation jusqu’à la génération, l’intégration, la sécurisation et l’industrialisation. Le résultat n’est pas uniquement le code que je produis, c’est aussi la méthode que je développe en le construisant, car j’apprends à rendre le développement plus reproductible, plus cohérent, et progressivement automatisable de bout en bout à partir d’un objet unique.

Lendemain

Pour la suite, je veux faire évoluer "The Object" vers un framework plus stable, plus sécurisé et plus complet, en transformant progressivement ce qui est aujourd’hui un socle de génération orienté données et API en une chaîne de production applicative réellement end-to-end. À court terme, ma priorité est de fiabiliser l’existant en réduisant les erreurs de génération, en renforçant la validation du schéma source et en améliorant la qualité des artefacts produits, afin que la génération d’entités TypeORM, la création ou l’évolution du schéma MySQL, et la production des endpoints CRUD deviennent plus prévisibles et plus robustes. Dans le même temps, je prévois d’intégrer une stratégie de chiffrement de bout en bout, avec une gestion des clés structurée et des règles claires sur les champs sensibles, afin d’augmenter significativement la sécurité des données et de préparer le framework à des usages plus exigeants que le simple prototypage. Ensuite, l’évolution majeure consistera à étendre l’algorithme de génération à la couche front-end, afin de produire automatiquement des composants React à partir du schéma de l’objet, avec des formulaires, des vues de consultation et d’édition, et des comportements standardisés, tout en assurant le lien automatique entre ces composants et les endpoints API concernés. Une fois cette brique en place, je veux intégrer The Object dans Next.js pour proposer une base applicative plus unifiée, avec des conventions d’organisation, une UI/UX cohérente et un ensemble de composants prêts à l’emploi, afin d’accélérer la création d’applications tout en conservant une architecture claire. Enfin, je souhaite industrialiser davantage l’ensemble en ajoutant la génération de tests à plusieurs niveaux, comme des tests unitaires, des tests d’intégration et des tests d’intégrité, ainsi que des contrôles de conformité et de non-régression, afin de sécuriser les évolutions, d’améliorer la maintenabilité et de rendre la solution plus fiable à mesure qu’elle gagne en complexité.

Analyse critique

"The Object" est un projet ambitieux et formateur, mais il présente aussi des limites et des points de vigilance qui peuvent rapidement devenir structurants, surtout si l’objectif évolue du prototypage vers un usage plus généralisé. Le premier élément critique concerne le périmètre, parce que viser simultanément la génération du modèle de données, de l’API, de l’UI, de l’intégration Next.js et des tests revient à construire une chaîne complète comparable à une plateforme, ce qui augmente fortement la complexité et le risque de dispersion. Si la roadmap n’est pas strictement priorisée, je peux me retrouver à multiplier les chantiers sans stabiliser suffisamment chaque brique, et je risque d’obtenir un système large mais fragile, dans lequel une amélioration à un endroit introduit des régressions ailleurs.

Un point sensible est la maintenabilité du code généré, parce que la génération peut produire beaucoup de code “correct” mais difficile à lire, à déboguer et à modifier, surtout lorsque des cas spécifiques apparaissent. Si les conventions ne sont pas très strictes et si la personnalisation n’est pas bien cadrée, je peux créer un framework qui enferme l’utilisateur dans ses choix initiaux, où le moindre écart par rapport au “happy path” devient coûteux. Cela implique que je dois très tôt décider où se situe la frontière entre ce qui doit être généré systématiquement et ce qui doit rester extensible, ainsi que la manière de gérer des “overrides” propres à un projet sans casser la capacité de régénération.

Le projet dépend aussi fortement de la qualité de la “source de vérité”, parce qu’un schéma unique est puissant, mais seulement si son expressivité est suffisante pour capturer les besoins réels. Si mon schéma devient trop simple, je serai limité et je devrai ajouter des exceptions partout, et si mon schéma devient trop riche, je risque d’aboutir à une mini-langue complexe à maintenir, à documenter et à valider. Dans les deux cas, le risque est de déplacer la complexité plutôt que de la supprimer, car au lieu d’écrire du code applicatif, je vais écrire des règles, des métadonnées et des mécanismes d’interprétation qui peuvent devenir plus difficiles à maîtriser que le développement classique.

Sur le plan technique, MySQL + TypeORM + Node.js est un choix cohérent pour un socle CRUD, mais il peut révéler des limites lorsque les exigences augmentent, notamment sur la gestion fine des migrations, la performance des requêtes générées, la gestion des relations complexes, ou la concurrence et la scalabilité. Un générateur a tendance à produire des patterns standardisés qui ne sont pas toujours optimaux, et si je ne prévois pas une stratégie d’optimisation et de contrôle des requêtes, je peux générer des accès données qui fonctionnent mais deviennent coûteux dès que le volume ou la complexité augmente. Cela signifie que la notion de “prototype” doit rester explicite, sinon je risque d’utiliser une base conçue pour aller vite dans un contexte qui demande des garanties plus fortes.

La sécurité est probablement l’aspect le plus délicat, parce que l’idée de chiffrement de bout en bout est pertinente, mais elle est aussi facile à mal implémenter. Un chiffrement mal pensé peut nuire à l’utilisabilité (recherche, tri, filtrage), ajouter des contraintes lourdes (rotation des clés, perte de clés, gestion des secrets), et créer une fausse impression de protection si certains flux restent en clair ou si les clés sont exposées. Je dois donc être critique sur l’objectif exact du chiffrement, sur le périmètre des données concernées, et sur le fait que la sécurité globale d’un système ne dépend pas seulement du chiffrement des champs, mais aussi de l’authentification, de l’autorisation, de la journalisation, de la gestion des secrets et de la surface d’attaque exposée par l’API.

L’ambition de générer l’UI est aussi un point à analyser prudemment, parce que générer des formulaires et des écrans CRUD est réaliste, mais produire une UX réellement “bonne” et adaptée à des contextes variés est beaucoup plus difficile. Je peux générer des interfaces cohérentes et rapides à mettre en place, mais je risque aussi d’obtenir une UI générique qui ne répond pas aux besoins réels dès que le produit sort du CRUD standard. La critique ici n’est pas que la génération est inutile, mais que sa valeur maximale sera probablement dans une approche hybride, où je génère un socle cohérent et où je laisse des espaces clairement définis pour l’adaptation et le design spécifique.

La génération de tests est très pertinente, mais elle présente aussi un risque de “tests superficiels” si je me limite à vérifier que le code s’exécute sans réellement capturer le comportement attendu. Générer des tests utiles implique de définir des invariants, des scénarios, des données de test, et des contrats API, et cela peut être presque aussi complexe que l’application elle-même. Si je ne fais pas attention, je peux générer beaucoup de tests qui donnent un sentiment de couverture sans donner une vraie confiance, notamment si les tests valident des implémentations plutôt que des comportements. L’enjeu critique est donc de privilégier des tests de contrat, des invariants et des scénarios représentatifs, plutôt que du volume.

Enfin, il y a une critique plus globale liée à la valeur différenciante, parce que le monde des générateurs, des frameworks CRUD, des backoffices générés et des meta-frameworks est déjà riche. La valeur du projet ne sera pas seulement dans “générer du code”, mais dans la cohérence de bout en bout, la qualité des conventions, la capacité à rester simple, et la capacité à rendre l’expérience développeur réellement meilleure. Si je veux que The Object dépasse le cadre d’un projet pédagogique, je dois être exigeant sur la documentation, la simplicité d’adoption, la stabilité des versions, et la clarté des limites du framework, sinon il restera un outil personnel très utile mais difficilement transférable.

En résumé, je vois "The Object" comme un projet très fort pour apprendre et structurer une démarche d’ingénierie, mais je dois rester lucide sur les risques de sur-complexité, de dette technique, de sécurité mal cadrée, et d’UI générée trop générique. La réussite du projet dépendra de ma capacité à stabiliser chaque couche avant d’élargir le périmètre, à concevoir une architecture extensible sans multiplier les exceptions, et à définir clairement ce que le framework promet, ce qu’il automatise bien, et ce qu’il ne doit pas chercher à couvrir.