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:
Torsten Schulz (local)
2025-10-17 14:11:28 +02:00
commit e95bb4cb76
86 changed files with 19530 additions and 0 deletions

View File

@@ -0,0 +1,100 @@
/**
* Rollback des Timezone-Fix
* Macht die Änderungen rückgängig
*/
const mysql = require('mysql2/promise');
const path = require('path');
require('dotenv').config({ path: path.join(__dirname, '.env') });
/**
* Prüft, ob ein Datum in der Sommerzeit liegt
*/
function isSummertime(date) {
const year = date.getFullYear();
const marchEnd = new Date(year, 2, 31);
const marchSunday = 31 - marchEnd.getDay();
const summerStart = new Date(year, 2, marchSunday, 2, 0, 0);
const octoberEnd = new Date(year, 9, 31);
const octoberSunday = 31 - octoberEnd.getDay();
const summerEnd = new Date(year, 9, octoberSunday, 3, 0, 0);
return date >= summerStart && date < summerEnd;
}
async function rollbackTimezones() {
let connection;
try {
connection = await mysql.createConnection({
host: process.env.DB_HOST || 'localhost',
user: process.env.DB_USER || 'root',
password: process.env.DB_PASSWORD || '',
database: process.env.DB_NAME || 'stechuhr2',
timezone: '+00:00'
});
console.log('✅ Datenbankverbindung hergestellt\n');
const [rows] = await connection.execute(
'SELECT id, tstamp FROM worklog ORDER BY id ASC'
);
console.log(`📊 Gefunden: ${rows.length} Worklog-Einträge\n`);
console.log('🔄 Wende Rollback an (addiere Offset zurück)...\n');
let updatedCount = 0;
for (const row of rows) {
const storedDate = new Date(row.tstamp);
// Erstelle lokales Datum aus UTC-Komponenten
const year = storedDate.getUTCFullYear();
const month = storedDate.getUTCMonth();
const day = storedDate.getUTCDate();
const hours = storedDate.getUTCHours();
const minutes = storedDate.getUTCMinutes();
const seconds = storedDate.getUTCSeconds();
const localDate = new Date(year, month, day, hours, minutes, seconds);
const offset = isSummertime(localDate) ? 2 : 1;
// Addiere den Offset ZURÜCK
const correctedDate = new Date(localDate.getTime() + (offset * 60 * 60 * 1000));
const correctedISO = correctedDate.toISOString().replace('T', ' ').replace('.000Z', '');
await connection.execute(
'UPDATE worklog SET tstamp = ? WHERE id = ?',
[correctedISO, row.id]
);
updatedCount++;
if (updatedCount % 100 === 0) {
console.log(` ${updatedCount}/${rows.length} aktualisiert...`);
}
}
console.log(`\n${updatedCount} Einträge erfolgreich zurückgesetzt!`);
} catch (error) {
console.error('❌ Fehler:', error);
process.exit(1);
} finally {
if (connection) {
await connection.end();
console.log('\n🔌 Datenbankverbindung geschlossen');
}
}
}
rollbackTimezones().then(() => {
process.exit(0);
}).catch(err => {
console.error('Fataler Fehler:', err);
process.exit(1);
});