@@ -88,15 +88,16 @@ function buildWindow(windowDays: 7 | 14 | 30, totals: RepoGithubTotalsSnapshotRe
8888 const targetMs = latestMs - windowDays * 24 * 60 * 60 * 1000 ;
8989 const baseline = [ ...totals ] . reverse ( ) . find ( ( snapshot ) => Date . parse ( snapshot . fetchedAt ) <= targetMs ) ;
9090 if ( ! baseline ) return unavailableWindow ( windowDays , `Need at least ${ windowDays } days of totals history.` ) ;
91- const observedDays = Math . max ( 0 , round ( ( latestMs - Date . parse ( baseline . fetchedAt ) ) / ( 24 * 60 * 60 * 1000 ) ) ) ;
91+ // Baseline is the newest snapshot at or before (latest - windowDays), so observedDays is always >= windowDays.
92+ const observedDays = round ( ( latestMs - Date . parse ( baseline . fetchedAt ) ) / ( 24 * 60 * 60 * 1000 ) ) ;
9293 const mergedPullRequests = Math . max ( 0 , latest . mergedPullRequestsTotal - baseline . mergedPullRequestsTotal ) ;
9394 const closedUnmergedPullRequests = Math . max ( 0 , latest . closedUnmergedPullRequestsTotal - baseline . closedUnmergedPullRequestsTotal ) ;
9495 const latestQueue = latestQueuePoint ( queuePoints ) ;
9596 const baselineQueue = latestQueue ? baselineQueuePoint ( queuePoints , latestQueue . generatedAt , windowDays ) : null ;
9697 const stalePullRequestRate = latestQueue ? staleRate ( latestQueue ) : null ;
9798 const baselineStaleRate = baselineQueue ? staleRate ( baselineQueue ) : null ;
9899 const duplicateTrend = latestQueue && baselineQueue ? latestQueue . collisionClusters - baselineQueue . collisionClusters : null ;
99- const reviewVelocityPerDay = computeReviewVelocityPerDay ( mergedPullRequests , closedUnmergedPullRequests , observedDays ) ;
100+ const reviewVelocityPerDay = round ( ( mergedPullRequests + closedUnmergedPullRequests ) / observedDays ) ;
100101 const pullRequestGrowth = latest . openPullRequestsTotal - baseline . openPullRequestsTotal ;
101102 return {
102103 windowDays,
@@ -112,16 +113,10 @@ function buildWindow(windowDays: 7 | 14 | 30, totals: RepoGithubTotalsSnapshotRe
112113 stalePullRequestRate,
113114 stalePullRequestRateDelta : stalePullRequestRate !== null && baselineStaleRate !== null ? round ( stalePullRequestRate - baselineStaleRate ) : null ,
114115 duplicateTrend,
115- summary : `${ windowDays } d trend: PR queue ${ signed ( pullRequestGrowth ) } , review velocity ${ reviewVelocityPerDay === null ? "n/a" : ` ${ reviewVelocityPerDay } /day` } .` ,
116+ summary : `${ windowDays } d trend: PR queue ${ signed ( pullRequestGrowth ) } , review velocity ${ reviewVelocityPerDay } /day.` ,
116117 } ;
117118}
118119
119- /** Returns null when the observation window spans zero days (avoids divide-by-zero / fabricated velocity). */
120- export function computeReviewVelocityPerDay ( mergedPullRequests : number , closedUnmergedPullRequests : number , observedDays : number ) : number | null {
121- if ( observedDays === 0 ) return null ;
122- return round ( ( mergedPullRequests + closedUnmergedPullRequests ) / observedDays ) ;
123- }
124-
125120function trendWarnings ( windows : QueueTrendWindow [ ] ) : string [ ] {
126121 const warnings : string [ ] = [ ] ;
127122 for ( const window of windows . filter ( ( entry ) => entry . status === "ready" ) ) {
0 commit comments