/** * Notification Scheme Housekeeping (Cloud) – Report + optional Delete * ------------------------------------------------------------------- * Strategy: * - PROTECTED_PROJECT_KEYS sind die einzigen Projekte, die "leben" * - Ein Scheme darf nur gelöscht werden, wenn es in KEINEM dieser Projekte steckt */ def PROTECTED_PROJECT_KEYS = ["NIN","NICS","NINPDS","NINPDSARC","CS","CRON"] def DRY_RUN = true // erst auf false, wenn der Report passt logger.info("=== Notification Scheme Housekeeping ===") logger.info("Protected projects: ${PROTECTED_PROJECT_KEYS}") logger.info("DRY_RUN: ${DRY_RUN}") // Helper: Project -> NotificationSchemeId (nur 6 Calls, ok) def projectToSchemeId = [:] PROTECTED_PROJECT_KEYS.each { key -> def resp = get("/rest/api/3/project/${key}/notificationscheme") .asObject(Map) if (resp.status == 200) { projectToSchemeId[key] = resp.body?.id?.toString() } else { projectToSchemeId[key] = null logger.warn("WARN|PROJECT_LOOKUP_FAILED|${key}|status=${resp.status}") } } logger.info("INFO|PROJECT_SCHEME_MAP|${projectToSchemeId}") // Alle Schemes holen def schemesResp = get("/rest/api/3/notificationscheme") .asObject(Map) assert schemesResp.status == 200 def schemes = schemesResp.body?.values ?: [] def candidates = [] // [id, name] def kept = 0 schemes.each { scheme -> def schemeId = scheme.id?.toString() def schemeName = scheme.name?.toString() def usedBy = projectToSchemeId.findAll { k, v -> v == schemeId }*.key if (usedBy && !usedBy.isEmpty()) { kept++ logger.info("KEEP|schemeId=${schemeId}|name=${schemeName}|usedBy=${usedBy}") } else { candidates << [schemeId, schemeName] logger.info("DEL?|schemeId=${schemeId}|name=${schemeName}|usedBy=[]") if (!DRY_RUN) { def delResp = delete("/rest/api/3/notificationscheme/${schemeId}") .asString() if (delResp.status == 204) { logger.info("DEL|OK|schemeId=${schemeId}|name=${schemeName}") } else { logger.error("DEL|FAIL|schemeId=${schemeId}|name=${schemeName}|status=${delResp.status}|body=${delResp.body}") } } } } logger.info("=== SUMMARY ===") logger.info("Total schemes: ${schemes.size()}") logger.info("Kept (used by protected projects): ${kept}") logger.info("Delete candidates: ${candidates.size()}") // Kandidaten am Ende nochmal gesammelt, damit du sie easy kopieren kannst candidates.each { c -> logger.info("CANDIDATE|schemeId=${c[0]}|name=${c[1]}") } logger.info("=== DONE ===")