diff --git a/.deployment-files b/.deployment-files
new file mode 100644
index 0000000..2da79da
--- /dev/null
+++ b/.deployment-files
@@ -0,0 +1,59 @@
+# Deployment-Dateien für TimeClock v3
+# Diese Datei listet alle für das Deployment relevanten Dateien auf
+
+## Hauptdokumentation
+- DEPLOYMENT.md # Vollständige Deployment-Anleitung
+- QUICKSTART_DEPLOYMENT.md # Schnellstart-Guide
+
+## Konfigurationsdateien
+- nginx.conf # Nginx-Konfiguration für stechuhr3.tsschulz.de
+- timeclock.service # Systemd-Service-Datei
+- ecosystem.config.js # PM2-Konfiguration
+- backend/env.production.template # Environment-Template
+
+## Scripts
+- deploy.sh # Automatisches Deployment-Script
+
+## Verwendung
+
+### Automatisches Deployment:
+```bash
+./deploy.sh install # Erste Installation
+./deploy.sh update # Update
+./deploy.sh backup # Backup
+./deploy.sh status # Status
+./deploy.sh logs # Logs
+```
+
+### Manuelle Installation:
+Siehe DEPLOYMENT.md oder QUICKSTART_DEPLOYMENT.md
+
+## Wichtige Pfade auf dem Server
+
+- Projekt: /var/www/timeclock
+- Backend: /var/www/timeclock/backend
+- Frontend: /var/www/timeclock/frontend/dist
+- Logs: /var/log/timeclock
+- Backups: /var/backups/timeclock
+- Nginx Config: /etc/nginx/sites-available/stechuhr3.tsschulz.de
+- Systemd Service: /etc/systemd/system/timeclock.service
+
+## Checkliste vor Deployment
+
+- [ ] DNS A-Record für stechuhr3.tsschulz.de gesetzt
+- [ ] MySQL/MariaDB läuft
+- [ ] Datenbank und User erstellt
+- [ ] .env Datei auf Server angepasst
+- [ ] JWT_SECRET und SESSION_SECRET generiert
+- [ ] E-Mail-Konfiguration angepasst (falls verwendet)
+- [ ] OAuth-Credentials erstellt (falls verwendet)
+
+## Nach dem Deployment prüfen
+
+- [ ] https://stechuhr3.tsschulz.de erreichbar
+- [ ] https://stechuhr3.tsschulz.de/api/health zeigt "ok"
+- [ ] Login funktioniert
+- [ ] SSL-Zertifikat gültig
+- [ ] Backend-Logs ohne Fehler
+- [ ] Nginx-Logs ohne Fehler
+
diff --git a/.deployment-info b/.deployment-info
new file mode 100644
index 0000000..9c38060
--- /dev/null
+++ b/.deployment-info
@@ -0,0 +1,99 @@
+# TimeClock v3 - Deployment Information
+
+## Deine Konfiguration
+
+- **Domain:** stechuhr3.tsschulz.de
+- **Webserver:** Apache2
+- **Backend Port:** 3010
+- **Process Manager:** PM2 (empfohlen) oder systemd
+- **SSL:** Let's Encrypt (Certbot)
+- **Database:** MySQL (tsschulz.de:3306/stechuhr2)
+
+## Wichtige Dateien
+
+### Für Apache2 Deployment
+- `apache2.conf` - Apache VirtualHost Konfiguration
+- `APACHE2_DEPLOYMENT.md` - Detaillierte Apache2-Anleitung
+- `deploy.sh` - Automatisches Deployment (auf apache2 konfiguriert)
+
+### Allgemein
+- `DEPLOYMENT.md` - Vollständige Deployment-Dokumentation
+- `QUICKSTART_DEPLOYMENT.md` - Schnellstart-Guide
+- `backend/env.production.template` - Environment-Template
+
+## Schnellstart
+
+```bash
+# Auf Server:
+cd /var/www/timeclock
+./deploy.sh install
+```
+
+Das Script ist bereits für Apache2 konfiguriert (Zeile 45: WEBSERVER="apache2").
+
+## Apache2-spezifische Befehle
+
+```bash
+# Site aktivieren
+sudo a2ensite stechuhr3.tsschulz.de
+
+# Apache testen
+sudo apache2ctl configtest
+
+# Apache neuladen
+sudo systemctl reload apache2
+
+# Logs ansehen
+sudo tail -f /var/log/apache2/stechuhr3-*.log
+
+# Modul aktivieren (falls benötigt)
+sudo a2enmod proxy proxy_http ssl rewrite headers
+```
+
+## Benötigte Apache2-Module
+
+Diese Module müssen aktiviert sein:
+- proxy
+- proxy_http
+- ssl
+- rewrite
+- headers
+- deflate
+- expires
+
+Aktivieren mit:
+```bash
+sudo a2enmod proxy proxy_http ssl rewrite headers deflate expires
+sudo systemctl restart apache2
+```
+
+## SSL-Zertifikat erstellen
+
+```bash
+# Certbot für Apache
+sudo apt install certbot python3-certbot-apache
+
+# Zertifikat erstellen
+sudo certbot --apache -d stechuhr3.tsschulz.de
+```
+
+## Nach dem Deployment
+
+✅ Frontend: https://stechuhr3.tsschulz.de
+✅ API Health: https://stechuhr3.tsschulz.de/api/health
+✅ Backend läuft auf: http://localhost:3010
+
+## Dokumentation
+
+- Vollständige Anleitung: `DEPLOYMENT.md`
+- Apache2-spezifisch: `APACHE2_DEPLOYMENT.md`
+- Schnellstart: `QUICKSTART_DEPLOYMENT.md`
+- Scripts: `scripts/README.md`
+
+## Support & Troubleshooting
+
+Bei Problemen siehe:
+1. `APACHE2_DEPLOYMENT.md` - Troubleshooting-Sektion
+2. Apache-Logs: `/var/log/apache2/stechuhr3-*.log`
+3. Backend-Logs: `pm2 logs timeclock-backend`
+
diff --git a/APACHE2_DEPLOYMENT.md b/APACHE2_DEPLOYMENT.md
new file mode 100644
index 0000000..c66e681
--- /dev/null
+++ b/APACHE2_DEPLOYMENT.md
@@ -0,0 +1,448 @@
+# TimeClock v3 - Apache2 Deployment Guide
+
+Spezielle Anleitung für das Deployment mit **Apache2** statt Nginx auf Ubuntu 22.04.
+
+## Schnellstart
+
+### Automatisches Deployment mit Apache2
+
+Das `deploy.sh` Script ist bereits für Apache2 konfiguriert:
+
+```bash
+cd /var/www/timeclock
+./deploy.sh install
+```
+
+Das Script erkennt automatisch, dass Apache2 verwendet wird (Variable `WEBSERVER="apache2"` in Zeile 45).
+
+## Manuelle Apache2-Installation
+
+### 1. Apache2 und Module installieren
+
+```bash
+# Apache2 installieren
+sudo apt update
+sudo apt install -y apache2
+
+# Benötigte Module aktivieren
+sudo a2enmod proxy proxy_http ssl rewrite headers deflate expires
+
+# Apache2 neustarten
+sudo systemctl restart apache2
+```
+
+### 2. VirtualHost konfigurieren
+
+```bash
+# Konfiguration kopieren
+sudo cp /var/www/timeclock/apache2.conf /etc/apache2/sites-available/stechuhr3.tsschulz.de.conf
+
+# Site aktivieren
+sudo a2ensite stechuhr3.tsschulz.de
+
+# Optional: Default-Site deaktivieren
+sudo a2dissite 000-default
+
+# Konfiguration testen
+sudo apache2ctl configtest
+
+# Apache2 neuladen
+sudo systemctl reload apache2
+```
+
+### 3. SSL mit Certbot
+
+```bash
+# Certbot für Apache installieren
+sudo apt install -y certbot python3-certbot-apache
+
+# Zertifikat erstellen
+sudo certbot --apache -d stechuhr3.tsschulz.de
+```
+
+## Apache2-Konfiguration erklärt
+
+Die `apache2.conf` enthält:
+
+### Proxy-Konfiguration für Backend-API
+
+```apache
+ProxyPass /api http://localhost:3010/api retry=0
+ProxyPassReverse /api http://localhost:3010/api
+```
+
+Dies leitet alle `/api/*` Anfragen an das Node.js Backend auf Port 3010 weiter.
+
+### SPA-Routing (Vue.js)
+
+```apache
+
+ RewriteEngine On
+ RewriteBase /
+ RewriteRule ^index\.html$ - [L]
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteCond %{REQUEST_FILENAME} !-d
+ RewriteCond %{REQUEST_URI} !^/api
+ RewriteRule . /index.html [L]
+
+```
+
+Dies sorgt dafür, dass alle Nicht-API-Anfragen an `index.html` geleitet werden (für Vue Router).
+
+### Compression (gzip)
+
+```apache
+
+ AddOutputFilterByType DEFLATE text/html text/css application/javascript
+ # ... weitere MIME-Types
+
+```
+
+### Caching
+
+```apache
+
+ ExpiresActive On
+ ExpiresByType text/css "access plus 1 year"
+ ExpiresByType application/javascript "access plus 1 year"
+ # ... weitere Cache-Regeln
+
+```
+
+### Security Headers
+
+```apache
+Header always set X-Frame-Options "SAMEORIGIN"
+Header always set X-Content-Type-Options "nosniff"
+Header always set Strict-Transport-Security "max-age=31536000"
+# ... weitere Security-Header
+```
+
+## Wichtige Apache2-Befehle
+
+### Sites verwalten
+
+```bash
+# Site aktivieren
+sudo a2ensite stechuhr3.tsschulz.de
+
+# Site deaktivieren
+sudo a2dissite stechuhr3.tsschulz.de
+
+# Alle aktivierten Sites anzeigen
+ls -la /etc/apache2/sites-enabled/
+```
+
+### Module verwalten
+
+```bash
+# Modul aktivieren
+sudo a2enmod proxy
+sudo a2enmod ssl
+sudo a2enmod rewrite
+
+# Modul deaktivieren
+sudo a2dismod module_name
+
+# Aktivierte Module anzeigen
+apache2ctl -M
+```
+
+### Apache2 steuern
+
+```bash
+# Status anzeigen
+sudo systemctl status apache2
+
+# Starten
+sudo systemctl start apache2
+
+# Stoppen
+sudo systemctl stop apache2
+
+# Neustarten (Downtime)
+sudo systemctl restart apache2
+
+# Neuladen (ohne Downtime)
+sudo systemctl reload apache2
+
+# Konfiguration testen
+sudo apache2ctl configtest
+# oder
+sudo apachectl -t
+```
+
+### Logs anzeigen
+
+```bash
+# Access-Log
+sudo tail -f /var/log/apache2/stechuhr3-access.log
+
+# Error-Log
+sudo tail -f /var/log/apache2/stechuhr3-error.log
+
+# Alle Apache-Logs
+sudo tail -f /var/log/apache2/*.log
+```
+
+## Troubleshooting
+
+### Apache startet nicht
+
+```bash
+# Detaillierte Fehlerausgabe
+sudo apache2ctl configtest
+
+# Systemd-Logs
+sudo journalctl -u apache2 -n 50
+
+# Konfigurationsdateien prüfen
+sudo apache2ctl -S
+```
+
+### Proxy funktioniert nicht
+
+```bash
+# Prüfe ob Modul aktiviert ist
+apache2ctl -M | grep proxy
+
+# Falls nicht aktiviert:
+sudo a2enmod proxy proxy_http
+sudo systemctl restart apache2
+
+# Backend-Verfügbarkeit prüfen
+curl http://localhost:3010/api/health
+```
+
+### SSL-Probleme
+
+```bash
+# Zertifikat prüfen
+sudo certbot certificates
+
+# Zertifikat erneuern
+sudo certbot renew --apache
+
+# SSL-Modul prüfen
+apache2ctl -M | grep ssl
+
+# Falls nicht aktiviert:
+sudo a2enmod ssl
+sudo systemctl restart apache2
+```
+
+### .htaccess wird ignoriert
+
+```bash
+# Stelle sicher, dass AllowOverride gesetzt ist
+# In der VirtualHost-Konfiguration:
+
+ AllowOverride All
+
+
+# Rewrite-Modul aktivieren
+sudo a2enmod rewrite
+sudo systemctl restart apache2
+```
+
+### Permissions-Probleme
+
+```bash
+# Korrekter Besitzer
+sudo chown -R www-data:www-data /var/www/timeclock/frontend/dist
+
+# Korrekte Berechtigungen
+sudo find /var/www/timeclock/frontend/dist -type f -exec chmod 644 {} \;
+sudo find /var/www/timeclock/frontend/dist -type d -exec chmod 755 {} \;
+```
+
+## Performance-Optimierung
+
+### EnableKeepAlive
+
+Füge in `/etc/apache2/apache2.conf` hinzu:
+
+```apache
+KeepAlive On
+MaxKeepAliveRequests 100
+KeepAliveTimeout 5
+```
+
+### MPM-Modul optimieren
+
+```bash
+# Zeige aktives MPM
+apache2ctl -V | grep MPM
+
+# Für Event MPM (empfohlen):
+sudo nano /etc/apache2/mods-available/mpm_event.conf
+```
+
+Beispiel-Konfiguration:
+
+```apache
+
+ StartServers 2
+ MinSpareThreads 25
+ MaxSpareThreads 75
+ ThreadLimit 64
+ ThreadsPerChild 25
+ MaxRequestWorkers 150
+ MaxConnectionsPerChild 0
+
+```
+
+### HTTP/2 aktivieren
+
+```bash
+# HTTP/2 Modul aktivieren
+sudo a2enmod http2
+
+# In VirtualHost hinzufügen:
+# Protocols h2 http/1.1
+
+sudo systemctl restart apache2
+```
+
+### Caching verbessern
+
+Aktiviere mod_cache:
+
+```bash
+sudo a2enmod cache
+sudo a2enmod cache_disk
+sudo systemctl restart apache2
+```
+
+In der VirtualHost-Konfiguration:
+
+```apache
+
+ CacheQuickHandler off
+ CacheLock on
+ CacheLockPath /tmp/mod_cache-lock
+ CacheLockMaxAge 5
+ CacheIgnoreHeaders Set-Cookie
+
+```
+
+## Sicherheit
+
+### mod_security installieren (Web Application Firewall)
+
+```bash
+# Installieren
+sudo apt install -y libapache2-mod-security2
+
+# Aktivieren
+sudo a2enmod security2
+
+# Basis-Konfiguration
+sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
+
+# SecRuleEngine auf "On" setzen
+sudo nano /etc/modsecurity/modsecurity.conf
+# SecRuleEngine On
+
+sudo systemctl restart apache2
+```
+
+### mod_evasive (DDoS-Schutz)
+
+```bash
+# Installieren
+sudo apt install -y libapache2-mod-evasive
+
+# Konfigurieren
+sudo nano /etc/apache2/mods-available/evasive.conf
+```
+
+```apache
+
+ DOSHashTableSize 3097
+ DOSPageCount 5
+ DOSSiteCount 100
+ DOSPageInterval 1
+ DOSSiteInterval 1
+ DOSBlockingPeriod 10
+ DOSEmailNotify admin@tsschulz.de
+
+```
+
+```bash
+sudo a2enmod evasive
+sudo systemctl restart apache2
+```
+
+### fail2ban für Apache
+
+```bash
+# Installieren
+sudo apt install -y fail2ban
+
+# Apache-Jail aktivieren
+sudo nano /etc/fail2ban/jail.local
+```
+
+```ini
+[apache-auth]
+enabled = true
+
+[apache-badbots]
+enabled = true
+
+[apache-noscript]
+enabled = true
+
+[apache-overflows]
+enabled = true
+```
+
+```bash
+sudo systemctl restart fail2ban
+```
+
+## Vergleich Nginx vs Apache2
+
+| Feature | Nginx | Apache2 |
+|---------|-------|---------|
+| **Performance** | Sehr hoch (Event-driven) | Hoch (Process/Thread-based) |
+| **Konfiguration** | Einfacher | Komplexer, aber mächtiger |
+| **.htaccess** | Nicht unterstützt | Unterstützt |
+| **Module** | Weniger, aber effizienter | Sehr viele verfügbar |
+| **Best for** | Reverse Proxy, statische Dateien | .htaccess, komplexe Setups |
+| **Memory** | Geringer | Höher |
+
+Für TimeClock ist **beides** geeignet, Apache2 bietet mehr Flexibilität, Nginx mehr Performance.
+
+## Migration von Nginx zu Apache2
+
+Falls du bereits Nginx installiert hast:
+
+```bash
+# Nginx stoppen und deaktivieren
+sudo systemctl stop nginx
+sudo systemctl disable nginx
+
+# Apache2 installieren und einrichten (siehe oben)
+
+# Firewall anpassen
+sudo ufw delete allow 'Nginx Full'
+sudo ufw allow 'Apache Full'
+
+# SSL-Zertifikat ist kompatibel, keine Änderung nötig
+```
+
+## Nützliche Links
+
+- [Apache2 Dokumentation](https://httpd.apache.org/docs/2.4/)
+- [Apache2 auf Ubuntu](https://ubuntu.com/server/docs/web-servers-apache)
+- [Let's Encrypt mit Apache](https://certbot.eff.org/instructions?ws=apache&os=ubuntufocal)
+- [Apache Security Best Practices](https://geekflare.com/apache-web-server-hardening-security/)
+
+---
+
+**Apache2 läuft! 🚀**
+
+Bei Fragen oder Problemen: Siehe `DEPLOYMENT.md` oder prüfe die Logs!
+
diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md
new file mode 100644
index 0000000..cd4bb4c
--- /dev/null
+++ b/DEPLOYMENT.md
@@ -0,0 +1,581 @@
+# TimeClock v3 - Deployment Guide für Ubuntu 22.04
+
+Dieser Guide beschreibt das komplette Deployment der TimeClock-App auf einem Ubuntu 22.04 Server unter der URL **stechuhr3.tsschulz.de**.
+
+## Voraussetzungen
+
+### Software-Anforderungen
+- Ubuntu 22.04 LTS
+- Node.js v18+ (empfohlen: v20)
+- MySQL 8.0 oder MariaDB 10.6+
+- Nginx
+- Certbot (für SSL/Let's Encrypt)
+- PM2 oder systemd für Process Management
+
+### Domain & DNS
+- Domain: `stechuhr3.tsschulz.de`
+- DNS A-Record muss auf die Server-IP zeigen
+
+## Schritt 1: System-Vorbereitung
+
+```bash
+# System aktualisieren
+sudo apt update && sudo apt upgrade -y
+
+# Node.js 20.x installieren
+curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
+sudo apt install -y nodejs
+
+# Nginx installieren
+sudo apt install -y nginx
+
+# Certbot für SSL installieren
+sudo apt install -y certbot python3-certbot-nginx
+
+# PM2 global installieren (empfohlen)
+sudo npm install -g pm2
+
+# MySQL/MariaDB sollte bereits installiert sein
+# Falls nicht:
+# sudo apt install -y mysql-server
+```
+
+## Schritt 2: Datenbank vorbereiten
+
+```bash
+# In MySQL/MariaDB einloggen
+sudo mysql -u root -p
+
+# Datenbank und User erstellen (falls noch nicht vorhanden)
+CREATE DATABASE IF NOT EXISTS stechuhr2;
+CREATE USER IF NOT EXISTS 'timeclock'@'localhost' IDENTIFIED BY 'SICHERES_PASSWORT';
+GRANT ALL PRIVILEGES ON stechuhr2.* TO 'timeclock'@'localhost';
+FLUSH PRIVILEGES;
+EXIT;
+
+# Schema importieren (falls noch nicht vorhanden)
+# mysql -u timeclock -p stechuhr2 < backend/database-schema.sql
+```
+
+## Schritt 3: Projekt auf Server klonen/übertragen
+
+```bash
+# Projekt-Verzeichnis erstellen
+sudo mkdir -p /var/www
+cd /var/www
+
+# Mit Git klonen (oder per SCP übertragen)
+# sudo git clone https://github.com/IHR-USERNAME/TimeClock.git timeclock
+# ODER das lokale Projekt übertragen:
+# rsync -avz --exclude 'node_modules' ~/Programs/TimeClock/ user@server:/var/www/timeclock/
+
+# Eigentümer setzen
+sudo chown -R $USER:$USER /var/www/timeclock
+```
+
+## Schritt 4: Backend konfigurieren
+
+```bash
+cd /var/www/timeclock/backend
+
+# Dependencies installieren
+npm install --production
+
+# .env Datei erstellen
+cp .env.production.example .env
+
+# .env bearbeiten und folgende Werte anpassen:
+nano .env
+```
+
+**Wichtige .env Variablen:**
+```env
+NODE_ENV=production
+PORT=3010
+
+# Datenbank
+DB_HOST=localhost
+DB_NAME=stechuhr2
+DB_USER=timeclock
+DB_PASSWORD=IHR_DB_PASSWORT
+
+# JWT
+JWT_SECRET=IHR_SICHERER_JWT_SECRET_KEY
+JWT_EXPIRES_IN=7d
+
+# Session
+SESSION_SECRET=IHR_SICHERER_SESSION_SECRET
+
+# Frontend URL
+FRONTEND_URL=https://stechuhr3.tsschulz.de
+
+# Email (optional, für Passwort-Reset)
+EMAIL_HOST=smtp.example.com
+EMAIL_PORT=587
+EMAIL_USER=your-email@example.com
+EMAIL_PASSWORD=your-email-password
+EMAIL_FROM=noreply@tsschulz.de
+
+# OAuth (optional, falls Google OAuth verwendet wird)
+GOOGLE_CLIENT_ID=your-client-id
+GOOGLE_CLIENT_SECRET=your-client-secret
+GOOGLE_CALLBACK_URL=https://stechuhr3.tsschulz.de/api/auth/oauth/google/callback
+```
+
+## Schritt 5: Frontend bauen
+
+```bash
+cd /var/www/timeclock/frontend
+
+# Dependencies installieren
+npm install
+
+# Produktions-Build erstellen
+npm run build
+
+# Build-Dateien werden in /var/www/timeclock/frontend/dist erstellt
+```
+
+## Schritt 6: Nginx konfigurieren
+
+```bash
+# Nginx-Konfiguration erstellen
+sudo nano /etc/nginx/sites-available/stechuhr3.tsschulz.de
+```
+
+Folgende Konfiguration einfügen (siehe `nginx.conf` im Projekt):
+
+```nginx
+server {
+ listen 80;
+ listen [::]:80;
+ server_name stechuhr3.tsschulz.de;
+
+ # Zunächst nur HTTP für Certbot
+ location /.well-known/acme-challenge/ {
+ root /var/www/certbot;
+ }
+
+ location / {
+ return 301 https://$server_name$request_uri;
+ }
+}
+
+server {
+ listen 443 ssl http2;
+ listen [::]:443 ssl http2;
+ server_name stechuhr3.tsschulz.de;
+
+ # SSL-Zertifikate (werden von Certbot automatisch eingefügt)
+ ssl_certificate /etc/letsencrypt/live/stechuhr3.tsschulz.de/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/stechuhr3.tsschulz.de/privkey.pem;
+
+ # SSL-Konfiguration
+ ssl_protocols TLSv1.2 TLSv1.3;
+ ssl_prefer_server_ciphers on;
+ ssl_ciphers HIGH:!aNULL:!MD5;
+
+ # Frontend (Vue.js SPA)
+ root /var/www/timeclock/frontend/dist;
+ index index.html;
+
+ # Logging
+ access_log /var/log/nginx/stechuhr3.access.log;
+ error_log /var/log/nginx/stechuhr3.error.log;
+
+ # Gzip Compression
+ gzip on;
+ gzip_vary on;
+ gzip_min_length 1024;
+ gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
+
+ # API Proxy zum Backend
+ location /api {
+ proxy_pass http://localhost:3010;
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection 'upgrade';
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_cache_bypass $http_upgrade;
+
+ # Timeouts
+ proxy_connect_timeout 60s;
+ proxy_send_timeout 60s;
+ proxy_read_timeout 60s;
+ }
+
+ # SPA Fallback - alle anderen Requests zu index.html
+ location / {
+ try_files $uri $uri/ /index.html;
+ }
+
+ # Cache für statische Assets
+ location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
+ expires 1y;
+ add_header Cache-Control "public, immutable";
+ }
+
+ # Security Headers
+ add_header X-Frame-Options "SAMEORIGIN" always;
+ add_header X-Content-Type-Options "nosniff" always;
+ add_header X-XSS-Protection "1; mode=block" always;
+ add_header Referrer-Policy "strict-origin-when-cross-origin" always;
+}
+```
+
+```bash
+# Konfiguration aktivieren
+sudo ln -s /etc/nginx/sites-available/stechuhr3.tsschulz.de /etc/nginx/sites-enabled/
+
+# Default-Seite deaktivieren (optional)
+sudo rm -f /etc/nginx/sites-enabled/default
+
+# Nginx-Konfiguration testen
+sudo nginx -t
+
+# Nginx neuladen
+sudo systemctl reload nginx
+```
+
+## Schritt 7: SSL-Zertifikat mit Let's Encrypt
+
+```bash
+# Certbot ausführen
+sudo certbot --nginx -d stechuhr3.tsschulz.de
+
+# Folgen Sie den Anweisungen:
+# - E-Mail-Adresse eingeben
+# - Nutzungsbedingungen akzeptieren
+# - Optional: Newsletter ablehnen
+# - HTTPS-Redirect: Ja (empfohlen)
+
+# Automatische Erneuerung testen
+sudo certbot renew --dry-run
+```
+
+## Schritt 8: Backend als Service einrichten
+
+### Option A: PM2 (empfohlen)
+
+```bash
+cd /var/www/timeclock/backend
+
+# Backend mit PM2 starten
+pm2 start src/index.js --name timeclock-backend --env production
+
+# PM2 Auto-Start konfigurieren
+pm2 startup systemd
+# Führen Sie den angezeigten Befehl aus
+
+# Aktuelle PM2-Prozesse speichern
+pm2 save
+
+# Status überprüfen
+pm2 status
+pm2 logs timeclock-backend
+```
+
+### Option B: Systemd Service
+
+```bash
+# Service-Datei erstellen
+sudo nano /etc/systemd/system/timeclock.service
+```
+
+Folgende Konfiguration einfügen:
+
+```ini
+[Unit]
+Description=TimeClock v3 Backend API
+After=network.target mysql.service
+
+[Service]
+Type=simple
+User=www-data
+WorkingDirectory=/var/www/timeclock/backend
+Environment=NODE_ENV=production
+ExecStart=/usr/bin/node src/index.js
+Restart=always
+RestartSec=10
+StandardOutput=append:/var/log/timeclock/backend.log
+StandardError=append:/var/log/timeclock/backend.error.log
+
+# Sicherheit
+NoNewPrivileges=true
+PrivateTmp=true
+ProtectSystem=strict
+ProtectHome=true
+ReadWritePaths=/var/www/timeclock/backend
+
+[Install]
+WantedBy=multi-user.target
+```
+
+```bash
+# Log-Verzeichnis erstellen
+sudo mkdir -p /var/log/timeclock
+sudo chown www-data:www-data /var/log/timeclock
+
+# Service aktivieren und starten
+sudo systemctl daemon-reload
+sudo systemctl enable timeclock
+sudo systemctl start timeclock
+
+# Status prüfen
+sudo systemctl status timeclock
+
+# Logs ansehen
+sudo journalctl -u timeclock -f
+```
+
+## Schritt 9: Firewall konfigurieren
+
+```bash
+# UFW Firewall aktivieren (falls noch nicht aktiv)
+sudo ufw allow ssh
+sudo ufw allow 'Nginx Full'
+sudo ufw enable
+
+# Status prüfen
+sudo ufw status
+```
+
+## Schritt 10: Deployment testen
+
+```bash
+# Backend-Health-Check
+curl http://localhost:3010/api/health
+
+# Frontend über Domain aufrufen
+# https://stechuhr3.tsschulz.de
+
+# SSL-Test
+curl -I https://stechuhr3.tsschulz.de
+```
+
+## Wartung und Updates
+
+### Backend aktualisieren
+
+```bash
+cd /var/www/timeclock/backend
+git pull # oder neue Dateien übertragen
+npm install --production
+
+# Mit PM2:
+pm2 restart timeclock-backend
+
+# Mit systemd:
+sudo systemctl restart timeclock
+```
+
+### Frontend aktualisieren
+
+```bash
+cd /var/www/timeclock/frontend
+git pull # oder neue Dateien übertragen
+npm install
+npm run build
+# Nginx cached automatisch neu
+```
+
+### Logs überwachen
+
+```bash
+# PM2 Logs
+pm2 logs timeclock-backend
+
+# Systemd Logs
+sudo journalctl -u timeclock -f
+
+# Nginx Logs
+sudo tail -f /var/log/nginx/stechuhr3.access.log
+sudo tail -f /var/log/nginx/stechuhr3.error.log
+```
+
+### Datenbank-Backup
+
+```bash
+# Tägliches Backup einrichten
+sudo nano /usr/local/bin/backup-timeclock.sh
+```
+
+```bash
+#!/bin/bash
+BACKUP_DIR="/var/backups/timeclock"
+DATE=$(date +%Y%m%d_%H%M%S)
+mkdir -p $BACKUP_DIR
+
+# Datenbank-Backup
+mysqldump -u timeclock -p'IHR_PASSWORT' stechuhr2 | gzip > $BACKUP_DIR/timeclock_$DATE.sql.gz
+
+# Alte Backups löschen (älter als 30 Tage)
+find $BACKUP_DIR -name "timeclock_*.sql.gz" -mtime +30 -delete
+
+echo "Backup erstellt: timeclock_$DATE.sql.gz"
+```
+
+```bash
+# Ausführbar machen
+sudo chmod +x /usr/local/bin/backup-timeclock.sh
+
+# Cronjob einrichten (täglich um 2 Uhr)
+sudo crontab -e
+# Folgende Zeile hinzufügen:
+# 0 2 * * * /usr/local/bin/backup-timeclock.sh
+```
+
+## Troubleshooting
+
+### Backend startet nicht
+
+```bash
+# Logs prüfen
+pm2 logs timeclock-backend --err
+# oder
+sudo journalctl -u timeclock -n 50
+
+# Port-Belegung prüfen
+sudo netstat -tulpn | grep 3010
+
+# .env Datei prüfen
+cat /var/www/timeclock/backend/.env
+```
+
+### Frontend zeigt nicht an
+
+```bash
+# Nginx-Konfiguration testen
+sudo nginx -t
+
+# Nginx neuladen
+sudo systemctl reload nginx
+
+# Dist-Verzeichnis prüfen
+ls -la /var/www/timeclock/frontend/dist/
+```
+
+### SSL-Probleme
+
+```bash
+# Zertifikat erneuern
+sudo certbot renew --force-renewal -d stechuhr3.tsschulz.de
+
+# Nginx neustarten
+sudo systemctl restart nginx
+```
+
+### API-Requests schlagen fehl
+
+```bash
+# CORS-Probleme: FRONTEND_URL in .env prüfen
+# Nginx Proxy-Konfiguration prüfen
+sudo nginx -t
+
+# Backend-Logs prüfen
+pm2 logs timeclock-backend
+```
+
+## Performance-Optimierung
+
+### PM2 Cluster-Modus (optional)
+
+```bash
+cd /var/www/timeclock/backend
+
+# PM2 im Cluster-Modus starten (nutzt alle CPU-Kerne)
+pm2 delete timeclock-backend
+pm2 start src/index.js --name timeclock-backend --instances max --env production
+pm2 save
+```
+
+### Nginx Caching (optional)
+
+Füge in der Nginx-Konfiguration hinzu:
+
+```nginx
+# Im http-Block von /etc/nginx/nginx.conf
+proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api_cache:10m max_size=100m inactive=60m use_temp_path=off;
+
+# Im server-Block der stechuhr3.tsschulz.de Konfiguration
+location /api {
+ proxy_cache api_cache;
+ proxy_cache_valid 200 5m;
+ proxy_cache_bypass $http_cache_control;
+ add_header X-Cache-Status $upstream_cache_status;
+
+ # ... rest der proxy_pass Konfiguration
+}
+```
+
+## Sicherheits-Checkliste
+
+- [x] SSL/TLS aktiviert (Let's Encrypt)
+- [x] Firewall konfiguriert (UFW)
+- [x] Starke Passwörter für DB und JWT_SECRET
+- [x] NODE_ENV=production gesetzt
+- [x] Nginx Security Headers aktiviert
+- [x] Backend läuft nicht als Root
+- [x] Regelmäßige Backups eingerichtet
+- [ ] fail2ban installieren (optional)
+- [ ] Rate Limiting in Nginx konfigurieren (optional)
+- [ ] ModSecurity WAF installieren (optional)
+
+## Monitoring (optional)
+
+### PM2 Plus Monitoring
+
+```bash
+# PM2 Plus Account erstellen: https://id.keymetrics.io
+pm2 plus
+# Link folgen und Account verbinden
+```
+
+### Einfaches Uptime-Monitoring
+
+```bash
+# Einfaches Health-Check Script
+sudo nano /usr/local/bin/check-timeclock.sh
+```
+
+```bash
+#!/bin/bash
+if ! curl -sf http://localhost:3010/api/health > /dev/null; then
+ echo "Backend ist down! $(date)" >> /var/log/timeclock/health-check.log
+ pm2 restart timeclock-backend
+ # oder: sudo systemctl restart timeclock
+fi
+```
+
+```bash
+# Ausführbar machen
+sudo chmod +x /usr/local/bin/check-timeclock.sh
+
+# Cronjob alle 5 Minuten
+sudo crontab -e
+# */5 * * * * /usr/local/bin/check-timeclock.sh
+```
+
+## Zusammenfassung der Endpunkte
+
+- **Frontend:** https://stechuhr3.tsschulz.de
+- **API:** https://stechuhr3.tsschulz.de/api
+- **Health-Check:** https://stechuhr3.tsschulz.de/api/health
+
+## Support
+
+Bei Problemen:
+1. Logs prüfen (`pm2 logs` oder `journalctl -u timeclock`)
+2. Nginx-Logs prüfen (`/var/log/nginx/`)
+3. Datenbank-Verbindung testen
+4. .env Konfiguration überprüfen
+
+---
+
+**Deployment erfolgreich! 🎉**
+
+Ihre TimeClock-App läuft jetzt auf https://stechuhr3.tsschulz.de
+
diff --git a/QUICKSTART_DEPLOYMENT.md b/QUICKSTART_DEPLOYMENT.md
new file mode 100644
index 0000000..95be8f1
--- /dev/null
+++ b/QUICKSTART_DEPLOYMENT.md
@@ -0,0 +1,421 @@
+# 🚀 TimeClock v3 - Schnellstart Deployment
+
+Eine Schritt-für-Schritt-Anleitung für das Deployment auf **stechuhr3.tsschulz.de**.
+
+## Voraussetzungen
+
+✅ Ubuntu 22.04 Server
+✅ Root/Sudo-Zugriff
+✅ Domain `stechuhr3.tsschulz.de` zeigt auf Server-IP
+✅ MySQL/MariaDB läuft
+✅ SSH-Zugang zum Server
+
+## Option 1: Automatisches Deployment (Empfohlen) 🎯
+
+### Auf deinem lokalen Rechner:
+
+```bash
+# 1. Projekt auf Server übertragen
+cd /home/torsten/Programs/TimeClock
+rsync -avz --exclude 'node_modules' --exclude '.git' . user@YOUR_SERVER_IP:/tmp/timeclock-deploy/
+
+# 2. SSH zum Server
+ssh user@YOUR_SERVER_IP
+```
+
+### Auf dem Server:
+
+```bash
+# 3. Projekt vorbereiten
+sudo mkdir -p /var/www
+sudo mv /tmp/timeclock-deploy /var/www/timeclock
+sudo chown -R $USER:$USER /var/www/timeclock
+
+# 4. Automatisches Deployment starten
+cd /var/www/timeclock
+chmod +x deploy.sh
+./deploy.sh install
+```
+
+Das war's! 🎉 Das Script führt automatisch durch alle notwendigen Schritte.
+
+---
+
+## Option 2: Manuelles Deployment (Schritt für Schritt) 📝
+
+### Schritt 1: System vorbereiten
+
+```bash
+# System aktualisieren
+sudo apt update && sudo apt upgrade -y
+
+# Node.js 20.x installieren
+curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
+sudo apt install -y nodejs
+
+# Weitere Abhängigkeiten
+sudo apt install -y nginx certbot python3-certbot-nginx
+sudo npm install -g pm2
+```
+
+### Schritt 2: Datenbank einrichten
+
+```bash
+# MySQL/MariaDB
+sudo mysql -u root -p
+
+# In MySQL:
+CREATE DATABASE IF NOT EXISTS stechuhr2;
+CREATE USER IF NOT EXISTS 'timeclock'@'localhost' IDENTIFIED BY 'DEIN_SICHERES_PASSWORT';
+GRANT ALL PRIVILEGES ON stechuhr2.* TO 'timeclock'@'localhost';
+FLUSH PRIVILEGES;
+EXIT;
+```
+
+### Schritt 3: Projekt auf Server übertragen
+
+```bash
+# Auf lokalem Rechner:
+rsync -avz --exclude 'node_modules' ~/Programs/TimeClock/ user@YOUR_SERVER_IP:/var/www/timeclock/
+
+# ODER per Git (wenn in Repository):
+# ssh user@YOUR_SERVER_IP
+# cd /var/www
+# git clone https://github.com/IHR-USERNAME/TimeClock.git timeclock
+```
+
+### Schritt 4: Backend konfigurieren
+
+```bash
+cd /var/www/timeclock/backend
+
+# Dependencies installieren
+npm install --production
+
+# .env erstellen
+cp env.production.template .env
+nano .env
+
+# Wichtige Werte anpassen:
+# - DB_PASSWORD=dein_db_passwort
+# - JWT_SECRET=generiere_mit_node_crypto
+# - SESSION_SECRET=generiere_mit_node_crypto
+# - FRONTEND_URL=https://stechuhr3.tsschulz.de
+
+# Secrets generieren:
+node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"
+```
+
+### Schritt 5: Frontend bauen
+
+```bash
+cd /var/www/timeclock/frontend
+npm install
+npm run build
+```
+
+### Schritt 6: Nginx einrichten
+
+```bash
+# Konfiguration kopieren
+sudo cp /var/www/timeclock/nginx.conf /etc/nginx/sites-available/stechuhr3.tsschulz.de
+
+# Site aktivieren
+sudo ln -s /etc/nginx/sites-available/stechuhr3.tsschulz.de /etc/nginx/sites-enabled/
+
+# Default-Site deaktivieren (optional)
+sudo rm /etc/nginx/sites-enabled/default
+
+# Testen und neuladen
+sudo nginx -t
+sudo systemctl reload nginx
+```
+
+### Schritt 7: SSL-Zertifikat erstellen
+
+```bash
+# Let's Encrypt Zertifikat
+sudo certbot --nginx -d stechuhr3.tsschulz.de
+
+# Folge den Anweisungen:
+# - E-Mail eingeben
+# - Nutzungsbedingungen akzeptieren
+# - HTTPS-Redirect aktivieren (empfohlen)
+```
+
+### Schritt 8: Backend starten
+
+**Option A: Mit PM2 (empfohlen):**
+
+```bash
+cd /var/www/timeclock/backend
+pm2 start src/index.js --name timeclock-backend --env production
+pm2 save
+pm2 startup systemd
+# Führe den angezeigten Befehl aus
+```
+
+**Option B: Mit systemd:**
+
+```bash
+# Service installieren
+sudo cp /var/www/timeclock/timeclock.service /etc/systemd/system/
+sudo systemctl daemon-reload
+sudo systemctl enable timeclock
+sudo systemctl start timeclock
+```
+
+### Schritt 9: Firewall konfigurieren
+
+```bash
+sudo ufw allow ssh
+sudo ufw allow 'Nginx Full'
+sudo ufw enable
+```
+
+### Schritt 10: Testen
+
+```bash
+# Backend-Health-Check
+curl http://localhost:3010/api/health
+
+# Frontend aufrufen
+# Browser: https://stechuhr3.tsschulz.de
+```
+
+---
+
+## Nützliche Befehle
+
+### Mit PM2:
+
+```bash
+pm2 status # Status anzeigen
+pm2 logs timeclock-backend # Logs anzeigen
+pm2 restart timeclock-backend # Neustart
+pm2 stop timeclock-backend # Stoppen
+pm2 monit # Monitoring
+```
+
+### Mit systemd:
+
+```bash
+sudo systemctl status timeclock # Status
+sudo journalctl -u timeclock -f # Logs
+sudo systemctl restart timeclock # Neustart
+sudo systemctl stop timeclock # Stoppen
+```
+
+### Nginx:
+
+```bash
+sudo nginx -t # Config testen
+sudo systemctl reload nginx # Neuladen
+sudo tail -f /var/log/nginx/stechuhr3.access.log
+sudo tail -f /var/log/nginx/stechuhr3.error.log
+```
+
+### SSL:
+
+```bash
+sudo certbot certificates # Zertifikate anzeigen
+sudo certbot renew # Erneuern
+sudo certbot renew --dry-run # Test-Erneuerung
+```
+
+---
+
+## Updates durchführen
+
+### Automatisch mit Script:
+
+```bash
+cd /var/www/timeclock
+./deploy.sh backup # Erst Backup
+./deploy.sh update # Dann Update
+```
+
+### Manuell:
+
+```bash
+# 1. Backup erstellen
+cd /var/www/timeclock
+./deploy.sh backup
+
+# 2. Code aktualisieren
+git pull # oder neue Dateien übertragen
+
+# 3. Backend
+cd backend
+npm install --production
+pm2 restart timeclock-backend
+
+# 4. Frontend
+cd ../frontend
+npm install
+npm run build
+```
+
+---
+
+## Problembehebung
+
+### Backend startet nicht
+
+```bash
+# Logs prüfen
+pm2 logs timeclock-backend --err
+
+# .env prüfen
+cat /var/www/timeclock/backend/.env
+
+# Port-Belegung prüfen
+sudo netstat -tulpn | grep 3010
+```
+
+### Frontend zeigt nicht an
+
+```bash
+# Nginx testen
+sudo nginx -t
+
+# Build-Verzeichnis prüfen
+ls -la /var/www/timeclock/frontend/dist/
+
+# Nginx neuladen
+sudo systemctl reload nginx
+```
+
+### API-Anfragen schlagen fehl
+
+```bash
+# CORS: FRONTEND_URL in .env prüfen
+# Backend muss FRONTEND_URL=https://stechuhr3.tsschulz.de haben
+
+# Nginx Proxy prüfen
+sudo nginx -t
+```
+
+### SSL-Probleme
+
+```bash
+# Zertifikat erneuern
+sudo certbot renew --force-renewal
+
+# Nginx neustarten
+sudo systemctl restart nginx
+```
+
+---
+
+## Backup & Restore
+
+### Backup erstellen:
+
+```bash
+# Automatisch
+./deploy.sh backup
+
+# Manuell - Datenbank
+mysqldump -u timeclock -p stechuhr2 | gzip > backup_$(date +%Y%m%d).sql.gz
+
+# Manuell - Code
+tar -czf backup_code_$(date +%Y%m%d).tar.gz /var/www/timeclock
+```
+
+### Restore:
+
+```bash
+# Datenbank
+gunzip < backup_20251018.sql.gz | mysql -u timeclock -p stechuhr2
+
+# Code
+./deploy.sh rollback
+```
+
+---
+
+## Performance-Tipps
+
+### PM2 Cluster-Modus (nutzt alle CPU-Kerne):
+
+```bash
+pm2 delete timeclock-backend
+pm2 start src/index.js --name timeclock-backend --instances max --env production
+pm2 save
+```
+
+### Nginx Caching aktivieren:
+
+Füge in `/etc/nginx/sites-available/stechuhr3.tsschulz.de` hinzu:
+
+```nginx
+proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api_cache:10m max_size=100m;
+
+location /api {
+ proxy_cache api_cache;
+ proxy_cache_valid 200 5m;
+ # ... rest der Config
+}
+```
+
+---
+
+## Sicherheits-Checkliste
+
+- [ ] Starke Passwörter für DB, JWT, Session
+- [ ] SSL/TLS aktiviert
+- [ ] Firewall konfiguriert
+- [ ] NODE_ENV=production
+- [ ] Console-Logs deaktiviert (Vite Build)
+- [ ] Regelmäßige Backups eingerichtet
+- [ ] fail2ban installieren (optional)
+- [ ] Rate Limiting aktivieren (optional)
+
+---
+
+## Monitoring einrichten
+
+### Einfaches Health-Check Script:
+
+```bash
+# /usr/local/bin/check-timeclock.sh
+#!/bin/bash
+if ! curl -sf http://localhost:3010/api/health > /dev/null; then
+ echo "Backend down! $(date)" >> /var/log/timeclock/health.log
+ pm2 restart timeclock-backend
+fi
+```
+
+```bash
+sudo chmod +x /usr/local/bin/check-timeclock.sh
+
+# Cronjob alle 5 Minuten
+sudo crontab -e
+# */5 * * * * /usr/local/bin/check-timeclock.sh
+```
+
+### PM2 Plus (Cloud-Monitoring):
+
+```bash
+pm2 plus
+# Link folgen und Account verbinden
+```
+
+---
+
+## Support
+
+Detaillierte Dokumentation: `DEPLOYMENT.md`
+
+Bei Problemen:
+1. Logs prüfen (`pm2 logs` oder `journalctl -u timeclock`)
+2. Nginx-Logs prüfen (`/var/log/nginx/`)
+3. Health-Check testen: `curl http://localhost:3010/api/health`
+
+---
+
+**Deployment erfolgreich! 🎉**
+
+Deine App läuft auf: **https://stechuhr3.tsschulz.de**
+
diff --git a/apache2.conf b/apache2.conf
new file mode 100644
index 0000000..c1a0d5f
--- /dev/null
+++ b/apache2.conf
@@ -0,0 +1,275 @@
+# Apache 2 VirtualHost-Konfiguration für TimeClock v3
+# Datei speichern unter: /etc/apache2/sites-available/stechuhr3.tsschulz.de.conf
+#
+# Installation:
+# sudo cp apache2.conf /etc/apache2/sites-available/stechuhr3.tsschulz.de.conf
+# sudo a2enmod proxy proxy_http ssl rewrite headers deflate expires
+# sudo a2ensite stechuhr3.tsschulz.de
+# sudo apache2ctl configtest
+# sudo systemctl reload apache2
+
+# HTTP VirtualHost - Redirect zu HTTPS
+
+ ServerName stechuhr3.tsschulz.de
+ ServerAdmin admin@tsschulz.de
+
+ # Let's Encrypt ACME Challenge
+ DocumentRoot /var/www/certbot
+
+ Require all granted
+
+
+ # Alle anderen Requests zu HTTPS umleiten
+ RewriteEngine On
+ RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/
+ RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
+
+ ErrorLog ${APACHE_LOG_DIR}/stechuhr3-error.log
+ CustomLog ${APACHE_LOG_DIR}/stechuhr3-access.log combined
+
+
+# HTTPS VirtualHost - Hauptkonfiguration
+
+ ServerName stechuhr3.tsschulz.de
+ ServerAdmin admin@tsschulz.de
+
+ # =================================================================
+ # SSL-Konfiguration (wird von Certbot automatisch verwaltet)
+ # =================================================================
+ SSLEngine on
+ SSLCertificateFile /etc/letsencrypt/live/stechuhr3.tsschulz.de/fullchain.pem
+ SSLCertificateKeyFile /etc/letsencrypt/live/stechuhr3.tsschulz.de/privkey.pem
+
+ # SSL-Protokolle und Cipher Suites
+ SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
+ SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
+ SSLHonorCipherOrder off
+ SSLSessionTickets off
+
+ # OCSP Stapling
+ SSLUseStapling on
+ SSLStaplingResponderTimeout 5
+ SSLStaplingReturnResponderErrors off
+
+ # =================================================================
+ # Frontend (Vue.js SPA)
+ # =================================================================
+ DocumentRoot /var/www/timeclock/frontend/dist
+
+
+ Options -Indexes +FollowSymLinks
+ AllowOverride All
+ Require all granted
+
+ # SPA Fallback - alle Requests zu index.html
+
+ RewriteEngine On
+ RewriteBase /
+ RewriteRule ^index\.html$ - [L]
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteCond %{REQUEST_FILENAME} !-d
+ RewriteCond %{REQUEST_URI} !^/api
+ RewriteRule . /index.html [L]
+
+
+
+ # =================================================================
+ # Gzip Compression
+ # =================================================================
+
+ AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript
+ AddOutputFilterByType DEFLATE application/javascript application/x-javascript application/json
+ AddOutputFilterByType DEFLATE application/xml application/xml+rss application/rss+xml
+ AddOutputFilterByType DEFLATE application/atom+xml
+ AddOutputFilterByType DEFLATE image/svg+xml
+ AddOutputFilterByType DEFLATE font/ttf font/woff font/woff2
+
+
+ # =================================================================
+ # Security Headers
+ # =================================================================
+
+ # X-Frame-Options: Schutz vor Clickjacking
+ Header always set X-Frame-Options "SAMEORIGIN"
+
+ # X-Content-Type-Options: Verhindert MIME-Type Sniffing
+ Header always set X-Content-Type-Options "nosniff"
+
+ # X-XSS-Protection: XSS-Schutz für ältere Browser
+ Header always set X-XSS-Protection "1; mode=block"
+
+ # Referrer-Policy: Kontrolliert Referrer-Informationen
+ Header always set Referrer-Policy "strict-origin-when-cross-origin"
+
+ # Permissions-Policy: Kontrolliert Browser-Features
+ Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
+
+ # Content-Security-Policy (angepasst für Vue.js)
+ Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https://stechuhr3.tsschulz.de;"
+
+ # Strict-Transport-Security (HSTS)
+ Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
+
+
+ # =================================================================
+ # API Reverse Proxy zum Backend
+ # =================================================================
+
+ ProxyPreserveHost On
+ ProxyRequests Off
+
+ # Timeouts
+ ProxyTimeout 60
+
+ # API Proxy
+ ProxyPass /api http://localhost:3010/api retry=0
+ ProxyPassReverse /api http://localhost:3010/api
+
+
+ # Proxy Headers
+ RequestHeader set X-Forwarded-Proto "https"
+ RequestHeader set X-Forwarded-Port "443"
+ RequestHeader set X-Real-IP %{REMOTE_ADDR}s
+
+ # CORS Headers (falls benötigt, aber Backend sollte das handhaben)
+ # Header set Access-Control-Allow-Origin "https://stechuhr3.tsschulz.de"
+ # Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
+ # Header set Access-Control-Allow-Headers "Content-Type, Authorization"
+ # Header set Access-Control-Allow-Credentials "true"
+
+
+
+ # =================================================================
+ # Statische Assets mit langem Cache
+ # =================================================================
+
+ ExpiresActive On
+
+ # JavaScript und CSS
+ ExpiresByType text/css "access plus 1 year"
+ ExpiresByType text/javascript "access plus 1 year"
+ ExpiresByType application/javascript "access plus 1 year"
+ ExpiresByType application/x-javascript "access plus 1 year"
+
+ # Bilder
+ ExpiresByType image/jpeg "access plus 1 year"
+ ExpiresByType image/jpg "access plus 1 year"
+ ExpiresByType image/png "access plus 1 year"
+ ExpiresByType image/gif "access plus 1 year"
+ ExpiresByType image/webp "access plus 1 year"
+ ExpiresByType image/svg+xml "access plus 1 year"
+ ExpiresByType image/x-icon "access plus 1 year"
+
+ # Fonts
+ ExpiresByType font/ttf "access plus 1 year"
+ ExpiresByType font/woff "access plus 1 year"
+ ExpiresByType font/woff2 "access plus 1 year"
+ ExpiresByType application/font-woff "access plus 1 year"
+ ExpiresByType application/font-woff2 "access plus 1 year"
+
+ # HTML (kein Cache)
+ ExpiresByType text/html "access plus 0 seconds"
+
+
+ # Cache-Control Headers für Assets
+
+
+ Header set Cache-Control "public, max-age=31536000, immutable"
+
+
+
+ # Kein Cache für HTML
+
+
+ Header set Cache-Control "no-cache, no-store, must-revalidate"
+ Header set Pragma "no-cache"
+ Header set Expires "0"
+
+
+
+ # =================================================================
+ # Spezielle Dateien
+ # =================================================================
+ # robots.txt und sitemap.xml
+
+
+ Header set Cache-Control "public, max-age=86400"
+
+
+
+ # =================================================================
+ # Sicherheit: Verstecke sensible Dateien
+ # =================================================================
+ # Blockiere Zugriff auf versteckte Dateien (.git, .env, etc.)
+
+ Require all denied
+
+
+
+ Require all denied
+
+
+ # Blockiere Zugriff auf Backup-Dateien
+
+ Require all denied
+
+
+ # Blockiere .env Dateien
+
+ Require all denied
+
+
+ # =================================================================
+ # Limits
+ # =================================================================
+ # Client Body Size Limit (z.B. für File-Uploads)
+ LimitRequestBody 10485760
+
+ # Timeouts
+ TimeOut 300
+
+ # =================================================================
+ # Logging
+ # =================================================================
+ ErrorLog ${APACHE_LOG_DIR}/stechuhr3-error.log
+ CustomLog ${APACHE_LOG_DIR}/stechuhr3-access.log combined
+
+ # Optional: Log-Level für detailliertere Logs
+ # LogLevel info ssl:warn proxy:debug
+
+
+# =================================================================
+# Globale SSL-Konfiguration (optional, in /etc/apache2/mods-available/ssl.conf)
+# =================================================================
+#
+# # OCSP Stapling Cache
+# SSLStaplingCache shmcb:/var/run/ocsp(128000)
+#
+# # SSL Session Cache
+# SSLSessionCache shmcb:/var/run/ssl_scache(512000)
+# SSLSessionCacheTimeout 300
+#
+
+# =================================================================
+# OPTIONAL: Rate Limiting mit mod_evasive
+# =================================================================
+# Installieren mit: sudo apt install libapache2-mod-evasive
+# Dann konfigurieren in: /etc/apache2/mods-available/evasive.conf
+#
+#
+# DOSHashTableSize 3097
+# DOSPageCount 5
+# DOSSiteCount 100
+# DOSPageInterval 1
+# DOSSiteInterval 1
+# DOSBlockingPeriod 10
+# DOSEmailNotify admin@tsschulz.de
+# DOSLogDir /var/log/apache2/mod_evasive
+#
+
+# =================================================================
+# OPTIONAL: Zusätzliche Security mit mod_security
+# =================================================================
+# Installieren mit: sudo apt install libapache2-mod-security2
+# Konfiguration in: /etc/modsecurity/modsecurity.conf
+
diff --git a/backend/env.production.template b/backend/env.production.template
new file mode 100644
index 0000000..6d2e62f
--- /dev/null
+++ b/backend/env.production.template
@@ -0,0 +1,90 @@
+# TimeClock v3 - Production Environment Configuration
+# Kopiere diese Datei zu .env und passe die Werte an:
+# cp env.production.template .env
+
+# =============================================================================
+# NODE ENVIRONMENT
+# =============================================================================
+NODE_ENV=production
+PORT=3010
+
+# =============================================================================
+# DATABASE CONFIGURATION
+# =============================================================================
+DB_HOST=tsschulz.de
+DB_PORT=3306
+DB_NAME=stechuhr2
+DB_USER=stechuhr2
+DB_PASSWORD=p3Lv9!7?+Qq
+
+# =============================================================================
+# JWT AUTHENTICATION
+# =============================================================================
+# Generiere einen sicheren Secret mit: node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"
+JWT_SECRET=f393b1159fd0212df164711112bc72edf9481181b719de6bc61e4654885a6269ecf95dca0568a27081fa68b039e4de7cffcb4c9a8927bcddaf54dc869899f6e8
+JWT_EXPIRES_IN=7d
+JWT_REFRESH_EXPIRES_IN=30d
+
+# =============================================================================
+# SESSION CONFIGURATION
+# =============================================================================
+# Generiere einen sicheren Secret mit: node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"
+SESSION_SECRET=f393b1159fd0212df164711112bc72edf9481181b719de6bc61e4654885a6269ecf95dca0568a27081fa68b039e4de7cffcb4c9a8927bcddaf54dc869899f6e8
+
+# =============================================================================
+# FRONTEND URL
+# =============================================================================
+FRONTEND_URL=https://stechuhr3.tsschulz.de
+
+# =============================================================================
+# EMAIL CONFIGURATION (für Passwort-Reset etc.)
+# =============================================================================
+# SMTP-Server Konfiguration
+EMAIL_HOST=smtp.1blu.de
+EMAIL_PORT=587
+EMAIL_SECURE=true
+EMAIL_USER=e226079_0-kontakt
+EMAIL_PASSWORD=aNN31bll3Na!
+EMAIL_FROM=kontakt@tsschulz.de
+EMAIL_FROM_NAME=TimeClock Zeiterfassung
+
+# =============================================================================
+# OAUTH CONFIGURATION (Google OAuth)
+# =============================================================================
+# Optional: Falls Google OAuth verwendet werden soll
+# Erstelle OAuth Credentials unter: https://console.cloud.google.com/
+GOOGLE_CLIENT_ID=your-google-client-id.apps.googleusercontent.com
+GOOGLE_CLIENT_SECRET=your-google-client-secret
+GOOGLE_CALLBACK_URL=https://stechuhr3.tsschulz.de/api/auth/oauth/google/callback
+
+# =============================================================================
+# SECURITY & CORS
+# =============================================================================
+# Allowed Origins (comma-separated, falls mehrere Domains)
+ALLOWED_ORIGINS=https://stechuhr3.tsschulz.de
+
+# =============================================================================
+# LOGGING
+# =============================================================================
+LOG_LEVEL=info
+# Optionen: error, warn, info, http, verbose, debug, silly
+
+# =============================================================================
+# APPLICATION SETTINGS
+# =============================================================================
+# Maximale Dateigröße für Uploads (falls implementiert)
+MAX_FILE_SIZE=5242880
+
+# Rate Limiting (Anfragen pro Fenster)
+RATE_LIMIT_WINDOW_MS=900000
+RATE_LIMIT_MAX_REQUESTS=100
+
+# =============================================================================
+# BACKUP CONFIGURATION (Optional)
+# =============================================================================
+# Backup-Verzeichnis
+BACKUP_DIR=/var/backups/timeclock
+
+# Backup-Retention in Tagen
+BACKUP_RETENTION_DAYS=30
+
diff --git a/deploy.sh b/deploy.sh
new file mode 100755
index 0000000..c4d1112
--- /dev/null
+++ b/deploy.sh
@@ -0,0 +1,663 @@
+#!/bin/bash
+
+# =============================================================================
+# TimeClock v3 - Deployment Script für Ubuntu 22.04
+# =============================================================================
+# Dieses Script automatisiert das Deployment auf dem Produktionsserver
+#
+# Verwendung:
+# ./deploy.sh [OPTION]
+#
+# Optionen:
+# install - Erste Installation (inkl. System-Setup)
+# update - Update einer bestehenden Installation
+# rollback - Rollback zur vorherigen Version
+# backup - Erstelle Backup der Datenbank
+# status - Zeige Status der Services
+# logs - Zeige Logs
+# help - Zeige diese Hilfe
+#
+# =============================================================================
+
+set -e # Bei Fehler abbrechen
+
+# Farben für Output
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+NC='\033[0m' # No Color
+
+# Konfiguration
+PROJECT_NAME="TimeClock"
+PROJECT_DIR="/var/www/timeclock"
+BACKEND_DIR="$PROJECT_DIR/backend"
+FRONTEND_DIR="$PROJECT_DIR/frontend"
+DOMAIN="stechuhr3.tsschulz.de"
+BACKUP_DIR="/var/backups/timeclock"
+LOG_DIR="/var/log/timeclock"
+
+# Service-Name (PM2 oder systemd)
+USE_PM2=true # true für PM2, false für systemd
+SERVICE_NAME="timeclock"
+
+# Webserver (nginx oder apache2)
+WEBSERVER="apache2" # "nginx" oder "apache2"
+
+# =============================================================================
+# Hilfsfunktionen
+# =============================================================================
+
+print_info() {
+ echo -e "${BLUE}ℹ️ $1${NC}"
+}
+
+print_success() {
+ echo -e "${GREEN}✅ $1${NC}"
+}
+
+print_warning() {
+ echo -e "${YELLOW}⚠️ $1${NC}"
+}
+
+print_error() {
+ echo -e "${RED}❌ $1${NC}"
+}
+
+print_header() {
+ echo ""
+ echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}"
+ echo -e "${BLUE} $1${NC}"
+ echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}"
+ echo ""
+}
+
+check_root() {
+ if [ "$EUID" -eq 0 ]; then
+ print_error "Bitte führe dieses Script NICHT als root aus!"
+ print_info "Verwende stattdessen sudo für einzelne Befehle."
+ exit 1
+ fi
+}
+
+check_command() {
+ if ! command -v $1 &> /dev/null; then
+ print_error "$1 ist nicht installiert!"
+ return 1
+ fi
+ return 0
+}
+
+# =============================================================================
+# Installation - Erste Einrichtung
+# =============================================================================
+
+install_dependencies() {
+ print_header "Installiere System-Abhängigkeiten"
+
+ print_info "Aktualisiere Paketquellen..."
+ sudo apt update
+
+ print_info "Installiere Node.js 20.x..."
+ if ! check_command node; then
+ curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
+ sudo apt install -y nodejs
+ else
+ print_success "Node.js ist bereits installiert ($(node -v))"
+ fi
+
+ if [ "$WEBSERVER" = "nginx" ]; then
+ print_info "Installiere Nginx..."
+ if ! check_command nginx; then
+ sudo apt install -y nginx
+ else
+ print_success "Nginx ist bereits installiert"
+ fi
+ else
+ print_info "Installiere Apache2..."
+ if ! check_command apache2; then
+ sudo apt install -y apache2
+ else
+ print_success "Apache2 ist bereits installiert"
+ fi
+
+ print_info "Aktiviere Apache2-Module..."
+ sudo a2enmod proxy proxy_http ssl rewrite headers deflate expires
+ fi
+
+ print_info "Installiere Certbot..."
+ if ! check_command certbot; then
+ if [ "$WEBSERVER" = "nginx" ]; then
+ sudo apt install -y certbot python3-certbot-nginx
+ else
+ sudo apt install -y certbot python3-certbot-apache
+ fi
+ else
+ print_success "Certbot ist bereits installiert"
+ fi
+
+ if [ "$USE_PM2" = true ]; then
+ print_info "Installiere PM2..."
+ if ! check_command pm2; then
+ sudo npm install -g pm2
+ else
+ print_success "PM2 ist bereits installiert"
+ fi
+ fi
+
+ print_success "Alle Abhängigkeiten installiert!"
+}
+
+setup_directories() {
+ print_header "Erstelle Verzeichnisse"
+
+ print_info "Erstelle Projekt-Verzeichnis..."
+ sudo mkdir -p $PROJECT_DIR
+ sudo chown -R $USER:$USER $PROJECT_DIR
+
+ print_info "Erstelle Log-Verzeichnis..."
+ sudo mkdir -p $LOG_DIR
+ sudo chown -R www-data:www-data $LOG_DIR
+
+ print_info "Erstelle Backup-Verzeichnis..."
+ sudo mkdir -p $BACKUP_DIR
+ sudo chown -R $USER:$USER $BACKUP_DIR
+
+ print_success "Verzeichnisse erstellt!"
+}
+
+copy_project_files() {
+ print_header "Kopiere Projekt-Dateien"
+
+ CURRENT_DIR=$(pwd)
+
+ print_info "Kopiere Backend..."
+ rsync -a --exclude 'node_modules' "$CURRENT_DIR/backend/" "$BACKEND_DIR/"
+
+ print_info "Kopiere Frontend..."
+ rsync -a --exclude 'node_modules' --exclude 'dist' "$CURRENT_DIR/frontend/" "$FRONTEND_DIR/"
+
+ print_success "Projekt-Dateien kopiert!"
+}
+
+setup_backend() {
+ print_header "Setup Backend"
+
+ cd $BACKEND_DIR
+
+ print_info "Installiere Backend-Dependencies..."
+ npm install --production
+
+ if [ ! -f .env ]; then
+ print_warning ".env Datei nicht gefunden!"
+ if [ -f env.production.template ]; then
+ print_info "Kopiere Template..."
+ cp env.production.template .env
+ print_warning "WICHTIG: Bitte bearbeite $BACKEND_DIR/.env und passe die Werte an!"
+ read -p "Drücke Enter wenn du fertig bist..."
+ else
+ print_error "Auch env.production.template nicht gefunden!"
+ exit 1
+ fi
+ else
+ print_success ".env bereits vorhanden"
+ fi
+
+ print_success "Backend Setup abgeschlossen!"
+}
+
+setup_frontend() {
+ print_header "Setup Frontend"
+
+ cd $FRONTEND_DIR
+
+ print_info "Installiere Frontend-Dependencies..."
+ npm install
+
+ print_info "Erstelle Produktions-Build..."
+ npm run build
+
+ if [ ! -d "dist" ]; then
+ print_error "Build fehlgeschlagen - dist/ Verzeichnis nicht gefunden!"
+ exit 1
+ fi
+
+ print_success "Frontend Build erstellt!"
+}
+
+setup_webserver() {
+ if [ "$WEBSERVER" = "nginx" ]; then
+ print_header "Setup Nginx"
+
+ WEBSERVER_CONF="/etc/nginx/sites-available/$DOMAIN"
+
+ if [ ! -f "$WEBSERVER_CONF" ]; then
+ print_info "Kopiere Nginx-Konfiguration..."
+ sudo cp "$PROJECT_DIR/nginx.conf" "$WEBSERVER_CONF"
+
+ print_info "Aktiviere Site..."
+ sudo ln -sf "$WEBSERVER_CONF" "/etc/nginx/sites-enabled/$DOMAIN"
+
+ print_info "Teste Nginx-Konfiguration..."
+ sudo nginx -t
+
+ print_info "Lade Nginx neu..."
+ sudo systemctl reload nginx
+
+ print_success "Nginx konfiguriert!"
+ else
+ print_warning "Nginx-Konfiguration existiert bereits"
+ read -p "Überschreiben? (y/N): " -n 1 -r
+ echo
+ if [[ $REPLY =~ ^[Yy]$ ]]; then
+ sudo cp "$PROJECT_DIR/nginx.conf" "$WEBSERVER_CONF"
+ sudo nginx -t && sudo systemctl reload nginx
+ print_success "Nginx-Konfiguration aktualisiert!"
+ fi
+ fi
+ else
+ print_header "Setup Apache2"
+
+ WEBSERVER_CONF="/etc/apache2/sites-available/$DOMAIN.conf"
+
+ if [ ! -f "$WEBSERVER_CONF" ]; then
+ print_info "Kopiere Apache2-Konfiguration..."
+ sudo cp "$PROJECT_DIR/apache2.conf" "$WEBSERVER_CONF"
+
+ print_info "Aktiviere Site..."
+ sudo a2ensite "$DOMAIN"
+
+ # Deaktiviere Default-Site (optional)
+ if [ -f "/etc/apache2/sites-enabled/000-default.conf" ]; then
+ print_info "Deaktiviere Default-Site..."
+ sudo a2dissite 000-default
+ fi
+
+ print_info "Teste Apache2-Konfiguration..."
+ sudo apache2ctl configtest
+
+ print_info "Lade Apache2 neu..."
+ sudo systemctl reload apache2
+
+ print_success "Apache2 konfiguriert!"
+ else
+ print_warning "Apache2-Konfiguration existiert bereits"
+ read -p "Überschreiben? (y/N): " -n 1 -r
+ echo
+ if [[ $REPLY =~ ^[Yy]$ ]]; then
+ sudo cp "$PROJECT_DIR/apache2.conf" "$WEBSERVER_CONF"
+ sudo apache2ctl configtest && sudo systemctl reload apache2
+ print_success "Apache2-Konfiguration aktualisiert!"
+ fi
+ fi
+ fi
+}
+
+setup_ssl() {
+ print_header "Setup SSL-Zertifikat"
+
+ print_info "Prüfe ob Zertifikat bereits existiert..."
+ if [ -d "/etc/letsencrypt/live/$DOMAIN" ]; then
+ print_success "SSL-Zertifikat bereits vorhanden"
+ return
+ fi
+
+ print_warning "Stelle sicher, dass $DOMAIN auf diesen Server zeigt!"
+ read -p "Fortfahren? (y/N): " -n 1 -r
+ echo
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
+ print_info "SSL-Setup übersprungen"
+ return
+ fi
+
+ print_info "Erstelle SSL-Zertifikat mit Let's Encrypt..."
+ if [ "$WEBSERVER" = "nginx" ]; then
+ sudo certbot --nginx -d $DOMAIN
+ else
+ sudo certbot --apache -d $DOMAIN
+ fi
+
+ print_success "SSL-Zertifikat erstellt!"
+}
+
+setup_backend_service() {
+ print_header "Setup Backend-Service"
+
+ if [ "$USE_PM2" = true ]; then
+ print_info "Starte Backend mit PM2..."
+ cd $BACKEND_DIR
+ pm2 delete $SERVICE_NAME 2>/dev/null || true
+ pm2 start src/index.js --name $SERVICE_NAME --env production
+ pm2 save
+
+ print_info "Richte PM2 Auto-Start ein..."
+ sudo env PATH=$PATH:/usr/bin pm2 startup systemd -u $USER --hp $HOME
+
+ print_success "Backend läuft mit PM2!"
+ else
+ print_info "Installiere systemd-Service..."
+ sudo cp "$PROJECT_DIR/timeclock.service" /etc/systemd/system/
+
+ sudo systemctl daemon-reload
+ sudo systemctl enable $SERVICE_NAME
+ sudo systemctl start $SERVICE_NAME
+
+ print_success "Backend läuft mit systemd!"
+ fi
+}
+
+setup_firewall() {
+ print_header "Setup Firewall"
+
+ if ! check_command ufw; then
+ print_warning "UFW nicht installiert, überspringe Firewall-Setup"
+ return
+ fi
+
+ print_info "Konfiguriere UFW..."
+ sudo ufw allow ssh
+ if [ "$WEBSERVER" = "nginx" ]; then
+ sudo ufw allow 'Nginx Full'
+ else
+ sudo ufw allow 'Apache Full'
+ fi
+
+ if ! sudo ufw status | grep -q "Status: active"; then
+ print_warning "UFW ist nicht aktiv"
+ read -p "UFW aktivieren? (y/N): " -n 1 -r
+ echo
+ if [[ $REPLY =~ ^[Yy]$ ]]; then
+ sudo ufw --force enable
+ print_success "UFW aktiviert!"
+ fi
+ else
+ print_success "UFW bereits konfiguriert"
+ fi
+}
+
+# =============================================================================
+# Update - Aktualisierung einer bestehenden Installation
+# =============================================================================
+
+do_update() {
+ print_header "Update $PROJECT_NAME"
+
+ # Backup erstellen
+ do_backup
+
+ # Backend aktualisieren
+ print_info "Aktualisiere Backend..."
+ cd $BACKEND_DIR
+ npm install --production
+
+ # Frontend neu bauen
+ print_info "Aktualisiere Frontend..."
+ cd $FRONTEND_DIR
+ npm install
+ npm run build
+
+ # Service neu starten
+ restart_backend
+
+ print_success "Update abgeschlossen!"
+}
+
+# =============================================================================
+# Backup & Rollback
+# =============================================================================
+
+do_backup() {
+ print_header "Erstelle Backup"
+
+ TIMESTAMP=$(date +%Y%m%d_%H%M%S)
+
+ print_info "Erstelle Datenbank-Backup..."
+ # Lese DB-Credentials aus .env
+ DB_NAME=$(grep DB_NAME $BACKEND_DIR/.env | cut -d '=' -f2)
+ DB_USER=$(grep DB_USER $BACKEND_DIR/.env | cut -d '=' -f2)
+ DB_PASSWORD=$(grep DB_PASSWORD $BACKEND_DIR/.env | cut -d '=' -f2)
+
+ mysqldump -u $DB_USER -p"$DB_PASSWORD" $DB_NAME | gzip > "$BACKUP_DIR/${PROJECT_NAME,,}_$TIMESTAMP.sql.gz"
+
+ print_info "Erstelle Code-Backup..."
+ tar -czf "$BACKUP_DIR/${PROJECT_NAME,,}_code_$TIMESTAMP.tar.gz" -C $(dirname $PROJECT_DIR) $(basename $PROJECT_DIR)
+
+ # Alte Backups löschen (älter als 30 Tage)
+ find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete
+ find $BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete
+
+ print_success "Backup erstellt: $TIMESTAMP"
+}
+
+do_rollback() {
+ print_header "Rollback zu vorheriger Version"
+
+ print_warning "Rollback wird die letzte Code-Version wiederherstellen"
+ read -p "Fortfahren? (y/N): " -n 1 -r
+ echo
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
+ print_info "Rollback abgebrochen"
+ return
+ fi
+
+ # Finde letztes Code-Backup
+ LAST_BACKUP=$(ls -t $BACKUP_DIR/${PROJECT_NAME,,}_code_*.tar.gz 2>/dev/null | head -n1)
+
+ if [ -z "$LAST_BACKUP" ]; then
+ print_error "Kein Backup gefunden!"
+ exit 1
+ fi
+
+ print_info "Stelle wieder her: $LAST_BACKUP"
+
+ # Aktuellen Code sichern
+ mv $PROJECT_DIR "${PROJECT_DIR}_rollback_backup_$(date +%Y%m%d_%H%M%S)"
+
+ # Backup wiederherstellen
+ tar -xzf "$LAST_BACKUP" -C $(dirname $PROJECT_DIR)
+
+ # Services neu starten
+ restart_backend
+
+ print_success "Rollback abgeschlossen!"
+}
+
+# =============================================================================
+# Service Management
+# =============================================================================
+
+restart_backend() {
+ print_info "Starte Backend neu..."
+
+ if [ "$USE_PM2" = true ]; then
+ pm2 restart $SERVICE_NAME
+ else
+ sudo systemctl restart $SERVICE_NAME
+ fi
+
+ print_success "Backend neu gestartet!"
+}
+
+show_status() {
+ print_header "Service Status"
+
+ if [ "$USE_PM2" = true ]; then
+ pm2 status $SERVICE_NAME
+ echo ""
+ pm2 info $SERVICE_NAME
+ else
+ sudo systemctl status $SERVICE_NAME
+ fi
+
+ echo ""
+ if [ "$WEBSERVER" = "nginx" ]; then
+ print_info "Nginx Status:"
+ sudo systemctl status nginx --no-pager | head -n 10
+ else
+ print_info "Apache2 Status:"
+ sudo systemctl status apache2 --no-pager | head -n 10
+ fi
+
+ echo ""
+ print_info "SSL-Zertifikat:"
+ sudo certbot certificates | grep -A 5 $DOMAIN || print_warning "Kein Zertifikat gefunden"
+}
+
+show_logs() {
+ print_header "Logs"
+
+ echo "1) Backend-Logs"
+ echo "2) Webserver Access-Logs"
+ echo "3) Webserver Error-Logs"
+ echo "4) Alle Logs (follow)"
+ read -p "Auswahl (1-4): " choice
+
+ if [ "$WEBSERVER" = "nginx" ]; then
+ ACCESS_LOG="/var/log/nginx/stechuhr3.access.log"
+ ERROR_LOG="/var/log/nginx/stechuhr3.error.log"
+ else
+ ACCESS_LOG="/var/log/apache2/stechuhr3-access.log"
+ ERROR_LOG="/var/log/apache2/stechuhr3-error.log"
+ fi
+
+ case $choice in
+ 1)
+ if [ "$USE_PM2" = true ]; then
+ pm2 logs $SERVICE_NAME
+ else
+ sudo journalctl -u $SERVICE_NAME -f
+ fi
+ ;;
+ 2)
+ sudo tail -f "$ACCESS_LOG"
+ ;;
+ 3)
+ sudo tail -f "$ERROR_LOG"
+ ;;
+ 4)
+ if [ "$USE_PM2" = true ]; then
+ pm2 logs $SERVICE_NAME &
+ PM2_PID=$!
+ else
+ sudo journalctl -u $SERVICE_NAME -f &
+ JOURNAL_PID=$!
+ fi
+ if [ "$WEBSERVER" = "nginx" ]; then
+ sudo tail -f /var/log/nginx/stechuhr3.*.log
+ else
+ sudo tail -f /var/log/apache2/stechuhr3-*.log
+ fi
+ ;;
+ *)
+ print_error "Ungültige Auswahl"
+ ;;
+ esac
+}
+
+# =============================================================================
+# Vollständige Installation
+# =============================================================================
+
+do_install() {
+ print_header "$PROJECT_NAME - Vollständige Installation"
+
+ check_root
+
+ print_warning "Diese Installation wird folgendes tun:"
+ echo " - System-Abhängigkeiten installieren"
+ echo " - Projekt nach $PROJECT_DIR kopieren"
+ echo " - Backend und Frontend einrichten"
+ echo " - Nginx konfigurieren"
+ echo " - SSL-Zertifikat erstellen"
+ echo " - Backend-Service starten"
+ echo " - Firewall konfigurieren"
+ echo ""
+ read -p "Fortfahren? (y/N): " -n 1 -r
+ echo
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
+ print_info "Installation abgebrochen"
+ exit 0
+ fi
+
+ install_dependencies
+ setup_directories
+ copy_project_files
+ setup_backend
+ setup_frontend
+ setup_webserver
+ setup_ssl
+ setup_backend_service
+ setup_firewall
+
+ print_header "Installation abgeschlossen! 🎉"
+ print_success "Deine TimeClock-App läuft jetzt auf https://$DOMAIN"
+ echo ""
+ print_info "Nützliche Befehle:"
+ echo " ./deploy.sh status - Zeige Service-Status"
+ echo " ./deploy.sh logs - Zeige Logs"
+ echo " ./deploy.sh update - Update durchführen"
+ echo " ./deploy.sh backup - Backup erstellen"
+ echo ""
+}
+
+# =============================================================================
+# Hauptprogramm
+# =============================================================================
+
+show_help() {
+ cat << EOF
+$PROJECT_NAME v3 - Deployment Script
+
+Verwendung: $0 [OPTION]
+
+Optionen:
+ install Erste Installation (inkl. System-Setup)
+ update Update einer bestehenden Installation
+ rollback Rollback zur vorherigen Version
+ backup Erstelle Backup der Datenbank
+ status Zeige Status der Services
+ logs Zeige Logs
+ help Zeige diese Hilfe
+
+Beispiele:
+ $0 install # Erste Installation
+ $0 update # Update durchführen
+ $0 backup # Backup erstellen
+ $0 status # Status anzeigen
+
+EOF
+}
+
+# Hauptlogik
+case "${1:-help}" in
+ install)
+ do_install
+ ;;
+ update)
+ do_update
+ ;;
+ rollback)
+ do_rollback
+ ;;
+ backup)
+ do_backup
+ ;;
+ status)
+ show_status
+ ;;
+ logs)
+ show_logs
+ ;;
+ help|--help|-h)
+ show_help
+ ;;
+ *)
+ print_error "Unbekannte Option: $1"
+ echo ""
+ show_help
+ exit 1
+ ;;
+esac
+
+exit 0
+
diff --git a/ecosystem.config.js b/ecosystem.config.js
new file mode 100644
index 0000000..bbbfb13
--- /dev/null
+++ b/ecosystem.config.js
@@ -0,0 +1,98 @@
+// PM2 Ecosystem File für TimeClock v3
+// Verwendung:
+// pm2 start ecosystem.config.js
+// pm2 start ecosystem.config.js --env production
+// pm2 stop timeclock-backend
+// pm2 restart timeclock-backend
+// pm2 logs timeclock-backend
+// pm2 monit
+
+module.exports = {
+ apps: [
+ {
+ // Backend-API
+ name: 'timeclock-backend',
+ cwd: '/var/www/timeclock/backend',
+ script: 'src/index.js',
+
+ // Instanzen (1 = single, 0 oder 'max' = alle CPU-Kerne)
+ instances: 1,
+ exec_mode: 'fork', // 'fork' oder 'cluster'
+
+ // Environment
+ env: {
+ NODE_ENV: 'development',
+ PORT: 3010
+ },
+ env_production: {
+ NODE_ENV: 'production',
+ PORT: 3010
+ },
+
+ // Auto-Restart
+ watch: false, // In Produktion false
+ watch_delay: 1000,
+ ignore_watch: [
+ 'node_modules',
+ 'logs',
+ '*.log'
+ ],
+
+ // Restart-Verhalten
+ autorestart: true,
+ max_restarts: 10,
+ min_uptime: '10s',
+ restart_delay: 4000,
+
+ // Limits
+ max_memory_restart: '500M',
+
+ // Logs
+ log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
+ error_file: '/var/log/timeclock/pm2-error.log',
+ out_file: '/var/log/timeclock/pm2-out.log',
+ log_file: '/var/log/timeclock/pm2-combined.log',
+
+ // Merge Logs (alle Instanzen in eine Datei)
+ merge_logs: true,
+
+ // Source Maps Support
+ source_map_support: false,
+
+ // Graceful Shutdown
+ kill_timeout: 5000,
+ wait_ready: false,
+ listen_timeout: 10000,
+
+ // Process Management
+ pid_file: '/var/run/timeclock-backend.pid',
+
+ // Cron Restart (optional)
+ // cron_restart: '0 2 * * *', // Täglich um 2 Uhr neustarten
+
+ // Monitoring
+ instance_var: 'INSTANCE_ID',
+
+ // Post-Deployment-Hooks (optional)
+ post_update: [
+ 'npm install --production',
+ 'echo "Backend updated"'
+ ]
+ }
+ ],
+
+ // Deployment-Konfiguration (optional, für pm2 deploy)
+ deploy: {
+ production: {
+ user: 'torsten',
+ host: 'stechuhr3.tsschulz.de',
+ ref: 'origin/main',
+ repo: 'git@github.com:IHR-USERNAME/TimeClock.git',
+ path: '/var/www/timeclock',
+ 'pre-deploy-local': '',
+ 'post-deploy': 'cd backend && npm install --production && pm2 reload ecosystem.config.js --env production',
+ 'pre-setup': ''
+ }
+ }
+};
+
diff --git a/frontend/vite.config.js b/frontend/vite.config.js
index b24888a..56195d7 100644
--- a/frontend/vite.config.js
+++ b/frontend/vite.config.js
@@ -17,6 +17,31 @@ export default defineConfig({
changeOrigin: true
}
}
- }
+ },
+ build: {
+ // Produktions-Build-Optimierungen
+ target: 'es2015',
+ outDir: 'dist',
+ assetsDir: 'assets',
+ sourcemap: false,
+ minify: 'terser',
+ terserOptions: {
+ compress: {
+ drop_console: true, // Console-Logs in Produktion entfernen
+ drop_debugger: true
+ }
+ },
+ rollupOptions: {
+ output: {
+ manualChunks: {
+ // Code-Splitting für bessere Performance
+ 'vue-vendor': ['vue', 'vue-router', 'pinia']
+ }
+ }
+ },
+ chunkSizeWarningLimit: 1000
+ },
+ // Base-URL für Produktion
+ base: '/'
})
diff --git a/nginx.conf b/nginx.conf
new file mode 100644
index 0000000..d712a52
--- /dev/null
+++ b/nginx.conf
@@ -0,0 +1,262 @@
+# Nginx-Konfiguration für TimeClock v3
+# Datei speichern unter: /etc/nginx/sites-available/stechuhr3.tsschulz.de
+#
+# Installation:
+# sudo cp nginx.conf /etc/nginx/sites-available/stechuhr3.tsschulz.de
+# sudo ln -s /etc/nginx/sites-available/stechuhr3.tsschulz.de /etc/nginx/sites-enabled/
+# sudo nginx -t
+# sudo systemctl reload nginx
+
+# HTTP Server - Redirect zu HTTPS
+server {
+ listen 80;
+ listen [::]:80;
+ server_name stechuhr3.tsschulz.de;
+
+ # Let's Encrypt ACME Challenge
+ location /.well-known/acme-challenge/ {
+ root /var/www/certbot;
+ }
+
+ # Alle anderen Requests zu HTTPS umleiten
+ location / {
+ return 301 https://$server_name$request_uri;
+ }
+}
+
+# HTTPS Server - Hauptkonfiguration
+server {
+ listen 443 ssl http2;
+ listen [::]:443 ssl http2;
+ server_name stechuhr3.tsschulz.de;
+
+ # =================================================================
+ # SSL-Konfiguration (wird von Certbot automatisch verwaltet)
+ # =================================================================
+ ssl_certificate /etc/letsencrypt/live/stechuhr3.tsschulz.de/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/stechuhr3.tsschulz.de/privkey.pem;
+
+ # SSL-Protokolle und Ciphers
+ ssl_protocols TLSv1.2 TLSv1.3;
+ ssl_prefer_server_ciphers on;
+ ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
+
+ # SSL-Session-Cache
+ ssl_session_cache shared:SSL:10m;
+ ssl_session_timeout 10m;
+ ssl_session_tickets off;
+
+ # OCSP Stapling
+ ssl_stapling on;
+ ssl_stapling_verify on;
+ ssl_trusted_certificate /etc/letsencrypt/live/stechuhr3.tsschulz.de/chain.pem;
+ resolver 8.8.8.8 8.8.4.4 valid=300s;
+ resolver_timeout 5s;
+
+ # =================================================================
+ # Frontend (Vue.js SPA)
+ # =================================================================
+ root /var/www/timeclock/frontend/dist;
+ index index.html;
+
+ # =================================================================
+ # Logging
+ # =================================================================
+ access_log /var/log/nginx/stechuhr3.access.log;
+ error_log /var/log/nginx/stechuhr3.error.log warn;
+
+ # =================================================================
+ # Gzip Compression
+ # =================================================================
+ gzip on;
+ gzip_vary on;
+ gzip_proxied any;
+ gzip_comp_level 6;
+ gzip_min_length 1024;
+ gzip_types
+ text/plain
+ text/css
+ text/xml
+ text/javascript
+ application/javascript
+ application/x-javascript
+ application/json
+ application/xml
+ application/xml+rss
+ application/rss+xml
+ application/atom+xml
+ image/svg+xml
+ font/ttf
+ font/woff
+ font/woff2;
+
+ # =================================================================
+ # Security Headers
+ # =================================================================
+ # X-Frame-Options: Schutz vor Clickjacking
+ add_header X-Frame-Options "SAMEORIGIN" always;
+
+ # X-Content-Type-Options: Verhindert MIME-Type Sniffing
+ add_header X-Content-Type-Options "nosniff" always;
+
+ # X-XSS-Protection: XSS-Schutz für ältere Browser
+ add_header X-XSS-Protection "1; mode=block" always;
+
+ # Referrer-Policy: Kontrolliert Referrer-Informationen
+ add_header Referrer-Policy "strict-origin-when-cross-origin" always;
+
+ # Permissions-Policy: Kontrolliert Browser-Features
+ add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
+
+ # Content-Security-Policy (angepasst für Vue.js)
+ # Kann bei Bedarf verschärft werden
+ add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https://stechuhr3.tsschulz.de;" always;
+
+ # Strict-Transport-Security (HSTS)
+ add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
+
+ # =================================================================
+ # API Reverse Proxy zum Backend
+ # =================================================================
+ location /api {
+ # Proxy Pass zum Backend auf localhost:3010
+ proxy_pass http://localhost:3010;
+
+ # HTTP Version
+ proxy_http_version 1.1;
+
+ # WebSocket Support (falls später benötigt)
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection 'upgrade';
+
+ # Standard Proxy Headers
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header X-Forwarded-Host $server_name;
+
+ # Cache Bypass
+ proxy_cache_bypass $http_upgrade;
+
+ # Timeouts
+ proxy_connect_timeout 60s;
+ proxy_send_timeout 60s;
+ proxy_read_timeout 60s;
+
+ # Buffer-Einstellungen
+ proxy_buffering on;
+ proxy_buffer_size 4k;
+ proxy_buffers 8 4k;
+ proxy_busy_buffers_size 8k;
+
+ # Fehlerbehandlung
+ proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
+ proxy_next_upstream_tries 2;
+ }
+
+ # =================================================================
+ # Statische Assets mit langem Cache
+ # =================================================================
+ location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|webp|avif)$ {
+ expires 1y;
+ add_header Cache-Control "public, immutable";
+ access_log off;
+ }
+
+ # Font-Dateien mit langem Cache
+ location ~* \.(woff|woff2|ttf|eot)$ {
+ expires 1y;
+ add_header Cache-Control "public, immutable";
+ add_header Access-Control-Allow-Origin "*";
+ access_log off;
+ }
+
+ # =================================================================
+ # SPA Fallback - alle anderen Requests zu index.html
+ # =================================================================
+ location / {
+ try_files $uri $uri/ /index.html;
+
+ # Cache-Control für HTML-Dateien (kein Cache)
+ add_header Cache-Control "no-cache, no-store, must-revalidate";
+ add_header Pragma "no-cache";
+ add_header Expires "0";
+ }
+
+ # =================================================================
+ # Spezielle Dateien
+ # =================================================================
+ # robots.txt und sitemap.xml
+ location ~* ^/(robots\.txt|sitemap\.xml)$ {
+ root /var/www/timeclock/frontend/dist;
+ access_log off;
+ }
+
+ # favicon.ico
+ location = /favicon.ico {
+ root /var/www/timeclock/frontend/dist;
+ access_log off;
+ log_not_found off;
+ }
+
+ # =================================================================
+ # Sicherheit: Verstecke sensible Dateien
+ # =================================================================
+ # Blockiere Zugriff auf .git, .env, etc.
+ location ~ /\. {
+ deny all;
+ access_log off;
+ log_not_found off;
+ }
+
+ # Blockiere Zugriff auf Backup-Dateien
+ location ~ ~$ {
+ deny all;
+ access_log off;
+ log_not_found off;
+ }
+
+ # =================================================================
+ # Limits und Rate Limiting (optional)
+ # =================================================================
+ # Client Body Size Limit (z.B. für File-Uploads)
+ client_max_body_size 10M;
+
+ # Client Body Timeout
+ client_body_timeout 30s;
+
+ # Client Header Timeout
+ client_header_timeout 30s;
+
+ # Send Timeout
+ send_timeout 30s;
+
+ # Rate Limiting für API (optional)
+ # Kommentare entfernen und in nginx.conf http-Block hinzufügen:
+ # limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
+ # location /api {
+ # limit_req zone=api_limit burst=20 nodelay;
+ # ... rest der Konfiguration
+ # }
+}
+
+# =================================================================
+# OPTIONAL: Rate Limiting Zone (in /etc/nginx/nginx.conf http-Block)
+# =================================================================
+# Uncomment und in die Haupt-nginx.conf einfügen, falls gewünscht:
+#
+# http {
+# ...
+#
+# # Rate Limiting Zones
+# limit_req_zone $binary_remote_addr zone=general_limit:10m rate=30r/s;
+# limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
+# limit_req_zone $binary_remote_addr zone=login_limit:10m rate=5r/m;
+#
+# # Connection Limiting
+# limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
+#
+# ...
+# }
+
diff --git a/scripts/README.md b/scripts/README.md
new file mode 100644
index 0000000..6e39387
--- /dev/null
+++ b/scripts/README.md
@@ -0,0 +1,345 @@
+# TimeClock v3 - Server-Management Scripts
+
+Dieses Verzeichnis enthält hilfreiche Wartungs- und Management-Scripts für den Produktions-Server.
+
+## Übersicht
+
+| Script | Beschreibung | Verwendung |
+|--------|--------------|------------|
+| `backup-timeclock.sh` | Erstellt automatische Datenbank-Backups | Täglich per Cronjob |
+| `health-check.sh` | Überwacht API-Verfügbarkeit | Alle 5 Min per Cronjob |
+| `restore-backup.sh` | Stellt Datenbank-Backup wieder her | Manuell bei Bedarf |
+
+---
+
+## 1. backup-timeclock.sh
+
+Erstellt automatische komprimierte Backups der MySQL-Datenbank.
+
+### Installation
+
+```bash
+# Auf den Server kopieren
+sudo cp scripts/backup-timeclock.sh /usr/local/bin/
+sudo chmod +x /usr/local/bin/backup-timeclock.sh
+
+# Cronjob einrichten (täglich um 2 Uhr)
+sudo crontab -e
+```
+
+Füge folgende Zeile hinzu:
+```cron
+0 2 * * * /usr/local/bin/backup-timeclock.sh >> /var/log/timeclock/backup.log 2>&1
+```
+
+### Manuell ausführen
+
+```bash
+/usr/local/bin/backup-timeclock.sh
+```
+
+### Features
+
+- ✅ Automatische Datenbank-Backups mit Kompression
+- ✅ Konfigurierbare Retention (Standard: 30 Tage)
+- ✅ Optional: Code-Backups
+- ✅ Optional: Remote-Backup per rsync
+- ✅ Optional: E-Mail-Benachrichtigungen
+- ✅ Backup-Statistiken
+
+### Konfiguration
+
+Bearbeite die Variablen am Anfang des Scripts:
+
+```bash
+BACKUP_DIR="/var/backups/timeclock"
+RETENTION_DAYS=30
+BACKUP_CODE=false # true für Code-Backups
+REMOTE_BACKUP=false # true für Remote-Backup
+SEND_EMAIL=false # true für E-Mail-Benachrichtigung
+```
+
+### Backup-Dateien
+
+Backups werden gespeichert unter:
+- Datenbank: `/var/backups/timeclock/timeclock_db_YYYYMMDD_HHMMSS.sql.gz`
+- Code: `/var/backups/timeclock/timeclock_code_YYYYMMDD_HHMMSS.tar.gz`
+
+---
+
+## 2. health-check.sh
+
+Überwacht die Verfügbarkeit des Backend-API und startet den Service bei Bedarf automatisch neu.
+
+### Installation
+
+```bash
+# Auf den Server kopieren
+sudo cp scripts/health-check.sh /usr/local/bin/
+sudo chmod +x /usr/local/bin/health-check.sh
+
+# Cronjob einrichten (alle 5 Minuten)
+crontab -e
+```
+
+Füge folgende Zeile hinzu:
+```cron
+*/5 * * * * /usr/local/bin/health-check.sh >> /var/log/timeclock/health-check.log 2>&1
+```
+
+### Manuell ausführen
+
+```bash
+/usr/local/bin/health-check.sh
+```
+
+### Features
+
+- ✅ Prüft `/api/health` Endpunkt
+- ✅ Automatischer Neustart bei Ausfall
+- ✅ Mehrere Retry-Versuche (Standard: 3)
+- ✅ Unterstützt PM2 und systemd
+- ✅ Optional: E-Mail/Webhook-Benachrichtigungen
+- ✅ Ressourcen-Monitoring (CPU/RAM/Disk)
+
+### Konfiguration
+
+```bash
+API_URL="http://localhost:3010/api/health"
+USE_PM2=true # false für systemd
+MAX_RETRIES=3
+RETRY_DELAY=5
+SEND_EMAIL=false # true für E-Mail-Benachrichtigung
+```
+
+### Benachrichtigungen
+
+Das Script kann bei Ausfällen Benachrichtigungen senden via:
+- E-Mail (benötigt `mail` command)
+- Webhook (Discord, Slack, etc.)
+
+Konfiguriere die entsprechenden Variablen im Script:
+
+```bash
+SEND_EMAIL=true
+EMAIL_TO="admin@tsschulz.de"
+
+WEBHOOK_URL="https://discord.com/api/webhooks/..."
+```
+
+---
+
+## 3. restore-backup.sh
+
+Interaktives Script zum Wiederherstellen von Datenbank-Backups.
+
+### Verwendung
+
+```bash
+# Interaktive Auswahl
+sudo /var/www/timeclock/scripts/restore-backup.sh
+
+# Spezifisches Backup wiederherstellen
+sudo /var/www/timeclock/scripts/restore-backup.sh timeclock_db_20251018_020000.sql.gz
+
+# Mit vollständigem Pfad
+sudo /var/www/timeclock/scripts/restore-backup.sh /var/backups/timeclock/timeclock_db_20251018_020000.sql.gz
+```
+
+### Features
+
+- ✅ Interaktive Backup-Auswahl
+- ✅ Sicherheitskopie vor Restore
+- ✅ Konfirmations-Prompts
+- ✅ Automatisches Service-Neustart (optional)
+- ✅ Datenbank-Statistiken nach Restore
+
+### Ablauf
+
+1. Zeigt Liste verfügbarer Backups
+2. Erstellt Sicherheitskopie der aktuellen DB
+3. Bestätigung erforderlich
+4. Restore durchführen
+5. Optional: Service neu starten
+
+### ⚠️ WARNUNG
+
+Das Restore überschreibt die aktuelle Datenbank! Eine Sicherheitskopie wird automatisch erstellt, aber sei vorsichtig!
+
+---
+
+## Logs
+
+Alle Scripts loggen nach:
+- `/var/log/timeclock/backup.log` - Backup-Logs
+- `/var/log/timeclock/health-check.log` - Health-Check-Logs
+
+### Logs ansehen
+
+```bash
+# Backup-Logs
+tail -f /var/log/timeclock/backup.log
+
+# Health-Check-Logs
+tail -f /var/log/timeclock/health-check.log
+
+# Alle Logs
+tail -f /var/log/timeclock/*.log
+```
+
+---
+
+## Cronjob-Übersicht
+
+Empfohlene Cronjob-Konfiguration:
+
+```cron
+# TimeClock Maintenance Jobs
+
+# Backup: Täglich um 2 Uhr morgens
+0 2 * * * /usr/local/bin/backup-timeclock.sh >> /var/log/timeclock/backup.log 2>&1
+
+# Health-Check: Alle 5 Minuten
+*/5 * * * * /usr/local/bin/health-check.sh >> /var/log/timeclock/health-check.log 2>&1
+
+# Optional: Log-Rotation - Alte Logs löschen (älter als 90 Tage)
+0 3 * * 0 find /var/log/timeclock -name "*.log" -mtime +90 -delete
+```
+
+---
+
+## Weitere nützliche Commands
+
+### Backup-Verwaltung
+
+```bash
+# Liste aller Backups
+ls -lh /var/backups/timeclock/
+
+# Anzahl der Backups
+ls -1 /var/backups/timeclock/timeclock_db_*.sql.gz | wc -l
+
+# Gesamtgröße der Backups
+du -sh /var/backups/timeclock/
+
+# Ältestes Backup
+ls -t /var/backups/timeclock/timeclock_db_*.sql.gz | tail -1
+
+# Neuestes Backup
+ls -t /var/backups/timeclock/timeclock_db_*.sql.gz | head -1
+
+# Manuell alte Backups löschen (älter als 30 Tage)
+find /var/backups/timeclock -name "timeclock_db_*.sql.gz" -mtime +30 -delete
+```
+
+### Service-Management
+
+```bash
+# Mit PM2
+pm2 status
+pm2 logs timeclock-backend
+pm2 restart timeclock-backend
+pm2 monit
+
+# Mit systemd
+sudo systemctl status timeclock
+sudo journalctl -u timeclock -f
+sudo systemctl restart timeclock
+```
+
+### API-Tests
+
+```bash
+# Health-Check
+curl http://localhost:3010/api/health
+
+# Mit Details
+curl -s http://localhost:3010/api/health | jq
+
+# Response-Zeit messen
+time curl -s http://localhost:3010/api/health > /dev/null
+```
+
+---
+
+## Troubleshooting
+
+### Script läuft nicht
+
+```bash
+# Berechtigungen prüfen
+ls -l /usr/local/bin/backup-timeclock.sh
+
+# Ausführbar machen
+sudo chmod +x /usr/local/bin/backup-timeclock.sh
+
+# Script-Fehler debuggen
+bash -x /usr/local/bin/backup-timeclock.sh
+```
+
+### Cronjob läuft nicht
+
+```bash
+# Cronjobs anzeigen
+crontab -l
+
+# Cron-Logs prüfen
+sudo grep CRON /var/log/syslog
+
+# Cronjob manuell testen
+/usr/local/bin/backup-timeclock.sh
+```
+
+### Backup schlägt fehl
+
+```bash
+# DB-Verbindung testen
+mysql -u timeclock -p -e "SHOW DATABASES;"
+
+# .env Datei prüfen
+cat /var/www/timeclock/backend/.env
+
+# Backup-Verzeichnis prüfen
+ls -ld /var/backups/timeclock
+
+# Schreibrechte prüfen
+touch /var/backups/timeclock/test.txt
+```
+
+---
+
+## Best Practices
+
+1. **Regelmäßige Backups testen**
+ - Teste mindestens monatlich ein Restore
+ - Verifiziere Backup-Integrität
+
+2. **Monitoring einrichten**
+ - Health-Checks aktivieren
+ - E-Mail-Benachrichtigungen konfigurieren
+
+3. **Logs überwachen**
+ - Prüfe regelmäßig die Log-Dateien
+ - Implementiere Log-Rotation
+
+4. **Off-Site Backups**
+ - Aktiviere Remote-Backup in `backup-timeclock.sh`
+ - Speichere Backups an einem anderen Ort
+
+5. **Sicherheit**
+ - Schütze Backup-Dateien (enthalten sensible Daten!)
+ - Setze restriktive Berechtigungen
+
+---
+
+## Support
+
+Bei Problemen:
+1. Prüfe die Log-Dateien
+2. Teste Scripts manuell
+3. Siehe Haupt-Dokumentation: `../DEPLOYMENT.md`
+
+---
+
+**Automatisierte Wartung für sorgenfreien Betrieb! 🚀**
+
diff --git a/scripts/backup-timeclock.sh b/scripts/backup-timeclock.sh
new file mode 100755
index 0000000..64fea26
--- /dev/null
+++ b/scripts/backup-timeclock.sh
@@ -0,0 +1,223 @@
+#!/bin/bash
+
+# =============================================================================
+# TimeClock v3 - Automatisches Backup-Script
+# =============================================================================
+# Erstellt tägliche Backups der Datenbank und optional des Codes
+#
+# Installation:
+# sudo cp backup-timeclock.sh /usr/local/bin/
+# sudo chmod +x /usr/local/bin/backup-timeclock.sh
+#
+# Cronjob einrichten (täglich um 2 Uhr):
+# sudo crontab -e
+# 0 2 * * * /usr/local/bin/backup-timeclock.sh >> /var/log/timeclock/backup.log 2>&1
+#
+# Manuell ausführen:
+# /usr/local/bin/backup-timeclock.sh
+# =============================================================================
+
+set -e
+
+# Konfiguration
+BACKUP_DIR="/var/backups/timeclock"
+PROJECT_DIR="/var/www/timeclock"
+ENV_FILE="$PROJECT_DIR/backend/.env"
+RETENTION_DAYS=30 # Backups älter als X Tage werden gelöscht
+
+# Datum
+DATE=$(date +%Y%m%d_%H%M%S)
+DATE_READABLE=$(date '+%Y-%m-%d %H:%M:%S')
+
+# Logging
+log() {
+ echo "[${DATE_READABLE}] $1"
+}
+
+log_error() {
+ echo "[${DATE_READABLE}] ERROR: $1" >&2
+}
+
+# =============================================================================
+# Voraussetzungen prüfen
+# =============================================================================
+
+if [ ! -f "$ENV_FILE" ]; then
+ log_error ".env Datei nicht gefunden: $ENV_FILE"
+ exit 1
+fi
+
+# Backup-Verzeichnis erstellen
+mkdir -p "$BACKUP_DIR"
+
+# =============================================================================
+# Datenbank-Credentials aus .env lesen
+# =============================================================================
+
+log "Lese Datenbank-Konfiguration..."
+
+# Funktion zum Auslesen von .env Werten
+get_env_value() {
+ grep "^$1=" "$ENV_FILE" | cut -d '=' -f2- | tr -d '"' | tr -d "'"
+}
+
+DB_HOST=$(get_env_value "DB_HOST")
+DB_PORT=$(get_env_value "DB_PORT")
+DB_NAME=$(get_env_value "DB_NAME")
+DB_USER=$(get_env_value "DB_USER")
+DB_PASSWORD=$(get_env_value "DB_PASSWORD")
+
+# Defaults setzen
+DB_HOST=${DB_HOST:-localhost}
+DB_PORT=${DB_PORT:-3306}
+
+if [ -z "$DB_NAME" ] || [ -z "$DB_USER" ] || [ -z "$DB_PASSWORD" ]; then
+ log_error "Datenbank-Credentials unvollständig in .env"
+ exit 1
+fi
+
+log "Datenbank: $DB_USER@$DB_HOST:$DB_PORT/$DB_NAME"
+
+# =============================================================================
+# Datenbank-Backup erstellen
+# =============================================================================
+
+log "Erstelle Datenbank-Backup..."
+
+BACKUP_FILE="$BACKUP_DIR/timeclock_db_$DATE.sql.gz"
+
+# mysqldump mit Kompression
+if mysqldump \
+ --host="$DB_HOST" \
+ --port="$DB_PORT" \
+ --user="$DB_USER" \
+ --password="$DB_PASSWORD" \
+ --single-transaction \
+ --routines \
+ --triggers \
+ --events \
+ --add-drop-database \
+ --databases "$DB_NAME" \
+ | gzip > "$BACKUP_FILE"; then
+
+ # Dateigröße ermitteln
+ SIZE=$(du -h "$BACKUP_FILE" | cut -f1)
+ log "✅ Datenbank-Backup erfolgreich erstellt: $BACKUP_FILE ($SIZE)"
+else
+ log_error "Datenbank-Backup fehlgeschlagen!"
+ exit 1
+fi
+
+# =============================================================================
+# Code-Backup erstellen (optional)
+# =============================================================================
+
+BACKUP_CODE=false # Auf true setzen für Code-Backups
+
+if [ "$BACKUP_CODE" = true ]; then
+ log "Erstelle Code-Backup..."
+
+ CODE_BACKUP_FILE="$BACKUP_DIR/timeclock_code_$DATE.tar.gz"
+
+ if tar -czf "$CODE_BACKUP_FILE" \
+ -C "$(dirname $PROJECT_DIR)" \
+ --exclude="node_modules" \
+ --exclude="dist" \
+ --exclude=".git" \
+ --exclude="*.log" \
+ "$(basename $PROJECT_DIR)"; then
+
+ SIZE=$(du -h "$CODE_BACKUP_FILE" | cut -f1)
+ log "✅ Code-Backup erfolgreich erstellt: $CODE_BACKUP_FILE ($SIZE)"
+ else
+ log_error "Code-Backup fehlgeschlagen!"
+ fi
+fi
+
+# =============================================================================
+# Alte Backups löschen
+# =============================================================================
+
+log "Lösche alte Backups (älter als $RETENTION_DAYS Tage)..."
+
+# Datenbank-Backups
+DELETED_DB=$(find "$BACKUP_DIR" -name "timeclock_db_*.sql.gz" -mtime +$RETENTION_DAYS -type f -delete -print | wc -l)
+if [ "$DELETED_DB" -gt 0 ]; then
+ log "🗑️ $DELETED_DB alte Datenbank-Backups gelöscht"
+fi
+
+# Code-Backups
+if [ "$BACKUP_CODE" = true ]; then
+ DELETED_CODE=$(find "$BACKUP_DIR" -name "timeclock_code_*.tar.gz" -mtime +$RETENTION_DAYS -type f -delete -print | wc -l)
+ if [ "$DELETED_CODE" -gt 0 ]; then
+ log "🗑️ $DELETED_CODE alte Code-Backups gelöscht"
+ fi
+fi
+
+# =============================================================================
+# Backup-Statistik
+# =============================================================================
+
+log "Backup-Statistik:"
+log " 📊 Gesamt-Backups: $(ls -1 $BACKUP_DIR/timeclock_db_*.sql.gz 2>/dev/null | wc -l)"
+log " 💾 Gesamtgröße: $(du -sh $BACKUP_DIR | cut -f1)"
+log " 📅 Ältestes Backup: $(ls -t $BACKUP_DIR/timeclock_db_*.sql.gz 2>/dev/null | tail -1 | xargs basename)"
+log " 📅 Neuestes Backup: $(ls -t $BACKUP_DIR/timeclock_db_*.sql.gz 2>/dev/null | head -1 | xargs basename)"
+
+# =============================================================================
+# Optional: Backup an Remote-Server senden
+# =============================================================================
+
+REMOTE_BACKUP=false # Auf true setzen für Remote-Backup
+REMOTE_USER="backup"
+REMOTE_HOST="backup.example.com"
+REMOTE_PATH="/backups/timeclock"
+
+if [ "$REMOTE_BACKUP" = true ]; then
+ log "Sende Backup an Remote-Server..."
+
+ if rsync -az --progress "$BACKUP_FILE" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_PATH/"; then
+ log "✅ Remote-Backup erfolgreich"
+ else
+ log_error "Remote-Backup fehlgeschlagen!"
+ fi
+fi
+
+# =============================================================================
+# Optional: Backup-Benachrichtigung per E-Mail
+# =============================================================================
+
+SEND_EMAIL=false # Auf true setzen für E-Mail-Benachrichtigung
+EMAIL_TO="admin@tsschulz.de"
+
+if [ "$SEND_EMAIL" = true ] && command -v mail &> /dev/null; then
+ log "Sende E-Mail-Benachrichtigung..."
+
+ SIZE=$(du -h "$BACKUP_FILE" | cut -f1)
+
+ echo "TimeClock Backup erfolgreich erstellt
+
+Datum: $DATE_READABLE
+Datei: $BACKUP_FILE
+Größe: $SIZE
+Datenbank: $DB_NAME
+
+Backup-Verzeichnis: $BACKUP_DIR
+Anzahl Backups: $(ls -1 $BACKUP_DIR/timeclock_db_*.sql.gz 2>/dev/null | wc -l)
+Gesamtgröße: $(du -sh $BACKUP_DIR | cut -f1)
+
+--
+TimeClock v3 Backup System
+" | mail -s "✅ TimeClock Backup erfolgreich ($DATE)" "$EMAIL_TO"
+
+ log "📧 E-Mail gesendet an $EMAIL_TO"
+fi
+
+# =============================================================================
+# Fertig
+# =============================================================================
+
+log "✅ Backup-Prozess abgeschlossen!"
+
+exit 0
+
diff --git a/scripts/health-check.sh b/scripts/health-check.sh
new file mode 100755
index 0000000..091344c
--- /dev/null
+++ b/scripts/health-check.sh
@@ -0,0 +1,210 @@
+#!/bin/bash
+
+# =============================================================================
+# TimeClock v3 - Health-Check Script
+# =============================================================================
+# Überwacht die Verfügbarkeit des Backend-API und startet bei Bedarf neu
+#
+# Installation:
+# sudo cp health-check.sh /usr/local/bin/
+# sudo chmod +x /usr/local/bin/health-check.sh
+#
+# Cronjob einrichten (alle 5 Minuten):
+# crontab -e
+# */5 * * * * /usr/local/bin/health-check.sh >> /var/log/timeclock/health-check.log 2>&1
+#
+# Manuell ausführen:
+# /usr/local/bin/health-check.sh
+# =============================================================================
+
+set -e
+
+# Konfiguration
+API_URL="http://localhost:3010/api/health"
+SERVICE_NAME="timeclock-backend"
+USE_PM2=true # true für PM2, false für systemd
+LOG_FILE="/var/log/timeclock/health-check.log"
+MAX_RETRIES=3
+RETRY_DELAY=5 # Sekunden zwischen Versuchen
+
+# Datum
+DATE=$(date '+%Y-%m-%d %H:%M:%S')
+
+# Logging
+log() {
+ echo "[$DATE] $1" | tee -a "$LOG_FILE"
+}
+
+log_error() {
+ echo "[$DATE] ERROR: $1" | tee -a "$LOG_FILE" >&2
+}
+
+# =============================================================================
+# Health-Check durchführen
+# =============================================================================
+
+check_health() {
+ # Versuche Health-Endpunkt zu erreichen
+ if curl -sf "$API_URL" > /dev/null 2>&1; then
+ return 0 # Erfolg
+ else
+ return 1 # Fehler
+ fi
+}
+
+# =============================================================================
+# Service neu starten
+# =============================================================================
+
+restart_service() {
+ log "⚠️ Versuche Service neu zu starten..."
+
+ if [ "$USE_PM2" = true ]; then
+ # PM2
+ if command -v pm2 &> /dev/null; then
+ if pm2 restart "$SERVICE_NAME" > /dev/null 2>&1; then
+ log "✅ Service mit PM2 neu gestartet"
+ return 0
+ else
+ log_error "PM2-Neustart fehlgeschlagen!"
+ return 1
+ fi
+ else
+ log_error "PM2 nicht gefunden!"
+ return 1
+ fi
+ else
+ # systemd
+ if sudo systemctl restart "$SERVICE_NAME"; then
+ log "✅ Service mit systemd neu gestartet"
+ return 0
+ else
+ log_error "systemd-Neustart fehlgeschlagen!"
+ return 1
+ fi
+ fi
+}
+
+# =============================================================================
+# Benachrichtigung senden
+# =============================================================================
+
+send_notification() {
+ local status=$1
+ local message=$2
+
+ # Optional: E-Mail-Benachrichtigung
+ SEND_EMAIL=false
+ EMAIL_TO="admin@tsschulz.de"
+
+ if [ "$SEND_EMAIL" = true ] && command -v mail &> /dev/null; then
+ echo "$message
+
+Zeitpunkt: $DATE
+API-URL: $API_URL
+Service: $SERVICE_NAME
+
+--
+TimeClock v3 Health-Check System
+" | mail -s "$status TimeClock Backend" "$EMAIL_TO"
+ fi
+
+ # Optional: Webhook-Benachrichtigung (z.B. Discord, Slack)
+ WEBHOOK_URL=""
+
+ if [ -n "$WEBHOOK_URL" ]; then
+ curl -X POST "$WEBHOOK_URL" \
+ -H "Content-Type: application/json" \
+ -d "{\"content\": \"$status $message\"}" \
+ > /dev/null 2>&1
+ fi
+}
+
+# =============================================================================
+# Hauptlogik
+# =============================================================================
+
+# Erstelle Log-Verzeichnis falls nicht vorhanden
+mkdir -p "$(dirname $LOG_FILE)"
+
+# Prüfe ob Service läuft
+if [ "$USE_PM2" = true ]; then
+ if ! pm2 list | grep -q "$SERVICE_NAME.*online"; then
+ log_error "⚠️ Service läuft nicht (PM2)!"
+ restart_service
+ sleep 10
+ fi
+else
+ if ! systemctl is-active --quiet "$SERVICE_NAME"; then
+ log_error "⚠️ Service läuft nicht (systemd)!"
+ restart_service
+ sleep 10
+ fi
+fi
+
+# Health-Check mit Retries
+SUCCESS=false
+
+for i in $(seq 1 $MAX_RETRIES); do
+ if check_health; then
+ # Nur beim ersten Check des Tages loggen (um Log-Spam zu vermeiden)
+ CURRENT_HOUR=$(date +%H)
+ CURRENT_MINUTE=$(date +%M)
+
+ if [ "$CURRENT_HOUR" = "00" ] && [ "$CURRENT_MINUTE" -lt 6 ]; then
+ log "✅ Health-Check erfolgreich"
+ fi
+
+ SUCCESS=true
+ break
+ else
+ if [ $i -lt $MAX_RETRIES ]; then
+ log "⚠️ Health-Check fehlgeschlagen (Versuch $i/$MAX_RETRIES), warte $RETRY_DELAY Sekunden..."
+ sleep $RETRY_DELAY
+ fi
+ fi
+done
+
+# Wenn alle Versuche fehlschlagen
+if [ "$SUCCESS" = false ]; then
+ log_error "❌ Health-Check fehlgeschlagen nach $MAX_RETRIES Versuchen!"
+
+ # Service neu starten
+ if restart_service; then
+ # Nach Neustart erneut prüfen
+ sleep 10
+
+ if check_health; then
+ log "✅ Service nach Neustart wieder erreichbar"
+ send_notification "⚠️ RECOVERED:" "TimeClock Backend wurde neu gestartet und ist wieder erreichbar."
+ else
+ log_error "❌ Service auch nach Neustart nicht erreichbar!"
+ send_notification "🚨 CRITICAL:" "TimeClock Backend ist auch nach Neustart nicht erreichbar! Manuelle Intervention erforderlich."
+ fi
+ else
+ log_error "❌ Service-Neustart fehlgeschlagen!"
+ send_notification "🚨 CRITICAL:" "TimeClock Backend-Neustart fehlgeschlagen! Manuelle Intervention erforderlich."
+ fi
+fi
+
+# =============================================================================
+# Zusätzliche Checks (optional)
+# =============================================================================
+
+# CPU & Memory Usage prüfen
+if [ "$USE_PM2" = true ] && command -v pm2 &> /dev/null; then
+ PM2_STATUS=$(pm2 jlist | jq -r ".[] | select(.name==\"$SERVICE_NAME\") | \"CPU: \(.monit.cpu)%, Memory: \(.monit.memory / 1024 / 1024 | floor)MB\"" 2>/dev/null || echo "N/A")
+
+ # Nur bei hohem Ressourcenverbrauch loggen
+ # (Optional: weitere Logik implementieren)
+fi
+
+# Disk Space prüfen
+DISK_USAGE=$(df -h / | awk 'NR==2 {print $5}' | sed 's/%//')
+if [ "$DISK_USAGE" -gt 90 ]; then
+ log_error "⚠️ Festplattenspeicher kritisch: ${DISK_USAGE}%"
+ send_notification "⚠️ WARNING:" "Festplattenspeicher auf TimeClock-Server kritisch: ${DISK_USAGE}%"
+fi
+
+exit 0
+
diff --git a/scripts/restore-backup.sh b/scripts/restore-backup.sh
new file mode 100755
index 0000000..e6299c5
--- /dev/null
+++ b/scripts/restore-backup.sh
@@ -0,0 +1,275 @@
+#!/bin/bash
+
+# =============================================================================
+# TimeClock v3 - Backup-Restore Script
+# =============================================================================
+# Stellt ein Datenbank-Backup wieder her
+#
+# Verwendung:
+# ./restore-backup.sh [BACKUP_FILE]
+# ./restore-backup.sh # Zeigt Liste der verfügbaren Backups
+# ./restore-backup.sh timeclock_db_20251018_020000.sql.gz
+#
+# WARNUNG: Dies überschreibt die aktuelle Datenbank!
+# =============================================================================
+
+set -e
+
+# Farben
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+NC='\033[0m'
+
+# Konfiguration
+BACKUP_DIR="/var/backups/timeclock"
+PROJECT_DIR="/var/www/timeclock"
+ENV_FILE="$PROJECT_DIR/backend/.env"
+
+# Logging
+log() {
+ echo -e "${BLUE}ℹ️ $1${NC}"
+}
+
+log_success() {
+ echo -e "${GREEN}✅ $1${NC}"
+}
+
+log_warning() {
+ echo -e "${YELLOW}⚠️ $1${NC}"
+}
+
+log_error() {
+ echo -e "${RED}❌ $1${NC}"
+}
+
+# =============================================================================
+# Voraussetzungen prüfen
+# =============================================================================
+
+if [ ! -f "$ENV_FILE" ]; then
+ log_error ".env Datei nicht gefunden: $ENV_FILE"
+ exit 1
+fi
+
+if [ ! -d "$BACKUP_DIR" ]; then
+ log_error "Backup-Verzeichnis nicht gefunden: $BACKUP_DIR"
+ exit 1
+fi
+
+# =============================================================================
+# Datenbank-Credentials aus .env lesen
+# =============================================================================
+
+get_env_value() {
+ grep "^$1=" "$ENV_FILE" | cut -d '=' -f2- | tr -d '"' | tr -d "'"
+}
+
+DB_HOST=$(get_env_value "DB_HOST")
+DB_PORT=$(get_env_value "DB_PORT")
+DB_NAME=$(get_env_value "DB_NAME")
+DB_USER=$(get_env_value "DB_USER")
+DB_PASSWORD=$(get_env_value "DB_PASSWORD")
+
+# Defaults
+DB_HOST=${DB_HOST:-localhost}
+DB_PORT=${DB_PORT:-3306}
+
+if [ -z "$DB_NAME" ] || [ -z "$DB_USER" ] || [ -z "$DB_PASSWORD" ]; then
+ log_error "Datenbank-Credentials unvollständig in .env"
+ exit 1
+fi
+
+# =============================================================================
+# Verfügbare Backups auflisten
+# =============================================================================
+
+list_backups() {
+ echo ""
+ log "Verfügbare Backups in $BACKUP_DIR:"
+ echo ""
+
+ BACKUPS=($(ls -t "$BACKUP_DIR"/timeclock_db_*.sql.gz 2>/dev/null))
+
+ if [ ${#BACKUPS[@]} -eq 0 ]; then
+ log_warning "Keine Backups gefunden!"
+ exit 1
+ fi
+
+ for i in "${!BACKUPS[@]}"; do
+ BACKUP="${BACKUPS[$i]}"
+ FILENAME=$(basename "$BACKUP")
+ SIZE=$(du -h "$BACKUP" | cut -f1)
+ DATE=$(stat -c %y "$BACKUP" | cut -d'.' -f1)
+
+ printf "%2d) %-50s %6s %s\n" $((i+1)) "$FILENAME" "$SIZE" "$DATE"
+ done
+
+ echo ""
+}
+
+# =============================================================================
+# Backup-Datei auswählen
+# =============================================================================
+
+select_backup() {
+ list_backups
+
+ read -p "Wähle ein Backup (Nummer) oder 'q' zum Beenden: " selection
+
+ if [ "$selection" = "q" ] || [ "$selection" = "Q" ]; then
+ log "Abgebrochen."
+ exit 0
+ fi
+
+ if ! [[ "$selection" =~ ^[0-9]+$ ]]; then
+ log_error "Ungültige Eingabe!"
+ exit 1
+ fi
+
+ BACKUPS=($(ls -t "$BACKUP_DIR"/timeclock_db_*.sql.gz 2>/dev/null))
+ INDEX=$((selection - 1))
+
+ if [ $INDEX -lt 0 ] || [ $INDEX -ge ${#BACKUPS[@]} ]; then
+ log_error "Ungültige Auswahl!"
+ exit 1
+ fi
+
+ BACKUP_FILE="${BACKUPS[$INDEX]}"
+}
+
+# =============================================================================
+# Restore durchführen
+# =============================================================================
+
+restore_backup() {
+ local backup_file=$1
+
+ if [ ! -f "$backup_file" ]; then
+ log_error "Backup-Datei nicht gefunden: $backup_file"
+ exit 1
+ fi
+
+ echo ""
+ log_warning "WARNUNG: Dies wird die aktuelle Datenbank '$DB_NAME' überschreiben!"
+ log "Backup-Datei: $(basename $backup_file)"
+ log "Größe: $(du -h $backup_file | cut -f1)"
+ log "Datenbank: $DB_USER@$DB_HOST:$DB_PORT/$DB_NAME"
+ echo ""
+
+ read -p "Fortfahren? (yes/no): " confirm
+
+ if [ "$confirm" != "yes" ]; then
+ log "Abgebrochen."
+ exit 0
+ fi
+
+ # Erstelle Backup der aktuellen Datenbank (Sicherheitskopie)
+ log "Erstelle Sicherheitskopie der aktuellen Datenbank..."
+ SAFETY_BACKUP="$BACKUP_DIR/timeclock_db_pre_restore_$(date +%Y%m%d_%H%M%S).sql.gz"
+
+ if mysqldump \
+ --host="$DB_HOST" \
+ --port="$DB_PORT" \
+ --user="$DB_USER" \
+ --password="$DB_PASSWORD" \
+ --single-transaction \
+ --databases "$DB_NAME" \
+ | gzip > "$SAFETY_BACKUP"; then
+ log_success "Sicherheitskopie erstellt: $(basename $SAFETY_BACKUP)"
+ else
+ log_error "Sicherheitskopie fehlgeschlagen!"
+ read -p "Trotzdem fortfahren? (yes/no): " force
+ if [ "$force" != "yes" ]; then
+ exit 1
+ fi
+ fi
+
+ # Restore durchführen
+ log "Stelle Backup wieder her..."
+
+ # Datenbank leeren (optional, aber empfohlen)
+ log "Leere Datenbank..."
+ mysql \
+ --host="$DB_HOST" \
+ --port="$DB_PORT" \
+ --user="$DB_USER" \
+ --password="$DB_PASSWORD" \
+ -e "DROP DATABASE IF EXISTS $DB_NAME; CREATE DATABASE $DB_NAME;"
+
+ # Backup einspielen
+ if gunzip < "$backup_file" | mysql \
+ --host="$DB_HOST" \
+ --port="$DB_PORT" \
+ --user="$DB_USER" \
+ --password="$DB_PASSWORD"; then
+
+ log_success "Backup erfolgreich wiederhergestellt!"
+
+ # Datenbank-Statistiken
+ TABLE_COUNT=$(mysql \
+ --host="$DB_HOST" \
+ --port="$DB_PORT" \
+ --user="$DB_USER" \
+ --password="$DB_PASSWORD" \
+ -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '$DB_NAME';" -s -N)
+
+ log "Datenbank-Statistik:"
+ log " 📊 Tabellen: $TABLE_COUNT"
+
+ # Optional: Service neu starten
+ log_warning "Möchtest du den Backend-Service neu starten?"
+ read -p "Service neu starten? (y/n): " restart
+
+ if [ "$restart" = "y" ] || [ "$restart" = "Y" ]; then
+ if command -v pm2 &> /dev/null && pm2 list | grep -q "timeclock-backend"; then
+ pm2 restart timeclock-backend
+ log_success "PM2-Service neu gestartet"
+ elif systemctl is-active --quiet timeclock; then
+ sudo systemctl restart timeclock
+ log_success "systemd-Service neu gestartet"
+ else
+ log_warning "Service-Verwaltung nicht gefunden - bitte manuell neu starten"
+ fi
+ fi
+
+ echo ""
+ log_success "Restore abgeschlossen!"
+ log "Sicherheitskopie der alten Datenbank: $(basename $SAFETY_BACKUP)"
+
+ else
+ log_error "Restore fehlgeschlagen!"
+ log "Die Sicherheitskopie befindet sich unter: $(basename $SAFETY_BACKUP)"
+ exit 1
+ fi
+}
+
+# =============================================================================
+# Hauptprogramm
+# =============================================================================
+
+echo ""
+echo -e "${BLUE}════════════════════════════════════════════════════════════${NC}"
+echo -e "${BLUE} TimeClock v3 - Backup Restore${NC}"
+echo -e "${BLUE}════════════════════════════════════════════════════════════${NC}"
+echo ""
+
+# Wenn Backup-Datei als Argument übergeben wurde
+if [ $# -eq 1 ]; then
+ BACKUP_FILE="$1"
+
+ # Wenn nur Dateiname (ohne Pfad) übergeben wurde
+ if [ ! -f "$BACKUP_FILE" ]; then
+ BACKUP_FILE="$BACKUP_DIR/$1"
+ fi
+
+ restore_backup "$BACKUP_FILE"
+else
+ # Interaktive Auswahl
+ select_backup
+ restore_backup "$BACKUP_FILE"
+fi
+
+exit 0
+
diff --git a/timeclock.service b/timeclock.service
new file mode 100644
index 0000000..7030b38
--- /dev/null
+++ b/timeclock.service
@@ -0,0 +1,135 @@
+# Systemd Service für TimeClock v3 Backend
+# Installation:
+# sudo cp timeclock.service /etc/systemd/system/
+# sudo systemctl daemon-reload
+# sudo systemctl enable timeclock
+# sudo systemctl start timeclock
+#
+# Status prüfen:
+# sudo systemctl status timeclock
+#
+# Logs ansehen:
+# sudo journalctl -u timeclock -f
+
+[Unit]
+Description=TimeClock v3 Backend API
+Documentation=https://github.com/yourusername/TimeClock
+After=network.target mysql.service mariadb.service
+Wants=mysql.service
+
+[Service]
+# Service-Typ
+Type=simple
+
+# User und Group
+User=www-data
+Group=www-data
+
+# Arbeitsverzeichnis
+WorkingDirectory=/var/www/timeclock/backend
+
+# Umgebungsvariablen
+Environment=NODE_ENV=production
+Environment=PATH=/usr/bin:/usr/local/bin
+EnvironmentFile=/var/www/timeclock/backend/.env
+
+# Start-Befehl
+ExecStart=/usr/bin/node src/index.js
+
+# Restart-Policy
+Restart=always
+RestartSec=10
+
+# Timeouts
+TimeoutStartSec=30s
+TimeoutStopSec=30s
+
+# Logging
+StandardOutput=append:/var/log/timeclock/backend.log
+StandardError=append:/var/log/timeclock/backend.error.log
+SyslogIdentifier=timeclock
+
+# Process Management
+KillMode=mixed
+KillSignal=SIGTERM
+
+# Limits
+LimitNOFILE=65536
+LimitNPROC=4096
+
+# =================================================================
+# Sicherheits-Härtung (Security Hardening)
+# =================================================================
+
+# Verhindert Privilege Escalation
+NoNewPrivileges=true
+
+# Privates /tmp Verzeichnis
+PrivateTmp=true
+
+# Schützt bestimmte Kernel-Variablen
+ProtectKernelTunables=true
+
+# Verhindert Laden von Kernel-Modulen
+ProtectKernelModules=true
+
+# Schützt Kernel-Logs
+ProtectKernelLogs=true
+
+# Verhindert Zugriff auf /proc
+ProtectProc=invisible
+
+# Verhindert Zugriff auf /sys
+ProtectControlGroups=true
+
+# Schützt Hostnamen
+ProtectHostname=true
+
+# Macht /home, /root und /run/user read-only
+ProtectHome=true
+
+# Macht das System teilweise read-only
+ProtectSystem=strict
+
+# Erlaubt Schreibzugriff auf bestimmte Verzeichnisse
+ReadWritePaths=/var/www/timeclock/backend
+ReadWritePaths=/var/log/timeclock
+
+# Verhindert Zugriff auf andere Benutzer
+PrivateUsers=false
+
+# Verhindert neue Devices
+PrivateDevices=true
+
+# Verhindert Zugriff auf Clock
+ProtectClock=true
+
+# Verhindert Realtime-Scheduling
+RestrictRealtime=true
+
+# Filtert gefährliche System-Calls
+SystemCallFilter=@system-service
+SystemCallFilter=~@privileged @resources @obsolete
+
+# Verhindert Nutzung bestimmter Namespaces
+RestrictNamespaces=true
+
+# Verhindert SUID/SGID
+RestrictSUIDSGID=true
+
+# Entfernt Capabilities
+CapabilityBoundingSet=
+AmbientCapabilities=
+
+# Address Space Layout Randomization
+LockPersonality=true
+
+# Verhindert Zugriff auf andere User-Sessions
+RemoveIPC=true
+
+# Umask setzen
+UMask=0077
+
+[Install]
+WantedBy=multi-user.target
+