# Mehrbenutzer-System & Authentifizierung - Konzept

## Inhaltsverzeichnis
1. [Überblick](#überblick)
2. [Architektur-Entscheidungen](#architektur-entscheidungen)
3. [Datenmodell](#datenmodell)
4. [Rollen & Berechtigungen](#rollen--berechtigungen)
5. [Authentifizierung](#authentifizierung)
6. [API-Änderungen](#api-änderungen)
7. [UI-Anpassungen](#ui-anpassungen)
8. [Implementierungs-Roadmap](#implementierungs-roadmap)
9. [Migrations-Strategie](#migrations-strategie)
10. [Sicherheitsaspekte](#sicherheitsaspekte)

---

## Überblick

### Ziel
Erweiterung des bestehenden Single-User-Systems zu einem Mehrbenutzer-System mit:
- **Benutzer-Authentifizierung** (Login/Logout)
- **Rollen-basierte Zugriffskontrolle** (RBAC)
- **Mehrbenutzer-Unterstützung** mit verschiedenen Berechtigungsstufen
- **Aktivitäts-Logging** für Nachvollziehbarkeit

### Anforderungen
- ✅ Einfache Integration in bestehendes System
- ✅ Abwärtskompatibilität (Migration bestehender Daten)
- ✅ Minimale Performance-Einbußen
- ✅ Datenschutz-konform (DSGVO)
- ✅ Session-basierte Authentifizierung (keine Tokens)
- ✅ Optional: Migration zu Datenbank möglich

---

## Architektur-Entscheidungen

### 1. Datenspeicherung
**Bevorzugte Lösung**: Hybrid-Ansatz
- **Benutzer & Sessions**: JSON-Dateien (einfache Migration)
- **Sponsoren-Daten**: Weiterhin JSON (kompatibel)
- **Optional**: Spätere Migration zu SQLite/MySQL

**Dateistruktur**:
```
/data/
├── benutzer.json           # Benutzer-Accounts
├── sessions.json           # Aktive Sessions
├── aktivitaeten.json       # Audit-Log
├── sponsoren.json          # Bestehende Daten
├── vertraege.json
├── leistungen.json
└── einstellungen.json
```

### 2. Session-Management
**PHP Sessions** mit JSON-Backend:
- Session-ID in Cookie
- Session-Daten in `sessions.json`
- Automatische Bereinigung abgelaufener Sessions
- Session-Timeout: 8 Stunden (konfigurierbar)

### 3. Passwort-Sicherheit
- **Hashing**: `password_hash()` mit `PASSWORD_BCRYPT` (PHP 7.4+)
- **Salt**: Automatisch durch PHP generiert
- **Mindestanforderungen**:
  - Mindestens 8 Zeichen
  - Optional: Komplexität erzwingen (1 Großbuchstabe, 1 Zahl, 1 Sonderzeichen)

---

## Datenmodell

### 1. Benutzer (data/benutzer.json)
```json
{
  "benutzer": [
    {
      "id": 1,
      "username": "admin",
      "email": "admin@example.com",
      "password_hash": "$2y$10$...",
      "vorname": "Max",
      "nachname": "Mustermann",
      "rolle": "admin",
      "aktiv": true,
      "erstellt": "2026-02-20T10:00:00Z",
      "letzter_login": "2026-02-20T15:30:00Z",
      "einstellungen": {
        "email_benachrichtigungen": true,
        "sprache": "de"
      }
    },
    {
      "id": 2,
      "username": "martin.meier",
      "email": "martin@example.com",
      "password_hash": "$2y$10$...",
      "vorname": "Martin",
      "nachname": "Meier",
      "rolle": "editor",
      "aktiv": true,
      "erstellt": "2026-02-20T11:00:00Z",
      "letzter_login": "2026-02-20T14:20:00Z",
      "einstellungen": {
        "email_benachrichtigungen": false,
        "sprache": "de"
      }
    }
  ]
}
```

### 2. Sessions (data/sessions.json)
```json
{
  "sessions": [
    {
      "session_id": "a3f8c9d2e1b4...",
      "benutzer_id": 1,
      "ip_adresse": "192.168.1.100",
      "user_agent": "Mozilla/5.0...",
      "erstellt": "2026-02-20T15:00:00Z",
      "läuft_ab": "2026-02-20T23:00:00Z",
      "letzte_aktivität": "2026-02-20T15:30:00Z"
    }
  ]
}
```

### 3. Aktivitäten-Log (data/aktivitaeten.json)
```json
{
  "aktivitaeten": [
    {
      "id": 1,
      "benutzer_id": 1,
      "username": "admin",
      "aktion": "sponsor.erstellt",
      "ressource_typ": "sponsor",
      "ressource_id": 42,
      "details": {
        "firmenname": "Neue Firma GmbH",
        "kategorie": "Gold"
      },
      "ip_adresse": "192.168.1.100",
      "zeitstempel": "2026-02-20T15:35:00Z"
    },
    {
      "id": 2,
      "benutzer_id": 2,
      "username": "martin.meier",
      "aktion": "vertrag.aktualisiert",
      "ressource_typ": "vertrag",
      "ressource_id": 15,
      "details": {
        "änderungen": {
          "betrag_2026": {"alt": 2000, "neu": 2500}
        }
      },
      "ip_adresse": "192.168.1.101",
      "zeitstempel": "2026-02-20T16:00:00Z"
    }
  ]
}
```

---

## Rollen & Berechtigungen

### Rollenmodell

#### 1. **Admin** (Volle Kontrolle)
- ✅ Benutzer verwalten (erstellen, bearbeiten, löschen)
- ✅ Alle Sponsoren-Daten bearbeiten
- ✅ Einstellungen ändern
- ✅ Export/Import
- ✅ Aktivitäten-Log einsehen
- ✅ System-Konfiguration

#### 2. **Editor** (Bearbeiten & Erstellen)
- ✅ Sponsoren erstellen und bearbeiten
- ✅ Verträge erstellen und bearbeiten
- ✅ Leistungen erstellen und bearbeiten
- ✅ Kommunikations-Protokoll pflegen
- ❌ Sponsoren löschen (nur eigene Einträge)
- ❌ Benutzer verwalten
- ❌ System-Einstellungen ändern
- ✅ Export (nur eigene Daten)

#### 3. **Viewer** (Nur Lesezugriff)
- ✅ Alle Sponsoren-Daten ansehen
- ✅ Dashboard einsehen
- ✅ Verträge ansehen
- ✅ Leistungen ansehen
- ❌ Keine Änderungen möglich
- ❌ Kein Export
- ❌ Keine Benutzer-Verwaltung

#### 4. **Contributor** (Eingeschränkt)
- ✅ Eigene zugewiesene Sponsoren bearbeiten
- ✅ Leistungen für eigene Sponsoren pflegen
- ✅ Kommunikations-Protokoll für eigene Sponsoren
- ❌ Andere Sponsoren ansehen/bearbeiten
- ❌ Verträge bearbeiten
- ❌ Dashboard-Statistiken anderer Benutzer

### Berechtigungs-Matrix

| Aktion | Admin | Editor | Viewer | Contributor |
|--------|-------|--------|--------|-------------|
| **Sponsoren** |
| Ansehen (alle) | ✅ | ✅ | ✅ | ❌ |
| Ansehen (eigene) | ✅ | ✅ | ✅ | ✅ |
| Erstellen | ✅ | ✅ | ❌ | ❌ |
| Bearbeiten (alle) | ✅ | ✅ | ❌ | ❌ |
| Bearbeiten (eigene) | ✅ | ✅ | ❌ | ✅ |
| Löschen | ✅ | ⚠️* | ❌ | ❌ |
| **Verträge** |
| Ansehen | ✅ | ✅ | ✅ | ⚠️** |
| Erstellen | ✅ | ✅ | ❌ | ❌ |
| Bearbeiten | ✅ | ✅ | ❌ | ❌ |
| Löschen | ✅ | ❌ | ❌ | ❌ |
| **Leistungen** |
| Ansehen | ✅ | ✅ | ✅ | ⚠️** |
| Erstellen | ✅ | ✅ | ❌ | ⚠️** |
| Bearbeiten | ✅ | ✅ | ❌ | ⚠️** |
| Status ändern | ✅ | ✅ | ❌ | ⚠️** |
| Archivieren | ✅ | ✅ | ❌ | ❌ |
| **System** |
| Einstellungen | ✅ | ❌ | ❌ | ❌ |
| Benutzer verwalten | ✅ | ❌ | ❌ | ❌ |
| Aktivitäten-Log | ✅ | ❌ | ❌ | ❌ |
| Export (alle) | ✅ | ✅ | ❌ | ❌ |
| Export (eigene) | ✅ | ✅ | ❌ | ✅ |

*Editor: Nur eigene erstellte Sponsoren  
**Contributor: Nur für zugewiesene Sponsoren

---

## Authentifizierung

### Login-Flow

```
1. Benutzer → Login-Seite (login.html)
   ↓
2. Eingabe: Username + Passwort
   ↓
3. POST /api/auth/login
   ↓
4. Backend:
   - Benutzer aus benutzer.json laden
   - Passwort verifizieren (password_verify)
   - Session erstellen
   - Session-ID in Cookie setzen
   ↓
5. Erfolg → Redirect zu /index.html
   Fehler → Fehlermeldung (Toast)
```

### Logout-Flow

```
1. Benutzer → Logout-Button
   ↓
2. POST /api/auth/logout
   ↓
3. Backend:
   - Session aus sessions.json löschen
   - Cookie löschen
   ↓
4. Redirect zu /login.html
```

### Session-Validierung

**Bei jedem API-Request**:
```php
1. Session-Cookie vorhanden?
   → Nein: 401 Unauthorized
   
2. Session in sessions.json?
   → Nein: 401 Unauthorized
   
3. Session abgelaufen?
   → Ja: Session löschen, 401 Unauthorized
   
4. Benutzer aktiv?
   → Nein: 403 Forbidden
   
5. Berechtigung für Aktion?
   → Nein: 403 Forbidden
   
6. ✅ Request erlaubt
   → Letzte Aktivität aktualisieren
```

### Auto-Logout
- Bei Inaktivität (konfigurierbar: 8h Standard)
- Bei Browser-Schließen (Option)
- Manuelle Logout-Funktion

---

## API-Änderungen

### Neue Endpoints

#### Authentifizierung
```
POST   /api/auth/login              # Login
POST   /api/auth/logout             # Logout
GET    /api/auth/session            # Aktuelle Session prüfen
POST   /api/auth/password/change    # Passwort ändern
POST   /api/auth/password/reset     # Passwort-Reset anfordern
```

#### Benutzerverwaltung
```
GET    /api/benutzer                # Alle Benutzer (nur Admin)
GET    /api/benutzer/{id}           # Einzelner Benutzer
POST   /api/benutzer                # Benutzer erstellen (nur Admin)
PUT    /api/benutzer/{id}           # Benutzer bearbeiten
DELETE /api/benutzer/{id}           # Benutzer löschen (nur Admin)
PUT    /api/benutzer/{id}/aktivieren # Benutzer aktivieren/deaktivieren
```

#### Aktivitäten
```
GET    /api/aktivitaeten            # Aktivitäten-Log (nur Admin)
GET    /api/aktivitaeten/benutzer/{id} # Aktivitäten eines Benutzers
```

### Geänderte Endpoints

**Alle bisherigen Endpoints** erhalten:
- Session-Validierung (Middleware)
- Berechtigungs-Prüfung
- Automatisches Logging

**Beispiel-Antwort mit Auth-Fehler**:
```json
{
  "success": false,
  "error": "unauthorized",
  "message": "Sie müssen angemeldet sein.",
  "code": 401
}
```

```json
{
  "success": false,
  "error": "forbidden",
  "message": "Sie haben keine Berechtigung für diese Aktion.",
  "code": 403
}
```

---

## UI-Anpassungen

### Neue Seiten

#### 1. Login-Seite (public/login.html)
```html
- Logo/Branding
- Username-Feld
- Passwort-Feld
- "Angemeldet bleiben"-Checkbox
- Login-Button
- "Passwort vergessen"-Link (optional)
- Toast-Benachrichtigungen
```

#### 2. Benutzerverwaltung (nur Admin)
```html
- Benutzer-Liste (Tabelle)
- Benutzer hinzufügen (Modal)
- Benutzer bearbeiten (Modal)
- Rollen-Zuweisung
- Aktivieren/Deaktivieren
- Letzter Login anzeigen
```

#### 3. Aktivitäten-Log (nur Admin)
Neuer Menüpunkt im Admin-Panel:
```html
- Filterbare Tabelle:
  - Benutzer
  - Aktion
  - Zeitraum
  - Ressource
- Export-Funktion
- Detail-Ansicht pro Aktivität
```

### Anpassungen bestehender Seiten

#### Navigation (index.html)
```html
<!-- Benutzer-Menü hinzufügen -->
<div class="user-menu">
  <i class="bi bi-person-circle"></i>
  <span>Max Mustermann</span>
  <div class="dropdown">
    <a href="#" onclick="openProfileModal()">Profil</a>
    <a href="#" onclick="openPasswordModal()">Passwort ändern</a>
    <a href="#" onclick="logout()">Abmelden</a>
  </div>
</div>
```

#### Dashboard
```html
<!-- Benutzer-spezifische Ansicht -->
- Nur eigene zugewiesene Aufgaben (Contributor)
- "Erstellt von mir"-Filter
- Aktivitäten der letzten 7 Tage
```

#### Sponsoren-Details
```html
<!-- Metadaten anzeigen -->
- Erstellt von: [Benutzername] am [Datum]
- Zuletzt bearbeitet: [Benutzername] am [Datum]
- Bearbeiten-Button: Nur wenn berechtigt
```

### Berechtigungs-basierte UI

**JavaScript-Funktion**:
```javascript
function hasPermission(action, resource) {
  // Prüft anhand der aktuellen Session
  const user = getCurrentUser();
  return checkPermission(user.rolle, action, resource);
}

// UI-Elemente ein/ausblenden
if (!hasPermission('delete', 'sponsor')) {
  document.getElementById('delete-btn').style.display = 'none';
}
```

---

## Implementierungs-Roadmap

### Phase 1: Backend-Grundlage (1-2 Wochen)

**Woche 1: Datenmodell & Session-Management**
- [ ] `benutzer.json` Struktur definieren
- [ ] `sessions.json` Struktur definieren
- [ ] `AuthManager.php` erstellen
  - Session-Erstellung
  - Session-Validierung
  - Session-Bereinigung
- [ ] `UserManager.php` erstellen
  - Benutzer erstellen
  - Benutzer abrufen
  - Passwort-Hash-Funktionen
- [ ] Migration: Initialen Admin-User erstellen

**Woche 2: API & Middleware**
- [ ] `AuthMiddleware.php` erstellen
  - Session-Check bei jedem Request
  - Berechtigungs-Prüfung
- [ ] Auth-Endpoints implementieren
  - `/api/auth/login`
  - `/api/auth/logout`
  - `/api/auth/session`
- [ ] User-Endpoints implementieren
  - `/api/benutzer` (CRUD)
- [ ] Bestehende Endpoints um Auth erweitern

### Phase 2: Frontend-Integration (1 Woche)

**Woche 3: Login & Navigation**
- [ ] `login.html` erstellen
  - Login-Formular
  - Toast-Integration
- [ ] `auth.js` erstellen
  - Login-Funktion
  - Logout-Funktion
  - Session-Check
- [ ] `app.js` erweitern
  - Auto-Redirect zu Login bei 401
  - Session-Refresh
  - Benutzer-Menü
- [ ] Navigation anpassen
  - Benutzer-Dropdown
  - Bedingte Menü-Punkte

### Phase 3: Benutzerverwaltung (1 Woche)

**Woche 4: Admin-Features**
- [ ] Benutzerverwaltung im Admin-Panel
  - Benutzer-Liste
  - Benutzer erstellen/bearbeiten
  - Rollen zuweisen
- [ ] Profil-Modal
  - Eigene Daten bearbeiten
  - Passwort ändern
- [ ] UI-Berechtigungen implementieren
  - Buttons ausblenden
  - Read-only-Felder

### Phase 4: Aktivitäten-Logging (1 Woche)

**Woche 5: Audit-Trail**
- [ ] `ActivityLogger.php` erstellen
- [ ] Logging in alle Manager integrieren
  - SponsorManager
  - VertragManager
  - LeistungManager
- [ ] Aktivitäten-Log UI
  - Admin-Panel-Seite
  - Filterbare Tabelle
  - Export-Funktion

### Phase 5: Testing & Refinement (1 Woche)

**Woche 6: Tests & Optimierungen**
- [ ] Sicherheits-Tests
  - SQL-Injection (nicht relevant, JSON)
  - XSS-Prevention
  - CSRF-Schutz (optional)
- [ ] Performance-Tests
  - Session-Bereinigung
  - JSON-File-Locking
- [ ] UI/UX-Verbesserungen
  - Error-Handling
  - Loading-States
  - Benachrichtigungen
- [ ] Dokumentation aktualisieren

---

## Migrations-Strategie

### Bestehende Daten migrieren

#### 1. Initialen Admin-User erstellen
```bash
php migrate_create_admin.php
```

**Script**: `migrate_create_admin.php`
```php
<?php
require_once 'src/UserManager.php';

$userManager = new UserManager();

// Erstelle Admin-User
$admin = [
    'username' => 'admin',
    'email' => 'admin@example.com',
    'password' => 'changeme123', // Wird gehasht
    'vorname' => 'Admin',
    'nachname' => 'User',
    'rolle' => 'admin'
];

$result = $userManager->create($admin);

if ($result['success']) {
    echo "✅ Admin-User erstellt!\n";
    echo "Username: admin\n";
    echo "Passwort: changeme123\n";
    echo "⚠️  WICHTIG: Passwort sofort ändern!\n";
} else {
    echo "❌ Fehler: " . $result['message'] . "\n";
}
```

#### 2. Bearbeiter zu Benutzern migrieren
```bash
php migrate_bearbeiter_to_users.php
```

**Script**: Erstellt User-Accounts für alle in `bearbeiter_liste` vorhandenen Namen

#### 3. Metadaten zu bestehenden Einträgen hinzufügen
```bash
php migrate_add_metadata.php
```

**Fügt hinzu**:
- `erstellt_von` (Benutzer-ID)
- `bearbeitet_von` (Benutzer-ID)
- `erstellt_am` (Timestamp)
- `bearbeitet_am` (Timestamp)

---

## Sicherheitsaspekte

### 1. Passwort-Sicherheit
- ✅ BCrypt-Hashing (Cost-Faktor: 10)
- ✅ Automatisches Salt
- ✅ Mindestlänge: 8 Zeichen
- ✅ Optional: Komplexitätsanforderungen
- ✅ Passwort-Historie (letzten 3 nicht wiederverwendbar)

### 2. Session-Sicherheit
- ✅ Sichere Session-IDs (32 Byte Random)
- ✅ Session-Timeout (8h Standard)
- ✅ IP-Bindung (optional, bei VPN problematisch)
- ✅ User-Agent-Validierung
- ✅ Automatische Bereinigung abgelaufener Sessions

### 3. Brute-Force-Schutz
- Rate-Limiting: Max 5 Fehlversuche / 15 Minuten
- Account-Sperre nach 10 Fehlversuchen
- Admin-Benachrichtigung bei Angriffen

### 4. XSS-Prevention
- HTML-Escaping bei Ausgabe
- Content-Security-Policy Header
- Input-Validierung

### 5. CSRF-Schutz (optional)
- Token-basiert
- Bei POST/PUT/DELETE-Requests

### 6. Datenschutz (DSGVO)
- Aktivitäten-Log: Nur 90 Tage Aufbewahrung
- Benutzer-Löschung: Anonymisierung statt Deletion
- Export eigener Daten ermöglichen
- Datenminimierung

### 7. Audit-Trail
- Alle kritischen Aktionen loggen
- Unveränderliches Log (Read-Only nach Erstellung)
- Regelmäßige Log-Reviews (Admin)

---

## Code-Beispiele

### AuthManager.php
```php
<?php
class AuthManager {
    private $db;
    private $sessionFile = __DIR__ . '/../data/sessions.json';
    private $sessionTimeout = 28800; // 8 Stunden
    
    public function __construct($database) {
        $this->db = $database;
    }
    
    public function login($username, $password) {
        // 1. Benutzer laden
        $users = $this->db->read('benutzer');
        $user = null;
        
        foreach ($users['benutzer'] as $u) {
            if ($u['username'] === $username && $u['aktiv']) {
                $user = $u;
                break;
            }
        }
        
        if (!$user) {
            return ['success' => false, 'message' => 'Benutzername oder Passwort falsch'];
        }
        
        // 2. Passwort verifizieren
        if (!password_verify($password, $user['password_hash'])) {
            return ['success' => false, 'message' => 'Benutzername oder Passwort falsch'];
        }
        
        // 3. Session erstellen
        $sessionId = bin2hex(random_bytes(32));
        $session = [
            'session_id' => $sessionId,
            'benutzer_id' => $user['id'],
            'ip_adresse' => $_SERVER['REMOTE_ADDR'],
            'user_agent' => $_SERVER['HTTP_USER_AGENT'],
            'erstellt' => date('c'),
            'läuft_ab' => date('c', time() + $this->sessionTimeout),
            'letzte_aktivität' => date('c')
        ];
        
        // 4. Session speichern
        $sessions = $this->db->read('sessions');
        if (!isset($sessions['sessions'])) {
            $sessions = ['sessions' => []];
        }
        $sessions['sessions'][] = $session;
        $this->db->write('sessions', $sessions);
        
        // 5. Cookie setzen
        setcookie('PHPSESSID', $sessionId, [
            'expires' => time() + $this->sessionTimeout,
            'path' => '/',
            'secure' => isset($_SERVER['HTTPS']),
            'httponly' => true,
            'samesite' => 'Lax'
        ]);
        
        // 6. Letzten Login aktualisieren
        $this->updateLastLogin($user['id']);
        
        return [
            'success' => true,
            'benutzer' => [
                'id' => $user['id'],
                'username' => $user['username'],
                'rolle' => $user['rolle'],
                'vorname' => $user['vorname'],
                'nachname' => $user['nachname']
            ]
        ];
    }
    
    public function validateSession() {
        $sessionId = $_COOKIE['PHPSESSID'] ?? null;
        
        if (!$sessionId) {
            return ['success' => false, 'code' => 401];
        }
        
        $sessions = $this->db->read('sessions');
        $session = null;
        
        foreach ($sessions['sessions'] as $s) {
            if ($s['session_id'] === $sessionId) {
                $session = $s;
                break;
            }
        }
        
        if (!$session) {
            return ['success' => false, 'code' => 401];
        }
        
        // Session abgelaufen?
        if (strtotime($session['läuft_ab']) < time()) {
            $this->deleteSession($sessionId);
            return ['success' => false, 'code' => 401, 'message' => 'Session abgelaufen'];
        }
        
        // Benutzer laden
        $users = $this->db->read('benutzer');
        $user = null;
        
        foreach ($users['benutzer'] as $u) {
            if ($u['id'] === $session['benutzer_id']) {
                $user = $u;
                break;
            }
        }
        
        if (!$user || !$user['aktiv']) {
            return ['success' => false, 'code' => 403];
        }
        
        // Letzte Aktivität aktualisieren
        $this->updateSessionActivity($sessionId);
        
        return [
            'success' => true,
            'benutzer' => [
                'id' => $user['id'],
                'username' => $user['username'],
                'rolle' => $user['rolle'],
                'vorname' => $user['vorname'],
                'nachname' => $user['nachname']
            ]
        ];
    }
    
    public function logout() {
        $sessionId = $_COOKIE['PHPSESSID'] ?? null;
        
        if ($sessionId) {
            $this->deleteSession($sessionId);
        }
        
        setcookie('PHPSESSID', '', time() - 3600, '/');
        
        return ['success' => true];
    }
    
    private function deleteSession($sessionId) {
        $sessions = $this->db->read('sessions');
        $sessions['sessions'] = array_filter($sessions['sessions'], function($s) use ($sessionId) {
            return $s['session_id'] !== $sessionId;
        });
        $sessions['sessions'] = array_values($sessions['sessions']);
        $this->db->write('sessions', $sessions);
    }
    
    private function updateSessionActivity($sessionId) {
        $sessions = $this->db->read('sessions');
        foreach ($sessions['sessions'] as &$s) {
            if ($s['session_id'] === $sessionId) {
                $s['letzte_aktivität'] = date('c');
                $s['läuft_ab'] = date('c', time() + $this->sessionTimeout);
                break;
            }
        }
        $this->db->write('sessions', $sessions);
    }
    
    private function updateLastLogin($userId) {
        $users = $this->db->read('benutzer');
        foreach ($users['benutzer'] as &$u) {
            if ($u['id'] === $userId) {
                $u['letzter_login'] = date('c');
                break;
            }
        }
        $this->db->write('benutzer', $users);
    }
    
    public function cleanupExpiredSessions() {
        $sessions = $this->db->read('sessions');
        $now = time();
        
        $sessions['sessions'] = array_filter($sessions['sessions'], function($s) use ($now) {
            return strtotime($s['läuft_ab']) > $now;
        });
        
        $sessions['sessions'] = array_values($sessions['sessions']);
        $this->db->write('sessions', $sessions);
    }
}
```

### PermissionManager.php
```php
<?php
class PermissionManager {
    private $permissions = [
        'admin' => [
            'sponsor.view.all' => true,
            'sponsor.create' => true,
            'sponsor.edit.all' => true,
            'sponsor.delete' => true,
            'vertrag.view.all' => true,
            'vertrag.create' => true,
            'vertrag.edit.all' => true,
            'vertrag.delete' => true,
            'leistung.view.all' => true,
            'leistung.create' => true,
            'leistung.edit.all' => true,
            'leistung.delete' => true,
            'user.manage' => true,
            'settings.edit' => true,
            'log.view' => true
        ],
        'editor' => [
            'sponsor.view.all' => true,
            'sponsor.create' => true,
            'sponsor.edit.all' => true,
            'sponsor.delete.own' => true,
            'vertrag.view.all' => true,
            'vertrag.create' => true,
            'vertrag.edit.all' => true,
            'leistung.view.all' => true,
            'leistung.create' => true,
            'leistung.edit.all' => true,
            'leistung.archive' => true
        ],
        'viewer' => [
            'sponsor.view.all' => true,
            'vertrag.view.all' => true,
            'leistung.view.all' => true
        ],
        'contributor' => [
            'sponsor.view.own' => true,
            'sponsor.edit.own' => true,
            'leistung.view.own' => true,
            'leistung.create.own' => true,
            'leistung.edit.own' => true
        ]
    ];
    
    public function hasPermission($rolle, $permission) {
        return $this->permissions[$rolle][$permission] ?? false;
    }
    
    public function canEditSponsor($user, $sponsor) {
        if ($this->hasPermission($user['rolle'], 'sponsor.edit.all')) {
            return true;
        }
        
        if ($this->hasPermission($user['rolle'], 'sponsor.edit.own')) {
            return $sponsor['erstellt_von'] === $user['id'];
        }
        
        return false;
    }
}
```

### login.html
```html
<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login - Sponsorenverwaltung</title>
    <link href="bootstrap.min.css" rel="stylesheet">
    <link href="bootstrap-icons.css" rel="stylesheet">
    <style>
        body {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        
        .login-card {
            max-width: 400px;
            width: 100%;
            background: white;
            border-radius: 15px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.3);
            padding: 40px;
        }
        
        .login-header {
            text-align: center;
            margin-bottom: 30px;
        }
        
        .login-header h1 {
            font-size: 1.8rem;
            font-weight: 700;
            color: #667eea;
        }
        
        .login-header p {
            color: #6c757d;
            margin-top: 10px;
        }
        
        .form-control:focus {
            border-color: #667eea;
            box-shadow: 0 0 0 0.2rem rgba(102, 126, 234, 0.25);
        }
        
        .btn-login {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            border: none;
            color: white;
            font-weight: 600;
            padding: 12px;
            width: 100%;
            margin-top: 20px;
        }
        
        .btn-login:hover {
            opacity: 0.9;
        }
    </style>
</head>
<body>
    <div id="toast-container" class="toast-container position-fixed top-0 end-0 p-3"></div>
    
    <div class="login-card">
        <div class="login-header">
            <i class="bi bi-people-fill" style="font-size: 3rem; color: #667eea;"></i>
            <h1>Sponsorenverwaltung</h1>
            <p>Bitte melden Sie sich an</p>
        </div>
        
        <form id="login-form" onsubmit="handleLogin(event)">
            <div class="mb-3">
                <label for="username" class="form-label">
                    <i class="bi bi-person"></i> Benutzername
                </label>
                <input type="text" class="form-control" id="username" required autofocus>
            </div>
            
            <div class="mb-3">
                <label for="password" class="form-label">
                    <i class="bi bi-lock"></i> Passwort
                </label>
                <input type="password" class="form-control" id="password" required>
            </div>
            
            <div class="form-check mb-3">
                <input class="form-check-input" type="checkbox" id="remember-me">
                <label class="form-check-label" for="remember-me">
                    Angemeldet bleiben
                </label>
            </div>
            
            <button type="submit" class="btn btn-login" id="login-btn">
                <i class="bi bi-box-arrow-in-right"></i> Anmelden
            </button>
        </form>
        
        <div class="text-center mt-4">
            <small class="text-muted">
                &copy; 2026 <a href="https://www.linkedin.com/in/jonas-laukandt/" target="_blank">Jonas Laukandt</a>
            </small>
        </div>
    </div>
    
    <script src="bootstrap.bundle.min.js"></script>
    <script>
        const API_BASE = 'api.php';
        
        function showToast(message, type = 'info') {
            const container = document.getElementById('toast-container');
            const toastEl = document.createElement('div');
            toastEl.className = `toast align-items-center show toast-${type}`;
            toastEl.innerHTML = `
                <div class="d-flex">
                    <div class="toast-body">${message}</div>
                    <button type="button" class="btn-close me-2 m-auto" data-bs-dismiss="toast"></button>
                </div>
            `;
            container.appendChild(toastEl);
            
            const toast = new bootstrap.Toast(toastEl, { delay: 4000 });
            toast.show();
            
            toastEl.addEventListener('hidden.bs.toast', () => toastEl.remove());
        }
        
        async function handleLogin(event) {
            event.preventDefault();
            
            const username = document.getElementById('username').value;
            const password = document.getElementById('password').value;
            const rememberMe = document.getElementById('remember-me').checked;
            const btn = document.getElementById('login-btn');
            
            btn.disabled = true;
            btn.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Anmelden...';
            
            try {
                const response = await fetch(`${API_BASE}?request=auth/login`, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ username, password, remember_me: rememberMe })
                });
                
                const data = await response.json();
                
                if (data.success) {
                    showToast('✅ Erfolgreich angemeldet!', 'success');
                    setTimeout(() => {
                        window.location.href = 'index.html';
                    }, 1000);
                } else {
                    showToast('❌ ' + (data.message || 'Login fehlgeschlagen'), 'danger');
                    btn.disabled = false;
                    btn.innerHTML = '<i class="bi bi-box-arrow-in-right"></i> Anmelden';
                }
            } catch (err) {
                showToast('❌ Verbindungsfehler', 'danger');
                btn.disabled = false;
                btn.innerHTML = '<i class="bi bi-box-arrow-in-right"></i> Anmelden';
            }
        }
    </script>
</body>
</html>
```

---

## Zusammenfassung

### Vorteile des Konzepts
✅ **Einfache Integration**: Minimale Änderungen am bestehenden Code  
✅ **Flexibel**: JSON-basiert, später zu DB migrierbar  
✅ **Sicher**: Moderne Best Practices (BCrypt, Sessions)  
✅ **DSGVO-konform**: Audit-Trail, Datenminimierung  
✅ **Benutzerfreundlich**: Toast-Benachrichtigungen, klare Berechtigungen  

### Geschätzte Entwicklungszeit
**6 Wochen** (bei 20h/Woche = 120 Stunden gesamt)

### Nächste Schritte
1. Konzept-Review & Freigabe
2. Phase 1 starten: Backend-Grundlage
3. Testing-Umgebung einrichten
4. Iterative Entwicklung mit Feedback-Loops

---

**Version**: 1.0  
**Datum**: 2026-02-20  
**Autor**: KI-Assistent  
**Status**: Entwurf
