enable-tables-offline について
Microsoft Dataverse のオフラインプロファイルを保守する人向けに、指定テーブルのオフライン対応を有効化するスキルです。利用可能フラグと変更追跡を設定し、メタデータを順に更新して公開・検証します。
主な機能
- 01テーブルのオフライン利用を有効化
- 02変更追跡の有効化
- 03テーブル単位での順次メタデータ更新
- 04カスタマイズの公開と検証
- 05有効化済みテーブルのスキップ
活用シーン
- 01モバイルオフラインプロファイルへの追加準備
- 02指定テーブルの変更追跡を有効化
- 03メタデータ変更の検証と公開
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ microsoft/ power-platform-skills --skill enable-tables-offlineインストール後、Claude Code で/enable-tables-offlineを入力して読み込まれたか確認します。
詳細
共通の指示:shared-instructions.md — まずお読みください。
参考資料:
- offline-profile-schema.md — エンティティのフィールド対応表(
IsAvailableOffline、ChangeTrackingEnabled)
テーブルをオフラインで利用できるようにする
1 つ以上の Dataverse テーブルの EntityMetadata で、IsAvailableOffline=true と ChangeTrackingEnabled=true に設定し、カスタマイズを公開します。これはメーカー ポータルの画像 4 に示されている「オフラインで使用可能」+「変更の追跡」の前提条件です。両方を設定しないと、テーブルをモバイル オフライン プロファイルに追加できません。
順次処理(Dataverse のメタデータ ロック)で、冪等性があります。有効化済みのテーブルに再度実行しても何も行われません。
呼び出しコンテキストとルートのバインド
この内部ヘルパーは、常に子呼び出しとして実行されます。プロジェクトを読み取ったりコマンドを実行したりする前に、app-working-directory.md を実行してください。
所有者の絶対パスの working_dir が必要です。指定された --working-dir は、同じネイティブ形式の正規化済みルートを示す必要があります。ルートコンテキストがない、相対パスである、または競合している場合は、プロジェクトにアクセスする前に NEEDS_CONTEXT を返します。ディレクトリにアクセスできない場合は BLOCKED です。起動時の cwd を使用したり、別のルート解決手段を導入したりしないでください。
MOBILE_APP_ORCHESTRATING=1、orchestrator: setup-offline-profile、working_dir、phase、approved_scope、および提供された回答を受け取ります。選択された環境 ID/URL/テナントと、テーブル/前提条件/公開の許可リストを正確に保持してください。このマーカーは承認を意味しません。現在のオフライン承認のうち、一致するものだけを再利用してください。スコープがない、または変更されている場合は、所有者に NEEDS_CONTEXT を返します。
--plan-only の場合、または計画フェーズで引き継ぐ場合は、読み取り専用の確認が許可されている範囲で、PUT、公開、成果物の書き込みを行う前に、提案する前提条件の変更を返してください。ゲート応答によって提案のみのモードを解除することはできません。
すべてのシェル呼び出しとファイルツールに、正規のルート契約を適用してください。呼び出しのたびに絶対パスの PLUGIN_ROOT と呼び出しコンテキストを再指定してください。以前の cd、エクスポート、シェル変数は引き継がれません。値がない場合は NEEDS_CONTEXT を返し、未解決のプレースホルダーは決して実行しないでください。
リンクされたすべての復旧コマンド、再 GET による検証、再試行では、同じルート、環境、明示的なテナントを使用してください。<working_dir>/power.config.json、<working_dir>/memory-bank.md、以下のマニフェストの場所を含め、アプリ内の絶対パスのみを読み取ってください。
ワークフロー
- プロジェクトと認証を確認 → 2. テーブル一覧を解決 → 3. 現在の状態を確認 → ゲート → 4. テーブルごとに EntityMetadata を PUT → 5. 公開 → 6. 検証 → 7. まとめ
ステップ 1 — プロジェクトと認証を確認
cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
if [ ! -f power.config.json ] || [ ! -f app.config.js ]; then
echo "BLOCKED: working_dir is not an initialized app" >&2
exit 1
fi
探索や変更を行う前に、アプリの environmentId が所有者の選択した環境と一致することを確認してください。同じルートから、次の永続化されない検索を実行します。
cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
environment_id=$(node -p "require('./power.config.json').environmentId || ''") || {
echo "BLOCKED: unreadable power.config.json" >&2; exit 1;
}
if [ -z "$environment_id" ] || [ "$environment_id" != "<selected-environment-id>" ]; then
echo "NEEDS_CONTEXT: selected environment does not match working_dir" >&2
exit 1
fi
node "${PLUGIN_ROOT}/scripts/resolve-environment.js" "$environment_id" --no-cache --require-tenant
リゾルバーから Environment URL と Tenant ID を取得し、<envUrl> と <tenantId> に設定してください。以下のすべてのヘルパー呼び出しと再試行で、このテナントを明示的に指定してください。テナントコンテキストがない場合、または競合している場合は NEEDS_CONTEXT です。ID、URL、テナントが所有者の情報と一致することを確認してください。復旧のためにアカウントや環境を切り替えてはいけません。認証されていない場合は中止してください。
ステップ 2 — テーブル一覧を解決
所有者の approved_scope に含まれる正確なテーブル許可リストのみを使用してください。$ARGUMENTS のカンマ区切りまたはスペース区切りのテーブル一覧は、この許可リストと一致する必要があります。--working-dir はルートコンテキストであり、テーブル名ではありません。テーブルの選択がない場合、または競合している場合は NEEDS_CONTEXT を返します。承認済みリストが明示的に空の場合は、検証済みの何もしない操作として扱います。
選択されたテーブルを確認する目的に限り、<working_dir>/.datamodel-manifest.json、または新しいアプリの場合は <working_dir>/docs/plan-artifacts/.datamodel-manifest.json を調べます。マニフェストは、すべての行を有効化する許可ではありません。別のアプリのマニフェストを探したり、許可リストを黙って拡張したりしないでください。
Step 3 — 現在の状態を確認する
開始前に表示します:
"→ 個のテーブルの現在の IsAvailableOffline + ChangeTrackingEnabled を照会しています…"
各テーブルを順番に処理します:
cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
node "${PLUGIN_ROOT}/scripts/dataverse-request.js" "<envUrl>" GET \
"EntityDefinitions(LogicalName='<table>')?\$select=LogicalName,DisplayName,IsAvailableOffline,ChangeTrackingEnabled,IsCustomizable" \
--tenant-id "<tenantId>"
ステータステーブルを作成します:
| Table | IsAvailableOffline | ChangeTrackingEnabled | IsCustomizable | Needs change? |
|--------------------|--------------------|-----------------------|----------------|---------------|
| cr123_note | false | false | true | YES (both) |
| cr123_visit | true | false | true | YES (track) |
| contact | true | true | true | NO |
厳守事項: いずれかのテーブルで IsCustomizable.Value=false の場合、そのテーブルは変更できません。変更セットから除外し、DONE_WITH_CONCERNS で報告してください。システム管理テーブル(ほとんどの OOB テーブル)には管理者によるソリューションパッチの手順が必要ですが、このスキルでは対応していません。
ゲート — 変更前の承認
Step 3 のステータステーブルを、オーナーが承認した前提条件と公開差分と比較します。一致する現在の Gate 1 承認がある場合は、重複してプロンプトを表示せず、その承認を再利用します。それ以外の場合は、ステータステーブルと NEEDS_CONTEXT: offline prerequisite approval を /setup-offline-profile に返します。このスキルが承認ゲートを管理します。スコープを拡大したり、提案のみのモードを上書きしたりしないでください。
計画本文:
The following EntityMetadata changes will be PUT in sequence:
cr123_note → set IsAvailableOffline=true, ChangeTrackingEnabled=true
cr123_visit → set ChangeTrackingEnabled=true (IsAvailableOffline already true)
After all updates, targeted PublishXml will publish only the changed tables.
Tables already in the desired state are skipped (no API call).
ユーザーが拒否した場合は、STOP してください。承認された変更内容をそのまま実行する場合に限り、続行してください。
Step 4 — テーブルごとに EntityMetadata を PUT する
開始前に表示します:
"→ 個のテーブルの EntityMetadata を順番に更新しています(Dataverse はメタデータ書き込みを直列化します)…"
⚠️ 同時実行に関するルール — 必ず遵守してください。 メタデータの書き込み中、組織ごとに排他ロックが保持されます。PUT を 1 回実行し、2xx の応答を待ってから次を実行してください。バッチ処理も並列呼び出しも禁止です。
/add-dataverseStep 5 と同じルールです。
変更が必要な各テーブルについて(すでに目標の状態にあるテーブルはスキップします):
cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
node "${PLUGIN_ROOT}/scripts/update-entity-offline-flags.js" "<envUrl>" \
--table "<table>" \
--offline true \
--tracking true \
--tenant-id "<tenantId>"
ヘルパーの動作:
EntityMetadataを再読み込みして、現在のMetadataIdとSchemaNameを取得します(どちらも PUT 本文に必須であり、指定しないと Dataverse は PUT を拒否します)。- 表示ラベルを保持するため、
MSCRM.MergeLabels: trueを送信します(falseを使用するとラベルが消去されるため、絶対に使用しないでください)。 - テーブルがすでに目標の状態にある場合は
{ "status": 200, "noop": true, ... }を返します(何も表示せずにスキップします)。 IsCustomizable.Value=falseのテーブル(システム管理対象)の場合は{ "status": 200, "skipped": "uncustomizable", ... }を返します(DONE_WITH_CONCERNSとして必ず報告してください)。- 更新が成功した場合は
{ "status": 204, ... }を返します。 - 401 のトークン更新と 429 のバックオフを自動的に処理します。
ヘルパーがステータス 403 PrivilegeCheckFailed を返した場合: ユーザーには "Customize System" 特権がありません。テーブル名と不足している特権を表示してから、STOP してください。
ChangeTrackingEnabled cannot be disabled を伴うステータス 400 の場合: 無視してください。この処理は true から false に変更するときだけ発生しますが、その変更は行いません。
204 の後に ✓ <table> を表示します。何も変更しない場合は ↷ <table> (already enabled) を表示し、スキップする場合は ⚠ <table> (uncustomizable) を表示します。
ステップ 5 — カスタマイズを公開する(対象を絞った PublishXml、失敗時は PublishAllXml にフォールバック)
開始前に出力します:
"→ カスタマイズを公開しています(編集したエンティティに対象を絞って PublishXml を実行)…"
実際に変更されたエンティティに対象を絞った PublishXml を使用します。これにより、共有環境で確認された組織全体のレート制限の急増(0x80071151「同時に PublishAll が実行中」)を回避できます。2026-05-25 の実測に基づきます。
cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
# Build the <entities> XML body from the list of tables modified in Step 4
node "${PLUGIN_ROOT}/scripts/dataverse-request.js" "<envUrl>" POST \
"PublishXml" --tenant-id "<tenantId>" --body '{
"ParameterXml": "<importexportxml><entities><entity><table></entity></entities></importexportxml>"
}'
ステップ 4 でヘルパーがフラグを PUT したすべてのテーブルについて、<entity>...</entity> の行に置き換えます。処理不要だったテーブルやカスタマイズできないテーブルは除外します。
204 の場合:成功です。ステップ 6 に進みます。
429 / 0x80071151(「同時に公開処理が実行中」)の場合:dataverse-request.js の再試行ロジックによって、自動的にバックオフします。4 回の再試行後も失敗する場合は、DONE_WITH_CONCERNS: publish bottlenecked on shared env; metadata changes are committed but maker portal will not refresh until next publish を返します。後続のスキル(/setup-offline-profile)は続行できます。メタデータレベルの書き込みは永続化されています。
対象を絞った呼び出しが 0x80048d19 など、レート制限以外のエラーを返した場合に限り、オーナーが別途、より広範な公開を承認したときに PublishAllXml にフォールバックします。テーブルのみの承認では、無関係な変更の公開は許可されません。
cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
node "${PLUGIN_ROOT}/scripts/dataverse-request.js" "<envUrl>" POST \
"PublishAllXml" --tenant-id "<tenantId>" --body '{}'
/setup-offline-profile のステップ 8 と同じ、タイムアウトしたものの成功している場合の処理を行います。クライアントがタイムアウトしても、テーブルの EntityMetadata に対する後続の GET でフラグが設定されていることを確認できた場合は、成功として扱います。
ステップ 6 — 検証
開始前に出力します:
"→ EntityMetadata を再クエリし、フラグが設定されていることを確認しています…"
変更したテーブルごとにステップ 3 のクエリを再実行します。変更した各行で IsAvailableOffline=true および ChangeTrackingEnabled=true になっていることを確認します。異なる値がある場合は BLOCKED とします。何かが PUT をサイレントに拒否しています(可能性は極めて低く、通常はマネージドソリューションのレイヤーがアンマネージドの変更を隠していることを示します)。
ステップ 7 — 概要
次を出力します:
✓ Offline prerequisites enabled on <N> table(s):
- cr123_note (IsAvailableOffline + ChangeTrackingEnabled set)
- cr123_visit (ChangeTrackingEnabled set; IsAvailableOffline already on)
Skipped (already enabled): contact
Next: return to the current /setup-offline-profile workflow.
タイムスタンプと検証済みテーブルの一覧を、<working_dir>/memory-bank.md の ## Offline profile の下に記録します。結果を現在のオーナーに返し、別のオフラインセットアップワークフローは起動しないでください。
ステータスコード
スキルの応答の最初の行は、次のいずれかの文字列です。
DONE— 要求されたすべてのテーブルで両方のフラグが設定されていますDONE_WITH_CONCERNS: <list>— 一部のテーブルがスキップされました(カスタマイズ不可、公開に関する警告など)NEEDS_CONTEXT: <missing>— テーブルの一覧を解決できず、ユーザーからも提供されませんでしたBLOCKED: <reason>— 認証に失敗した、権限チェックに失敗した、または PUT 後の検証結果が一致しませんでした