feat: add forced WAP server deletion support to clean up associated organizations and runtime bots

This commit is contained in:
2026-07-30 17:58:10 -03:00
parent cb830fcf01
commit 446c65ff37
8 changed files with 191 additions and 19 deletions
+58 -6
View File
@@ -1157,33 +1157,85 @@ class WapServerManager implements IWapServerManager {
throw new Error("WAP server not found");
}
if (server.active) {
const force = data.force === true;
if (!force && server.active) {
throw new Error("WAP server must be inactive before deletion");
}
const assignedCompanies = await CompaniesManager.companies.find({ wapServerId: data.serverId });
if (assignedCompanies.length > 0) {
if (!force && assignedCompanies.length > 0) {
throw new Error(`WAP server cannot be deleted because it has ${assignedCompanies.length} associated bot(s) in DB`);
}
let detectedBots: SysAdminWapContainerDto[];
let detectedBots: SysAdminWapContainerDto[] = [];
let auditFailed = false;
let auditMessage: string | undefined;
try {
detectedBots = await this.getSysAdminRuntimeContainers(server);
} catch (error) {
const message = error instanceof Error && error.message ? error.message : "unknown error";
throw new Error(`WAP server cannot be deleted because bot-admin could not be audited. Verify runtime bots manually before deleting. ${message}`);
if (!force) {
throw new Error(`WAP server cannot be deleted because bot-admin could not be audited. Verify runtime bots manually before deleting. ${message}`);
}
auditFailed = true;
auditMessage = message;
}
if (detectedBots.length > 0) {
if (!force && detectedBots.length > 0) {
throw new Error(`WAP server cannot be deleted because bot-admin detected ${detectedBots.length} runtime bot(s)`);
}
let deletedRuntimeBots = 0;
let skippedRuntimeBots = 0;
if (force) {
const baseUrl = this.getBotAdminApiUrl(server.ipv4);
for (const bot of detectedBots) {
if (!bot.organizationId) {
skippedRuntimeBots += 1;
continue;
}
try {
const result = await this.deleteSysAdminRuntimeBot(baseUrl, encodeURIComponent(bot.organizationId), true);
if (result.botDeleted) {
deletedRuntimeBots += 1;
}
} catch (_error) {
skippedRuntimeBots += 1;
}
}
for (const company of assignedCompanies) {
const companyDocument = company as typeof company & { save: () => Promise<unknown> };
companyDocument.wapServerId = undefined;
await companyDocument.save();
}
}
await this.servers.delete(data.serverId);
return { serverId: data.serverId, deleted: true };
return {
serverId: data.serverId,
deleted: true,
...(force
? {
force: true,
detachedOrganizations: assignedCompanies.length,
deletedRuntimeBots,
skippedRuntimeBots,
...(auditFailed ? { auditFailed: true, auditMessage } : {}),
}
: {}),
};
}
public async sysAdminStartBot(data: SysAdminWapServerOrganizationActionParams): Promise<void> {