missions api2 gitea
This commit is contained in:
parent
3e803e3112
commit
9a0fea9c90
@ -658,43 +658,107 @@ export class LeantimeService {
|
|||||||
*/
|
*/
|
||||||
async deleteProject(projectId: number): Promise<boolean> {
|
async deleteProject(projectId: number): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
console.log(`Attempting to delete Leantime project ${projectId} with method: leantime.rpc.Projects.Projects.deleteProject`);
|
console.log(`Attempting to delete Leantime project ${projectId} using REST API approach`);
|
||||||
|
|
||||||
const response = await axios.post(
|
// Get base URL by removing any API path
|
||||||
this.getApiEndpoint(),
|
const baseUrl = this.apiUrl
|
||||||
{
|
.replace('/api/jsonrpc', '')
|
||||||
method: 'leantime.rpc.Projects.Projects.deleteProject',
|
.replace('/api/jsonrpc.php', '');
|
||||||
jsonrpc: '2.0',
|
|
||||||
id: 1,
|
// Construct REST API URL for project deletion
|
||||||
params: {
|
// Attempt different patterns that might work:
|
||||||
id: projectId
|
|
||||||
}
|
// 1. First, try the standard REST API approach
|
||||||
},
|
const restApiUrl = baseUrl.endsWith('/')
|
||||||
{
|
? `${baseUrl}api/v1/projects/${projectId}`
|
||||||
headers: {
|
: `${baseUrl}/api/v1/projects/${projectId}`;
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'X-API-Key': this.apiToken
|
console.log(`Trying REST API deletion via DELETE to: ${restApiUrl}`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const restResponse = await axios.delete(
|
||||||
|
restApiUrl,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-API-Key': this.apiToken
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(`REST API Delete response:`, JSON.stringify(restResponse.data, null, 2));
|
||||||
|
|
||||||
|
if (restResponse.status >= 200 && restResponse.status < 300) {
|
||||||
|
console.log(`Successfully deleted project ${projectId} via REST API`);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
);
|
} catch (restError) {
|
||||||
|
console.error('REST API error:', restError);
|
||||||
// Log the full response for debugging
|
if (axios.isAxiosError(restError)) {
|
||||||
console.log(`Leantime delete response for project ${projectId}:`, JSON.stringify(response.data, null, 2));
|
console.error('REST API error details:', {
|
||||||
|
status: restError.response?.status,
|
||||||
if (!response.data || response.data.result !== true) {
|
data: restError.response?.data,
|
||||||
console.error(`Failed to delete Leantime project ${projectId} with first method. API Response:`, JSON.stringify(response.data, null, 2));
|
message: restError.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Try the web interface approach (simulate a form submission)
|
||||||
|
console.log(`Trying web interface simulation for project deletion...`);
|
||||||
|
|
||||||
|
// Assuming a standard web interface form submission
|
||||||
|
const formUrl = baseUrl.endsWith('/')
|
||||||
|
? `${baseUrl}projects/deleteProject/${projectId}`
|
||||||
|
: `${baseUrl}/projects/deleteProject/${projectId}`;
|
||||||
|
|
||||||
|
console.log(`Simulating form submission to: ${formUrl}`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Some systems require a POST to the delete endpoint
|
||||||
|
const formResponse = await axios.post(
|
||||||
|
formUrl,
|
||||||
|
{}, // Empty payload or { confirm: true } depending on the system
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-API-Key': this.apiToken
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// Try alternative method (without double "Projects")
|
console.log(`Form submission response:`, JSON.stringify(formResponse.data, null, 2));
|
||||||
console.log(`Trying alternative method: leantime.rpc.Projects.deleteProject for project ${projectId}`);
|
|
||||||
|
|
||||||
const alternativeResponse = await axios.post(
|
if (formResponse.status >= 200 && formResponse.status < 300) {
|
||||||
|
console.log(`Successfully deleted project ${projectId} via web interface simulation`);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (formError) {
|
||||||
|
console.error('Form submission error:', formError);
|
||||||
|
if (axios.isAxiosError(formError)) {
|
||||||
|
console.error('Form submission error details:', {
|
||||||
|
status: formError.response?.status,
|
||||||
|
data: formError.response?.data,
|
||||||
|
message: formError.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Last resort: Try to mark the project as archived/inactive if deletion isn't supported
|
||||||
|
console.log(`Attempting to mark project as archived/inactive as a fallback...`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Use the JSON-RPC API to update the project status
|
||||||
|
const updateResponse = await axios.post(
|
||||||
this.getApiEndpoint(),
|
this.getApiEndpoint(),
|
||||||
{
|
{
|
||||||
method: 'leantime.rpc.Projects.deleteProject',
|
method: 'leantime.rpc.Projects.Projects.updateProject',
|
||||||
jsonrpc: '2.0',
|
jsonrpc: '2.0',
|
||||||
id: 1,
|
id: 1,
|
||||||
params: {
|
params: {
|
||||||
id: projectId
|
id: projectId,
|
||||||
|
values: {
|
||||||
|
status: 'archived' // Try 'archived', 'deleted', or 'inactive'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -705,76 +769,35 @@ export class LeantimeService {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// Log the alternative response
|
console.log(`Project status update response:`, JSON.stringify(updateResponse.data, null, 2));
|
||||||
console.log(`Alternative method response for project ${projectId}:`, JSON.stringify(alternativeResponse.data, null, 2));
|
|
||||||
|
|
||||||
// Check if alternative method worked
|
if (updateResponse.data && updateResponse.data.result) {
|
||||||
if (alternativeResponse.data && alternativeResponse.data.result === true) {
|
console.log(`Successfully marked project ${projectId} as archived`);
|
||||||
console.log(`Successfully deleted project ${projectId} with alternative method`);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
} catch (updateError) {
|
||||||
// If we get here, both methods failed
|
console.error('Project status update error:', updateError);
|
||||||
console.error(`Failed to delete Leantime project ${projectId} with both methods.`);
|
if (axios.isAxiosError(updateError)) {
|
||||||
return false;
|
console.error('Update error details:', {
|
||||||
}
|
status: updateError.response?.status,
|
||||||
|
data: updateError.response?.data,
|
||||||
console.log(`Successfully deleted Leantime project ${projectId}`);
|
message: updateError.message
|
||||||
return true;
|
});
|
||||||
} catch (error) {
|
|
||||||
// Check if this is a rate limiting error
|
|
||||||
if (axios.isAxiosError(error) && error.response?.status === 429) {
|
|
||||||
console.log('Rate limiting detected (429) on delete. Waiting and retrying...');
|
|
||||||
|
|
||||||
// Wait 3 seconds and then retry
|
|
||||||
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Retry the delete
|
|
||||||
console.log(`Retrying deletion after rate limit for project ${projectId}`);
|
|
||||||
const retryResponse = await axios.post(
|
|
||||||
this.getApiEndpoint(),
|
|
||||||
{
|
|
||||||
method: 'leantime.rpc.Projects.Projects.deleteProject',
|
|
||||||
jsonrpc: '2.0',
|
|
||||||
id: 1,
|
|
||||||
params: {
|
|
||||||
id: projectId
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'X-API-Key': this.apiToken
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Log the retry response
|
|
||||||
console.log(`Retry response for project ${projectId}:`, JSON.stringify(retryResponse.data, null, 2));
|
|
||||||
|
|
||||||
if (retryResponse.data && retryResponse.data.result === true) {
|
|
||||||
console.log(`Successfully deleted project ${projectId} on retry`);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
console.error(`Retry failed to delete project ${projectId}. Response:`, JSON.stringify(retryResponse.data, null, 2));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (retryError) {
|
|
||||||
console.error(`Error on retry delete for project ${projectId}:`, retryError);
|
|
||||||
if (axios.isAxiosError(retryError)) {
|
|
||||||
console.error('Retry error details:', {
|
|
||||||
status: retryError.response?.status,
|
|
||||||
data: retryError.response?.data,
|
|
||||||
message: retryError.message
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we get here, all methods failed
|
||||||
|
console.error(`Failed to delete or archive Leantime project ${projectId} with all methods.`);
|
||||||
|
console.log(`Please manually delete/archive project ${projectId} from Leantime.`);
|
||||||
|
|
||||||
|
// Get the project URL for manual deletion
|
||||||
|
const projectUrl = this.getProjectUrl(projectId);
|
||||||
|
console.log(`Project URL for manual cleanup: ${projectUrl}`);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} catch (error) {
|
||||||
// Log detailed error information
|
// Log detailed error information
|
||||||
console.error(`Error deleting Leantime project ${projectId}:`, error);
|
console.error(`Error in deleteProject for Leantime project ${projectId}:`, error);
|
||||||
if (axios.isAxiosError(error)) {
|
if (axios.isAxiosError(error)) {
|
||||||
console.error('Error details:', {
|
console.error('Error details:', {
|
||||||
status: error.response?.status,
|
status: error.response?.status,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user