44 */
55const { BaseService } = require ( './base-service' ) ;
66const { performanceMonitor } = require ( '../performance-monitor' ) ;
7+ const { ProgressTracker } = require ( '../utils/progress-tracker' ) ;
78
89class DeploymentService extends BaseService {
910 constructor ( dependencies = { } ) {
@@ -38,6 +39,9 @@ class DeploymentService extends BaseService {
3839 async deploySolution ( config , progressCallback ) {
3940 const deploymentId = this . generateDeploymentId ( ) ;
4041
42+ // Initialize enhanced progress tracker
43+ const progressTracker = new ProgressTracker ( 'deployment' , progressCallback ) ;
44+
4145 // Start performance monitoring
4246 this . performanceMonitor . startOperation ( deploymentId , 'deployment' , {
4347 entityCount : 0 , // Will be updated when we parse the ERD
@@ -59,6 +63,7 @@ class DeploymentService extends BaseService {
5963 config : { ...config , mermaidContent : '[REDACTED]' } // Don't store full content
6064 } ) ;
6165
66+ // Legacy progress function for backward compatibility
6267 const progress = ( step , message , details = { } ) => {
6368 this . updateDeploymentStatus ( deploymentId , step , message ) ;
6469 if ( progressCallback ) {
@@ -67,26 +72,28 @@ class DeploymentService extends BaseService {
6772 } ;
6873
6974 try {
70- progress ( 'initialization' , 'Initializing deployment...' ) ;
71-
72- // Step 1: Parse ERD content
73- progress ( 'parsing' , 'Parsing ERD content...' ) ;
75+ // Step 1: Parse and validate ERD content
76+ progressTracker . startStep ( 'validation' , 'Parsing and validating ERD content...' ) ;
77+
7478 const parseResult = await this . parseERDContent ( config . mermaidContent ) ;
7579
76- // Step 2: Validate ERD content
80+ // Validate ERD content
7781 if ( this . validationService ) {
78- progress ( 'validation' , 'Validating ERD' ) ;
82+ progressTracker . updateStep ( 'validation' , 'Running ERD validation checks... ' ) ;
7983 const validationResult = await this . validationService . validateERD ( {
8084 mermaidContent : config . mermaidContent ,
8185 options : { }
8286 } ) ;
8387 if ( ! validationResult . success ) {
88+ progressTracker . failStep ( 'validation' , 'ERD validation failed' , validationResult . message ) ;
8489 throw new Error ( validationResult . message || 'Invalid ERD syntax' ) ;
8590 }
8691 }
8792
88- // Step 3: Setup Dataverse client
89- progress ( 'configuration' , 'Connecting to Dataverse...' ) ;
93+ progressTracker . completeStep ( 'validation' , 'ERD content validated successfully' ) ;
94+
95+ // Step 2: Setup Dataverse connection
96+ progressTracker . startStep ( 'publisher' , 'Connecting to Dataverse...' ) ;
9097 const dataverseConfigResult = await this . configRepository . getDataverseConfig ( ) ;
9198 const dataverseConfig = dataverseConfigResult ?. data || dataverseConfigResult ;
9299
@@ -98,8 +105,8 @@ class DeploymentService extends BaseService {
98105 keys : Object . keys ( dataverseConfig || { } )
99106 } ) ;
100107
101- // Step 4 : Ensure solution and publisher
102- progress ( 'publisher' , config . useExistingSolution ? 'Using existing solution publisher' : 'Creating publisher' ) ;
108+ // Step 3 : Ensure publisher
109+ progressTracker . updateStep ( 'publisher' , config . useExistingSolution ? 'Using existing solution publisher' : 'Creating publisher... ' ) ;
103110 const publisherResult = await this . ensurePublisher ( config , dataverseConfig ) ;
104111
105112 console . log ( '🔧 DEBUG: publisherResult:' , {
@@ -110,13 +117,18 @@ class DeploymentService extends BaseService {
110117 success : publisherResult ?. success
111118 } ) ;
112119
113- progress ( 'solution' , config . useExistingSolution ? 'Using existing solution' : 'Creating solution' ) ;
120+ progressTracker . completeStep ( 'publisher' , 'Publisher setup completed' ) ;
121+
122+ // Step 4: Ensure solution
123+ progressTracker . startStep ( 'solution' , config . useExistingSolution ? 'Using existing solution' : 'Creating solution...' ) ;
114124 // Extract the actual publisher data from the wrapped response
115125 const publisher = publisherResult ?. data || publisherResult ;
116126 const solutionResult = await this . ensureSolution ( config , publisher , dataverseConfig ) ;
117127
118128 // Extract the actual solution data from the wrapped response
119129 const solution = solutionResult ?. data || solutionResult ;
130+
131+ progressTracker . completeStep ( 'solution' , 'Solution setup completed' ) ;
120132
121133 console . log ( '🔧 DEBUG: Final solution being used:' , {
122134 uniquename : solution ?. uniquename ,
@@ -174,11 +186,9 @@ class DeploymentService extends BaseService {
174186 message : 'Deployment completed successfully'
175187 } ;
176188
177- // Step 6 : Process CDM entities if any
189+ // Step 5 : Process CDM entities if any
178190 if ( cdmEntities . length > 0 ) {
179- // If CDM entities are detected, process them as CDM entities
180- // regardless of user choice (they can't be created as custom entities anyway)
181- progress ( 'cdm' , `Adding ${ cdmEntities . length } CDM Tables...` ) ;
191+ progressTracker . startStep ( 'entities' , `Processing ${ cdmEntities . length } CDM Tables...` ) ;
182192 console . log ( '🔧 DEBUG: Processing CDM entities:' , {
183193 count : cdmEntities . length ,
184194 entities : cdmEntities . map ( e => e ?. originalEntity ?. name || e ?. name ) ,
@@ -201,12 +211,21 @@ class DeploymentService extends BaseService {
201211 if ( cdmData . summary ?. relationshipsCreated ) {
202212 results . relationshipsCreated += cdmData . summary . relationshipsCreated ;
203213 }
214+
215+ progressTracker . updateStep ( 'entities' , `Successfully processed ${ cdmEntities . length } CDM entities` ) ;
216+ } else {
217+ progressTracker . updateStep ( 'entities' , `CDM entities processing completed with warnings` ) ;
204218 }
205219 }
206220
207- // Step 7 : Process custom entities if any
221+ // Step 6 : Process custom entities if any
208222 if ( customEntities . length > 0 ) {
209- progress ( 'custom-entities' , `Creating ${ customEntities . length } Custom Tables...` ) ;
223+ if ( cdmEntities . length === 0 ) {
224+ progressTracker . startStep ( 'entities' , `Creating ${ customEntities . length } Custom Tables...` ) ;
225+ } else {
226+ progressTracker . updateStep ( 'entities' , `Creating ${ customEntities . length } Custom Tables...` ) ;
227+ }
228+
210229 results . customResults = await this . processCustomEntities (
211230 customEntities ,
212231 parseResult . relationships ,
@@ -227,6 +246,8 @@ class DeploymentService extends BaseService {
227246 results . warnings . push ( ...results . customResults . warnings ) ;
228247 }
229248
249+ progressTracker . updateStep ( 'entities' , `Successfully created ${ results . customResults . entitiesCreated } custom entities` ) ;
250+
230251 console . log ( '🔍 DEBUG: Updated results after custom entities:' , {
231252 entitiesCreated : results . entitiesCreated ,
232253 relationshipsCreated : results . relationshipsCreated ,
@@ -237,12 +258,18 @@ class DeploymentService extends BaseService {
237258 warnings : results . customResults . warnings ?. length || 0
238259 }
239260 } ) ;
261+ } else {
262+ progressTracker . updateStep ( 'entities' , `Custom entities creation completed with warnings` ) ;
240263 }
241264 }
265+
266+ if ( cdmEntities . length > 0 || customEntities . length > 0 ) {
267+ progressTracker . completeStep ( 'entities' , `Entity creation completed - ${ results . entitiesCreated } entities created` ) ;
268+ }
242269
243- // Step 8 : Process global choices
270+ // Step 7 : Process global choices
244271 if ( config . selectedChoices ?. length > 0 || config . customChoices ?. length > 0 ) {
245- progress ( 'global-choices ', 'Processing Global Choices...' ) ;
272+ progressTracker . startStep ( 'globalChoices ', 'Processing Global Choices...' ) ;
246273
247274 // Determine the correct publisher prefix to use
248275 let publisherPrefix ;
@@ -269,11 +296,22 @@ class DeploymentService extends BaseService {
269296 results . globalChoicesAdded = results . globalChoicesResults . totalAdded || 0 ;
270297 results . globalChoicesCreated = results . globalChoicesResults . totalCreated || 0 ;
271298 results . globalChoicesExistingAdded = results . globalChoicesResults . totalExistingAdded || 0 ;
299+
300+ progressTracker . completeStep ( 'globalChoices' , `Global choices processed - ${ results . globalChoicesCreated } created, ${ results . globalChoicesAdded } added` ) ;
301+ } else {
302+ progressTracker . completeStep ( 'globalChoices' , 'Global choices processing completed with warnings' ) ;
272303 }
304+ } else {
305+ progressTracker . startStep ( 'globalChoices' , 'No global choices to process' ) ;
306+ progressTracker . completeStep ( 'globalChoices' , 'Skipped global choices - none specified' ) ;
273307 }
274308
309+ // Step 8: Process relationships (this happens during entity creation but we track it separately)
310+ progressTracker . startStep ( 'relationships' , `Setting up ${ parseResult . relationships ?. length || 0 } relationships...` ) ;
311+ progressTracker . completeStep ( 'relationships' , `${ results . relationshipsCreated } relationships created successfully` ) ;
312+
275313 // Step 9: Finalize deployment
276- progress ( 'finalizing ', 'Finalizing deployment...' ) ;
314+ progressTracker . startStep ( 'finalization ', 'Finalizing deployment...' ) ;
277315 results . summary = this . generateDeploymentSummary ( results ) ;
278316
279317 // Step 10: Record deployment in history
@@ -344,7 +382,9 @@ class DeploymentService extends BaseService {
344382 // End performance monitoring
345383 this . performanceMonitor . endOperation ( deploymentId , results ) ;
346384
347- progress ( 'complete' , results . summary , { completed : true } ) ;
385+ // Complete the final step and the overall operation
386+ progressTracker . completeStep ( 'finalization' , 'Deployment recorded and finalized' ) ;
387+ progressTracker . complete ( results . summary ) ;
348388
349389 // Use the generated summary as the success message
350390 return this . createSuccess ( results , results . summary ) ;
@@ -353,6 +393,9 @@ class DeploymentService extends BaseService {
353393 this . error ( 'Deployment failed' , error ) ;
354394 this . updateDeploymentStatus ( deploymentId , 'failed' , error . message ) ;
355395
396+ // Fail the progress tracker
397+ progressTracker . fail ( 'Deployment failed' , error ) ;
398+
356399 // End performance monitoring for failed deployment
357400 this . performanceMonitor . endOperation ( deploymentId , {
358401 success : false ,
0 commit comments