@memberjunction/external-change-detection 2.32.1 → 2.33.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.
Files changed (2) hide show
  1. package/README.md +243 -0
  2. package/package.json +5 -5
package/README.md ADDED
@@ -0,0 +1,243 @@
1
+ # MemberJunction External Change Detection
2
+
3
+ A powerful library for detecting and reconciling changes made to entities by external systems or integrations in MemberJunction applications.
4
+
5
+ ## Overview
6
+
7
+ The `@memberjunction/external-change-detection` package provides functionality to detect when records in your MemberJunction entities have been modified by external systems, third-party integrations, or direct database changes that bypass the MemberJunction application logic. This helps maintain data integrity and ensures that your application can react appropriately to external modifications.
8
+
9
+ ## Key Features
10
+
11
+ - Detect external changes to entity records
12
+ - Compare current state with previous snapshots
13
+ - Generate detailed change reports
14
+ - Support for field-level change detection
15
+ - Configurable change detection criteria
16
+ - Ability to replay/apply detected changes
17
+ - Built-in optimization for large datasets
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install @memberjunction/external-change-detection
23
+ ```
24
+
25
+ ## Dependencies
26
+
27
+ This package relies on the following MemberJunction packages:
28
+ - `@memberjunction/core`
29
+ - `@memberjunction/core-entities`
30
+ - `@memberjunction/global`
31
+ - `@memberjunction/sqlserver-dataprovider`
32
+
33
+ ## Basic Usage
34
+
35
+ ```typescript
36
+ import { ExternalChangeDetector } from '@memberjunction/external-change-detection';
37
+ import { User } from '@memberjunction/core-entities';
38
+
39
+ async function detectChanges() {
40
+ // Create change detector instance
41
+ const detector = new ExternalChangeDetector();
42
+
43
+ // Run detection for the User entity
44
+ const changes = await detector.detectChanges({
45
+ entityName: 'User',
46
+ captureTimeLimit: 30, // minutes
47
+ });
48
+
49
+ // Process detected changes
50
+ console.log(`Detected ${changes.length} changes in User entity`);
51
+
52
+ // Replay changes if needed
53
+ if (changes.length > 0) {
54
+ await detector.replayChanges(changes);
55
+ }
56
+ }
57
+
58
+ detectChanges();
59
+ ```
60
+
61
+ ## Eligible Entities
62
+
63
+ Not all entities support external change detection. For an entity to be eligible for change detection:
64
+
65
+ 1. The entity must have a TrackChanges property set to true in the metadata
66
+ 2. The entity must have a LastUpdated or LastModifiedDate field
67
+ 3. The entity must have the required fields for tracking history
68
+
69
+ You can check if an entity is eligible using:
70
+
71
+ ```typescript
72
+ import { ExternalChangeDetector } from '@memberjunction/external-change-detection';
73
+
74
+ const detector = new ExternalChangeDetector();
75
+ const isEligible = await detector.isEntityEligibleForChangeDetection('User');
76
+
77
+ console.log(`User entity is eligible for change detection: ${isEligible}`);
78
+ ```
79
+
80
+ ## Detecting Changes
81
+
82
+ ### Simple Detection
83
+
84
+ ```typescript
85
+ import { ExternalChangeDetector } from '@memberjunction/external-change-detection';
86
+
87
+ const detector = new ExternalChangeDetector();
88
+ const changes = await detector.detectChanges({
89
+ entityName: 'Customer',
90
+ captureTimeLimit: 60 // Look back 60 minutes
91
+ });
92
+ ```
93
+
94
+ ### Filtering by Record IDs
95
+
96
+ ```typescript
97
+ import { ExternalChangeDetector } from '@memberjunction/external-change-detection';
98
+
99
+ const detector = new ExternalChangeDetector();
100
+ const changes = await detector.detectChanges({
101
+ entityName: 'Product',
102
+ recordIDs: [1001, 1002, 1003], // Only check these specific records
103
+ captureTimeLimit: 24 * 60 // Look back 24 hours
104
+ });
105
+ ```
106
+
107
+ ### Setting Change Criteria
108
+
109
+ ```typescript
110
+ import { ExternalChangeDetector, ExternalChangeDetectorCriteria } from '@memberjunction/external-change-detection';
111
+
112
+ const criteria: ExternalChangeDetectorCriteria = {
113
+ entityName: 'Order',
114
+ captureTimeLimit: 120, // 2 hours
115
+ includeFieldNames: ['Status', 'TotalAmount', 'CustomerID'], // Only check these fields
116
+ excludeFieldNames: ['UpdatedBy', 'InternalNotes'] // Ignore changes to these fields
117
+ };
118
+
119
+ const detector = new ExternalChangeDetector();
120
+ const changes = await detector.detectChanges(criteria);
121
+ ```
122
+
123
+ ## Replaying Changes
124
+
125
+ Once changes are detected, you can replay or apply them through the MemberJunction application to ensure that all business logic is properly executed:
126
+
127
+ ```typescript
128
+ import { ExternalChangeDetector } from '@memberjunction/external-change-detection';
129
+
130
+ async function syncChanges() {
131
+ const detector = new ExternalChangeDetector();
132
+
133
+ // Detect changes
134
+ const changes = await detector.detectChanges({
135
+ entityName: 'Invoice',
136
+ captureTimeLimit: 720 // 12 hours
137
+ });
138
+
139
+ if (changes.length > 0) {
140
+ // Apply the detected changes through MemberJunction
141
+ const results = await detector.replayChanges(changes);
142
+
143
+ // Log results
144
+ console.log(`Applied ${results.successCount} changes successfully`);
145
+ console.log(`Failed to apply ${results.failureCount} changes`);
146
+
147
+ if (results.failureCount > 0) {
148
+ console.error('Failures:', results.failures);
149
+ }
150
+ }
151
+ }
152
+ ```
153
+
154
+ ## Return Types
155
+
156
+ ### ExternalChangeResult
157
+
158
+ ```typescript
159
+ interface ExternalChangeResult {
160
+ entityName: string;
161
+ recordID: number;
162
+ fieldChanges: ExternalFieldChange[];
163
+ errorMessage?: string;
164
+ }
165
+ ```
166
+
167
+ ### ExternalFieldChange
168
+
169
+ ```typescript
170
+ interface ExternalFieldChange {
171
+ fieldName: string;
172
+ oldValue: any;
173
+ newValue: any;
174
+ }
175
+ ```
176
+
177
+ ### ReplayChangesResult
178
+
179
+ ```typescript
180
+ interface ReplayChangesResult {
181
+ successCount: number;
182
+ failureCount: number;
183
+ successes: ReplayChangeSuccess[];
184
+ failures: ReplayChangeFailure[];
185
+ }
186
+ ```
187
+
188
+ ## Server-Side Usage
189
+
190
+ This library is primarily intended for server-side applications, often running as scheduled jobs or services that periodically check for external changes and reconcile them.
191
+
192
+ Example of setting up a scheduled check:
193
+
194
+ ```typescript
195
+ import { ExternalChangeDetector } from '@memberjunction/external-change-detection';
196
+ import { EntityInfo } from '@memberjunction/core';
197
+
198
+ async function scheduleChangeDetection() {
199
+ const detector = new ExternalChangeDetector();
200
+
201
+ // Get all entities that support change detection
202
+ const metadata = new EntityInfo();
203
+ const entities = await metadata.getEntitiesWithTrackChanges();
204
+
205
+ // Check each eligible entity
206
+ for (const entity of entities) {
207
+ try {
208
+ const isEligible = await detector.isEntityEligibleForChangeDetection(entity.Name);
209
+
210
+ if (isEligible) {
211
+ console.log(`Checking ${entity.Name} for external changes...`);
212
+
213
+ const changes = await detector.detectChanges({
214
+ entityName: entity.Name,
215
+ captureTimeLimit: 24 * 60 // Daily check
216
+ });
217
+
218
+ if (changes.length > 0) {
219
+ await detector.replayChanges(changes);
220
+ console.log(`Applied ${changes.length} changes to ${entity.Name}`);
221
+ }
222
+ }
223
+ } catch (error) {
224
+ console.error(`Error processing ${entity.Name}:`, error);
225
+ }
226
+ }
227
+ }
228
+ ```
229
+
230
+ ## Performance Considerations
231
+
232
+ For large entities with many records, change detection can be resource-intensive. Consider using these optimization strategies:
233
+
234
+ 1. Use smaller `captureTimeLimit` values
235
+ 2. Filter by specific `recordIDs` when possible
236
+ 3. Use `includeFieldNames` to limit which fields are checked
237
+ 4. Schedule detection jobs during off-peak hours
238
+ 5. Process entities in batches
239
+ 6. Implement error handling and retry logic
240
+
241
+ ## License
242
+
243
+ ISC
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/external-change-detection",
3
- "version": "2.32.1",
3
+ "version": "2.33.0",
4
4
  "description": "Library used by server side applications to determine if changes have been made to entities by external systems/integrations",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -19,9 +19,9 @@
19
19
  "typescript": "^5.4.5"
20
20
  },
21
21
  "dependencies": {
22
- "@memberjunction/core": "2.32.1",
23
- "@memberjunction/core-entities": "2.32.1",
24
- "@memberjunction/global": "2.32.1",
25
- "@memberjunction/sqlserver-dataprovider": "2.32.1"
22
+ "@memberjunction/core": "2.33.0",
23
+ "@memberjunction/core-entities": "2.33.0",
24
+ "@memberjunction/global": "2.33.0",
25
+ "@memberjunction/sqlserver-dataprovider": "2.33.0"
26
26
  }
27
27
  }