884f26bf25
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.
127 lines
5.2 KiB
JavaScript
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;
|