Files
ressourcenplanung/server/db.js
T
admin 884f26bf25 Migrate existing employees.name to first_name/last_name in-place
Bestehende Deployments mit dem alten name-Feld verlieren beim Redeploy
keine Daten mehr: db.js erkennt das alte Schema (PRAGMA table_info),
splittet name in first_name/last_name und übernimmt alle Zeilen, statt
die Tabelle neu anzulegen. Läuft nur einmal (Spalte "name" existiert
danach nicht mehr) und lässt neue Datenbanken unverändert.
2026-07-04 00:13:10 +02:00

127 lines
5.2 KiB
JavaScript

const path = require('path');
const fs = require('fs');
const Database = require('better-sqlite3');
const dataDir = path.join(__dirname, 'data');
if (!fs.existsSync(dataDir)) fs.mkdirSync(dataDir, { recursive: true });
const dbPath = path.join(dataDir, 'data.db');
const isNew = !fs.existsSync(dbPath);
const db = new Database(dbPath);
db.pragma('foreign_keys = ON');
const schema = fs.readFileSync(path.join(__dirname, 'schema.sql'), 'utf8');
db.exec(schema);
migrateEmployeeName();
if (isNew) {
seed();
}
// Ältere Deployments hatten ein einzelnes "name"-Feld statt first_name/last_name.
// Bestehende Daten werden erhalten, indem der Name gesplittet statt die Tabelle neu angelegt wird.
function migrateEmployeeName() {
const columns = db.prepare('PRAGMA table_info(employees)').all().map((c) => c.name);
if (!columns.includes('name') || columns.includes('first_name')) return;
db.exec('ALTER TABLE employees ADD COLUMN first_name TEXT');
db.exec('ALTER TABLE employees ADD COLUMN last_name TEXT');
const rows = db.prepare('SELECT id, name FROM employees').all();
const update = db.prepare('UPDATE employees SET first_name = ?, last_name = ? WHERE id = ?');
for (const row of rows) {
const parts = (row.name || '').trim().split(/\s+/);
const first_name = parts.shift() || '';
const last_name = parts.join(' ');
update.run(first_name, last_name, row.id);
}
db.exec('ALTER TABLE employees DROP COLUMN name');
}
function seed() {
const insertEmployee = db.prepare(
'INSERT INTO employees (first_name, last_name, email, role, weekly_capacity_hours) VALUES (?, ?, ?, ?, ?)'
);
const employees = [
['Anna', 'Keller', 'anna.keller@example.com', 'Frontend-Entwicklerin', 40],
['Jonas', 'Weber', 'jonas.weber@example.com', 'Backend-Entwickler', 40],
['Mira', 'Schulz', 'mira.schulz@example.com', 'UX-Designerin', 32],
['Tom', 'Fischer', 'tom.fischer@example.com', 'Projektleiter', 40],
['Lea', 'Hoffmann', 'lea.hoffmann@example.com', 'QA-Ingenieurin', 30],
];
const employeeIds = employees.map((e) => insertEmployee.run(...e).lastInsertRowid);
const insertTeam = db.prepare('INSERT INTO teams (name, description) VALUES (?, ?)');
const teamWeb = insertTeam.run('Web-Team', 'Frontend & Backend fürs Kundenportal').lastInsertRowid;
const teamDesign = insertTeam.run('Design-Team', 'UX/UI und Prototyping').lastInsertRowid;
const insertMember = db.prepare(
'INSERT INTO team_members (team_id, employee_id) VALUES (?, ?)'
);
insertMember.run(teamWeb, employeeIds[0]);
insertMember.run(teamWeb, employeeIds[1]);
insertMember.run(teamWeb, employeeIds[3]);
insertMember.run(teamDesign, employeeIds[2]);
insertMember.run(teamDesign, employeeIds[3]);
const insertProject = db.prepare(
'INSERT INTO projects (name, description, start_date, end_date, color) VALUES (?, ?, ?, ?, ?)'
);
const projectPortal = insertProject.run(
'Kundenportal Relaunch',
'Neugestaltung des Self-Service-Portals',
'2026-07-01',
'2026-08-28',
'#4f46e5'
).lastInsertRowid;
const projectApp = insertProject.run(
'Mobile App v2',
'Neue Funktionen für die mobile App',
'2026-07-06',
'2026-09-18',
'#059669'
).lastInsertRowid;
const insertTask = db.prepare(
'INSERT INTO tasks (project_id, name, start_date, end_date, estimated_hours, status) VALUES (?, ?, ?, ?, ?, ?)'
);
const t1 = insertTask.run(projectPortal, 'Konzept & Wireframes', '2026-07-01', '2026-07-10', 40, 'in Arbeit').lastInsertRowid;
const t2 = insertTask.run(projectPortal, 'Frontend-Umsetzung', '2026-07-13', '2026-08-07', 120, 'geplant').lastInsertRowid;
const t3 = insertTask.run(projectPortal, 'Backend-API', '2026-07-13', '2026-08-07', 100, 'geplant').lastInsertRowid;
const t4 = insertTask.run(projectPortal, 'QA & Rollout', '2026-08-10', '2026-08-28', 60, 'geplant').lastInsertRowid;
const t5 = insertTask.run(projectApp, 'Anforderungsanalyse', '2026-07-06', '2026-07-17', 30, 'in Arbeit').lastInsertRowid;
const t6 = insertTask.run(projectApp, 'Umsetzung Feature-Set', '2026-07-20', '2026-09-04', 150, 'geplant').lastInsertRowid;
const t7 = insertTask.run(projectApp, 'Test & Release', '2026-09-07', '2026-09-18', 50, 'geplant').lastInsertRowid;
const insertDependency = db.prepare(
'INSERT INTO task_dependencies (task_id, depends_on_task_id) VALUES (?, ?)'
);
insertDependency.run(t2, t1);
insertDependency.run(t3, t1);
insertDependency.run(t4, t2);
insertDependency.run(t4, t3);
insertDependency.run(t6, t5);
insertDependency.run(t7, t6);
const insertAssignment = db.prepare(
'INSERT INTO assignments (task_id, employee_id, allocated_hours_per_week) VALUES (?, ?, ?)'
);
insertAssignment.run(t1, employeeIds[2], 20);
insertAssignment.run(t1, employeeIds[3], 10);
insertAssignment.run(t2, employeeIds[0], 32);
insertAssignment.run(t3, employeeIds[1], 32);
insertAssignment.run(t4, employeeIds[4], 24);
insertAssignment.run(t4, employeeIds[3], 8);
insertAssignment.run(t5, employeeIds[3], 16);
insertAssignment.run(t5, employeeIds[2], 12);
insertAssignment.run(t6, employeeIds[0], 20);
insertAssignment.run(t6, employeeIds[1], 24);
insertAssignment.run(t7, employeeIds[4], 24);
}
module.exports = db;