fix: improve JiraService pagination and cleanup logic
- Updated pagination logging to include total issues retrieved. - Increased safety limit for pagination from 5000 to 10000 tickets to prevent infinite loops. - Removed deprecated cleanupEpics method to streamline synchronization process. - Added check for actual changes before updating tasks to avoid unnecessary database operations.
This commit is contained in:
@@ -94,15 +94,17 @@ export class JiraService {
|
||||
}
|
||||
|
||||
allIssues.push(...data.issues);
|
||||
console.log(`✅ ${data.issues.length} tickets récupérés (total: ${allIssues.length})`);
|
||||
console.log(`✅ ${data.issues.length} tickets récupérés (total: ${allIssues.length}/${data.total || '?'})`);
|
||||
|
||||
// Vérifier s'il y a plus de pages
|
||||
hasMorePages = data.issues.length === maxResults && allIssues.length < (data.total || Number.MAX_SAFE_INTEGER);
|
||||
startAt += maxResults;
|
||||
|
||||
// Sécurité: éviter les boucles infinies
|
||||
if (allIssues.length > 5000) {
|
||||
console.warn('⚠️ Limite de sécurité atteinte (5000 tickets). Arrêt de la pagination.');
|
||||
console.log(`📊 Pagination: hasMorePages=${hasMorePages}, startAt=${startAt}, maxResults=${maxResults}`);
|
||||
|
||||
// Sécurité: éviter les boucles infinies (augmenté avec la nouvelle taille de page)
|
||||
if (allIssues.length > 10000) {
|
||||
console.warn('⚠️ Limite de sécurité atteinte (10000 tickets). Arrêt de la pagination.');
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -145,61 +147,6 @@ export class JiraService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Nettoie les epics Jira de la base (ne doivent plus être synchronisés)
|
||||
*/
|
||||
async cleanupEpics(): Promise<number> {
|
||||
try {
|
||||
console.log('🧹 Nettoyage des epics Jira...');
|
||||
|
||||
// D'abord, listons toutes les tâches Jira pour voir lesquelles sont des epics
|
||||
const allJiraTasks = await prisma.task.findMany({
|
||||
where: { source: 'jira' }
|
||||
});
|
||||
|
||||
console.log(`🔍 ${allJiraTasks.length} tâches Jira trouvées:`);
|
||||
allJiraTasks.forEach(task => {
|
||||
// @ts-expect-error - jiraType existe mais n'est pas encore dans les types générés
|
||||
console.log(` - ${task.jiraKey}: "${task.title}" [${task.jiraType || 'N/A'}] (ID: ${task.id})`);
|
||||
});
|
||||
|
||||
// Trouver les tâches Jira qui sont des epics
|
||||
// Maintenant on peut utiliser le type Jira mappé directement !
|
||||
const epicsToDelete = await prisma.task.findMany({
|
||||
where: {
|
||||
source: 'jira',
|
||||
// @ts-expect-error - jiraType existe mais n'est pas encore dans les types générés
|
||||
jiraType: 'Epic' // Maintenant standardisé grâce au mapping
|
||||
}
|
||||
});
|
||||
|
||||
if (epicsToDelete.length > 0) {
|
||||
// Supprimer les relations de tags d'abord
|
||||
await prisma.taskTag.deleteMany({
|
||||
where: {
|
||||
taskId: { in: epicsToDelete.map(task => task.id) }
|
||||
}
|
||||
});
|
||||
|
||||
// Supprimer les tâches epics
|
||||
const result = await prisma.task.deleteMany({
|
||||
where: {
|
||||
id: { in: epicsToDelete.map(task => task.id) }
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`✅ ${result.count} epics supprimés de la base`);
|
||||
return result.count;
|
||||
} else {
|
||||
console.log('✅ Aucun epic trouvé à nettoyer');
|
||||
return 0;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Erreur lors du nettoyage des epics:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronise les tickets Jira avec la base locale
|
||||
*/
|
||||
@@ -216,9 +163,6 @@ export class JiraService {
|
||||
try {
|
||||
console.log('🔄 Début de la synchronisation Jira...');
|
||||
|
||||
// Nettoyer les epics existants (une seule fois)
|
||||
await this.cleanupEpics();
|
||||
|
||||
// S'assurer que le tag "From Jira" existe
|
||||
await this.ensureJiraTagExists();
|
||||
|
||||
@@ -317,6 +261,29 @@ export class JiraService {
|
||||
return 'skipped';
|
||||
}
|
||||
|
||||
// Vérifier s'il y a vraiment des changements
|
||||
const hasChanges =
|
||||
existingTask.title !== taskData.title ||
|
||||
existingTask.description !== taskData.description ||
|
||||
existingTask.status !== taskData.status ||
|
||||
existingTask.priority !== taskData.priority ||
|
||||
(existingTask.dueDate?.getTime() || null) !== (taskData.dueDate?.getTime() || null) ||
|
||||
existingTask.jiraProject !== taskData.jiraProject ||
|
||||
existingTask.jiraKey !== taskData.jiraKey ||
|
||||
// @ts-expect-error - jiraType existe mais n'est pas encore dans les types générés
|
||||
existingTask.jiraType !== taskData.jiraType ||
|
||||
existingTask.assignee !== taskData.assignee;
|
||||
|
||||
if (!hasChanges) {
|
||||
console.log(`⏭️ Aucun changement pour ${jiraTask.key}, skip mise à jour`);
|
||||
|
||||
// S'assurer que les tags Jira sont assignés (pour les anciennes tâches) même en skip
|
||||
await this.assignJiraTag(existingTask.id);
|
||||
await this.assignProjectTag(existingTask.id, jiraTask.project.key);
|
||||
|
||||
return 'skipped';
|
||||
}
|
||||
|
||||
// Mettre à jour seulement les champs Jira (pas les modifs locales)
|
||||
await prisma.task.update({
|
||||
where: { id: existingTask.id },
|
||||
@@ -331,7 +298,7 @@ export class JiraService {
|
||||
// @ts-expect-error - jiraType existe mais n'est pas encore dans les types générés
|
||||
jiraType: taskData.jiraType,
|
||||
assignee: taskData.assignee,
|
||||
updatedAt: taskData.updatedAt
|
||||
updatedAt: taskData.updatedAt // Seulement si changements réels
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user