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
This commit is contained in:
316
backend/DB_SETUP.md
Normal file
316
backend/DB_SETUP.md
Normal file
@@ -0,0 +1,316 @@
|
||||
# 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:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Bearbeiten Sie die `.env` Datei mit Ihren Datenbankzugangsdaten:
|
||||
|
||||
```env
|
||||
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:
|
||||
|
||||
```bash
|
||||
mysql -u root -p
|
||||
```
|
||||
|
||||
```sql
|
||||
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:
|
||||
|
||||
```sql
|
||||
SELECT * FROM user WHERE id = 1;
|
||||
```
|
||||
|
||||
Falls kein Benutzer existiert, erstellen Sie einen:
|
||||
|
||||
```sql
|
||||
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
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
npm install
|
||||
```
|
||||
|
||||
Dies installiert auch `mysql2` für die Datenbankverbindung.
|
||||
|
||||
### 5. Backend starten
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```sql
|
||||
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:
|
||||
|
||||
```sql
|
||||
-- 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!
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```javascript
|
||||
// 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
|
||||
|
||||
```bash
|
||||
# MySQL-Status prüfen
|
||||
sudo systemctl status mysql
|
||||
|
||||
# MySQL starten
|
||||
sudo systemctl start mysql
|
||||
|
||||
# Port prüfen
|
||||
netstat -an | grep 3306
|
||||
```
|
||||
|
||||
### Berechtigungen
|
||||
|
||||
```sql
|
||||
-- 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:
|
||||
|
||||
```javascript
|
||||
// In src/config/database.js
|
||||
connectionLimit: 10 // Erhöhen auf 20 oder mehr
|
||||
```
|
||||
|
||||
### Debugging
|
||||
|
||||
Aktivieren Sie Query-Logging:
|
||||
|
||||
```javascript
|
||||
// In src/repositories/WorklogRepository.js
|
||||
console.log('SQL:', sql);
|
||||
console.log('Params:', params);
|
||||
```
|
||||
|
||||
## Performance-Tipps
|
||||
|
||||
### Indizes prüfen
|
||||
|
||||
```sql
|
||||
SHOW INDEX FROM worklog;
|
||||
```
|
||||
|
||||
Wichtige Indizes:
|
||||
- `worklog_user_id_IDX` (user_id, tstamp)
|
||||
- `worklog_tstamp_IDX` (tstamp)
|
||||
|
||||
### Query-Performance analysieren
|
||||
|
||||
```sql
|
||||
EXPLAIN SELECT * FROM worklog WHERE user_id = 1 ORDER BY tstamp DESC;
|
||||
```
|
||||
|
||||
### Alte Einträge archivieren
|
||||
|
||||
```sql
|
||||
-- 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)
|
||||
|
||||
```bash
|
||||
# /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:
|
||||
|
||||
```ini
|
||||
# /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
|
||||
|
||||
```javascript
|
||||
// Ersetzen Sie mysql2 durch pg
|
||||
const { Pool } = require('pg');
|
||||
```
|
||||
|
||||
### MongoDB
|
||||
|
||||
```javascript
|
||||
// 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
|
||||
|
||||
Reference in New Issue
Block a user