mission-tab deletemission
This commit is contained in:
parent
9824e54843
commit
aafe4d7035
253
MISSION_INTEGRATION_IDS_ISSUE_FIX.md
Normal file
253
MISSION_INTEGRATION_IDS_ISSUE_FIX.md
Normal file
@ -0,0 +1,253 @@
|
||||
# Fix: IDs d'Intégration Vides lors de la Suppression
|
||||
|
||||
## 🔍 Problème Identifié
|
||||
|
||||
Lors de la suppression d'une mission, N8N reçoit des IDs vides :
|
||||
|
||||
```json
|
||||
{
|
||||
"missionId": "cd0225cf-8dfd-4bf0-a20a-6aa9c04ebb42",
|
||||
"name": "Creation",
|
||||
"repoName": "",
|
||||
"leantimeProjectId": 0,
|
||||
"documentationCollectionId": "",
|
||||
"rocketchatChannelId": "",
|
||||
"giteaRepositoryUrl": null,
|
||||
"outlineCollectionId": null,
|
||||
"rocketChatChannelId": null
|
||||
}
|
||||
```
|
||||
|
||||
**Cause** : Les IDs retournés par N8N lors de la création ne sont **pas sauvegardés en base**.
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Analyse du Problème
|
||||
|
||||
### Flow Actuel
|
||||
|
||||
```
|
||||
1. POST /api/missions → Crée mission en Prisma
|
||||
2. Upload logo dans Minio
|
||||
3. POST N8N webhook → N8N crée intégrations
|
||||
4. N8N → POST /mission-created (avec IDs)
|
||||
5. ❌ Endpoint cherche mission par name + creatorId (peut échouer)
|
||||
6. ❌ IDs jamais sauvegardés
|
||||
7. ❌ Lors de suppression → IDs vides
|
||||
```
|
||||
|
||||
### Problèmes Identifiés
|
||||
|
||||
1. **Recherche de mission fragile** : L'endpoint `/mission-created` cherche par `name` + `creatorId`, ce qui peut échouer si :
|
||||
- Plusieurs missions ont le même nom
|
||||
- Le nom a changé
|
||||
- Le creatorId ne correspond pas exactement
|
||||
|
||||
2. **missionId non envoyé** : On n'envoie pas le `missionId` à N8N, donc N8N ne peut pas le renvoyer
|
||||
|
||||
3. **N8N ne renvoie peut-être pas missionId** : Même si on l'envoie, N8N doit le renvoyer dans `/mission-created`
|
||||
|
||||
---
|
||||
|
||||
## ✅ Solutions Implémentées
|
||||
|
||||
### 1. Envoyer missionId à N8N
|
||||
|
||||
**Fichier** : `app/api/missions/route.ts`
|
||||
|
||||
```typescript
|
||||
const n8nData = {
|
||||
...body,
|
||||
missionId: mission.id, // ✅ Send missionId so N8N can return it
|
||||
creatorId: userId,
|
||||
logoPath: logoPath,
|
||||
logoUrl: logoUrl,
|
||||
config: { ... }
|
||||
};
|
||||
```
|
||||
|
||||
**Avantage** : N8N peut maintenant renvoyer le `missionId` dans `/mission-created`
|
||||
|
||||
### 2. Améliorer la Recherche de Mission
|
||||
|
||||
**Fichier** : `app/api/missions/mission-created/route.ts`
|
||||
|
||||
```typescript
|
||||
// Prefer missionId if provided, otherwise use name + creatorId
|
||||
let mission;
|
||||
|
||||
if (body.missionId) {
|
||||
// ✅ Use missionId if provided (more reliable)
|
||||
mission = await prisma.mission.findUnique({
|
||||
where: { id: body.missionId }
|
||||
});
|
||||
} else if (body.name && body.creatorId) {
|
||||
// Fallback to name + creatorId (for backward compatibility)
|
||||
mission = await prisma.mission.findFirst({
|
||||
where: {
|
||||
name: body.name,
|
||||
creatorId: body.creatorId
|
||||
},
|
||||
orderBy: { createdAt: 'desc' }
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
**Avantages** :
|
||||
- ✅ Recherche par `missionId` (plus fiable)
|
||||
- ✅ Fallback vers `name` + `creatorId` (rétrocompatibilité)
|
||||
- ✅ Gestion d'erreurs améliorée
|
||||
|
||||
---
|
||||
|
||||
## 📋 Format de Requête N8N → /mission-created
|
||||
|
||||
### Format Recommandé (avec missionId)
|
||||
|
||||
```json
|
||||
{
|
||||
"missionId": "cd0225cf-8dfd-4bf0-a20a-6aa9c04ebb42",
|
||||
"name": "Creation",
|
||||
"creatorId": "user-id",
|
||||
"gitRepoUrl": "https://gite.slm-lab.net/alma/creation",
|
||||
"leantimeProjectId": "123",
|
||||
"documentationCollectionId": "collection-456",
|
||||
"rocketchatChannelId": "channel-789"
|
||||
}
|
||||
```
|
||||
|
||||
### Format de Fallback (sans missionId)
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Creation",
|
||||
"creatorId": "user-id",
|
||||
"gitRepoUrl": "https://gite.slm-lab.net/alma/creation",
|
||||
"leantimeProjectId": "123",
|
||||
"documentationCollectionId": "collection-456",
|
||||
"rocketchatChannelId": "channel-789"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Action Requise dans N8N
|
||||
|
||||
### Modifier le Node "Save Mission To API"
|
||||
|
||||
Le node N8N doit inclure `missionId` dans le body :
|
||||
|
||||
**Avant** :
|
||||
```json
|
||||
{
|
||||
"name": "{{ name }}",
|
||||
"creatorId": "{{ creatorId }}",
|
||||
"gitRepoUrl": "{{ gitRepo.html_url }}",
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
**Après** :
|
||||
```json
|
||||
{
|
||||
"missionId": "{{ missionId }}", // ✅ Ajouter missionId
|
||||
"name": "{{ name }}",
|
||||
"creatorId": "{{ creatorId }}",
|
||||
"gitRepoUrl": "{{ gitRepo.html_url }}",
|
||||
"leantimeProjectId": "{{ leantimeProject.result[0] }}",
|
||||
"documentationCollectionId": "{{ docCollection.data.id }}",
|
||||
"rocketchatChannelId": "{{ rocketChatChannel.channel._id }}",
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
**Où trouver missionId dans N8N** :
|
||||
- Il est dans les données initiales : `{{ $node['Process Mission Data'].json.missionId }}`
|
||||
- Ou dans le body original : `{{ $json.missionId }}`
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Tests
|
||||
|
||||
### Test 1: Vérifier missionId est envoyé à N8N
|
||||
|
||||
1. Créer une mission
|
||||
2. Vérifier les logs :
|
||||
```
|
||||
Sending to N8N: { missionId: "...", ... }
|
||||
```
|
||||
3. ✅ `missionId` doit être présent
|
||||
|
||||
### Test 2: Vérifier N8N renvoie missionId
|
||||
|
||||
1. Vérifier les logs N8N
|
||||
2. Vérifier que le node "Save Mission To API" inclut `missionId`
|
||||
3. ✅ `missionId` doit être dans le body envoyé à `/mission-created`
|
||||
|
||||
### Test 3: Vérifier IDs sont sauvegardés
|
||||
|
||||
1. Créer une mission
|
||||
2. Vérifier les logs :
|
||||
```
|
||||
=== Mission Created Webhook Received ===
|
||||
Looking up mission by ID: ...
|
||||
Mission updated successfully: { ... }
|
||||
```
|
||||
3. Vérifier en base :
|
||||
```sql
|
||||
SELECT id, name, giteaRepositoryUrl, leantimeProjectId,
|
||||
outlineCollectionId, rocketChatChannelId
|
||||
FROM Mission
|
||||
WHERE id = '...';
|
||||
```
|
||||
4. ✅ Les IDs doivent être présents
|
||||
|
||||
### Test 4: Vérifier Suppression
|
||||
|
||||
1. Supprimer une mission avec IDs sauvegardés
|
||||
2. Vérifier les logs :
|
||||
```
|
||||
Sending deletion data to N8N: {
|
||||
repoName: "creation",
|
||||
leantimeProjectId: 123,
|
||||
...
|
||||
}
|
||||
```
|
||||
3. ✅ Les IDs doivent être présents (pas vides)
|
||||
|
||||
---
|
||||
|
||||
## 📝 Checklist
|
||||
|
||||
- [x] Envoyer `missionId` à N8N lors de la création
|
||||
- [x] Améliorer recherche de mission dans `/mission-created`
|
||||
- [ ] **Modifier N8N workflow pour inclure `missionId` dans `/mission-created`**
|
||||
- [ ] Tester création avec `missionId`
|
||||
- [ ] Tester sauvegarde des IDs
|
||||
- [ ] Tester suppression avec IDs sauvegardés
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Action Immédiate Requise
|
||||
|
||||
**Modifier le workflow N8N** pour inclure `missionId` dans le node "Save Mission To API" :
|
||||
|
||||
1. Ouvrir le workflow N8N `NeahMissionCreate`
|
||||
2. Trouver le node "Save Mission To API"
|
||||
3. Ajouter `missionId` dans le body :
|
||||
```json
|
||||
{
|
||||
"missionId": "={{ $node['Process Mission Data'].json.missionId }}",
|
||||
...
|
||||
}
|
||||
```
|
||||
4. Sauvegarder et activer le workflow
|
||||
|
||||
---
|
||||
|
||||
**Date**: $(date)
|
||||
**Version**: 1.1
|
||||
**Fichiers Modifiés**:
|
||||
- `app/api/missions/route.ts` (ajout missionId dans n8nData)
|
||||
- `app/api/missions/mission-created/route.ts` (recherche par missionId)
|
||||
|
||||
@ -53,20 +53,22 @@ export async function POST(request: Request) {
|
||||
console.log('Received mission-created data:', JSON.stringify(body, null, 2));
|
||||
|
||||
// Validation des champs requis
|
||||
if (!body.name || !body.creatorId) {
|
||||
console.error('Missing required fields:', {
|
||||
hasName: !!body.name,
|
||||
hasCreatorId: !!body.creatorId
|
||||
});
|
||||
return NextResponse.json(
|
||||
{ error: 'Missing required fields: name and creatorId' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
// Prefer missionId if provided, otherwise use name + creatorId
|
||||
let mission;
|
||||
|
||||
// Trouver la mission par name + creatorId
|
||||
// On cherche la mission la plus récente avec ce nom et ce créateur
|
||||
const mission = await prisma.mission.findFirst({
|
||||
if (body.missionId) {
|
||||
// ✅ Use missionId if provided (more reliable)
|
||||
console.log('Looking up mission by ID:', body.missionId);
|
||||
mission = await prisma.mission.findUnique({
|
||||
where: { id: body.missionId }
|
||||
});
|
||||
} else if (body.name && body.creatorId) {
|
||||
// Fallback to name + creatorId (for backward compatibility)
|
||||
console.log('Looking up mission by name + creatorId:', {
|
||||
name: body.name,
|
||||
creatorId: body.creatorId
|
||||
});
|
||||
mission = await prisma.mission.findFirst({
|
||||
where: {
|
||||
name: body.name,
|
||||
creatorId: body.creatorId
|
||||
@ -75,9 +77,21 @@ export async function POST(request: Request) {
|
||||
createdAt: 'desc' // Prendre la plus récente
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.error('Missing required fields:', {
|
||||
hasMissionId: !!body.missionId,
|
||||
hasName: !!body.name,
|
||||
hasCreatorId: !!body.creatorId
|
||||
});
|
||||
return NextResponse.json(
|
||||
{ error: 'Missing required fields: missionId OR (name and creatorId)' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
if (!mission) {
|
||||
console.error('Mission not found:', {
|
||||
missionId: body.missionId,
|
||||
name: body.name,
|
||||
creatorId: body.creatorId
|
||||
});
|
||||
|
||||
@ -370,8 +370,10 @@ export async function POST(request: Request) {
|
||||
|
||||
const n8nData = {
|
||||
...body,
|
||||
missionId: mission.id, // ✅ Send missionId so N8N can return it in /mission-created
|
||||
creatorId: userId,
|
||||
logoPath: logoPath,
|
||||
logoUrl: logoUrl, // ✅ Send logo URL for N8N to use
|
||||
config: {
|
||||
N8N_API_KEY: process.env.N8N_API_KEY,
|
||||
MISSION_API_URL: process.env.NEXT_PUBLIC_API_URL
|
||||
|
||||
Loading…
Reference in New Issue
Block a user