Mandantenlöschung

Löschen Sie einen Mandanten und alle zugehörigen Daten dauerhaft. Dieser Vorgang erfordert eine dreifache Verifizierung zur Sicherheit.

WICHTIG: Alle Endpunkte auf dieser Seite erfordern einen Globalen API-Schlüssel. Dies ist eine gefährliche Operation, die nicht rückgängig gemacht werden kann.


Mandanten löschen

DELETE /api/tenant

Löscht einen Mandanten und alle zugehörigen Daten dauerhaft. Erfordert eine dreifache Verifizierung zur Sicherheit.

WARNUNG

Dieser Vorgang ist NICHT WIDERRUFLICH. Alle Mandantendaten werden dauerhaft gelöscht, einschließlich:

  • Alle Projekte und deren Datensätze
  • Alle Untersuchungen, Notebooks und Dashboards
  • Blob-Speichercontainer und Dateien
  • Datenbankeinträge und Einstellungen
  • Benutzerzuweisungen zum Mandanten (Benutzer selbst werden nicht gelöscht)

Exportieren Sie immer wichtige Daten, bevor Sie einen Mandanten löschen.


Request Body

{
  "tenantId": "12345678-1234-1234-1234-123456789012",
  "name": "acme-corp",
  "displayName": "Acme Corporation"
}

Dreifache Verifizierung

Alle drei Identifikatoren müssen exakt übereinstimmen, damit die Löschung ausgeführt wird:

Feld Typ Erforderlich Beschreibung
tenantId GUID Ja Zu löschende Mandanten-ID
name string Ja Mandantenname (muss exakt übereinstimmen)
displayName string Ja Anzeigename (muss exakt übereinstimmen)

Diese dreifache Verifizierung verhindert versehentliche Löschungen, indem Sie alle drei Identifikatoren kennen und bestätigen müssen.


Antwort (200 OK)

{
  "message": "Tenant 'Acme Corporation' deleted successfully",
  "tenantName": "acme-corp",
  "tenantDisplayName": "Acme Corporation",
  "storageContainerDeleted": true
}

Antwortfelder

Feld Typ Beschreibung
message string Bestätigung der erfolgreichen Löschung
tenantName string Systemname des gelöschten Mandanten
tenantDisplayName string Anzeigename des gelöschten Mandanten
storageContainerDeleted boolean Ob der Blob-Speicher gelöscht wurde

Fehlermeldungen

Nicht gefunden (404)

{
  "error": "Tenant not found with ID '12345678-1234-1234-1234-123456789012'"
}

Verifizierung fehlgeschlagen (400)

Wenn der Mandantenname nicht übereinstimmt:

{
  "error": "Tenant name 'wrong-name' does not match the tenant with ID '12345678-1234-1234-1234-123456789012'. Expected 'acme-corp'.",
  "hint": "All three identifiers (ID, name, display name) must match exactly for safety"
}

Wenn der Anzeigename nicht übereinstimmt:

{
  "error": "Display name 'Wrong Name' does not match the tenant with ID '12345678-1234-1234-1234-123456789012'. Expected 'Acme Corporation'.",
  "hint": "All three identifiers (ID, name, display name) must match exactly for safety"
}

Nicht autorisiert (401)

{
  "error": "This endpoint requires a Global API key.",
  "hint": "Global API keys can be created at /admin/global-api-keys"
}

Implementierungsbeispiele

cURL

# Mandanten löschen (erfordert dreifache Verifizierung)
curl -X DELETE "https://your-mindzie-instance.com/api/tenant" \
  -H "Authorization: Bearer YOUR_GLOBAL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tenantId": "12345678-1234-1234-1234-123456789012",
    "name": "test-tenant",
    "displayName": "Test Tenant"
  }'

Python

import requests

BASE_URL = 'https://your-mindzie-instance.com'

class TenantDeleter:
    def __init__(self, global_api_key):
        """Initialisiert mit einem GLOBALEN API-Schlüssel (nicht mandantenspezifisch)."""
        self.headers = {
            'Authorization': f'Bearer {global_api_key}',
            'Content-Type': 'application/json'
        }

    def get_tenant(self, tenant_id):
        """Holt Mandantendetails zur Verifizierung."""
        url = f'{BASE_URL}/api/tenant/{tenant_id}'
        response = requests.get(url, headers=self.headers)
        response.raise_for_status()
        return response.json()

    def delete_tenant(self, tenant_id, name, display_name, confirm=False):
        """
        Löscht einen Mandanten mit dreifacher Verifizierung.

        Args:
            tenant_id: Die GUID des Mandanten
            name: Der Systemname des Mandanten (muss exakt übereinstimmen)
            display_name: Der Anzeigename des Mandanten (muss exakt übereinstimmen)
            confirm: Auf True setzen, um die Löschung tatsächlich durchzuführen
        """
        if not confirm:
            # Verifizierungsmodus - prüfen, ob Werte übereinstimmen
            tenant = self.get_tenant(tenant_id)

            errors = []
            if tenant['name'] != name:
                errors.append(f"Name stimmt nicht überein: erwartet '{tenant['name']}', erhalten '{name}'")
            if tenant['displayName'] != display_name:
                errors.append(f"Anzeigename stimmt nicht überein: erwartet '{tenant['displayName']}', erhalten '{display_name}'")

            if errors:
                raise ValueError("Verifizierung fehlgeschlagen:\n" + "\n".join(errors))

            print(f"Verifizierung erfolgreich für Mandanten '{display_name}' ({name})")
            print(f"  - ID: {tenant_id}")
            print(f"  - Benutzer: {tenant.get('userCount', 'k.A.')}")
            print(f"  - Fälle: {tenant.get('caseCount', 'k.A.')}")
            print("\nRufen Sie delete_tenant mit confirm=True auf, um die Löschung durchzuführen.")
            return None

        # Löschung durchführen
        url = f'{BASE_URL}/api/tenant'
        payload = {
            'tenantId': tenant_id,
            'name': name,
            'displayName': display_name
        }

        response = requests.delete(url, json=payload, headers=self.headers)

        if response.ok:
            return response.json()
        elif response.status_code == 404:
            raise Exception(f'Mandant nicht gefunden: {tenant_id}')
        elif response.status_code == 400:
            error = response.json()
            raise Exception(f"Verifizierung fehlgeschlagen: {error.get('error', 'Unbekannter Fehler')}")
        else:
            raise Exception(f'Fehler beim Löschen des Mandanten: {response.text}')

# Anwendung - Sicherer Löschvorgang
deleter = TenantDeleter('your-global-api-key')

tenant_id = '12345678-1234-1234-1234-123456789012'
tenant_name = 'test-tenant'
display_name = 'Test Tenant'

# Schritt 1: Verifizieren (keine Löschung erfolgt)
try:
    deleter.delete_tenant(tenant_id, tenant_name, display_name, confirm=False)
except ValueError as e:
    print(f"Verifizierung fehlgeschlagen: {e}")
    exit(1)

# Schritt 2: Löschung bestätigen (auskommentieren, wenn bereit)
# result = deleter.delete_tenant(tenant_id, tenant_name, display_name, confirm=True)
# print(f"Geloescht: {result['message']}")

JavaScript

const BASE_URL = 'https://your-mindzie-instance.com';

class TenantDeleter {
  constructor(globalApiKey) {
    this.headers = {
      'Authorization': `Bearer ${globalApiKey}`,
      'Content-Type': 'application/json'
    };
  }

  async getTenant(tenantId) {
    const url = `${BASE_URL}/api/tenant/${tenantId}`;
    const response = await fetch(url, { headers: this.headers });
    if (!response.ok) throw new Error(`Fehler beim Abrufen des Mandanten: ${response.status}`);
    return await response.json();
  }

  async deleteTenant(tenantId, name, displayName, confirm = false) {
    if (!confirm) {
      // Verifizierungsmodus
      const tenant = await this.getTenant(tenantId);

      const errors = [];
      if (tenant.name !== name) {
        errors.push(`Name stimmt nicht überein: erwartet '${tenant.name}', erhalten '${name}'`);
      }
      if (tenant.displayName !== displayName) {
        errors.push(`Anzeigename stimmt nicht überein: erwartet '${tenant.displayName}', erhalten '${displayName}'`);
      }

      if (errors.length > 0) {
        throw new Error('Verifizierung fehlgeschlagen:\n' + errors.join('\n'));
      }

      console.log(`Verifizierung erfolgreich für Mandanten '${displayName}' (${name})`);
      console.log(`  - ID: ${tenantId}`);
      console.log(`  - Benutzer: ${tenant.userCount || 'k.A.'}`);
      console.log('\nRufen Sie deleteTenant mit confirm=true auf, um die Löschung durchzuführen.');
      return null;
    }

    // Löschung durchführen
    const url = `${BASE_URL}/api/tenant`;
    const response = await fetch(url, {
      method: 'DELETE',
      headers: this.headers,
      body: JSON.stringify({ tenantId, name, displayName })
    });

    if (response.ok) {
      return await response.json();
    }

    const error = await response.json();
    throw new Error(error.error || `Löschung fehlgeschlagen: ${response.status}`);
  }
}

// Anwendung - Sicherer Löschvorgang
const deleter = new TenantDeleter('your-global-api-key');

const tenantId = '12345678-1234-1234-1234-123456789012';
const tenantName = 'test-tenant';
const displayName = 'Test Tenant';

// Schritt 1: Verifizieren (keine Löschung erfolgt)
try {
  await deleter.deleteTenant(tenantId, tenantName, displayName, false);
} catch (e) {
  console.error(`Verifizierung fehlgeschlagen: ${e.message}`);
  process.exit(1);
}

// Schritt 2: Löschung bestätigen (auskommentieren, wenn bereit)
// const result = await deleter.deleteTenant(tenantId, tenantName, displayName, true);
// console.log(`Gelöscht: ${result.message}`);

Sicherheitsbest Practices

Vor der Löschung

  1. Alle Daten exportieren: Verwenden Sie die Projekt-API, um alle Projekte als .mpz-Dateien zu exportieren
  2. Benutzer überprüfen: Prüfen Sie, welche Benutzer zugewiesen sind und benachrichtigen Sie sie
  3. Dokumentieren: Halten Sie fest, was gelöscht wird und warum – für Audit-Zwecke
  4. Doppelt prüfen: Vergewissern Sie sich, dass Mandanten-ID, Name und Anzeigename korrekt sind

Während der Löschung

  1. Verifizierungsmuster verwenden: Rufen Sie den Lösch-Endpunkt zuerst im Verifizierungsmodus auf
  2. Antwort prüfen: Verifizieren Sie, dass die Antwort die korrekten Mandanteninformationen enthält
  3. Bewusst bestätigen: Übergeben Sie confirm=True nur nach manueller Überprüfung

Nach der Löschung

  1. Löschung verifizieren: Prüfen Sie, ob der Mandant nicht mehr in der Mandantenliste erscheint
  2. Benutzer prüfen: Vergewissern Sie sich, dass betroffene Benutzer keinen Zugriff mehr auf den gelöschten Mandanten haben
  3. Dokumentation aktualisieren: Halten Sie die Löschung in Ihren Systemdokumentationen fest

Alternative: Deaktivieren statt Löschen

Erwägen Sie, einen Mandanten zu deaktivieren, um Daten zu bewahren und dennoch den Zugriff zu verhindern:

# Mandanten deaktivieren (Daten bleiben erhalten)
curl -X PUT "https://your-mindzie-instance.com/api/tenant" \
  -H "Authorization: Bearer YOUR_GLOBAL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tenantId": "12345678-1234-1234-1234-123456789012",
    "isDisabled": true
  }'

Deaktivierte Mandanten:

  • Benutzer können sich nicht mehr beim Mandanten anmelden
  • Alle Daten bleiben erhalten
  • Können später wieder aktiviert werden, indem isDisabled: false gesetzt wird
  • Erscheinen in der Mandantenliste mit isDisabled: true

Dies ist oft eine sicherere Wahl als eine permanente Löschung.