diff --git a/app/api/missions/route.ts b/app/api/missions/route.ts index 0fd9ee78..f3f07c4f 100644 --- a/app/api/missions/route.ts +++ b/app/api/missions/route.ts @@ -5,6 +5,13 @@ import { prisma } from '@/lib/prisma'; import { getPublicUrl } from '@/lib/s3'; import { S3_CONFIG } from '@/lib/s3'; import { N8nService } from '@/lib/services/n8n-service'; +import { MissionUser, Prisma } from '@prisma/client'; + +interface MissionUserInput { + role: string; + userId: string; + missionId: string; +} // Helper function to check authentication async function checkAuth(request: Request, body?: any) { @@ -143,170 +150,118 @@ export async function GET(request: Request) { // POST endpoint to create a new mission export async function POST(request: Request) { try { - const body = await request.json(); - const auth = await checkAuth(request, body); - if (!auth.authorized || !auth.userId) { + const session = await getServerSession(authOptions); + if (!session?.user) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } - // Check for existing mission with the same name + const body = await request.json(); + const { name, oddScope, niveau, intention, missionType, donneurDOrdre, projection, services, participation, profils, guardians, volunteers } = body; + + // Check if mission with same name exists const existingMission = await prisma.mission.findFirst({ - where: { - name: body.name - } + where: { name } }); if (existingMission) { - return NextResponse.json({ - error: 'A mission with this name already exists', - existingMission - }, { status: 409 }); + return NextResponse.json({ error: 'A mission with this name already exists' }, { status: 400 }); } - // Validate required fields - if (!body.name || !body.niveau || !body.intention || !body.missionType || !body.donneurDOrdre || !body.projection) { - return NextResponse.json({ - error: 'Missing required fields', - required: { - name: true, - niveau: true, - intention: true, - missionType: true, - donneurDOrdre: true, - projection: true - }, - received: { - name: !!body.name, - niveau: !!body.niveau, - intention: !!body.intention, - missionType: !!body.missionType, - donneurDOrdre: !!body.donneurDOrdre, - projection: !!body.projection - } - }, { status: 400 }); - } - - // Create mission with default values + // Create the mission const mission = await prisma.mission.create({ data: { - name: body.name, - oddScope: body.oddScope || [], - niveau: body.niveau || [], - intention: body.intention || [], - missionType: body.missionType || 'hybrid', - donneurDOrdre: body.donneurDOrdre || [], - projection: body.projection || [], - services: body.services || [], - profils: body.profils || [], - creatorId: auth.userId + name, + oddScope, + niveau, + intention, + missionType, + donneurDOrdre, + projection, + services, + profils, + creatorId: session.user.id } }); - // Add guardians if provided - if (body.guardians) { - const guardianRoles = ['gardien-temps', 'gardien-parole', 'gardien-memoire']; - const guardianEntries = Object.entries(body.guardians) - .filter(([role, userId]) => guardianRoles.includes(role) && userId) - .map(([role, userId]) => ({ - role, - userId: userId as string, - missionId: mission.id - })); - - if (guardianEntries.length > 0) { + // Add guardians and volunteers + if (guardians || volunteers) { + const missionUsers: MissionUserInput[] = []; + + // Add guardians + if (guardians) { + Object.entries(guardians).forEach(([role, userId]) => { + if (userId) { + missionUsers.push({ + role, + userId: userId as string, + missionId: mission.id + }); + } + }); + } + + // Add volunteers + if (volunteers && Array.isArray(volunteers)) { + volunteers.forEach(userId => { + if (userId) { + missionUsers.push({ + role: 'volontaire', + userId, + missionId: mission.id + }); + } + }); + } + + if (missionUsers.length > 0) { await prisma.missionUser.createMany({ - data: guardianEntries + data: missionUsers }); } } - - // Add volunteers if provided - if (body.volunteers && body.volunteers.length > 0) { - const volunteerEntries = body.volunteers.map((userId: string) => ({ - role: 'volontaire', - userId, - missionId: mission.id - })); - - await prisma.missionUser.createMany({ - data: volunteerEntries - }); - } - try { - // Trigger the n8n workflow - console.log('About to trigger n8n workflow with data:', { - missionId: mission.id, - name: mission.name, - creatorId: auth.userId, - fullData: body - }); - - const n8nService = new N8nService(); - const workflowResult = await n8nService.createMission({ - ...body, - missionId: mission.id, - creatorId: auth.userId - }); + // Trigger n8n workflow + const n8nService = new N8nService(); + console.log('About to trigger n8n workflow with data:', { + missionId: mission.id, + name: mission.name, + creatorId: mission.creatorId, + fullData: body + }); - console.log('Received workflow result:', workflowResult); + const workflowResult = await n8nService.createMission({ + ...body, + missionId: mission.id, + creatorId: mission.creatorId + }); - // Update mission with integration results - if (workflowResult.results) { - console.log('Processing workflow results:', workflowResult.results); - const updateData: any = {}; - - // Update fields based on workflow results - if (workflowResult.results.gitRepo?.html_url) { - updateData.giteaRepositoryUrl = workflowResult.results.gitRepo.html_url; - } - if (workflowResult.results.leantimeProject?.result) { - updateData.leantimeProjectId = workflowResult.results.leantimeProject.result.toString(); - } - if (workflowResult.results.rocketChatChannel?.channel?._id) { - updateData.rocketChatChannelId = workflowResult.results.rocketChatChannel.channel._id; - } - if (workflowResult.results.docCollection?.id) { - updateData.outlineCollectionId = workflowResult.results.docCollection.id; - } + console.log('Received workflow result:', workflowResult); - console.log('Updating mission with integration data:', updateData); + // Process workflow results + const results = workflowResult.results || {}; + console.log('Processing workflow results:', results); - // Update mission with integration data - await prisma.mission.update({ - where: { id: mission.id }, - data: updateData - }); - } + // Update mission with integration data + const integrationData: Prisma.MissionUncheckedUpdateInput = { + leantimeProjectId: results.leantimeProjectId?.toString(), + outlineCollectionId: results.outlineCollectionId?.toString(), + rocketChatChannelId: results.rocketChatChannelId?.toString(), + giteaRepositoryUrl: results.giteaRepositoryUrl?.toString() + }; - return NextResponse.json({ - success: true, - mission: { - id: mission.id, - name: mission.name, - createdAt: mission.createdAt - }, - workflow: { - status: workflowResult.success ? 'success' : 'partial_success', - data: workflowResult, - errors: workflowResult.errors || [] - } - }); - } catch (workflowError) { - // If workflow fails completely, delete the mission and report failure - console.error('Workflow error:', workflowError); - await prisma.mission.delete({ where: { id: mission.id } }); - - return NextResponse.json({ - error: 'Failed to set up external services', - details: workflowError instanceof Error ? workflowError.message : String(workflowError) - }, { status: 500 }); - } + console.log('Updating mission with integration data:', integrationData); + + const updatedMission = await prisma.mission.update({ + where: { id: mission.id }, + data: integrationData + }); + + return NextResponse.json(updatedMission); } catch (error) { console.error('Error creating mission:', error); - return NextResponse.json({ - error: 'Internal server error', - details: error instanceof Error ? error.message : String(error) - }, { status: 500 }); + return NextResponse.json( + { error: 'Failed to create mission' }, + { status: 500 } + ); } } \ No newline at end of file diff --git a/lib/services/n8n-service.ts b/lib/services/n8n-service.ts index 1944ff6e..35642bcb 100644 --- a/lib/services/n8n-service.ts +++ b/lib/services/n8n-service.ts @@ -47,7 +47,12 @@ export class N8nService { return { success: true, results: { - message: response.data + message: response.data, + // Add default empty integration results + leantimeProjectId: null, + outlineCollectionId: null, + rocketChatChannelId: null, + giteaRepositoryUrl: null } }; } @@ -65,7 +70,18 @@ export class N8nService { throw new Error(`Workflow execution failed: ${response.data.message || 'Unknown error'}`); } - return response.data; + // Ensure the response has the expected structure + const result = response.data; + if (!result.results) { + result.results = { + leantimeProjectId: null, + outlineCollectionId: null, + rocketChatChannelId: null, + giteaRepositoryUrl: null + }; + } + + return result; } catch (error) { console.error('Error triggering n8n workflow:', { error: error instanceof Error ? error.message : String(error),