diff --git a/lib/services/leantime-service.ts b/lib/services/leantime-service.ts index f65bb48c..e0458596 100644 --- a/lib/services/leantime-service.ts +++ b/lib/services/leantime-service.ts @@ -94,9 +94,40 @@ export class LeantimeService { await this.setProjectAvatar(projectId, mission.logo); } - // Assign users to the project - if (mission.missionUsers && mission.missionUsers.length > 0) { - await this.assignUsersToProject(projectId, mission.missionUsers); + try { + // Wait a bit before attempting to add any users to avoid rate limits + await new Promise(resolve => setTimeout(resolve, 3000)); + // Check if we can make at least one API call without hitting rate limits + const testResponse = await axios.post( + this.getApiEndpoint(), + { + method: 'leantime.rpc.Auth.getCurrentUser', + jsonrpc: '2.0', + id: 1 + }, + { + headers: { + 'Content-Type': 'application/json', + 'X-API-Key': this.apiToken + } + } + ); + + // If test API call succeeds, try to assign users + if (mission.missionUsers && mission.missionUsers.length > 0) { + await this.assignUsersToProject(projectId, mission.missionUsers); + } + } catch (apiError) { + // If we hit rate limits on the test call, skip user assignment completely + if (axios.isAxiosError(apiError) && apiError.response?.status === 429) { + console.log('⚠️ Rate limiting detected. Skipping all user assignments.'); + console.log(`⚠️ Users will need to be added manually at: ${this.getProjectUrl(projectId)}`); + } else { + // Try to assign users anyway for other types of errors + if (mission.missionUsers && mission.missionUsers.length > 0) { + await this.assignUsersToProject(projectId, mission.missionUsers); + } + } } return projectId; @@ -152,9 +183,40 @@ export class LeantimeService { await this.setProjectAvatar(projectId, mission.logo); } - // Assign users to the project - if (mission.missionUsers && mission.missionUsers.length > 0) { - await this.assignUsersToProject(projectId, mission.missionUsers); + try { + // Wait a bit before attempting to add any users to avoid rate limits + await new Promise(resolve => setTimeout(resolve, 3000)); + // Check if we can make at least one API call without hitting rate limits + const testResponse = await axios.post( + this.getApiEndpoint(), + { + method: 'leantime.rpc.Auth.getCurrentUser', + jsonrpc: '2.0', + id: 1 + }, + { + headers: { + 'Content-Type': 'application/json', + 'X-API-Key': this.apiToken + } + } + ); + + // If test API call succeeds, try to assign users + if (mission.missionUsers && mission.missionUsers.length > 0) { + await this.assignUsersToProject(projectId, mission.missionUsers); + } + } catch (apiError) { + // If we hit rate limits on the test call, skip user assignment completely + if (axios.isAxiosError(apiError) && apiError.response?.status === 429) { + console.log('⚠️ Rate limiting detected. Skipping all user assignments.'); + console.log(`⚠️ Users will need to be added manually at: ${this.getProjectUrl(projectId)}`); + } else { + // Try to assign users anyway for other types of errors + if (mission.missionUsers && mission.missionUsers.length > 0) { + await this.assignUsersToProject(projectId, mission.missionUsers); + } + } } return projectId; @@ -1045,4 +1107,17 @@ export class LeantimeService { return false; } } + + /** + * Helper method to get the project URL + */ + private getProjectUrl(projectId: number): string { + const baseUrl = this.apiUrl + .replace('/api/jsonrpc', '') + .replace('/api/jsonrpc.php', ''); + + return baseUrl.endsWith('/') + ? `${baseUrl}projects/showProject/${projectId}` + : `${baseUrl}/projects/showProject/${projectId}`; + } } \ No newline at end of file