セットアップ
前提条件: Python 3.11+、uv、Node.js 18+、pnpm。LLM_API_KEY はバックエンドをローカルで実行するか、コミット時に自動翻訳されたロケール出力をプレビューするためにのみ必要です。キーを持たないコントリビューターは、EN の変更をコミットできます。GitHub Actions ワークフローが PR マージ後に master で翻訳します。下記の i18n を参照してください。型安全性
mypy strict モードが強制されています。コードベース全体がゼロエラーで通過し、プリコミットフックは段階的な.py ファイルすべてに対して完全なインポートチェーン検査を実行して mypy を実行します。
ルール:
- すべてのパブリック関数に型ヒントが必須です。
# type: ignoreはimport-untyped(スタブのないサードパーティライブラリ)を除いて使用しないでください。- 前方参照には
from __future__ import annotationsを使用してください。 - 実際の型を修正してください — CI を通すためにエラーを抑制しないでください。
テスト
すべての新しいモジュールには、対応するテストファイルが必須です。すべての機能コミットにはテストを含める必要があります。| 規約 | パターン |
|---|---|
| ファイル | tests/test_{module}.py |
| クラス | Test{Feature} |
| メソッド | test_{behavior_under_test} |
- コミット前にすべての既存テストが成功している必要があります:
uv run pytest tests/ -x -q. - テストは外部サービスに依存してはいけません —
unittest.mock/AsyncMockを使用してデータベース、MCP サーバー、HTTP エンドポイント、および LLM 呼び出しをモックしてください。 - カバレッジ付きでテストを実行してください:
uv run pytest --cov=fim_one.
コードスタイル
- 非同期ファースト。 I/O バウンド操作には
async defを使用します。同期呼び出しはasyncio.to_thread()でラップして、イベントループをブロックしないようにします。 - Ruff によるリンティング。
uv run ruff check src/— 行の長さは 100 文字です。 - 最小限の
__init__.pyエクスポート。 パブリック API のみを再エクスポートし、内部シンボルはプライベートに保ちます。 - パッケージマネージャー。 Python には
uv、フロントエンドにはpnpmを使用します。pipやnpmは使用しないでください。
Git規約
アトミックコミット。 1つの論理的な変更ごとに1つのコミット。関連のない変更は一緒に開発されていても分割してください。 コミットメッセージ形式:type: description
| Type | 使用時期 |
|---|---|
feat | ユーザー向けの新機能 |
fix | バグ修正 |
refactor | 動作変更のないコード再構成 |
docs | ドキュメントのみ |
test | テストの追加または更新 |
chore | ビルド、CI、依存関係の更新 |
--no-verifyでフックをスキップしないでください。 pre-commitパイプラインは、エラーがリポジトリに到達する前に検出するために存在します。
Pre-commit hook pipeline
フックはすべてのコミットで自動的に実行されます。各ステップに関連するステージング済みファイルのみを処理します。Pythonファイルのみを変更した場合、i18nステップはスキップされます(その逆も同様)。| Order | Step | Trigger | What it does |
|---|---|---|---|
| 0 | Locale-edit guard | messages/{locale}/、docs/{locale}/、または README.{locale}.md の下にあるステージング済みファイル | コミットを中止します——オーバーライドはできません。代わりに scripts/translation-glossary.md を使用して翻訳を修正してください。 |
| 1 | OpenAPI spec regen | src/fim_one/web/**/*.py が変更された場合 | FastAPIルートから docs/openapi.json を再エクスポートします |
| 2 | i18n translation | messages/en/*.json、docs/*.mdx、または README.md が変更された場合(ローカル LLM_API_KEY が必要、ない場合はマージ後にCIが処理) | 新規/変更されたキーをすべてのターゲットロケールに翻訳します |
| 3 | mypy type checking | src/fim_one/**/*.py の任意のファイルが変更された場合 | ステージング済みファイルの完全なインポートチェーンでmypyを実行します |
| 4 | MDX validation | .mdx ファイルがステージングされた場合 | Mintlifyに到達する前にJSX/MDX構文を検証します |
i18n
FIM One は6つのロケール(EN、ZH、JA、KO、DE、FR)をサポートしています。翻訳は完全に自動化されています。 英語のソースファイルのみを編集してください:frontend/messages/en/{namespace}.json— UI文字列docs/*.mdx(ロケールサブディレクトリではなくルートレベル)— ドキュメントREADME.md— プロジェクトREADME
messages/zh/、docs/zh/、README.zh.mdなど)は自動生成され、プリコミットフックは手動編集されたファイルのコミットを無条件に拒否します。誤訳を修正するには、すべての翻訳ルールのシングルソースオブトゥルースであるscripts/translation-glossary.mdを編集してから、uv run scripts/translate.py --files <en-sources> --forceで影響を受けるファイルを再生成してください。すべての用語集の修正は5つのロケール全体に永続的に適用されます。
ロケールファイルを生成する2つの方法:
- ローカルプリコミットフック —
.envでLLM_API_KEYが設定されている場合に実行されます。翻訳はプッシュ前に行われるため、出力をプレビューできます。 - CIフォールバック — ローカルフックにキーがなくスキップされた場合、
.github/workflows/i18n-sync.ymlはマージ後にmasterで翻訳し、結果を自動コミットします。
messages/en/{ns}.jsonを作成してください。その他のロケールファイルは次のコミット時またはマージ後のCI上で生成されます。
完全な再翻訳を強制する: uv run scripts/translate.py --all(ローカルLLM_API_KEYが必要)。
データベースマイグレーション
開発環境ではSQLite、本番環境ではPostgreSQLを使用します。1つのAlembicマイグレーションファイルセットが両方で動作する必要があります。 主なルール:- 新しいORMモデルまたはカラムには必ずマイグレーションが必要です —
metadata.create_all()に依存しないでください。 - すべてのマイグレーションはべき等である必要があります —
fim_one.migrations.helpersのヘルパー(table_exists、table_has_column、index_exists)を使用してください。 - ブール値のデフォルト値:
server_default=sa.text("FALSE")/sa.text("TRUE")。"0"/"1"は使用しないでください — PostgreSQLはブール型カラムに対して整数リテラルを拒否します。 - SQLiteは
ALTER COLUMNができません — カラム制約の変更にはop.batch_alter_table()を使用してください。 - マイグレーションを作成した後、すぐに
uv run alembic upgrade headを実行して適用してください。