TL;DR
If you do three things early, you avoid most long-term chaos:
- Define tables like you’re writing a dictionary entry.
- Name things so people can find them without guessing.
- Organize solutions in a clean, consolidated way so deployments are repeatable.
You’re here because…
- “We keep adding fields and now nobody knows what anything means.”
- “We built the same concept in three places.”
- “Deployments feel messy.”
- “Why do we have five ‘Status’ fields?”
- “Users are entering random placeholder text just to save.”
Fast path: what to do in the next hour
- Write one Table Definition Card for the next thing you’re building.
- Lock in naming rules (tables, columns, flows, solutions).
- Pick a solution strategy (feature-based or layer-based — both can work).
- Build the smallest working slice (1 table, 5–10 fields, 1 relationship).
- Test one real user journey end-to-end.
Future You will thank you.
Part 1: Data model that doesn’t collapse later
What this is for
Designing Dataverse tables/columns/relationships so reporting, security, automation, and UI stay predictable.
When to use it
- New table creation
- Refactors / re-architecture
- Adding a “new concept” (not just another attribute)
The Table Definition Card
Before creating a new table, fill this out.
Template: Table Definition Card
- Table name (singular concept):
- Business definition (one sentence):
- What makes a record unique: (external ID, natural key, combination)
- Who owns it: (user/team/org-owned)
- Who needs access: (personas/teams/BUs)
- Lifecycle/status: (Active/Inactive + what status reasons mean)
- Top 5 questions we must answer: (views/reports)
- Related tables: (parents/children)
- Automation touching it: (flows/plugins/BPF)
Consultant law #12: If the table can’t be defined in one sentence, it’s not ready to exist.
Table vs fields (simple decision guide)
Make a NEW TABLE when…
- It’s a repeatable thing with multiple instances (Payments, Reviews, Approvals)
- It has its own lifecycle (status, dates, ownership)
- It needs security rules separate from the parent
- You’ll report on it (counts, totals, time trends)
- It needs many related records (notes, files, activities)
Keep it as FIELDS when…
- It’s a single attribute of an existing thing
- It has no separate ownership/status/lifecycle
- You’ll never need multiple instances per parent
Required fields: be selective
Make a field required only if the record is invalid without it.
Good required fields
- Primary identifier (name/title)
- Required relationship (parent lookup)
- Core classification (Type) that drives downstream logic
Avoid making fields required when…
- Users don’t know it at creation time
- It’s “nice to have”
- It’s hidden on the form (this creates save blockers)
Choices vs text
- Use a Choice when values are controlled + used for reporting/logic.
- Use Text when it’s genuinely free-form.
Tip: Don’t drive logic off labels. Labels change; values stay stable.
Part 2: Naming rules that prevent chaos
What this is for
Making everything predictable, searchable, and scannable.
Naming goals
- Predictable: you can guess names without tribal knowledge
- Searchable: you can find it quickly in maker portal / solution explorer
- Scannable: names show intent, not mystery
Practical naming patterns
Tables
- Use: Singular noun (Invoice, Voucher, Review)
- Avoid: Data, Misc, New Table 2, Invoice Table
Columns (fields)
Use: Thing + Attribute
- Voucher Balance
- Payment Amount
- Review Due Date
Avoid:
- Amount2
- Temp Field
- New Status
Choices
- Choice set name: Approval Status
- Values: Draft, Submitted, Approved, Denied (clean + consistent)
Flows
Use: Verb – Object – Context
- Create – Invoice – On Voucher Payment
- Sync – Account Region – On Update
- Notify – Reviewer – On Submission
Scripts / plugins / rules (if used)
- BR – Require Fields – On Submit
- JS – Set Defaults – Work Order
- PLG – Validate Balance – PreOperation
Part 3: Solutions that make ALM boring (in a good way)
Key idea
There isn’t one perfect solution strategy. The goal is:
- Clean boundaries
- Consolidated where it makes sense
- Repeatable deployments
- Minimal “where does this live?” confusion
Two common ways to organize solutions (both valid)
Option A: Feature-based solutions (common + scalable)
- Feature – Intake
- Feature – Approvals
- Feature – Billing
- Feature – Integrations
Why teams like it: you deploy features independently and keep changes grouped by business capability.
Option B: Layer-based solutions (clean + very organized)
- Data Model (tables, columns, relationships)
- User Experience (apps, forms, views, command bar, dashboards)
- Cloud Flows (Power Automate + env vars + conn refs)
- Custom Code (JS, plugins, PCF, web resources)
Why teams like it: it keeps “what type of component” clear and avoids mixing code/UX/schema in one place.
Hotfix solutions (use carefully)
A hotfix solution can be fine when you need to patch prod quickly, as long as:
- It’s small and labeled clearly (ex: Hotfix – 02.16.2026 – Invoice Total)
- You later merge/roll it into the main solution path so you don’t end up with 40 hotfixes forever
Rule of thumb: Hotfix solutions should be temporary, not a lifestyle.
Versioning (date format)
Example
- First release that day: 02.16.2026.1
- Second release same day: 02.16.2026.2
- Next day: 02.17.2026.1
What to track with it (keep it simple)
Alongside the version, keep a tiny release note:
- What changed
- What to test
- Any special steps (env var updates, connection refs, etc.)
Future You will thank you.
Common gotchas (no drama, just real)
- Creating tables without defining uniqueness → duplicates later
- Making too many fields required too early → placeholder data
- Creating multiple similar fields because naming wasn’t specific
- One giant solution for everything → slow imports + messy changes
- Too many tiny solutions → hard to track + hard to deploy
- Building important components outside solutions → “works in dev only” problems
Definition of Done
You’re done when:
Data model
- ☐ Every new table has a Table Definition Card
- ☐ Uniqueness is defined (key/strategy)
- ☐ Relationships are intentional
- ☐ Required fields are justified and visible at the right time
Naming
- ☐ Tables and columns are predictable and consistent
- ☐ Flows follow Verb–Object–Context
- ☐ You can find key components quickly without guessing
Solutions
- ☐ Your solution strategy is documented (feature-based OR layer-based)
- ☐ Components are consolidated and clean (not scattered)
- ☐ Deployments don’t require manual mystery fixes
Printable templates
Template 1: Table Definition Card
- Table name:
- One sentence definition:
- Unique key strategy:
- Ownership:
- Access needed:
- Lifecycle/status:
- Top 5 reporting questions:
- Parent/child relationships:
- Automation touching it:
Template 2: Naming quick rules
- Tables: Singular nouns
- Columns: Thing + Attribute
- Flows: Verb – Object – Context
- One publisher prefix
- Avoid vague names (Temp, New, Test2 Final)
Template 3: Solution strategy (pick one)
- Feature-based: Core shared + Feature solutions by capability
- Layer-based: Data Model + UX + Cloud Flows + Custom Code
- Hotfix: small, labeled, and merged back later