これらの図のポイントは、リポジトリに新しく来た人がそれらを信頼できることです。存在しないサービスをでっち上げたりデータベースを見逃したりする図は、ないより悪いので、ここでのすべてはコードが実際に示しているものを描くことについてです。
1. 描画前の調査
リポジトリルートに対して scripts/survey.py(このスキル内のパスはスキルのフォルダからの相対パスです)を実行します:
python3 scripts/survey.py /path/to/repo > /tmp/mermaid-survey.txt
これにより、ファイル数を含むモジュール、マニフェスト、エントリポイント、宣言された依存関係にある外部サービス、データモデルソース、およびモジュール間のインポートグラフ(カウント付き)が一覧表示されます。各インポートエッジは実際のインポート文に基づいているため、これらのエッジをアーキテクチャ図のバックボーンとして使用します。1つのモジュールがコードの大部分を占めていて分割が必要な場合は、--depth 3 を付けて再実行します。
次に、スクリプトでは見えないものを読み取ります:
- READMEと既存のドキュメント:チームがすでに使用している名前を確認するため
- エントリポイント:独自のプロセスとして実行されるもの(サーバー、ワーカー、CLI、cronジョブ、Lambda)を確認するため
- デプロイ設定(Dockerfile、composeファイル、fly.toml、サーバーレス/CDK、Terraform):個別にデプロイされるものとそれが通信する相手を確認するため
- プロセス境界を越える呼び出し:HTTPクライアントとベースURL、キュー公開者と消費者、外部サービス用のSDKクライアント
各ボックスと矢印をどのファイルがサポートしているかの短いメモを残します。これは出力内の「Sources」リストになります。
ユーザーが1つの図だけを要求した場合(「データベースのER図」など)、その図だけを作成しますが、それでも最初に調査は行います。
2. アーキテクチャ概要
デプロイ可能なコンポーネントとその内部のモジュール、さらにそれらが使用するデータストアと外部サービスを含む flowchart を描画します。ノード数は6〜20を目指します。より大きなリポジトリの場合は、ボックスを増やすのではなく、デプロイ可能な単位ごとにサブグラフにグループ化します。
- ノードは開発者が名付けるようなものにします:「APIサーバー」、「webアプリ」、「firehoseコンシューマー」、「PostgreSQL」、「Stripe」。READMEまたはパッケージ名からチームの名前を使用します。
- 矢印は呼び出し元から呼び出し先へ向け、プロセスを越える場合はその方法を示します(「REST /api」、「SQL」、「S3 upload」)。プロセス内のインポートにはラベルを付けません。
- システムの説明に不要なものは削除します:誰もがインポートするユーティリティモジュール、型のみのパッケージ、テスト、ビルドスクリプト。それらが重要ならテキストで言及します。
- 指し示せないものは描画しません。 接続を推測してもそのコードが見つからない場合は、そのままにせずテキストでその旨を述べます。
図形とスタイルの規則は references/diagram-guide.md にあります。
3. データモデル
調査でデータモデルソースがリストされた場合にのみ erDiagram を描画します。リストにない場合は一文でその旨を述べてスキップします。APIの型や変数名からテーブルを推測しないでください。推測されたスキーマは本物とまったく同じように信頼できるように見えてしまうからです。
- マイグレーションが存在する場合、それらが真実です。 それらを順序通りに適用し、後続の
ALTER、DROP、およびリネームが優先されます。ORMモデルがマイグレーションと矛盾する場合は、マイグレーションに従い、不一致をメモします。 - 2セットのマイグレーション(例:古い
supabase/migrations/と現在のdrizzle/フォルダ)がある場合は、通常、一方が古くなっています。アプリのマイグレーションコマンドまたはORM設定が指している方(drizzle.config.*、prisma/schema.prisma、package.json内のmigrateスクリプト)に従い、古い方をテキストで指名します。 - キーと行を識別するカラムを表示します:主キー、外部キー、ユニークカラム、およびリーダーがエンティティを認識するために必要な数個のカラム。タイムスタンプやその他の簿記的なカラムは、重要でない限りスキップします。
- カーディナリティは制約から読み取ります。 NOT NULLの外部キーは親側で「1」、NULL許容の場合は「0または1」、ユニーク外部キーはリレーションシップを1対1にします。各リレーションシップには短い動詞句でラベルを付けます。
- エンティティが約15を超えたら、1つのテーブルの壁を描くのではなく、ドメインごとに図を分割します。
4. ファイルを書く
docs/architecture.md を作成するか、存在する場合は更新します。リポジトリがドキュメントを別の場所に保管している場合はそれに従い、ユーザーがパスを指定した場合はそのパスを使用します。各図について:
## アーキテクチャ
図が示す内容と、省略されている事項についての2、3文。
<!-- mermaid-gen:start architecture -->
```mermaid
flowchart LR
...
```
<!-- mermaid-gen:end architecture -->
**ソース:** `cmd/server/main.go`、`internal/handler/`、`fly.toml`
マーカーコメントにより、後続の実行で手動で編集された散文に触れることなく、図だけを置き換えることができます。既存のファイルを更新する場合は、マーカー間の内容と、そのすぐ周囲の説明およびソースのみを変更します。
5. レンダリングを確認する
ファイルに対して scripts/lint_mermaid.py を実行します:
python3 scripts/lint_mermaid.py /path/to/repo/docs/architecture.md
これにより、レンダリングを最も頻繁に壊す間違い(引用符で囲まれていないラベルの特殊文字、ノードIDとしての end などの予約語、閉じられていない subgraph、不正なERリレーションシップや属性)を検出します。終了する前にすべてのエラーを修正します。mmdc(mermaid-cli)がインストールされている場合は、それも使用してレンダリングします。
最後に、ファイルの場所、各図がカバーする内容、および省略した点や確認できなかった点をユーザーに伝えて終了します。