アプリの拡張

アプリ自身の規約に従って、新しい CRUD モジュール、権限、設定、またはスケジュールタスクを追加します。

このページ内

アプリの拡張

CBGenesis は完成品ではなく、出発点です。以下は、アプリ自身の Users/Roles/Permissions/Settings モジュールが従っているのと同じ手順です - 何か新しいものを作るときのテンプレートとして使ってください。

AI エージェントで構築する

AI コーディングエージェント(Claude Code、Copilot、Cursor など)で cbGenesis を拡張する場合は、コードを書かせる前に .agents/skills-custom/ を参照させてください - これらのスキルは、以下の手順を、このコードベースからの実際のコード抜粋付きの機械可読な指示としてエンコードしているため、エージェントがすべてのハンドラーを調べてそれらをリバースエンジニアリングする必要がなくなります。

スキルカバーする内容
cbgenesis-crud-resource以下の完全な縦割りスライス - エンティティ、サービス、ハンドラー、ルート、ビュー、コンポーネント - をエンドツーエンドで。
cbgenesis-rbac-permissionsresource:action 権限モデル、@secured、そして自己操作ガード。
cbgenesis-csrf-frontendミューテーションを行うすべてのフロントエンドリクエストに必須の fetchWithCsrf() パターン。
cbgenesis-alpine-componentsAlpine.js コンポーネントの形、登録方法、そして共有 utils/ ライブラリ。
cbgenesis-testing-conventionsBaseIntegrationSpec、実際のトランザクションロールバック分離メカニズム、そしてフィクスチャヘルパー。
cbgenesis-settings-config環境変数を使うべきか、DB に保存された設定レジストリを使うべきかの判断基準。

エージェント(または人間)が試行錯誤で再発見しなくて済むような新しい規約を見つけましたか? PR の説明に暗黙知として残すのではなく、ここに新しいスキルとして追加してください。これが重要な理由と、実測による前後比較については、AI 支援開発のために構築 を参照してください。

新しい CRUD モジュールの追加

1
エンティティを作成する

app/models/<domain>/ に、BaseEntity を継承して作成します — データベースと ORM を参照してください。

2
サービスを作成する

BaseService を継承し、singleton threadSafe を指定します — サービスパターン を参照してください。

3
ハンドラーを作成する

BaseSecureHandler を継承し、@secured アノテーションを付けます — ハンドラーとルーティング を参照してください。このベースを継承するということは、追加する POST/PUT/DELETE アクションはすべて 自動的に CSRF 検証される ことを意味します。オプトインするものは何もありませんが、フォームと Alpine コンポーネントは rc.csrf を送信しなければなりません。

4
ルートを追加する

app/config/Router.bx の // @app_routes@ マーカー付近に追加します。

5
ビューを作成する

app/views/<domain>/ に、既存の _components/ui/ パーシャルを再利用して作成します。

6
Alpine コンポーネントを作成する

resources/assets/js/components/<domain>/ に作成し、App.js に登録します — フロントエンド を参照してください。

7
SCSS を追加する

resources/assets/scss/views/ に追加し、app.scss からインポートします。

8
テストを書く

tests/specs/unit/<domain>/ にユニットスペックを、追加したルート向けの統合スペックを tests/specs/integration/ に書きます — テスト を参照してください。

新しい権限の追加

1
スラッグをシードする

resources/database/seeds/AdminData.bx に resource:action スラッグを追加し、適切なロールに割り当てます。

2
ハンドラーを保護する

@secured( "resource:action,resource:admin" ) — カンマは OR を意味します。セキュリティと権限 を参照してください。

3
ビューをゲートする
<bx:if prc.authUser.hasPermission( "resource:action,resource:admin" )>

これにより、UI がハンドラーが拒否するようなものを決して提供しないようになります。

4
再シードする

既存のデータベースに対して box migrate seed run を実行するか、Roles 管理ページから直接ロールに権限を付与します。

設定の追加

SettingService.bx の DEFAULTS 構造体に新しいキーを追加します。preFlightCheck() が次回起動時に自動的にシードし、追加の配線なしで /settings 管理ページに表示されます — 設定 を参照してください。

レイアウトのカスタマイズ

レイアウトは app/layouts/ にあります。選択はハンドラーごとに、通常は preHandler で行われます。

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

スケジュールタスクの追加

app/config/Scheduler.bx にタスクを登録します。すでに実行されている 3 つのタスクの隣に追加してください - それらが何をするかについては アーキテクチャ を参照してください。

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

onOneServer() と withNoOverlaps() は、複数インスタンスをデプロイした瞬間に重要になります。これらがないと、すべてのインスタンスが独自のスケジュールでタスクを実行してしまいます。実際のパージ/クリーンアップロジックは、クロージャの中に直接書くのではなく、サービス側(上記の doWork())に置いてください。そうすればユニットテストが可能になります。

モジュール設定の上書き

app/config/modules/ 内のモジュール設定は、モジュール自身のデフォルトを継承しています。そこにある任意のキーを上書きしてください — 変更は次の ?fwreinit で反映されます。

このページを編集 Markdown をダウンロード 最終更新日 Oct 1, 2026, 2:02:30 PM