feat: TFS Sync
This commit is contained in:
@@ -57,6 +57,7 @@ export async function POST(request: Request) {
|
||||
if (jiraConfig.enabled && jiraConfig.baseUrl && jiraConfig.email && jiraConfig.apiToken) {
|
||||
// Utiliser la config depuis la base de données
|
||||
jiraService = new JiraService({
|
||||
enabled: jiraConfig.enabled,
|
||||
baseUrl: jiraConfig.baseUrl,
|
||||
email: jiraConfig.email,
|
||||
apiToken: jiraConfig.apiToken,
|
||||
@@ -131,6 +132,7 @@ export async function GET() {
|
||||
if (jiraConfig.enabled && jiraConfig.baseUrl && jiraConfig.email && jiraConfig.apiToken) {
|
||||
// Utiliser la config depuis la base de données
|
||||
jiraService = new JiraService({
|
||||
enabled: jiraConfig.enabled,
|
||||
baseUrl: jiraConfig.baseUrl,
|
||||
email: jiraConfig.email,
|
||||
apiToken: jiraConfig.apiToken,
|
||||
|
||||
40
src/app/api/tfs/delete-all/route.ts
Normal file
40
src/app/api/tfs/delete-all/route.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { tfsService } from '@/services/tfs';
|
||||
|
||||
/**
|
||||
* Supprime toutes les tâches TFS de la base de données locale
|
||||
*/
|
||||
export async function DELETE() {
|
||||
try {
|
||||
console.log('🔄 Début de la suppression des tâches TFS...');
|
||||
|
||||
// Supprimer via le service singleton
|
||||
const result = await tfsService.deleteAllTasks();
|
||||
|
||||
if (result.success) {
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: result.deletedCount > 0
|
||||
? `${result.deletedCount} tâche(s) TFS supprimée(s) avec succès`
|
||||
: 'Aucune tâche TFS trouvée à supprimer',
|
||||
data: {
|
||||
deletedCount: result.deletedCount
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: result.error || 'Erreur lors de la suppression',
|
||||
}, { status: 500 });
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Erreur lors de la suppression des tâches TFS:', error);
|
||||
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: 'Erreur lors de la suppression des tâches TFS',
|
||||
details: error instanceof Error ? error.message : 'Erreur inconnue'
|
||||
}, { status: 500 });
|
||||
}
|
||||
}
|
||||
79
src/app/api/tfs/sync/route.ts
Normal file
79
src/app/api/tfs/sync/route.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { tfsService } from '@/services/tfs';
|
||||
|
||||
/**
|
||||
* Route POST /api/tfs/sync
|
||||
* Synchronise les Pull Requests TFS/Azure DevOps avec la base locale
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export async function POST(_request: Request) {
|
||||
try {
|
||||
console.log('🔄 Début de la synchronisation TFS manuelle...');
|
||||
|
||||
// Effectuer la synchronisation via le service singleton
|
||||
const result = await tfsService.syncTasks();
|
||||
|
||||
if (result.success) {
|
||||
return NextResponse.json({
|
||||
message: 'Synchronisation TFS terminée avec succès',
|
||||
data: result,
|
||||
});
|
||||
} else {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Synchronisation TFS terminée avec des erreurs',
|
||||
data: result,
|
||||
},
|
||||
{ status: 207 } // Multi-Status
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('❌ Erreur API sync TFS:', error);
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Erreur interne lors de la synchronisation',
|
||||
details: error instanceof Error ? error.message : 'Erreur inconnue',
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Route GET /api/tfs/sync
|
||||
* Teste la connexion TFS
|
||||
*/
|
||||
export async function GET() {
|
||||
try {
|
||||
// Tester la connexion via le service singleton
|
||||
const isConnected = await tfsService.testConnection();
|
||||
|
||||
if (isConnected) {
|
||||
return NextResponse.json({
|
||||
message: 'Connexion TFS OK',
|
||||
connected: true,
|
||||
});
|
||||
} else {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Connexion TFS échouée',
|
||||
connected: false,
|
||||
},
|
||||
{ status: 401 }
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('❌ Erreur test connexion TFS:', error);
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Erreur interne',
|
||||
details: error instanceof Error ? error.message : 'Erreur inconnue',
|
||||
connected: false,
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
71
src/app/api/tfs/test/route.ts
Normal file
71
src/app/api/tfs/test/route.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { tfsService } from '@/services/tfs';
|
||||
|
||||
/**
|
||||
* Route GET /api/tfs/test
|
||||
* Teste uniquement la connexion TFS/Azure DevOps sans effectuer de synchronisation
|
||||
*/
|
||||
export async function GET() {
|
||||
try {
|
||||
console.log('🔄 Test de connexion TFS...');
|
||||
|
||||
// Valider la configuration via le service singleton
|
||||
const configValidation = await tfsService.validateConfig();
|
||||
if (!configValidation.valid) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Configuration TFS invalide',
|
||||
connected: false,
|
||||
details: configValidation.error,
|
||||
},
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Tester la connexion
|
||||
const isConnected = await tfsService.testConnection();
|
||||
|
||||
if (isConnected) {
|
||||
// Test approfondi : récupérer des métadonnées
|
||||
try {
|
||||
const repositories = await tfsService.getMetadata();
|
||||
return NextResponse.json({
|
||||
message: 'Connexion Azure DevOps réussie',
|
||||
connected: true,
|
||||
details: {
|
||||
repositoriesCount: repositories.repositories.length,
|
||||
},
|
||||
});
|
||||
} catch (repoError) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Connexion OK mais accès aux repositories limité',
|
||||
connected: false,
|
||||
details: `Vérifiez les permissions du token PAT: ${repoError instanceof Error ? repoError.message : 'Erreur inconnue'}`,
|
||||
},
|
||||
{ status: 403 }
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Connexion Azure DevOps échouée',
|
||||
connected: false,
|
||||
details: "Vérifiez l'URL d'organisation et le token PAT",
|
||||
},
|
||||
{ status: 401 }
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('❌ Erreur test connexion TFS:', error);
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Erreur interne',
|
||||
connected: false,
|
||||
details: error instanceof Error ? error.message : 'Erreur inconnue',
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -7,11 +7,15 @@ export const dynamic = 'force-dynamic';
|
||||
export default async function IntegrationsSettingsPage() {
|
||||
// Fetch data server-side
|
||||
// Preferences are now available via context
|
||||
const jiraConfig = await userPreferencesService.getJiraConfig();
|
||||
const [jiraConfig, tfsConfig] = await Promise.all([
|
||||
userPreferencesService.getJiraConfig(),
|
||||
userPreferencesService.getTfsConfig()
|
||||
]);
|
||||
|
||||
return (
|
||||
<IntegrationsSettingsPageClient
|
||||
initialJiraConfig={jiraConfig}
|
||||
initialTfsConfig={tfsConfig}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user