Die App erweitern
Ein neues CRUD-Modul, eine Berechtigung, eine Einstellung oder eine geplante Aufgabe hinzufügen, gemäß den eigenen Konventionen der App.
Auf dieser Seite
Die App erweitern
CBGenesis ist eine Startrampe, kein fertiges Produkt. Dies sind dieselben Schritte, denen die eigenen Users/Roles/Permissions/Settings-Module folgen - verwende sie als Vorlage fĂĽr alles Neue.
Bauen mit einem KI-Agenten
Wenn du cbGenesis mit einem KI-Coding-Agenten (Claude Code, Copilot, Cursor oder ähnlich) erweiterst, richte ihn auf .agents/skills-custom/ aus, bevor er Code schreibt - diese Skills halten die untenstehenden Schritte als maschinenlesbare Anweisungen fest, mit echten Code-Ausschnitten aus dieser Codebasis, sodass der Agent sie nicht durch das Erkunden jedes Handlers reverse-engineeren muss:
| Skill | Deckt ab |
|---|---|
cbgenesis-crud-resource | Die vollständige vertikale Slice unten - Entität, Service, Handler, Route, View, Komponente - Ende zu Ende. |
cbgenesis-rbac-permissions | Das resource:action-Berechtigungsmodell, @secured und den Schutz vor Selbst-Aktionen. |
cbgenesis-csrf-frontend | Das verpflichtende fetchWithCsrf()-Muster fĂĽr jeden mutierenden Frontend-Request. |
cbgenesis-alpine-components | Alpine.js-Komponentenform, Registrierung und die gemeinsame utils/-Bibliothek. |
cbgenesis-testing-conventions | BaseIntegrationSpec, den echten Transaktions-Rollback-Isolationsmechanismus und Fixture-Helfer. |
cbgenesis-settings-config | Wann eine Umgebungsvariable statt der DB-gestĂĽtzten Einstellungsregistrierung zu verwenden ist. |
Eine neue Konvention, die es wert ist, dass ein Agent (oder ein Mensch) sie nicht durch Trial-and-Error neu entdecken muss? FĂĽge sie hier als neuen Skill hinzu, statt sie als stilles Wissen in einer PR-Beschreibung zurĂĽckzulassen. Siehe Gebaut fĂĽr KI-gestĂĽtzte Entwicklung dafĂĽr, warum das wichtig ist, mit einem gemessenen Vorher-Nachher-Vergleich.
Ein neues CRUD-Modul hinzufĂĽgen
In app/models/<domain>/, als Erweiterung von BaseEntity — siehe Datenbank & ORM.
Als Erweiterung von BaseService, markiert singleton threadSafe — siehe das Service-Muster.
Als Erweiterung von BaseSecureHandler, mit einer @secured-Annotation — siehe Handler & Routing. Von dieser Basis zu erben bedeutet, dass jede POST/PUT/DELETE-Aktion, die du hinzufügst, automatisch CSRF-verifiziert wird; es gibt nichts, dem man sich anschließen muss, aber deine Formulare und Alpine-Komponenten müssen rc.csrf senden.
In app/config/Router.bx, nahe der Markierung // @app_routes@.
In app/views/<domain>/, unter Wiederverwendung vorhandener _components/ui/-Partials.
In resources/assets/js/components/<domain>/, dann registrieren in App.js — siehe Frontend.
In resources/assets/scss/views/, importiert aus app.scss.
Unit-Specs in tests/specs/unit/<domain>/, plus eine Integrations-Spec in tests/specs/integration/ für die hinzugefügten Routen — siehe Testing.
Eine neue Berechtigung hinzufĂĽgen
FĂĽge den resource:action-Slug zu resources/database/seeds/AdminData.bx hinzu und weise ihn der/den passenden Rolle(n) zu.
@secured( "resource:action,resource:admin" ) — Komma bedeutet ODER. Siehe Sicherheit & Berechtigungen.
<bx:if prc.authUser.hasPermission( "resource:action,resource:admin" )>
damit die UI niemals etwas anbietet, das der Handler ablehnen wĂĽrde.
box migrate seed run gegen eine bestehende Datenbank - oder die Berechtigung direkt ĂĽber die Roles-Admin-Seite einer Rolle zuweisen.
Eine Einstellung hinzufĂĽgen
Füge einen neuen Schlüssel zum DEFAULTS-Struct in SettingService.bx hinzu. preFlightCheck() sät ihn beim nächsten Boot automatisch ein, und er erscheint ohne weitere Verdrahtung auf der /settings-Admin-Seite — siehe Konfiguration.
Layouts anpassen
Layouts liegen in app/layouts/. Die Auswahl erfolgt pro Handler, typischerweise in preHandler:
function preHandler( event, rc, prc ){
event.setLayout( "Admin" );
}
Eine geplante Aufgabe hinzufĂĽgen
Registriere Aufgaben in app/config/Scheduler.bx, neben den drei, die dort bereits laufen - siehe Architektur fĂĽr das, was sie tun:
task( "My Task" )
.call( () => getInstance( "MyService" ).doWork() )
.everyDayAt( "03:45" )
.onOneServer()
.withNoOverlaps();
onOneServer() und withNoOverlaps() werden wichtig, sobald du mehr als eine Instanz deployst: Ohne sie fĂĽhrt jede Instanz die Aufgabe nach ihrem eigenen Zeitplan aus. Platziere die eigentliche Bereinigungslogik am Service (doWork() oben), nicht inline im Closure, damit sie unit-testbar bleibt.
Modulkonfiguration ĂĽberschreiben
Modulkonfigurationen in app/config/modules/ erweitern die eigenen Standardwerte des Moduls. Überschreibe dort jeden Schlüssel — Änderungen wirken beim nächsten ?fwreinit.
Warum die individuellen Skills existieren, und ein gemessener Token-/Tool-Aufruf-Vergleich.
Die vollständigen Handler-/Routen-Konventionen, auf denen dieser Abschnitt aufbaut.
Entitäts- und Service-Muster im Detail.
Bring aus, was du gebaut hast.