本文へ移動
cccskills
無料GitHub で公開

model-driven-app

モデル駆動型アプリを Dataverse Web API(appmodules / sitemaps テーブル)で作成・構成・公開する。

インストール方法を見る

含まれるファイル(7)

  • SKILL.md17.5 KB
  • references/.env.example1.0 KB
  • references/deploy-reference.md7.1 KB
  • references/troubleshooting.md4.0 KB
  • scripts/customize_views_forms.py29.1 KB
  • scripts/deploy_model_driven_app.py26.3 KB
  • scripts/test_customize_views_forms.py2.1 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

モデル駆動型アプリ構築スキル

Dataverse Web API(appmodules / sitemaps テーブル)でモデル駆動型アプリを ソリューション対応で 作成・構成・公開する。

前提: setup_dataverse.py で Dataverse テーブルが作成済みであること。 テーブルが存在しないとアプリに追加するコンポーネントがない。

大前提: 一つのソリューション内に開発

Dataverse テーブル・Code Apps・Power Automate フロー・Copilot Studio エージェント・モデル駆動型アプリ は すべて同一のソリューション内 に含める。 .env の SOLUTION_NAME と PUBLISHER_PREFIX を全フェーズで統一して使用する。

認証: Python スクリプトの認証は standard スキルの auth_helper.py を使用。

前提: 設計フェーズ完了後にデプロイに入る(必須)

アプリをデプロイする前に、アプリ設計をユーザーに提示し承認を得ていること。

設計提示時に含める内容:

項目内容
アプリ名表示名とユニーク名(英語のみ)
アプリ説明アプリの目的の簡潔な説明
含めるテーブル一覧ソリューション内のどのテーブルをアプリに含めるか
ナビゲーション構造SiteMap の Area/Group/SubArea 構成
ビュー・フォーム各テーブルで表示するビューとフォーム(デフォルト: 全て含む)
セキュリティロールアプリに関連付けるロール
モデル駆動型アプリ: 設計提示 → ユーザー承認 → デプロイスクリプト実行

必須要件

AppModule 作成の必須プロパティ

name:          アプリの表示名(日本語 OK)
uniquename:    一意名(英語のみ。自動的にソリューション prefix が付く)
clienttype:    4(Unified Interface)★ 必須
webresourceid: アイコン用 WebResource ID
               システムデフォルト: 953b9fac-1e5e-e611-80d6-00155ded156f

clienttype=4 を必ず指定する【必須】

❌ clienttype 未指定 → レガシー Web クライアント用アプリが作成される
   「このアプリはレガシ Web クライアント用に設計されたものです」警告が表示
✅ clienttype=4 → Unified Interface(新しい Look & Feel)
   モダンな UI で動作し、警告なし

uniquename は英語のみ

✅ uniquename: "ProjectManagement"
❌ uniquename: "プロジェクト管理"
→ 英数字とアンダースコアのみ許容
→ 作成時にソリューション publisher prefix が自動付与(例: new_ProjectManagement)

SiteMap が必須(ValidateApp で検証される)

❌ SiteMap なしで AppModule を作成 → ValidateApp で "App does not contain Site Map" エラー
✅ SiteMap を先に作成し、AddAppComponents でアプリに追加

SiteMap XML の正式フォーマット【必須】

<SiteMap IntroducedVersion="7.0.0.0">
  <Area Id="MainArea" ShowGroups="true" IntroducedVersion="7.0.0.0">
    <Titles><Title LCID="1041" Title="アプリ名" /></Titles>
    <Group Id="grp_transaction" IntroducedVersion="7.0.0.0" IsProfile="false">
      <Titles><Title LCID="1041" Title="業務データ" /></Titles>
      <SubArea Id="sub_entity1" Entity="prefix_entity1" AvailableOffline="true" />
      <SubArea Id="sub_entity2" Entity="prefix_entity2" AvailableOffline="true" />
    </Group>
    <Group Id="grp_master" IntroducedVersion="7.0.0.0" IsProfile="false">
      <Titles><Title LCID="1041" Title="マスタ" /></Titles>
      <SubArea Id="sub_master1" Entity="prefix_master1" AvailableOffline="true" />
    </Group>
  </Area>
</SiteMap>
  • Area: ナビゲーションの最上位区分
  • Group: Area 内のグループ(複数テーブルをまとめる)
  • SubArea: 個別テーブルへのナビゲーション。Entity は 論理名(例: geek_project)
  • 複数の Area / Group を定義可能(例: マスタデータとトランザクションデータを分離)

ShowGroups="true" を必ず指定する【必須】

❌ ShowGroups 未指定 or "false" → グループヘッダーが非表示
   → 最初のグループのテーブルしかナビゲーションに表示されない
✅ ShowGroups="true" → 全グループがヘッダー付きで表示される

教訓: 複数 Group がある SiteMap で ShowGroups="true" を忘れると、 最初のグループのアイテムしか表示されず、他のグループが完全に消える。 これはエラーにならず ValidateApp も通るため発見が困難。

SiteMap XML 必須属性一覧

要素必須属性説明
SiteMapIntroducedVersion="7.0.0.0"バージョニング用。Unified Interface で必要
AreaShowGroups="true", IntroducedVersion="7.0.0.0"ShowGroups がないと複数グループが表示されない
GroupIntroducedVersion="7.0.0.0", IsProfile="false"IsProfile=false でプロファイルグループと区別
SubAreaEntity, AvailableOffline="true"オフラインアクセス。モバイル対応に必要

Title は属性ではなく Titles 子要素で指定する

❌ <Area Id="MainArea" Title="アプリ名">           ← Title 属性は非正式
✅ <Area Id="MainArea" ShowGroups="true" IntroducedVersion="7.0.0.0">
     <Titles><Title LCID="1041" Title="アプリ名" /></Titles>

LCID="1041" は日本語。英語は 1033。 Title 属性でも動作する場合があるが、正式フォーマットは Titles 子要素。

SiteMap レコードは isappaware: true で作成

body = {
    "sitemapname": "MyApp_SiteMap",
    "sitemapnameunique": "MyApp_SiteMap",
    "sitemapxml": sitemap_xml,
    "isappaware": True,  # ← 必須。アプリ固有 SiteMap として認識される
}

コンポーネント追加は AddAppComponents アクション

# SiteMap の追加
api_post("AddAppComponents", {
    "AppId": app_id,
    "Components": [
        {"sitemapid": sitemap_id, "@odata.type": "Microsoft.Dynamics.CRM.sitemap"},
    ]
})

# ビュー(savedquery)の追加
api_post("AddAppComponents", {
    "AppId": app_id,
    "Components": [
        {"savedqueryid": view_id, "@odata.type": "Microsoft.Dynamics.CRM.savedquery"},
    ]
})

# フォーム(systemform)の追加
api_post("AddAppComponents", {
    "AppId": app_id,
    "Components": [
        {"formid": form_id, "@odata.type": "Microsoft.Dynamics.CRM.systemform"},
    ]
})

注意: テーブルのビューとフォームを追加すると、テーブルも自動的にアプリに含まれる。 ただし AppComponents.Entities は空のままになる場合がある(appmodulecomponent テーブルに Entity Type=1 のレコードが自動作成されない)。 これはアプリの動作には影響しない。SiteMap の SubArea で Entity を指定していれば正常にナビゲーションに表示される。

AddAppComponents のバッチ分割パターン

大量のコンポーネント(ビュー・フォーム × 複数テーブル)を一度に送信すると失敗する場合がある。
✅ 50 件ずつバッチ分割して送信
✅ バッチ失敗時は 1 件ずつフォールバック(既に追加済みのコンポーネントをスキップ)

Entity コンポーネント (Type=1) は API で直接追加できない

❌ appmodulecomponent テーブルへの POST → "The 'Create' method does not support entities of type 'appmodulecomponent'"
❌ appmodules の collection-valued ナビゲーションプロパティへの deep insert → 非対応
✅ AddAppComponents で savedquery/systemform を追加すれば、SiteMap 経由でテーブルが表示される

教訓: Market Insight App のように UI で作成したアプリは Entity (Type=1) コンポーネントが登録されるが、 API で作成したアプリでは savedquery/systemform のみが登録される。これは正常動作であり修正不要。

ビューとフォームの取得パターン

# テーブルのシステムビュー(querytype=0 = Public View)
views = api_get("savedqueries", {
    "$filter": f"returnedtypecode eq '{entity_logical_name}' and querytype eq 0",
    "$select": "savedqueryid,name",
})

# テーブルのメインフォーム(type=2 = Main Form)
forms = api_get("systemforms", {
    "$filter": f"objecttypecode eq '{entity_logical_name}' and type eq 2",
    "$select": "formid,name",
})

セキュリティロール関連付け

# appmoduleroles_association ナビゲーションプロパティで関連付け
requests.post(
    f"{API}/appmodules({app_id})/appmoduleroles_association/$ref",
    headers=headers,
    json={"@odata.id": f"{API}/roles({role_id})"}
)
  • Basic User(旧 Common Data Service User)ロールを最低限関連付ける
  • 追加のカスタムロールがあれば同様に関連付け

ValidateApp で事前検証

result = api_get(f"ValidateApp(AppModuleId={app_id})")
# ValidationSuccess: true/false
# ValidationIssueList: エラー/警告の配列
  • SiteMap がない → Error
  • テーブルにフォーム/ビュー参照がない → Warning

PublishXml でアプリ公開

publish_xml = (
    f"<importexportxml>"
    f"<appmodules><appmodule>{app_id}</appmodule></appmodules>"
    f"</importexportxml>"
)
api_post("PublishXml", {"ParameterXml": publish_xml})

個別テーブルの PublishXml(ビュー・フォーム変更時)

# ビュー・フォーム・アイコンなどテーブル単位の変更を公開する場合
publish_xml = (
    '<importexportxml>'
    f'<entities><entity>{entity_logical_name}</entity></entities>'
    '</importexportxml>'
)
api_post("PublishXml", {"ParameterXml": publish_xml})

PublishXml vs PublishAllXml: テーブル単位の変更は <entities> で個別公開するのが高速。 PublishAllXml は全コンポーネントを公開するため時間がかかる。

アプリ URL フォーマット

✅ {DATAVERSE_URL}/main.aspx?appid={app_id}
❌ {DATAVERSE_URL}/apps/{app_id}      ← 動作しない

デプロイスクリプトは完了時に .env へ APP_MODULE_ID を自動保存する。 この値は deploy_security_role.py のアプリ関連付けステップで使用される。

ソリューション含有の検証

# AppModule (ComponentType=80)
api_post("AddSolutionComponent", {
    "ComponentId": app_id,
    "ComponentType": 80,
    "SolutionUniqueName": SOLUTION_NAME,
    "AddRequiredComponents": False,
    "DoNotIncludeSubcomponents": False,
})

# SiteMap (ComponentType=62)
api_post("AddSolutionComponent", {
    "ComponentId": sitemap_id,
    "ComponentType": 62,
    "SolutionUniqueName": SOLUTION_NAME,
    "AddRequiredComponents": False,
    "DoNotIncludeSubcomponents": False,
})

べき等デプロイパターン

# 既存アプリ検索
existing = api_get("appmodules", {
    "$filter": f"uniquename eq '{APP_UNIQUE_NAME}'",
    "$select": "appmoduleid,name"
})

if existing["value"]:
    app_id = existing["value"][0]["appmoduleid"]
    # 更新(PATCH)
    api_patch(f"appmodules({app_id})", {"name": new_name, "description": new_desc})
else:
    # 新規作成(POST)
    api_post("appmodules", body)

.env パラメータ

全パラメータの定義(取得元コメント付き)は references/.env.example を参照。 実値はリポジトリルートの .env に置く(.gitignore 済み)。

# === 必須(共通)===
DATAVERSE_URL=https://{org}.crm7.dynamics.com/
TENANT_ID={your-tenant-id}
SOLUTION_NAME=ProjectManagement
PUBLISHER_PREFIX=geek

# === モデル駆動型アプリ オプション ===
APP_DISPLAY_NAME=プロジェクト管理           # 未設定時は SOLUTION_NAME から生成
APP_UNIQUE_NAME=ProjectManagement          # 未設定時は SOLUTION_NAME を使用
APP_DESCRIPTION=プロジェクト管理アプリ      # 未設定時は自動生成

デプロイ・設計パターン

デプロイスクリプト・ナビゲーション設計パターンの詳細は デプロイリファレンス を参照。

トラブルシューティングは トラブルシューティング を参照。

コンポーネントタイプ定数

コンポーネントComponentTypeOData Type
SiteMap62Microsoft.Dynamics.CRM.sitemap
AppModule80Microsoft.Dynamics.CRM.appmodule
Entity (テーブル)1—
View (savedquery)26Microsoft.Dynamics.CRM.savedquery
Form (systemform)60Microsoft.Dynamics.CRM.systemform
Dashboard60—
Security Role20Microsoft.Dynamics.CRM.role

クイックリファレンス: 必須要件

ルール理由
clienttype=4 (Unified Interface) を必ず指定未指定だとレガシー Web クライアント用アプリになる
uniquename は英語のみ日本語は API エラーになる
SiteMap は isappaware: true で作成アプリ固有 SiteMap として認識させる
SiteMap を AddAppComponents で追加追加しないと ValidateApp でエラー
ShowGroups="true" を Area に指定未指定だと最初のグループしか表示されない【必須】
IntroducedVersion="7.0.0.0" を全要素に指定Unified Interface で必須。欠けると表示不具合
Title は <Titles> 子要素で指定属性ではなくネスト要素が正式フォーマット
AvailableOffline="true" を SubArea に指定モバイル対応・オフラインアクセスに必要
ビュー・フォームを追加するとテーブルも含まれるテーブル直接追加は不要(API で追加もできない)
Basic User ロールを関連付けユーザーがアプリを表示できるようにする
公開前に ValidateApp で検証エラーがあると公開しても正常動作しない
AddSolutionComponent でソリューション含有検証MSCRM.SolutionName ヘッダーだけに依存しない
べき等デプロイパターンを使うuniquename で検索 → 更新 or 新規作成
ビューのプライマリ列は常に先頭_name 列を LayoutXml の最初の <cell> にする
複数行テキスト(Memo)はビューに含めない一覧表示で見づらいため。フォームのみに表示
テーブルアイコンは SVG で設定IconVectorName + Web Resource (type=11)。詳細は standard スキルの アイコン作成リファレンス 参照
IconVectorName は PUT で設定MSCRM.MergeLabels: true 必須。詳細は standard スキルの アイコン作成リファレンス 参照
AddAppComponents は 50 件ずつバッチ分割大量送信は失敗する場合あり。失敗時は 1 件ずつ再試行
アプリ URL は main.aspx?appid=/apps/{id} 形式ではない
PublishXml はテーブル単位で個別公開PublishAllXml より高速
既存 SiteMap は PATCH で XML 更新新 SiteMap を AddAppComponents で追加すると 0x80050111
appmodulecomponent は appmoduleidunique で検索不可componenttype=62 で全件取得し objectid で照合

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

admin

無料日本語概要

Power Platform のテナント / 環境ガバナンスを確認・設定する管理スキル。開発着手前の環境チェック(既定環境ではないか・マネージド環境・Dataverse / Code Apps / MCP の有効化・セキュリティ ロール・管理 API アクセス)と DLP 事前チェックを非対話スクリプトで実行し、必要ならマネージド環境設定・カスタムコネクタの DLP 分類・ACP(Advanced connector policies)の許可コネクタを dry-run 付きで変更する。Microsoft 第一者サービスだけを許可する ACP 推奨プロファイルの適用と、クラシック DLP から ACP への移行も支援する。クラシック DLP と ACP は既定の混成モードで併用され、より制限の厳しい方が適用されるため両方を確認する。オプションとして、既定環境 / 個人開発者環境 / 市民開発者環境 / AI CoE セントラル / AI CoE 内製開発の 5 グループからなるテナント全体の環境戦略を、読み取り専用スキャン → 移行プラン(admin-migration-plan.md)→ レビュー → 適用の順で策定・実行する。設定は環境グループのルールで行うのを原則とし、グループ ルールに無い項目(既定環境ルーティング・Dataverse for Teams 禁止・Dataverse 検索・グループへの割り当て・Copilot クレジット配分)だけをテナント設定・環境個別設定・Dataverse の組織設定で補う。IP 制限・テナント分離・監査ログ・ライセンス配分などの管理設定は references にまとめる。

geekfujiwara/CodeAppsDevelopmentStandard722026年10月9日 更新

agent-flows

無料日本語概要

Copilot Studio 新 UI の Agent flows / Workflows を構築・公開・検証する。Dataverse レコード作成/更新トリガーから既存の発行済み Copilot Studio v2 を Agent ノードで呼ぶ標準経路、Code Apps との非同期要求/結果連携、および手動 Start + inline Agent の API ライフサイクル検証を扱う。

geekfujiwara/CodeAppsDevelopmentStandard722026年10月9日 更新

agm-qa-authoring

無料日本語概要

株主総会の想定問答を、IR 抜粋(決算短信・説明資料・招集通知など)を根拠に下書きし、利用者の確認後に Dataverse の想定問答テーブルへ「下書き」として登録するスキル。 Use when ユーザーが「配当について想定問答を作って」「この論点の想定問答を 3 件追加して」「招集通知から想定問答を作って」「想定問答を登録して」と依頼したとき。 Dataverse MCP コネクタ(describe / read_query / search_data / create_record / update_record)を使用する。削除・テーブル変更のツールは使わない。

geekfujiwara/CodeAppsDevelopmentStandard722026年10月9日 更新

agm-qa-review

無料日本語概要

株主総会の想定問答を点検し、根拠の IR 抜粋に無い数値・存在しない根拠 ID・回答者や注意事項の抜け・趣旨の重複・下書きのまま残っているものを一覧にするスキル(書き込みはしない)。 Use when ユーザーが「想定問答を点検して」「根拠の無い数値が無いか確認して」「下書きの想定問答を一覧にして」と依頼したとき。 Dataverse MCP コネクタ(describe / read_query / search_data)を使用する。書き込み・削除のツールは使わない。

geekfujiwara/CodeAppsDevelopmentStandard722026年10月9日 更新

agm-rehearsal-script

無料日本語概要

株主総会の質疑応答のリハーサル台本(議長・株主・回答役員の読み上げ原稿)を、承認済みの想定問答から作り、Dataverse のリハーサル台本テーブルへ登録するスキル。 Use when ユーザーが「リハーサルの台本を作って」「QA-001〜QA-010 で読み上げ原稿を作って」「番号を言わない株主も入れた台本を作って」と依頼したとき。 Dataverse MCP コネクタ(describe / read_query / search_data / create_record / update_record)を使用する。削除・テーブル変更のツールは使わない。

geekfujiwara/CodeAppsDevelopmentStandard722026年10月9日 更新

ai-builder

無料日本語概要

AI Builder の AI プロンプト(GPT Dynamic Prompt)を Dataverse API で作成し、Copilot Studio エージェントにツール(アクション)として追加する。Power Automate フローとの統合パターンも含む。

geekfujiwara/CodeAppsDevelopmentStandard722026年10月9日 更新

geekfujiwara のスキルをすべて見る

このスキルの問題を報告する