plugins/power-pages/skills/setup-datamodel/SKILL.md
Creates Dataverse tables, columns, and relationships for a Power Pages site based on a data model proposal. Use when the user wants to set up the data model, create database tables, or build the Dataverse schema for their site.
npx skillsauth add microsoft/power-platform-skills setup-datamodelInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Plugin check: Run
node "${PLUGIN_ROOT}/scripts/check-version.js"— if it outputs a message, show it to the user before proceeding.
Guide the user through creating Dataverse tables, columns, and relationships for their Power Pages site. Follow a systematic approach: verify prerequisites, obtain a data model (via AI analysis or user-provided diagram), review and approve, then create all schema objects via OData API.
Initial request: $ARGUMENTS
Goal: Confirm PAC CLI authentication, acquire an Azure CLI token, and verify API access
Actions:
${PLUGIN_ROOT}/references/dataverse-prerequisites.md to verify PAC CLI auth, acquire an Azure CLI token, and confirm API access. Note the environment URL as <envUrl> for subsequent script calls.Output: Verified PAC CLI auth, valid Azure CLI token, confirmed API access, <envUrl> noted
Goal: Determine whether the user will upload an existing ER diagram or let AI analyze the site
Actions:
<!-- gate: setup-datamodel:2.source | category=plan | cancel-leaves=nothing -->🚦 Gate (plan · setup-datamodel:2.source): Decide whether the user uploads an existing ER diagram or the data-model-architect agent infers the model. Choice routes the rest of the skill into Path A vs Path B.
Trigger: Entering Phase 2. Why we ask: Auto-picking either path can run a multi-minute architect agent against the wrong intent (Path B) or skip Dataverse-existence checks (Path A). Cancel leaves: Nothing — no Dataverse calls made yet.
Ask the user how they want to define the data model using the AskUserQuestion tool:
Question: "How would you like to define the data model for your site?"
| Option | Description | |--------|-------------| | Upload an existing ER diagram | Provide an image (PNG/JPG) or Mermaid diagram of your existing data model | | Let the Data Model Architect figure it out | The Data Model Architect will analyze your site's source code and propose a data model automatically |
Route to the appropriate path:
If the user chooses to upload an existing diagram:
Ask the user to provide their ER diagram. Supported formats:
Read tool to view the image and extract tables, columns, relationships, and cardinalities from itParse the diagram into the same structured format used by the data-model-architect agent:
pac env who)logicalName, displayName, status (new/modified/reused), columns, relationshipslogicalName, displayName, type, requiredQuery existing Dataverse tables (same as Phase 3 would) to mark each table as new, modified, or reused.
Generate a Mermaid ER diagram from the parsed data (if the user provided an image or text) for visual confirmation.
Proceed directly to Phase 4: Review Proposal with the parsed data model.
If the user chooses to let the Data Model Architect figure it out, proceed to Phase 3: Invoke Data Model Architect (the existing automated flow).
Output: Data model source chosen and, for Path A, parsed data model ready for review
Goal: Spawn the data-model-architect agent to autonomously analyze the site and propose a data model
Actions:
Use the Task tool to spawn the data-model-architect agent. This agent autonomously:
Spawn the agent:
Task tool:
subagent_type: general-purpose
prompt: |
You are the data-model-architect agent. Follow the instructions in
the agent definition file at:
${PLUGIN_ROOT}/agents/data-model-architect.md
Analyze the current project and Dataverse environment, then propose
a complete data model. Return:
1. Publisher prefix
2. Table definitions (logicalName, displayName, status, columns, relationships)
3. Mermaid ER diagram
Wait for the agent to return its structured proposal before proceeding.
Output: Structured data model proposal from the agent (publisher prefix, table definitions, ER diagram)
Goal: Present the data model proposal to the user and get explicit approval before creating anything
Actions:
Present the data model proposal directly to the user as a formatted message, including:
🚦 Gate (plan · setup-datamodel:4.2.approval): Final sign-off on the data model proposal before any Dataverse write. Cancel here stops the skill with zero side effects.
Trigger: Phase 4.1 rendered the proposal (tables, columns, relationships, ER diagram). Why we ask: Tables and columns get created in Dataverse against the user's actual schema intent — column types and relationship cardinalities are awkward to undo. Cancel leaves: Nothing — no
EntityDefinitionsPOST yet, no.datamodel-manifest.jsonwrite.
Use AskUserQuestion to get approval:
| Question | Header | Options | |----------|--------|---------| | Does this data model look correct? | Data Model Proposal | Approve and create tables (Recommended), Request changes, Cancel |
Only proceed to creation after explicit user approval.
Output: User-approved data model proposal
Goal: Refresh the token, verify what already exists in Dataverse, and build the creation plan to avoid duplicates
Actions:
Re-acquire the auth token (tokens expire after ~60 minutes):
node "${PLUGIN_ROOT}/scripts/verify-dataverse-access.js" <envUrl>
For each table in the approved proposal marked as new, check whether it already exists:
node "${PLUGIN_ROOT}/scripts/dataverse-request.js" <envUrl> GET "api/data/v9.2/EntityDefinitions(LogicalName='<table_logical_name>')"
For tables marked as modified, verify the table exists (it should) and check which columns are missing.
From the pre-creation checks, build a list of:
Inform the user of any skipped items.
Output: Finalized creation plan with tables, columns, and relationships to create or skip
Goal: Create each approved table and its columns using the Dataverse OData Web API
Actions:
Refer to references/odata-api-patterns.md for full JSON body templates.
For each new table, POST to the EntityDefinitions endpoint:
node "${PLUGIN_ROOT}/scripts/dataverse-request.js" <envUrl> POST "api/data/v9.2/EntityDefinitions" --body '<JSON body from references/odata-api-patterns.md>'
Use the deep-insert pattern to create the table and its columns in a single POST request. See references/odata-api-patterns.md for the complete JSON structure.
For tables marked as modified, add new columns one at a time:
node "${PLUGIN_ROOT}/scripts/dataverse-request.js" <envUrl> POST "api/data/v9.2/EntityDefinitions(LogicalName='<table>')/Attributes" --body '<column JSON from references/odata-api-patterns.md>'
Track each creation attempt and its result (success/failure/skipped). Do NOT attempt automated rollback on failure — report failures and continue with remaining items.
If creating many tables, the dataverse-request.js script handles 401 token refresh automatically. No manual refresh is needed between batches.
Output: All approved tables and columns created (or failures reported)
Goal: Create all relationships between the newly created and existing tables
Actions:
Create lookup columns that establish 1:N relationships:
node "${PLUGIN_ROOT}/scripts/dataverse-request.js" <envUrl> POST "api/data/v9.2/RelationshipDefinitions" --body '<relationship JSON from references/odata-api-patterns.md>'
Create M:N relationships (intersect tables are created automatically):
node "${PLUGIN_ROOT}/scripts/dataverse-request.js" <envUrl> POST "api/data/v9.2/RelationshipDefinitions" --body '<M:N relationship JSON from references/odata-api-patterns.md>'
Track each relationship creation attempt. Report failures without rolling back.
Output: All approved relationships created (or failures reported)
Goal: Publish all customizations, verify tables exist, write the manifest, and present a summary
Actions:
Publish all customizations so the new tables and columns become available:
node "${PLUGIN_ROOT}/scripts/dataverse-request.js" <envUrl> POST "api/data/v9.2/PublishXml" --body '{"ParameterXml":"<importexportxml><entities><entity>cr123_project</entity><entity>cr123_task</entity></entities></importexportxml>"}'
See references/odata-api-patterns.md for the full PublishXml pattern.
For each created table, run a verification query:
node "${PLUGIN_ROOT}/scripts/dataverse-request.js" <envUrl> GET "api/data/v9.2/EntityDefinitions(LogicalName='<table>')?$select=LogicalName,DisplayName"
After successful verification, write .datamodel-manifest.json to the project root. This file records which tables and columns were verified to exist, and is used by the validation hook.
{
"environmentUrl": "https://org12345.crm.dynamics.com",
"tables": [
{
"logicalName": "cr123_project",
"displayName": "Project",
"status": "new",
"columns": [
{ "logicalName": "cr123_name", "type": "String" },
{ "logicalName": "cr123_description", "type": "Memo" }
]
}
]
}
Use the Write tool to create this file at <PROJECT_ROOT>/.datamodel-manifest.json. Only include tables and columns that were confirmed to exist in Step 8.2. See ${PLUGIN_ROOT}/references/datamodel-manifest-schema.md for the full schema specification.
Reference:
${PLUGIN_ROOT}/references/skill-tracking-reference.md
Follow the skill tracking instructions in the reference to record this skill's usage. Use --skillName "SetupDatamodel".
Present a summary to the user:
| Table | Status | Columns | Relationships |
|-------|--------|---------|---------------|
| cr123_project (Project) | Created | 5 columns | 2 relationships |
| contact (Contact) | Reused | 1 column added | — |
| cr123_task (Task) | Created | 4 columns | 1 relationship |
Include:
.datamodel-manifest.json)After the summary, suggest:
/add-sample-data/integrate-webapi/create-site/deploy-siteOutput: Published customizations, verified tables, manifest written, summary presented
dataverse-request.js script handles 401 token refresh and 429/5xx retry internallyBefore starting Phase 1, create a task list with all phases using TaskCreate:
| Task subject | activeForm | Description | |-------------|------------|-------------| | Verify prerequisites | Verifying prerequisites | Confirm PAC CLI auth, acquire Azure CLI token, verify API access | | Choose data model source | Choosing data model source | Ask user to upload ER diagram or let AI analyze the site | | Invoke data model architect | Invoking data model architect | Spawn agent to analyze site and propose data model | | Review and approve proposal | Reviewing proposal | Present data model proposal to user, get explicit approval | | Pre-creation checks | Running pre-creation checks | Refresh token, query existing tables, build creation plan | | Create tables and columns | Creating tables and columns | POST to OData API to create tables and columns | | Create relationships | Creating relationships | POST to OData API to create 1:N and M:N relationships | | Publish and verify | Publishing and verifying | Publish customizations, verify tables, write manifest, present summary |
Mark each task in_progress when starting it and completed when done via TaskUpdate. This gives the user visibility into progress and keeps the workflow deterministic.
Begin with Phase 1: Verify Prerequisites
tools
Adds Work IQ (M365 Copilot Search) to a Power Apps code app via the Work IQ Copilot MCP connector (shared_a365copilotchatmcp), then wires up a production-ready McpSession wrapper for AI-powered, knowledge-grounded search and chat. Use when integrating Microsoft 365 Copilot search/chat. The CopilotChat tool searches internal Microsoft 365 content (documents, emails, chats, sites, files) across your organization — prefer workload-specific tools (SharePoint, OneDrive, Teams, Mail) when the workload is explicit; do not use it for general knowledge, news, public web, or external information.
tools
Use when the user wants to preview generated screens in a browser without starting Metro / a simulator — for example after /create-mobile-app finishes or after /edit-app regenerates a screen.
development
Use when the user wants to iterate on an existing generated Power Apps mobile app after /create-mobile-app: update the plan, data model, native capabilities, design, screens, generated app code, and preview without restarting the full project flow.
development
Creates and manages the brand design system for a Power Apps mobile app. Generates brand/design-system.md (source of truth), brand/tokens.ts (importable Tamagui tokens), and brand/design-system.html (visual gallery). Triggered at Step 6.5 of /create-mobile-app, or standalone via /design-system.