@khester/create-dynamics-app 1.0.8 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/create-dynamics-app.js +1 -1
- package/dist/index.js +140 -15
- package/dist/index.js.map +1 -1
- package/dist/utils/consultingHelpers.d.ts +13 -0
- package/dist/utils/consultingHelpers.d.ts.map +1 -0
- package/dist/utils/consultingHelpers.js +569 -0
- package/dist/utils/consultingHelpers.js.map +1 -0
- package/dist/utils/copyTemplate.d.ts.map +1 -1
- package/dist/utils/copyTemplate.js.map +1 -1
- package/dist/utils/initGit.d.ts.map +1 -1
- package/dist/utils/initGit.js.map +1 -1
- package/dist/utils/installDependencies.d.ts.map +1 -1
- package/dist/utils/installDependencies.js +3 -2
- package/dist/utils/installDependencies.js.map +1 -1
- package/dist/utils/updatePackageJson.d.ts +1 -1
- package/dist/utils/updatePackageJson.d.ts.map +1 -1
- package/dist/utils/updatePackageJson.js +11 -1
- package/dist/utils/updatePackageJson.js.map +1 -1
- package/package.json +1 -1
- package/templates/dynamics-365-starter/INTEGRATION_TEST_RESULTS.md +302 -0
- package/templates/dynamics-365-starter/PHASE_4_COMPLETION_SUMMARY.md +305 -0
- package/templates/dynamics-365-starter/README.md +566 -137
- package/templates/dynamics-365-starter/deployment/QUICKSTART-MAC.md +507 -0
- package/templates/dynamics-365-starter/deployment/QUICKSTART-WINDOWS.md +372 -0
- package/templates/dynamics-365-starter/deployment/README.md +484 -0
- package/templates/dynamics-365-starter/deployment/pipelines/README.md +375 -0
- package/templates/dynamics-365-starter/deployment/pipelines/azure-pipelines.yml +330 -0
- package/templates/dynamics-365-starter/deployment/pipelines/github-actions.yml +422 -0
- package/templates/dynamics-365-starter/deployment/pipelines/jenkins.groovy +636 -0
- package/templates/dynamics-365-starter/deployment/scripts/deploy.ps1 +417 -0
- package/templates/dynamics-365-starter/deployment/scripts/deploy.sh +582 -0
- package/templates/dynamics-365-starter/deployment/scripts/team-onboarding.ps1 +486 -0
- package/templates/dynamics-365-starter/deployment/scripts/team-onboarding.sh +567 -0
- package/templates/dynamics-365-starter/deployment/scripts/validate-setup.ps1 +703 -0
- package/templates/dynamics-365-starter/deployment/scripts/validate-setup.sh +671 -0
- package/templates/dynamics-365-starter/docs/ARCHITECTURE_OVERVIEW.md +506 -0
- package/templates/dynamics-365-starter/docs/BEST_PRACTICES.md +723 -0
- package/templates/dynamics-365-starter/docs/MIGRATION_GUIDE.md +447 -0
- package/templates/dynamics-365-starter/docs/team-standards/README.md +273 -0
- package/templates/dynamics-365-starter/docs/team-standards/client-onboarding.md +577 -0
- package/templates/dynamics-365-starter/docs/team-standards/code-review-checklist.md +359 -0
- package/templates/dynamics-365-starter/docs/team-standards/coding-standards.md +700 -0
- package/templates/dynamics-365-starter/docs/team-standards/cross-platform-team-guide.md +736 -0
- package/templates/dynamics-365-starter/docs/team-standards/development-workflows.md +727 -0
- package/templates/dynamics-365-starter/docs/troubleshooting/common-errors.md +758 -0
- package/templates/dynamics-365-starter/docs/troubleshooting/platform-specific-issues.md +878 -0
- package/templates/dynamics-365-starter/package.json +22 -1
- package/templates/dynamics-365-starter/public/index.html +8 -11
- package/templates/dynamics-365-starter/scripts/custom-build.js +255 -0
- package/templates/dynamics-365-starter/src/client-project-template/README.md +234 -0
- package/templates/dynamics-365-starter/src/client-project-template/config/client.template.json +114 -0
- package/templates/dynamics-365-starter/src/client-project-template/config/environments/template.json +186 -0
- package/templates/dynamics-365-starter/src/client-project-template/scripts/client-setup.js +667 -0
- package/templates/dynamics-365-starter/src/components/AccountForm.css +71 -0
- package/templates/dynamics-365-starter/src/components/AccountForm.tsx +541 -0
- package/templates/dynamics-365-starter/src/components/AccountManagement.css +86 -0
- package/templates/dynamics-365-starter/src/components/AccountManagement.tsx +370 -0
- package/templates/dynamics-365-starter/src/components/ContactForm.tsx +149 -63
- package/templates/dynamics-365-starter/src/components/ContactManagement.tsx +153 -63
- package/templates/dynamics-365-starter/src/components/Logging/LogDialog.tsx +291 -0
- package/templates/dynamics-365-starter/src/components/Logging/LoggingContext.tsx +166 -0
- package/templates/dynamics-365-starter/src/components/Logging/LoggingDebugPanel.css +192 -0
- package/templates/dynamics-365-starter/src/components/Logging/LoggingDebugPanel.tsx +177 -0
- package/templates/dynamics-365-starter/src/components/Logging/LoggingProvider.tsx +3 -0
- package/templates/dynamics-365-starter/src/components/Logging/logger.ts +193 -0
- package/templates/dynamics-365-starter/src/constants/account.ts +410 -0
- package/templates/dynamics-365-starter/src/constants/contact.ts +362 -0
- package/templates/dynamics-365-starter/src/examples/README.md +52 -0
- package/templates/dynamics-365-starter/src/examples/component-examples/opportunity-management.tsx +625 -0
- package/templates/dynamics-365-starter/src/examples/entity-examples/opportunity-model.ts +545 -0
- package/templates/dynamics-365-starter/src/examples/integration-examples/custom-pcf-wrapper.tsx +722 -0
- package/templates/dynamics-365-starter/src/examples/workflow-examples/sales-workflow.ts +662 -0
- package/templates/dynamics-365-starter/src/index.tsx +107 -19
- package/templates/dynamics-365-starter/src/models/Account.ts +480 -0
- package/templates/dynamics-365-starter/src/models/BaseEntity.ts +204 -0
- package/templates/dynamics-365-starter/src/models/Contact.ts +580 -0
- package/templates/dynamics-365-starter/src/page-templates/EntityDashboard.tsx +519 -0
- package/templates/dynamics-365-starter/src/page-templates/EntityDetailPage.tsx +456 -0
- package/templates/dynamics-365-starter/src/page-templates/EntityListPage.tsx +406 -0
- package/templates/dynamics-365-starter/src/page-templates/RelatedEntitiesPage.tsx +578 -0
- package/templates/dynamics-365-starter/src/page-templates/SearchPage.tsx +629 -0
- package/templates/dynamics-365-starter/src/pcf/ContactControlWrapper.tsx +75 -22
- package/templates/dynamics-365-starter/src/pcf/MultiEntityControlWrapper.tsx +205 -0
- package/templates/dynamics-365-starter/src/providers/DynamicsProvider.tsx +297 -80
- package/templates/dynamics-365-starter/src/services/MockApiService.ts +260 -0
- package/templates/dynamics-365-starter/src/services/ServiceFactory.ts +65 -0
- package/templates/dynamics-365-starter/src/services/XrmApiService.ts +213 -0
- package/templates/dynamics-365-starter/src/styles/index.css +74 -7
- package/templates/dynamics-365-starter/tools/entity-generator/index.js +168 -0
- package/templates/dynamics-365-starter/tools/entity-generator/templates/constants.template.ts +124 -0
- package/templates/dynamics-365-starter/tools/entity-generator/templates/form.template.css +283 -0
- package/templates/dynamics-365-starter/tools/entity-generator/templates/form.template.tsx +275 -0
- package/templates/dynamics-365-starter/tools/entity-generator/templates/management.template.css +204 -0
- package/templates/dynamics-365-starter/tools/entity-generator/templates/management.template.tsx +413 -0
- package/templates/dynamics-365-starter/tools/entity-generator/templates/model.template.ts +250 -0
- package/templates/dynamics-365-starter/tools/metadata-sync/d365-client.js +410 -0
- package/templates/dynamics-365-starter/tools/metadata-sync/index.js +512 -0
- package/templates/dynamics-365-starter/tools/metadata-sync/type-generator.js +675 -0
- package/templates/dynamics-365-starter/tsconfig.json +11 -8
- package/templates/dynamics-365-starter/webpack.config.js +8 -9
- package/templates/power-pages-starter/README.md +7 -1
- package/templates/power-pages-starter/public/index.html +8 -11
- package/templates/power-pages-starter/src/components/ContactForm.tsx +60 -41
- package/templates/power-pages-starter/src/index.tsx +3 -3
- package/templates/power-pages-starter/src/providers/PowerPagesProvider.tsx +46 -23
- package/templates/power-pages-starter/tsconfig.json +3 -9
- package/templates/power-pages-starter/webpack.config.js +8 -3
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
# Architecture Overview - Dynamics 365 Template
|
|
2
|
+
|
|
3
|
+
## Executive Summary
|
|
4
|
+
|
|
5
|
+
The Enhanced Dynamics 365 Template provides a comprehensive, enterprise-grade foundation for
|
|
6
|
+
building sophisticated React applications that integrate seamlessly with Microsoft Dynamics 365.
|
|
7
|
+
Built with TypeScript, modern React patterns, and Fluent UI v8, this template delivers
|
|
8
|
+
production-ready code with advanced features including entity models, service layer abstraction,
|
|
9
|
+
comprehensive logging, and intelligent environment detection.
|
|
10
|
+
|
|
11
|
+
## High-Level Architecture
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
15
|
+
│ Dynamics 365 Template │
|
|
16
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
17
|
+
│ Presentation Layer (React Components) │
|
|
18
|
+
│ ├── Management Components (Account/Contact/Opportunity) │
|
|
19
|
+
│ ├── Form Components (Validation & Submission) │
|
|
20
|
+
│ ├── PCF Wrappers (Custom Control Integration) │
|
|
21
|
+
│ └── UI Components (Fluent UI v8) │
|
|
22
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
23
|
+
│ Context & Providers │
|
|
24
|
+
│ ├── DynamicsProvider (API Service Context) │
|
|
25
|
+
│ ├── LoggingProvider (Centralized Logging) │
|
|
26
|
+
│ └── React Context API (State Management) │
|
|
27
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
28
|
+
│ Business Logic Layer │
|
|
29
|
+
│ ├── Entity Models (Account, Contact, BaseEntity) │
|
|
30
|
+
│ ├── Constants (Field Definitions & Metadata) │
|
|
31
|
+
│ ├── Validation (Client-side & Business Rules) │
|
|
32
|
+
│ └── Workflows (Multi-entity Business Processes) │
|
|
33
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
34
|
+
│ Service Layer │
|
|
35
|
+
│ ├── ServiceFactory (Environment Detection) │
|
|
36
|
+
│ ├── XrmApiService (Production D365 Integration) │
|
|
37
|
+
│ ├── MockApiService (Development & Testing) │
|
|
38
|
+
│ └── IApiService (Common Interface) │
|
|
39
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
40
|
+
│ Infrastructure Layer │
|
|
41
|
+
│ ├── Logger (Structured Logging System) │
|
|
42
|
+
│ ├── Error Handling (Layered Error Management) │
|
|
43
|
+
│ ├── Build System (Custom Webpack Configuration) │
|
|
44
|
+
│ └── Deployment (Web Resources, PCF, Custom Pages) │
|
|
45
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
46
|
+
│
|
|
47
|
+
┌─────────▼─────────┐
|
|
48
|
+
│ Dynamics 365 │
|
|
49
|
+
│ │
|
|
50
|
+
│ ├── Web API │
|
|
51
|
+
│ ├── Xrm Object │
|
|
52
|
+
│ ├── FetchXML │
|
|
53
|
+
│ └── Custom APIs │
|
|
54
|
+
└───────────────────┘
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Core Architectural Patterns
|
|
58
|
+
|
|
59
|
+
### 1. Entity Model Pattern
|
|
60
|
+
|
|
61
|
+
**Purpose**: Provide a consistent, type-safe interface for Dynamics 365 entity operations with
|
|
62
|
+
built-in validation and logging.
|
|
63
|
+
|
|
64
|
+
**Implementation**:
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
export class Account extends BaseEntity implements IAccount {
|
|
68
|
+
// Static CRUD operations
|
|
69
|
+
public static async create(apiService: IApiService, account: Account): Promise<Account>;
|
|
70
|
+
public static async retrieveByName(apiService: IApiService, name: string): Promise<Account[]>;
|
|
71
|
+
public static async update(
|
|
72
|
+
apiService: IApiService,
|
|
73
|
+
id: string,
|
|
74
|
+
account: Account
|
|
75
|
+
): Promise<Account>;
|
|
76
|
+
public static async delete(apiService: IApiService, id: string): Promise<void>;
|
|
77
|
+
|
|
78
|
+
// Instance validation
|
|
79
|
+
public validate(): boolean;
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Benefits**:
|
|
84
|
+
|
|
85
|
+
- Consistent API across all entities
|
|
86
|
+
- Built-in validation and error handling
|
|
87
|
+
- Comprehensive logging for all operations
|
|
88
|
+
- Type safety with TypeScript
|
|
89
|
+
- Reusable patterns for custom entities
|
|
90
|
+
|
|
91
|
+
### 2. Service Factory Pattern
|
|
92
|
+
|
|
93
|
+
**Purpose**: Automatically detect the runtime environment and provide the appropriate API service
|
|
94
|
+
implementation.
|
|
95
|
+
|
|
96
|
+
**Implementation**:
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
export class ServiceFactory {
|
|
100
|
+
public static createApiService(Xrm?: any): IApiService {
|
|
101
|
+
if (this.isMockEnvironment) {
|
|
102
|
+
return new MockApiService();
|
|
103
|
+
}
|
|
104
|
+
return new XrmApiService(Xrm);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
public static get isMockEnvironment(): boolean {
|
|
108
|
+
return window.location.hostname === 'localhost';
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Benefits**:
|
|
114
|
+
|
|
115
|
+
- Seamless development-to-production workflow
|
|
116
|
+
- No code changes required between environments
|
|
117
|
+
- Automatic fallback mechanisms
|
|
118
|
+
- Easy testing with mock services
|
|
119
|
+
|
|
120
|
+
### 3. Provider Pattern for Context Management
|
|
121
|
+
|
|
122
|
+
**Purpose**: Manage API services and logging context throughout the React component tree.
|
|
123
|
+
|
|
124
|
+
**Implementation**:
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
export const DynamicsProvider: React.FC<DynamicsProviderProps> = ({
|
|
128
|
+
children,
|
|
129
|
+
customApiService
|
|
130
|
+
}) => {
|
|
131
|
+
const apiService = useMemo(() => {
|
|
132
|
+
return customApiService || ServiceFactory.createApiService();
|
|
133
|
+
}, [customApiService]);
|
|
134
|
+
|
|
135
|
+
return (
|
|
136
|
+
<DynamicsContext.Provider value={{ apiService, environmentType, isEnvironmentMock }}>
|
|
137
|
+
{children}
|
|
138
|
+
</DynamicsContext.Provider>
|
|
139
|
+
);
|
|
140
|
+
};
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**Benefits**:
|
|
144
|
+
|
|
145
|
+
- Clean dependency injection
|
|
146
|
+
- Easy testing with custom services
|
|
147
|
+
- Centralized configuration
|
|
148
|
+
- Type-safe context consumption
|
|
149
|
+
|
|
150
|
+
### 4. Layered Error Handling
|
|
151
|
+
|
|
152
|
+
**Purpose**: Provide comprehensive error management from API calls through user interface feedback.
|
|
153
|
+
|
|
154
|
+
**Implementation**:
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
// Layer 1: API Service Level
|
|
158
|
+
class XrmApiService {
|
|
159
|
+
async createRecord(entityName: string, record: any): Promise<any> {
|
|
160
|
+
try {
|
|
161
|
+
return await this.xrm.WebApi.createRecord(entityName, record);
|
|
162
|
+
} catch (error) {
|
|
163
|
+
Logger.error(`API operation failed`, 'XrmApiService.createRecord', error);
|
|
164
|
+
throw new Error(`Unable to create ${entityName}: ${error}`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Layer 2: Entity Model Level
|
|
170
|
+
class Account {
|
|
171
|
+
public static async create(apiService: IApiService, account: Account): Promise<Account> {
|
|
172
|
+
try {
|
|
173
|
+
account.validate(); // Business logic validation
|
|
174
|
+
return await this.createEntity(apiService, account, AccountConstants.EntityCollectionName);
|
|
175
|
+
} catch (error) {
|
|
176
|
+
Logger.error('Account creation failed', 'Account.create', error);
|
|
177
|
+
throw error; // Re-throw for component handling
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Layer 3: Component Level
|
|
183
|
+
const AccountForm: React.FC = () => {
|
|
184
|
+
const [error, setError] = useState<string>('');
|
|
185
|
+
|
|
186
|
+
const handleSubmit = async () => {
|
|
187
|
+
try {
|
|
188
|
+
await Account.create(apiService, formData);
|
|
189
|
+
onSuccess();
|
|
190
|
+
} catch (error) {
|
|
191
|
+
setError(getUserFriendlyErrorMessage(error));
|
|
192
|
+
Logger.error('Form submission failed', 'AccountForm.handleSubmit', error);
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
};
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### 5. Comprehensive Logging Architecture
|
|
199
|
+
|
|
200
|
+
**Purpose**: Provide structured, queryable logging for debugging, monitoring, and business
|
|
201
|
+
intelligence.
|
|
202
|
+
|
|
203
|
+
**Implementation**:
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
export class Logger {
|
|
207
|
+
// User action tracking
|
|
208
|
+
static userAction(action: string, data: any, context: string): void;
|
|
209
|
+
|
|
210
|
+
// API operation logging
|
|
211
|
+
static apiOperation(operation: string, entity: string, data: any, context: string): void;
|
|
212
|
+
|
|
213
|
+
// Performance monitoring
|
|
214
|
+
static timing(operation: string, startTime: number, context: string): void;
|
|
215
|
+
|
|
216
|
+
// Business rule validation
|
|
217
|
+
static validation(entity: string, errors: string[], context: string): void;
|
|
218
|
+
|
|
219
|
+
// FetchXML query logging
|
|
220
|
+
static fetchXml(query: string, context: string): void;
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
**Log Categories**:
|
|
225
|
+
|
|
226
|
+
- **User Actions**: Button clicks, form submissions, navigation
|
|
227
|
+
- **API Operations**: CRUD operations, custom API calls
|
|
228
|
+
- **Performance**: Operation timing, slow queries
|
|
229
|
+
- **Validation**: Business rule enforcement, data validation
|
|
230
|
+
- **Errors**: Exception details with context
|
|
231
|
+
- **Debug**: Development troubleshooting information
|
|
232
|
+
|
|
233
|
+
## Technology Stack
|
|
234
|
+
|
|
235
|
+
### Frontend Framework
|
|
236
|
+
|
|
237
|
+
- **React 18**: Modern component architecture with hooks
|
|
238
|
+
- **TypeScript**: Full type safety and IntelliSense support
|
|
239
|
+
- **Fluent UI v8**: Microsoft's design system for consistency
|
|
240
|
+
|
|
241
|
+
### Build & Development
|
|
242
|
+
|
|
243
|
+
- **Webpack 5**: Custom configuration optimized for D365
|
|
244
|
+
- **ESLint**: Code quality and consistency enforcement
|
|
245
|
+
- **CSS Modules**: Scoped styling to prevent conflicts
|
|
246
|
+
|
|
247
|
+
### Dynamics 365 Integration
|
|
248
|
+
|
|
249
|
+
- **Xrm.WebApi**: Direct integration with D365 Web API
|
|
250
|
+
- **FetchXML**: Optimized queries for data retrieval
|
|
251
|
+
- **PCF Framework**: Custom control development support
|
|
252
|
+
|
|
253
|
+
## Deployment Architecture
|
|
254
|
+
|
|
255
|
+
### Web Resources Deployment
|
|
256
|
+
|
|
257
|
+
```
|
|
258
|
+
Dynamics 365 Environment
|
|
259
|
+
├── Web Resources
|
|
260
|
+
│ ├── Script (JScript): /new_scripts/main.js (726 KB)
|
|
261
|
+
│ ├── Style Sheet (CSS): /new_styles/app.css
|
|
262
|
+
│ └── Web Page (HTML): /new_pages/index.html
|
|
263
|
+
├── Security Roles
|
|
264
|
+
│ ├── Read permissions for entities
|
|
265
|
+
│ ├── Write permissions for data operations
|
|
266
|
+
│ └── Web resource access permissions
|
|
267
|
+
└── Custom Pages/Forms
|
|
268
|
+
├── Account Management Page
|
|
269
|
+
├── Contact Management Page
|
|
270
|
+
└── Multi-Entity Dashboard
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### PCF Control Deployment
|
|
274
|
+
|
|
275
|
+
```
|
|
276
|
+
PCF Solution Package
|
|
277
|
+
├── Control Manifest (ControlManifest.Input.xml)
|
|
278
|
+
├── TypeScript Sources (/src/)
|
|
279
|
+
├── React Components (/components/)
|
|
280
|
+
├── Entity Models (/models/)
|
|
281
|
+
├── Build Output (/out/controls/)
|
|
282
|
+
└── Solution Package (.zip)
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Custom Pages Deployment
|
|
286
|
+
|
|
287
|
+
```
|
|
288
|
+
Model-Driven App
|
|
289
|
+
├── Custom Pages
|
|
290
|
+
│ ├── Account Management (accountmanagement.html)
|
|
291
|
+
│ ├── Contact Dashboard (contactdashboard.html)
|
|
292
|
+
│ └── Opportunity Pipeline (opportunitypipeline.html)
|
|
293
|
+
├── Navigation
|
|
294
|
+
│ ├── Sitemap entries
|
|
295
|
+
│ └── Custom navigation items
|
|
296
|
+
└── Security
|
|
297
|
+
├── Security roles assignment
|
|
298
|
+
└── Field-level security
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## Data Flow Architecture
|
|
302
|
+
|
|
303
|
+
### 1. User Interaction Flow
|
|
304
|
+
|
|
305
|
+
```
|
|
306
|
+
User Action → Component Event Handler → Entity Model Method → API Service → D365 Web API
|
|
307
|
+
↓ ↓ ↓ ↓
|
|
308
|
+
State Update ← Component Update ← Response Handler ← HTTP Response
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### 2. Logging Flow
|
|
312
|
+
|
|
313
|
+
```
|
|
314
|
+
Operation → Logger Method → Log Entry Creation → Console Output
|
|
315
|
+
↓ ↓ ↓ ↓
|
|
316
|
+
Context Data → Structured → Local Storage → Debug Panel
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### 3. Error Handling Flow
|
|
320
|
+
|
|
321
|
+
```
|
|
322
|
+
API Error → Service Layer → Entity Model → Component Handler → User Feedback
|
|
323
|
+
↓ ↓ ↓ ↓ ↓
|
|
324
|
+
Logger → Structured Log → Context Data → Error State → UI Display
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
## Security Architecture
|
|
328
|
+
|
|
329
|
+
### Authentication & Authorization
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
// Permission checking before operations
|
|
333
|
+
const checkPermissions = async (operation: string, entityName: string): Promise<boolean> => {
|
|
334
|
+
try {
|
|
335
|
+
const userPrivileges = await Xrm.Utility.getGlobalContext().getUserPrivileges();
|
|
336
|
+
return userPrivileges.some(
|
|
337
|
+
(privilege) => privilege.privilegeName === `prv${operation}${entityName}`
|
|
338
|
+
);
|
|
339
|
+
} catch {
|
|
340
|
+
return false; // Fail secure
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### Input Validation & Sanitization
|
|
346
|
+
|
|
347
|
+
```typescript
|
|
348
|
+
// Multi-layer validation
|
|
349
|
+
class BaseEntity {
|
|
350
|
+
// XSS prevention
|
|
351
|
+
protected static escapeXml(value: string): string;
|
|
352
|
+
|
|
353
|
+
// Input length enforcement
|
|
354
|
+
protected static validateInput(input: string, maxLength: number): string;
|
|
355
|
+
|
|
356
|
+
// SQL injection prevention in FetchXML
|
|
357
|
+
protected static buildFetchXml(entityName: string, attributes: string[], filter?: string): string;
|
|
358
|
+
}
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
### Data Privacy
|
|
362
|
+
|
|
363
|
+
- **Field-level security**: Respect D365 security model
|
|
364
|
+
- **Audit logging**: Track all data access and modifications
|
|
365
|
+
- **Encryption**: Leverage D365's built-in encryption
|
|
366
|
+
- **Access control**: Role-based permissions enforcement
|
|
367
|
+
|
|
368
|
+
## Performance Architecture
|
|
369
|
+
|
|
370
|
+
### Bundle Optimization
|
|
371
|
+
|
|
372
|
+
- **Production bundle**: 726 KB (optimized)
|
|
373
|
+
- **Development bundle**: 3.95 MB (with debugging)
|
|
374
|
+
- **Code splitting**: Automatic vendor chunk separation
|
|
375
|
+
- **Tree shaking**: Eliminate unused code
|
|
376
|
+
|
|
377
|
+
### Runtime Performance
|
|
378
|
+
|
|
379
|
+
```typescript
|
|
380
|
+
// Efficient data loading
|
|
381
|
+
const loadAccountsOptimized = async () => {
|
|
382
|
+
// Only load required fields
|
|
383
|
+
const fetchXml = Account.buildFetchXml(
|
|
384
|
+
'account',
|
|
385
|
+
['accountid', 'name', 'emailaddress1'], // Minimal field set
|
|
386
|
+
filter,
|
|
387
|
+
{ attribute: 'createdon', descending: true }
|
|
388
|
+
);
|
|
389
|
+
|
|
390
|
+
// Implement pagination
|
|
391
|
+
return await Account.retrieveEntitiesByFilter(apiService, 'accounts', fetchXml, Account);
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
// React optimization
|
|
395
|
+
const AccountManagement = React.memo(() => {
|
|
396
|
+
// Memoized calculations
|
|
397
|
+
const filteredAccounts = useMemo(
|
|
398
|
+
() => accounts.filter((account) => account.name?.includes(searchText)),
|
|
399
|
+
[accounts, searchText]
|
|
400
|
+
);
|
|
401
|
+
|
|
402
|
+
// Callback memoization
|
|
403
|
+
const handleItemInvoked = useCallback((item: Account) => {
|
|
404
|
+
setSelectedAccount(item);
|
|
405
|
+
}, []);
|
|
406
|
+
});
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### Caching Strategy
|
|
410
|
+
|
|
411
|
+
- **Session storage**: API service instances
|
|
412
|
+
- **Memory caching**: Component state optimization
|
|
413
|
+
- **Browser caching**: Static asset optimization
|
|
414
|
+
- **D365 caching**: Leverage platform caching
|
|
415
|
+
|
|
416
|
+
## Scalability Considerations
|
|
417
|
+
|
|
418
|
+
### Horizontal Scaling
|
|
419
|
+
|
|
420
|
+
- **Modular architecture**: Easy to split into micro-frontends
|
|
421
|
+
- **Service abstraction**: Support for multiple D365 environments
|
|
422
|
+
- **Component isolation**: Independent development and deployment
|
|
423
|
+
|
|
424
|
+
### Vertical Scaling
|
|
425
|
+
|
|
426
|
+
- **Lazy loading**: Load components on demand
|
|
427
|
+
- **Code splitting**: Reduce initial bundle size
|
|
428
|
+
- **Efficient queries**: Optimized FetchXML generation
|
|
429
|
+
- **Memory management**: Proper cleanup and garbage collection
|
|
430
|
+
|
|
431
|
+
## Monitoring & Observability
|
|
432
|
+
|
|
433
|
+
### Application Monitoring
|
|
434
|
+
|
|
435
|
+
```typescript
|
|
436
|
+
// Performance monitoring
|
|
437
|
+
const performanceObserver = new PerformanceObserver((list) => {
|
|
438
|
+
for (const entry of list.getEntries()) {
|
|
439
|
+
if (entry.duration > 1000) {
|
|
440
|
+
Logger.performance('Slow operation detected', {
|
|
441
|
+
name: entry.name,
|
|
442
|
+
duration: entry.duration,
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
// Error tracking
|
|
449
|
+
window.addEventListener('error', (event) => {
|
|
450
|
+
Logger.error('Unhandled error', 'GlobalErrorHandler', {
|
|
451
|
+
message: event.error?.message,
|
|
452
|
+
stack: event.error?.stack,
|
|
453
|
+
filename: event.filename,
|
|
454
|
+
lineno: event.lineno,
|
|
455
|
+
});
|
|
456
|
+
});
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
### Business Intelligence
|
|
460
|
+
|
|
461
|
+
- **User action tracking**: All user interactions logged
|
|
462
|
+
- **Performance metrics**: Operation timing and success rates
|
|
463
|
+
- **Error analytics**: Categorized error patterns
|
|
464
|
+
- **Usage patterns**: Feature adoption and user workflows
|
|
465
|
+
|
|
466
|
+
## Future Architecture Considerations
|
|
467
|
+
|
|
468
|
+
### Microservices Ready
|
|
469
|
+
|
|
470
|
+
- **Service abstraction**: Easy to split into separate services
|
|
471
|
+
- **API gateway**: Centralized API management
|
|
472
|
+
- **Event-driven**: Support for event sourcing patterns
|
|
473
|
+
|
|
474
|
+
### Cloud Native
|
|
475
|
+
|
|
476
|
+
- **Container support**: Docker-ready build process
|
|
477
|
+
- **CI/CD integration**: Automated testing and deployment
|
|
478
|
+
- **Monitoring**: Application Insights integration
|
|
479
|
+
- **Scaling**: Kubernetes deployment support
|
|
480
|
+
|
|
481
|
+
### Advanced Features
|
|
482
|
+
|
|
483
|
+
- **Real-time updates**: SignalR integration capability
|
|
484
|
+
- **Offline support**: Progressive Web App features
|
|
485
|
+
- **Mobile optimization**: Responsive design and touch support
|
|
486
|
+
- **AI integration**: Power Platform AI Builder support
|
|
487
|
+
|
|
488
|
+
## Conclusion
|
|
489
|
+
|
|
490
|
+
The Enhanced Dynamics 365 Template provides a robust, scalable, and maintainable foundation for
|
|
491
|
+
enterprise-grade Dynamics 365 applications. Its layered architecture, comprehensive error handling,
|
|
492
|
+
and modern development practices ensure that applications built with this template can grow and
|
|
493
|
+
evolve with changing business requirements while maintaining high standards of quality, performance,
|
|
494
|
+
and user experience.
|
|
495
|
+
|
|
496
|
+
The template's design philosophy emphasizes:
|
|
497
|
+
|
|
498
|
+
- **Developer Experience**: Modern tooling and clear patterns
|
|
499
|
+
- **Type Safety**: Full TypeScript support throughout
|
|
500
|
+
- **Maintainability**: Clean architecture and comprehensive documentation
|
|
501
|
+
- **Performance**: Optimized builds and efficient runtime execution
|
|
502
|
+
- **Security**: Multiple layers of validation and authorization
|
|
503
|
+
- **Observability**: Comprehensive logging and monitoring capabilities
|
|
504
|
+
|
|
505
|
+
This architecture serves as both a practical implementation and a reference for building
|
|
506
|
+
sophisticated Dynamics 365 integrations that meet enterprise requirements.
|