157 lines
5.1 KiB
TypeScript
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
|
|
}
|
|
}
|
|
}
|