Zum Inhalt

Architektur

🏗️ System-Architektur

CommunicationFinder folgt einer modularen, dezentralen Architektur mit klarer Trennung zwischen Backend (Konfiguration) und Frontend (Nutzung).


📐 High-Level-Übersicht

graph TB subgraph "User Layer" U1[Einzelperson] U2[Team] U3[Organisation] end subgraph "Application Layer" A1[Konfigurator
Backend] A2[Matrix
Frontend] A3[Visualizer] end subgraph "Data Layer" D1[JSON Settings] D2[LocalStorage] D3[IPFS] D4[Arweave] end subgraph "Identity Layer" I1[DIDs] I2[ENS/Unstoppable] I3[Web3 Wallet] end subgraph "Computation Layer" C1[Client-Side JS] C2[Cloudflare Workers] C3[WASM Modules] end U1 --> A1 U2 --> A1 U3 --> A1 A1 --> D1 D1 --> D2 D1 --> D3 D1 --> D4 A2 --> D1 A2 --> C1 I1 --> D3 I2 --> I1 I3 --> I2 C1 --> C2 C2 --> C3 style A1 fill:#E3F2FD style A2 fill:#E8F5E9 style D3 fill:#FFF3E0 style I1 fill:#F3E5F5

🔧 Komponenten-Details

1. Backend: Konfigurator

Technologie: Vanilla JavaScript, HTML5, CSS3

Funktionen: - 8-seitiger Wizard mit progressiver Offenlegung - Fragebogen-Engine mit Validierung - Gewichtungs-Algorithmus - JSON-Export mit SHA-256 Checksummen

Code-Struktur:

class Konfigurator {
    // State Management
    pages: Page[]
    currentPage: number
    answers: Map<string, Answer>

    // Navigation
    nextPage()
    previousPage()

    // Data Processing
    calculateWeights(): Weights
    generateSettings(): SettingsJSON
    exportSettings()

    // Validation
    validateAnswers(): boolean
}

Datenfluss:

Benutzer → Fragen beantworten → Antworten validieren 
→ Gewichte berechnen → JSON generieren → Exportieren


2. Frontend: Matrix

Technologie: Vanilla JavaScript, HTML5, CSS3

Funktionen: - 5×5 interaktive Matrix - Drag & Drop JSON-Import - Multi-Settings-Merging - Temporäre Modifikatoren - Live-Visualisierung

Code-Struktur:

class MatrixDecisionEngine {
    // Data Management
    loadedSettings: Settings[]
    mergedWeights: Weights
    activeModifiers: Set<Modifier>

    // Import/Merge
    loadSettings(files: File[])
    mergeSettings(): MergedWeights

    // Decision Logic
    calculateDecision(urgency, relationship): Decision
    applyModifiers(decision): ModifiedDecision

    // Visualization
    generateFlowDiagram(): HTML
    updateVisualization()
}

Datenfluss:

JSON Import → Parsing → Validierung → Merging 
→ Matrix-Klick → Decision Calculation → Modifier Apply 
→ Visualisierung → Display Result


3. Daten-Modell

Settings JSON Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid"
    },
    "version": {
      "type": "string",
      "pattern": "^\\d+\\.\\d+$"
    },
    "created": {
      "type": "string",
      "format": "date-time"
    },
    "checksum": {
      "type": "string",
      "pattern": "^[a-f0-9]{64}$"
    },
    "weights": {
      "type": "object",
      "properties": {
        "whatsapp": { "type": "number", "minimum": 0, "maximum": 100 },
        "signal": { "type": "number", "minimum": 0, "maximum": 100 },
        "telegram": { "type": "number", "minimum": 0, "maximum": 100 },
        "sms": { "type": "number", "minimum": 0, "maximum": 100 },
        "email": { "type": "number", "minimum": 0, "maximum": 100 },
        "slack": { "type": "number", "minimum": 0, "maximum": 100 },
        "teams": { "type": "number", "minimum": 0, "maximum": 100 },
        "discord": { "type": "number", "minimum": 0, "maximum": 100 },
        "phone": { "type": "number", "minimum": 0, "maximum": 100 },
        "video": { "type": "number", "minimum": 0, "maximum": 100 }
      },
      "required": ["whatsapp", "signal", "email", "phone"]
    },
    "rules": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "condition": { "type": "string" },
          "channels": { 
            "type": "array",
            "items": { "type": "string" }
          },
          "reason": { "type": "string" }
        },
        "required": ["condition", "channels", "reason"]
      }
    }
  },
  "required": ["id", "version", "created", "checksum", "weights"]
}

🌐 Dezentrale Architektur (Phase 3)

IPFS Integration

graph LR A[User Browser] -->|1. Upload Settings| B[IPFS Node] B -->|2. Generate CID| C[Content-Addressed Storage] C -->|3. Replicate| D[IPFS Network] D -->|4. Retrieve via CID| E[Other Users] style B fill:#FFF3E0 style C fill:#E8F5E9 style D fill:#E3F2FD

Vorteile: - ✅ Keine zentrale Speicherung - ✅ Content-basierte Adressierung (Integrität garantiert) - ✅ Automatische Replikation - ✅ Permanente Verfügbarkeit (solange 1 Node hostet)

Blockchain Identity (DIDs)

// Beispiel: DID-basierte Authentifizierung
const did = await createDID({
  method: 'ethr', // Ethereum-basiert
  provider: 'https://rinkeby.infura.io/v3/YOUR_KEY'
});

// Settings mit DID signieren
const signedSettings = await did.sign({
  payload: settingsJSON,
  keyType: 'Ed25519'
});

// Verifizierung durch andere
const isValid = await did.verify(signedSettings);

Vorteile: - ✅ Keine E-Mail-Adressen oder persönliche Daten nötig - ✅ Kryptographische Verifizierung - ✅ Selbstverwaltete Identität - ✅ Interoperabel mit Web3-Ökosystem


🔒 Security-Architektur

1. Client-Side Encryption

class SecureSettings {
    async encrypt(settings, password) {
        const key = await this.deriveKey(password);
        const iv = crypto.getRandomValues(new Uint8Array(12));

        const encrypted = await crypto.subtle.encrypt(
            { name: 'AES-GCM', iv },
            key,
            new TextEncoder().encode(JSON.stringify(settings))
        );

        return {
            iv: Array.from(iv),
            data: Array.from(new Uint8Array(encrypted))
        };
    }

    async deriveKey(password) {
        const salt = crypto.getRandomValues(new Uint8Array(16));
        const keyMaterial = await crypto.subtle.importKey(
            'raw',
            new TextEncoder().encode(password),
            'PBKDF2',
            false,
            ['deriveBits', 'deriveKey']
        );

        return crypto.subtle.deriveKey(
            {
                name: 'PBKDF2',
                salt,
                iterations: 100000,
                hash: 'SHA-256'
            },
            keyMaterial,
            { name: 'AES-GCM', length: 256 },
            false,
            ['encrypt', 'decrypt']
        );
    }
}

2. Integrity Verification

async function verifyChecksum(settings) {
    const { checksum, ...data } = settings;
    const computed = await crypto.subtle.digest(
        'SHA-256',
        new TextEncoder().encode(JSON.stringify(data))
    );
    const computedHex = Array.from(new Uint8Array(computed))
        .map(b => b.toString(16).padStart(2, '0'))
        .join('');

    return computedHex === checksum;
}

3. Privacy Layers

graph TB A[Original Settings] --> B[Anonymisierung] B --> C[UUID statt Namen] C --> D[Aggregation] D --> E[Gewichte statt Antworten] E --> F[Verschlüsselung] F --> G[IPFS Upload] style A fill:#ffcdd2 style G fill:#c8e6c9

⚡ Performance-Optimierung

1. Lazy Loading

// Module erst bei Bedarf laden
async function loadVisualization() {
    if (!window.MermaidRenderer) {
        const module = await import('./visualizer.js');
        window.MermaidRenderer = module.default;
    }
    return new window.MermaidRenderer();
}

2. Caching

class SettingsCache {
    constructor() {
        this.cache = new Map();
        this.maxSize = 50; // Max 50 Settings im Cache
    }

    set(uuid, settings) {
        if (this.cache.size >= this.maxSize) {
            const firstKey = this.cache.keys().next().value;
            this.cache.delete(firstKey);
        }
        this.cache.set(uuid, settings);
    }

    get(uuid) {
        return this.cache.get(uuid);
    }
}

3. Web Workers

// Gewichts-Berechnung in Background
const worker = new Worker('calculate-weights.js');
worker.postMessage({ answers: userAnswers });
worker.onmessage = (e) => {
    const weights = e.data;
    displayWeights(weights);
};

🔄 Synchronisation (Phase 3)

P2P mit Gun.js

const gun = Gun(['https://relay.peer1.com', 'https://relay.peer2.com']);

// Settings publizieren
gun.get('communicationfinder')
   .get('settings')
   .get(userDID)
   .put(encryptedSettings);

// Settings abonnieren
gun.get('communicationfinder')
   .get('settings')
   .map()
   .on((settings, key) => {
       console.log('Neue Settings von', key);
       mergeRemoteSettings(settings);
   });

Vorteile: - Echtzei-Synchronisation - Offline-First (lokale Kopie immer verfügbar) - Kein zentraler Server nötig - Konflikt-Auflösung automatisch


📊 Monitoring & Observability

Client-Side Analytics (Privacy-Friendly)

class PrivacyAnalytics {
    track(event, data) {
        // Nur aggregierte, anonyme Daten
        const sanitized = {
            event: event,
            timestamp: Date.now(),
            // KEINE User-IDs, IPs, oder persönliche Daten
            browserType: this.getBrowserFamily(),
            screenSize: this.getScreenCategory(),
        };

        // Lokal speichern, batch-upload einmal täglich
        this.localQueue.push(sanitized);
        if (this.localQueue.length > 100) {
            this.flush();
        }
    }
}

← Zurück zur Vision Weiter: Dezentralisierung →