PowerApps Model-Driven Apps: Enterprise Data Management with Dataverse

Introduction

While Canvas Apps excel at mobile-first experiences, Model-Driven Apps shine when building complex, data-centric enterprise applications. Built on Microsoft Dataverse (formerly Common Data Service), model-driven apps provide automatic UI generation, sophisticated business logic, and enterprise-grade securityβ€”perfect for CRM systems, ERP solutions, and line-of-business applications.

In this comprehensive guide, you'll master model-driven app development from table design through advanced customization. You'll build a complete Project Management System with projects, tasks, time tracking, resource allocation, and reportingβ€”demonstrating real-world enterprise patterns and best practices.

What You'll Learn:

  • Dataverse table design and relationships
  • Creating model-driven apps with sitemap navigation
  • Custom forms with business rules and JavaScript
  • Views, charts, and dashboards for data visualization
  • Security roles and field-level permissions
  • Business Process Flows for guided workflows
  • Power Automate integration for automation
  • Custom pages with Canvas Apps components
  • ALM strategies for model-driven apps
  • Performance optimization techniques

Time to Complete: 120-180 minutes
Skill Level: Intermediate to Advanced

Model-Driven Apps Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              Model-Driven Apps & Dataverse Architecture                     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                              β”‚
β”‚                          User Interface Layer                                β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚                    Model-Driven App (Unified Interface)               β”‚  β”‚
β”‚  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€  β”‚
β”‚  β”‚                                                                        β”‚  β”‚
β”‚  β”‚  Navigation:                                                          β”‚  β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”           β”‚  β”‚
β”‚  β”‚  β”‚ Projects β”‚  β”‚  Tasks   β”‚  β”‚Resources β”‚  β”‚ Reports  β”‚           β”‚  β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜           β”‚  β”‚
β”‚  β”‚                                                                        β”‚  β”‚
β”‚  β”‚  Main Content Area:                                                   β”‚  β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚  β”‚
β”‚  β”‚  β”‚                        Form / View                              β”‚ β”‚  β”‚
β”‚  β”‚  β”‚                                                                  β”‚ β”‚  β”‚
β”‚  β”‚  β”‚  Forms:                    Views:                               β”‚ β”‚  β”‚
β”‚  β”‚  β”‚  β€’ Main Form               β€’ Active Projects (Grid)            β”‚ β”‚  β”‚
β”‚  β”‚  β”‚  β€’ Quick Create Form       β€’ My Tasks (Kanban)                 β”‚ β”‚  β”‚
β”‚  β”‚  β”‚  β€’ Quick View Form         β€’ Overdue Items (Calendar)          β”‚ β”‚  β”‚
β”‚  β”‚  β”‚  β€’ Mobile Form             β€’ Resource Utilization (Chart)      β”‚ β”‚  β”‚
β”‚  β”‚  β”‚                                                                  β”‚ β”‚  β”‚
β”‚  β”‚  β”‚  Business Rules:            Dashboards:                         β”‚ β”‚  β”‚
β”‚  β”‚  β”‚  β€’ Field Validation         β€’ Project Health                    β”‚ β”‚  β”‚
β”‚  β”‚  β”‚  β€’ Conditional Visibility   β€’ Time Tracking                     β”‚ β”‚  β”‚
β”‚  β”‚  β”‚  β€’ Auto-calculation         β€’ Resource Allocation               β”‚ β”‚  β”‚
β”‚  β”‚  β”‚                                                                  β”‚ β”‚  β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚  β”‚
β”‚  β”‚                                                                        β”‚  β”‚
β”‚  β”‚  Command Bar:                                                         β”‚  β”‚
β”‚  β”‚  [New] [Save] [Delete] [Deactivate] [Assign] [Custom Actions]       β”‚  β”‚
β”‚  β”‚                                                                        β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                  β”‚                                           β”‚
β”‚                                  β”‚ Metadata-Driven                           β”‚
β”‚                                  β–Ό                                           β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚                        Business Logic Layer                            β”‚ β”‚
β”‚  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚
β”‚  β”‚                                                                          β”‚ β”‚
β”‚  β”‚  Business Rules:                 JavaScript:                            β”‚ β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”‚ β”‚
β”‚  β”‚  β”‚ β€’ Scope: Form/Entity β”‚        β”‚ β€’ OnLoad Event           β”‚          β”‚ β”‚
β”‚  β”‚  β”‚ β€’ Conditions         β”‚        β”‚ β€’ OnSave Event           β”‚          β”‚ β”‚
β”‚  β”‚  β”‚ β€’ Actions            β”‚        β”‚ β€’ OnChange Event         β”‚          β”‚ β”‚
β”‚  β”‚  β”‚   - Set Field Value  β”‚        β”‚ β€’ Custom Functions       β”‚          β”‚ β”‚
β”‚  β”‚  β”‚   - Set Required     β”‚        β”‚ β€’ Web API Calls          β”‚          β”‚ β”‚
β”‚  β”‚  β”‚   - Show/Hide Field  β”‚        β”‚ β€’ Complex Calculations   β”‚          β”‚ β”‚
β”‚  β”‚  β”‚   - Lock/Unlock      β”‚        β”‚                          β”‚          β”‚ β”‚
β”‚  β”‚  β”‚   - Show Message     β”‚        β”‚                          β”‚          β”‚ β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β”‚ β”‚
β”‚  β”‚                                                                          β”‚ β”‚
β”‚  β”‚  Business Process Flows:         Power Automate:                       β”‚ β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”‚ β”‚
β”‚  β”‚  β”‚ β€’ Linear Workflow    β”‚        β”‚ β€’ Automated Flows        β”‚          β”‚ β”‚
β”‚  β”‚  β”‚ β€’ Stage Gates        β”‚        β”‚ β€’ Approval Workflows     β”‚          β”‚ β”‚
β”‚  β”‚  β”‚ β€’ Required Fields    β”‚        β”‚ β€’ Notifications          β”‚          β”‚ β”‚
β”‚  β”‚  β”‚ β€’ Cross-Entity       β”‚        β”‚ β€’ External Integrations  β”‚          β”‚ β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β”‚ β”‚
β”‚  β”‚                                                                          β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                                  β”‚                                           β”‚
β”‚                                  β”‚ Data Access                               β”‚
β”‚                                  β–Ό                                           β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚                        Microsoft Dataverse                             β”‚ β”‚
β”‚  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚
β”‚  β”‚                                                                          β”‚ β”‚
β”‚  β”‚  Tables (Entities):                                                     β”‚ β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
β”‚  β”‚  β”‚                                                                    β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  Project (Custom Table)                                           β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ Name (Primary Field)                                         β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ Status (OptionSet: Active, On Hold, Completed, Cancelled)    β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ Start Date (Date)                                             β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ End Date (Date)                                               β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ Budget (Currency)                                             β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ Project Manager (Lookup to User)                             β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ Client (Lookup to Account)                                   β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  └─ Description (Multi-line Text)                                β”‚ β”‚ β”‚
β”‚  β”‚  β”‚                                                                    β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  Task (Custom Table)                                              β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ Title (Primary Field)                                        β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ Project (Lookup to Project) [1:N Relationship]               β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ Assigned To (Lookup to User)                                 β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ Status (OptionSet: Not Started, In Progress, Complete)       β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ Priority (OptionSet: Low, Medium, High, Critical)            β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ Due Date (Date)                                               β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ Estimated Hours (Decimal)                                    β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ Actual Hours (Rollup from Time Entries)                      β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  └─ Completion % (Calculated Field)                              β”‚ β”‚ β”‚
β”‚  β”‚  β”‚                                                                    β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  Time Entry (Custom Table)                                        β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ Description (Primary Field)                                  β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ Task (Lookup to Task) [1:N Relationship]                     β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ User (Lookup to User)                                        β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ Date (Date)                                                  β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ Hours (Decimal)                                              β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ Billable (Yes/No)                                            β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  └─ Notes (Multi-line Text)                                      β”‚ β”‚ β”‚
β”‚  β”‚  β”‚                                                                    β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  Resource Allocation (Custom Table)                              β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ Name (Primary Field - Auto-numbered)                         β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ Project (Lookup to Project) [N:N via intersection]           β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ Resource (Lookup to User)                                    β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ Role (OptionSet: Developer, Designer, PM, Tester)            β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ Allocation % (Whole Number)                                  β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  β”œβ”€ Start Date (Date)                                             β”‚ β”‚ β”‚
β”‚  β”‚  β”‚  └─ End Date (Date)                                               β”‚ β”‚ β”‚
β”‚  β”‚  β”‚                                                                    β”‚ β”‚ β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
β”‚  β”‚                                                                          β”‚ β”‚
β”‚  β”‚  Relationships:                                                         β”‚ β”‚
β”‚  β”‚  β€’ Project β†’ Task (1:N)                                                β”‚ β”‚
β”‚  β”‚  β€’ Task β†’ Time Entry (1:N)                                             β”‚ β”‚
β”‚  β”‚  β€’ Project β†’ Resource Allocation (1:N)                                β”‚ β”‚
β”‚  β”‚  β€’ User β†’ Task (1:N - Assigned To)                                    β”‚ β”‚
β”‚  β”‚  β€’ Account β†’ Project (1:N - Client)                                   β”‚ β”‚
β”‚  β”‚                                                                          β”‚ β”‚
β”‚  β”‚  Security:                                                              β”‚ β”‚
β”‚  β”‚  β€’ Security Roles (CRUD permissions per table)                        β”‚ β”‚
β”‚  β”‚  β€’ Field-Level Security (sensitive data)                              β”‚ β”‚
β”‚  β”‚  β€’ Column-Level Security (encryption)                                 β”‚ β”‚
β”‚  β”‚  β€’ Business Units (organizational hierarchy)                          β”‚ β”‚
β”‚  β”‚  β€’ Teams (shared access)                                               β”‚ β”‚
β”‚  β”‚                                                                          β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                                                                              β”‚
β”‚  Integration Layer:                                                         β”‚
β”‚  β€’ Dataverse Web API (REST/OData)                                          β”‚
β”‚  β€’ Power Automate (automated workflows)                                    β”‚
β”‚  β€’ Power BI (analytics and reporting)                                      β”‚
β”‚  β€’ Azure Logic Apps (external integrations)                                β”‚
β”‚  β€’ Custom Connectors (third-party systems)                                 β”‚
β”‚                                                                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Prerequisites

Required Licenses

  • Power Apps per user/per app license (or included in Microsoft 365 E3/E5)
  • Dataverse database (automatic with Power Apps environment)
  • Power Automate premium (optional, for advanced flows)

Required Permissions

  • Environment Maker role (minimum)
  • System Administrator (for full solution management)
  • System Customizer (for app and entity creation)

Development Tools

  • Power Apps Studio (web-based)
  • Visual Studio Code (for JavaScript development)
  • XrmToolBox (optional, for advanced administration)
  • Power Platform CLI (for ALM and CI/CD)

Verify Prerequisites

# Install Power Platform CLI
winget install Microsoft.PowerPlatformCLI

# Verify installation
pac --version

# Authenticate to Power Platform
pac auth create --url https://contoso.crm.dynamics.com

# List environments
pac env list

# Select environment
pac env select --environment <Environment-ID>

# List solutions in environment
pac solution list

Step 1: Create Dataverse Tables

Create Project Table

# Using Power Platform CLI to create table
pac solution init --publisher-name Contoso --publisher-prefix con

# Create Project table definition (JSON)
$projectTable = @{
    "@odata.type" = "Microsoft.Dynamics.CRM.EntityDefinition"
    LogicalName = "con_project"
    DisplayName = @{
        "@odata.type" = "Microsoft.Dynamics.CRM.Label"
        LocalizedLabels = @(
            @{
                "@odata.type" = "Microsoft.Dynamics.CRM.LocalizedLabel"
                Label = "Project"
                LanguageCode = 1033
            }
        )
    }
    DisplayCollectionName = @{
        "@odata.type" = "Microsoft.Dynamics.CRM.Label"
        LocalizedLabels = @(
            @{
                "@odata.type" = "Microsoft.Dynamics.CRM.LocalizedLabel"
                Label = "Projects"
                LanguageCode = 1033
            }
        )
    }
    Description = @{
        "@odata.type" = "Microsoft.Dynamics.CRM.Label"
        LocalizedLabels = @(
            @{
                "@odata.type" = "Microsoft.Dynamics.CRM.LocalizedLabel"
                Label = "Project management table"
                LanguageCode = 1033
            }
        )
    }
    OwnershipType = "UserOwned"
    IsActivity = $false
    HasActivities = $true
    HasNotes = $true
} | ConvertTo-Json -Depth 10

# Note: In practice, create tables via Power Apps UI for simplicity
Write-Host "⚠ Recommended: Create tables via Power Apps maker portal" -ForegroundColor Yellow
Write-Host "  Navigate to: https://make.powerapps.com β†’ Dataverse β†’ Tables" -ForegroundColor Cyan

Create Tables via Power Apps Portal

Step-by-Step Table Creation:

  1. Navigate to https://make.powerapps.com
  2. Select your environment
  3. Go to Dataverse β†’ Tables
  4. Click + New table β†’ Add columns and data

Project Table:

Column Name Data Type Required Settings
Name Single line of text Yes Primary field, max 100 chars
Status Choice Yes Active, On Hold, Completed, Cancelled
Start Date Date only Yes
End Date Date only No
Budget Currency No Precision 2, min 0
Actual Cost Currency No Calculated rollup
Project Manager Lookup Yes References: User table
Client Lookup No References: Account table
Description Multiple lines of text No Max 2000 chars
Priority Choice Yes Low, Medium, High, Critical
Health Status Choice Yes Green, Yellow, Red
Completion % Whole number No Min 0, Max 100

PowerShell Script to Create Columns:

# Connect to Dataverse
Install-Module Microsoft.Xrm.Data.PowerShell -Force
$conn = Get-CrmConnection -InteractiveMode

# Create Status column (Choice)
$statusChoices = @(
    @{Value=1; Label="Active"; Color="#0078D4"},
    @{Value=2; Label="On Hold"; Color="#FFB900"},
    @{Value=3; Label="Completed"; Color="#107C10"},
    @{Value=4; Label="Cancelled"; Color="#D13438"}
)

# Note: Use Power Apps UI for easier column creation
# Below is conceptual API approach

# Create lookup column (Project Manager)
$lookupAttribute = @{
    SchemaName = "con_ProjectManager"
    DisplayName = "Project Manager"
    Description = "User responsible for project"
    RequiredLevel = "ApplicationRequired"
    Type = "Lookup"
    Targets = @("systemuser")
}

Write-Host "βœ“ Table schema defined" -ForegroundColor Green
Write-Host "  Continue in Power Apps portal for visual creation" -ForegroundColor Cyan

Create Task Table

Task Table Schema:

Column Name Data Type Required Settings
Title Single line of text Yes Primary field
Project Lookup Yes References: Project (1:N)
Assigned To Lookup No References: User
Status Choice Yes Not Started, In Progress, Complete
Priority Choice Yes Low, Medium, High, Critical
Due Date Date only No
Estimated Hours Decimal number No Precision 2
Actual Hours Decimal number No Rollup from Time Entries
Completion % Whole number No 0-100
Dependencies Lookup No References: Task (self-referential)
Notes Multiple lines of text No

Create Time Entry Table

Time Entry Table Schema:

Column Name Data Type Required Settings
Description Single line of text Yes Primary field
Task Lookup Yes References: Task
User Lookup Yes References: User
Date Date only Yes Default: Today
Hours Decimal number Yes Precision 2, min 0.25
Billable Yes/No Yes Default: Yes
Notes Multiple lines of text No

Create Resource Allocation Table

Resource Allocation Schema:

Column Name Data Type Required Settings
Name Auto number Yes Format: RA-{SEQNUM:5}
Project Lookup Yes References: Project
Resource Lookup Yes References: User
Role Choice Yes Developer, Designer, PM, Tester, BA
Allocation % Whole number Yes Min 0, Max 100
Start Date Date only Yes
End Date Date only No
Hourly Rate Currency No For cost calculation

Step 2: Configure Table Relationships

Create 1:N Relationships

# Conceptual relationship definitions

# Project β†’ Task (1:N)
$projectTaskRelationship = @{
    SchemaName = "con_project_task"
    ReferencedEntity = "con_project"
    ReferencedAttribute = "con_projectid"
    ReferencingEntity = "con_task"
    ReferencingAttribute = "con_projectid"
    RelationshipBehavior = "Parental"  # Cascade delete
    CascadeConfiguration = @{
        Assign = "Cascade"
        Delete = "Cascade"
        Merge = "Cascade"
        Reparent = "Cascade"
        Share = "Cascade"
        Unshare = "Cascade"
    }
}

# Task β†’ Time Entry (1:N)
$taskTimeEntryRelationship = @{
    SchemaName = "con_task_timeentry"
    ReferencedEntity = "con_task"
    ReferencingEntity = "con_timeentry"
    RelationshipBehavior = "Parental"
}

# Project β†’ Resource Allocation (1:N)
$projectResourceRelationship = @{
    SchemaName = "con_project_resourceallocation"
    ReferencedEntity = "con_project"
    ReferencingEntity = "con_resourceallocation"
    RelationshipBehavior = "Referential"  # Don't cascade delete
}

Write-Host "βœ“ Relationship schema defined" -ForegroundColor Green

Create Relationships via Power Apps UI:

  1. Navigate to Dataverse β†’ Tables β†’ Project
  2. Click Relationships tab
  3. Click + Add relationship β†’ One-to-many
  4. Configure:
    • Related table: Task
    • Lookup column: Project
    • Relationship behavior: Parental (cascade delete)
  5. Click Done β†’ Save table

Step 3: Create Model-Driven App

Create New Model-Driven App

# Using Power Platform CLI
pac canvas create --msapp-name "Project Management System"

# Note: Model-driven apps are better created via UI
Write-Host "Creating model-driven app via Power Apps portal..." -ForegroundColor Cyan

Create App via Power Apps Portal:

  1. Go to https://make.powerapps.com
  2. Click + Create β†’ Model-driven app
  3. Name: "Project Management System"
  4. Click Create

Configure Sitemap (Navigation)

Sitemap Structure:

<!-- Sitemap definition -->
<SiteMap>
  <Area Id="ProjectsArea" Title="Projects" Icon="/_imgs/area_1.png">
    <Group Id="ProjectsGroup" Title="Project Management">
      <SubArea Id="ProjectsSubArea" Title="Projects" Entity="con_project" />
      <SubArea Id="TasksSubArea" Title="Tasks" Entity="con_task" />
      <SubArea Id="TimeEntriesSubArea" Title="Time Tracking" Entity="con_timeentry" />
      <SubArea Id="ResourcesSubArea" Title="Resources" Entity="con_resourceallocation" />
    </Group>
    <Group Id="ReportsGroup" Title="Analytics">
      <SubArea Id="DashboardsSubArea" Title="Dashboards" Url="/main.aspx?pagetype=dashboard" />
      <SubArea Id="ChartsSubArea" Title="Charts" Url="/main.aspx?pagetype=chartlist" />
    </Group>
  </Area>
  <Area Id="SettingsArea" Title="Settings" Icon="/_imgs/area_2.png">
    <Group Id="AdminGroup" Title="Administration">
      <SubArea Id="SecuritySubArea" Title="Security Roles" Url="/main.aspx?page=settingssecurity" />
      <SubArea Id="CustomizationsSubArea" Title="Customizations" Url="/main.aspx?page=settingscustomization" />
    </Group>
  </Area>
</SiteMap>

Configure via App Designer:

  1. In App Designer, click Site Map (navigation icon)
  2. Add Area: "Projects"
  3. Add Group: "Project Management"
  4. Add Subarea:
    • Title: "Projects"
    • Entity: Project
    • Icon: Select from gallery
  5. Repeat for Tasks, Time Entries, Resources
  6. Click Save β†’ Publish

Step 4: Design Forms

Create Main Form for Project

Form Layout:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Project: Web Application Redesign                       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                          β”‚
β”‚ [General Tab] [Team Tab] [Tasks Tab] [Timeline]        β”‚
β”‚                                                          β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚ β”‚ General Information                               β”‚   β”‚
β”‚ β”‚                                                    β”‚   β”‚
β”‚ β”‚ Name*: [Web Application Redesign              ]  β”‚   β”‚
β”‚ β”‚ Client: [Contoso Corporation          β–Ό]         β”‚   β”‚
β”‚ β”‚ Project Manager*: [John Doe            β–Ό]        β”‚   β”‚
β”‚ β”‚                                                    β”‚   β”‚
β”‚ β”‚ Start Date*: [01/15/2025]  End Date: [06/30/2025]β”‚   β”‚
β”‚ β”‚ Status*: [Active β–Ό]   Priority: [High β–Ό]         β”‚   β”‚
β”‚ β”‚ Health Status: [Green β–Ό]  Completion: [45%]      β”‚   β”‚
β”‚ β”‚                                                    β”‚   β”‚
β”‚ β”‚ Budget: [$150,000.00]  Actual Cost: [$67,500.00] β”‚   β”‚
β”‚ β”‚                                                    β”‚   β”‚
β”‚ β”‚ Description:                                       β”‚   β”‚
β”‚ β”‚ [Complete redesign of customer portal with      ] β”‚   β”‚
β”‚ β”‚ [modern UI/UX, mobile responsiveness, and       ] β”‚   β”‚
β”‚ β”‚ [integration with new backend APIs.             ] β”‚   β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                          β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Quick Stats                                         β”‚ β”‚
β”‚ β”‚                                                      β”‚ β”‚
β”‚ β”‚ Total Tasks: 45      Resources: 8                  β”‚ β”‚
β”‚ β”‚ Completed: 20        Open Tasks: 25                 β”‚ β”‚
β”‚ β”‚ Overdue: 3          Hours Logged: 450              β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                                                          β”‚
β”‚ [Save] [Save & Close] [Deactivate] [Assign] [...]     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Form Configuration Steps:

  1. In App Designer, select Project table
  2. Click Forms β†’ Main Form β†’ Edit
  3. Add sections:
    • General Information (2 columns)
    • Financial (2 columns)
    • Quick Stats (read-only, 3 columns)
  4. Add fields by dragging from field explorer
  5. Configure field properties:
    • Required fields: Red asterisk
    • Read-only: Lock icon
    • Business rules: Will add next

Add Business Rules to Form

Business Rule 1: Auto-calculate Budget Status

// When Budget or Actual Cost changes
// IF Actual Cost > Budget THEN
//   Set Health Status = Red
//   Show Warning Message
// ELSE IF Actual Cost > (Budget * 0.8) THEN
//   Set Health Status = Yellow
// ELSE
//   Set Health Status = Green

Create via Business Rules Designer:

  1. In Form Designer, click Business Rules β†’ + New business rule
  2. Name: "Budget Health Check"
  3. Scope: Entity (applies to all forms)
  4. Condition:
    • IF Actual Cost > Budget
    • THEN Set Health Status = "Red"
    • AND Show Error: "Project is over budget!"
  5. Add second condition:
    • ELSE IF Actual Cost > (Budget Γ— 0.8)
    • THEN Set Health Status = "Yellow"
    • AND Show Warning: "Approaching budget limit"
  6. Add default action:
    • ELSE Set Health Status = "Green"
  7. Click Activate β†’ Save

Business Rule 2: Validate Dates

  1. Name: "Date Validation"
  2. Condition:
    • IF End Date < Start Date
    • THEN Show Error: "End date must be after start date"
    • AND Set Required: End Date = true
  3. Activate and save

Add JavaScript for Complex Logic

Create Web Resource (JavaScript):

// ProjectForm.js
var ProjectForm = ProjectForm || {};

ProjectForm.OnLoad = function(executionContext) {
    var formContext = executionContext.getFormContext();
    
    // Calculate and display project duration
    ProjectForm.calculateDuration(formContext);
    
    // Load team members count
    ProjectForm.loadTeamStats(formContext);
    
    // Set up event handlers
    formContext.getAttribute("con_startdate").addOnChange(ProjectForm.calculateDuration);
    formContext.getAttribute("con_enddate").addOnChange(ProjectForm.calculateDuration);
};

ProjectForm.calculateDuration = function(executionContext) {
    var formContext = executionContext.getFormContext();
    
    var startDate = formContext.getAttribute("con_startdate").getValue();
    var endDate = formContext.getAttribute("con_enddate").getValue();
    
    if (startDate && endDate) {
        var duration = Math.floor((endDate - startDate) / (1000 * 60 * 60 * 24));
        
        // Display duration (requires custom field: con_duration)
        formContext.getAttribute("con_duration").setValue(duration);
        
        // Update notification
        formContext.ui.setFormNotification(
            "Project duration: " + duration + " days",
            "INFO",
            "duration"
        );
    }
};

ProjectForm.loadTeamStats = function(formContext) {
    var projectId = formContext.data.entity.getId().replace(/[{}]/g, "");
    
    // Query related resource allocations
    var fetchXml = [
        "<fetch aggregate='true'>",
        "  <entity name='con_resourceallocation'>",
        "    <attribute name='con_resourceallocationid' aggregate='count' alias='count'/>",
        "    <filter>",
        "      <condition attribute='con_projectid' operator='eq' value='" + projectId + "'/>",
        "    </filter>",
        "  </entity>",
        "</fetch>"
    ].join("");
    
    Xrm.WebApi.retrieveMultipleRecords(
        "con_resourceallocation",
        "?fetchXml=" + encodeURIComponent(fetchXml)
    ).then(
        function success(result) {
            if (result.entities.length > 0) {
                var count = result.entities[0].count;
                formContext.ui.setFormNotification(
                    "Team Members: " + count,
                    "INFO",
                    "teamcount"
                );
            }
        },
        function error(error) {
            console.error("Error loading team stats:", error.message);
        }
    );
};

ProjectForm.OnSave = function(executionContext) {
    var formContext = executionContext.getFormContext();
    
    // Validate budget before saving
    var budget = formContext.getAttribute("con_budget").getValue();
    var actualCost = formContext.getAttribute("con_actualcost").getValue();
    
    if (actualCost > budget * 1.2) {
        executionContext.getEventArgs().preventDefault();
        Xrm.Navigation.openAlertDialog({
            text: "Project is significantly over budget. Please review before saving.",
            confirmButtonLabel: "OK"
        });
    }
};

Upload JavaScript as Web Resource:

  1. Go to Solutions β†’ Your solution
  2. Click + New β†’ More β†’ Web resource
  3. Upload ProjectForm.js
  4. Name: "con_/scripts/ProjectForm.js"
  5. Display Name: "Project Form Scripts"
  6. Click Save β†’ Publish

Attach to Form:

  1. Open Project Main Form
  2. Click Form Properties
  3. Form Libraries β†’ Add Library
  4. Select "con_/scripts/ProjectForm.js"
  5. Event Handlers:
    • OnLoad: ProjectForm.OnLoad
    • OnSave: ProjectForm.OnSave
  6. Save β†’ Publish

Step 5: Create Views

Create Active Projects View

View Configuration:

  1. Go to Project table β†’ Views
  2. Click + New view
  3. Name: "Active Projects"
  4. Filter: Status = Active
  5. Add columns:
    • Name
    • Client
    • Project Manager
    • Start Date
    • End Date
    • Health Status
    • Completion %
    • Budget
  6. Sort by: Start Date (Descending)
  7. Save and publish

FetchXML for Advanced View:

<fetch version="1.0" output-format="xml-platform" mapping="logical">
  <entity name="con_project">
    <attribute name="con_name" />
    <attribute name="con_status" />
    <attribute name="con_startdate" />
    <attribute name="con_enddate" />
    <attribute name="con_budget" />
    <attribute name="con_completion" />
    <attribute name="con_healthstatus" />
    <order attribute="con_startdate" descending="true" />
    <filter type="and">
      <condition attribute="con_status" operator="eq" value="1" />
      <condition attribute="statecode" operator="eq" value="0" />
    </filter>
    <link-entity name="account" from="accountid" to="con_clientid" link-type="outer" alias="client">
      <attribute name="name" />
    </link-entity>
    <link-entity name="systemuser" from="systemuserid" to="con_projectmanagerid" alias="pm">
      <attribute name="fullname" />
    </link-entity>
  </entity>
</fetch>

Create My Tasks View (for Task table)

<fetch version="1.0" output-format="xml-platform" mapping="logical">
  <entity name="con_task">
    <attribute name="con_title" />
    <attribute name="con_priority" />
    <attribute name="con_status" />
    <attribute name="con_duedate" />
    <attribute name="con_estimatedhours" />
    <attribute name="con_completion" />
    <order attribute="con_duedate" descending="false" />
    <filter type="and">
      <condition attribute="con_assignedtoid" operator="eq-userid" />
      <condition attribute="con_status" operator="ne" value="3" />
      <condition attribute="statecode" operator="eq" value="0" />
    </filter>
    <link-entity name="con_project" from="con_projectid" to="con_projectid" alias="project">
      <attribute name="con_name" />
    </link-entity>
  </entity>
</fetch>

Step 6: Create Dashboards and Charts

Create Project Health Dashboard

Dashboard Layout:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚           Project Management Dashboard                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                               β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Projects by Status   β”‚  β”‚ Projects by Health Status    β”‚ β”‚
β”‚ β”‚                      β”‚  β”‚                              β”‚ β”‚
β”‚ β”‚ [Pie Chart]          β”‚  β”‚ [Donut Chart]                β”‚ β”‚
β”‚ β”‚ Active: 15           β”‚  β”‚ Green: 10                    β”‚ β”‚
β”‚ β”‚ On Hold: 3           β”‚  β”‚ Yellow: 4                    β”‚ β”‚
β”‚ β”‚ Completed: 25        β”‚  β”‚ Red: 4                       β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                                                               β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚ β”‚ Active Projects (Grid)                                  β”‚  β”‚
β”‚ β”‚                                                          β”‚  β”‚
β”‚ β”‚ Name               PM          Budget    Completion%    β”‚  β”‚
β”‚ β”‚ Web Redesign       John Doe    $150K     45%           β”‚  β”‚
β”‚ β”‚ Mobile App         Jane Smith  $200K     30%           β”‚  β”‚
β”‚ β”‚ CRM Integration    Bob Johnson $100K     75%           β”‚  β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                                               β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Budget vs Actual     β”‚  β”‚ Tasks by Priority            β”‚ β”‚
β”‚ β”‚ (Column Chart)       β”‚  β”‚ (Bar Chart)                  β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                                                               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Create Chart: Projects by Status

  1. Go to Project table β†’ Charts
  2. Click + New chart
  3. Name: "Projects by Status"
  4. View: Active Projects
  5. Chart type: Pie
  6. Legend: Status
  7. Series: Count of Projects
  8. Save and close

Create Chart: Budget vs Actual

<!-- Chart data descriptor -->
<datadescription>
  <fetch aggregate="true">
    <entity name="con_project">
      <attribute name="con_name" alias="name" groupby="true" />
      <attribute name="con_budget" alias="budget" aggregate="sum" />
      <attribute name="con_actualcost" alias="actual" aggregate="sum" />
      <filter>
        <condition attribute="con_status" operator="eq" value="1" />
      </filter>
      <order alias="name" descending="false" />
    </entity>
  </fetch>
</datadescription>

Step 7: Implement Business Process Flow

Create Project Initiation Process Flow

BPF Stages:

[Stage 1: Planning] β†’ [Stage 2: Approval] β†’ [Stage 3: Execution] β†’ [Stage 4: Closure]

Stage 1: Planning

  • Required Fields:
    • Project Name
    • Project Manager
    • Start Date
    • Budget
  • Steps:
    1. Define scope
    2. Identify stakeholders
    3. Create initial schedule

Stage 2: Approval

  • Required Fields:
    • Client
    • Budget (confirmed)
    • Resource Allocation
  • Steps:
    1. Submit for manager approval
    2. Get client sign-off
    3. Allocate resources

Stage 3: Execution

  • Required Fields:
    • Team assigned
    • Tasks created
  • Steps:
    1. Kick-off meeting
    2. Begin task execution
    3. Track progress

Stage 4: Closure

  • Required Fields:
    • Completion % = 100
    • Status = Completed
  • Steps:
    1. Final deliverables review
    2. Client acceptance
    3. Lessons learned documentation

Create BPF:

  1. Go to Flows (Power Automate)
  2. Click + New flow β†’ Business process flow
  3. Name: "Project Lifecycle"
  4. Entity: Project
  5. Add stages and steps as defined
  6. Configure branching:
    • IF Budget > $100K THEN require executive approval
  7. Save and activate

Step 8: Configure Security Roles

Create Custom Security Roles

Project Manager Role:

Privileges:
- Project: Create, Read, Write, Delete (Own), Append, Append To
- Task: Create, Read, Write, Delete (Team), Append, Append To
- Time Entry: Read (Organization), Create/Write/Delete (Own)
- Resource Allocation: Create, Read, Write (Team)

Team Member Role:

Privileges:
- Project: Read (Team)
- Task: Read (Team), Create/Write/Delete (Assigned To Me)
- Time Entry: Create, Read, Write, Delete (Own)
- Resource Allocation: Read (Team)

Executive Role:

Privileges:
- Project: Read (Organization), Write (Business Unit)
- Task: Read (Organization)
- Time Entry: Read (Organization)
- Resource Allocation: Read (Organization)
- Dashboards: Read (Organization)

Create Security Role:

  1. Go to Settings β†’ Security β†’ Security Roles
  2. Click + New role
  3. Name: "Project Manager"
  4. Configure privileges for each table
  5. Save and assign to users

Step 9: Advanced Customization

Add Calculated and Rollup Fields

Calculated Field: Days Remaining

// Field type: Calculated
// Data type: Whole Number
// Formula:
DIFFINDAYS(TODAY(), con_enddate)

Rollup Field: Total Hours Logged

// Field type: Rollup
// Source Entity: Time Entry
// Aggregation: SUM
// Field to Aggregate: Hours
// Filter: Task = Current Project's Tasks

Create via Power Apps:

  1. Edit Project table
  2. Add column β†’ Calculated or Rollup
  3. Configure formula/aggregation
  4. Save and publish

Create Power Automate Integration

Flow: Notify PM on Overdue Tasks

Trigger: Recurrence (Daily at 8 AM)

Actions:
  1. List overdue tasks:
     - Filter: Due Date < Today AND Status != Complete
  
  2. For each overdue task:
     a. Get project details
     b. Get project manager email
     c. Send email notification:
        To: Project Manager
        Subject: "Overdue Task Alert: [Task Title]"
        Body: |
          Task: [Title]
          Project: [Project Name]
          Assigned To: [User]
          Due Date: [Due Date]
          Days Overdue: [Calculated]

Real-World Enterprise Example

Scenario: Contoso Consulting Firm

Challenge: Managing 50+ concurrent client projects with 200+ employees

  • No centralized project tracking
  • Time entry done in spreadsheets
  • Resource allocation conflicts
  • Budget overruns not caught early
  • Client reporting manual and time-consuming

Solution Implementation:

  1. Dataverse Schema:

    • 5 custom tables (Project, Task, Time Entry, Resource, Client)
    • 20+ custom fields with business logic
    • Automated rollups for financial tracking
  2. Model-Driven App:

    • 4 custom forms with JavaScript validation
    • 12 views for different stakeholder needs
    • 6 dashboards (Executive, PM, Team Member)
    • Business Process Flow for standardized project lifecycle
  3. Integration:

    • Power BI for executive reporting
    • Power Automate for 15+ workflows
    • Outlook integration for time entry
    • Teams integration for collaboration

Results After 6 Months:

Metric Before After Improvement
Time to create project 2 hours 15 minutes 87% faster
Budget overruns 25% of projects 8% of projects 68% reduction
Resource utilization 65% 85% 31% increase
Time entry compliance 60% 95% 58% increase
Client reporting time 4 hours/project 30 minutes 87% faster
PM productivity Baseline +40% Significant gain

Best Practices Summary

DO:

  1. βœ… Design schema before building UI
  2. βœ… Use business rules for simple logic (no code)
  3. βœ… Implement rollup fields for aggregations
  4. βœ… Create separate security roles for each persona
  5. βœ… Use Business Process Flows for standardization
  6. βœ… Enable auditing for compliance requirements
  7. βœ… Use solutions for ALM (export/import)
  8. βœ… Test in dev environment before production
  9. βœ… Document customizations for maintenance
  10. βœ… Use FetchXML for complex queries

DON'T:

  1. ❌ Over-customize with JavaScript (use platform features first)
  2. ❌ Create too many tables (normalize appropriately)
  3. ❌ Skip relationship configuration
  4. ❌ Grant excessive permissions
  5. ❌ Forget to publish customizations
  6. ❌ Ignore performance (limit form fields < 100)
  7. ❌ Hard-code GUIDs in JavaScript
  8. ❌ Skip field-level security for sensitive data
  9. ❌ Create forms without business rules
  10. ❌ Deploy without backup/rollback plan

Key Takeaways

  1. Dataverse is powerful - Relational database with built-in features
  2. Metadata-driven UI - Forms/views generated from schema
  3. Business rules > Code - Use no-code when possible
  4. Security is granular - Field-level, row-level, table-level
  5. BPF standardizes workflows - Guided user experiences
  6. Rollups aggregate data - No manual calculations needed
  7. JavaScript extends capabilities - Complex logic when needed
  8. Integration is seamless - Power Automate, Power BI, Teams
  9. ALM with solutions - Export/import entire apps
  10. Enterprise-ready - Scalable, secure, compliant

Additional Resources

Next Steps

  1. Add mobile optimization: Configure mobile forms and views
  2. Implement AI Builder: Prediction models for project risk
  3. Create custom connectors: Integrate with external systems
  4. Build Power BI reports: Advanced analytics and forecasting
  5. Deploy to production: Using solutions and pipelines
  6. Train end users: Create documentation and training videos
  7. Set up monitoring: Application Insights and usage analytics
  8. Implement CI/CD: Azure DevOps pipelines for solutions

Ready to build enterprise data management solutions? Model-driven apps with Dataverse provide the foundation for scalable, secure, and maintainable business applications!