mcpField
F
frappe-impl-customapp

frappe-impl-customapp

github.com/impertio-studio開発198114 回インストール30 週間前に更新
リポジトリ

frappe-impl-customapp について

Frappe 開発者向けに、カスタムアプリの作成からテスト、配布までを案内する実装ガイドです。カスタムアプリが必要かを先に見極め、v14、v15、v16 の手順も扱います。

主な機能

  1. 01カスタムアプリの必要性を判断
  2. 02アプリ作成とモジュール設定
  3. 03フック、パッチ、Fixture の実装
  4. 04アプリの移行、テスト、配布
  5. 05v14〜v16 の違いを確認

活用シーン

  1. 01Frappe カスタムアプリの新規作成
  2. 02DocType 用モジュールとコントローラーの追加
  3. 03データ移行とアプリ設定の管理
  4. 04アプリのテストと別サイトへの導入

インストール

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

$npx skills add https://github.com/impertio-studio/frappe_claude_skill_package --skill frappe-impl-customapp

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

同梱ファイル

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

references/
anti-patterns.md
decision-tree.md
examples.md
workflows.md

詳細

Frappe カスタムアプリ - 実装

Frappe アプリをゼロから構築するワークフローです。正確な構文については、frappe-syntax-customapp を参照してください。

バージョン:v14/v15/v16 に対応


主な判断:カスタムアプリは必要ですか?

WHAT CHANGES DO YOU NEED?
|
+-- Add fields to existing DocType?
|   +-- NO APP NEEDED: Custom Field + Property Setter
|
+-- Simple automation/validation (<50 lines)?
|   +-- NO APP NEEDED: Server Script or Client Script
|
+-- Complex business logic, new DocTypes, or Python code?
|   +-- YES: Create custom app
|
+-- Integration with external system (needs imports)?
|   +-- YES: Custom app REQUIRED (Server Scripts block imports)
|
+-- Custom reports with complex queries?
|   +-- Script Report (no app) vs Query Report (app optional)

ルール:必ず最もシンプルな解決策から始めてください。Server Scripts と Custom Fields で、カスタムアプリがなくてもニーズの 70% を満たせます。


ステップ 1:アプリの構造を作成する

cd ~/frappe-bench
bench new-app my_app
# Prompts: Title, Description, Publisher, Email, License

必ず直ちに確認してください:

# my_app/my_app/__init__.py MUST have:
__version__ = "0.0.1"

ステップ 2:pyproject.toml を設定する(v15 以降)

[build-system]
requires = ["flit_core >=3.4,<4"]
build-backend = "flit_core.buildapi"

[project]
name = "my_app"
authors = [{ name = "Your Company", email = "[email protected]" }]
description = "Your app description"
requires-python = ">=3.10"
readme = "README.md"
dynamic = ["version"]
dependencies = [
    "requests>=2.28.0"   # Only PyPI packages here
]

[tool.bench.frappe-dependencies]
frappe = ">=15.0.0,<16.0.0"
# erpnext = ">=15.0.0,<16.0.0"  # Only if needed

ルール:[project].dependencies に frappe や erpnext を絶対に指定しないでください。これらは PyPI にありません。


ステップ 3:hooks.py を設定する

app_name = "my_app"
app_title = "My App"
app_publisher = "Your Company"
app_description = "Description"
app_email = "[email protected]"
app_license = "MIT"

required_apps = ["frappe"]  # Or ["frappe", "erpnext"]

fixtures = []  # Configured later

ルール:依存関係をすべて指定して、必ず required_apps を宣言してください。


ステップ 4:モジュールを定義する

# my_app/my_app/modules.txt
My App
アプリの規模モジュール戦略
1~5 個の DocTypeアプリ名を使った 1 つのモジュール
6~15 個の DocType機能領域ごとに 2~4 個のモジュール
15 個以上の DocTypeビジネスドメインごとのモジュール

ルール:各 DocType は必ず 1 つのモジュールにのみ属します。modules.txt のモジュール名はディレクトリに対応します:My Custom App --> my_custom_app/。

モジュールの追加
mkdir -p my_app/my_app/new_module/doctype
touch my_app/my_app/new_module/__init__.py
# Add "New Module" to modules.txt
bench --site mysite migrate

ステップ 5:インストールして DocType を作成する

# Install app on site
bench --site mysite install-app my_app

# Create DocType (via UI recommended, or CLI)
bench --site mysite new-doctype "My Document" --module "My App"

次のものが作成されます:

my_app/my_app/doctype/my_document/
+-- my_document.json    # DocType definition
+-- my_document.py      # Controller
+-- my_document.js      # Client script
+-- test_my_document.py # Tests

ステップ 6:フックを追加する

doc_events(v14/v15/v16)
doc_events = {
    "Sales Invoice": {
        "validate": "my_app.events.sales_invoice.validate",
        "on_submit": "my_app.events.sales_invoice.on_submit"
    }
}
extend_doctype_class(v16 のみ — 推奨)
extend_doctype_class = {
    "Sales Invoice": "my_app.overrides.sales_invoice.CustomSalesInvoice"
}

ルール:v16 でライフサイクルメソッドをオーバーライドする場合は、必ず super().method() を呼び出してください。

スケジューラーイベント
scheduler_events = {
    "daily": ["my_app.tasks.daily_cleanup"],
    "cron": {"0 9 * * 1-5": ["my_app.tasks.morning_report"]}
}

完全なパターンについては、frappe-impl-hooks と frappe-impl-scheduler を参照してください。


ステップ 7:パッチを追加する

パッチファイルを作成する
mkdir -p my_app/my_app/patches/v1_0
touch my_app/my_app/patches/__init__.py
touch my_app/my_app/patches/v1_0/__init__.py
# my_app/my_app/patches/v1_0/populate_defaults.py
import frappe

def execute():
    if not frappe.db.has_column("My DocType", "target_field"):
        return  # Skip if not applicable

    batch_size = 1000
    offset = 0
    while True:
        records = frappe.get_all("My DocType",
            limit_page_length=batch_size, limit_start=offset)
        if not records:
            break
        for r in records:
            frappe.db.set_value("My DocType", r.name,
                "target_field", "default", update_modified=False)
        frappe.db.commit()
        offset += batch_size
patches.txt に登録する
[pre_model_sync]
# Patches that run BEFORE schema changes (backup data from deleted fields)

[post_model_sync]
# Patches that run AFTER schema changes (populate new fields)
my_app.patches.v1_0.populate_defaults

ルール:

  • パッチが必要かどうかを必ず確認する(ガード節を使用)
  • 1000 件以上のレコードは必ずバッチ処理する
  • 各バッチの処理後に必ずコミットする
  • 本番環境で未テストのパッチを絶対に実行しない

ステップ 8:フィクスチャの管理

hooks.py で設定する
fixtures = [
    {"dt": "Custom Field", "filters": [["module", "=", "My App"]]},
    {"dt": "Property Setter", "filters": [["module", "=", "My App"]]},
    {"dt": "Role", "filters": [["name", "in", ["My App User", "My App Manager"]]]},
    {"dt": "Workflow", "filters": [["document_type", "=", "My DocType"]]},
    "My Category",  # All records of your own config DocType
]
エクスポートして確認する
bench --site mysite export-fixtures --app my_app
ls my_app/my_app/fixtures/
# custom_field.json, property_setter.json, etc.

ルール:

  • 必ず自分のアプリのカスタマイズにフィクスチャを絞り込む
  • トランザクションデータ(請求書、注文)を絶対に含めない
  • 共有 DocType(Custom Field、Workflow)は、フィルターなしで絶対にエクスポートしない
  • フィクスチャは bench migrate 中に自動インポートされます

ステップ 9:開発ワークフロー

必須コマンド
# After schema changes (DocType fields, hooks.py, patches)
bench --site mysite migrate

# After JS/CSS changes
bench build --app my_app

# After Python changes (controllers, events)
bench --site mysite clear-cache

# Full restart (production)
bench restart

# Watch mode (development)
bench watch  # Auto-rebuilds on file changes
開発サイクル
1. Edit code/DocType
2. bench --site mysite migrate (if schema changed)
3. bench build --app my_app (if JS/CSS changed)
4. bench --site mysite clear-cache (if Python changed)
5. Test in browser
6. Repeat

ステップ 10:アプリをテストする

# Run all tests
bench --site mysite run-tests --app my_app

# Run specific test
bench --site mysite run-tests --module my_app.my_module.doctype.my_doctype.test_my_doctype

# Run with verbose output
bench --site mysite run-tests --app my_app -v

テストケースの作成については、frappe-testing-unit を参照してください。


ステップ 11:配布用にパッケージ化する

Git 経由(標準的な方法)
cd apps/my_app
git init && git add . && git commit -m "Initial commit"
git remote add origin https://github.com/org/my_app.git
git push -u origin main
別のサイトにインストールする
# On target bench
bench get-app https://github.com/org/my_app.git
bench --site target-site install-app my_app
bench --site target-site migrate
バージョン管理
# my_app/my_app/__init__.py
__version__ = "1.0.0"  # Semantic versioning: MAJOR.MINOR.PATCH
変更の種類バージョンの更新例
破壊的変更MAJOR1.x -> 2.0.0
新機能MINOR1.1.x -> 1.2.0
バグ修正PATCH1.2.0 -> 1.2.1

ステップ 12:アプリの依存関係

Frappe/ERPNext の依存関係
# hooks.py
required_apps = ["frappe", "erpnext"]  # Install order matters
# pyproject.toml
[tool.bench.frappe-dependencies]
frappe = ">=15.0.0,<16.0.0"
erpnext = ">=15.0.0,<16.0.0"
Python パッケージの依存関係
[project]
dependencies = ["requests>=2.28.0", "pandas>=1.5.0"]

ルール:アプリ間に循環依存を絶対に作らないでください。


バージョン固有の考慮事項

項目v14v15v16
ビルド設定setup.pypyproject.tomlpyproject.toml
DocType の拡張doc_eventsdoc_eventsextend_doctype_class を推奨
Python の最小バージョン3.103.103.11
パッチ形式INI セクションINI セクションINI セクション
v16 で把握しておくべき破壊的変更
  • extend_doctype_class フック:ミックスインによる、より簡潔な拡張
  • データマスキング:フィールド単位のプライバシー設定
  • UUID による命名:新しい命名ルールのオプション
  • Chrome PDF:wkhtmltopdf は非推奨

重要なルールのまとめ

必ず実行すること
  1. bench new-app から始める — 構造を手動で絶対に作成しない
  2. __init__.py で __version__ を定義する
  3. pyproject.toml で dynamic = ["version"] を使用する
  4. 本番環境に適用する前に、データベースのコピーでパッチをテストする
  5. フィクスチャを自分のアプリのカスタマイズだけに絞り込む
  6. パッチにバージョンを付ける(v1_0、v2_0 ディレクトリ)
  7. 新規サイトへのインストールをテストする
NEVER
  1. [project].dependencies に frappe/erpnext を含めないでください
  2. フィクスチャにトランザクションデータを含めないでください
  3. サイト固有の値をハードコードしないでください(設定用 DocType を使用してください)
  4. 大規模なパッチで frappe.db.commit() を省略しないでください
  5. バックアップパッチを用意せずにフィールドを削除しないでください
  6. ERPNext のコアファイルを直接変更しないでください

参照ファイル

ファイル内容
workflows.md8 つのステップごとの実装ガイド
decision-tree.md完全な意思決定フローチャート
examples.md完全に動作するアプリの例 5 件
anti-patterns.md避けるべきよくある間違い

関連項目

  • frappe-syntax-customapp - 正確な構文のリファレンス
  • frappe-syntax-hooks - フック設定の構文
  • frappe-impl-hooks - フック実装のパターン
  • frappe-core-database - パッチでのデータベース操作
  • frappe-impl-scheduler - スケジュールタスクの実装
  • frappe-ops-bench - Bench コマンドのリファレンス
  • frappe-ops-app-lifecycle - アプリのバージョン管理とリリース管理
  • frappe-testing-unit - アプリのテスト作成
  • frappe-testing-cicd - アプリのテスト用 CI/CD パイプライン

コメント