@@ -47,6 +47,7 @@ import { decrypt, encrypt } from '@/shared/utils/crypto';
4747import { PullRequestState } from '@/shared/domain/enums/pullRequestState.enum' ;
4848import { safelyParseMessageContent } from '@/shared/utils/safelyParseMessageContent' ;
4949import { PromptService } from '../prompt.service' ;
50+ import { CacheService } from '@/shared/utils/cache/cache.service' ;
5051import moment from 'moment' ;
5152import { ParametersKey } from '@/shared/domain/enums/parameters-key.enum' ;
5253import { Commit } from '@/config/types/general/commit.type' ;
@@ -111,9 +112,12 @@ export class BitbucketService
111112 private readonly logger : PinoLoggerService ,
112113
113114 private readonly configService : ConfigService ,
115+ private readonly cacheService : CacheService ,
114116 private readonly mcpManagerService ?: MCPManagerService ,
115117 ) { }
116118
119+ private readonly USER_CACHE_TTL = 60 * 60 * 1000 ; // 1 hour
120+
117121 async getPullRequestAuthors ( params : {
118122 organizationAndTeamData : OrganizationAndTeamData ;
119123 } ) : Promise < PullRequestAuthor [ ] > {
@@ -217,6 +221,7 @@ export class BitbucketService
217221 . listActivitiesForRepo ( {
218222 repo_slug : `{${ repository . id } }` ,
219223 workspace : `{${ workspace } }` ,
224+ pagelen : 100 ,
220225 } )
221226 . then ( ( res ) => this . getPaginatedResults ( bitbucketAPI , res ) ) ;
222227
@@ -787,14 +792,15 @@ export class BitbucketService
787792 const bitbucketAPI = this . instanceBitbucketApi ( bitbucketAuthDetail ) ;
788793
789794 const workspaces = await bitbucketAPI . workspaces
790- . getWorkspaces ( { } )
795+ . getWorkspaces ( { pagelen : 100 } )
791796 . then ( ( res ) => this . getPaginatedResults ( bitbucketAPI , res ) ) ;
792797
793798 const workspacesWithRepos = await Promise . all (
794799 workspaces . map ( ( workspace ) =>
795800 bitbucketAPI . repositories
796801 . list ( {
797802 workspace : `${ workspace . uuid } ` ,
803+ pagelen : 100 ,
798804 } )
799805 . then ( ( res ) =>
800806 this . getPaginatedResults ( bitbucketAPI , res ) ,
@@ -887,6 +893,7 @@ export class BitbucketService
887893 . list ( {
888894 repo_slug : `{${ repo . id } }` ,
889895 workspace : `{${ repo . workspaceId } }` ,
896+ pagelen : 100 ,
890897 } )
891898 . then ( ( res ) =>
892899 this . getPaginatedResults ( bitbucketAPI , res ) ,
@@ -989,7 +996,9 @@ export class BitbucketService
989996
990997 return null ;
991998 } )
992- . filter ( ( workspace ) : workspace is string => ! ! workspace ) ,
999+ . filter (
1000+ ( workspace ) : workspace is string => ! ! workspace ,
1001+ ) ,
9931002 ) ,
9941003 ) ;
9951004
@@ -1005,14 +1014,18 @@ export class BitbucketService
10051014 pagelen : 100 ,
10061015 } )
10071016 . then ( ( res ) =>
1008- this . getPaginatedResults <
1009- Schema . WorkspaceMembership
1010- > ( bitbucketAPI , res ) ,
1017+ this . getPaginatedResults < Schema . WorkspaceMembership > (
1018+ bitbucketAPI ,
1019+ res ,
1020+ ) ,
10111021 ) ,
10121022 ) ,
10131023 ) ;
10141024
1015- const uniqueMembers = new Map < string , { name : string ; id : string } > ( ) ;
1025+ const uniqueMembers = new Map <
1026+ string ,
1027+ { name : string ; id : string }
1028+ > ( ) ;
10161029
10171030 allMembers . forEach ( ( memberships ) => {
10181031 memberships . forEach ( ( membership ) => {
@@ -1208,6 +1221,7 @@ export class BitbucketService
12081221 . list ( {
12091222 repo_slug : `{${ repo . id } }` ,
12101223 workspace : `{${ repo . workspaceId } }` ,
1224+ pagelen : 100 ,
12111225 } )
12121226 . then ( ( res ) =>
12131227 this . getPaginatedResults ( bitbucketAPI , res ) ,
@@ -1339,6 +1353,7 @@ export class BitbucketService
13391353 repo_slug : `{${ repo . id } }` ,
13401354 workspace : `{${ repo . workspaceId } }` ,
13411355 state : normalizedStatus ,
1356+ pagelen : 100 ,
13421357 } )
13431358 . then ( ( res ) =>
13441359 this . getPaginatedResults ( bitbucketAPI , res ) ,
@@ -1462,6 +1477,7 @@ export class BitbucketService
14621477 repo_slug : `{${ repo . id } }` ,
14631478 workspace : `{${ repo . workspaceId } }` ,
14641479 q : `(state = 'MERGED' OR state = 'DECLINED')${ query } ` ,
1480+ pagelen : 100 ,
14651481 } )
14661482 . then ( ( res ) =>
14671483 this . getPaginatedResults ( bitbucketAPI , res ) ,
@@ -2066,16 +2082,18 @@ export class BitbucketService
20662082 const bitbucketAPI =
20672083 this . instanceBitbucketApi ( bitbucketAuthDetails ) ;
20682084
2069- const commits = await bitbucketAPI . repositories
2070- . listCommits ( {
2071- repo_slug : `{${ repo . id } }` ,
2072- workspace : `{${ repo . workspaceId } }` ,
2073- include :
2074- pullRequest . head ?. ref || pullRequest . base ?. ref || '' ,
2075- } )
2076- . then ( ( res ) => this . getPaginatedResults ( bitbucketAPI , res ) ) ;
2085+ const commits = await bitbucketAPI . repositories . listCommits ( {
2086+ repo_slug : `{${ repo . id } }` ,
2087+ workspace : `{${ repo . workspaceId } }` ,
2088+ pagelen : 1 ,
2089+ include : pullRequest . head ?. ref || pullRequest . base ?. ref || '' ,
2090+ } ) ;
20772091
2078- const commit = commits [ 0 ] ;
2092+ const commit = commits ?. data ?. values ?. [ 0 ] ;
2093+
2094+ if ( ! commit ) {
2095+ return null ;
2096+ }
20792097
20802098 const fileContent = await bitbucketAPI . source
20812099 . read ( {
@@ -2102,6 +2120,7 @@ export class BitbucketService
21022120 params,
21032121 } ,
21042122 } ) ;
2123+ return null ;
21052124 }
21062125 }
21072126
@@ -2555,6 +2574,7 @@ export class BitbucketService
25552574 pull_request_id : filters . pullRequestNumber ,
25562575 repo_slug : `{${ filters . repository . id } }` ,
25572576 workspace : `{${ workspace } }` ,
2577+ pagelen : 100 ,
25582578 } )
25592579 . then ( ( res ) => this . getPaginatedResults ( bitbucketAPI , res ) ) ;
25602580
@@ -2921,6 +2941,7 @@ export class BitbucketService
29212941 . listForRepo ( {
29222942 repo_slug : `{${ repo . id } }` ,
29232943 workspace : `{${ repo . workspaceId } }` ,
2944+ pagelen : 100 ,
29242945 } )
29252946 . then ( ( res ) => this . getPaginatedResults ( bitbucketAPI , res ) ) ;
29262947
@@ -3471,6 +3492,7 @@ export class BitbucketService
34713492 repo_slug : `{${ repository . id } }` ,
34723493 workspace : `{${ workspace } }` ,
34733494 pull_request_id : prNumber ,
3495+ pagelen : 100 ,
34743496 } )
34753497 . then ( ( res ) => this . getPaginatedResults ( bitbucketAPI , res ) ) ;
34763498
@@ -3684,6 +3706,7 @@ export class BitbucketService
36843706 pull_request_id : prNumber ,
36853707 repo_slug : `{${ repository . id } }` ,
36863708 workspace : `{${ workspace } }` ,
3709+ pagelen : 100 ,
36873710 } )
36883711 . then ( ( res ) => this . getPaginatedResults ( bitbucketAPI , res ) ) ;
36893712
@@ -3752,6 +3775,7 @@ export class BitbucketService
37523775 workspace : `{${ workspace } }` ,
37533776 q : queryString ,
37543777 fields : '+values.participants,+values.reviewers,+values.draft' ,
3778+ pagelen : 100 ,
37553779 } )
37563780 . then ( ( res ) => this . getPaginatedResults ( bitbucketAPI , res ) ) ;
37573781
@@ -3782,6 +3806,21 @@ export class BitbucketService
37823806 return null ;
37833807 }
37843808
3809+ const cacheKey = `bitbucket-user-${ organizationAndTeamData . organizationId } -${ username } ` ;
3810+
3811+ const cached = await this . cacheService . getFromCache < any > ( cacheKey ) ;
3812+ if ( cached !== null ) {
3813+ this . logger . debug ( {
3814+ message : `User data retrieved from cache` ,
3815+ context : BitbucketService . name ,
3816+ metadata : {
3817+ username,
3818+ organizationId : organizationAndTeamData . organizationId ,
3819+ } ,
3820+ } ) ;
3821+ return cached ;
3822+ }
3823+
37853824 try {
37863825 const bitbucketAuthDetails = await this . getAuthDetails (
37873826 organizationAndTeamData ,
@@ -3797,14 +3836,30 @@ export class BitbucketService
37973836 } )
37983837 . then ( ( res ) => res . data ) ;
37993838
3800- return user ?? null ;
3839+ const userData = user ?? null ;
3840+
3841+ await this . cacheService . addToCache (
3842+ cacheKey ,
3843+ userData ,
3844+ this . USER_CACHE_TTL ,
3845+ ) ;
3846+
3847+ return userData ;
38013848 } catch ( error : any ) {
38023849 if ( error ?. response ?. status === 404 ) {
38033850 this . logger . warn ( {
38043851 message : `Bitbucket user not found: ${ username } ` ,
38053852 context : BitbucketService . name ,
38063853 metadata : { username, organizationAndTeamData } ,
38073854 } ) ;
3855+
3856+ // Cache null result to avoid repeated 404 calls
3857+ await this . cacheService . addToCache (
3858+ cacheKey ,
3859+ null ,
3860+ this . USER_CACHE_TTL ,
3861+ ) ;
3862+
38083863 return null ;
38093864 }
38103865
@@ -3855,6 +3910,7 @@ export class BitbucketService
38553910 workspace : `{${ workspace } }` ,
38563911 pull_request_id : prNumber ,
38573912 fields : '+values.resolution.type,+values.resolution.+values.id,+values.pullrequest' ,
3913+ pagelen : 100 ,
38583914 } )
38593915 . then ( ( res ) => this . getPaginatedResults ( bitbucketAPI , res ) ) ;
38603916
@@ -3934,7 +3990,7 @@ export class BitbucketService
39343990
39353991 // Check for thumbs up reaction
39363992 if (
3937- replyBody . includes ( thumbsUpText ) &&
3993+ replyBody ? .includes ( thumbsUpText ) &&
39383994 ! userReaction . thumbsUp
39393995 ) {
39403996 comment . thumbsUp ++ ;
@@ -3943,7 +3999,7 @@ export class BitbucketService
39433999
39444000 // Check for thumbs down reaction
39454001 if (
3946- replyBody . includes ( thumbsDownText ) &&
4002+ replyBody ? .includes ( thumbsDownText ) &&
39474003 ! userReaction . thumbsDown
39484004 ) {
39494005 comment . thumbsDown ++ ;
@@ -4008,14 +4064,20 @@ export class BitbucketService
40084064 bitbucketAPI : APIClient ,
40094065 response : BitbucketResponse < { values ?: T [ ] } > ,
40104066 ) : Promise < T [ ] > {
4067+ if ( ! response . data . values || ! Array . isArray ( response . data . values ) ) {
4068+ return [ ] ;
4069+ }
4070+
40114071 let allResults = [ ...response . data . values ] ;
40124072 let currentResults = response . data ;
40134073
40144074 while ( bitbucketAPI . hasNextPage ( currentResults ) ) {
40154075 currentResults = ( await bitbucketAPI . getNextPage ( currentResults ) )
40164076 . data ;
40174077
4018- allResults = allResults . concat ( currentResults . values ) ;
4078+ if ( currentResults . values && Array . isArray ( currentResults . values ) ) {
4079+ allResults = allResults . concat ( currentResults . values ) ;
4080+ }
40194081 }
40204082
40214083 return allResults ;
@@ -4034,6 +4096,10 @@ export class BitbucketService
40344096 response : BitbucketResponse < { values ?: T [ ] } > ,
40354097 limit : number = 100 ,
40364098 ) : Promise < T [ ] > {
4099+ if ( ! response . data . values || ! Array . isArray ( response . data . values ) ) {
4100+ return [ ] ;
4101+ }
4102+
40374103 let allResults = [ ...response . data . values ] ;
40384104 let currentResults = response . data ;
40394105
@@ -4049,7 +4115,9 @@ export class BitbucketService
40494115 currentResults = ( await bitbucketAPI . getNextPage ( currentResults ) )
40504116 . data ;
40514117
4052- allResults = allResults . concat ( currentResults . values ) ;
4118+ if ( currentResults . values && Array . isArray ( currentResults . values ) ) {
4119+ allResults = allResults . concat ( currentResults . values ) ;
4120+ }
40534121 }
40544122
40554123 // Return only up to the limit
@@ -4134,6 +4202,7 @@ export class BitbucketService
41344202 . listForRepo ( {
41354203 repo_slug : `{${ this . sanitizeUUID ( targetRepo . id ) } }` ,
41364204 workspace : `{${ this . sanitizeUUID ( targetRepo . workspaceId ) } }` ,
4205+ pagelen : 100 ,
41374206 } )
41384207 . then ( ( res ) => this . getPaginatedResults ( bitbucketAPI , res ) ) ;
41394208
@@ -4191,6 +4260,7 @@ export class BitbucketService
41914260 . listForRepo ( {
41924261 repo_slug : `{${ repo . id } }` ,
41934262 workspace : `{${ repo . workspaceId } }` ,
4263+ pagelen : 100 ,
41944264 } )
41954265 . then ( ( res ) =>
41964266 this . getPaginatedResults ( bitbucketAPI , res ) ,
@@ -4480,7 +4550,7 @@ export class BitbucketService
44804550 // Se max_depth falhar (timeout 555), tentar com profundidade menor
44814551 if (
44824552 error instanceof Error &&
4483- error . message . includes ( '555' ) &&
4553+ error . message ? .includes ( '555' ) &&
44844554 maxDepth > 3
44854555 ) {
44864556 this . logger . warn ( {
@@ -5000,7 +5070,7 @@ export class BitbucketService
50005070 } ,
50015071 message : pullRequest ?. title ?? '' ,
50025072 created_at : pullRequest ?. created_on ?? '' ,
5003- closed_at : this . _prClosedStates . includes ( pullRequest ?. state )
5073+ closed_at : this . _prClosedStates ? .includes ( pullRequest ?. state )
50045074 ? ( pullRequest ?. updated_on ?? '' )
50055075 : '' ,
50065076 updated_at : pullRequest ?. updated_on ?? '' ,
0 commit comments