11import { PullRequestData , GitHubWebhookPayload } from "../../models/ai-review.model" ;
22import { backgroundJobService , BackgroundJobService } from "../background-job.service" ;
33import { AIReviewOrchestrationService } from "./orchestration.service" ;
4+ import { AIReviewCommentService } from "./comment.service" ;
45import { PRAnalysisService } from "./pr-analysis.service" ;
56import { PRAnalysisError } from "../../models/error.model" ;
67import { dataLogger , messageLogger } from "../../config/logger.config" ;
@@ -75,6 +76,7 @@ export class WorkflowIntegrationService {
7576 reason ?: string ;
7677 } > {
7778 const startTime = Date . now ( ) ;
79+ let prData : PullRequestData = { } as PullRequestData ;
7880
7981 try {
8082 dataLogger . info (
@@ -86,10 +88,47 @@ export class WorkflowIntegrationService {
8688 }
8789 ) ;
8890
91+ // Determine whether this is a follow-up (synchronize) or initial review.
92+ // Manual triggers ("review" comment) always queue as an initial review.
93+ const isFollowUp = ! payload . manualTrigger && payload . action === "synchronize" ;
94+ const { pull_request, repository, installation } = payload ;
95+
96+ let isActualFollowUp = false ;
97+ if ( isFollowUp ) {
98+ // Check whether a completed initial review already exists for this PR
99+ isActualFollowUp = await this . orchestrationService . hasCompletedReview (
100+ installation . id . toString ( ) ,
101+ pull_request . number ,
102+ repository . full_name
103+ ) ;
104+ }
105+
106+ // Post an "in progress" comment so contributors know a review is underway
107+ try {
108+ const commentResult = isActualFollowUp
109+ ? await AIReviewCommentService . postFollowUpInProgressComment (
110+ installation . id . toString ( ) ,
111+ repository . full_name ,
112+ pull_request . number
113+ )
114+ : await AIReviewCommentService . postInProgressComment (
115+ installation . id . toString ( ) ,
116+ repository . full_name ,
117+ pull_request . number
118+ ) ;
119+
120+ if ( commentResult . success && commentResult . commentId ) {
121+ prData . pendingCommentId = commentResult . commentId ;
122+ }
123+ } catch ( inProgressError ) {
124+ dataLogger . error ( "Failed to post in-progress comment" , { inProgressError } ) ;
125+ }
126+
89127 // Extract and validate PR data
90- let prData : PullRequestData ;
91128 try {
129+ const pendingCommentId = prData . pendingCommentId ;
92130 prData = await PRAnalysisService . createCompletePRData ( payload ) ;
131+ prData . pendingCommentId = pendingCommentId ;
93132 } catch ( error ) {
94133 if ( error instanceof PRAnalysisError && error . code === "PR_NOT_ELIGIBLE_ERROR" ) {
95134 dataLogger . info (
@@ -105,32 +144,19 @@ export class WorkflowIntegrationService {
105144 // Log analysis decision
106145 PRAnalysisService . logAnalysisDecision ( prData , true ) ;
107146
108- // Determine whether this is a follow-up (synchronize) or initial review.
109- // Manual triggers ("review" comment) always queue as an initial review.
110- const isFollowUp = ! payload . manualTrigger && payload . action === "synchronize" ;
111-
112147 let jobId : string ;
113- if ( isFollowUp ) {
114- // Check whether a completed initial review already exists for this PR
115- const hasPreviousReview = await this . orchestrationService . hasCompletedReview (
116- prData . installationId ,
117- prData . prNumber ,
118- prData . repositoryName
119- ) ;
120-
121- if ( hasPreviousReview ) {
122- // Queue as a follow-up job
123- jobId = await this . jobQueue . addPRAnalysisJob ( prData , true ) ;
124- dataLogger . info ( "Queued follow-up review job" , { jobId, prNumber : prData . prNumber } ) ;
125- } else {
126- // No prior review exists yet — treat this like an initial review
127- jobId = await this . jobQueue . addPRAnalysisJob ( prData , false ) ;
128- dataLogger . info ( "No prior review found; queued as initial review" , { jobId, prNumber : prData . prNumber } ) ;
129- }
148+ if ( isActualFollowUp ) {
149+ // Queue as a follow-up job
150+ jobId = await this . jobQueue . addPRAnalysisJob ( prData , true ) ;
151+ dataLogger . info ( "Queued follow-up review job" , { jobId, prNumber : prData . prNumber } ) ;
130152 } else {
131- // Initial review (opened / ready_for_review)
153+ // No prior review exists yet, or it's an opened/ ready_for_review event — treat this like an initial review
132154 jobId = await this . jobQueue . addPRAnalysisJob ( prData , false ) ;
133- dataLogger . info ( "Queued initial review job" , { jobId, prNumber : prData . prNumber } ) ;
155+ if ( isFollowUp ) {
156+ dataLogger . info ( "No prior review found; queued as initial review" , { jobId, prNumber : prData . prNumber } ) ;
157+ } else {
158+ dataLogger . info ( "Queued initial review job" , { jobId, prNumber : prData . prNumber } ) ;
159+ }
134160 }
135161
136162 dataLogger . info (
0 commit comments