mcpField
F
fitness-functions

fitness-functions

github.com/event-catalogテスト・品質149 回インストール2 日前に更新
リポジトリ

fitness-functions について

EventCatalog Fitness Functions は、EventCatalog のカタログに対するアーキテクチャルールを TypeScript のチェックとして定義するスキルです。違反を報告し、CLI の終了コードでプルリクエストを制御できます。対象はカタログに記録された情報で、稼働中のシステムではありません。

主な機能

  1. 01TypeScript によるアーキテクチャルール
  2. 02読み取り専用カタログ SDK のクエリ
  3. 03リソース参照付き違反レポート
  4. 04エラーと警告の重大度
  5. 05プルリクエスト制御用 CLI チェック

活用シーン

  1. 01ドメイン所有権の境界ルールの適用
  2. 02カタログリソース間の依存関係の確認
  3. 03所有者やメッセージチャネルの不足検出
  4. 04CI でのカタログ変更の制御

インストール

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

$npx skills add https://github.com/event-catalog/skills --skill fitness-functions

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

同梱ファイル

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

references/
api.md
ci.md
examples.md

詳細

EventCatalog フィットネス関数

フィットネス関数は、コードで記述されたアーキテクチャルールです。それぞれの関数は、読み取り専用 SDK を通じてカタログを読み取る TypeScript ファイルで、見つかった違反を返します。eventcatalog fitness check はすべての関数を実行し、結果を出力して JSON レポートを書き込み、ルールに違反がある場合はゼロ以外の終了コードを返すため、プルリクエストのチェックに使用できます。

健全なアーキテクチャの定義はチームが決め、EventCatalog はルールを実行して結果を報告します。

フィットネス関数がチェックするのは、カタログに記述されたアーキテクチャであり、実行中のシステムではありません。ルールの精度は、読み取るカタログデータの精度に左右されます。

要件(最初に確認してください)

  1. バージョン — @eventcatalog/core 5.4.0 以降(カタログの package.json を確認してください)。代わりに @eventcatalog/cli 1.4.0 以降を使えば、core なしで同じチェックを実行できます(npx @eventcatalog/cli fitness check)。Node.js 20 以降が必要です。
  2. エディターの型情報(任意) — フィットネス関数はほかに何もインストールせずに実行できますが、型情報と自動補完を利用するには、開発用依存関係として @eventcatalog/fitness をインストールしてください。create-eventcatalog で作成したカタログには、すでにこれが含まれており、fitness/ 内にスターター関数が 2 つ、npm run fitness スクリプトも用意されています。

フィットネス関数、リンター、それともガバナンス?

コードを書く前に、適切なツールを選んでください。

ルールの対象…使用するもの
単一ファイルの妥当性:frontmatter のフィールド、必須プロパティ、参照切れ、ファイルレイアウト@eventcatalog/linter
プルリクエストで変更された内容(新しいコンシューマー、スキーマの変更、非推奨化)と通知eventcatalog governance check(governance.yaml)
アーキテクチャの構造:所有権、命名、境界、依存関係、アクセス権限など、複数のリソースにまたがるものフィットネス関数(このスキル)

手順

ステップ 1:カタログと既存の内容を確認する

カタログ(eventcatalog.config.js があるフォルダー)を探し、以下を確認してください。

  • ルートに fitness/ フォルダーがあるか、またはリソースフォルダー内に fitness/ フォルダーがあるか。既存の関数を読み、ヘルパーを再利用してスタイルを合わせ、重複するルールを作成しないでください。
  • フィットネス関数の ID は、カタログ全体で一意でなければなりません。すでに使われている ID を一覧にしてください。
  • package.json に fitness スクリプトがあるか。@eventcatalog/fitness がインストールされているか。
  • .eventcatalog/fitness/ が .gitignore に含まれているか。このフォルダーにはチェック結果のレポートが書き込まれるため、コミットしないようにしてください。
ステップ 2:ルールを具体的なチェックにする

「サービスは自分のデータを所有するべき」といったルールは曖昧すぎて、コードにできません。明確でない場合はユーザーに確認し、以下を具体化してください。

  • 何が違反にあたりますか?(「サービスが、別のドメインに属するシステムのデータストアに書き込んでいる。」)
  • どのリソースに適用しますか? すべて、1 つのドメイン、1 つのシステム、または 1 つのサービスですか?
  • 最新バージョンのみですか、それともすべてのバージョンですか? ほとんどの場合、最新バージョンのみです({ latestOnly: true })。
  • 重要度 — error はチェックを失敗させます(CI も失敗します)。warning は報告されますが、チェックは失敗しません。違反が多数見つかりそうな既存のカタログに新しいルールを導入する場合は、まず warning に設定し、後から厳格化してください。
  • 各違反の対象を何にし、どのように修正すべきですか? 各違反では、関係するリソースを明示し、修正方法を提案してください。

カタログデータでルールをチェックできることを確認してください。ルールで writesTo、owners、sends.to が必要なのにカタログに記載されていない場合は、その旨を伝えてください。その場合、ルールは実質的に何もチェックせずに合格してしまいます。

ステップ 3:ファイルの配置場所を選ぶ

ファイルの配置場所によって、割り当てられる resource が決まります。参照できる内容が制限されるわけではありません。すべての関数がカタログ全体を照会できます。

ルールの適用対象配置先resource の値
カタログ全体fitness/<name>.fitness.ts(サブフォルダー可)undefined
1 つのドメインdomains/Orders/fitness/<name>.fitness.tsOrders ドメイン
1 つのシステム…/systems/checkout-system/fitness/<name>.fitness.tsそのシステム
1 つのサービス…/services/OrderService/fitness/<name>.fitness.tsそのサービス
1 つのイベント、コマンド、またはクエリ…/events/OrderCreated/fitness/<name>.fitness.tsそのメッセージ
1 つのデータストア…/containers/payment-database/fitness/<name>.fitness.tsそのデータストア(type: 'container')
1 つの特定のバージョン…/versioned/1.0.0/fitness/<name>.fitness.tsそのバージョン

チャネル、フロー、エンティティ、データプロダクト、ADR、図も同じように機能します。ルールは次のとおりです。

  • .fitness.ts で終わるファイルのみが実行されます。その他の .ts ファイル(共有ヘルパー)は実行されないため、フィットネス関数からインポートできます。
  • fitness/ フォルダーは、リソースのフォルダー内に直接配置する必要があります(index.mdx と同じ階層)。それ以外の場所にある .fitness.ts ファイルは実行されず、診断として報告されます。
  • フェデレーションカタログ(federated/…)内のフィットネス関数は実行されず、フェデレーションによって fitness/ フォルダーがコピーされることもありません。
ステップ 4:フィットネス関数を書く
// domains/Orders/fitness/no-shared-data-stores.fitness.ts
import { defineFitnessFunction } from '@eventcatalog/fitness';

export default defineFitnessFunction({
  id: 'orders-no-shared-data-stores', // unique across the catalog
  name: 'Orders services only use Orders data stores',
  description: 'Reaching into another domain’s database couples the domains together.',
  severity: 'error', // or 'warning'; defaults to 'error'

  async run({ resource, catalog }) {
    if (resource?.type !== 'domain') throw new Error('Expected to run beside a domain');

    // ...read what you need from `catalog`, decide what's wrong...

    return [
      {
        message: 'Order Service writes to payment-database, which is outside the Orders domain',
        resources: [
          { type: 'service', id: 'order-service', version: '1.0.0' },
          { type: 'container', id: 'payment-database' },
        ],
        details: 'Optional extra context',
        suggestion: 'Get payment data through the Payments API or its events.',
      },
    ]; // [] means the rule passed
  },
});

フィットネス関数を作成する際の規約:

  • export default defineFitnessFunction({ ... }) — 1 ファイルにつき関数は 1 つです。run は同期でも非同期でもかまいません。
  • 違反をスローせず、返します。 空の配列は合格を意味します。スローした場合、または { message, resources?, details?, suggestion? } の配列以外を返した場合、関数は error となり、チェックも失敗します。ただしこれは「アーキテクチャに問題がある」ではなく、「評価できなかった」ことを意味します。
  • type で resource を絞り込みます(resource?.type === 'domain' によって型付きの Domain が得られます)。ファイルの配置場所が間違っている場合は、明確なエラーをスローします。
  • catalog の読み取りメソッドを使用します — 名前と引数は @eventcatalog/sdk と同じです。例:getDomains、getServices、getEvents、getDataStores、getTeams、getGraph、getOwnersForResource、getSchemaForMessage、getResourcesByProperty、… コレクションを取得するメソッドは、該当するものがない場合 undefined を返すため、(await catalog.getEvents({ latestOnly: true })) ?? [] のように記述します。書き込みメソッドはありません。また、呼び出すたびにコピーが返されるため、結果を変更しても問題ありません。全一覧はreferences/api.mdを参照してください。
  • コレクションは一度だけ読み込み、ルックアップを作成します(マップまたはセットを使用)。ループ内でカタログを呼び出すのは避けてください。たとえば、メッセージごとに getProducersAndConsumersForMessage を呼び出すのではなく、すべてのサービスの sends を一度に収集します。
  • 各違反でリソースを参照します。{ type, id, version? } を指定してください。EventCatalog では違反からリソースへのリンクが設定されます。型:domain、system、service、agent、event、command、query、flow、channel、entity、container(dataStore も指定できます)、data-product、adr、diagram、team、user。
  • 読んだ人が行動に移せるメッセージを書きます:リソース名を含め(Order Service sends Order Amended without a channel)、修正方法は suggestion に記載します。
  • 共有ロジックはヘルパーファイルに記述します(例:fitness/helpers/catalog.ts)。相対パスでインポートしてください。型は import type { ReadOnlyCatalog } from '@eventcatalog/fitness' でインポートします。
  • 決定性を保ちます:ネットワーク呼び出し、ファイルへの書き込み、現在の日付への依存は禁止です。

一般的なルール(所有権、命名、プロデューサー、循環依存、ドメイン境界、ファンアウト、チャネル、スキーマ、データアクセス)の実例は、references/examples.mdを参照してください。

ステップ 5:実行して検証する
npx eventcatalog fitness check          # or: npm run fitness
npx eventcatalog fitness check --format json

出力には、すべての関数とその結果が一覧表示され、その下に違反とエラーが表示されます。

EventCatalog Fitness

✓ Every message has an owner                        Passed
✗ orders / Orders services only use Orders data…    1 violation
    • Order Service writes to payment-database, which is outside the Orders domain
      Resources: order-service (service), payment-database (container)
      Suggestion: Get payment data through the Payments API or its events.
! Every event has a producer                        3 warnings

3 fitness functions evaluated

引き渡す前に検証してください。決して失敗しないルールは、ルールがないよりも悪いものです。

  1. 新しい関数が実行されたことと、想定どおりのステータスであることを確認します。Error と表示された場合は修正してください(「トラブルシューティング」を参照)。
  2. 結果が正しいことを確認します。カタログファイルを手作業で確認し、違反と合格の両方をいくつか照合します。
  3. 失敗する可能性があることを確認します。現在のカタログで合格する場合は、実際の違反を検出できることを確認します。ユーザーと一緒に考えるか、カタログのスクラッチコピー内でリソースを壊し、そのコピーでチェックを実行してください。テストによる編集をユーザーのカタログに残さないでください。
  4. 参照が解決されることを確認します。(…, not found in the catalog) と表示される参照は、型または ID が誤っています。

終了コード:0 すべて合格、または警告のみ、1 関数が失敗したか評価できなかった、2 チェック自体を実行できなかった

ステップ 6:CI で実行する

依存関係をインストールした後、カタログの変更をチェックするパイプラインで npx eventcatalog fitness check を実行します。ルールが失敗すると 1 で終了し、ジョブが失敗します。GitHub Actions、GitLab、レポート公開の例については、references/ci.md を参照してください。

トラブルシューティング

症状原因/修正方法
関数がまったく一覧に表示されないファイル名が .fitness.ts で終わっていない、fitness/ フォルダー内にない、または federated/、node_modules、dist、ドットフォルダーの下にある
! <file>: Not run: fitness functions must be in a fitness/ folderファイルをルート、またはリソースのフォルダー直下にある fitness/ フォルダーへ移動します
No resource found for this fitness function: '<folder>' has no index.mdx or index.mdfitness/ フォルダーがリソースのフォルダー直下にありません
… is not in a resource folder (such as domains/ or services/)fitness/ を含むフォルダーが、認識されたリソースフォルダーではありません
The file has no default exportexport default defineFitnessFunction({ ... }) を追加します
Invalid fitness function: \id` must be a non-empty string, …`id/name/run がないか、severity が 'error' または 'warning' ではありません
Another fitness function already has the id '<id>'ID は一意である必要があります。最初のファイル(パス順)が実行され、それ以降のファイルはエラーになります
run() must return an array of violations … / Violation 0: …run が別の値を返したか、違反に message がない、または resources のエントリーに誤りがあります
Cannot find module './helpers/…'ヘルパーへの相対パスが誤っています。カタログルートまで何階層上がるか数えてください
リソースの後に (…, not found in the catalog) と表示される参照の type または id がリソースと一致しません。参照は保持されますが、リンクされません
エディター内だけで Cannot find module '@eventcatalog/fitness' と表示される@eventcatalog/fitness を開発用依存関係としてインストールします。チェック自体はインストールなしで動作します
fitness is not a command@eventcatalog/core が 5.4.0 より古い状態です。アップグレードするか、npx @eventcatalog/cli fitness check を使用してください

信頼性

Fitness 関数はカタログ内のコードであり、プロジェクト内の他のスクリプトと同じアクセス権で実行されます。ローカルでも CI でも、信頼できる Fitness 関数だけを実行してください。EventCatalog は、ブラウザー内、ページリクエスト時、またはフェデレーションされたカタログから関数を実行することはありません。

リファレンスファイル

  • references/api.md — defineFitnessFunction、コンテキスト、すべての catalog メソッド、違反、ステータス、JSON レポート、CLI オプション、検出ルール
  • references/examples.md — 共通ルールに対応する、共有ヘルパーを使ったグローバルおよびスコープ指定の Fitness 関数の完全な例
  • references/ci.md — GitHub Actions と GitLab でのチェック実行、レポート公開、JSON 出力の読み取り

コメント