From d7eb700860e4e757b4eb4aaa4794319776471845 Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Wed, 15 Apr 2026 00:17:00 +0200 Subject: [PATCH] refactor: move PG cleanup to TenantDatabaseService, keep only ClickHouse TenantDataCleanupService now handles only ClickHouse GDPR erasure; the dropPostgresSchema private method is removed and the public method renamed cleanupClickHouse(). VendorTenantService updated accordingly with the TODO comment removed. Co-Authored-By: Claude Sonnet 4.6 --- .../TenantDataCleanupService.java | 33 ++++--------------- .../saas/vendor/VendorTenantService.java | 5 ++- 2 files changed, 9 insertions(+), 29 deletions(-) diff --git a/src/main/java/net/siegeln/cameleer/saas/provisioning/TenantDataCleanupService.java b/src/main/java/net/siegeln/cameleer/saas/provisioning/TenantDataCleanupService.java index f06dedf..907803e 100644 --- a/src/main/java/net/siegeln/cameleer/saas/provisioning/TenantDataCleanupService.java +++ b/src/main/java/net/siegeln/cameleer/saas/provisioning/TenantDataCleanupService.java @@ -12,8 +12,8 @@ import java.util.ArrayList; import java.util.List; /** - * Cleans up tenant data from the server PostgreSQL and ClickHouse databases - * when a tenant is deleted (GDPR data erasure). + * Deletes tenant data from ClickHouse tables when a tenant is deleted + * (GDPR data erasure). PostgreSQL cleanup is handled by TenantDatabaseService. */ @Service public class TenantDataCleanupService { @@ -26,33 +26,14 @@ public class TenantDataCleanupService { this.props = props; } - public void cleanup(String slug) { - dropPostgresSchema(slug); + /** + * Deletes tenant data from ClickHouse tables (GDPR data erasure). + * PostgreSQL cleanup is handled by TenantDatabaseService. + */ + public void cleanupClickHouse(String slug) { deleteClickHouseData(slug); } - private void dropPostgresSchema(String slug) { - String url = props.datasourceUrl(); - if (url == null || url.isBlank()) { - log.warn("No server datasource URL configured — skipping PostgreSQL schema cleanup"); - return; - } - - String schema = "tenant_" + slug; - if (!schema.matches("^[a-z0-9_-]+$")) { - log.error("Refusing to drop schema with unexpected characters: {}", schema); - return; - } - - try (Connection conn = DriverManager.getConnection(url, props.datasourceUsername(), props.datasourcePassword()); - Statement stmt = conn.createStatement()) { - stmt.execute("DROP SCHEMA IF EXISTS \"" + schema + "\" CASCADE"); - log.info("Dropped PostgreSQL schema: {}", schema); - } catch (Exception e) { - log.warn("Failed to drop PostgreSQL schema '{}': {}", schema, e.getMessage()); - } - } - private void deleteClickHouseData(String slug) { String url = props.clickhouseUrl(); if (url == null || url.isBlank()) { diff --git a/src/main/java/net/siegeln/cameleer/saas/vendor/VendorTenantService.java b/src/main/java/net/siegeln/cameleer/saas/vendor/VendorTenantService.java index adb4c6c..409bc37 100644 --- a/src/main/java/net/siegeln/cameleer/saas/vendor/VendorTenantService.java +++ b/src/main/java/net/siegeln/cameleer/saas/vendor/VendorTenantService.java @@ -336,9 +336,8 @@ public class VendorTenantService { log.warn("Failed to drop tenant database for {}: {}", tenant.getSlug(), e.getMessage()); } - // Erase tenant data from server databases (GDPR) - // TODO: split into cleanupClickHouse() in next task - dataCleanupService.cleanup(tenant.getSlug()); + // Erase tenant data from ClickHouse (GDPR) + dataCleanupService.cleanupClickHouse(tenant.getSlug()); // Soft-delete tenant.setStatus(TenantStatus.DELETED);