Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions backend/modules/audit/domain/event_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ const (
TENANT_UPDATE_SUCCESS ApplicationEventType = "TENANT_UPDATE_SUCCESS"
TENANT_TERMINATE_ATTEMPT ApplicationEventType = "TENANT_TERMINATE_ATTEMPT"
TENANT_TERMINATE_SUCCESS ApplicationEventType = "TENANT_TERMINATE_SUCCESS"
TENANT_REACTIVATE_ATTEMPT ApplicationEventType = "TENANT_REACTIVATE_ATTEMPT"
TENANT_REACTIVATE_SUCCESS ApplicationEventType = "TENANT_REACTIVATE_SUCCESS"
TENANT_PURGE_ATTEMPT ApplicationEventType = "TENANT_PURGE_ATTEMPT"
TENANT_PURGE_SUCCESS ApplicationEventType = "TENANT_PURGE_SUCCESS"
TENANT_SUPPORT_ACCESS_ATTEMPT ApplicationEventType = "TENANT_SUPPORT_ACCESS_ATTEMPT"
TENANT_SUPPORT_ACCESS_SUCCESS ApplicationEventType = "TENANT_SUPPORT_ACCESS_SUCCESS"

Expand Down
23 changes: 23 additions & 0 deletions backend/pkg/eventstore/eventstore.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package eventstore

import (
"context"
"fmt"
"time"

chdriver "github.com/ClickHouse/clickhouse-go/v2"
"github.com/ClickHouse/clickhouse-go/v2/lib/driver"
"github.com/google/uuid"
"github.com/threatwinds/go-sdk/store"
"github.com/threatwinds/go-sdk/store/clickhouse"

Expand Down Expand Up @@ -69,4 +72,24 @@ func (s *Store) TableName(d store.Dataset) string {
return db + "." + name
}

// PurgeTenant deletes all rows scoped to the given tenant across every
// dataset table. ClickHouse mutation, not synchronous — the ALTER returns
// once accepted and the rows disappear as the mutation runs.
//
// tenantID must be a UUID string (caller passes uuid.UUID.String()); it is
// inlined into the SQL because ClickHouse does not bind parameters inside
// ALTER ... DELETE mutation expressions. The UUID shape makes inlining safe.
func (s *Store) PurgeTenant(ctx context.Context, tenantID string) error {
if _, err := uuid.Parse(tenantID); err != nil {
return fmt.Errorf("purge: invalid tenant id: %w", err)
}
for _, d := range []store.Dataset{DatasetLogs, DatasetAlerts, DatasetStats} {
sql := fmt.Sprintf("ALTER TABLE %s DELETE WHERE tenantId = '%s'", s.TableName(d), tenantID)
if err := s.Conn.Exec(ctx, sql); err != nil {
return fmt.Errorf("purge %s: %w", d, err)
}
}
return nil
}

func SupportsTextSearch(d store.Dataset) bool { return d == DatasetLogs }
Loading