9 lines
28 KiB
JavaScript
9 lines
28 KiB
JavaScript
"use strict";exports.id=297,exports.ids=[297],exports.modules={60297:(e,t,o)=>{o.d(t,{a:()=>c});var r=o(79464),s=o(94612);class i{constructor(){this.apiUrl=process.env.LEANTIME_API_URL||"",this.apiToken=process.env.LEANTIME_TOKEN||"",this.apiUserId=null,console.log("LeantimeService initialized with URL:",this.apiUrl)}getApiEndpoint(){return this.apiUrl.endsWith("/api/jsonrpc")?this.apiUrl:this.apiUrl.endsWith("/")?`${this.apiUrl}api/jsonrpc`:`${this.apiUrl}/api/jsonrpc`}async createProject(e){try{let t="a"===e.niveau.toLowerCase()?await this.getClientIdByName("Enkun"):await this.getClientIdByName("ONG");if(!t)throw Error(`Leantime client not found for mission type ${e.niveau}`);let o=new Date,r=new Date;r.setFullYear(o.getFullYear()+1);let i=o.toISOString().split("T")[0],a=r.toISOString().split("T")[0];console.log(`Creating project with dates: start=${i}, end=${a}`);let n={name:e.name,clientId:t,details:e.intention||"",type:"project",start:i,end:a,status:"open",psettings:"restricted"};console.log("Creating project with data:",JSON.stringify(n,null,2));let l={method:"leantime.rpc.Projects.Projects.addProject",jsonrpc:"2.0",id:1,params:{values:n}};console.log("Project creation payload:",JSON.stringify(l,null,2));let c=await s.A.post(this.getApiEndpoint(),l,{headers:{"Content-Type":"application/json","X-API-Key":this.apiToken}});if(console.log("Project creation response status:",c.status),console.log("Project creation response data:",JSON.stringify(c.data,null,2)),!c.data||!c.data.result)throw Error(`Failed to create Leantime project: ${JSON.stringify(c.data)}`);let d=c.data.result[0];if(console.log(`Created Leantime project with ID: ${d}`),e.logo&&await this.setProjectAvatar(d,e.logo),e.missionUsers&&e.missionUsers.length>0)await this.assignUsersToProject(d,e.missionUsers);else{let e=this.getProjectUrl(d);console.log(`ℹ️ No users to assign. Project created at: ${e}`)}return d}catch(e){throw s.A.isAxiosError(e)&&e.response&&console.error("Axios Error Details:",{status:e.response.status,data:e.response.data,headers:e.response.headers}),console.error("Error creating Leantime project:",e),Error(`Leantime integration failed: ${e instanceof Error?e.message:String(e)}`)}}async setProjectAvatar(e,t){try{let o=await fetch(`/api/missions/image/${t}`);if(!o.ok)throw Error(`Failed to fetch logo file: ${o.statusText}`);let r=new FormData,i=await o.blob();r.append("file",i,"logo.png"),r.append("project",JSON.stringify({id:e}));let a=this.apiUrl.replace("/api/jsonrpc","").replace("/api/jsonrpc.php",""),n=a.endsWith("/")?`${a}api/v1/projects.setProjectAvatar`:`${a}/api/v1/projects.setProjectAvatar`;console.log("Using avatar endpoint:",n);let l=await s.A.post(n,r,{headers:{"Content-Type":"multipart/form-data","X-API-Key":this.apiToken}});if(!l.data||!l.data.success)throw Error(`Failed to set project avatar: ${JSON.stringify(l.data)}`);console.log(`Set avatar for Leantime project ${e}`)}catch(e){console.error("Error setting project avatar:",e)}}async getApiUserId(){if(this.apiUserId)return this.apiUserId;try{let e=await s.A.post(this.getApiEndpoint(),{method:"leantime.rpc.Auth.getCurrentUser",jsonrpc:"2.0",id:1},{headers:{"Content-Type":"application/json","X-API-Key":this.apiToken}});if(e.data&&e.data.result&&e.data.result.id)return this.apiUserId=e.data.result.id,console.log(`Found API user ID: ${this.apiUserId}`),this.apiUserId;return null}catch(e){return console.error("Error getting API user ID:",e),null}}async assignUsersToProject(e,t){let o=this.getProjectUrl(e);console.log(`⚠️ For best results, please assign users manually at: ${o}`),console.log("ℹ️ Automatic user assignment is currently disabled due to API limitations.")}async verifyUserAssignedToProject(e,t){try{console.log(`Verifying if user ${e} is assigned to project ${t}...`);let o=await s.A.post(this.getApiEndpoint(),{method:"leantime.rpc.Projects.Projects.getProjectIdAssignedToUser",jsonrpc:"2.0",id:1,params:{userId:e}},{headers:{"Content-Type":"application/json","X-API-Key":this.apiToken}});if(o.data&&o.data.result&&Array.isArray(o.data.result)){let r=o.data.result.map(e=>String(e)),s=String(t),i=r.includes(s);return console.log(`User ${e} ${i?"is":"is not"} assigned to project ${t}`),i}return console.log(`User ${e} is not assigned to any projects`),!1}catch(t){return console.error(`Error verifying user assignment for user ${e}:`,t),!1}}async assignUserToProject(e,t,o){try{console.log(`Assigning user ${t} to project ${e} with role ${o}`),await new Promise(e=>setTimeout(e,2e3));let r=await s.A.post(this.getApiEndpoint(),{method:"leantime.rpc.Projects.addProjectUser",jsonrpc:"2.0",id:1,params:{projectId:e,userId:t,role:o}},{headers:{"Content-Type":"application/json","X-API-Key":this.apiToken}});if(r.data&&r.data.result)return console.log(`✅ Assigned user ${t} to project ${e} with role ${o}`),!0;return console.warn(`⚠️ Could not assign user ${t} to project ${e}.`),!1}catch(o){return console.error(`Error assigning user ${t} to project ${e}:`,o),console.warn(`⚠️ User assignment failed. The project ${e} was created successfully, but users will need to be added manually.`),!1}}async assignApiUserToProject(e,t){if(console.log(`Assigning API user ${t} to project ${e} as admin`),await this.verifyUserAssignedToProject(t,e))return console.log(`✅ API user ${t} is already assigned to project ${e}`),!0;await new Promise(e=>setTimeout(e,2e3));try{let o=await s.A.post(this.getApiEndpoint(),{method:"leantime.rpc.Projects.addProjectUser",jsonrpc:"2.0",id:1,params:{projectId:e,userId:t,role:"admin"}},{headers:{"Content-Type":"application/json","X-API-Key":this.apiToken}});if(o.data&&o.data.result)return console.log(`✅ API user successfully assigned to project ${e}`),!0}catch(e){console.error("Error assigning API user to project:",e)}return console.warn(`⚠️ Could not assign API user to project ${e}. The project may appear with "New API Access" as the only team member.`),!1}async getClientIdByName(e){try{console.log("Leantime API URL:",this.apiUrl);let t=this.getApiEndpoint();console.log("Using endpoint:",t);let o=await s.A.post(t,{method:"leantime.rpc.Clients.Clients.getAll",jsonrpc:"2.0",id:1,params:{}},{headers:{"Content-Type":"application/json","X-API-Key":this.apiToken}});if(!o.data||!o.data.result)throw Error(`Failed to get clients: ${JSON.stringify(o.data)}`);let r=o.data.result.find(t=>t.name.toLowerCase()===e.toLowerCase());if(r)return parseInt(r.id);return console.log(`Client "${e}" not found. Creating it...`),await new Promise(e=>setTimeout(e,1e3)),await this.createClient(e)}catch(t){console.error("Error getting client by name:",t),s.A.isAxiosError(t)&&t.response?.status===429&&(console.log("Rate limiting detected (429). Waiting before retry..."),await new Promise(e=>setTimeout(e,2e3)));try{return console.log(`Attempting to create client "${e}" after error...`),await this.createClient(e)}catch(e){return console.error("Error creating client:",e),null}}}async createClient(e){try{await new Promise(e=>setTimeout(e,1e3));let t=await s.A.post(this.getApiEndpoint(),{method:"leantime.rpc.Clients.Clients.addClient",jsonrpc:"2.0",id:1,params:{values:{name:e,street:"",zip:"",city:"",state:"",country:"",phone:"",internet:"",email:""}}},{headers:{"Content-Type":"application/json","X-API-Key":this.apiToken}});if(!t.data||!t.data.result)throw Error(`Failed to create client: ${JSON.stringify(t.data)}`);let o=parseInt(t.data.result);return console.log(`Created client "${e}" with ID: ${o}`),o}catch(t){if(s.A.isAxiosError(t)&&t.response?.status===429){console.log("Rate limiting detected (429). Waiting and retrying..."),await new Promise(e=>setTimeout(e,3e3));try{let t=await s.A.post(this.getApiEndpoint(),{method:"leantime.rpc.Clients.Clients.addClient",jsonrpc:"2.0",id:1,params:{values:{name:e,street:"",zip:"",city:"",state:"",country:"",phone:"",internet:"",email:""}}},{headers:{"Content-Type":"application/json","X-API-Key":this.apiToken}});if(t.data&&t.data.result){let o=parseInt(t.data.result);return console.log(`Created client "${e}" with ID: ${o} (retry)`),o}}catch(e){console.error("Error on retry:",e)}}return console.error(`Error creating client "${e}":`,t),null}}async getUserByEmail(e){try{console.log(`Looking up user with email: ${e}`);try{let t=await s.A.post(this.getApiEndpoint(),{method:"leantime.rpc.Users.Users.getUserByEmail",jsonrpc:"2.0",id:1,params:{email:e}},{headers:{"Content-Type":"application/json","X-API-Key":this.apiToken}});if(t.data&&t.data.result&&!1!==t.data.result&&t.data.result.id)return console.log(`Found user by direct email lookup: ${t.data.result.id}`),t.data.result.id}catch(e){console.log("Direct email lookup failed, trying alternate method..."),s.A.isAxiosError(e)&&e.response?.status===429&&(console.log("Rate limiting detected (429). Waiting before retry..."),await new Promise(e=>setTimeout(e,1e3)))}try{let t=await s.A.post(this.getApiEndpoint(),{method:"leantime.rpc.Users.Users.getAll",jsonrpc:"2.0",id:1},{headers:{"Content-Type":"application/json","X-API-Key":this.apiToken}});if(!t.data||!t.data.result)throw Error(`Failed to get users: ${JSON.stringify(t.data)}`);let o=t.data.result,r=o.find(t=>t.email===e||t.username===e);if(!r){let t=e.toLowerCase();r=o.find(e=>e.email&&e.email.toLowerCase()===t||e.username&&e.username.toLowerCase()===t)}if(r)return console.log(`Found user with email ${e}: ID ${r.id}`),r.id}catch(e){s.A.isAxiosError(e)&&e.response?.status===429?console.log("Rate limiting detected (429). Consider user assignment through manual UI."):console.error("Error fetching users:",e)}return console.log(`No user found with email ${e}`),null}catch(e){return console.error("Error getting user by email:",e),null}}async deleteProject(e){try{console.log(`Attempting to delete Leantime project ${e} using REST API approach`);let t=this.apiUrl.replace("/api/jsonrpc","").replace("/api/jsonrpc.php",""),o=t.endsWith("/")?`${t}api/v1/projects/${e}`:`${t}/api/v1/projects/${e}`;console.log(`Trying REST API deletion via DELETE to: ${o}`);try{let t=await s.A.delete(o,{headers:{"Content-Type":"application/json","X-API-Key":this.apiToken}});if(console.log("REST API Delete response:",JSON.stringify(t.data,null,2)),t.status>=200&&t.status<300)return console.log(`Successfully deleted project ${e} via REST API`),!0}catch(e){console.error("REST API error:",e),s.A.isAxiosError(e)&&console.error("REST API error details:",{status:e.response?.status,data:e.response?.data,message:e.message})}console.log("Trying web interface simulation for project deletion...");let r=t.endsWith("/")?`${t}projects/deleteProject/${e}`:`${t}/projects/deleteProject/${e}`;console.log(`Simulating form submission to: ${r}`);try{let t=await s.A.post(r,{},{headers:{"Content-Type":"application/json","X-API-Key":this.apiToken}});if(console.log("Form submission response:",JSON.stringify(t.data,null,2)),t.status>=200&&t.status<300)return console.log(`Successfully deleted project ${e} via web interface simulation`),!0}catch(e){console.error("Form submission error:",e),s.A.isAxiosError(e)&&console.error("Form submission error details:",{status:e.response?.status,data:e.response?.data,message:e.message})}console.log("Attempting to mark project as archived/inactive as a fallback...");try{let t=await s.A.post(this.getApiEndpoint(),{method:"leantime.rpc.Projects.Projects.updateProject",jsonrpc:"2.0",id:1,params:{id:e,values:{status:"archived"}}},{headers:{"Content-Type":"application/json","X-API-Key":this.apiToken}});if(console.log("Project status update response:",JSON.stringify(t.data,null,2)),t.data&&t.data.result)return console.log(`Successfully marked project ${e} as archived`),!0}catch(e){console.error("Project status update error:",e),s.A.isAxiosError(e)&&console.error("Update error details:",{status:e.response?.status,data:e.response?.data,message:e.message})}console.error(`Failed to delete or archive Leantime project ${e} with all methods.`),console.log(`Please manually delete/archive project ${e} from Leantime.`);let i=this.getProjectUrl(e);return console.log(`Project URL for manual cleanup: ${i}`),!1}catch(t){return console.error(`Error in deleteProject for Leantime project ${e}:`,t),s.A.isAxiosError(t)&&console.error("Error details:",{status:t.response?.status,data:t.response?.data,message:t.message}),!1}}getProjectUrl(e){let t=this.apiUrl.replace("/api/jsonrpc","").replace("/api/jsonrpc.php","");return t.endsWith("/")?`${t}projects/showProject/${e}`:`${t}/projects/showProject/${e}`}}class a{constructor(){this.apiUrl=process.env.OUTLINE_API_URL||"https://chapitre.slm-lab.net/api",this.apiToken=process.env.OUTLINE_API_KEY||"",console.log("OutlineService initialized with URL:",this.apiUrl),console.log("Creating Outline collection with token length:",this.apiToken.length)}async createCollection(e){if(!this.apiToken)throw Error("Outline API token is not configured");console.log("Mission data received:",JSON.stringify({id:e.id,label:e.label,name:e.name,description:e.description},null,2));let t=e.name||e.label||`Mission ${e.id}`;console.log(`Using collection name: "${t}"`);try{let o={name:t,description:e.description||"Mission documentation",color:"#4f46e5",permission:"read",private:!0,sharing:!1};console.log("Sending to Outline API:",JSON.stringify(o,null,2));let r=await s.A.post(`${this.apiUrl}/collections.create`,o,{headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiToken}`}});if(console.log("Outline API response:",JSON.stringify(r.data,null,2)),r.data&&(r.data.data?.id||r.data.id)){let e=r.data.data?.id||r.data.id;try{await this.createWelcomeDocument(e,t)}catch(e){console.warn("Failed to create welcome document, but collection was created:",e)}return e}throw Error("Failed to get collection ID from Outline API response")}catch(e){if(s.A.isAxiosError(e)){if(console.error("Full error response:",JSON.stringify(e.response?.data,null,2)),e.response?.status===401)throw console.error("Outline authentication error:",e.response.data),Error("Outline API authentication failed - check your token");if(e.response?.status===429)throw console.error("Outline rate limit error:",e.response.data),Error("Outline API rate limit exceeded - try again later");throw console.error("Outline API error:",e.response?.data||e.message),Error(`Outline API error: ${e.response?.status} - ${e.message}`)}throw e}}async createWelcomeDocument(e,t){try{let o=await s.A.post(`${this.apiUrl}/documents.create`,{title:`Welcome to ${t}`,text:`# Welcome to ${t}
|
||
|
||
This is your new private collection in Outline. Here you can store and share documents related to this mission.
|
||
|
||
## Getting Started
|
||
|
||
- Use the + button to create new documents
|
||
- Organize documents with headers and lists
|
||
- Share this collection only with team members involved in this mission`,collectionId:e,publish:!0},{headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiToken}`}});console.log("Created welcome document with ID:",o.data?.data?.id||o.data?.id)}catch(e){console.error("Failed to create welcome document:",e)}}async deleteCollection(e){if(!this.apiToken)throw Error("Outline API token is not configured");try{return await s.A.post(`${this.apiUrl}/collections.delete`,{id:e},{headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiToken}`}}),!0}catch(e){return console.error("Error deleting Outline collection:",e),!1}}}class n{constructor(){let e="https://parole.slm-lab.net/channel/City".split("/channel")[0]||"";this.apiUrl=e,this.authToken=process.env.ROCKET_CHAT_TOKEN||"",this.userId=process.env.ROCKET_CHAT_USER_ID||""}async createChannel(e){try{let t=e.missionUsers.map(e=>e.user.email),o=[];for(let e of t){let t=await this.getUserByEmail(e);t?o.push(t.username):console.warn(`User not found in Rocket.Chat: ${e}`)}let r=this.sanitizeChannelName(e.name),i=await s.A.post(`${this.apiUrl}/api/v1/channels.create`,{name:r,members:o,readOnly:!1},{headers:{"Content-Type":"application/json","X-Auth-Token":this.authToken,"X-User-Id":this.userId}});if(!i.data||!i.data.success)throw Error(`Failed to create Rocket.Chat channel: ${JSON.stringify(i.data)}`);let a=i.data.channel._id;return console.log(`Created Rocket.Chat channel with ID: ${a}`),await this.setChannelAdmins(a,e.missionUsers),a}catch(e){throw console.error("Error creating Rocket.Chat channel:",e),Error(`Rocket.Chat integration failed: ${e instanceof Error?e.message:String(e)}`)}}async setChannelAdmins(e,t){try{for(let o of t.filter(e=>"gardien-parole"===e.role)){let t=await this.getUserByEmail(o.user.email);t&&await this.makeUserChannelOwner(e,t._id)}}catch(e){console.error("Error setting channel admins:",e)}}async makeUserChannelOwner(e,t){try{let o=await s.A.post(`${this.apiUrl}/api/v1/channels.addOwner`,{roomId:e,userId:t},{headers:{"Content-Type":"application/json","X-Auth-Token":this.authToken,"X-User-Id":this.userId}});if(!o.data||!o.data.success)throw Error(`Failed to make user channel owner: ${JSON.stringify(o.data)}`);console.log(`Made user ${t} an owner of channel ${e}`)}catch(e){console.error(`Error making user ${t} channel owner:`,e)}}async getUserByEmail(e){try{let t=await s.A.get(`${this.apiUrl}/api/v1/users.list`,{headers:{"X-Auth-Token":this.authToken,"X-User-Id":this.userId}});if(!t.data||!t.data.success)throw Error(`Failed to get users: ${JSON.stringify(t.data)}`);let o=t.data.users.find(t=>t.emails?.some(t=>t.address===e));if(o)return o;let r=e.split("@")[0];return t.data.users.find(e=>e.username===r)||null}catch(e){return console.error("Error getting user by email:",e),null}}sanitizeChannelName(e){let t=e.replace(/[^0-9a-zA-Z-_.]/g,"-");return(t=(t=t.replace(/-+/g,"-")).replace(/^-+|-+$/g,""))||(t="mission-channel"),t.toLowerCase()}async deleteChannel(e){try{let t=await s.A.post(`${this.apiUrl}/api/v1/channels.delete`,{roomId:e},{headers:{"Content-Type":"application/json","X-Auth-Token":this.authToken,"X-User-Id":this.userId}});return t.data&&!0===t.data.success}catch(t){return console.error(`Error deleting Rocket.Chat channel ${e}:`,t),!1}}}class l{constructor(){this.apiUrl=process.env.GITEA_API_URL||"",this.apiToken=process.env.GITEA_API_TOKEN||"",this.owner=process.env.GITEA_OWNER||"",console.log("GiteaService initialized with URL:",this.apiUrl)}getApiEndpoint(e){let t=this.apiUrl.endsWith("/")?this.apiUrl.slice(0,-1):this.apiUrl,o=e.startsWith("/")?e.slice(1):e;return`${t}/api/v1/${o}`}async createRepository(e){try{let t=e.name.toLowerCase().replace(/\s+/g,"-").replace(/[^a-z0-9-]/g,"");console.log(`Creating repository: ${t}`);let o=this.owner.startsWith("@")?this.getApiEndpoint(`org/${this.owner.substring(1)}/repos`):this.getApiEndpoint("user/repos"),r=await s.A.post(o,{name:t,private:!0,auto_init:!0},{headers:{"Content-Type":"application/json",Authorization:`token ${this.apiToken}`}});return console.log(`Repository created: ${r.data.full_name}`),e.missionUsers&&e.missionUsers.length>0&&await this.addCollaborators(r.data.owner.login,t,e.missionUsers),r.data}catch(e){throw s.A.isAxiosError(e)&&e.response&&console.error("Gitea API Error:",{status:e.response.status,data:e.response.data}),console.error("Error creating Gitea repository:",e),Error(`Gitea integration failed: ${e instanceof Error?e.message:String(e)}`)}}async addCollaborators(e,t,o){console.log(`Adding ${o.length} collaborators to ${e}/${t}`);let r=(await this.enrichUsersWithGiteaInfo(o)).map(async o=>{try{if(!o.giteaUsername)return void console.log(`No Gitea username for user ${o.missionUser.user.email}, skipping`);let r="write";"gardien-temps"===o.missionUser.role?r="admin":"observateur"===o.missionUser.role&&(r="read"),console.log(`Adding ${o.giteaUsername} as ${r}`),await s.A.put(this.getApiEndpoint(`repos/${e}/${t}/collaborators/${o.giteaUsername}`),{permission:r},{headers:{"Content-Type":"application/json",Authorization:`token ${this.apiToken}`}}),console.log(`Added ${o.giteaUsername} as collaborator`)}catch(e){console.error(`Error adding collaborator ${o.missionUser.user.email}:`,e)}});await Promise.all(r),console.log("Finished adding collaborators")}async enrichUsersWithGiteaInfo(e){return await Promise.all(e.map(async e=>{let t=null;try{if(!e.user.email)return console.log("User has no email address, skipping"),{missionUser:e,giteaUsername:t};let o=await s.A.get(this.getApiEndpoint("users/search"),{params:{q:e.user.email},headers:{Authorization:`token ${this.apiToken}`}});if(o.data&&o.data.data&&o.data.data.length>0){let r=o.data.data.find(t=>t.email===e.user.email);r?(t=r.username,console.log(`Found exact match Gitea username "${t}" for ${e.user.email}`)):(t=o.data.data[0].username,console.log(`Found closest match Gitea username "${t}" for ${e.user.email}`))}else console.log(`No Gitea user found for email ${e.user.email}`)}catch(t){console.log(`Error searching for Gitea user with email ${e.user.email}:`,t)}return{missionUser:e,giteaUsername:t}}))}async deleteRepository(e,t){try{return await s.A.delete(this.getApiEndpoint(`repos/${e}/${t}`),{headers:{"Content-Type":"application/json",Authorization:`token ${this.apiToken}`}}),console.log(`Repository ${e}/${t} deleted successfully`),!0}catch(o){return console.error(`Error deleting repository ${e}/${t}:`,o),!1}}async createBranch(e,t,o,r="main"){try{let i=(await s.A.get(this.getApiEndpoint(`repos/${e}/${t}/git/refs/heads/${r}`),{headers:{Authorization:`token ${this.apiToken}`}})).data.object.sha;return await s.A.post(this.getApiEndpoint(`repos/${e}/${t}/git/refs`),{ref:`refs/heads/${o}`,sha:i},{headers:{"Content-Type":"application/json",Authorization:`token ${this.apiToken}`}}),console.log(`Branch ${o} created in ${e}/${t}`),!0}catch(r){return console.error(`Error creating branch ${o} in ${e}/${t}:`,r),!1}}async createFile(e,t,o,r,i,a="main"){try{let n=Buffer.from(r).toString("base64");return await s.A.post(this.getApiEndpoint(`repos/${e}/${t}/contents/${o}`),{message:i,content:n,branch:a},{headers:{"Content-Type":"application/json",Authorization:`token ${this.apiToken}`}}),console.log(`File ${o} created in ${e}/${t}`),!0}catch(r){return console.error(`Error creating file ${o} in ${e}/${t}:`,r),!1}}getRepositoryUrl(e){let t=this.apiUrl.replace("/api/v1","");return`${t}/${this.owner}/${e}`}}class c{constructor(){this.leantimeService=new i,this.outlineService=new a,this.rocketChatService=new n,this.giteaService=new l}async setupIntegrationsForMission(e){try{let t,o,i,a,n=await r.z.mission.findUnique({where:{id:e},include:{missionUsers:{include:{user:!0}},attachments:!0}});if(!n)throw Error(`Mission not found: ${e}`);let l={leantime:{success:!1,id:void 0,error:void 0},outline:{success:!1,id:void 0,error:void 0},rocketchat:{success:!1,id:void 0,error:void 0},gitea:{success:!1,url:void 0,error:void 0}},c=!1;try{try{console.log("Starting Leantime project creation..."),t=await this.leantimeService.createProject(n),console.log(`Leantime project created with ID: ${t}`),l.leantime.success=!0,l.leantime.id=t}catch(e){throw console.error("Error creating Leantime project:",e),l.leantime.success=!1,l.leantime.error=e instanceof Error?e.message:String(e),c=!0,e}console.log("Waiting 3 seconds before proceeding to Outline integration..."),await new Promise(e=>setTimeout(e,3e3));try{console.log("Starting Outline collection creation..."),o=await this.outlineService.createCollection(n),console.log(`Outline collection created with ID: ${o}`),l.outline.success=!0,l.outline.id=o}catch(e){console.error("Error creating Outline collection:",e),l.outline.success=!1,l.outline.error=e instanceof Error?e.message:String(e),s.A.isAxiosError(e)&&e.response?.status===401?console.log("⚠️ Outline authentication error. Please check your API credentials."):s.A.isAxiosError(e)&&e.response?.status===429&&console.log("⚠️ Outline rate limiting error (429). The integration will be skipped for now.")}console.log("Waiting 3 seconds before proceeding to Rocket.Chat integration..."),await new Promise(e=>setTimeout(e,3e3));try{console.log("Starting Rocket.Chat channel creation..."),i=await this.rocketChatService.createChannel(n),console.log(`Rocket.Chat channel created with ID: ${i}`),l.rocketchat.success=!0,l.rocketchat.id=i}catch(e){console.error("Error creating Rocket.Chat channel:",e),l.rocketchat.success=!1,l.rocketchat.error=e instanceof Error?e.message:String(e),s.A.isAxiosError(e)&&e.response?.status===429&&console.log("⚠️ Rocket.Chat rate limiting error (429). The integration will be skipped for now.")}if(console.log("Waiting 3 seconds before proceeding to Gitea integration..."),await new Promise(e=>setTimeout(e,3e3)),n.services&&(n.services.includes("Gite")||n.services.includes("Calcul")))try{console.log("Starting Gitea repository creation...");let e=await this.giteaService.createRepository(n);a=e&&e.html_url?e.html_url:this.giteaService.getRepositoryUrl(n.name.toLowerCase().replace(/\s+/g,"-").replace(/[^a-z0-9-]/g,"")),console.log(`Gitea repository created at: ${a}`),l.gitea.success=!0,l.gitea.url=a}catch(e){console.error("Error creating Gitea repository:",e),l.gitea.success=!1,l.gitea.error=e instanceof Error?e.message:String(e)}else console.log("Skipping Gitea repository creation - neither Gite nor Calcul services selected"),l.gitea.success=!1,l.gitea.error="Skipped - service not selected";return await r.z.mission.update({where:{id:e},data:{leantimeProjectId:l.leantime.success?t?.toString():void 0,outlineCollectionId:l.outline.success?o:void 0,rocketChatChannelId:l.rocketchat.success?i:void 0,giteaRepositoryUrl:l.gitea.success?a:void 0}}),console.log("Integration results:",JSON.stringify(l,null,2)),{success:!c,data:{leantimeProjectId:t,outlineCollectionId:o,rocketChatChannelId:i,giteaRepositoryUrl:a}}}catch(s){console.error("Error setting up integrations:",s),await this.rollbackIntegrations(t,o,i,a);try{await r.z.mission.delete({where:{id:e}}),console.log(`Mission ${e} deleted due to critical integration failure.`)}catch(e){console.error("Error deleting mission after integration failure:",e)}return{success:!1,error:`Integration failed: ${s instanceof Error?s.message:String(s)}`}}}catch(e){return console.error("Error in integration setup:",e),{success:!1,error:`Integration setup failed: ${e instanceof Error?e.message:String(e)}`}}}async rollbackIntegrations(e,t,o,r){console.log("⚠️ Rolling back integrations due to an error...");let s={leantime:!1,outline:!1,rocketchat:!1,gitea:!1};try{if(e)try{console.log(`Attempting to delete Leantime project: ${e}`);let t=await this.leantimeService.deleteProject(e);s.leantime=t,console.log(`Leantime project deletion ${t?"successful":"failed"}: ${e}`),console.log("Waiting 3 seconds before next rollback operation..."),await new Promise(e=>setTimeout(e,3e3))}catch(t){console.error("Error during Leantime rollback:",t),console.log(`⚠️ Note: Leantime project ${e} may need to be deleted manually`)}if(t)try{console.log(`Attempting to delete Outline collection: ${t}`);let e=await this.outlineService.deleteCollection(t);s.outline=e,console.log(`Outline collection deletion ${e?"successful":"failed"}: ${t}`),console.log("Waiting 3 seconds before next rollback operation..."),await new Promise(e=>setTimeout(e,3e3))}catch(e){console.error("Error during Outline rollback:",e),console.log(`⚠️ Note: Outline collection ${t} may need to be deleted manually`)}if(o)try{console.log(`Attempting to delete Rocket.Chat channel: ${o}`);let e=await this.rocketChatService.deleteChannel(o);s.rocketchat=e,console.log(`Rocket.Chat channel deletion ${e?"successful":"failed"}: ${o}`),console.log("Waiting 3 seconds before next rollback operation..."),await new Promise(e=>setTimeout(e,3e3))}catch(e){console.error("Error during Rocket.Chat rollback:",e),console.log(`⚠️ Note: Rocket.Chat channel ${o} may need to be deleted manually`)}if(r)try{let e=r.split("/");if(e.length>=2){let t=e[e.length-2],o=e[e.length-1];console.log(`Attempting to delete Gitea repository: ${t}/${o}`);let r=await this.giteaService.deleteRepository(t,o);s.gitea=r,console.log(`Gitea repository deletion ${r?"successful":"failed"}: ${t}/${o}`)}else console.log(`Invalid Gitea repository URL format: ${r}`)}catch(e){console.error("Error during Gitea rollback:",e),console.log(`⚠️ Note: Gitea repository at ${r} may need to be deleted manually`)}else console.log("No Gitea repository was created, skipping rollback"),s.gitea=!0;console.log("Rollback summary:",JSON.stringify(s)),s.leantime&&s.outline&&s.rocketchat&&s.gitea||console.log("⚠️ Some resources may need to be deleted manually.")}catch(s){console.error("Error during rollback:",s),console.log("⚠️ Resources may need to be deleted manually:"),e&&console.log(`- Leantime project: ${e}`),t&&console.log(`- Outline collection: ${t}`),o&&console.log(`- Rocket.Chat channel: ${o}`),r&&console.log(`- Gitea repository: ${r}`)}}}}}; |