neutralizer

This commit is contained in:
ValueOn AG 2025-06-06 15:50:29 +02:00
parent 83000a60c5
commit 0cd3c10b66
5 changed files with 729 additions and 0 deletions

285
poweron/pricing.html Normal file
View file

@ -0,0 +1,285 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI Enterprise Suite - Preise</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 20px;
min-height: 100vh;
}
.container {
max-width: 210mm;
margin: 0 auto;
background: white;
border-radius: 20px;
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
overflow: hidden;
height: 297mm;
display: flex;
flex-direction: column;
}
.header {
background: linear-gradient(135deg, #2C3E50 0%, #34495E 100%);
color: white;
padding: 30px;
text-align: center;
}
.header h1 {
font-size: 2.5rem;
margin-bottom: 10px;
font-weight: 700;
}
.header p {
font-size: 1.1rem;
opacity: 0.9;
}
.pricing-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
padding: 40px;
flex: 1;
}
.plan {
background: #f8f9fa;
border-radius: 15px;
padding: 25px;
text-align: center;
position: relative;
border: 3px solid transparent;
transition: all 0.3s ease;
}
.plan:hover {
transform: translateY(-5px);
box-shadow: 0 15px 30px rgba(0,0,0,0.1);
}
.plan.popular {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-color: #FFD700;
transform: scale(1.05);
}
.plan.popular::before {
content: "BELIEBTESTE WAHL";
position: absolute;
top: -15px;
left: 50%;
transform: translateX(-50%);
background: #FFD700;
color: #2C3E50;
padding: 8px 20px;
border-radius: 20px;
font-size: 0.8rem;
font-weight: bold;
}
.plan h3 {
font-size: 1.5rem;
margin-bottom: 15px;
font-weight: 600;
}
.price {
font-size: 2.5rem;
font-weight: 700;
margin-bottom: 5px;
}
.period {
font-size: 0.9rem;
opacity: 0.7;
margin-bottom: 20px;
}
.features {
list-style: none;
margin-bottom: 25px;
text-align: left;
}
.features li {
padding: 8px 0;
position: relative;
padding-left: 25px;
font-size: 0.9rem;
}
.features li::before {
content: "✓";
position: absolute;
left: 0;
color: #27AE60;
font-weight: bold;
}
.plan.popular .features li::before {
color: #FFD700;
}
.setup-fee {
background: #e74c3c;
color: white;
padding: 8px 15px;
border-radius: 20px;
font-size: 0.8rem;
display: inline-block;
margin-bottom: 15px;
}
.cta-button {
background: #2C3E50;
color: white;
border: none;
padding: 12px 25px;
border-radius: 25px;
font-size: 1rem;
cursor: pointer;
transition: all 0.3s ease;
width: 100%;
}
.cta-button:hover {
background: #34495E;
transform: translateY(-2px);
}
.plan.popular .cta-button {
background: white;
color: #667eea;
}
.plan.popular .cta-button:hover {
background: #f8f9fa;
}
.footer {
background: #2C3E50;
color: white;
padding: 25px;
text-align: center;
}
.footer-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
margin-bottom: 20px;
}
.footer h4 {
margin-bottom: 10px;
color: #FFD700;
}
.footer p {
font-size: 0.9rem;
opacity: 0.9;
}
.contact {
border-top: 1px solid #34495E;
padding-top: 15px;
font-size: 0.9rem;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>PowerOn</h1>
<p>Integrierte AI Plattform für DeineDaten - E-Mail, Kalender & SharePoint Integration</p>
</div>
<div class="pricing-grid">
<div class="plan">
<h3>Starter</h3>
<div class="price">CHF 1'190</div>
<div class="period">pro Monat</div>
<div class="setup-fee">Setup: CHF 7'900</div>
<ul class="features">
<li>1'000 AI-Abfragen/Monat</li>
<li>E-Mail Integration</li>
<li>Basis-Dashboard</li>
<li>E-Mail Support</li>
<li>Professional Services: CHF 195/h</li>
<li><strong>Einsparung: &lt;1 FTE/Jahr</strong></li>
</ul>
<button class="cta-button">Jetzt starten</button>
</div>
<div class="plan popular">
<h3>Professional</h3>
<div class="price">CHF 3'990</div>
<div class="period">pro Monat</div>
<div class="setup-fee">Setup: CHF 14'900</div>
<ul class="features">
<li>20'000 AI-Abfragen/Monat</li>
<li>Vollständige SharePoint Integration</li>
<li>Advanced Analytics</li>
<li>Custom Workflows</li>
<li>Priority Support</li>
<li>Professional Services: CHF 195/h</li>
<li><strong>Einsparung: 1-3 FTE/Jahr</strong></li>
</ul>
<button class="cta-button">Empfohlen</button>
</div>
<div class="plan">
<h3>Enterprise</h3>
<div class="price">CHF 7'990</div>
<div class="period">pro Monat</div>
<div class="setup-fee">Setup: CHF 19'900</div>
<ul class="features">
<li>50'000 AI-Abfragen/Monat</li>
<li>Google Workspace Integration</li>
<li>Dedicated Server Option</li>
<li>White-Label Lösung</li>
<li>24/7 Support</li>
<li>Professional Services: CHF 195/h</li>
<li><strong>Einsparung: 12+ FTE/Jahr</strong></li>
</ul>
<button class="cta-button">CHF 3.25/Min</button>
</div>
</div>
<div class="footer">
<div class="footer-grid">
<div>
<h4>Zusätzliche Abfragen</h4>
<p>CHF 0.20 pro zusätzliche AI-Abfrage bei Überschreitung des Kontingents</p>
</div>
<div>
<h4>Jahresrabatt</h4>
<p>15% Rabatt bei Jahresvertrag<br>25% Rabatt bei 3-Jahres-Vertrag</p>
</div>
<div>
<h4>Compliance & Sicherheit</h4>
<p>DSGVO-konform<br>Swiss Cloud Hosting verfügbar</p>
</div>
</div>
<div class="contact">
<strong>Kontakt:</strong> sales@poweron.ch | +41 44 123 45 67 | Kostenlose Demo verfügbar
</div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,14 @@
"""
Test Neutralizer Package
"""
from .neutralizer import DataAnonymizer, ChatDataProcessor, RegionalPatterns, SensitivePattern
__version__ = '1.0.0'
__all__ = [
'DataAnonymizer',
'ChatDataProcessor',
'RegionalPatterns',
'SensitivePattern'
]

View file

@ -0,0 +1,201 @@
"""
DSGVO-konformer Daten-Neutralisierer für KI-Agentensysteme
Unterstützt TXT, JSON, CSV, Excel und Word-Dateien
Mehrsprachig: DE, EN, FR, IT
"""
import re
import json
import pandas as pd
import docx
from pathlib import Path
from typing import Dict, List, Tuple, Any, Union
from dataclasses import dataclass
import uuid
import logging
import sys
# Add the parent directory to the Python path
sys.path.append(str(Path(__file__).parent.parent))
# Konfiguration für Logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
@dataclass
class SensitivePattern:
"""Definiert ein Pattern für sensitive Daten"""
name: str
pattern: str
languages: List[str]
replacement_template: str
class DataAnonymizer:
"""Hauptklasse für die Datenanonymisierung"""
def __init__(self):
self.patterns = self._initialize_patterns()
self.anonymization_map = {}
def _initialize_patterns(self) -> List[SensitivePattern]:
"""Initialisiert die Regex-Pattern für verschiedene Sprachen"""
return [
# E-Mail Adressen
SensitivePattern(
name="email",
pattern=r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b',
languages=["de", "en", "fr", "it", "ch"],
replacement_template="EMAIL_{}"
),
# Telefonnummern (verschiedene Formate)
SensitivePattern(
name="phone",
pattern=r'(\+\d{1,3}[-.\s]?)?\(?\d{1,4}\)?[-.\s]?\d{1,4}[-.\s]?\d{1,9}',
languages=["de", "en", "fr", "it", "ch"],
replacement_template="PHONE_{}"
),
# Deutsche Telefonnummern spezifisch
SensitivePattern(
name="phone_de",
pattern=r'(\+49|0049|0)\s?(\d{2,5})\s?(\d{3,8})',
languages=["de"],
replacement_template="PHONE_DE_{}"
),
# Schweizer Telefonnummern
SensitivePattern(
name="phone_ch",
pattern=r'(\+41|0041|0)\s?(\d{2})\s?(\d{3})\s?(\d{2})\s?(\d{2})',
languages=["ch"],
replacement_template="PHONE_CH_{}"
),
# IBAN
SensitivePattern(
name="iban",
pattern=r'\b[A-Z]{2}\d{2}[A-Z0-9]{4}\d{7}([A-Z0-9]?){0,16}\b',
languages=["de", "en", "fr", "it", "ch"],
replacement_template="IBAN_{}"
),
# Kreditkartennummern
SensitivePattern(
name="credit_card",
pattern=r'\b(?:\d{4}[-\s]?){3}\d{4}\b',
languages=["de", "en", "fr", "it", "ch"],
replacement_template="CREDITCARD_{}"
),
# Deutsche Sozialversicherungsnummer
SensitivePattern(
name="social_security_de",
pattern=r'\b\d{2}\s?\d{6}\s?[A-Z]\s?\d{3}\b',
languages=["de"],
replacement_template="SSN_DE_{}"
),
# Schweizer AHV/AVS Nummer
SensitivePattern(
name="ahv_number",
pattern=r'\b(756\.\d{4}\.\d{4}\.\d{2}|756\s\d{4}\s\d{4}\s\d{2})\b',
languages=["ch"],
replacement_template="AHV_CH_{}"
),
# IP-Adressen
SensitivePattern(
name="ip_address",
pattern=r'\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b',
languages=["de", "en", "fr", "it", "ch"],
replacement_template="IP_{}"
),
# Postleitzahlen (Deutschland)
SensitivePattern(
name="postal_code_de",
pattern=r'\b\d{5}\b',
languages=["de"],
replacement_template="PLZ_{}"
),
# Schweizer Postleitzahlen
SensitivePattern(
name="postal_code_ch",
pattern=r'\b[1-9]\d{3}\b',
languages=["ch"],
replacement_template="PLZ_CH_{}"
),
# Namen (einfache Heuristik - kann erweitert werden)
SensitivePattern(
name="names",
pattern=r'\b(Herr|Frau|Mr\.|Mrs\.|Ms\.|Monsieur|Madame|Signore|Signora)\s+[A-ZÄÖÜ][a-zäöüß]+\s+[A-ZÄÖÜ][a-zäöüß]+\b',
languages=["de", "en", "fr", "it", "ch"],
replacement_template="NAME_{}"
),
# Adressen (vereinfacht)
SensitivePattern(
name="address",
pattern=r'\b[A-ZÄÖÜ][a-zäöüß]+straße\s+\d+[a-z]?\b|\b[A-ZÄÖÜ][a-zäöüß]+\s+Street\s+\d+\b|\b\d+\s+[A-ZÄÖÜ][a-zäöüß]+\s+Street\b',
languages=["de", "en", "ch"],
replacement_template="ADDRESS_{}"
),
# Schweizer UID/IDE Nummer
SensitivePattern(
name="uid_number",
pattern=r'\bCHE-\d{3}\.\d{3}\.\d{3}\b',
languages=["ch"],
replacement_template="UID_CH_{}"
),
# Schweizer Bankkontonummern (BC-Nummern)
SensitivePattern(
name="bank_account_ch",
pattern=r'\b\d{2}-\d{2,6}-\d{1}\b',
languages=["ch"],
replacement_template="BANK_CH_{}"
),
]
def main():
"""Einfaches Beispiel für die Verwendung des Daten-Neutralisierers"""
anonymizer = DataAnonymizer()
# Beispieltext
sample_text = """
Sehr geehrte Frau Müller,
vielen Dank für Ihre E-Mail an max.mustermann@beispiel.de.
Ihre Telefonnummer 030-12345678 wurde in unserem System hinterlegt.
Die Rechnung wird an folgende Adresse gesendet:
Musterstraße 123, 12345 Berlin
Ihre IBAN: DE89 3704 0044 0532 0130 00
Mit freundlichen Grüßen
Max Mustermann
"""
# Anonymisierung
anonymized_text, mapping = anonymizer.anonymize_text(sample_text, "de")
print("Originaler Text:")
print(sample_text)
print("\n" + "="*50 + "\n")
print("Anonymisierter Text:")
print(anonymized_text)
print("\n" + "="*50 + "\n")
print("Mapping:")
for placeholder, original in mapping.items():
print(f"{placeholder} -> {original}")
if __name__ == "__main__":
main()

View file

@ -0,0 +1,133 @@
"""
Test-Anwendung für den Daten-Neutralisierer
Demonstriert die Funktionalität mit verschiedenen Testdaten
"""
import os
import json
from pathlib import Path
import sys
# Add the parent directory to the Python path
sys.path.append(str(Path(__file__).parent.parent))
# Import directly from the package
from test_neutralizer import DataAnonymizer, ChatDataProcessor, TEST_DATA
def test_text_anonymization():
"""Testet die Text-Anonymisierung für verschiedene Sprachen"""
anonymizer = DataAnonymizer()
for language in ["de", "ch", "fr", "it"]:
print(f"\n{'='*20} Test für Sprache: {language} {'='*20}")
# Text anonymisieren
anonymized_text, mapping = anonymizer.anonymize_text(TEST_DATA[language], language)
print("\nOriginaler Text:")
print(TEST_DATA[language])
print("\nAnonymisierter Text:")
print(anonymized_text)
print("\nMapping:")
for placeholder, original in mapping.items():
print(f"{placeholder} -> {original}")
# Test der Deanonymisierung
ai_response = f"Basierend auf dem Text können wir sehen, dass NAME_1 an EMAIL_1 geschrieben hat."
restored_response = anonymizer.deanonymize_text(ai_response, mapping)
print("\nKI-Antwort (anonymisiert):")
print(ai_response)
print("\nKI-Antwort (deanonymisiert):")
print(restored_response)
def test_file_processing():
"""Testet die Verarbeitung verschiedener Dateiformate"""
anonymizer = DataAnonymizer()
# Temporäre Testdateien erstellen
test_dir = Path("test_files")
test_dir.mkdir(exist_ok=True)
# JSON-Datei erstellen
json_path = test_dir / "test.json"
with open(json_path, "w", encoding="utf-8") as f:
json.dump(TEST_DATA["json"], f, indent=2)
# CSV-Datei erstellen
csv_path = test_dir / "test.csv"
with open(csv_path, "w", encoding="utf-8") as f:
f.write(TEST_DATA["csv"])
# Dateien verarbeiten
print("\n" + "="*20 + " JSON-Verarbeitung " + "="*20)
json_result = anonymizer.process_file(str(json_path), "de")
print("\nAnonymisierte JSON-Daten:")
print(json.dumps(json_result["anonymized_content"], indent=2))
print("\n" + "="*20 + " CSV-Verarbeitung " + "="*20)
csv_result = anonymizer.process_file(str(csv_path), "de")
print("\nAnonymisierte CSV-Daten:")
for row in csv_result["anonymized_content"]:
print(row)
# Aufräumen
json_path.unlink()
csv_path.unlink()
test_dir.rmdir()
def test_chat_processor():
"""Testet die Chat-Integration"""
processor = ChatDataProcessor()
# Temporäre Testdatei erstellen
test_dir = Path("test_files")
test_dir.mkdir(exist_ok=True)
txt_path = test_dir / "test.txt"
with open(txt_path, "w", encoding="utf-8") as f:
f.write(TEST_DATA["de"])
# Chat-Nachricht verarbeiten
print("\n" + "="*20 + " Chat-Verarbeitung " + "="*20)
result = processor.process_chat_message("user123", str(txt_path), "de")
print("\nSession-ID:", result["session_id"])
print("\nAnonymisierte Daten:")
print(result["content"])
# KI-Antwort verarbeiten
ai_response = "Basierend auf den Daten können wir sehen, dass NAME_1 an EMAIL_1 geschrieben hat."
restored = processor.restore_ai_response(result["session_id"], ai_response)
print("\nKI-Antwort (anonymisiert):")
print(ai_response)
print("\nKI-Antwort (deanonymisiert):")
print(restored["restored_response"])
# Aufräumen
txt_path.unlink()
test_dir.rmdir()
processor.cleanup_session(result["session_id"])
def main():
"""Hauptfunktion für die Test-Ausführung"""
print("Starte Tests für den Daten-Neutralisierer...")
# Text-Anonymisierung testen
test_text_anonymization()
# Dateiverarbeitung testen
test_file_processing()
# Chat-Integration testen
test_chat_processor()
print("\nAlle Tests abgeschlossen!")
if __name__ == "__main__":
main()

View file

@ -0,0 +1,96 @@
"""
Testdaten für den Daten-Neutralisierer
Enthält Beispieldaten für verschiedene Sprachen und Regionen
"""
# Deutsche Testdaten
DE_TEST_DATA = """
Sehr geehrte Frau Müller,
vielen Dank für Ihre E-Mail an max.mustermann@beispiel.de.
Ihre Telefonnummer 030-12345678 wurde in unserem System hinterlegt.
Die Rechnung wird an folgende Adresse gesendet:
Musterstraße 123, 12345 Berlin
Ihre IBAN: DE89 3704 0044 0532 0130 00
Steuernummer: 123/456/78901
Personalausweis: A12345678
Mit freundlichen Grüßen
Max Mustermann
"""
# Schweizer Testdaten
CH_TEST_DATA = """
Sehr geehrte Frau Weber,
vielen Dank für Ihre E-Mail an maria.weber@example.ch.
Ihre Telefonnummer +41 44 123 45 67 wurde in unserem System hinterlegt.
Die Rechnung wird an folgende Adresse gesendet:
Bahnhofstrasse 1, 8001 Zürich
Ihre AHV-Nummer: 756.1234.5678.90
UID-Nummer: CHE-123.456.789
Bankkonto: 01-234567-8
Mit freundlichen Grüssen
Maria Weber
"""
# Französische Testdaten
FR_TEST_DATA = """
Cher Monsieur Dupont,
Merci pour votre email à jean.dupont@example.fr.
Votre numéro de téléphone +33 1 23 45 67 89 a été enregistré dans notre système.
La facture sera envoyée à l'adresse suivante:
123 Rue de Paris, 75001 Paris
Votre numéro de sécurité sociale: 123456789012345
IBAN: FR76 1234 5678 9012 3456 7890 123
Cordialement,
Jean Dupont
"""
# Italienische Testdaten
IT_TEST_DATA = """
Gentile Signora Rossi,
Grazie per la sua email a anna.rossi@example.it.
Il suo numero di telefono +39 02 1234 5678 è stato registrato nel nostro sistema.
La fattura sarà inviata al seguente indirizzo:
Via Roma 123, 20100 Milano
Il suo codice fiscale: ABCDEF12G34H567I
IBAN: IT60 X123 4567 8901 2345 6789 012
Cordiali saluti,
Anna Rossi
"""
# Testdaten für verschiedene Dateiformate
TEST_JSON_DATA = {
"customer": {
"name": "Max Mustermann",
"email": "max.mustermann@beispiel.de",
"phone": "+49 30 12345678",
"address": "Musterstraße 123, 12345 Berlin",
"iban": "DE89 3704 0044 0532 0130 00"
}
}
TEST_CSV_DATA = """name,email,phone,address,iban
Max Mustermann,max.mustermann@beispiel.de,+49 30 12345678,Musterstraße 123 12345 Berlin,DE89 3704 0044 0532 0130 00
Maria Weber,maria.weber@example.ch,+41 44 123 45 67,Bahnhofstrasse 1 8001 Zürich,CH93 0076 7000 E529 0767 9
"""
# Dictionary mit allen Testdaten
TEST_DATA = {
"de": DE_TEST_DATA,
"ch": CH_TEST_DATA,
"fr": FR_TEST_DATA,
"it": IT_TEST_DATA,
"json": TEST_JSON_DATA,
"csv": TEST_CSV_DATA
}