Étendre l'application

Ajouter un nouveau module CRUD, une permission, un paramètre, ou une tâche planifiée, en suivant les conventions propres de l'application.

Sur cette page

Étendre l'application

CBGenesis est un tremplin, pas un produit fini. Ce sont les mêmes étapes que suivent ses propres modules Users/Roles/Permissions/Settings - utilisez-les comme modèle pour tout ce que vous ajoutez.

Construire avec un agent IA

Si vous étendez cbGenesis avec un agent de codage IA (Claude Code, Copilot, Cursor, ou similaire), pointez-le vers .agents/skills-custom/ avant qu'il n'écrive la moindre ligne de code - ces skills encodent les étapes exactes ci-dessous sous forme d'instructions lisibles par une machine, avec de vrais extraits de code de cette base de code, afin que l'agent n'ait pas à les rétro-ingénierer en explorant chaque handler :

SkillCouvre
cbgenesis-crud-resourceLa tranche verticale complète ci-dessous - entité, service, handler, route, vue, composant - de bout en bout.
cbgenesis-rbac-permissionsLe modèle de permissions resource:action, @secured, et les protections contre les auto-actions.
cbgenesis-csrf-frontendLe patron obligatoire fetchWithCsrf() pour toute requête frontend mutative.
cbgenesis-alpine-componentsLa forme des composants Alpine.js, leur enregistrement, et la bibliothèque utils/ partagée.
cbgenesis-testing-conventionsBaseIntegrationSpec, le véritable mécanisme d'isolation par annulation de transaction, et les aides de fixtures.
cbgenesis-settings-configQuand utiliser une variable d'environnement plutôt que le registre de paramètres en base de données.

Une nouvelle convention qui mériterait qu'un agent (ou un humain) n'ait pas à la redécouvrir par essais et erreurs ? Ajoutez-la comme nouvelle skill ici plutôt que de la laisser comme savoir tribal dans une description de PR. Voir Conçu pour le développement assisté par IA pour comprendre pourquoi cela compte, avec une comparaison chiffrée avant/après.

Ajouter un nouveau module CRUD

1
Créer l'entité

Dans app/models/<domain>/, en étendant BaseEntity — voir Base de données & ORM.

2
Créer le service

En étendant BaseService, marqué singleton threadSafe — voir le patron de service.

3
Créer le handler

En étendant BaseSecureHandler, avec une annotation @secured — voir Handlers & Routage. Hériter de cette base signifie que chaque action POST/PUT/DELETE que vous ajoutez est vérifiée CSRF automatiquement ; il n'y a rien à activer, mais vos formulaires et composants Alpine doivent envoyer rc.csrf.

4
Ajouter des routes

Dans app/config/Router.bx, près du marqueur // @app_routes@.

5
Créer des vues

Dans app/views/<domain>/, en réutilisant les partials _components/ui/ existants.

6
Créer un composant Alpine

Dans resources/assets/js/components/<domain>/, puis l'enregistrer dans App.js — voir Frontend.

7
Ajouter du SCSS

Dans resources/assets/scss/views/, importé depuis app.scss.

8
Écrire des tests

Spécifications unitaires dans tests/specs/unit/<domain>/, plus une spécification d'intégration dans tests/specs/integration/ pour les routes ajoutées — voir Tests.

Ajouter une nouvelle permission

1
Semer le slug

Ajouter le slug resource:action à resources/database/seeds/AdminData.bx et l'assigner au(x) rôle(s) approprié(s).

2
Protéger le handler

@secured( "resource:action,resource:admin" ) — la virgule signifie OU. Voir Sécurité & Permissions.

3
Conditionner la vue
<bx:if prc.authUser.hasPermission( "resource:action,resource:admin" )>

afin que l'interface n'offre jamais quelque chose que le handler rejetterait.

4
Réensemencer

box migrate seed run sur une base de données existante - ou accorder la permission à un rôle directement depuis la page d'administration des Rôles.

Ajouter un paramètre

Ajoutez une nouvelle clé à la structure DEFAULTS dans SettingService.bx. preFlightCheck() l'insère automatiquement en base au prochain démarrage, et elle apparaît dans la page d'administration /settings sans câblage supplémentaire — voir Configuration.

Personnaliser les mises en page

Les mises en page vivent dans app/layouts/. La sélection se fait par handler, typiquement dans preHandler :

function preHandler( event, rc, prc ){
    event.setLayout( "Admin" );
}

Ajouter une tâche planifiée

Enregistrez les tâches dans app/config/Scheduler.bx, à côté des trois qui s'y exécutent déjà - voir Architecture pour ce qu'elles font :

task( "My Task" )
    .call( () => getInstance( "MyService" ).doWork() )
    .everyDayAt( "03:45" )
    .onOneServer()
    .withNoOverlaps();

onOneServer() et withNoOverlaps() comptent dès l'instant où vous déployez plus d'une instance : sans eux, chaque instance exécute la tâche selon son propre planning. Placez la logique réelle de purge/nettoyage sur le service (doWork() ci-dessus), pas en ligne dans la closure, afin qu'elle reste testable unitairement.

Surcharger la configuration des modules

Les configurations de module dans app/config/modules/ étendent les valeurs par défaut du module lui-même. Surchargez n'importe quelle clé là - les modifications prennent effet au prochain ?fwreinit.

Modifier cette page Télécharger le Markdown Dernière mise à jour Oct 1, 2026, 11:06:51 AM