## 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
```powershell
# 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 = @{
> **Architecture Overview:** "@odata.type" = "Microsoft.Dynamics.CRM.EntityDefinition"
## 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:**
```powershell
## Connect to Dataverse
Install-Module Microsoft.Xrm.Data.PowerShell -Force
$conn = Get-CrmConnection -InteractiveMode
## Create Status column (Choice)
$statusChoices = @(
```text
@{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 = @{
```text
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
Expected output:
Package installed successfully.
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
Architecture Overview: ## Conceptual relationship definitions
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 = @{
Architecture Overview: SchemaName = "con_task_timeentry"
SchemaName = "con_project_resourceallocation" ReferencedEntity = "con_project" ReferencingEntity = "con_resourceallocation" RelationshipBehavior = "Referential" # Don't cascade delete``` }
Write-Host "✓ Relationship schema defined" -ForegroundColor Green
Architecture Overview: Create Relationships via Power Apps UI:
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
Architecture Overview: Create App via Power Apps Portal:
Diagram: See the official Microsoft documentation for architecture details.
Create My Tasks View (for Task table)
<fetch version="1.0" output-format="xml-platform" mapping="logical">
<entity name="con_task">
```text
<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:
Diagram: See the official Microsoft documentation for architecture details.
Step 7: Implement Business Process Flow
Create Project Initiation Process Flow
BPF Stages:
Architecture Overview: [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:
- Define scope
- Identify stakeholders
- Create initial schedule
Stage 2: Approval
- Required Fields:
- Client
- Budget (confirmed)
- Resource Allocation
- Steps:
- Submit for manager approval
- Get client sign-off
- Allocate resources
Stage 3: Execution
- Required Fields:
- Team assigned
- Tasks created
- Steps:
- Kick-off meeting
- Begin task execution
- Track progress
Stage 4: Closure
- Required Fields:
- Completion % = 100
- Status = Completed
- Steps:
- Final deliverables review
- Client acceptance
- Lessons learned documentation
Create BPF:
- Go to Flows (Power Automate)
- Click + New flow → Business process flow
- Name: "Project Lifecycle"
- Entity: Project
- Add stages and steps as defined
- Configure branching:
- IF Budget > $100K THEN require executive approval
- 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:
- Go to Settings → Security → Security Roles
- Click + New role
- Name: "Project Manager"
- Configure privileges for each table
- 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:
- Edit Project table
- Add column → Calculated or Rollup
- Configure formula/aggregation
- 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:
-
Dataverse Schema:
- 5 custom tables (Project, Task, Time Entry, Resource, Client)
- 20+ custom fields with business logic
- Automated rollups for financial tracking
-
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
-
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:
- ✅ Design schema before building UI
- ✅ Use business rules for simple logic (no code)
- ✅ Implement rollup fields for aggregations
- ✅ Create separate security roles for each persona
- ✅ Use Business Process Flows for standardization
- ✅ Enable auditing for compliance requirements
- ✅ Use solutions for ALM (export/import)
- ✅ Test in dev environment before production
- ✅ Document customizations for maintenance
- ✅ Use FetchXML for complex queries
DON'T:
- ❌ Over-customize with JavaScript (use platform features first)
- ❌ Create too many tables (normalize appropriately)
- ❌ Skip relationship configuration
- ❌ Grant excessive permissions
- ❌ Forget to publish customizations
- ❌ Ignore performance (limit form fields < 100)
- ❌ Hard-code GUIDs in JavaScript
- ❌ Skip field-level security for sensitive data
- ❌ Create forms without business rules
- ❌ Deploy without backup/rollback plan
Architecture Decision and Tradeoffs
When designing low-code development solutions with Power Apps, consider these key architectural trade-offs:
| Approach | Best For | Tradeoff |
|---|---|---|
| Managed / platform service | Rapid delivery, reduced ops burden | Less customisation, potential vendor lock-in |
| Custom / self-hosted | Full control, advanced tuning | Higher operational overhead and cost |
Recommendation: Start with the managed approach for most workloads and move to custom only when specific requirements demand it.
Validation and Versioning
- Last validated: April 2026
- Validate examples against your tenant, region, and SKU constraints before production rollout.
- Keep module, CLI, and SDK versions pinned in automation pipelines and review quarterly.
Security and Governance Considerations
- Apply least-privilege access using RBAC roles and just-in-time elevation for admin tasks.
- Store secrets in managed secret stores and avoid embedding credentials in scripts or source files.
- Enable audit logging, data protection policies, and periodic access reviews for regulated workloads.
Cost and Performance Notes
- Define budgets and alerts, then monitor usage and cost trends continuously after go-live.
- Baseline performance with synthetic and real-user checks before and after major changes.
- Scale resources with measured thresholds and revisit sizing after usage pattern changes.
Official Microsoft References
- https://learn.microsoft.com/power-apps/
- https://learn.microsoft.com/power-platform/admin/
- https://learn.microsoft.com/power-platform/guidance/
Public Examples from Official Sources
- These examples are sourced from official public Microsoft documentation and sample repositories.
- Documentation examples: https://learn.microsoft.com/power-apps/
- Sample repositories: https://github.com/microsoft/PowerApps-Samples
- Prefer adapting these examples to your tenant, subscriptions, and governance requirements before production use.
Key Takeaways
- Dataverse is powerful - Relational database with built-in features
- Metadata-driven UI - Forms/views generated from schema
- Business rules > Code - Use no-code when possible
- Security is granular - Field-level, row-level, table-level
- BPF standardizes workflows - Guided user experiences
- Rollups aggregate data - No manual calculations needed
- JavaScript extends capabilities - Complex logic when needed
- Integration is seamless - Power Automate, Power BI, Teams
- ALM with solutions - Export/import entire apps
- Enterprise-ready - Scalable, secure, compliant
Additional Resources
- Model-Driven Apps Documentation
- Dataverse Developer Guide
- Business Rules
- FetchXML Reference
- Web API Reference
Next Steps
- Add mobile optimization: Configure mobile forms and views
- Implement AI Builder: Prediction models for project risk
- Create custom connectors: Integrate with external systems
- Build Power BI reports: Advanced analytics and forecasting
- Deploy to production: Using solutions and pipelines
- Train end users: Create documentation and training videos
- Set up monitoring: Application Insights and usage analytics
- 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!
Discussion