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
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
- ✅ Datenbank konfiguriert und getestet
- 🔄 Frontend anpassen (optional)
- 🔄 Authentifizierung implementieren
- 🔄 Multi-User Support aktivieren
- 🔄 Backup-Automatisierung einrichten