NeahNew/lib/services/integration-service.ts
2025-05-06 15:36:15 +02:00

157 lines
5.1 KiB
TypeScript

import { prisma } from '@/lib/prisma';
import { LeantimeService } from './leantime-service';
import { OutlineService } from './outline-service';
import { RocketChatService } from './rocketchat-service';
interface IntegrationResult {
success: boolean;
error?: string;
data?: {
leantimeProjectId?: number;
outlineCollectionId?: string;
rocketChatChannelId?: string;
giteaRepositoryUrl?: string;
penpotProjectId?: string;
};
}
export class IntegrationService {
private leantimeService: LeantimeService;
private outlineService: OutlineService;
private rocketChatService: RocketChatService;
constructor() {
this.leantimeService = new LeantimeService();
this.outlineService = new OutlineService();
this.rocketChatService = new RocketChatService();
}
/**
* Set up all integrations for a mission
* @param missionId The mission ID
* @returns Integration result
*/
async setupIntegrationsForMission(missionId: string): Promise<IntegrationResult> {
try {
// Get complete mission data with users
const mission = await prisma.mission.findUnique({
where: { id: missionId },
include: {
missionUsers: {
include: {
user: true
}
},
attachments: true
}
});
if (!mission) {
throw new Error(`Mission not found: ${missionId}`);
}
// These fields will store the IDs of created resources
let leantimeProjectId: number | undefined;
let outlineCollectionId: string | undefined;
let rocketChatChannelId: string | undefined;
try {
// Step 1: Create Leantime project
leantimeProjectId = await this.leantimeService.createProject(mission);
console.log(`Leantime project created with ID: ${leantimeProjectId}`);
// Step 2: Create Outline collection
outlineCollectionId = await this.outlineService.createCollection(mission);
console.log(`Outline collection created with ID: ${outlineCollectionId}`);
// Step 3: Create Rocket.Chat channel
rocketChatChannelId = await this.rocketChatService.createChannel(mission);
console.log(`Rocket.Chat channel created with ID: ${rocketChatChannelId}`);
// Add integrations for specific services
if (mission.services.includes('gite')) {
// TODO: Add Gitea integration when API docs are available
console.log('Gitea service requested but integration not implemented yet');
}
if (mission.services.includes('artlab')) {
// TODO: Add Penpot integration when API docs are available
console.log('Artlab service requested but integration not implemented yet');
}
// Update the mission with the integration IDs
await prisma.mission.update({
where: { id: missionId },
data: {
leantimeProjectId: leantimeProjectId.toString(),
outlineCollectionId: outlineCollectionId,
rocketChatChannelId: rocketChatChannelId,
// giteaRepositoryUrl and penpotProjectId will be added when implemented
}
});
return {
success: true,
data: {
leantimeProjectId,
outlineCollectionId,
rocketChatChannelId
}
};
} catch (error) {
console.error('Error setting up integrations:', error);
// Rollback any created resources
await this.rollbackIntegrations(leantimeProjectId, outlineCollectionId, rocketChatChannelId);
// Delete the mission itself since an integration failed
await prisma.mission.delete({
where: { id: missionId }
});
return {
success: false,
error: `Integration failed: ${error instanceof Error ? error.message : String(error)}`
};
}
} catch (error) {
console.error('Error in integration setup:', error);
return {
success: false,
error: `Integration setup failed: ${error instanceof Error ? error.message : String(error)}`
};
}
}
/**
* Rollback integrations if any step fails
* @param leantimeProjectId The Leantime project ID to delete
* @param outlineCollectionId The Outline collection ID to delete
* @param rocketChatChannelId The Rocket.Chat channel ID to delete
*/
private async rollbackIntegrations(
leantimeProjectId?: number,
outlineCollectionId?: string,
rocketChatChannelId?: string
): Promise<void> {
try {
// Attempt to delete Leantime project
if (leantimeProjectId) {
await this.leantimeService.deleteProject(leantimeProjectId);
}
// Attempt to delete Outline collection
if (outlineCollectionId) {
await this.outlineService.deleteCollection(outlineCollectionId);
}
// Attempt to delete Rocket.Chat channel
if (rocketChatChannelId) {
await this.rocketChatService.deleteChannel(rocketChatChannelId);
}
} catch (error) {
console.error('Error during rollback:', error);
// Even if rollback fails, we continue with mission deletion
}
}
}