This commit is contained in:
Ida Dittrich 2025-09-02 07:04:41 +02:00
commit 64bb90b0fa
46 changed files with 5249 additions and 93 deletions

View file

@ -65,17 +65,6 @@ class HandlingTasks:
logger.info(f"User Input: {userInput}")
available_docs = self.service.getAvailableDocuments(workflow)
# Set initial workflow context - handle new workflow vs continuation properly
current_round = getattr(workflow, 'currentRound', 0)
if current_round == 0:
# New workflow session, start with round 1
self.service.setWorkflowContext(round_number=1, task_number=0, action_number=0)
else:
# This should not happen for a new workflow - reset to ensure clean state
logger.warning(f"Workflow has currentRound={current_round} but should be 0 for new workflow. Resetting...")
self.resetWorkflowForNewSession()
self.service.setWorkflowContext(round_number=1, task_number=0, action_number=0)
# Check workflow status before calling AI service
self._checkWorkflowStopped()

View file

@ -1119,12 +1119,22 @@ Please provide a comprehensive summary of this conversation."""
def setWorkflowContext(self, round_number: int = None, task_number: int = None, action_number: int = None):
"""Set current workflow context for document generation and routing"""
try:
# Prepare update data
update_data = {}
if round_number is not None:
self.workflow.currentRound = round_number
update_data["currentRound"] = round_number
if task_number is not None:
self.workflow.currentTask = task_number
update_data["currentTask"] = task_number
if action_number is not None:
self.workflow.currentAction = action_number
update_data["currentAction"] = action_number
# Persist changes to database if any updates were made
if update_data:
self.interfaceChat.updateWorkflow(self.workflow.id, update_data)
logger.debug(f"Updated workflow context: Round {self.workflow.currentRound if hasattr(self.workflow, 'currentRound') else 'N/A'}, Task {self.workflow.currentTask if hasattr(self.workflow, 'currentTask') else 'N/A'}, Action {self.workflow.currentAction if hasattr(self.workflow, 'currentAction') else 'N/A'}")
except Exception as e:
@ -1143,27 +1153,35 @@ Please provide a comprehensive summary of this conversation."""
return {'currentRound': 0, 'currentTask': 0, 'currentAction': 0}
def incrementWorkflowContext(self, context_type: str):
"""Increment workflow context counters"""
"""Increment workflow context counters (task and action only - rounds handled in interface layer)"""
try:
if context_type == 'round':
current_round = self.workflow.currentRound if hasattr(self.workflow, 'currentRound') else 0
self.workflow.currentRound = current_round + 1
# Reset task and action when round changes
self.workflow.currentTask = 0
self.workflow.currentAction = 0
logger.info(f"Incremented workflow round to {self.workflow.currentRound}")
elif context_type == 'task':
update_data = {}
if context_type == 'task':
current_task = self.workflow.currentTask if hasattr(self.workflow, 'currentTask') else 0
self.workflow.currentTask = current_task + 1
# Reset action when task changes
self.workflow.currentAction = 0
update_data = {
"currentTask": self.workflow.currentTask,
"currentAction": 0
}
logger.info(f"Incremented workflow task to {self.workflow.currentTask}")
elif context_type == 'action':
current_action = self.workflow.currentAction if hasattr(self.workflow, 'currentAction') else 0
self.workflow.currentAction = current_action + 1
update_data = {
"currentAction": self.workflow.currentAction
}
logger.info(f"Incremented workflow action to {self.workflow.currentAction}")
else:
logger.warning(f"Unknown context type for increment: {context_type}")
return
# Persist changes to database
if update_data:
self.interfaceChat.updateWorkflow(self.workflow.id, update_data)
except Exception as e:
logger.error(f"Error incrementing workflow context: {str(e)}")

View file

@ -156,6 +156,25 @@ class UserConnection(BaseModel, ModelMixin):
frontend_readonly=True,
frontend_required=False
)
tokenStatus: Optional[str] = Field(
None,
description="Current token status: active, expired, none",
frontend_type="select",
frontend_readonly=True,
frontend_required=False,
frontend_options=[
{"value": "active", "label": {"en": "Active", "fr": "Actif"}},
{"value": "expired", "label": {"en": "Expired", "fr": "Expiré"}},
{"value": "none", "label": {"en": "None", "fr": "Aucun"}}
]
)
tokenExpiresAt: Optional[float] = Field(
None,
description="When the current token expires (UTC timestamp in seconds)",
frontend_type="timestamp",
frontend_readonly=True,
frontend_required=False
)
# Register labels for UserConnection
register_model_labels(
@ -171,7 +190,9 @@ register_model_labels(
"status": {"en": "Status", "fr": "Statut"},
"connectedAt": {"en": "Connected At", "fr": "Connecté le"},
"lastChecked": {"en": "Last Checked", "fr": "Dernière vérification"},
"expiresAt": {"en": "Expires At", "fr": "Expire le"}
"expiresAt": {"en": "Expires At", "fr": "Expire le"},
"tokenStatus": {"en": "Connection Status", "fr": "Statut de connexion"},
"tokenExpiresAt": {"en": "Expires At", "fr": "Expire le"}
}
)

View file

@ -398,7 +398,7 @@ register_model_labels(
)
class ChatStat(BaseModel, ModelMixin):
"""Data model for chat statistics"""
"""Data model for chat statistics - ONLY statistics, not workflow progress"""
id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="Primary key")
processingTime: Optional[float] = Field(None, description="Processing time in seconds")
tokenCount: Optional[int] = Field(None, description="Number of tokens processed")
@ -406,13 +406,6 @@ class ChatStat(BaseModel, ModelMixin):
bytesReceived: Optional[int] = Field(None, description="Number of bytes received")
successRate: Optional[float] = Field(None, description="Success rate of operations")
errorCount: Optional[int] = Field(None, description="Number of errors encountered")
# Enhanced workflow progress tracking
currentRound: Optional[int] = Field(None, description="Current round number in workflow")
totalTasks: Optional[int] = Field(None, description="Total number of tasks in current round")
currentTask: Optional[int] = Field(None, description="Current task number within round")
totalActions: Optional[int] = Field(None, description="Total number of actions in current task")
currentAction: Optional[int] = Field(None, description="Current action number within task")
# Register labels for ChatStat
register_model_labels(
@ -425,12 +418,7 @@ register_model_labels(
"bytesSent": {"en": "Bytes Sent", "fr": "Octets envoyés"},
"bytesReceived": {"en": "Bytes Received", "fr": "Octets reçus"},
"successRate": {"en": "Success Rate", "fr": "Taux de succès"},
"errorCount": {"en": "Error Count", "fr": "Nombre d'erreurs"},
"currentRound": {"en": "Current Round", "fr": "Tour actuel"},
"totalTasks": {"en": "Total Tasks", "fr": "Tâches totales"},
"currentTask": {"en": "Current Task", "fr": "Tâche actuelle"},
"totalActions": {"en": "Total Actions", "fr": "Actions totales"},
"currentAction": {"en": "Current Action", "fr": "Action actuelle"}
"errorCount": {"en": "Error Count", "fr": "Nombre d'erreurs"}
}
)
@ -487,25 +475,12 @@ class ChatMessage(BaseModel, ModelMixin):
# New workflow progress fields:
taskProgress: Optional[str] = Field(
None,
description="Task progress status: pending, running, success, fail, retry",
frontend_options=[
{"value": "pending", "label": {"en": "Pending", "fr": "En attente"}},
{"value": "running", "label": {"en": "Running", "fr": "En cours"}},
{"value": "success", "label": {"en": "Success", "fr": "Succès"}},
{"value": "fail", "label": {"en": "Failed", "fr": "Échec"}},
{"value": "retry", "label": {"en": "Retry", "fr": "Nouvel essai"}}
]
description="Task progress status: pending, running, success, fail, retry"
)
actionProgress: Optional[str] = Field(
None,
description="Action progress status: pending, running, success, fail",
frontend_options=[
{"value": "pending", "label": {"en": "Pending", "fr": "En attente"}},
{"value": "running", "label": {"en": "Running", "fr": "En cours"}},
{"value": "success", "label": {"en": "Success", "fr": "Succès"}},
{"value": "fail", "label": {"en": "Failed", "fr": "Échec"}}
]
description="Action progress status: pending, running, success, fail"
)
# Register labels for ChatMessage

View file

@ -157,7 +157,7 @@ class ChatObjects:
id=workflow["id"],
status=workflow.get("status", "running"),
name=workflow.get("name"),
currentRound=workflow.get("currentRound", 0), # Fixed: Default to 0 for new workflows
currentRound=workflow.get("currentRound", 0), # Default value
currentTask=workflow.get("currentTask", 0),
currentAction=workflow.get("currentAction", 0),
totalTasks=workflow.get("totalTasks", 0),
@ -166,12 +166,7 @@ class ChatObjects:
startedAt=workflow.get("startedAt", get_utc_timestamp()),
logs=[ChatLog(**log) for log in workflow.get("logs", [])],
messages=[ChatMessage(**msg) for msg in workflow.get("messages", [])],
stats=ChatStat(**workflow.get("dataStats", {})) if workflow.get("dataStats") else ChatStat(
bytesSent=0,
bytesReceived=0,
tokenCount=0,
processingTime=0
),
stats=ChatStat(**workflow.get("stats", {})) if workflow.get("stats") else None,
mandateId=workflow.get("mandateId", self.currentUser.mandateId)
)
except Exception as e:
@ -202,7 +197,7 @@ class ChatObjects:
id=created["id"],
status=created.get("status", "running"),
name=created.get("name"),
currentRound=created.get("currentRound", 0), # Fixed: Default to 0 for new workflows
currentRound=created.get("currentRound", 0), # Default value
currentTask=created.get("currentTask", 0),
currentAction=created.get("currentAction", 0),
totalTasks=created.get("totalTasks", 0),
@ -211,7 +206,7 @@ class ChatObjects:
startedAt=created.get("startedAt", currentTime),
logs=[],
messages=[],
stats=ChatStat(**created.get("dataStats", {})) if created.get("dataStats") else None,
stats=ChatStat(**created.get("stats", {})) if created.get("stats") else None,
mandateId=created.get("mandateId", self.currentUser.mandateId)
)
@ -248,12 +243,7 @@ class ChatObjects:
startedAt=updated.get("startedAt", workflow.startedAt),
logs=[ChatLog(**log) for log in updated.get("logs", workflow.logs)],
messages=[ChatMessage(**msg) for msg in updated.get("messages", workflow.messages)],
stats=ChatStat(**updated.get("dataStats", workflow.stats.dict() if workflow.stats else {})) if updated.get("dataStats") or workflow.stats else ChatStat(
bytesSent=0,
bytesReceived=0,
tokenCount=0,
processingTime=0
),
stats=ChatStat(**updated.get("stats", workflow.stats.dict() if workflow.stats else {})) if updated.get("stats") or workflow.stats else None,
mandateId=updated.get("mandateId", workflow.mandateId)
)
@ -709,7 +699,7 @@ class ChatObjects:
# Update workflow in database
self.db.recordModify("workflows", workflowId, {
"dataStats": currentStats
"stats": currentStats
})
# Log to stats table
@ -882,7 +872,7 @@ class ChatObjects:
# Wait a moment for any running processes to detect the stop
await asyncio.sleep(0.1)
# Update workflow - set status back to running for resumed workflows
# Update workflow - increment round for existing workflows
newRound = workflow.currentRound + 1
self.updateWorkflow(workflowId, {
"status": "running", # Set status back to running for resumed workflows
@ -890,14 +880,15 @@ class ChatObjects:
"currentRound": newRound
})
# Update the workflow object status and round number as well
workflow.status = "running"
workflow.currentRound = newRound
# Reload workflow object to get updated currentRound from database
workflow = self.loadWorkflowState(workflowId)
if not workflow:
raise ValueError(f"Failed to reload workflow {workflowId} after update")
# Add log entry for workflow resumption
self.createWorkflowLog({
"workflowId": workflowId,
"message": f"Workflow resumed (round {workflow.currentRound + 1})",
"message": f"Workflow resumed (round {workflow.currentRound})",
"type": "info",
"status": "running",
"progress": 0
@ -910,25 +901,29 @@ class ChatObjects:
"status": "running",
"startedAt": currentTime,
"lastActivity": currentTime,
"currentRound": 0, # Fixed: Start with 0, will be set to 1 when workflow starts
"currentRound": 0, # Default value, will be set to 1 in workflowStart()
"currentTask": 0,
"currentAction": 0,
"totalTasks": 0,
"totalActions": 0,
"mandateId": self.mandateId,
"messageIds": [],
"dataStats": {
"totalMessages": 0,
"totalDocuments": 0,
"totalTokens": 0
"stats": {
"processingTime": None,
"tokenCount": None,
"bytesSent": None,
"bytesReceived": None,
"successRate": None,
"errorCount": None
}
}
# Create workflow
workflow = self.createWorkflow(workflowData)
# Ensure workflow is in clean state for new session
if hasattr(workflow, 'currentRound') and workflow.currentRound != 0:
logger.warning(f"New workflow has currentRound={workflow.currentRound}, resetting to 0")
workflow.currentRound = 0
workflow.currentTask = 0
workflow.currentAction = 0
# Set currentRound to 1 for new workflows
workflow.currentRound = 1
self.updateWorkflow(workflow.id, {"currentRound": 1})
# Initialize stats for the new workflow
self.updateWorkflowStats(workflow.id, bytesSent=0, bytesReceived=0)

View file

@ -15,7 +15,7 @@ from datetime import datetime
import logging
import json
from modules.interfaces.interfaceAppModel import User, UserConnection, AuthAuthority, ConnectionStatus
from modules.interfaces.interfaceAppModel import User, UserConnection, AuthAuthority, ConnectionStatus, Token
from modules.security.auth import getCurrentUser, limiter
from modules.interfaces.interfaceAppObjects import getInterface, getRootInterface
from modules.shared.timezoneUtils import get_utc_timestamp
@ -23,6 +23,57 @@ from modules.shared.timezoneUtils import get_utc_timestamp
# Configure logger
logger = logging.getLogger(__name__)
def get_token_status_for_connection(interface, connection_id: str) -> tuple[str, Optional[float]]:
"""
Get token status and expiration for a connection.
Args:
interface: The database interface
connection_id: The connection ID to check
Returns:
tuple: (token_status, token_expires_at)
- token_status: 'active', 'expired', or 'none'
- token_expires_at: UTC timestamp or None
"""
try:
# Query tokens table for the latest token for this connection
tokens = interface.db.getRecordset(
table="tokens",
recordFilter={"connectionId": connection_id}
)
if not tokens:
return "none", None
# Find the most recent token (highest createdAt timestamp)
latest_token = None
latest_created_at = 0
for token_data in tokens:
created_at = token_data.get("createdAt", 0)
if created_at > latest_created_at:
latest_created_at = created_at
latest_token = token_data
if not latest_token:
return "none", None
# Check if token is expired
expires_at = latest_token.get("expiresAt")
if not expires_at:
return "none", None
current_time = get_utc_timestamp()
if expires_at <= current_time:
return "expired", expires_at
else:
return "active", expires_at
except Exception as e:
logger.error(f"Error getting token status for connection {connection_id}: {str(e)}")
return "none", None
router = APIRouter(
prefix="/api/connections",
tags=["Manage Connections"],
@ -47,7 +98,32 @@ async def get_connections(
# SECURITY FIX: All users (including admins) can only see their own connections
# This prevents admin from seeing other users' connections and causing confusion
return interface.getUserConnections(currentUser.id)
connections = interface.getUserConnections(currentUser.id)
# Enhance each connection with token status information
enhanced_connections = []
for connection in connections:
# Get token status for this connection
token_status, token_expires_at = get_token_status_for_connection(interface, connection.id)
# Create enhanced connection with token status
enhanced_connection = UserConnection(
id=connection.id,
userId=connection.userId,
authority=connection.authority,
externalId=connection.externalId,
externalUsername=connection.externalUsername,
externalEmail=connection.externalEmail,
status=connection.status,
connectedAt=connection.connectedAt,
lastChecked=connection.lastChecked,
expiresAt=connection.expiresAt,
tokenStatus=token_status,
tokenExpiresAt=token_expires_at
)
enhanced_connections.append(enhanced_connection)
return enhanced_connections
except Exception as e:
logger.error(f"Error getting connections: {str(e)}")
@ -164,8 +240,26 @@ async def update_connection(
# Clear cache to ensure fresh data
interface.db.clearTableCache("connections")
# Get updated connection
return connection
# Get token status for the updated connection
token_status, token_expires_at = get_token_status_for_connection(interface, connectionId)
# Create enhanced connection with token status
enhanced_connection = UserConnection(
id=connection.id,
userId=connection.userId,
authority=connection.authority,
externalId=connection.externalId,
externalUsername=connection.externalUsername,
externalEmail=connection.externalEmail,
status=connection.status,
connectedAt=connection.connectedAt,
lastChecked=connection.lastChecked,
expiresAt=connection.expiresAt,
tokenStatus=token_status,
tokenExpiresAt=token_expires_at
)
return enhanced_connection
except HTTPException:
raise

View file

@ -68,6 +68,8 @@ async def upload_file(
workflowId: Optional[str] = Form(None),
currentUser: User = Depends(getCurrentUser)
) -> JSONResponse:
# Add fileName property to UploadFile for consistency with backend model
file.fileName = file.filename
"""Upload a file"""
try:
managementInterface = interfaceComponentObjects.getInterface(currentUser)

View file

@ -67,7 +67,7 @@ async def get_workflows(
id=workflow_data["id"],
status=workflow_data.get("status", "running"),
name=workflow_data.get("name"),
currentRound=workflow_data.get("currentRound", 0), # Fixed: Default to 0 for new workflows
currentRound=workflow_data.get("currentRound", 0), # Default value
currentTask=workflow_data.get("currentTask", 0),
currentAction=workflow_data.get("currentAction", 0),
totalTasks=workflow_data.get("totalTasks", 0),
@ -76,12 +76,7 @@ async def get_workflows(
startedAt=workflow_data.get("startedAt", get_utc_timestamp()),
logs=[ChatLog(**log) for log in workflow_data.get("logs", [])],
messages=[ChatMessage(**msg) for msg in workflow_data.get("messages", [])],
stats=ChatStat(**workflow_data.get("dataStats", {})) if workflow_data.get("dataStats") else ChatStat(
bytesSent=0,
bytesReceived=0,
tokenCount=0,
processingTime=0
),
stats=ChatStat(**workflow_data.get("stats", {})) if workflow_data.get("stats") else None,
mandateId=workflow_data.get("mandateId", currentUser.mandateId or "")
)
workflows.append(workflow)

263
test_neutralizer/apprun.py Normal file
View file

@ -0,0 +1,263 @@
"""
DSGVO-konformer Daten-Neutralisierer für KI-Agentensysteme
Unterstützt TXT, JSON, CSV, Excel und Word-Dateien
Mehrsprachig: DE, EN, FR, IT
"""
import os
import shutil
import logging
import csv
import json
import pandas as pd
from datetime import datetime
from pathlib import Path
from neutralizer import DataAnonymizer
import traceback
# Define directories
SCRIPT_DIR = Path(__file__).parent
INPUT_DIR = SCRIPT_DIR / 'input'
OUTPUT_DIR = SCRIPT_DIR / 'output'
LOG_DIR = SCRIPT_DIR / 'logs'
LOG_MAPPING = LOG_DIR / 'log_mapping.csv'
LOG_REPLACEMENTS = LOG_DIR / 'log_replacements.csv'
# Configure logging
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
def setup_directories():
"""Setup output and log directories"""
# Close any existing log handlers
for handler in logger.handlers[:]:
handler.close()
logger.removeHandler(handler)
# Clear and recreate output directory
output_dir = Path("output")
if output_dir.exists():
shutil.rmtree(output_dir)
output_dir.mkdir()
logger.info(f"Output directory '{output_dir}' created")
# Clear and recreate logs directory
log_dir = Path("logs")
if log_dir.exists():
shutil.rmtree(log_dir)
log_dir.mkdir()
logger.info(f"Log directory '{log_dir}' created")
# Create log files
mapping_log = log_dir / "log_mapping.csv"
replacements_log = log_dir / "log_replacements.csv"
# Create headers for mapping log
with open(mapping_log, 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow(['timestamp', 'success', 'file_name', 'replaced_fields', 'content_type', 'headers', 'row_count'])
# Create headers for replacements log
with open(replacements_log, 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow(['timestamp', 'success', 'file_name', 'original', 'replacement'])
# Reconfigure logging with new log file
for handler in logger.handlers[:]:
handler.close()
logger.removeHandler(handler)
file_handler = logging.FileHandler(LOG_DIR / 'app.log', encoding='utf-8')
file_handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
logger.addHandler(file_handler)
return output_dir, log_dir
def log_mapping(log_dir: Path, file_name: str, success: bool, replaced_fields: list):
"""Log mapping information"""
try:
with open(log_dir / "log_mapping.csv", 'a', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow([
datetime.now().isoformat(),
file_name,
success,
';'.join(replaced_fields) if replaced_fields else '',
'unknown'
])
except Exception as e:
logger.error(f"Error logging mapping: {str(e)}")
def log_replacements(log_dir: Path, file_name: str, mapping: dict):
"""Log replacement information"""
try:
with open(log_dir / "log_replacements.csv", 'a', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
for original, replacement in mapping.items():
writer.writerow([
datetime.now().isoformat(),
file_name,
original,
replacement
])
except Exception as e:
logger.error(f"Error logging replacements: {str(e)}")
def save_anonymized_data(data: any, output_path: Path, file_type: str):
"""Save anonymized data to file"""
try:
if file_type == '.csv':
if isinstance(data, pd.DataFrame):
data.to_csv(output_path, index=False, encoding='utf-8')
else:
raise ValueError("Data must be a DataFrame for CSV output")
elif file_type == '.json':
if isinstance(data, pd.DataFrame):
data.to_json(output_path, orient='records', force_ascii=False)
else:
with open(output_path, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
elif file_type == '.xml':
if isinstance(data, str):
with open(output_path, 'w', encoding='utf-8') as f:
f.write(data)
else:
raise ValueError("Data must be a string for XML output")
elif file_type in ['.txt', '.docx']:
if isinstance(data, str):
with open(output_path, 'w', encoding='utf-8') as f:
f.write(data)
else:
raise ValueError("Data must be a string for text output")
else:
raise ValueError(f"Unsupported file type: {file_type}")
except Exception as e:
logger.error(f"Error saving anonymized data to {output_path}: {str(e)}")
raise
def read_file_content(file_path: Path) -> tuple[str, str]:
"""Read file content and determine content type"""
try:
file_type = file_path.suffix.lower()
if file_type == '.docx':
import docx
doc = docx.Document(file_path)
content = '\n'.join(para.text for para in doc.paragraphs)
else:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
return content, file_type
except Exception as e:
logger.error(f"Error reading file {file_path}: {str(e)}")
raise
def process_file(file_path: Path, anonymizer: DataAnonymizer) -> bool:
"""Process a single file and save anonymized version"""
try:
# Read file content
content = file_path.read_text(encoding='utf-8')
# Process content
result = anonymizer.process_content(content, file_path.suffix[1:])
if result.data is None:
logger.error(f"Failed to process {file_path.name}")
return False
# Save anonymized content with neutralized_ prefix
output_path = OUTPUT_DIR / f"neutralized_{file_path.name}"
if file_path.suffix.lower() == '.csv':
result.data.to_csv(output_path, index=False)
elif file_path.suffix.lower() == '.json':
with open(output_path, 'w', encoding='utf-8') as f:
json.dump(result.data, f, indent=2)
elif file_path.suffix.lower() == '.xml':
with open(output_path, 'w', encoding='utf-8') as f:
f.write(result.data)
else:
# For text files, preserve original whitespace
with open(output_path, 'w', encoding='utf-8') as f:
f.write(result.data)
# Log processing details
timestamp = datetime.now().isoformat()
success = True
# Create detailed log entry
log_entry = {
'timestamp': timestamp,
'success': success,
'file_name': file_path.name,
'replaced_fields': ';'.join(set(result.replaced_fields)), # Use set to remove duplicates
'content_type': result.processed_info.get('type', 'unknown')
}
# Add type-specific details
if result.processed_info['type'] == 'table':
log_entry.update({
'headers': ';'.join(result.processed_info['headers']),
'row_count': result.processed_info['row_count']
})
elif result.processed_info['type'] == 'text':
tables = result.processed_info.get('tables', [])
text_sections = result.processed_info.get('text_sections', [])
log_entry.update({
'headers': '', # Empty for text files
'row_count': sum(s['length'] for s in text_sections) # Total text length
})
# Write to log file
with open(LOG_MAPPING, 'a', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=log_entry.keys())
if f.tell() == 0: # Write header if file is empty
writer.writeheader()
writer.writerow(log_entry)
# Log replacements
for original, replacement in result.mapping.items():
with open(LOG_REPLACEMENTS, 'a', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow([timestamp, success, file_path.name, original, replacement])
return True
except Exception as e:
logger.error(f"Error processing {file_path.name}: {str(e)}")
logger.debug(traceback.format_exc())
return False
def main():
# Setup directories
setup_directories()
# Initialize anonymizer
anonymizer = DataAnonymizer()
# Process all files
logger.info("Starting file processing...")
testdata_dir = Path("testdata")
for file_path in testdata_dir.glob("*.*"):
try:
logger.info(f"Processing file: {file_path.name}")
# Process file
if process_file(file_path, anonymizer):
logger.info(f"Anonymization completed for {file_path.name}")
else:
logger.error(f"Error processing {file_path.name}")
except Exception as e:
logger.error(f"Error processing {file_path.name}: {str(e)}")
continue
logger.info("Processing completed!")
if __name__ == "__main__":
main()

View file

@ -0,0 +1,17 @@
timestamp,success,file_name,replaced_fields,content_type,headers,row_count
2025-06-07T18:12:08.019661,True,Case.md,,text,,0
2025-06-07T18:12:08.040653,True,customers.csv,ahv_number;phone;credit_card;address;name;iban;email,table,id;name;email;phone;address;iban;credit_card;ahv_number,5
2025-06-07T18:12:08.064201,True,cv_lara_meier.txt,,text,,0
2025-06-07T18:12:08.080961,True,employees.csv,bank_account;first_name;last_name;office_address;phone;uid_number;email,table,employee_id;first_name;last_name;email;phone;department;office_address;uid_number;bank_account,5
2025-06-07T18:12:08.101660,True,english.txt,,text,,0
2025-06-07T18:12:08.125634,True,example.json,,json
2025-06-07T18:12:08.157397,True,example.xml,,xml
2025-06-07T18:12:08.178030,True,french.txt,,text,,0
2025-06-07T18:12:08.201071,True,german.txt,,text,,0
2025-06-07T18:12:08.228652,True,geschaeftsstrategie.txt,,text,,0
2025-06-07T18:12:08.255652,True,geschäfte.csv,datum;kundenname;kundenemail;zahlungsdetails;lieferadresse,table,geschäft_id;datum;kundenname;kundenemail;betrag;zahlungsmethode;zahlungsdetails;lieferadresse,5
2025-06-07T18:12:08.284172,True,italian.txt,,text,,0
2025-06-07T18:12:08.314527,True,kunden.csv,kreditkarte;vorname;adresse;telefon;iban;steuernummer;email;nachname,table,kunden_id;vorname;nachname;email;telefon;adresse;iban;kreditkarte;steuernummer,5
2025-06-07T18:12:08.349750,True,mitarbeiter.csv,vorname;büroadresse;telefon;steuernummer;email;sozialversicherungsnummer;nachname,table,mitarbeiter_id;vorname;nachname;email;telefon;abteilung;büroadresse;steuernummer;sozialversicherungsnummer,5
2025-06-07T18:12:08.389324,True,swiss.txt,,text,,0
2025-06-07T18:12:08.431916,True,transactions.csv,date;customer_email;payment_details;customer_name;shipping_address,table,transaction_id;date;customer_name;customer_email;amount;payment_method;payment_details;shipping_address,5
1 timestamp,success,file_name,replaced_fields,content_type,headers,row_count
2 2025-06-07T18:12:08.019661,True,Case.md,,text,,0
3 2025-06-07T18:12:08.040653,True,customers.csv,ahv_number;phone;credit_card;address;name;iban;email,table,id;name;email;phone;address;iban;credit_card;ahv_number,5
4 2025-06-07T18:12:08.064201,True,cv_lara_meier.txt,,text,,0
5 2025-06-07T18:12:08.080961,True,employees.csv,bank_account;first_name;last_name;office_address;phone;uid_number;email,table,employee_id;first_name;last_name;email;phone;department;office_address;uid_number;bank_account,5
6 2025-06-07T18:12:08.101660,True,english.txt,,text,,0
7 2025-06-07T18:12:08.125634,True,example.json,,json
8 2025-06-07T18:12:08.157397,True,example.xml,,xml
9 2025-06-07T18:12:08.178030,True,french.txt,,text,,0
10 2025-06-07T18:12:08.201071,True,german.txt,,text,,0
11 2025-06-07T18:12:08.228652,True,geschaeftsstrategie.txt,,text,,0
12 2025-06-07T18:12:08.255652,True,geschäfte.csv,datum;kundenname;kundenemail;zahlungsdetails;lieferadresse,table,geschäft_id;datum;kundenname;kundenemail;betrag;zahlungsmethode;zahlungsdetails;lieferadresse,5
13 2025-06-07T18:12:08.284172,True,italian.txt,,text,,0
14 2025-06-07T18:12:08.314527,True,kunden.csv,kreditkarte;vorname;adresse;telefon;iban;steuernummer;email;nachname,table,kunden_id;vorname;nachname;email;telefon;adresse;iban;kreditkarte;steuernummer,5
15 2025-06-07T18:12:08.349750,True,mitarbeiter.csv,vorname;büroadresse;telefon;steuernummer;email;sozialversicherungsnummer;nachname,table,mitarbeiter_id;vorname;nachname;email;telefon;abteilung;büroadresse;steuernummer;sozialversicherungsnummer,5
16 2025-06-07T18:12:08.389324,True,swiss.txt,,text,,0
17 2025-06-07T18:12:08.431916,True,transactions.csv,date;customer_email;payment_details;customer_name;shipping_address,table,transaction_id;date;customer_name;customer_email;amount;payment_method;payment_details;shipping_address,5

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,338 @@
"""
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
from typing import Dict, List, Tuple, Any, Union, Optional
from dataclasses import dataclass
import logging
import traceback
import xml.etree.ElementTree as ET
from io import StringIO
from patterns import Pattern, HeaderPatterns, DataPatterns, get_pattern_for_header, find_patterns_in_text, TextTablePatterns
# Configure logging
logger = logging.getLogger(__name__)
@dataclass
class TableData:
"""Repräsentiert Tabellendaten"""
headers: List[str]
rows: List[List[str]]
source_type: str # 'csv', 'json', 'xml', 'text_table'
@dataclass
class PlainText:
"""Repräsentiert normalen Text"""
content: str
source_type: str # 'txt', 'docx', 'text_plain'
@dataclass
class ProcessResult:
"""Result of content processing"""
data: Any
mapping: Dict[str, str]
replaced_fields: List[str]
processed_info: Dict[str, Any] # Additional processing information
class DataAnonymizer:
"""Hauptklasse für die Datenanonymisierung"""
def __init__(self):
"""Initialize the anonymizer with patterns"""
self.header_patterns = HeaderPatterns.patterns
self.data_patterns = DataPatterns.patterns
self.replaced_fields = set()
self.mapping = {}
self.processing_info = []
def _normalize_whitespace(self, text: str) -> str:
"""Normalize whitespace in text"""
text = re.sub(r'\s+', ' ', text)
text = text.replace('\r\n', '\n').replace('\r', '\n')
return text.strip()
def _is_table_line(self, line: str) -> bool:
"""Check if a line represents a table row"""
return bool(re.match(r'^\s*[^:]+:\s*[^:]+$', line) or
re.match(r'^\s*[^\t]+\t[^\t]+$', line))
def _extract_tables_from_text(self, content: str) -> Tuple[List[TableData], List[PlainText]]:
"""
Extract tables and plain text from content
Args:
content: Content to process
Returns:
Tuple of (list of tables, list of plain text sections)
"""
tables = []
plain_texts = []
# Process the entire content as plain text
plain_texts.append(PlainText(content=content, source_type='text_plain'))
return tables, plain_texts
def _anonymize_table(self, table: TableData) -> TableData:
"""Anonymize table data"""
try:
anonymized_table = TableData(
headers=table.headers.copy(),
rows=[row.copy() for row in table.rows],
source_type=table.source_type
)
for i, header in enumerate(anonymized_table.headers):
pattern = get_pattern_for_header(header, self.header_patterns)
if pattern:
for row in anonymized_table.rows:
if row[i] is not None:
original = str(row[i])
if original not in self.mapping:
self.mapping[original] = pattern.replacement_template.format(len(self.mapping) + 1)
row[i] = self.mapping[original]
return anonymized_table
except Exception as e:
logger.error(f"Error anonymizing table: {str(e)}")
logger.debug(traceback.format_exc())
raise
def _anonymize_plain_text(self, text: PlainText) -> PlainText:
"""Anonymize plain text content"""
try:
# Process the entire text at once instead of line by line
current_text = text.content
# Find all matches in the entire text
matches = find_patterns_in_text(current_text, self.data_patterns)
# Process matches in reverse order to avoid position shifting
for match in sorted(matches, key=lambda x: x[2], reverse=True):
pattern_name, matched_text, start, end = match
# Skip if the matched text is already a placeholder
if re.match(r'\[[A-Z_]+\d+\]', matched_text):
continue
# Find the pattern that matched
pattern = next((p for p in self.data_patterns if p.name == pattern_name), None)
if pattern:
# Use the pattern's replacement template
if matched_text not in self.mapping:
self.mapping[matched_text] = pattern.replacement_template.format(len(self.mapping) + 1)
replacement = self.mapping[matched_text]
if pattern_name == 'email':
print(f"DEBUG: Replacing email '{matched_text}' with '{replacement}'")
print(f"DEBUG: Text after replacement: {current_text[:start] + replacement + current_text[end:]}")
# Replace the matched text while preserving surrounding whitespace
current_text = current_text[:start] + replacement + current_text[end:]
return PlainText(content=current_text, source_type=text.source_type)
except Exception as e:
logger.error(f"Error anonymizing plain text: {str(e)}")
logger.debug(traceback.format_exc())
raise
def _anonymize_json_value(self, value: Any, key: str = None) -> Any:
"""
Recursively anonymize JSON values based on their keys and content
Args:
value: Value to anonymize
key: Key name (if part of a key-value pair)
Returns:
Anonymized value
"""
if isinstance(value, dict):
return {k: self._anonymize_json_value(v, k) for k, v in value.items()}
elif isinstance(value, list):
return [self._anonymize_json_value(item) for item in value]
elif isinstance(value, str):
# Check if this is a key we should process
if key:
pattern = get_pattern_for_header(key, self.header_patterns)
if pattern:
if value not in self.mapping:
self.mapping[value] = pattern.replacement_template.format(len(self.mapping) + 1)
return self.mapping[value]
# Check if the value itself matches any patterns
matches = find_patterns_in_text(value, self.data_patterns)
if matches:
# Use the first match's pattern
pattern_name = matches[0][0]
if value not in self.mapping:
self.mapping[value] = f"{pattern_name.upper()}_{len(self.mapping) + 1}"
return self.mapping[value]
return value
else:
return value
def _anonymize_xml_element(self, element: ET.Element, indent: str = '') -> str:
"""
Recursively process XML element and return formatted string
Args:
element: XML element to process
indent: Current indentation level
Returns:
Formatted XML string
"""
# Process attributes
processed_attrs = {}
for attr_name, attr_value in element.attrib.items():
# Check if attribute name matches any header patterns
pattern = get_pattern_for_header(attr_name, self.header_patterns)
if pattern:
if attr_value not in self.mapping:
self.mapping[attr_value] = pattern.replacement_template.format(len(self.mapping) + 1)
processed_attrs[attr_name] = self.mapping[attr_value]
else:
# Check if attribute value matches any data patterns
matches = find_patterns_in_text(attr_value, self.data_patterns)
if matches:
pattern_name = matches[0][0]
pattern = next((p for p in self.data_patterns if p.name == pattern_name), None)
if pattern:
if attr_value not in self.mapping:
self.mapping[attr_value] = pattern.replacement_template.format(len(self.mapping) + 1)
processed_attrs[attr_name] = self.mapping[attr_value]
else:
processed_attrs[attr_name] = attr_value
else:
processed_attrs[attr_name] = attr_value
attrs = ' '.join(f'{k}="{v}"' for k, v in processed_attrs.items())
attrs = f' {attrs}' if attrs else ''
# Process text content
text = element.text.strip() if element.text and element.text.strip() else ''
if text:
# Check if text matches any patterns
matches = find_patterns_in_text(text, self.data_patterns)
if matches:
pattern_name = matches[0][0]
pattern = next((p for p in self.data_patterns if p.name == pattern_name), None)
if pattern:
if text not in self.mapping:
self.mapping[text] = pattern.replacement_template.format(len(self.mapping) + 1)
text = self.mapping[text]
# Process child elements
children = []
for child in element:
child_str = self._anonymize_xml_element(child, indent + ' ')
children.append(child_str)
# Build element string
if not children and not text:
return f"{indent}<{element.tag}{attrs}/>"
elif not children:
return f"{indent}<{element.tag}{attrs}>{text}</{element.tag}>"
else:
result = [f"{indent}<{element.tag}{attrs}>"]
if text:
result.append(f"{indent} {text}")
result.extend(children)
result.append(f"{indent}</{element.tag}>")
return '\n'.join(result)
def process_content(self, content: str, content_type: str) -> ProcessResult:
"""
Process content and return anonymized data
Args:
content: Content to process
content_type: Type of content ('csv', 'json', 'xml', 'text')
Returns:
ProcessResult: Contains anonymized data, mapping, replaced fields and processing info
"""
try:
replaced_fields = []
processed_info = {}
if content_type in ['csv', 'json', 'xml']:
# Handle as table
if content_type == 'csv':
df = pd.read_csv(StringIO(content), encoding='utf-8')
table = TableData(
headers=df.columns.tolist(),
rows=df.values.tolist(),
source_type='csv'
)
processed_info['type'] = 'table'
processed_info['headers'] = table.headers
processed_info['row_count'] = len(table.rows)
elif content_type == 'json':
data = json.loads(content)
# Process JSON recursively
result = self._anonymize_json_value(data)
processed_info['type'] = 'json'
return ProcessResult(result, self.mapping, replaced_fields, processed_info)
else: # xml
root = ET.fromstring(content)
# Process XML recursively with proper formatting
result = self._anonymize_xml_element(root)
processed_info['type'] = 'xml'
return ProcessResult(result, self.mapping, replaced_fields, processed_info)
if not table.rows:
return ProcessResult(None, self.mapping, [], processed_info)
anonymized_table = self._anonymize_table(table)
# Track replaced fields
for i, header in enumerate(anonymized_table.headers):
for orig_row, anon_row in zip(table.rows, anonymized_table.rows):
if anon_row[i] != orig_row[i]:
replaced_fields.append(header)
# Convert back to original format
if content_type == 'csv':
result = pd.DataFrame(anonymized_table.rows, columns=anonymized_table.headers)
elif content_type == 'json':
if len(anonymized_table.headers) == 1 and anonymized_table.headers[0] == 'value':
result = anonymized_table.rows[0][0]
else:
result = dict(zip(anonymized_table.headers, anonymized_table.rows[0]))
else: # xml
result = ET.tostring(root, encoding='unicode')
return ProcessResult(result, self.mapping, replaced_fields, processed_info)
else:
# Handle as text
# First, identify what needs to be replaced using table detection
tables, plain_texts = self._extract_tables_from_text(content)
processed_info['type'] = 'text'
processed_info['tables'] = [{'headers': t.headers, 'row_count': len(t.rows)} for t in tables]
# Process plain text sections
anonymized_texts = [self._anonymize_plain_text(text) for text in plain_texts]
# Combine all processed content
result = content
for text, anonymized_text in zip(plain_texts, anonymized_texts):
if text.content != anonymized_text.content:
result = result.replace(text.content, anonymized_text.content)
return ProcessResult(result, self.mapping, replaced_fields, processed_info)
except Exception as e:
logger.error(f"Error processing content: {str(e)}")
logger.debug(traceback.format_exc())
return ProcessResult(None, self.mapping, [], {'type': 'error', 'error': str(e)})

View file

@ -0,0 +1,608 @@
# Bewertung der PowerOn AI Platform
Basierend auf dem nachstehenden Q&A ergibt sich nachfolgende Bewertung des Softwareprodukts "PowerOn AI Platform".
## Aktueller Wert per Juni 2025
1. **Technischer Wert des Codes**:
- Professionelle, modulare Codebasis (~50.000-60.000 LOC)
- Moderne Architektur mit innovativen Komponenten
- 5 Personenmonate Entwicklung x CHF 15.000/PM = CHF 75.000
- Zusätzlicher Wert durch Enterprise-Ready Architektur: CHF 50.000
2. **Bisherige Investitionen**:
- Hardware/Software: CHF 20.000
- Expertise-Premium (30+ Jahre Erfahrung): CHF 25.000
3. **IP und Innovationswert**:
- Multi-Agent Workflow-System
- Modulare Architecture mit Alleinstellungsmerkmalen
- Geschätzter Wert: CHF 100.000
4. **Marktpotenzial-Faktor**:
- Adressierbares Marktvolumen von CHF 500-700 Mio.
- Wachstumsmarkt (25-30% jährlich)
- Frühphasen-Multiplikator: 2x
**Aktueller Gesamtwert (Juni 2025)**: **CHF 500.000**
## Prognostizierte Wertentwicklung
### Ende 2025
- Abschluss der technischen Entwicklung
- Erste Pilotprojekte mit 3-5 Referenzkunden
- Validierung des Produkts am Markt
- **Geschätzter Wert Ende 2025**: **CHF 1,2 Millionen**
(Steigerung durch Marktvalidierung und Risikoreduktion)
### Ende 2026
- 20-30 Kunden
- ARR: CHF 0,5-0,8 Mio.
- Etablierung im DACH-Markt
- **Geschätzter Wert Ende 2026**: **CHF 4-5 Millionen**
(Bewertungsmultiplikator von 6-8x ARR für wachstumsstarke SaaS)
### Ende 2027
- 70-90 Kunden
- ARR: CHF 2-2,5 Mio.
- Erweiterung der Produktpalette
- **Geschätzter Wert Ende 2027**: **CHF 12-15 Millionen**
(Bewertungsmultiplikator von 6x ARR)
### Ende 2028
- 150+ Kunden
- ARR: CHF 4,5 Mio.
- Internationale Expansion
- **Geschätzter Wert Ende 2028**: **CHF 25-30 Millionen**
(Bewertungsmultiplikator von 5,5-6,5x ARR für etablierte SaaS)
## Schlüsselfaktoren und Risikobeurteilung für die Wertentwicklung
1. **Erfolgreiche Markteinführung**: Der Übergang von Entwicklung zu erfolgreicher Pilotphase ist kritisch für die Wertentwicklung 2025-2026.
2. **Skalierung des Vertriebs**: Die Fähigkeit, die Kundenakquisition gemäss der Prognose zu skalieren, ist entscheidend für die 2026-[ADDRESS_2].
3. **Kapitaleffizienz**: Die effiziente Nutzung des Kapitals (CHF 750.000-1.050.000) für die nächste Entwicklungsphase wird die Bewertung massgeblich beeinflussen.
4. **Marktdynamik**: Die Entwicklung des KI-Marktes und regulatorische Änderungen können sowohl positive als auch negative Auswirkungen haben.
Diese Bewertung basiert auf der Annahme, dass die Meilensteine wie geplant erreicht werden und keine signifikanten externen Faktoren die Marktentwicklung negativ beeinflussen.
# Kriterienkatalog zur Softwarebewertung
## Teil 1: Technische Bewertung (Code-basiert)
1. Wie umfangreich ist die Codebasis (LOC, Module, Komponenten)?
2. Welche Programmiersprachen und Frameworks wurden verwendet?
3. Wie hoch ist die Codequalität und -konsistenz (saubere Architektur, Dokumentation, Tests)?
4. Gibt es innovative Algorithmen oder patentierbare technische Lösungen?
5. Wie modular und wartbar ist die Software gestaltet?
6. Wie robust ist die Fehlerbehandlung und Sicherheitsarchitektur?
7. Wie skalierbar ist die technische Infrastruktur?
8. Gibt es technische Schulden, die zukünftige Entwicklungen behindern könnten?
### 1. Umfang der Codebasis
- **Frontend**: Modulare JavaScript-Struktur mit ca. 15 Hauptmodulen
- **Backend**: Python/FastAPI mit ca. 15 Hauptmodulen
- **Hauptkomponenten**:
- Frontend: Workflow, UI, Koordination, Datenmanagement
- Backend: Gateway, Agent Service, Connectors, Workflow Manager
- **Geschätzte LOC**: ~50,000-60,000 Zeilen Code
### 2. Programmiersprachen und Frameworks
- **Frontend**:
- JavaScript (ES6+)
- Modulares System mit ES6-Import/Export
- Vanilla JS ohne externe Frameworks
- **Backend**:
- Python 3.x
- FastAPI für REST-API
- Asyncio für asynchrone Verarbeitung
### 3. Codequalität und -konsistenz
- **Saubere Architektur**:
- Klare Trennung Frontend/Backend
- Modulare Struktur mit definierten Verantwortlichkeiten
- State Machine Pattern für Workflow-Management
- **Dokumentation**:
- Ausführliche JSDoc/Python-Docstrings
- Architekturdiagramme (Mermaid)
- Technische Spezifikationen
- **Tests**:
- Automatisierte Modultests
- Manuell Integrationstests
- Benutzertests über Tickets in Clickup
### 4. Innovative Algorithmen/patentierbare Lösungen
- Multi-Agent Workflow-System mit spezialisierten Agenten
- Modulares Agent-Registry-System
- State Machine für Workflow-Koordination
- Dynamische Agenten-Integration
### 5. Modularität und Wartbarkeit
- **Hohe Modularität**:
- Klare Trennung der Verantwortlichkeiten
- Plug-and-Play Agent-System
- Erweiterbare Connector-Architektur
- **Wartbarkeit**:
- Konsistente Codestruktur
- Klare Namenskonventionen
- Dokumentierte Schnittstellen
### 6. Fehlerbehandlung und Sicherheit
- **Robuste Fehlerbehandlung**:
- State Machine für Workflow-Status
- Exception Handling auf allen Ebenen
- Logging-System für Debugging
- **Sicherheitsarchitektur**:
- Multi-Tenant-Architektur
- Authentifizierung/Autorisierung
- Mandantenverwaltung
### 7. Skalierbarkeit
- **Horizontale Skalierbarkeit**:
- Modulare Architektur
- Asynchrone Verarbeitung
- Connector-System für externe Dienste
- **Vertikale Skalierbarkeit**:
- Workflow-Parallelisierung
- Agent-Pooling
- Caching-Mechanismen
### 8. Technische Schulden
- **Potenzielle Verbesserungsbereiche**:
- Test-Coverage nicht sichtbar
- Eventuell fehlende Performance-Optimierungen
- Dokumentation für Zielgruppen noch unvollständig
- **Keine kritischen Blockierer identifiziert**
### Fazit der technischen Bewertung
Die Codebasis zeigt eine professionelle, gut strukturierte Enterprise-Anwendung mit klarer Architektur und modernen Best Practices. Die modulare Struktur und die saubere Implementierung der State Machine für Workflow-Management sind besonders hervorzuheben. Die Anwendung ist technisch reif und zeigt ein hohes Mass an Professionalität in der Implementierung.
## Teil 2: Bewertung der bisherigen Aufwände
### 1. Entwicklungsaufwände
- **Patrick**:
- ValueOn AG: 80 Stunden
- Private Entwicklung: 650 Stunden
- **Gesamt**: 730 Stunden (ca. 4.5 Personenmonate)
- **Ida**:
- ValueOn AG: 60 Stunden
- **Gesamt**: 60 Stunden (ca. 0.4 Personenmonate)
- **Gesamtaufwand**: ~5 Personenmonate
### 2. Qualifikationen und Erfahrungslevel
- **Patrick**:
- Business Consultant
- Software Architect
- Full Stack Developer
- 30+ Jahre Berufserfahrung
- Experte für Enterprise-Architekturen
- **Ida**:
- Business Analyst
- Project Manager
- Scrum Master
- Erfahrung in agiler Entwicklung
- Expertise in Prozessoptimierung
### 3. Spezifische Fachkenntnisse
- **Patrick**:
- Umfassende Markt- und Business-Erfahrung (30 Jahre)
- Expertise in Software-Architektur
- Full Stack Entwicklung
- Azure Cloud-Integration
- KI/ML Integration
- Enterprise-Systeme
- **Ida**:
- Projektmanagement
- Agile Methoden
- Business Analysis
- Prozessoptimierung
- Qualitätssicherung
### 4. Finanzielle Investitionen
- **Hardware**: CHF 10,000
- Entwicklungsserver
- Testumgebungen
- Entwicklungshardware
- **Software & Lizenzen**: CHF 10,000
- Entwicklungstools
- Cloud-Services
- KI-API-Zugänge
- **Gesamt**: CHF 20,000
### 5. Externe Dienstleister
- **Aktueller Status**: Keine externen Dienstleister
- **Vorteile**:
- Volle Kontrolle über Entwicklung
- Tiefes Verständnis der Architektur
- Schnelle Entscheidungswege
- Kosteneffizienz
### 6. Schlüsselkomponenten-Entwicklung
- **Patrick**:
- Frontend-Architektur
- Backend-System
- Workflow-Engine
- Agent-System
- Connector-Framework
- Datenmanagement
- Sicherheitsarchitektur
- **Verantwortlichkeiten**:
- Systemarchitektur
- Technische Leitung
- Code-Review
- Qualitätssicherung
### 7. Nicht-monetäre Ressourcen
- **Dominic**:
- Umfangreiches Sales & Marketing Netzwerk
- Marktzugang
- Branchenkontakte
- **ValueOn AG**:
- Infrastruktur
- Rechtlicher Rahmen
- Geschäftsprozesse
- **Netzwerke**:
- Technologie-Partner
- Potenzielle Kunden
- Branchenexperten
### 8. Finanzielle Risiken
- **ValueOn AG**:
- Bereitstellung von Infrastruktur
- Personelle Ressourcen
- Rechtlicher Rahmen
- **Private Investitionen**:
- Entwicklungszeit
- Hardware/Software
- Cloud-Services
### Fazit bisherige Aufwände
Die bisherigen Aufwände zeigen ein ausgewogenes Verhältnis zwischen technischer Expertise und Business-Know-how. Die private Investition von 730 Stunden durch Patrick demonstriert ein hohes Engagement und tiefes Verständnis der Technologie. Die Kombination aus technischer Expertise, Business-Erfahrung und Marktzugang bildet eine solide Grundlage für die weitere Entwicklung. Die bisherigen Investitionen sind effizient eingesetzt worden, mit Fokus auf kritische Kernkomponenten und skalierbare Architektur.
## Teil 3: Markt- und Geschäftspotenzial
### 1. Adressierbarer Gesamtmarkt und Wachstumspotenzial
- **Gesamtmarktvolumen 2025**:
- KI-Markt: $190 Mrd.
- Business Process Automation: $19,6 Mrd.
- Enterprise Knowledge Management: $43 Mrd.
- **Adressierbarer Markt (SAM)**:
- Initial: Mittlerer Markt in DACH (Professional Services, Finanzdienstleistungen, Gesundheitswesen)
- Geschätztes SAM: CHF 500-700 Mio.
- **Wachstumspotenzial**:
- Jährliches Marktwachstum: 25-30%
- Erweiterung auf internationale Märkte
- Branchenspezifische Lösungen
### 2. Alleinstellungsmerkmale
1. **Technologische Vorteile**:
- Proprietäre Multi-Agent-Technologie
- Modellunabhängige KI-Integration
- Enterprise-Ready Architektur
- Fortschrittliche Workflow-Orchestrierung
2. **Funktionale Vorteile**:
- Nahtlose Integration verschiedener KI-Modelle
- Robuste Fehlerbehandlung
- Skalierbare Multi-Tenant-Architektur
- Umfassende Enterprise-Features
### 3. Kunden und Pilotprojekte
- **Aktueller Status**:
- In Entwicklung
- Erste Referenzkunden in Planung
- Fokus auf mittelständische Unternehmen
- **Pilotphase**:
- Geplant für Q3/Q4 2025
- 3-5 Schlüsselreferenzkunden
- Branchenspezifische Templates
### 4. Geschäftsmodell
- **Hauptmodell**: SaaS (Software as a Service)
- **Preismodell**:
- Basis: Pro-Benutzer/Monat Abonnement
- Zusätzlich: Nutzungsbasierte Abrechnung
- Enterprise-Lizenzen für grössere Kunden
- **Erwartete Margen**: 75-85% nach Skalierung
### 5. Preisgestaltung
- **Wettbewerbsvergleich**:
- Unterhalb Enterprise-Lösungen
- Über Standard-BPA-Tools
- Flexiblere Preisgestaltung als Konkurrenz
- **Preisstruktur**:
- Basis-Abonnement: CHF 50-100 pro Benutzer/Monat
- Nutzungsbasierte Komponente: CHF 0.10-0.50 pro Verarbeitungseinheit
- Enterprise-Pakete: Individuelle Preisgestaltung
### 6. Umsatzpotenziale
- **Jahr 1 (2026)**:
- Ziel: 20-30 Kunden
- Erwartetes ARR: CHF 0.5-0.8 Mio.
- **Jahr 2 (2027)**:
- Ziel: 70-90 Kunden
- Erwartetes ARR: CHF 2-2.5 Mio.
- **Jahr 3 (2028)**:
- Ziel: 150+ Kunden
- Erwartetes ARR: CHF 4.5 Mio.
### 7. Akquisitionskosten
- **Customer Acquisition Cost (CAC)**:
- Erwarteter CAC: CHF 15,000-20,000
- Payback-Zeit: 12-18 Monate
- **Kostenstruktur**:
- 30% Vertrieb und Marketing
- Fokus auf effiziente Akquisition
- Skaleneffekte ab 50+ Kunden
### 8. Regulatorische Herausforderungen
- **Datenschutz**:
- DSGVO-Konformität
- Datensicherheit
- Mandantentrennung
- **KI-Regulierung**:
- EU AI Act
- Transparenzpflichten
- Qualitätssicherung
- **Branchenspezifische Regulierung**:
- Finanzdienstleistungen
- Gesundheitswesen
- Professional Services
### Fazit Markt- und Geschäftspotenzial
Die PowerOn AI Platform adressiert einen wachsenden Markt mit klaren Alleinstellungsmerkmalen. Das Geschäftsmodell ist skalierbar und die Preisgestaltung wettbewerbsfähig. Die regulatorischen Herausforderungen sind bekannt und adressierbar. Die Umsatzprognosen sind konservativ kalkuliert und basieren auf realistischen Marktannahmen.
## Teil 4: Skalierungs- und Zukunftspotenzial
### 1. Ressourcen für Support und Weiterentwicklung
- **Entwicklungsteam**:
- 2-3 Full-Stack Entwickler, KI-unterstützte Entwicklung
- 1 DevOps Engineer
- 1 QA Engineer
- **Support-Team**:
- 1-2 Support Engineers
- 1 Technical Account Manager
- **Infrastruktur**:
- Cloud-basierte Skalierung (Azure)
- Automatisierte Deployment-Pipeline
- Monitoring und Logging-Systeme
### 2. Skalierbarkeit
- **Technische Skalierbarkeit**:
- Horizontale Skalierung durch Multi-Tenant-Architektur
- Vertikale Skalierung durch Agent-Pooling
- Automatische Lastverteilung
- **Skalierungszeitrahmen**:
- 2x Nutzer: Sofort möglich
- 5x Nutzer: 1-2 Monate Vorbereitung
- 10x Nutzer: 3-4 Monate mit Infrastruktur-Erweiterung
### 3. Kapitalbedarf
- **Nächste Entwicklungsphase (12 Monate)**:
- Entwicklung: CHF 400,000-500,000
- Marketing & Sales: CHF 100,000-200,000
- Infrastruktur: CHF 50,000-100,000
- Betrieb & Support: CHF 100,000-150,000
- **Gesamt**: CHF 750,000-1,050,000
### 4. Schlüsselpersonen
- **Technische Leitung**:
- Patrick (Software Architect, Full Stack Developer)
- Verantwortlich für: Architektur, Entwicklung, Technische Strategie
- **Business & Operations**:
- Ida (Business Analyst, Project Manager)
- Verantwortlich für: Projektmanagement, Business Analysis
- **Sales & Marketing**:
- Dominic (Sales & Marketing)
- Verantwortlich für: Marktentwicklung, Kundenakquisition
### 5. Exit-Strategien
- **Strategische Übernahme**:
- Enterprise Software Anbieter
- KI/ML Plattform Betreiber
- Business Process Automation Unternehmen
- **IPO-Potenzial**:
- Ab CHF 50 Mio. ARR
- Zeitrahmen: 5-7 Jahre
- **Extraktion aus ValueOn AG**:
- Vergütung der Aufwände
- Anrechnung des Mehrwerts für Schlüsselpersonen
- Beschaffung des notwendigen Kapitals
### 6. Strategische Partnerschaften
- **Technologie-Partner**:
- KI-Provider (OpenAI, Anthropic)
- Cloud-Provider (Azure)
- Enterprise Software Anbieter
- **Vertriebspartner**:
- Systemhäuser
- Beratungsunternehmen
- Branchenspezialisten
- **Forschungspartner**:
- Universitäten
- Forschungsinstitute
- KI-Labore
### 7. Geplante Erweiterungen
- **Kurzfristig (12 Monate)**:
- Erweiterte Agent-Typen
- Branchenspezifische Templates
- API-Erweiterungen
- **Mittelfristig (24 Monate)**:
- Agentenmarktplatz
- Proprietäre KI-Modelle
- Erweiterte Analytics
- **Langfristig (36+ Monate)**:
- KI-Middleware für Unternehmen
- Branchenlösungen
- Internationale Expansion
### 8. Langfristige Vision
- **Technologische Vision**:
- Führende Multi-Agent KI-Plattform
- Standard für Enterprise Workflow Automation
- Innovationstreiber in der KI-Integration
- **Marktvision**:
- Globaler Marktführer in Nischenbereichen
- Branchenstandard für bestimmte Anwendungsfälle
- Referenz für KI-gestützte Prozessoptimierung
- **Geschäftsvision**:
- Nachhaltiges Wachstum
- Profitables Geschäftsmodell
- Führende Position in ausgewählten Märkten
### Fazit Skalierungs- und Zukunftspotenzial
Die PowerOn AI Platform verfügt über ein solides Skalierungspotenzial sowohl technisch als auch geschäftlich. Die modulare Architektur ermöglicht schnelles Wachstum, während die klare Vision und die strategischen Partnerschaften den langfristigen Erfolg unterstützen. Die Kapitalanforderungen sind realistisch kalkuliert und die Exit-Strategien bieten verschiedene Optionen für die Zukunft.
# Exitplan: PowerOn AI Platform als eigenständige AG
## Bewertung und Ausgangssituation
**Aktueller Wert (Juni 2025)**: CHF 500.000
**Angepasster Gründungswert**: CHF 800.000 (berücksichtigt den strategischen Wert der Produktvision, welche bereits als innerer Wert im Produkt enthalten ist)
## Strukturierung der PowerOn AG
### 1. Aktienstruktur bei Gründung
**Gesamtes Aktienkapital**: 1.000.000 Aktien (Nennwert CHF 0,10)
**Firmenvaluation bei Gründung**: CHF 800.000
#### Verteilung der initialen Aktien:
- **Patrick**:
- Eingebrachte Leistung: Entwicklung, technische Expertise und essenzielles Gesamtkonzept
- **Aktienanteil**: 35% (350.000 Aktien)
- **Dominic**:
- Eingebrachte Leistung: Netzwerk, Sales & Marketing Expertise und Vision
- **Aktienanteil**: 15% (150.000 Aktien)
- **ValueOn AG**:
- Eingebrachte Leistung: Infrastruktur, rechtlicher Rahmen, Arbeitszeit, Übertragung von IP
- **Aktienanteil**: 25% (250.000 Aktien)
- **Reservierter Anteil für Mitarbeiter-Pool**:
- **Aktienanteil**: 10% (100.000 Aktien)
- **Reserviert für Investoren (erste Runde)**:
- **Aktienanteil**: 15% (150.000 Aktien)
### 2. Kapitalbedarfsplanung (18 Monate)
| Kategorie | Betrag (CHF) |
|-----------|--------------|
| Entwicklung | 550.000 |
| Marketing & Sales | 250.000 |
| Infrastruktur | 100.000 |
| Betrieb & Support | 200.000 |
| **Gesamtbedarf** | **1.100.000** |
**Kapitalbeschaffungsstrategie**:
- **Erste Finanzierungsrunde**: CHF 1.000.000 (für 18 Monate)
- **Sicherheitspuffer**: CHF 100.000 (aus Umsätzen/zukünftigen Einnahmen)
### 3. Investitionskonditionen
**Pre-Money Bewertung**: CHF 800.000
**Investitionsvolumen**: CHF 1.000.000
**Post-Money Bewertung**: CHF 1.800.000
**Aktienkurs für Investoren**:
- 150.000 bestehende Aktien + 214.285 neue Aktien = 364.285 Aktien für Investoren
- **Aktienkurs**: CHF 2,75 pro Aktie
**Aktienstruktur nach Investment**:
- Patrick: 35% → 28,9% (350.000 Aktien)
- Dominic: 15% → 12,4% (150.000 Aktien)
- ValueOn AG: 25% → 20,7% (250.000 Aktien)
- Mitarbeiter-Pool: 10% → 8,3% (100.000 Aktien)
- Investoren: 29,7% (364.285 Aktien)
## Governance und Organisation
### 1. Schlüsselpositionen in der Organisation
- **CEO**: Gesamtführung des Unternehmens
- **CTO**: Verantwortlich für technische Strategie und Produktentwicklung
- **CSO/Vertriebsleitung**: Verantwortlich für Vertrieb und Marktentwicklung
- **COO**: Operative Leitung und Geschäftsprozesse
Die Besetzung dieser Positionen wird unter Berücksichtigung der Kompetenzen von Patrick, Dominic und möglichen neuen Führungskräften festgelegt. Die Rollen von CEO und COO werden im Rahmen der Unternehmensgründung evaluiert.
### 2. Vergütungsstruktur
- **Führungsebene**: Marktübliche Vergütung zwischen CHF 150.[PHONE_1]ahr je nach Position
- **Aktienoptionen**: Zusätzliche Aktienoptionen bei Erreichen definierter Unternehmensziele
## Meilensteine und Finanzielle Ziele
### Kritische Meilensteine (18 Monate)
| Zeitpunkt | Meilenstein | KPI |
|-----------|-------------|-----|
| Q3 2025 | Ausgründung & Finanzierung | Abschluss der Seed-Runde |
| Q4 2025 | Markteinführung | 3-5 Pilotprojekte |
| Q1 2026 | Produktvalidierung | 10+ zahlende Kunden |
| Q2 2026 | Skalierung | 15+ zahlende Kunden |
| Q4 2026 | Vorbereitung Serie A | 25+ Kunden, ARR: CHF 0,8 Mio. |
### Umsatz- und Bewertungsprognose
| Jahr | Kunden | ARR (CHF) | Valuation (CHF) | Multiplikator |
|------|--------|-----------|-----------------|---------------|
| Ende 2025 | 5-8 | 0,2 Mio. | 1,8 Mio. | 9x ARR |
| Ende 2026 | 25-30 | 0,8 Mio. | 5,6 Mio. | 7x ARR |
| Ende 2027 | 80-90 | 2,5 Mio. | 15 Mio. | 6x ARR |
| Ende 2028 | 150+ | 4,5 Mio. | 27 Mio. | 6x ARR |
## Liquiditätsoptionen
### Mittelfristige Optionen (2-3 Jahre)
1. **Serie A Finanzierung** (Ende 2026):
- Teilweise Liquidität für Gründer und ValueOn AG (10-15% ihrer Anteile)
- Zu erwartender Wert: CHF 5-6 Mio.
2. **Strategische Partnerschaft**:
- Investment durch strategischen Partner mit teilweisem Aktienrückkauf
- Potenzielle Partner: Enterprise Software-Anbieter, KI-Plattform-Betreiber
### Langfristige Optionen (4-7 Jahre)
1. **Komplette Übernahme**:
- Erwarteter Exit-Wert 2028: CHF 25-30 Mio.
- Vollständige Liquidität für alle Anteilseigner
2. **IPO-Vorbereitung**:
- Bei Erreichen von CHF 10+ Mio. ARR
- Potenzielle Bewertung: CHF 50-70 Mio.
## Nächste Schritte im Ausgründungsprozess
1. **Rechtliche Strukturierung**:
- Gründung der PowerOn AG
- Übertragungsvereinbarungen für geistiges Eigentum
- Aktionärsvereinbarungen
2. **Finanzierung**:
- Erstellung eines detaillierten Businessplans
- Vorbereitung des Investor Pitch Decks
- Ansprache potenzieller Investoren
3. **Organisationsaufbau**:
- Definition der Führungsstruktur und Schlüsselpositionen
- Rekrutierung des Kernteams
- Aufbau der operativen Prozesse
4. **Markteinführungsstrategie**:
- Festlegung der Go-to-Market Strategie
- Identifikation von Pilotprojekten
- Vorbereitung der Vertriebsunterlagen

View file

@ -0,0 +1,6 @@
id,name,email,phone,address,iban,credit_card,ahv_number
1,[NAME_3],[EMAIL_8],[PHONE_13],[ADDRESS_18],[IBAN_23],[IBAN_28],[SSN_33]
2,[NAME_4],[EMAIL_9],[PHONE_14],[ADDRESS_19],[IBAN_24],[IBAN_29],[SSN_34]
3,[NAME_5],[EMAIL_10],[PHONE_15],[ADDRESS_20],[IBAN_25],[IBAN_30],[SSN_33]
4,[NAME_6],[EMAIL_11],[PHONE_16],[ADDRESS_21],[IBAN_26],[IBAN_31],[SSN_33]
5,[NAME_7],[EMAIL_12],[PHONE_17],[ADDRESS_22],[IBAN_27],[IBAN_32],[SSN_35]
1 id name email phone address iban credit_card ahv_number
2 1 [NAME_3] [EMAIL_8] [PHONE_13] [ADDRESS_18] [IBAN_23] [IBAN_28] [SSN_33]
3 2 [NAME_4] [EMAIL_9] [PHONE_14] [ADDRESS_19] [IBAN_24] [IBAN_29] [SSN_34]
4 3 [NAME_5] [EMAIL_10] [PHONE_15] [ADDRESS_20] [IBAN_25] [IBAN_30] [SSN_33]
5 4 [NAME_6] [EMAIL_11] [PHONE_16] [ADDRESS_21] [IBAN_26] [IBAN_31] [SSN_33]
6 5 [NAME_7] [EMAIL_12] [PHONE_17] [ADDRESS_22] [IBAN_27] [IBAN_32] [SSN_35]

View file

@ -0,0 +1,69 @@
Lebenslauf: Lara Meier
Persönliche Daten:
Name: Lara Meier
Geboren: 15.03.[ADDRESS_55]: [ADDRESS_54], [ADDRESS_53]
Telefon: [PHONE_40] 67
E-Mail: [EMAIL_52]
AHV-Nr.: [SSN_34]
Steuernummer: [SSN_48]
Berufserfahrung:
2020-2023: Senior Projektmanagerin
Firma: TechSolutions AG
Adresse: [ADDRESS_51], [ADDRESS_50]
UID: [SSN_49]lefon: [PHONE_37] 43
E-Mail: [EMAIL_47]
In dieser Position leitete ich ein Team von 15 Mitarbeitern und verantwortete die Implementierung von Cloud-Lösungen für internationale Kunden. Meine Hauptaufgaben umfassten:
- Projektplanung und -steuerung mit einem Budget von CHF 2.5 Mio.
- Kundenbetreuung und Stakeholder-Management
- Teamführung und Personalentwicklung
- Qualitätssicherung und Risikomanagement
2015-2020: Projektmanagerin
Firma: Digital Systems GmbH
Adresse: [ADDRESS_46], [ADDRESS_45]
UID: [SSN_44]lefon: [PHONE_42] 90
E-Mail: [EMAIL_41]
Als Projektmanagerin verantwortete ich die erfolgreiche Durchführung von Digitalisierungsprojekten. Meine Leistungen:
- Implementierung von ERP-Systemen
- Optimierung von Geschäftsprozessen
- Schulung von Endbenutzern
- Erstellung von Projektdokumentation
Ausbildung:
2010-2015: ETH Zürich
Studiengang: Informatik
Matrikelnummer: 12-345-678
Abschluss: Master of Science in Computer Science
Thesis: "Künstliche Intelligenz in der Prozessautomatisierung"
2005-2010: Kantonsschule Zürich
Abschluss: Eidgenössische Maturität
Schwerpunkt: Mathematik und Naturwissenschaften
Sprachen:
Deutsch (Muttersprache)
Englisch (C2)
Französisch (B2)
Italienisch (B1)
Zertifizierungen:
PMP (Project Management Professional)
ITIL v4 Foundation
AWS Certified Solutions Architect
Scrum Master (PSM I)
Referenzen:
Prof. Dr. Hans Müller
ETH Zürich
Department of Computer Science
Telefon: [PHONE_40] 68
E-Mail: [EMAIL_39]
[NAME_38] AG
CTO
Telefon: [PHONE_37] 44
E-Mail: [EMAIL_36]

View file

@ -0,0 +1,20 @@
employee_id,first_name,last_name,email,phone,department,office_address,uid_number,bank_account
E001,[NAME_56],[NAME_61],[EMAIL_66],[PHONE_71],IT,[ADDRESS_76],,[IBAN_23]
E002,[NAME_57],[NAME_62],[EMAIL_67],[PHONE_72],HR,[ADDRESS_77],CHE-123.456.789,[IBAN_81]
E003,[NAME_58],[NAME_63],[EMAIL_68],[PHONE_73],Finance,[ADDRESS_78],,[IBAN_25]
E004,[NAME_59],[NAME_64],[EMAIL_69],[PHONE_74],Marketing,[ADDRESS_79],,[IBAN_26]
E005,[NAME_60],[NAME_65],[EMAIL_70],[PHONE_75],Sales,[ADDRESS_80],,[IBAN_82]
[REINTEGRATE]
The employee database has 9 attributes,
uid_number and bank_account is not defined for all records.
1 employee_id,first_name,last_name,email,phone,department,office_address,uid_number,bank_account
2 E001,[NAME_56],[NAME_61],[EMAIL_66],[PHONE_71],IT,[ADDRESS_76],,[IBAN_23]
3 E002,[NAME_57],[NAME_62],[EMAIL_67],[PHONE_72],HR,[ADDRESS_77],CHE-123.456.789,[IBAN_81]
4 E003,[NAME_58],[NAME_63],[EMAIL_68],[PHONE_73],Finance,[ADDRESS_78],,[IBAN_25]
5 E004,[NAME_59],[NAME_64],[EMAIL_69],[PHONE_74],Marketing,[ADDRESS_79],,[IBAN_26]
6 E005,[NAME_60],[NAME_65],[EMAIL_70],[PHONE_75],Sales,[ADDRESS_80],,[IBAN_82]
7 [REINTEGRATE]
8 The employee database has 9 attributes,
9 uid_number and bank_account is not defined for all records.

View file

@ -0,0 +1,9 @@
Dear Mr. Smith,
Thank you for your email to [EMAIL_85].
Your contact details have been recorded:
Phone: [PHONE_17]RESS_84]: 123 High Street, London SW1A 1AA
Your IBAN: GB29 NWBK 6016 1331 9268 19
Credit Card: 4532 1234 5678 [ADDRESS_83] regards,
John Doe

View file

@ -0,0 +1,54 @@
{
"customer": {
"personal_info": {
"name": "[NAME_3]",
"email": "[EMAIL_86]",
"phone": "[PHONE_87]",
"address": {
"street": "Hauptstra\u00dfe 123",
"city": "M\u00fcnchen",
"zip": "80331",
"country": "Deutschland"
}
},
"order_history": [
{
"order_id": "ORD-2024-001",
"date": "[DATE_88]",
"items": [
{
"product": "Laptop",
"price": 1299.99,
"payment": {
"method": "credit_card",
"card_number": "[IBAN_89]",
"iban": "[IBAN_23]"
}
}
]
}
],
"preferences": {
"language": "de",
"newsletter": true,
"marketing_consent": {
"email": "[EMAIL_86]",
"phone": "[PHONE_87]"
}
}
},
"company": {
"name": "[NAME_90]",
"contact": {
"manager": "NAME_91",
"email": "[EMAIL_92]",
"phone": "[PHONE_71]",
"address": {
"street": "Technologiestra\u00dfe 45",
"city": "Berlin",
"zip": "10115",
"country": "Deutschland"
}
}
}
}

View file

@ -0,0 +1,78 @@
<company_data>
<employees>
<employee id="EMP001">
<personal_info>
<name>[NAME_93]</name>
<email>[EMAIL_94]</email>
<phone>[PHONE_13]</phone>
<address>
<street>Musterstraße 42</street>
<city>Hamburg</city>
<zip>20095</zip>
<country>Deutschland</country>
</address>
</personal_info>
<employment>
<department>IT</department>
<position>Senior Developer</position>
<salary currency="EUR">75000</salary>
<bank_details>
<iban>[IBAN_23]</iban>
<bic>COBADEFFXXX</bic>
</bank_details>
</employment>
</employee>
<employee id="EMP002">
<personal_info>
<name>Maria Schmidt</name>
<email>[EMAIL_95]</email>
<phone>[PHONE_96]</phone>
<address>
<street>Bahnhofstraße 15</street>
<city>Frankfurt</city>
<zip>60329</zip>
<country>Deutschland</country>
</address>
</personal_info>
<employment>
<department>HR</department>
<position>HR Manager</position>
<salary currency="EUR">65000</salary>
<bank_details>
<iban>[PHONE_97]</iban>
<bic>COBADEFFXXX</bic>
</bank_details>
</employment>
</employee>
</employees>
<projects>
<project id="PRJ001">
<name>Digital Transformation</name>
<manager>[NAME_93]</manager>
<budget currency="EUR">150000</budget>
<team_members>
<member email="[EMAIL_94]">[NAME_93]</member>
<member email="[EMAIL_95]">Maria Schmidt</member>
</team_members>
</project>
</projects>
<company_info>
<name>Tech Innovations GmbH</name>
<address>
<street>Innovationsstraße 1</street>
<city>München</city>
<zip>80331</zip>
<country>Deutschland</country>
</address>
<contact>
<email>[EMAIL_98]</email>
<phone>[PHONE_71]</phone>
<fax>[PHONE_99]</fax>
</contact>
<banking>
<iban>[PHONE_100]</iban>
<bic>COBADEFFXXX</bic>
<tax_id>DE123456789</tax_id>
</banking>
</company_info>
</company_data>

View file

@ -0,0 +1,10 @@
Bonjour Madame Dupont,
Merci pour votre email à [EMAIL_104].
Vos coordonnées ont été enregistrées:
Téléphone: [PHONE_103] 67 89
Adresse: 123 Rue de Paris, 75001 Paris
Votre IBAN: FR76 3000 6000 [PHONE_102]9
Carte de crédit: 4532 1234 5678 [ADDRESS_101],
Jean Martin

View file

@ -0,0 +1,24 @@
Sehr geehrte Frau [NAME_12],
vielen Dank für Ihre E-Mail an [EMAIL_8].
Ihre Telefonnummer [PHONE_108]urde in unserem System hinterlegt.
Die Rechnung wird an folgende Adresse gesendet:
Musterstraße 123, 12345 Berlin
Ihre IBAN: DE89 3704 [PHONE_107]Kreditkarte: 4532 1234 5678 [ADDRESS_105] freundlichen Grüßen
Max Mustermann
[REINTEGRATE]
Brief von Frau Müller zur
Rechnungsnachfrage an den Helpdesk

View file

@ -0,0 +1,54 @@
Geschäftsstrategie 2024-[ADDRESS_112] AG
Unternehmensdaten:
Firmenname: TechSolutions AG
UID: [SSN_49]resse: [ADDRESS_51], [ADDRESS_50]
Telefon: [PHONE_37] 43
E-Mail: [EMAIL_111]
Website: www.techsolutions.ch
Geschäftsführung:
CEO: [NAME_93]
E-Mail: [EMAIL_110]
Telefon: [PHONE_37] 44
CTO: Dr. Sarah Müller
E-Mail: [EMAIL_109]
Telefon: [PHONE_37] 45
Finanzdaten:
Bank: UBS AG
IBAN: CH93 0076 7000 E529 0767 9
BIC: UBSWCHZH80A
Strategische Ziele:
1. Marktpositionierung
- Marktanteil in der Schweiz auf 25% steigern
- Expansion in DACH-Region
- Neue Zielgruppe: KMU
2. Produktentwicklung
- Cloud-Lösung für KMU
- KI-basierte Automatisierung
- Mobile App für Kunden
3. Personalentwicklung
- Team auf 50 Mitarbeiter ausbauen
- Neue Standorte: Bern und Genf
- Fokus auf Diversity & Inclusion
4. Nachhaltigkeit
- CO2-Neutralität bis 2025
- Green IT Zertifizierung
- Nachhaltige Lieferkette
Budgetplanung:
2024: CHF 5.2 Mio.
2025: CHF 6.8 Mio.
2026: CHF 8.5 Mio.
Risikoanalyse:
- Marktrisiken
- Technologische Risiken
- Personelle Risiken
- Finanzielle Risiken

View file

@ -0,0 +1,6 @@
geschäft_id,datum,kundenname,kundenemail,betrag,zahlungsmethode,zahlungsdetails,lieferadresse
2024-03-15,[DATE_113],[NAME_118],[EMAIL_123],50,IBAN,[IBAN_23],[ADDRESS_132]
2024-03-15,[DATE_114],[NAME_119],[EMAIL_124],75,IBAN,[IBAN_128],[ADDRESS_133]
2024-03-15,[DATE_115],[NAME_120],[EMAIL_125],25,IBAN,[IBAN_129],[ADDRESS_134]
2024-03-15,[DATE_116],[NAME_121],[EMAIL_126],0,IBAN,[IBAN_130],[ADDRESS_135]
2024-03-15,[DATE_117],[NAME_122],[EMAIL_127],50,IBAN,[IBAN_131],[ADDRESS_136]
1 geschäft_id datum kundenname kundenemail betrag zahlungsmethode zahlungsdetails lieferadresse
2 2024-03-15 [DATE_113] [NAME_118] [EMAIL_123] 50 IBAN [IBAN_23] [ADDRESS_132]
3 2024-03-15 [DATE_114] [NAME_119] [EMAIL_124] 75 IBAN [IBAN_128] [ADDRESS_133]
4 2024-03-15 [DATE_115] [NAME_120] [EMAIL_125] 25 IBAN [IBAN_129] [ADDRESS_134]
5 2024-03-15 [DATE_116] [NAME_121] [EMAIL_126] 0 IBAN [IBAN_130] [ADDRESS_135]
6 2024-03-15 [DATE_117] [NAME_122] [EMAIL_127] 50 IBAN [IBAN_131] [ADDRESS_136]

View file

@ -0,0 +1,9 @@
Buongiorno Signora Rossi,
Grazie per la sua email a [EMAIL_141].
Grazie per la sua email a [EMAIL_141] .
I suoi dati di contatto sono stati registrati:
Telefono: [PHONE_16]S_139]: Via Roma 123, 20100 Milano
Il suo IBAN: IT60 X054 2811 1010 [PHONE_138]arta di credito: 4532 1234 5678 [ADDRESS_137] saluti,
Marco Bianchi

View file

@ -0,0 +1,6 @@
kunden_id,vorname,nachname,email,telefon,adresse,iban,kreditkarte,steuernummer
K001,[NAME_142],[NAME_146],[EMAIL_149],[PHONE_13],[ADDRESS_18],[IBAN_23],[IBAN_28],[SSN_162]
K002,[NAME_143],[NAME_62],[EMAIL_150],[PHONE_154],[ADDRESS_158],[IBAN_128],[IBAN_29],[SSN_163]
K003,[NAME_57],[NAME_61],[EMAIL_151],[PHONE_155],[ADDRESS_159],[IBAN_129],[IBAN_30],[SSN_164]
K004,[NAME_144],[NAME_147],[EMAIL_152],[PHONE_156],[ADDRESS_160],[IBAN_130],[IBAN_31],[SSN_165]
K005,[NAME_145],[NAME_148],[EMAIL_153],[PHONE_157],[ADDRESS_161],[IBAN_131],[IBAN_32],[SSN_166]
1 kunden_id vorname nachname email telefon adresse iban kreditkarte steuernummer
2 K001 [NAME_142] [NAME_146] [EMAIL_149] [PHONE_13] [ADDRESS_18] [IBAN_23] [IBAN_28] [SSN_162]
3 K002 [NAME_143] [NAME_62] [EMAIL_150] [PHONE_154] [ADDRESS_158] [IBAN_128] [IBAN_29] [SSN_163]
4 K003 [NAME_57] [NAME_61] [EMAIL_151] [PHONE_155] [ADDRESS_159] [IBAN_129] [IBAN_30] [SSN_164]
5 K004 [NAME_144] [NAME_147] [EMAIL_152] [PHONE_156] [ADDRESS_160] [IBAN_130] [IBAN_31] [SSN_165]
6 K005 [NAME_145] [NAME_148] [EMAIL_153] [PHONE_157] [ADDRESS_161] [IBAN_131] [IBAN_32] [SSN_166]

View file

@ -0,0 +1,6 @@
mitarbeiter_id,vorname,nachname,email,telefon,abteilung,büroadresse,steuernummer,sozialversicherungsnummer
M001,[NAME_167],[NAME_172],[EMAIL_177],[PHONE_182],IT,[ADDRESS_187],[SSN_162],[SSN_192]
M002,[NAME_168],[NAME_173],[EMAIL_178],[PHONE_183],HR,[ADDRESS_188],[SSN_163],[SSN_193]
M003,[NAME_169],[NAME_174],[EMAIL_179],[PHONE_184],Finanzen,[ADDRESS_189],[SSN_164],[SSN_194]
M004,[NAME_170],[NAME_175],[EMAIL_180],[PHONE_185],Marketing,[ADDRESS_190],[SSN_165],[SSN_195]
M005,[NAME_171],[NAME_176],[EMAIL_181],[PHONE_186],Vertrieb,[ADDRESS_161],[SSN_191],[SSN_196]
1 mitarbeiter_id vorname nachname email telefon abteilung büroadresse steuernummer sozialversicherungsnummer
2 M001 [NAME_167] [NAME_172] [EMAIL_177] [PHONE_182] IT [ADDRESS_187] [SSN_162] [SSN_192]
3 M002 [NAME_168] [NAME_173] [EMAIL_178] [PHONE_183] HR [ADDRESS_188] [SSN_163] [SSN_193]
4 M003 [NAME_169] [NAME_174] [EMAIL_179] [PHONE_184] Finanzen [ADDRESS_189] [SSN_164] [SSN_194]
5 M004 [NAME_170] [NAME_175] [EMAIL_180] [PHONE_185] Marketing [ADDRESS_190] [SSN_165] [SSN_195]
6 M005 [NAME_171] [NAME_176] [EMAIL_181] [PHONE_186] Vertrieb [ADDRESS_161] [SSN_191] [SSN_196]

View file

@ -0,0 +1,10 @@
Guten Tag [NAME_200] für Ihre Anfrage an [EMAIL_199].
Ihre Kontaktdaten wurden wie folgt erfasst:
Telefon: [PHONE_40] 67
Adresse: [ADDRESS_198], [ADDRESS_53]
Ihre AHV-Nummer: [SSN_34]
UID-Nummer: [SSN_49]nkkonto: [PHONE_197]7]-8
Mit freundlichen Grüßen
Peter Muster

View file

@ -0,0 +1,6 @@
transaction_id,date,customer_name,customer_email,amount,payment_method,payment_details,shipping_address
T001,[DATE_88],[DATE_113],[NAME_118],1250.5,IBAN,[IBAN_23],[ADDRESS_132]
T002,[DATE_88],[DATE_114],[EMAIL_201],890.75,AHV,[SSN_34],[ADDRESS_205]
T003,[DATE_88],[DATE_115],[EMAIL_202],2340.25,IBAN,[IBAN_25],[ADDRESS_206]
T004,[DATE_88],[DATE_116],[EMAIL_203],1750.0,IBAN,[IBAN_26],[ADDRESS_207]
T005,[DATE_88],[DATE_117],[EMAIL_204],3200.5,IBAN,[IBAN_27],[ADDRESS_208]
1 transaction_id date customer_name customer_email amount payment_method payment_details shipping_address
2 T001 [DATE_88] [DATE_113] [NAME_118] 1250.5 IBAN [IBAN_23] [ADDRESS_132]
3 T002 [DATE_88] [DATE_114] [EMAIL_201] 890.75 AHV [SSN_34] [ADDRESS_205]
4 T003 [DATE_88] [DATE_115] [EMAIL_202] 2340.25 IBAN [IBAN_25] [ADDRESS_206]
5 T004 [DATE_88] [DATE_116] [EMAIL_203] 1750.0 IBAN [IBAN_26] [ADDRESS_207]
6 T005 [DATE_88] [DATE_117] [EMAIL_204] 3200.5 IBAN [IBAN_27] [ADDRESS_208]

View file

@ -0,0 +1,402 @@
"""
Pattern definitions for data anonymization
Separates header patterns from data patterns
"""
from dataclasses import dataclass
from typing import List, Optional, Tuple
import re
@dataclass
class Pattern:
"""Base class for patterns"""
name: str
patterns: List[str]
replacement_template: str
class HeaderPatterns:
"""Patterns for identifying sensitive data in headers"""
patterns = [
# Name patterns
Pattern(
name="name",
patterns=[
# Simple variations
r'\b(?:name|first[-_\s]*name|last[-_\s]*name|full[-_\s]*name)\b',
r'\b(?:customer[-_\s]*name|client[-_\s]*name|user[-_\s]*name)\b',
r'\b(?:given[-_\s]*name|family[-_\s]*name|surname)\b',
# German variations
r'\b(?:vorname|nachname|vollständiger[-_\s]*name|name)\b',
r'\b(?:kunden[-_\s]*name|kunde[-_\s]*name|benutzer[-_\s]*name)\b',
# French variations
r'\b(?:prénom|nom|nom[-_\s]*complet)\b',
r'\b(?:nom[-_\s]*du[-_\s]*client|nom[-_\s]*d\'utilisateur)\b',
# Italian variations
r'\b(?:nome|cognome|nome[-_\s]*completo)\b',
r'\b(?:nome[-_\s]*cliente|nome[-_\s]*utente)\b',
# Common variations
r'\b(?:nom|name|nome|naam)\b'
],
replacement_template="[NAME_{}]"
),
# Email patterns
Pattern(
name="email",
patterns=[
# Simple variations - only labels
r'\b(?:email|e[-_\s]*mail|mail)\s*:?\b',
r'\b(?:contact[-_\s]*email|user[-_\s]*email|client[-_\s]*email)\s*:?\b',
r'\b(?:customer[-_\s]*email|customer[-_\s]*mail|customer[-_\s]*e[-_\s]*mail)\s*:?\b',
# German variations - only labels
r'\b(?:e[-_\s]*mail|e[-_\s]*post|mail[-_\s]*adresse)\s*:?\b',
r'\b(?:kontakt[-_\s]*email|benutzer[-_\s]*email|kunden[-_\s]*email)\s*:?\b',
r'\b(?:kunden[-_\s]*mail|kunden[-_\s]*e[-_\s]*mail|kunden[-_\s]*e[-_\s]*post)\s*:?\b',
# French variations - only labels
r'\b(?:courriel|e[-_\s]*mail|adresse[-_\s]*e[-_\s]*mail)\s*:?\b',
r'\b(?:courriel[-_\s]*de[-_\s]*contact|e[-_\s]*mail[-_\s]*client)\s*:?\b',
r'\b(?:courriel[-_\s]*client|courriel[-_\s]*utilisateur|mail[-_\s]*client)\s*:?\b',
# Italian variations - only labels
r'\b(?:posta[-_\s]*elettronica|e[-_\s]*mail|indirizzo[-_\s]*e[-_\s]*mail)\s*:?\b',
r'\b(?:email[-_\s]*cliente|email[-_\s]*utente)\s*:?\b',
r'\b(?:mail[-_\s]*cliente|mail[-_\s]*utente|posta[-_\s]*cliente)\s*:?\b'
],
replacement_template="[EMAIL_{}]"
),
# Phone patterns
Pattern(
name="phone",
patterns=[
# Simple variations
r'\b(?:phone|tel|telephone|mobile)\b',
r'\b(?:contact[-_\s]*number|phone[-_\s]*number|tel[-_\s]*number)\b',
# German variations
r'\b(?:telefon|mobil|handy|telefon[-_\s]*nummer)\b',
r'\b(?:kontakt[-_\s]*nummer|telefon[-_\s]*nummer|tel[-_\s]*nummer)\b',
# French variations
r'\b(?:téléphone|portable|mobile|numéro[-_\s]*de[-_\s]*téléphone)\b',
r'\b(?:numéro[-_\s]*de[-_\s]*contact|tél[-_\s]*fixe|tél[-_\s]*mobile)\b',
# Italian variations
r'\b(?:telefono|cellulare|mobile|numero[-_\s]*di[-_\s]*telefono)\b',
r'\b(?:numero[-_\s]*di[-_\s]*contatto|tel[-_\s]*fisso|tel[-_\s]*mobile)\b'
],
replacement_template="[PHONE_{}]"
),
# IBAN patterns
Pattern(
name="iban",
patterns=[
# Simple variations
r'\b(?:iban|bank[-_\s]*account|account[-_\s]*number)\b',
r'\b(?:bank[-_\s]*details|account[-_\s]*details|banking[-_\s]*info)\b',
# German variations
r'\b(?:iban|bank[-_\s]*konto|konto[-_\s]*nummer)\b',
r'\b(?:bank[-_\s]*verbindung|konto[-_\s]*verbindung|bank[-_\s]*daten)\b',
# French variations
r'\b(?:iban|compte[-_\s]*bancaire|numéro[-_\s]*de[-_\s]*compte)\b',
r'\b(?:coordonnées[-_\s]*bancaires|détails[-_\s]*bancaires)\b',
# Credit card variations in French
r'\b(?:carte[-_\s]*de[-_\s]*credit|carte[-_\s]*credit|numero[-_\s]*carte[-_\s]*credit)\b',
r'\b(?:carte[-_\s]*bancaire|carte[-_\s]*de[-_\s]*paiement)\b',
r'\b(?:carte[-_\s]*de[-_\s]*crédit|carte[-_\s]*crédit|numéro[-_\s]*carte[-_\s]*crédit)\b',
r'\b(?:carte[-_\s]*de[-_\s]*débit|carte[-_\s]*débit|numéro[-_\s]*carte[-_\s]*débit)\b',
# Italian variations
r'\b(?:iban|conto[-_\s]*bancario|numero[-_\s]*di[-_\s]*conto)\b',
r'\b(?:coordinate[-_\s]*bancarie|dettagli[-_\s]*bancari)\b',
# Common variations
r'\b(?:bankkonto|bank[-_\s]*konto|conto[-_\s]*di[-_\s]*banca)\b',
# Credit card variations
r'\b(?:credit[-_\s]*card|credit[-_\s]*card[-_\s]*number|credit[-_\s]*card[-_\s]*no)\b',
r'\b(?:credit[-_\s]*card[-_\s]*nr|credit[-_\s]*card[-_\s]*num)\b',
r'\b(?:credit[-_\s]*card[-_\s]*id|credit[-_\s]*card[-_\s]*code)\b',
r'\b(?:credit[-_\s]*card[-_\s]*reference|credit[-_\s]*card[-_\s]*ref)\b',
r'\b(?:credit[-_\s]*card[-_\s]*details|credit[-_\s]*card[-_\s]*info)\b',
r'\b(?:credit[-_\s]*card[-_\s]*data|credit[-_\s]*card[-_\s]*account)\b',
# Credit card variations in other languages
r'\b(?:kredit[-_\s]*karte|kreditkarte|kredit[-_\s]*karten[-_\s]*nummer)\b',
r'\b(?:carta[-_\s]*di[-_\s]*credito|carta[-_\s]*credito|numero[-_\s]*carta[-_\s]*credito)\b',
# Payment variations
r'\b(?:payment[-_\s]*details|payment[-_\s]*info|payment[-_\s]*data)\b',
r'\b(?:zahlungs[-_\s]*details|zahlungs[-_\s]*informationen|zahlungs[-_\s]*daten)\b',
r'\b(?:détails[-_\s]*de[-_\s]*paiement|informations[-_\s]*de[-_\s]*paiement)\b',
r'\b(?:dettagli[-_\s]*di[-_\s]*pagamento|informazioni[-_\s]*di[-_\s]*pagamento)\b',
# Common credit card abbreviations
r'\b(?:cc[-_\s]*number|cc[-_\s]*no|cc[-_\s]*nr)\b',
r'\b(?:cc[-_\s]*num|cc[-_\s]*id|cc[-_\s]*code)\b',
r'\b(?:cc[-_\s]*ref|cc[-_\s]*details|cc[-_\s]*info)\b',
r'\b(?:cc[-_\s]*data|cc[-_\s]*account)\b',
# Simple credit card
r'\b(?:credit[-_\s]*card|credit[-_\s]*card[-_\s]*number)\b',
# Additional credit card variations
r'\b(?:card[-_\s]*number|card[-_\s]*no|card[-_\s]*nr)\b',
r'\b(?:card[-_\s]*num|card[-_\s]*id|card[-_\s]*code)\b',
r'\b(?:card[-_\s]*ref|card[-_\s]*details|card[-_\s]*info)\b',
r'\b(?:card[-_\s]*data|card[-_\s]*account)\b'
],
replacement_template="[IBAN_{}]"
),
# Address patterns
Pattern(
name="address",
patterns=[
# English variations
r'\b(?:address|street[-_\s]*address|mailing[-_\s]*address)\b',
r'\b(?:home[-_\s]*address|work[-_\s]*address|billing[-_\s]*address)\b',
r'\b(?:.*address.*)\b', # Match any text containing "address"
# German variations
r'\b(?:adresse|strassen[-_\s]*adresse|post[-_\s]*adresse)\b',
r'\b(?:wohn[-_\s]*adresse|geschäfts[-_\s]*adresse|rechnungs[-_\s]*adresse)\b',
r'\b(?:.*adresse.*)\b', # Match any text containing "adresse"
# French variations
r'\b(?:adresse|adresse[-_\s]*postale|adresse[-_\s]*de[-_\s]*livraison)\b',
r'\b(?:adresse[-_\s]*personnelle|adresse[-_\s]*professionnelle)\b',
r'\b(?:.*adresse.*)\b', # Match any text containing "adresse"
# Italian variations
r'\b(?:indirizzo|indirizzo[-_\s]*postale|indirizzo[-_\s]*di[-_\s]*consegna)\b',
r'\b(?:indirizzo[-_\s]*personale|indirizzo[-_\s]*professionale)\b',
r'\b(?:.*indirizzo.*)\b', # Match any text containing "indirizzo"
# Common variations
r'\b(?:location|place|residence|domicile)\b',
r'\b(?:standort|ort|wohnort|domizil)\b',
r'\b(?:lieu|emplacement|résidence|domicile)\b',
r'\b(?:luogo|posizione|residenza|domicilio)\b'
],
replacement_template="[ADDRESS_{}]"
),
# Date patterns
Pattern(
name="date",
patterns=[
# English variations
r'\b(?:date|birth[-_\s]*date|date[-_\s]*of[-_\s]*birth)\b',
r'\b(?:dob|birthday|anniversary)\b',
# German variations
r'\b(?:datum|geburt[-_\s]*datum|geboren[-_\s]*am)\b',
r'\b(?:geburtstag|jubiläum|feier[-_\s]*tag)\b',
r'\b(?:geboren|geb\.|geboren[-_\s]*am)\b',
# French variations
r'\b(?:date|date[-_\s]*de[-_\s]*naissance|né[-_\s]*le)\b',
r'\b(?:anniversaire|date[-_\s]*anniversaire)\b',
r'\b(?:né|née|né[-_\s]*le)\b',
# Italian variations
r'\b(?:data|data[-_\s]*di[-_\s]*nascita|nato[-_\s]*il)\b',
r'\b(?:compleanno|anniversario)\b',
r'\b(?:nato|nata|nato[-_\s]*il)\b',
# Common variations
r'\b(?:birth|born|geboren|né|nato)\b'
],
replacement_template="[DATE_{}]"
),
# SSN patterns
Pattern(
name="ssn",
patterns=[
# English variations
r'\b(?:ssn|social[-_\s]*security[-_\s]*number|tax[-_\s]*id)\b',
r'\b(?:tax[-_\s]*identification|national[-_\s]*id)\b',
# German variations
r'\b(?:ahv[-_\s]*nummer|sozial[-_\s]*versicherungs[-_\s]*nummer)\b',
r'\b(?:steuer[-_\s]*nummer|steuer[-_\s]*id|svn)\b',
r'\b(?:ahv[-_\s]*nr|ahv[-_\s]*no|ahv[-_\s]*num)\b',
# French variations
r'\b(?:numéro[-_\s]*avs|numéro[-_\s]*de[-_\s]*sécurité[-_\s]*sociale)\b',
r'\b(?:numéro[-_\s]*fiscal|numéro[-_\s]*d\'identification)\b',
# Italian variations
r'\b(?:numero[-_\s]*avs|numero[-_\s]*di[-_\s]*sicurezza[-_\s]*sociale)\b',
r'\b(?:numero[-_\s]*fiscale|codice[-_\s]*fiscale)\b',
# Common variations
r'\b(?:ahv|svn|nss|avs)\b',
# Additional AHV variations
r'\b(?:ahv_nummer|ahvnummer|ahv-nummer|ahv_number)\b',
r'\b(?:ahv[-_\s]*nr|ahv[-_\s]*no|ahv[-_\s]*num)\b',
r'\b(?:ahv[-_\s]*number|ahv[-_\s]*number)\b',
r'\b(?:ahv[-_\s]*id|ahv[-_\s]*id)\b',
r'\b(?:ahv[-_\s]*code|ahv[-_\s]*code)\b',
r'\b(?:ahv[-_\s]*reference|ahv[-_\s]*reference)\b',
r'\b(?:ahv[-_\s]*reference[-_\s]*number|ahv[-_\s]*reference[-_\s]*number)\b',
r'\b(?:ahv[-_\s]*reference[-_\s]*no|ahv[-_\s]*reference[-_\s]*no)\b',
r'\b(?:ahv[-_\s]*reference[-_\s]*nr|ahv[-_\s]*reference[-_\s]*nr)\b',
r'\b(?:ahv[-_\s]*reference[-_\s]*num|ahv[-_\s]*reference[-_\s]*num)\b',
r'\b(?:ahv[-_\s]*reference[-_\s]*id|ahv[-_\s]*reference[-_\s]*id)\b',
r'\b(?:ahv[-_\s]*reference[-_\s]*code|ahv[-_\s]*reference[-_\s]*code)\b'
],
replacement_template="[SSN_{}]"
)
]
class DataPatterns:
"""Patterns for identifying sensitive data in content"""
patterns = [
# Name patterns
Pattern(
name="name",
patterns=[
# Person names with titles and academic degrees
r'\b(?:Dr\.|Prof\.|PhD\.?|MD\.?|Herr|Frau|Mr\.|Mrs\.|Ms\.|Monsieur|Madame|Signore|Signora)\s+[A-Z][a-z]{2,}(?:\s+[A-Za-z]{2,}){1,2}\b'
],
replacement_template="[NAME_{}]"
),
# Email pattern for plain text
Pattern(
name="email",
patterns=[
# Basic email pattern
r'[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)*'
],
replacement_template="[EMAIL_{}]"
),
# Phone patterns
Pattern(
name="phone",
patterns=[
# International format
r'\+\d{1,3}[-.\s]?\d{1,4}[-.\s]?\d{1,4}[-.\s]?\d{1,9}\b',
# Swiss format
r'\b(?:0\d{1,2}|0041\d{1,2})[-.\s]?\d{3}[-.\s]?\d{2}[-.\s]?\d{2}\b',
# German format
r'\b(?:0\d{1,4}|0049\d{1,4})[-.\s]?\d{3,}[-.\s]?\d{3,}\b',
# French format
r'\b(?:0\d{1,2}|0033\d{1,2})[-.\s]?\d{1,2}[-.\s]?\d{2}[-.\s]?\d{2}[-.\s]?\d{2}\b',
# Italian format
r'\b(?:0\d{1,3}|0039\d{1,3})[-.\s]?\d{3,}[-.\s]?\d{3,}\b',
# Mobile numbers
r'\b(?:07|00417|004917|00337|00397)\d{8,9}\b',
# Emergency numbers
r'\b(?:112|911|118|117|144|1414)\b'
],
replacement_template="[PHONE_{}]"
),
# IBAN patterns
Pattern(
name="iban",
patterns=[
r'\b(?:CH|DE|FR|IT)\d{2}\s?(?:\d{4}\s?){5}\d{2}\b',
r'\b(?:CH|DE|FR|IT)\d{2}(?:\d{4}){5}\d{2}\b'
],
replacement_template="[IBAN_{}]"
),
# Address patterns
Pattern(
name="address",
patterns=[
r'\b(?:[A-Za-zäöüßÄÖÜ]+(?:strasse|str\.|gasse|weg|platz|allee|boulevard|avenue|via|strada|rue|chemin|route))\s+\d{1,4}(?:[a-z])?\b',
r'\b\d{4}\s+[A-Za-zäöüßÄÖÜ]+\b'
],
replacement_template="[ADDRESS_{}]"
),
# Date patterns
Pattern(
name="date",
patterns=[
# Specific date formats with context
r'\b(?:geboren|birth|né|nato)\s+am\s+[0-9]{2}[./-][0-9]{2}[./-][0-9]{4}\b', # Birth dates
r'\b(?:geboren|birth|né|nato)\s+am\s+[0-9]{4}[./-][0-9]{2}[./-][0-9]{2}\b', # Birth dates
r'\b(?:vertrag|contract|contrat|contratto)\s+vom\s+[0-9]{2}[./-][0-9]{2}[./-][0-9]{4}\b', # Contract dates
r'\b(?:vertrag|contract|contrat|contratto)\s+vom\s+[0-9]{4}[./-][0-9]{2}[./-][0-9]{2}\b', # Contract dates
# Specific date formats with month names
r'\b(?:geboren|birth|né|nato)\s+am\s+(?:jan|feb|mar|apr|mai|jun|jul|aug|sep|okt|nov|dez|januar|februar|märz|april|mai|juni|juli|august|september|oktober|november|dezember)[a-z]*\s+\d{4}\b', # Birth dates with month
r'\b(?:vertrag|contract|contrat|contratto)\s+vom\s+(?:jan|feb|mar|apr|mai|jun|jul|aug|sep|okt|nov|dez|januar|februar|märz|april|mai|juni|juli|august|september|oktober|november|dezember)[a-z]*\s+\d{4}\b' # Contract dates with month
],
replacement_template="[DATE_{}]"
),
# SSN patterns
Pattern(
name="ssn",
patterns=[
r'\b(?:756|757|758|759)\.\d{4}\.\d{4}\.\d{2}\b', # Swiss AHV
r'\b(?:CHE|DE|FR|IT)-\d{3}\.\d{3}\.\d{3}\b', # Company IDs
r'\b\d{3}\.\d{3}\.\d{3}\b' # Generic SSN format
],
replacement_template="[SSN_{}]"
)
]
class TextTablePatterns:
"""Patterns for identifying table-like structures in text"""
@staticmethod
def get_patterns() -> List[Tuple[str, str]]:
return [
# key: value pattern (with optional whitespace)
(r'^([^:]+):\s*(.+)$', ':'),
# key = value pattern (with optional whitespace)
(r'^([^=]+)=\s*(.+)$', '='),
# key = value pattern (with required whitespace)
(r'^([^=]+)\s+=\s+(.+)$', '='),
# key: value pattern (with required whitespace)
(r'^([^:]+)\s+:\s+(.+)$', ':'),
]
@staticmethod
def is_table_line(line: str) -> bool:
"""Check if a line matches any table pattern"""
patterns = TextTablePatterns.get_patterns()
return any(re.match(pattern[0], line.strip()) for pattern in patterns)
@staticmethod
def extract_key_value(line: str) -> Optional[Tuple[str, str]]:
"""Extract key and value from a table line"""
patterns = TextTablePatterns.get_patterns()
for pattern, separator in patterns:
match = re.match(pattern, line.strip())
if match:
key = match.group(1).strip()
value = match.group(2).strip()
return key, value
return None
def get_pattern_for_header(header: str, patterns: List[Pattern]) -> Optional[Pattern]:
"""
Find matching pattern for a header
Args:
header: The header to check
patterns: List of patterns to check against
Returns:
Optional[Pattern]: Matching pattern or None
"""
if not header:
return None
header = header.lower().strip()
for pattern in patterns:
for p in pattern.patterns:
if re.search(p, header, re.IGNORECASE):
return pattern
return None
def find_patterns_in_text(text: str, patterns: List[Pattern]) -> List[tuple]:
"""
Find all pattern matches in text
Args:
text: Text to search
patterns: List of patterns to check
Returns:
List[tuple]: List of (pattern_name, match, start, end)
"""
matches = []
for pattern in patterns:
for p in pattern.patterns:
if pattern.name == 'email':
print(f"\nDEBUG: Checking email pattern '{p}'")
for match in re.finditer(p, text, re.IGNORECASE):
if pattern.name == 'email':
print(f"DEBUG: Found email match: '{match.group(0)}' at position {match.start()}-{match.end()}")
print(f"DEBUG: Context: '{text[max(0, match.start()-20):match.end()+20]}'")
matches.append((pattern.name, match.group(0), match.start(), match.end()))
return sorted(matches, key=lambda x: x[2]) # Sort by start position

608
test_neutralizer/testdata/Case.md vendored Normal file
View file

@ -0,0 +1,608 @@
# Bewertung der PowerOn AI Platform
Basierend auf dem nachstehenden Q&A ergibt sich nachfolgende Bewertung des Softwareprodukts "PowerOn AI Platform".
## Aktueller Wert per Juni 2025
1. **Technischer Wert des Codes**:
- Professionelle, modulare Codebasis (~50.000-60.000 LOC)
- Moderne Architektur mit innovativen Komponenten
- 5 Personenmonate Entwicklung x CHF 15.000/PM = CHF 75.000
- Zusätzlicher Wert durch Enterprise-Ready Architektur: CHF 50.000
2. **Bisherige Investitionen**:
- Hardware/Software: CHF 20.000
- Expertise-Premium (30+ Jahre Erfahrung): CHF 25.000
3. **IP und Innovationswert**:
- Multi-Agent Workflow-System
- Modulare Architecture mit Alleinstellungsmerkmalen
- Geschätzter Wert: CHF 100.000
4. **Marktpotenzial-Faktor**:
- Adressierbares Marktvolumen von CHF 500-700 Mio.
- Wachstumsmarkt (25-30% jährlich)
- Frühphasen-Multiplikator: 2x
**Aktueller Gesamtwert (Juni 2025)**: **CHF 500.000**
## Prognostizierte Wertentwicklung
### Ende 2025
- Abschluss der technischen Entwicklung
- Erste Pilotprojekte mit 3-5 Referenzkunden
- Validierung des Produkts am Markt
- **Geschätzter Wert Ende 2025**: **CHF 1,2 Millionen**
(Steigerung durch Marktvalidierung und Risikoreduktion)
### Ende 2026
- 20-30 Kunden
- ARR: CHF 0,5-0,8 Mio.
- Etablierung im DACH-Markt
- **Geschätzter Wert Ende 2026**: **CHF 4-5 Millionen**
(Bewertungsmultiplikator von 6-8x ARR für wachstumsstarke SaaS)
### Ende 2027
- 70-90 Kunden
- ARR: CHF 2-2,5 Mio.
- Erweiterung der Produktpalette
- **Geschätzter Wert Ende 2027**: **CHF 12-15 Millionen**
(Bewertungsmultiplikator von 6x ARR)
### Ende 2028
- 150+ Kunden
- ARR: CHF 4,5 Mio.
- Internationale Expansion
- **Geschätzter Wert Ende 2028**: **CHF 25-30 Millionen**
(Bewertungsmultiplikator von 5,5-6,5x ARR für etablierte SaaS)
## Schlüsselfaktoren und Risikobeurteilung für die Wertentwicklung
1. **Erfolgreiche Markteinführung**: Der Übergang von Entwicklung zu erfolgreicher Pilotphase ist kritisch für die Wertentwicklung 2025-2026.
2. **Skalierung des Vertriebs**: Die Fähigkeit, die Kundenakquisition gemäss der Prognose zu skalieren, ist entscheidend für die 2026-2027 Bewertung.
3. **Kapitaleffizienz**: Die effiziente Nutzung des Kapitals (CHF 750.000-1.050.000) für die nächste Entwicklungsphase wird die Bewertung massgeblich beeinflussen.
4. **Marktdynamik**: Die Entwicklung des KI-Marktes und regulatorische Änderungen können sowohl positive als auch negative Auswirkungen haben.
Diese Bewertung basiert auf der Annahme, dass die Meilensteine wie geplant erreicht werden und keine signifikanten externen Faktoren die Marktentwicklung negativ beeinflussen.
# Kriterienkatalog zur Softwarebewertung
## Teil 1: Technische Bewertung (Code-basiert)
1. Wie umfangreich ist die Codebasis (LOC, Module, Komponenten)?
2. Welche Programmiersprachen und Frameworks wurden verwendet?
3. Wie hoch ist die Codequalität und -konsistenz (saubere Architektur, Dokumentation, Tests)?
4. Gibt es innovative Algorithmen oder patentierbare technische Lösungen?
5. Wie modular und wartbar ist die Software gestaltet?
6. Wie robust ist die Fehlerbehandlung und Sicherheitsarchitektur?
7. Wie skalierbar ist die technische Infrastruktur?
8. Gibt es technische Schulden, die zukünftige Entwicklungen behindern könnten?
### 1. Umfang der Codebasis
- **Frontend**: Modulare JavaScript-Struktur mit ca. 15 Hauptmodulen
- **Backend**: Python/FastAPI mit ca. 15 Hauptmodulen
- **Hauptkomponenten**:
- Frontend: Workflow, UI, Koordination, Datenmanagement
- Backend: Gateway, Agent Service, Connectors, Workflow Manager
- **Geschätzte LOC**: ~50,000-60,000 Zeilen Code
### 2. Programmiersprachen und Frameworks
- **Frontend**:
- JavaScript (ES6+)
- Modulares System mit ES6-Import/Export
- Vanilla JS ohne externe Frameworks
- **Backend**:
- Python 3.x
- FastAPI für REST-API
- Asyncio für asynchrone Verarbeitung
### 3. Codequalität und -konsistenz
- **Saubere Architektur**:
- Klare Trennung Frontend/Backend
- Modulare Struktur mit definierten Verantwortlichkeiten
- State Machine Pattern für Workflow-Management
- **Dokumentation**:
- Ausführliche JSDoc/Python-Docstrings
- Architekturdiagramme (Mermaid)
- Technische Spezifikationen
- **Tests**:
- Automatisierte Modultests
- Manuell Integrationstests
- Benutzertests über Tickets in Clickup
### 4. Innovative Algorithmen/patentierbare Lösungen
- Multi-Agent Workflow-System mit spezialisierten Agenten
- Modulares Agent-Registry-System
- State Machine für Workflow-Koordination
- Dynamische Agenten-Integration
### 5. Modularität und Wartbarkeit
- **Hohe Modularität**:
- Klare Trennung der Verantwortlichkeiten
- Plug-and-Play Agent-System
- Erweiterbare Connector-Architektur
- **Wartbarkeit**:
- Konsistente Codestruktur
- Klare Namenskonventionen
- Dokumentierte Schnittstellen
### 6. Fehlerbehandlung und Sicherheit
- **Robuste Fehlerbehandlung**:
- State Machine für Workflow-Status
- Exception Handling auf allen Ebenen
- Logging-System für Debugging
- **Sicherheitsarchitektur**:
- Multi-Tenant-Architektur
- Authentifizierung/Autorisierung
- Mandantenverwaltung
### 7. Skalierbarkeit
- **Horizontale Skalierbarkeit**:
- Modulare Architektur
- Asynchrone Verarbeitung
- Connector-System für externe Dienste
- **Vertikale Skalierbarkeit**:
- Workflow-Parallelisierung
- Agent-Pooling
- Caching-Mechanismen
### 8. Technische Schulden
- **Potenzielle Verbesserungsbereiche**:
- Test-Coverage nicht sichtbar
- Eventuell fehlende Performance-Optimierungen
- Dokumentation für Zielgruppen noch unvollständig
- **Keine kritischen Blockierer identifiziert**
### Fazit der technischen Bewertung
Die Codebasis zeigt eine professionelle, gut strukturierte Enterprise-Anwendung mit klarer Architektur und modernen Best Practices. Die modulare Struktur und die saubere Implementierung der State Machine für Workflow-Management sind besonders hervorzuheben. Die Anwendung ist technisch reif und zeigt ein hohes Mass an Professionalität in der Implementierung.
## Teil 2: Bewertung der bisherigen Aufwände
### 1. Entwicklungsaufwände
- **Patrick**:
- ValueOn AG: 80 Stunden
- Private Entwicklung: 650 Stunden
- **Gesamt**: 730 Stunden (ca. 4.5 Personenmonate)
- **Ida**:
- ValueOn AG: 60 Stunden
- **Gesamt**: 60 Stunden (ca. 0.4 Personenmonate)
- **Gesamtaufwand**: ~5 Personenmonate
### 2. Qualifikationen und Erfahrungslevel
- **Patrick**:
- Business Consultant
- Software Architect
- Full Stack Developer
- 30+ Jahre Berufserfahrung
- Experte für Enterprise-Architekturen
- **Ida**:
- Business Analyst
- Project Manager
- Scrum Master
- Erfahrung in agiler Entwicklung
- Expertise in Prozessoptimierung
### 3. Spezifische Fachkenntnisse
- **Patrick**:
- Umfassende Markt- und Business-Erfahrung (30 Jahre)
- Expertise in Software-Architektur
- Full Stack Entwicklung
- Azure Cloud-Integration
- KI/ML Integration
- Enterprise-Systeme
- **Ida**:
- Projektmanagement
- Agile Methoden
- Business Analysis
- Prozessoptimierung
- Qualitätssicherung
### 4. Finanzielle Investitionen
- **Hardware**: CHF 10,000
- Entwicklungsserver
- Testumgebungen
- Entwicklungshardware
- **Software & Lizenzen**: CHF 10,000
- Entwicklungstools
- Cloud-Services
- KI-API-Zugänge
- **Gesamt**: CHF 20,000
### 5. Externe Dienstleister
- **Aktueller Status**: Keine externen Dienstleister
- **Vorteile**:
- Volle Kontrolle über Entwicklung
- Tiefes Verständnis der Architektur
- Schnelle Entscheidungswege
- Kosteneffizienz
### 6. Schlüsselkomponenten-Entwicklung
- **Patrick**:
- Frontend-Architektur
- Backend-System
- Workflow-Engine
- Agent-System
- Connector-Framework
- Datenmanagement
- Sicherheitsarchitektur
- **Verantwortlichkeiten**:
- Systemarchitektur
- Technische Leitung
- Code-Review
- Qualitätssicherung
### 7. Nicht-monetäre Ressourcen
- **Dominic**:
- Umfangreiches Sales & Marketing Netzwerk
- Marktzugang
- Branchenkontakte
- **ValueOn AG**:
- Infrastruktur
- Rechtlicher Rahmen
- Geschäftsprozesse
- **Netzwerke**:
- Technologie-Partner
- Potenzielle Kunden
- Branchenexperten
### 8. Finanzielle Risiken
- **ValueOn AG**:
- Bereitstellung von Infrastruktur
- Personelle Ressourcen
- Rechtlicher Rahmen
- **Private Investitionen**:
- Entwicklungszeit
- Hardware/Software
- Cloud-Services
### Fazit bisherige Aufwände
Die bisherigen Aufwände zeigen ein ausgewogenes Verhältnis zwischen technischer Expertise und Business-Know-how. Die private Investition von 730 Stunden durch Patrick demonstriert ein hohes Engagement und tiefes Verständnis der Technologie. Die Kombination aus technischer Expertise, Business-Erfahrung und Marktzugang bildet eine solide Grundlage für die weitere Entwicklung. Die bisherigen Investitionen sind effizient eingesetzt worden, mit Fokus auf kritische Kernkomponenten und skalierbare Architektur.
## Teil 3: Markt- und Geschäftspotenzial
### 1. Adressierbarer Gesamtmarkt und Wachstumspotenzial
- **Gesamtmarktvolumen 2025**:
- KI-Markt: $190 Mrd.
- Business Process Automation: $19,6 Mrd.
- Enterprise Knowledge Management: $43 Mrd.
- **Adressierbarer Markt (SAM)**:
- Initial: Mittlerer Markt in DACH (Professional Services, Finanzdienstleistungen, Gesundheitswesen)
- Geschätztes SAM: CHF 500-700 Mio.
- **Wachstumspotenzial**:
- Jährliches Marktwachstum: 25-30%
- Erweiterung auf internationale Märkte
- Branchenspezifische Lösungen
### 2. Alleinstellungsmerkmale
1. **Technologische Vorteile**:
- Proprietäre Multi-Agent-Technologie
- Modellunabhängige KI-Integration
- Enterprise-Ready Architektur
- Fortschrittliche Workflow-Orchestrierung
2. **Funktionale Vorteile**:
- Nahtlose Integration verschiedener KI-Modelle
- Robuste Fehlerbehandlung
- Skalierbare Multi-Tenant-Architektur
- Umfassende Enterprise-Features
### 3. Kunden und Pilotprojekte
- **Aktueller Status**:
- In Entwicklung
- Erste Referenzkunden in Planung
- Fokus auf mittelständische Unternehmen
- **Pilotphase**:
- Geplant für Q3/Q4 2025
- 3-5 Schlüsselreferenzkunden
- Branchenspezifische Templates
### 4. Geschäftsmodell
- **Hauptmodell**: SaaS (Software as a Service)
- **Preismodell**:
- Basis: Pro-Benutzer/Monat Abonnement
- Zusätzlich: Nutzungsbasierte Abrechnung
- Enterprise-Lizenzen für grössere Kunden
- **Erwartete Margen**: 75-85% nach Skalierung
### 5. Preisgestaltung
- **Wettbewerbsvergleich**:
- Unterhalb Enterprise-Lösungen
- Über Standard-BPA-Tools
- Flexiblere Preisgestaltung als Konkurrenz
- **Preisstruktur**:
- Basis-Abonnement: CHF 50-100 pro Benutzer/Monat
- Nutzungsbasierte Komponente: CHF 0.10-0.50 pro Verarbeitungseinheit
- Enterprise-Pakete: Individuelle Preisgestaltung
### 6. Umsatzpotenziale
- **Jahr 1 (2026)**:
- Ziel: 20-30 Kunden
- Erwartetes ARR: CHF 0.5-0.8 Mio.
- **Jahr 2 (2027)**:
- Ziel: 70-90 Kunden
- Erwartetes ARR: CHF 2-2.5 Mio.
- **Jahr 3 (2028)**:
- Ziel: 150+ Kunden
- Erwartetes ARR: CHF 4.5 Mio.
### 7. Akquisitionskosten
- **Customer Acquisition Cost (CAC)**:
- Erwarteter CAC: CHF 15,000-20,000
- Payback-Zeit: 12-18 Monate
- **Kostenstruktur**:
- 30% Vertrieb und Marketing
- Fokus auf effiziente Akquisition
- Skaleneffekte ab 50+ Kunden
### 8. Regulatorische Herausforderungen
- **Datenschutz**:
- DSGVO-Konformität
- Datensicherheit
- Mandantentrennung
- **KI-Regulierung**:
- EU AI Act
- Transparenzpflichten
- Qualitätssicherung
- **Branchenspezifische Regulierung**:
- Finanzdienstleistungen
- Gesundheitswesen
- Professional Services
### Fazit Markt- und Geschäftspotenzial
Die PowerOn AI Platform adressiert einen wachsenden Markt mit klaren Alleinstellungsmerkmalen. Das Geschäftsmodell ist skalierbar und die Preisgestaltung wettbewerbsfähig. Die regulatorischen Herausforderungen sind bekannt und adressierbar. Die Umsatzprognosen sind konservativ kalkuliert und basieren auf realistischen Marktannahmen.
## Teil 4: Skalierungs- und Zukunftspotenzial
### 1. Ressourcen für Support und Weiterentwicklung
- **Entwicklungsteam**:
- 2-3 Full-Stack Entwickler, KI-unterstützte Entwicklung
- 1 DevOps Engineer
- 1 QA Engineer
- **Support-Team**:
- 1-2 Support Engineers
- 1 Technical Account Manager
- **Infrastruktur**:
- Cloud-basierte Skalierung (Azure)
- Automatisierte Deployment-Pipeline
- Monitoring und Logging-Systeme
### 2. Skalierbarkeit
- **Technische Skalierbarkeit**:
- Horizontale Skalierung durch Multi-Tenant-Architektur
- Vertikale Skalierung durch Agent-Pooling
- Automatische Lastverteilung
- **Skalierungszeitrahmen**:
- 2x Nutzer: Sofort möglich
- 5x Nutzer: 1-2 Monate Vorbereitung
- 10x Nutzer: 3-4 Monate mit Infrastruktur-Erweiterung
### 3. Kapitalbedarf
- **Nächste Entwicklungsphase (12 Monate)**:
- Entwicklung: CHF 400,000-500,000
- Marketing & Sales: CHF 100,000-200,000
- Infrastruktur: CHF 50,000-100,000
- Betrieb & Support: CHF 100,000-150,000
- **Gesamt**: CHF 750,000-1,050,000
### 4. Schlüsselpersonen
- **Technische Leitung**:
- Patrick (Software Architect, Full Stack Developer)
- Verantwortlich für: Architektur, Entwicklung, Technische Strategie
- **Business & Operations**:
- Ida (Business Analyst, Project Manager)
- Verantwortlich für: Projektmanagement, Business Analysis
- **Sales & Marketing**:
- Dominic (Sales & Marketing)
- Verantwortlich für: Marktentwicklung, Kundenakquisition
### 5. Exit-Strategien
- **Strategische Übernahme**:
- Enterprise Software Anbieter
- KI/ML Plattform Betreiber
- Business Process Automation Unternehmen
- **IPO-Potenzial**:
- Ab CHF 50 Mio. ARR
- Zeitrahmen: 5-7 Jahre
- **Extraktion aus ValueOn AG**:
- Vergütung der Aufwände
- Anrechnung des Mehrwerts für Schlüsselpersonen
- Beschaffung des notwendigen Kapitals
### 6. Strategische Partnerschaften
- **Technologie-Partner**:
- KI-Provider (OpenAI, Anthropic)
- Cloud-Provider (Azure)
- Enterprise Software Anbieter
- **Vertriebspartner**:
- Systemhäuser
- Beratungsunternehmen
- Branchenspezialisten
- **Forschungspartner**:
- Universitäten
- Forschungsinstitute
- KI-Labore
### 7. Geplante Erweiterungen
- **Kurzfristig (12 Monate)**:
- Erweiterte Agent-Typen
- Branchenspezifische Templates
- API-Erweiterungen
- **Mittelfristig (24 Monate)**:
- Agentenmarktplatz
- Proprietäre KI-Modelle
- Erweiterte Analytics
- **Langfristig (36+ Monate)**:
- KI-Middleware für Unternehmen
- Branchenlösungen
- Internationale Expansion
### 8. Langfristige Vision
- **Technologische Vision**:
- Führende Multi-Agent KI-Plattform
- Standard für Enterprise Workflow Automation
- Innovationstreiber in der KI-Integration
- **Marktvision**:
- Globaler Marktführer in Nischenbereichen
- Branchenstandard für bestimmte Anwendungsfälle
- Referenz für KI-gestützte Prozessoptimierung
- **Geschäftsvision**:
- Nachhaltiges Wachstum
- Profitables Geschäftsmodell
- Führende Position in ausgewählten Märkten
### Fazit Skalierungs- und Zukunftspotenzial
Die PowerOn AI Platform verfügt über ein solides Skalierungspotenzial sowohl technisch als auch geschäftlich. Die modulare Architektur ermöglicht schnelles Wachstum, während die klare Vision und die strategischen Partnerschaften den langfristigen Erfolg unterstützen. Die Kapitalanforderungen sind realistisch kalkuliert und die Exit-Strategien bieten verschiedene Optionen für die Zukunft.
# Exitplan: PowerOn AI Platform als eigenständige AG
## Bewertung und Ausgangssituation
**Aktueller Wert (Juni 2025)**: CHF 500.000
**Angepasster Gründungswert**: CHF 800.000 (berücksichtigt den strategischen Wert der Produktvision, welche bereits als innerer Wert im Produkt enthalten ist)
## Strukturierung der PowerOn AG
### 1. Aktienstruktur bei Gründung
**Gesamtes Aktienkapital**: 1.000.000 Aktien (Nennwert CHF 0,10)
**Firmenvaluation bei Gründung**: CHF 800.000
#### Verteilung der initialen Aktien:
- **Patrick**:
- Eingebrachte Leistung: Entwicklung, technische Expertise und essenzielles Gesamtkonzept
- **Aktienanteil**: 35% (350.000 Aktien)
- **Dominic**:
- Eingebrachte Leistung: Netzwerk, Sales & Marketing Expertise und Vision
- **Aktienanteil**: 15% (150.000 Aktien)
- **ValueOn AG**:
- Eingebrachte Leistung: Infrastruktur, rechtlicher Rahmen, Arbeitszeit, Übertragung von IP
- **Aktienanteil**: 25% (250.000 Aktien)
- **Reservierter Anteil für Mitarbeiter-Pool**:
- **Aktienanteil**: 10% (100.000 Aktien)
- **Reserviert für Investoren (erste Runde)**:
- **Aktienanteil**: 15% (150.000 Aktien)
### 2. Kapitalbedarfsplanung (18 Monate)
| Kategorie | Betrag (CHF) |
|-----------|--------------|
| Entwicklung | 550.000 |
| Marketing & Sales | 250.000 |
| Infrastruktur | 100.000 |
| Betrieb & Support | 200.000 |
| **Gesamtbedarf** | **1.100.000** |
**Kapitalbeschaffungsstrategie**:
- **Erste Finanzierungsrunde**: CHF 1.000.000 (für 18 Monate)
- **Sicherheitspuffer**: CHF 100.000 (aus Umsätzen/zukünftigen Einnahmen)
### 3. Investitionskonditionen
**Pre-Money Bewertung**: CHF 800.000
**Investitionsvolumen**: CHF 1.000.000
**Post-Money Bewertung**: CHF 1.800.000
**Aktienkurs für Investoren**:
- 150.000 bestehende Aktien + 214.285 neue Aktien = 364.285 Aktien für Investoren
- **Aktienkurs**: CHF 2,75 pro Aktie
**Aktienstruktur nach Investment**:
- Patrick: 35% → 28,9% (350.000 Aktien)
- Dominic: 15% → 12,4% (150.000 Aktien)
- ValueOn AG: 25% → 20,7% (250.000 Aktien)
- Mitarbeiter-Pool: 10% → 8,3% (100.000 Aktien)
- Investoren: 29,7% (364.285 Aktien)
## Governance und Organisation
### 1. Schlüsselpositionen in der Organisation
- **CEO**: Gesamtführung des Unternehmens
- **CTO**: Verantwortlich für technische Strategie und Produktentwicklung
- **CSO/Vertriebsleitung**: Verantwortlich für Vertrieb und Marktentwicklung
- **COO**: Operative Leitung und Geschäftsprozesse
Die Besetzung dieser Positionen wird unter Berücksichtigung der Kompetenzen von Patrick, Dominic und möglichen neuen Führungskräften festgelegt. Die Rollen von CEO und COO werden im Rahmen der Unternehmensgründung evaluiert.
### 2. Vergütungsstruktur
- **Führungsebene**: Marktübliche Vergütung zwischen CHF 150.000-180.000/Jahr je nach Position
- **Aktienoptionen**: Zusätzliche Aktienoptionen bei Erreichen definierter Unternehmensziele
## Meilensteine und Finanzielle Ziele
### Kritische Meilensteine (18 Monate)
| Zeitpunkt | Meilenstein | KPI |
|-----------|-------------|-----|
| Q3 2025 | Ausgründung & Finanzierung | Abschluss der Seed-Runde |
| Q4 2025 | Markteinführung | 3-5 Pilotprojekte |
| Q1 2026 | Produktvalidierung | 10+ zahlende Kunden |
| Q2 2026 | Skalierung | 15+ zahlende Kunden |
| Q4 2026 | Vorbereitung Serie A | 25+ Kunden, ARR: CHF 0,8 Mio. |
### Umsatz- und Bewertungsprognose
| Jahr | Kunden | ARR (CHF) | Valuation (CHF) | Multiplikator |
|------|--------|-----------|-----------------|---------------|
| Ende 2025 | 5-8 | 0,2 Mio. | 1,8 Mio. | 9x ARR |
| Ende 2026 | 25-30 | 0,8 Mio. | 5,6 Mio. | 7x ARR |
| Ende 2027 | 80-90 | 2,5 Mio. | 15 Mio. | 6x ARR |
| Ende 2028 | 150+ | 4,5 Mio. | 27 Mio. | 6x ARR |
## Liquiditätsoptionen
### Mittelfristige Optionen (2-3 Jahre)
1. **Serie A Finanzierung** (Ende 2026):
- Teilweise Liquidität für Gründer und ValueOn AG (10-15% ihrer Anteile)
- Zu erwartender Wert: CHF 5-6 Mio.
2. **Strategische Partnerschaft**:
- Investment durch strategischen Partner mit teilweisem Aktienrückkauf
- Potenzielle Partner: Enterprise Software-Anbieter, KI-Plattform-Betreiber
### Langfristige Optionen (4-7 Jahre)
1. **Komplette Übernahme**:
- Erwarteter Exit-Wert 2028: CHF 25-30 Mio.
- Vollständige Liquidität für alle Anteilseigner
2. **IPO-Vorbereitung**:
- Bei Erreichen von CHF 10+ Mio. ARR
- Potenzielle Bewertung: CHF 50-70 Mio.
## Nächste Schritte im Ausgründungsprozess
1. **Rechtliche Strukturierung**:
- Gründung der PowerOn AG
- Übertragungsvereinbarungen für geistiges Eigentum
- Aktionärsvereinbarungen
2. **Finanzierung**:
- Erstellung eines detaillierten Businessplans
- Vorbereitung des Investor Pitch Decks
- Ansprache potenzieller Investoren
3. **Organisationsaufbau**:
- Definition der Führungsstruktur und Schlüsselpositionen
- Rekrutierung des Kernteams
- Aufbau der operativen Prozesse
4. **Markteinführungsstrategie**:
- Festlegung der Go-to-Market Strategie
- Identifikation von Pilotprojekten
- Vorbereitung der Vertriebsunterlagen

View file

@ -0,0 +1,6 @@
id,name,email,phone,address,iban,credit_card,ahv_number
1,Max Mustermann,max.mustermann@beispiel.de,+49 30 12345678,Musterstraße 123 12345 Berlin,DE89 3704 0044 0532 0130 00,4532 1234 5678 9012,
2,Peter Schmid,peter.schmid@beispiel.ch,+41 44 123 45 67,Bahnhofstrasse 1 8001 Zürich,CH93 0076 7000 E529 3557 7,4532 1234 5678 9013,756.1234.5678.90
3,Marie Dupont,marie.dupont@exemple.fr,+33 1 23 45 67 89,123 Rue de Paris 75001 Paris,FR76 3000 6000 0112 3456 7890 189,4532 1234 5678 9014,
4,Marco Rossi,marco.rossi@esempio.it,+39 02 1234 5678,Via Roma 123 20100 Milano,IT60 X054 2811 1010 0000 0123 456,4532 1234 5678 9015,
5,John Smith,john.smith@example.com,+44 20 1234 5678,123 High Street London SW1A 1AA,GB29 NWBK 6016 1331 9268 19,4532 1234 5678 9016,
1 id name email phone address iban credit_card ahv_number
2 1 Max Mustermann max.mustermann@beispiel.de +49 30 12345678 Musterstraße 123 12345 Berlin DE89 3704 0044 0532 0130 00 4532 1234 5678 9012
3 2 Peter Schmid peter.schmid@beispiel.ch +41 44 123 45 67 Bahnhofstrasse 1 8001 Zürich CH93 0076 7000 E529 3557 7 4532 1234 5678 9013 756.1234.5678.90
4 3 Marie Dupont marie.dupont@exemple.fr +33 1 23 45 67 89 123 Rue de Paris 75001 Paris FR76 3000 6000 0112 3456 7890 189 4532 1234 5678 9014
5 4 Marco Rossi marco.rossi@esempio.it +39 02 1234 5678 Via Roma 123 20100 Milano IT60 X054 2811 1010 0000 0123 456 4532 1234 5678 9015
6 5 John Smith john.smith@example.com +44 20 1234 5678 123 High Street London SW1A 1AA GB29 NWBK 6016 1331 9268 19 4532 1234 5678 9016

View file

@ -0,0 +1,73 @@
Lebenslauf: Lara Meier
Persönliche Daten:
Name: Lara Meier
Geboren: 15.03.1990
Adresse: Bahnhofstrasse 45, 8001 Zürich
Telefon: +41 44 123 45 67
E-Mail: lara.meier@example.ch
AHV-Nr.: 756.1234.5678.90
Steuernummer: 123.456.789
Berufserfahrung:
2020-2023: Senior Projektmanagerin
Firma: TechSolutions AG
Adresse: Industriestrasse 100, 8004 Zürich
UID: CHE-123.456.789
Telefon: +41 44 987 65 43
E-Mail: lara.meier@techsolutions.ch
In dieser Position leitete ich ein Team von 15 Mitarbeitern und verantwortete die Implementierung von Cloud-Lösungen für internationale Kunden. Meine Hauptaufgaben umfassten:
- Projektplanung und -steuerung mit einem Budget von CHF 2.5 Mio.
- Kundenbetreuung und Stakeholder-Management
- Teamführung und Personalentwicklung
- Qualitätssicherung und Risikomanagement
2015-2020: Projektmanagerin
Firma: Digital Systems GmbH
Adresse: Musterstrasse 123, 8002 Zürich
UID: CHE-987.654.321
Telefon: +41 44 456 78 90
E-Mail: l.meier@digitalsystems.ch
Als Projektmanagerin verantwortete ich die erfolgreiche Durchführung von Digitalisierungsprojekten. Meine Leistungen:
- Implementierung von ERP-Systemen
- Optimierung von Geschäftsprozessen
- Schulung von Endbenutzern
- Erstellung von Projektdokumentation
Ausbildung:
2010-2015: ETH Zürich
Studiengang: Informatik
Matrikelnummer: 12-345-678
Abschluss: Master of Science in Computer Science
Thesis: "Künstliche Intelligenz in der Prozessautomatisierung"
2005-2010: Kantonsschule Zürich
Abschluss: Eidgenössische Maturität
Schwerpunkt: Mathematik und Naturwissenschaften
Sprachen:
Deutsch (Muttersprache)
Englisch (C2)
Französisch (B2)
Italienisch (B1)
Zertifizierungen:
PMP (Project Management Professional)
ITIL v4 Foundation
AWS Certified Solutions Architect
Scrum Master (PSM I)
Referenzen:
Prof. Dr. Hans Müller
ETH Zürich
Department of Computer Science
Telefon: +41 44 123 45 68
E-Mail: hans.mueller@ethz.ch
Dr. Sarah Weber
TechSolutions AG
CTO
Telefon: +41 44 987 65 44
E-Mail: sarah.weber@techsolutions.ch

View file

@ -0,0 +1,6 @@
employee_id,first_name,last_name,email,phone,department,office_address,uid_number,bank_account
E001,Hans,Müller,hans.mueller@firma.de,+49 89 12345678,IT,Hauptstraße 1 80331 München,,DE89 3704 0044 0532 0130 00
E002,Thomas,Weber,thomas.weber@firma.ch,+41 44 234 56 78,HR,Bahnhofstrasse 2 8001 Zürich,CHE-123.456.789,01-234567-8
E003,Sophie,Martin,sophie.martin@entreprise.fr,+33 1 34 56 78 90,Finance,15 Avenue des Champs-Élysées 75008 Paris,,FR76 3000 6000 0112 3456 7890 189
E004,Luca,Ferrari,luca.ferrari@azienda.it,+39 02 2345 6789,Marketing,Via Monte Napoleone 8 20121 Milano,,IT60 X054 2811 1010 0000 0123 456
E005,Emma,Wilson,emma.wilson@company.com,+44 20 2345 6789,Sales,25 Old Street London EC1V 9HL,,GB29 NWBK 6016 1331 9268 19
1 employee_id first_name last_name email phone department office_address uid_number bank_account
2 E001 Hans Müller hans.mueller@firma.de +49 89 12345678 IT Hauptstraße 1 80331 München DE89 3704 0044 0532 0130 00
3 E002 Thomas Weber thomas.weber@firma.ch +41 44 234 56 78 HR Bahnhofstrasse 2 8001 Zürich CHE-123.456.789 01-234567-8
4 E003 Sophie Martin sophie.martin@entreprise.fr +33 1 34 56 78 90 Finance 15 Avenue des Champs-Élysées 75008 Paris FR76 3000 6000 0112 3456 7890 189
5 E004 Luca Ferrari luca.ferrari@azienda.it +39 02 2345 6789 Marketing Via Monte Napoleone 8 20121 Milano IT60 X054 2811 1010 0000 0123 456
6 E005 Emma Wilson emma.wilson@company.com +44 20 2345 6789 Sales 25 Old Street London EC1V 9HL GB29 NWBK 6016 1331 9268 19

12
test_neutralizer/testdata/english.txt vendored Normal file
View file

@ -0,0 +1,12 @@
Dear Mr. Smith,
Thank you for your email to contact@example.com.
Your contact details have been recorded:
Phone: +44 20 1234 5678
Address: 123 High Street, London SW1A 1AA
Your IBAN: GB29 NWBK 6016 1331 9268 19
Credit Card: 4532 1234 5678 9012
Best regards,
John Doe

54
test_neutralizer/testdata/example.json vendored Normal file
View file

@ -0,0 +1,54 @@
{
"customer": {
"personal_info": {
"name": "Max Mustermann",
"email": "max.mustermann@example.com",
"phone": "+49 123 4567890",
"address": {
"street": "Hauptstraße 123",
"city": "München",
"zip": "80331",
"country": "Deutschland"
}
},
"order_history": [
{
"order_id": "ORD-2024-001",
"date": "2024-03-15",
"items": [
{
"product": "Laptop",
"price": 1299.99,
"payment": {
"method": "credit_card",
"card_number": "4111 1111 1111 1111",
"iban": "DE89 3704 0044 0532 0130 00"
}
}
]
}
],
"preferences": {
"language": "de",
"newsletter": true,
"marketing_consent": {
"email": "max.mustermann@example.com",
"phone": "+49 123 4567890"
}
}
},
"company": {
"name": "Tech Solutions GmbH",
"contact": {
"manager": "Dr. Anna Schmidt",
"email": "anna.schmidt@techsolutions.de",
"phone": "+49 89 12345678",
"address": {
"street": "Technologiestraße 45",
"city": "Berlin",
"zip": "10115",
"country": "Deutschland"
}
}
}
}

79
test_neutralizer/testdata/example.xml vendored Normal file
View file

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<company_data>
<employees>
<employee id="EMP001">
<personal_info>
<name>Dr. Thomas Weber</name>
<email>thomas.weber@company.de</email>
<phone>+49 30 12345678</phone>
<address>
<street>Musterstraße 42</street>
<city>Hamburg</city>
<zip>20095</zip>
<country>Deutschland</country>
</address>
</personal_info>
<employment>
<department>IT</department>
<position>Senior Developer</position>
<salary currency="EUR">75000</salary>
<bank_details>
<iban>DE89 3704 0044 0532 0130 00</iban>
<bic>COBADEFFXXX</bic>
</bank_details>
</employment>
</employee>
<employee id="EMP002">
<personal_info>
<name>Maria Schmidt</name>
<email>maria.schmidt@company.de</email>
<phone>+49 40 98765432</phone>
<address>
<street>Bahnhofstraße 15</street>
<city>Frankfurt</city>
<zip>60329</zip>
<country>Deutschland</country>
</address>
</personal_info>
<employment>
<department>HR</department>
<position>HR Manager</position>
<salary currency="EUR">65000</salary>
<bank_details>
<iban>DE27 3704 0044 0532 0130 01</iban>
<bic>COBADEFFXXX</bic>
</bank_details>
</employment>
</employee>
</employees>
<projects>
<project id="PRJ001">
<name>Digital Transformation</name>
<manager>Dr. Thomas Weber</manager>
<budget currency="EUR">150000</budget>
<team_members>
<member email="thomas.weber@company.de">Dr. Thomas Weber</member>
<member email="maria.schmidt@company.de">Maria Schmidt</member>
</team_members>
</project>
</projects>
<company_info>
<name>Tech Innovations GmbH</name>
<address>
<street>Innovationsstraße 1</street>
<city>München</city>
<zip>80331</zip>
<country>Deutschland</country>
</address>
<contact>
<email>info@techinnovations.de</email>
<phone>+49 89 12345678</phone>
<fax>+49 89 12345679</fax>
</contact>
<banking>
<iban>DE89 3704 0044 0532 0130 02</iban>
<bic>COBADEFFXXX</bic>
<tax_id>DE123456789</tax_id>
</banking>
</company_info>
</company_data>

12
test_neutralizer/testdata/french.txt vendored Normal file
View file

@ -0,0 +1,12 @@
Bonjour Madame Dupont,
Merci pour votre email à contact@exemple.fr.
Vos coordonnées ont été enregistrées:
Téléphone: +33 1 23 45 67 89
Adresse: 123 Rue de Paris, 75001 Paris
Votre IBAN: FR76 3000 6000 0112 3456 7890 189
Carte de crédit: 4532 1234 5678 9012
Cordialement,
Jean Martin

12
test_neutralizer/testdata/german.txt vendored Normal file
View file

@ -0,0 +1,12 @@
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
Kreditkarte: 4532 1234 5678 9012
Mit freundlichen Grüßen
Max Mustermann

View file

@ -0,0 +1,56 @@
Geschäftsstrategie 2024-2026
TechSolutions AG
Unternehmensdaten:
Firmenname: TechSolutions AG
UID: CHE-123.456.789
Adresse: Industriestrasse 100, 8004 Zürich
Telefon: +41 44 987 65 43
E-Mail: info@techsolutions.ch
Website: www.techsolutions.ch
Geschäftsführung:
CEO: Dr. Thomas Weber
E-Mail: thomas.weber@techsolutions.ch
Telefon: +41 44 987 65 44
CTO: Dr. Sarah Müller
E-Mail: sarah.mueller@techsolutions.ch
Telefon: +41 44 987 65 45
Finanzdaten:
Bank: UBS AG
IBAN: CH93 0076 7000 E529 0767 9
BIC: UBSWCHZH80A
Strategische Ziele:
1. Marktpositionierung
- Marktanteil in der Schweiz auf 25% steigern
- Expansion in DACH-Region
- Neue Zielgruppe: KMU
2. Produktentwicklung
- Cloud-Lösung für KMU
- KI-basierte Automatisierung
- Mobile App für Kunden
3. Personalentwicklung
- Team auf 50 Mitarbeiter ausbauen
- Neue Standorte: Bern und Genf
- Fokus auf Diversity & Inclusion
4. Nachhaltigkeit
- CO2-Neutralität bis 2025
- Green IT Zertifizierung
- Nachhaltige Lieferkette
Budgetplanung:
2024: CHF 5.2 Mio.
2025: CHF 6.8 Mio.
2026: CHF 8.5 Mio.
Risikoanalyse:
- Marktrisiken
- Technologische Risiken
- Personelle Risiken
- Finanzielle Risiken

View file

@ -0,0 +1,6 @@
geschäft_id,datum,kundenname,kundenemail,betrag,zahlungsmethode,zahlungsdetails,lieferadresse
G001,2024-03-15,Anna Schmidt,anna.schmidt@kunde.de,1250,50,IBAN,DE89 3704 0044 0532 0130 00,Kirchstraße 10 10115 Berlin
G002,2024-03-15,Franz Huber,franz.huber@kunde.de,890,75,IBAN,DE02 5001 0517 5407 3249 31,Seefeldstraße 5 10117 Berlin
G003,2024-03-15,Pierre Dubois,pierre.dubois@kunde.de,2340,25,IBAN,DE27 2005 0550 1045 1862 37,15 Rue de la Paix 10115 Berlin
G004,2024-03-15,Giovanni Bianchi,giovanni.bianchi@kunde.de,1750,00,IBAN,DE02 5001 0517 5407 3249 32,Via della Spiga 20 10115 Berlin
G005,2024-03-15,William Brown,william.brown@kunde.de,3200,50,IBAN,DE02 5001 0517 5407 3249 33,42 Oxford Street 10115 Berlin
1 geschäft_id,datum,kundenname,kundenemail,betrag,zahlungsmethode,zahlungsdetails,lieferadresse
2 G001,2024-03-15,Anna Schmidt,anna.schmidt@kunde.de,1250,50,IBAN,DE89 3704 0044 0532 0130 00,Kirchstraße 10 10115 Berlin
3 G002,2024-03-15,Franz Huber,franz.huber@kunde.de,890,75,IBAN,DE02 5001 0517 5407 3249 31,Seefeldstraße 5 10117 Berlin
4 G003,2024-03-15,Pierre Dubois,pierre.dubois@kunde.de,2340,25,IBAN,DE27 2005 0550 1045 1862 37,15 Rue de la Paix 10115 Berlin
5 G004,2024-03-15,Giovanni Bianchi,giovanni.bianchi@kunde.de,1750,00,IBAN,DE02 5001 0517 5407 3249 32,Via della Spiga 20 10115 Berlin
6 G005,2024-03-15,William Brown,william.brown@kunde.de,3200,50,IBAN,DE02 5001 0517 5407 3249 33,42 Oxford Street 10115 Berlin

13
test_neutralizer/testdata/italian.txt vendored Normal file
View file

@ -0,0 +1,13 @@
Buongiorno Signora Rossi,
Grazie per la sua email a info@esempio.it.
Grazie per la sua email a info@esempio.it .
I suoi dati di contatto sono stati registrati:
Telefono: +39 02 1234 5678
Indirizzo: Via Roma 123, 20100 Milano
Il suo IBAN: IT60 X054 2811 1010 0000 0123 456
Carta di credito: 4532 1234 5678 9012
Cordiali saluti,
Marco Bianchi

6
test_neutralizer/testdata/kunden.csv vendored Normal file
View file

@ -0,0 +1,6 @@
kunden_id,vorname,nachname,email,telefon,adresse,iban,kreditkarte,steuernummer
K001,Michael,Schmidt,michael.schmidt@kunde.de,+49 30 12345678,Musterstraße 123 12345 Berlin,DE89 3704 0044 0532 0130 00,4532 1234 5678 9012,12/345/67890
K002,Sabine,Weber,sabine.weber@kunde.de,+49 89 23456789,Hauptstraße 45 80331 München,DE02 5001 0517 5407 3249 31,4532 1234 5678 9013,98/765/43210
K003,Thomas,Müller,thomas.mueller@kunde.de,+49 40 34567890,Neue Straße 78 20095 Hamburg,DE27 2005 0550 1045 1862 37,4532 1234 5678 9014,45/678/90123
K004,Petra,Fischer,petra.fischer@kunde.de,+49 69 45678901,Frankfurter Ring 12 60313 Frankfurt,DE02 5001 0517 5407 3249 32,4532 1234 5678 9015,34/567/89012
K005,Klaus,Wagner,klaus.wagner@kunde.de,+49 211 56789012,Königsallee 92 40212 Düsseldorf,DE02 5001 0517 5407 3249 33,4532 1234 5678 9016,23/456/78901
1 kunden_id vorname nachname email telefon adresse iban kreditkarte steuernummer
2 K001 Michael Schmidt michael.schmidt@kunde.de +49 30 12345678 Musterstraße 123 12345 Berlin DE89 3704 0044 0532 0130 00 4532 1234 5678 9012 12/345/67890
3 K002 Sabine Weber sabine.weber@kunde.de +49 89 23456789 Hauptstraße 45 80331 München DE02 5001 0517 5407 3249 31 4532 1234 5678 9013 98/765/43210
4 K003 Thomas Müller thomas.mueller@kunde.de +49 40 34567890 Neue Straße 78 20095 Hamburg DE27 2005 0550 1045 1862 37 4532 1234 5678 9014 45/678/90123
5 K004 Petra Fischer petra.fischer@kunde.de +49 69 45678901 Frankfurter Ring 12 60313 Frankfurt DE02 5001 0517 5407 3249 32 4532 1234 5678 9015 34/567/89012
6 K005 Klaus Wagner klaus.wagner@kunde.de +49 211 56789012 Königsallee 92 40212 Düsseldorf DE02 5001 0517 5407 3249 33 4532 1234 5678 9016 23/456/78901

View file

@ -0,0 +1,6 @@
mitarbeiter_id,vorname,nachname,email,telefon,abteilung,büroadresse,steuernummer,sozialversicherungsnummer
M001,Andreas,Becker,andreas.becker@firma.de,+49 30 98765432,IT,Hauptstraße 1 10115 Berlin,12/345/67890,12 345678 901
M002,Monika,Hoffmann,monika.hoffmann@firma.de,+49 89 87654321,HR,Leopoldstraße 45 80802 München,98/765/43210,98 765432 102
M003,Frank,Schäfer,frank.schaefer@firma.de,+49 40 76543210,Finanzen,Neuer Wall 78 20354 Hamburg,45/678/90123,45 678901 203
M004,Susanne,Koch,susanne.koch@firma.de,+49 69 65432109,Marketing,Mainzer Landstraße 12 60329 Frankfurt,34/567/89012,34 567890 304
M005,Dieter,Richter,dieter.richter@firma.de,+49 211 54321098,Vertrieb,Königsallee 92 40212 Düsseldorf,23/456/78901,23 456789 405
1 mitarbeiter_id vorname nachname email telefon abteilung büroadresse steuernummer sozialversicherungsnummer
2 M001 Andreas Becker andreas.becker@firma.de +49 30 98765432 IT Hauptstraße 1 10115 Berlin 12/345/67890 12 345678 901
3 M002 Monika Hoffmann monika.hoffmann@firma.de +49 89 87654321 HR Leopoldstraße 45 80802 München 98/765/43210 98 765432 102
4 M003 Frank Schäfer frank.schaefer@firma.de +49 40 76543210 Finanzen Neuer Wall 78 20354 Hamburg 45/678/90123 45 678901 203
5 M004 Susanne Koch susanne.koch@firma.de +49 69 65432109 Marketing Mainzer Landstraße 12 60329 Frankfurt 34/567/89012 34 567890 304
6 M005 Dieter Richter dieter.richter@firma.de +49 211 54321098 Vertrieb Königsallee 92 40212 Düsseldorf 23/456/78901 23 456789 405

13
test_neutralizer/testdata/swiss.txt vendored Normal file
View file

@ -0,0 +1,13 @@
Guten Tag Herr Schmid
Vielen Dank für Ihre Anfrage an info@beispiel.ch.
Ihre Kontaktdaten wurden wie folgt erfasst:
Telefon: +41 44 123 45 67
Adresse: 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üßen
Peter Muster

View file

@ -0,0 +1,6 @@
transaction_id,date,customer_name,customer_email,amount,payment_method,payment_details,shipping_address
T001,2024-03-15,Anna Schmidt,anna.schmidt@kunde.de,1250.50,IBAN,DE89 3704 0044 0532 0130 00,Kirchstraße 10 10115 Berlin
T002,2024-03-15,Franz Huber,franz.huber@kunde.ch,890.75,AHV,756.1234.5678.90,Seefeldstrasse 5 8008 Zürich
T003,2024-03-15,Pierre Dubois,pierre.dubois@client.fr,2340.25,IBAN,FR76 3000 6000 0112 3456 7890 189,15 Rue de la Paix 75002 Paris
T004,2024-03-15,Giovanni Bianchi,giovanni.bianchi@cliente.it,1750.00,IBAN,IT60 X054 2811 1010 0000 0123 456,Via della Spiga 20 20121 Milano
T005,2024-03-15,William Brown,william.brown@customer.com,3200.50,IBAN,GB29 NWBK 6016 1331 9268 19,42 Oxford Street London W1D 2BJ
1 transaction_id date customer_name customer_email amount payment_method payment_details shipping_address
2 T001 2024-03-15 Anna Schmidt anna.schmidt@kunde.de 1250.50 IBAN DE89 3704 0044 0532 0130 00 Kirchstraße 10 10115 Berlin
3 T002 2024-03-15 Franz Huber franz.huber@kunde.ch 890.75 AHV 756.1234.5678.90 Seefeldstrasse 5 8008 Zürich
4 T003 2024-03-15 Pierre Dubois pierre.dubois@client.fr 2340.25 IBAN FR76 3000 6000 0112 3456 7890 189 15 Rue de la Paix 75002 Paris
5 T004 2024-03-15 Giovanni Bianchi giovanni.bianchi@cliente.it 1750.00 IBAN IT60 X054 2811 1010 0000 0123 456 Via della Spiga 20 20121 Milano
6 T005 2024-03-15 William Brown william.brown@customer.com 3200.50 IBAN GB29 NWBK 6016 1331 9268 19 42 Oxford Street London W1D 2BJ

157
test_neutralizer/zdocu.html Normal file
View file

@ -0,0 +1,157 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Daten-Neutralisierer Logik</title>
<style>
body {
font-family: Arial, sans-serif;
line-height: 1.6;
margin: 40px;
color: #333;
}
h1, h2, h3 {
color: #2c3e50;
}
.pattern-group {
margin: 20px 0;
padding: 15px;
border: 1px solid #ddd;
border-radius: 5px;
}
.pattern {
margin: 10px 0;
padding: 10px;
background-color: #f8f9fa;
border-left: 4px solid #2c3e50;
}
.languages {
color: #666;
font-style: italic;
}
.replacement {
color: #27ae60;
font-weight: bold;
}
</style>
</head>
<body>
<h1>Daten-Neutralisierer Logik</h1>
<p>Der Daten-Neutralisierer unterstützt die Anonymisierung von sensiblen Daten in verschiedenen Dateiformaten (TXT, JSON, CSV, XML, DOCX) und Sprachen (DE, EN, FR, IT).</p>
<h2>1. Unterstützte Dateiformate</h2>
<ul>
<li>CSV-Dateien</li>
<li>JSON-Dateien</li>
<li>XML-Dateien</li>
<li>Text-Dateien (TXT)</li>
<li>Word-Dokumente (DOCX)</li>
</ul>
<h2>2. Neutralisierungsmuster</h2>
<div class="pattern-group">
<h3>Personenbezogene Daten</h3>
<div class="pattern">
<h4>Vornamen</h4>
<p>Deutsch: vorname, vornamen, rufname, taufname</p>
<p>Englisch: first name, given name, forename, personal name</p>
<p>Französisch: prénom, prénoms, nom de baptême</p>
<p>Italienisch: nome, nome di battesimo</p>
<p class="replacement">Ersetzung: NAME_{uuid}</p>
</div>
<div class="pattern">
<h4>Nachnamen</h4>
<p>Deutsch: nachname, nachnamen, familienname, familiennamen, zuname, zunamen</p>
<p>Englisch: last name, family name, surname, second name</p>
<p>Französisch: nom de famille, nom, noms</p>
<p>Italienisch: cognome, cognomi</p>
<p class="replacement">Ersetzung: NAME_{uuid}</p>
</div>
<div class="pattern">
<h4>Namen mit Titel</h4>
<p>Muster: Herr/Frau/Mr./Mrs./Ms./Monsieur/Madame/Signore/Signora/Dr./Prof.</p>
<p class="replacement">Ersetzung: NAME_{uuid}</p>
</div>
</div>
<div class="pattern-group">
<h3>Kontaktdaten</h3>
<div class="pattern">
<h4>E-Mail-Adressen</h4>
<p>Muster: [A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}</p>
<p class="replacement">Ersetzung: EMAIL_{uuid}</p>
</div>
<div class="pattern">
<h4>Telefonnummern</h4>
<p>Allgemein: (+XXX)? (XXX) XXX-XXXX</p>
<p>Deutsch: (+49|0049|0) XXX XXXXXXX</p>
<p>Schweiz: (+41|0041|0) XXX XXX XX XX</p>
<p class="replacement">Ersetzung: PHONE_{uuid}</p>
</div>
</div>
<div class="pattern-group">
<h3>Finanzielle Daten</h3>
<div class="pattern">
<h4>IBAN</h4>
<p>Muster: [A-Z]{2}\d{2}[A-Z0-9]{4}\d{7}([A-Z0-9]?){0,16}</p>
<p class="replacement">Ersetzung: IBAN_{uuid}</p>
</div>
<div class="pattern">
<h4>Kreditkartennummern</h4>
<p>Muster: XXXX-XXXX-XXXX-XXXX</p>
<p class="replacement">Ersetzung: CREDITCARD_{uuid}</p>
</div>
</div>
<div class="pattern-group">
<h3>Adressdaten</h3>
<div class="pattern">
<h4>Vollständige Adressen</h4>
<p>Muster: Straßenname + Hausnummer + PLZ + Stadt</p>
<p class="replacement">Ersetzung: ADDRESS_{uuid}</p>
</div>
<div class="pattern">
<h4>Städte und Orte</h4>
<p>Muster: Stadtnamen mit typischen Endungen (-stadt, -dorf, -berg, etc.)</p>
<p class="replacement">Ersetzung: CITY_{uuid}</p>
</div>
</div>
<h2>3. Verarbeitungslogik</h2>
<ol>
<li>Datei wird basierend auf dem Dateityp eingelesen</li>
<li>Bei Tabellendaten (CSV, JSON, XML):
<ul>
<li>Header werden analysiert und Spaltentypen identifiziert</li>
<li>Daten in den Spalten werden entsprechend dem Spaltentyp neutralisiert</li>
</ul>
</li>
<li>Bei Textdaten:
<ul>
<li>Text wird nach Tabellenstrukturen analysiert</li>
<li>Gefundene Tabellen werden wie oben verarbeitet</li>
<li>Verbleibender Text wird nach Mustern durchsucht</li>
</ul>
</li>
<li>Alle Ersetzungen werden in einer Mapping-Datei protokolliert</li>
</ol>
<h2>4. Logging und Tracking</h2>
<ul>
<li>Mapping-Log: Protokolliert alle durchgeführten Ersetzungen</li>
<li>Replacements-Log: Speichert Original- und anonymisierte Werte</li>
<li>Alle Aktionen werden mit Zeitstempel und Dateiname dokumentiert</li>
</ul>
</body>
</html>