Dataverse CLAUDE.md Template
One file at the root of your project that teaches Claude Code (and GitHub Copilot via .github/copilot-instructions.md) the right way to build Dataverse — tables, forms, views, and dashboards — based on the Eyedeas Inc developer guidelines.
In this template
- Locks in your solution & publisher choice every time
- Stops Claude from pluralising table names or inventing new status columns
- Tells it to use OOB
statuscode/statecodeand global option sets - Authors forms in 2-column sections, with child tables as sub-grids on their own tabs
- Moves Status Reason + Owner to the header
- Adds custom fields to all relevant views
- Routes dashboard requests through gen-pages
1. Drop It Into Your Project
Two files, one for each AI assistant. They share the same content, just different locations.
| Tool | File path |
|---|---|
| Claude Code | CLAUDE.md at the repo root |
| GitHub Copilot | .github/copilot-instructions.md at the repo root |
Both load automatically into every session. Set them once and every prompt for the life of the project gets sharper. (Tip: keep them in sync — when you update one, copy to the other.)
2. The Template
Copy this whole block into CLAUDE.md (or copilot-instructions.md). Edit the placeholders marked «like-this» for your project.
# «Project Name» — Dataverse authoring rules
Use the Microsoft Dataverse skills published at
https://github.com/microsoft/Dataverse-skills as the implementation reference.
## Solution design
- Always use the **preferred solution** and a **custom publisher**.
- Publisher prefix: `«fs»` (used for all custom tables, columns, choices)
- Target environment URLs are in `.env` — never hard-code them in prompts.
## Table creation
- **Do not pluralize** table names (e.g. `fs_workorder`, not `fs_workorders`).
- **Do not** create custom status fields — use OOB **`statuscode` / `statecode`**.
Add custom values to `statuscode` instead of inventing new state columns.
- **Option sets must use global definitions**, never local-per-column.
- When analysing the data model, **favor the least amount of data repetition**
(normalise; reuse tables; avoid duplicate columns across tables).
- **Enable Quick Create** when creating tables.
- For **child relationships**, make the primary attribute (the `name` column)
meaningful — e.g. an auto-number, not a generic "Name" text field.
## Form authoring (main forms)
- Lay out custom fields **logically by solution domain**, in **sections of 2 fields**.
- For tables with many fields, **split into multiple tabs**.
- Show **related (child) tables as sub-grids in their own tabs**.
- Move **Owner** and **Status Reason** to the **header**.
## View authoring
- Add custom fields to **all relevant views** — except long-description fields
(those bloat the row height).
## Dashboards / enhanced UI
- When a dashboard is requested or implied, **ask whether to build it with
gen-pages** first (skill: https://github.com/microsoft/power-platform-skills),
before falling back to classic dashboards.
## Naming conventions
- Tables: `«fs»_«singular-name»` e.g. `fs_workorder`
- Choice columns: `«fs»_«name»` + global option set
- Lookups: `«fs»_«target-table»id` e.g. `fs_accountid`
- Solutions: PascalCase, no spaces e.g. `ContosoFieldService`
## Hard rules (do not break)
- Never deploy from Claude directly to Production.
- Wrap every PAC CLI write with a confirmation step.
- All schema changes go through the `«main»` branch via PR — never push to it.
3. Why Each Rule Matters
If a teammate asks "why is this in our CLAUDE.md?", here are the one-line answers.
Solution & publisher
Using the preferred solution + a custom publisher keeps everything you create discoverable, exportable, and namespaced. Without it, AI-generated tables can land in the default solution where they're hard to package and promote.
Don't pluralize
Microsoft's own convention. Singular table names read better in code, in lookups (fs_workorderid, not fs_workordersid), and in N:N relationship names.
Use OOB status / statecode
Every Dataverse table already has statecode (Active/Inactive) and statuscode (configurable values). Custom status columns mean two sources of truth, broken model-driven UX, and reporting headaches. Add values to statuscode — don't invent.
Global option sets
Local option sets can't be shared across tables. The first time you need the same Priority values on Cases and Work Orders, a global option set saves a refactor.
Sections of 2 + header for Owner/Status
It's the layout users read fastest in model-driven apps and the one Microsoft's own first-party apps follow. Putting Owner and Status Reason in the header keeps record context visible without scrolling.
Child tables on their own tabs
Sub-grids inline get truncated and slow the main form. A dedicated tab per related table loads on demand and gives users room to filter and sort.
Custom fields in views
If a field is worth creating, it's worth surfacing where users browse records. Skipping long descriptions keeps the row height usable.
Ask before building dashboards
Gen-pages produce richer, AI-generated UI than classic dashboards for most modern use cases. Confirming up-front avoids wasted work on a classic dashboard the user will throw away.
4. Extending the Template
The base rules above are organisation-level (Eyedeas Inc). Add project-level conventions below them:
## Project-specific (Contoso Field Service)
### Domain
- Tables: fs_workorder, fs_technician, fs_servicelocation, fs_partsinventory
- Status flow: Draft → Scheduled → InProgress → Complete
### Integrations
- Teams notifications via flow `Notify-Technician`
- Power Pages partner extranet exposes fs_workorder (read-only via Web API)
### Security
- App user `SVC-FieldService` owns scheduled flows
- Partner role: read-only on fs_workorder filtered by their account
### Out of scope
- No custom plug-ins on Dataverse events (use flows)
- No model-driven apps for partner users (Power Pages only)
5. Use It With Other Guides
- Claude Code Setup Guide — install Claude Code and load this CLAUDE.md.
- GitHub Copilot Setup Guide — drop the same content into
.github/copilot-instructions.mdso both assistants follow the rules. - GitHub Desktop Setup Guide — commit the file so the rules ship with the repo.
- One file, every session. CLAUDE.md (and copilot-instructions.md) load automatically — no need to repeat your rules in every prompt.
- Solution + publisher locked in means AI-generated tables always land where they belong.
- Singular names, OOB status, global option sets, header Owner/Status — these are the four most-violated conventions in AI-generated Dataverse output. Lock them down once.
- Child tables on their own tabs. Default layout from the AI is usually inline sub-grids; the template fixes it.
- Dashboards default to gen-pages, with confirmation. Stops the AI from quietly building a classic dashboard you'll throw away.
- Keep CLAUDE.md and copilot-instructions.md in sync. Edit one, copy to the other.