mcpField
F
forge-idiomatic-engineer

forge-idiomatic-engineer

github.com/isala404開発85927 回インストール9 週間前に更新
リポジトリ

forge-idiomatic-engineer について

Forge のフルスタック Rust フレームワークを扱うエンジニア向けのコーディングスキルです。プロジェクトの把握からハンドラー実装、検証、障害に備えた設計までを案内します。

主な機能

  1. 01Forge プロジェクトの把握と環境確認
  2. 02ハンドラーの種類と登録方法の案内
  3. 03forge コマンドによる生成と検証
  4. 04Rust、SQLx、マイグレーション、フロントエンドの参照情報
  5. 05レジリエンスと障害対応の原則

活用シーン

  1. 01既存の Forge プロジェクトで作業を始める
  2. 02バックエンドハンドラーを追加して検証する
  3. 03Forge のビルドやマイグレーションの問題を調べる

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/isala404/forge --skill forge-idiomatic-engineer

インストール後、Claude Code で/forge-idiomatic-engineerを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
api.md
frontend.md
patterns.md
pitfalls.md
recipes.md
resilience.md
testing.md
references/frontend/
dioxus.md
svelte.md
scripts/
orient.sh

詳細

Forge Idiomatic Engineer

フルスタックの Rust フレームワークです。単一バイナリで、PostgreSQL をバックエンドに使用します。Axum + Tokio + SQLx を採用しています。マクロがランタイムの配線とフロントエンドのバインディングを生成します。各ハンドラーは src/main.rs に登録する必要があります(マクロだけでは配線されません)。

コンパイルループの厳守事項

見落とすと、デバッグに何時間も無駄にすることになります。コードを書く前に、以下をしっかり把握してください。

  • 手動で cargo check / cargo build を実行する場合は、必ず SQLX_OFFLINE=true を設定してください。 CI ではグローバルに設定されています。設定しないと、sqlx はライブの DATABASE_URL に対してすべての sqlx::query!() を検証しようとします。編集できない公開済みの forge-runtime クレートのファイル内にあるクエリも対象となり、サードパーティーのコードについて「column does not exist」というエラーが大量に出ます。最も簡単な解決方法は、シェルの rc ファイルに eval "$(forge env)" を追加することです。それ以外の場合は、手動で export SQLX_OFFLINE=true を実行してください。
  • forge check はオフラインキャッシュを自動的に準備します。 src/ が .sqlx/ より新しいことを検出すると、パイプラインの残りの処理を実行する前に cargo sqlx prepare --workspace を実行するため、prepare の順序を気にする必要はありません。(通常の cargo check では、sqlx::query!() を編集した後も forge migrate prepare を実行する必要があります。)キャッシュがすでに正しいはずの CI では、--no-prepare を渡してください。
  • cargo-sqlx がない場合、forge migrate prepare は失敗します。 cargo install sqlx-cli --no-default-features --features postgres でインストールしてから、再実行してください。
  • すべての forge コマンドは、上の階層をたどって forge.toml を探します。 任意のサブディレクトリから実行でき、解決されたルートは起動時に表示されます。事前に cd する必要はありません。
  • コンパイルループに少しでも問題があると感じたら、まず forge doctor を実行してください。 rustc、cargo-sqlx、SQLX_OFFLINE、DATABASE_URL への接続、Docker、フロントエンドツール、forge.toml の構文、.sqlx/ の鮮度、最新のマイグレーションファイルが空でないことを、一度に確認します。
  • cargo sqlx prepare が成功すれば、コンパイルも成功しています。 prepare で確認できた内容を「念のため確認」するためだけに forge check を実行しないでください。prepare は内部で完全な cargo check を実行します。forge check は、前回の prepare 以降に新しい編集を行った場合、または検証スイートの残り(登録、スキーマ、clippy)を実行する場合にのみ使ってください。

セッション開始時:一度読んだら、記憶を信頼する

まず bash docs/skills/forge-idiomatic-engineer/scripts/orient.sh を実行してください。このスクリプトは上の階層をたどって forge.toml を探し、構造化された情報を出力します。内容は、プロジェクト名 + 認証モード + フロントエンド、環境の準備状況(SQLX_OFFLINE、DATABASE_URL、cargo-sqlx、Docker)、.sqlx/ キャッシュの鮮度、src/main.rs / src/functions/mod.rs / src/schema/mod.rs の内容、種類別にまとめた登録済みハンドラーの一覧、最新のマイグレーション、リアクティビティが有効なテーブル、具体的な NEXT アクションのヒントです。これを一度実行すれば、個別に5回読み込む必要はありません。

スクリプトでは表示されないため、各セッションで references/pitfalls.md と references/resilience.md を一度は必ず読んでください。

スクリプトを利用できない場合(古いチェックアウト、サンドボックス環境など)は、forge.toml、Cargo.toml、src/main.rs、src/functions/mod.rs、および migrations/ 内の最新ファイルを読んでください。

これらのファイルは編集しない限り変更されないため、セッションの途中で読み直しても、ほとんどの場合はコンテキストの無駄になります。

自動圧縮後は、要約に記載されたファイル一覧を信頼してください。 要約ですでに確認できている内容を確かめるためだけに main.rs / mod.rs を読み直さないでください。読み直すのは、それらを編集する必要があり、正確な現在の内容を確認するときだけです。圧縮時にファイルが <attachment> として添付されている場合は、すでにコンテキストに含まれているものとして扱い、新たに Read を実行しないでください。

ファイルを読む必要がある場合は、一度の呼び出しですべて読み込んでください。 重複する範囲(offset 200 の後に offset 1 など)を指定せず、offset 1 から十分な上限を指定して、一度に読み込んでください。Forge のハンドラーファイルは、600 行を超えることはほとんどありません。

ハンドラーの種類

概念マクロ構造体の接尾辞登録
読み取り専用クエリ#[forge::query]Query.register_query::<FnNameQuery>()
データ変更#[forge::mutation]Mutation.register_mutation::<FnNameMutation>()
バックグラウンドジョブ#[forge::job]Job.register_job::<FnNameJob>()
スケジュールタスク#[forge::cron]Cron.register_cron::<FnNameCron>()
永続ワークフロー#[forge::workflow]Workflow.register_workflow::<FnNameWorkflow>()
長時間実行プロセス#[forge::daemon]Daemon.register_daemon::<FnNameDaemon>()
外部 HTTP イベント#[forge::webhook]Webhook.register_webhook::<FnNameWebhook>()
AI エージェントツール#[forge::mcp_tool]McpTool.register_mcp_tool::<FnNameMcpTool>()

または、.auto_register() を使うと、inventory 経由ですべてのハンドラーを登録できます。

命名規則
  • ハンドラーにできるのは pub async fn のみです。非公開関数はコード生成に失敗します。
  • snake_case の関数名から、マクロが PascalCase と型の接尾辞を生成します。関数名に型を含めないでください(heartbeat とし、heartbeat_daemon にはしないでください。そうすると HeartbeatDaemonDaemon が生成されます)。
  • #[forge::model] は、構造体の最初の属性にする必要があります。
Context API の概要

実装中に forge-core のソースを確認せずに済むよう、覚えておきましょう。

  • ctx.db() → ForgeDb(sqlx::Executor)です。クエリマクロにそのまま渡します:sqlx::query_as!(...).fetch_one(ctx.db()).await?。
  • ctx.conn().await? → ForgeConn<'_>(トランザクション対応で、ミューテーションのみ)です。クエリマクロには &mut conn を渡します。
  • ctx.user_id() → QueryContext と MutationContext で Result<Uuid> を返します。プリンシパルがない場合は ForgeError::Unauthorized を返します。MutationContext に ctx.auth() メソッドはありません。
  • ctx.db_conn() → クエリとミューテーションの両方で使う共有ヘルパー向けの DbConn<'_> です。DbConn では呼び出し方が逆になっており、クエリを渡して DbConn に .fetch_* を呼び出します。references/patterns.md を参照してください。
  • バインディング名は型推論に任せます(let mut conn = ctx.conn().await?)。ヘルパーのシグネチャで必要な場合を除き、ForgeConn/ForgeDb/DbConn をインポートして明示的な型を書かないでください。

ワークフロー

  1. 状況を把握する — 上記のセッション開始時のファイル一覧に加え、references/pitfalls.md と references/resilience.md を読みます。frontend/package.json(Svelte)または frontend/Cargo.toml(Dioxus)でフロントエンドを判別します。
  2. 作業範囲を計画する — コードを書く前に、この PR に含めるハンドラー、マイグレーション、フロントエンドの変更を決めます。変更は的を絞り、垂直に一つの機能にまとめます。
  3. ハンドラーごとにチェックポイントを設けて進める:
    1. ファイルを手動で書くのではなく、forge new <kind> <name> を実行します。適切なマクロのデフォルトを含むスキャフォールドを生成し、src/functions/mod.rs に pub mod <name>; を追加し、必要な場合は src/main.rs に mod functions; を挿入します。種類:query、mutation、job、cron、workflow、daemon、webhook、mcp_tool、model、enum。
    2. スキャフォールドされたファイルを編集し、プレースホルダーの SQL/ビジネスロジックを実際の実装に置き換えます。
    3. forge check を実行します。ソースのほうが新しい場合は .sqlx/ キャッシュが自動で準備されるため、通常は別途 forge migrate prepare を実行する必要はありません。
    4. 失敗した場合は根本原因を修正し、失敗したステップだけを再実行します。エラーが残った状態で次のハンドラーを書かないでください。
    5. 次のハンドラーに進みます。
  4. バックエンドの変更が確定したら、forge generate を実行します。生成されたファイルは編集しないでください。
  5. フロントエンド — 生成されたバインディングを使って UI を接続します。Playwright の E2E テストには forge test を実行します。
  6. 最終確認 — forge check がクリーンに完了し、forge test がすべて成功していることを確認して、簡潔な変更概要を書きます。

問題の診断後にユーザーが「直して」/「直してもらえますか」と言った場合は、再確認を求めずに修正してください。確認のために作業を止めるのは、破壊的な操作(データ削除、スキーマ削除、強制プッシュ)の場合だけです。

アーキテクチャのデフォルト設定(事前に選択)
  • 認証:ソーシャル OAuth、パスワード+HS256、または RS256 のいずれかをコーディング前に選択してください(patterns.md を参照)。ソーシャルログインは user_identities テーブルを使って紐付ける必要があります。
  • 環境変数:ctx.env_require() / ctx.env_or() を使い、std::env::var() は使わないでください。
  • HTTP:RPC には ctx.http() を使い、bytes_stream() やカスタムのリダイレクトポリシーが必要な場合は ctx.raw_http() を使ってください。
  • SQL:sqlx::query!() / query_as!() のバンマクロのみを使ってください。スキーマまたはクエリを変更した後は forge migrate prepare を実行してください。詳細は「コンパイルループの厳格なルール」を参照してください。
  • ジョブ/ワークフロー:ディスパッチはミューテーション内でのみ行ってください(トランザクションはデフォルトで有効です)。ディスパッチを行うミューテーションで transactional = false を設定しないでください。
  • 共有ロジック:2 つのハンドラーで必要になった時点で、src/utils/ に切り出してください。

リファレンスの選択ガイド

タスクリファレンス
新しいハンドラー全般(必読)references/resilience.md
マクロ、コンテキスト、エラー、設定、CLIreferences/api.md
バックエンドのパターン:ジョブ、ワークフロー、認証、Webhook、コンパイルループreferences/patterns.md
コピー&ペースト可能なレシピ(ユーザー取得、プラン制御、メール、S3、決済、AI)references/recipes.md
フロントエンドの原則(リアクティビティ、サブスクリプション、エラー、アップロード)references/frontend.md
SvelteKit の詳細(runes、ストア、認証ヘルパー)references/frontend/svelte.md
Dioxus の詳細(フック、シグナル、認証キー設定)references/frontend/dioxus.md
テストの作成(バックエンドビルダー+Playwright シナリオ)references/testing.md
ビルドまたは実行時エラーのデバッグreferences/pitfalls.md

エンジニアリングの原則

  • 失敗を前提に設計する:認証が失効し、エンティティが消失し、ネットワークが障害を起こします。resilience.md を参照してください。
  • 不要なコードを残さない:未使用コードや置き換えられたパターンは完全に削除してください。ワークスペースの lint では dead_code、unwrap_used、panic、indexing_slicing、unsafe_code が deny に設定されています。
  • 差分は最小限にする:PR ごとに薄い垂直スライスにしてください。
  • 境界で検証する:ハンドラーの入口で検証し、ForgeError のバリアントを返してください(unwrap/expect/panic! は使わないでください)。
  • スコープを適用する(マクロによりコンパイル時に強制):プライベートクエリでは user_id / owner_id で絞り込む必要があります。プリンシパルには ctx.user_id() を使ってください。共有データ/管理者データに限り、#[query(unscoped)] で適用を除外できます。
  • トランザクション内でディスパッチする(コンパイル時に強制):dispatch_job と start_workflow にはトランザクション対応のミューテーションが必要です。トランザクションはデフォルトで有効なので、ディスパッチを行うミューテーションに transactional = false を設定しないでください。
  • システムテーブルへのアクセスは禁止(forge check により強制):forge_* テーブルに対して INSERT/UPDATE/DELETE を実行しないでください。dispatch_job、start_workflow、record_signal を使ってください。
  • マイグレーション:前方へのみ適用します。-- @down は使わないでください。任意の -- @up マーカーは取り除かれます。SELECT forge_enable_reactivity('table_name'); でリアクティビティを有効にしてください。IF NOT EXISTS は使わないでください。
  • 見つからない場合の処理:fetch_optional().await?.ok_or_else(|| ForgeError::NotFound(format!(...))) を使ってください。

出力の要件

完了時に、次の内容を報告してください。

  • 変更点:変更したファイル、対処した障害モード、追加したテスト(失敗パスを含む)。
  • 検証:実行したコマンド、阻害要因、最終的な forge check の結果。
  • レビュー:レジリエンス上の不足、前提条件。

すべてのハンドラーは、認証の失効、エンティティの削除、同時変更、ネットワーク切断に耐えられる必要があります。

コメント