Files
stechuhr3/backend/DB_SETUP.md
Torsten Schulz (local) e95bb4cb76 Initial commit: TimeClock v3 - Node.js/Vue.js Zeiterfassung
Features:
- Backend: Node.js/Express mit MySQL/MariaDB
- Frontend: Vue.js 3 mit Composition API
- UTC-Zeithandling für korrekte Zeiterfassung
- Timewish-basierte Überstundenberechnung
- Wochenübersicht mit Urlaubs-/Krankheits-/Feiertagshandling
- Bereinigtes Arbeitsende (Generell/Woche)
- Überstunden-Offset für historische Daten
- Fixed Layout mit scrollbarem Content
- Kompakte UI mit grünem Theme
2025-10-17 14:11:28 +02:00

6.8 KiB

Datenbank-Setup für TimeClock v3

Voraussetzungen

  • MySQL 5.7 oder höher
  • Zugriff auf MySQL-Server (localhost oder remote)

Setup-Schritte

1. Datenbank-Verbindung konfigurieren

Erstellen Sie eine .env Datei im backend/ Verzeichnis:

cd backend
cp .env.example .env

Bearbeiten Sie die .env Datei mit Ihren Datenbankzugangsdaten:

PORT=3000
NODE_ENV=development

# MySQL Datenbank
DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASSWORD=ihr_mysql_passwort
DB_NAME=stechuhr2

2. Datenbank prüfen

Die Datenbank stechuhr2 sollte bereits existieren. Prüfen Sie dies:

mysql -u root -p
SHOW DATABASES;
USE stechuhr2;
SHOW TABLES;

Sie sollten die Tabellen sehen:

  • worklog (Haupttabelle für Zeiteinträge)
  • user (Benutzerverwaltung)
  • auth_info (Authentifizierung)
  • ... und weitere

3. Testbenutzer prüfen/erstellen

Prüfen Sie, ob ein Benutzer mit ID 1 existiert:

SELECT * FROM user WHERE id = 1;

Falls kein Benutzer existiert, erstellen Sie einen:

INSERT INTO user (
  id, version, last_change, role, daily_hours, 
  state_id, full_name, week_hours, week_workdays, preferred_title_type
) VALUES (
  1, 0, NOW(), 0, 8, 
  NULL, 'Test Benutzer', 40, 5, 0
);

4. Abhängigkeiten installieren

cd backend
npm install

Dies installiert auch mysql2 für die Datenbankverbindung.

5. Backend starten

npm run dev

Erwartete Ausgabe:

✅ MySQL-Datenbankverbindung hergestellt
🕐 TimeClock Server läuft auf Port 3010
📍 API verfügbar unter http://localhost:3010/api

Bei Fehlern:

  • "Access denied for user": Überprüfen Sie DB_USER und DB_PASSWORD in .env
  • "Unknown database": Erstellen Sie die Datenbank stechuhr2
  • "ECONNREFUSED": MySQL-Server läuft nicht oder falscher DB_HOST/DB_PORT

6. API testen

# Health Check
curl http://localhost:3010/api/health

# Zeiteinträge abrufen
curl http://localhost:3010/api/time-entries

# Neuen Timer starten
curl -X POST http://localhost:3010/api/time-entries \
  -H "Content-Type: application/json" \
  -d '{"project":"Test","description":"Test-Timer"}'

Worklog-Struktur

Die Haupttabelle worklog speichert Zeiteinträge:

Clock In (Start):
┌────────────────────────────────────────────┐
│ id: 1                                      │
│ user_id: 1                                 │
│ state: {"action":"Clock In","project":... }│
│ tstamp: 2025-10-15 10:00:00               │
│ relatedTo_id: NULL                         │
└────────────────────────────────────────────┘

Clock Out (End):
┌────────────────────────────────────────────┐
│ id: 2                                      │
│ user_id: 1                                 │
│ state: {"action":"Clock Out","project":...}│
│ tstamp: 2025-10-15 12:00:00               │
│ relatedTo_id: 1  ← Verweist auf Clock In  │
└────────────────────────────────────────────┘

Bestehende Daten

Falls bereits Worklog-Einträge in der Datenbank existieren:

Datenformat prüfen

SELECT id, user_id, state, tstamp, relatedTo_id 
FROM worklog 
ORDER BY tstamp DESC 
LIMIT 10;

Altes Format konvertieren

Falls state nicht im JSON-Format vorliegt, können Sie Einträge konvertieren:

-- Beispiel: state ist "in" oder "out"
UPDATE worklog 
SET state = JSON_OBJECT('action', 'Clock In', 'project', 'Allgemein', 'description', '')
WHERE state = 'in' AND relatedTo_id IS NULL;

UPDATE worklog 
SET state = JSON_OBJECT('action', 'Clock Out', 'project', 'Allgemein', 'description', '')
WHERE state = 'out' AND relatedTo_id IS NOT NULL;

⚠️ Wichtig: Erstellen Sie vorher ein Backup!

mysqldump -u root -p stechuhr2 > backup_before_conversion.sql

Mehrere Benutzer

Der aktuelle Code verwendet standardmäßig Benutzer-ID 1. Für Multi-User-Support:

Option 1: Benutzer-ID in Service setzen

// In zukünftigen Endpunkten
const userId = req.user.id; // Aus Auth-Middleware
const entries = await timeEntryService.getAllEntries(userId);

Option 2: Authentifizierung hinzufügen

Die Datenbank hat bereits auth_info und auth_token Tabellen für JWT-basierte Authentifizierung.

Troubleshooting

Verbindungsprobleme

# MySQL-Status prüfen
sudo systemctl status mysql

# MySQL starten
sudo systemctl start mysql

# Port prüfen
netstat -an | grep 3306

Berechtigungen

-- Benutzer-Berechtigungen prüfen
SHOW GRANTS FOR 'root'@'localhost';

-- Falls nötig, Berechtigungen gewähren
GRANT ALL PRIVILEGES ON stechuhr2.* TO 'root'@'localhost';
FLUSH PRIVILEGES;

Connection Pool Limits

Bei vielen gleichzeitigen Anfragen:

// In src/config/database.js
connectionLimit: 10  // Erhöhen auf 20 oder mehr

Debugging

Aktivieren Sie Query-Logging:

// In src/repositories/WorklogRepository.js
console.log('SQL:', sql);
console.log('Params:', params);

Performance-Tipps

Indizes prüfen

SHOW INDEX FROM worklog;

Wichtige Indizes:

  • worklog_user_id_IDX (user_id, tstamp)
  • worklog_tstamp_IDX (tstamp)

Query-Performance analysieren

EXPLAIN SELECT * FROM worklog WHERE user_id = 1 ORDER BY tstamp DESC;

Alte Einträge archivieren

-- Einträge älter als 2 Jahre in Archiv-Tabelle verschieben
CREATE TABLE worklog_archive LIKE worklog;

INSERT INTO worklog_archive 
SELECT * FROM worklog 
WHERE tstamp < DATE_SUB(NOW(), INTERVAL 2 YEAR);

DELETE FROM worklog 
WHERE tstamp < DATE_SUB(NOW(), INTERVAL 2 YEAR);

Backup-Strategie

Tägliches Backup (Cron)

# /etc/cron.daily/mysql-backup.sh
#!/bin/bash
mysqldump -u root -p'password' stechuhr2 > /backup/stechuhr2_$(date +\%Y\%m\%d).sql
find /backup -name "stechuhr2_*.sql" -mtime +30 -delete

Point-in-Time Recovery

Aktivieren Sie Binary Logging in MySQL:

# /etc/mysql/my.cnf
[mysqld]
log-bin=mysql-bin
expire_logs_days=7

Migration auf andere Datenbank

Die Repository-Struktur ermöglicht einfache Migration:

PostgreSQL

// Ersetzen Sie mysql2 durch pg
const { Pool } = require('pg');

MongoDB

// Erstellen Sie neue Repositories mit MongoDB
const mongodb = require('mongodb');

Der Service und Controller bleiben unverändert! 🎉

Nächste Schritte

  1. Datenbank konfiguriert und getestet
  2. 🔄 Frontend anpassen (optional)
  3. 🔄 Authentifizierung implementieren
  4. 🔄 Multi-User Support aktivieren
  5. 🔄 Backup-Automatisierung einrichten