Template · Dataverse CLAUDE.md
Template Dataverse ≈ reading…

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 / statecode and 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.

ToolFile path
Claude CodeCLAUDE.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.

markdown
# «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:

markdown
## 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)
  • 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.