Files
SkillMate/backend/scripts/seed-demo-data.ts
2025-09-29 00:35:31 +02:00

446 Zeilen
12 KiB
TypeScript

import dotenv from 'dotenv'
import { v4 as uuidv4 } from 'uuid'
import bcrypt from 'bcryptjs'
import { initializeSecureDatabase, encryptedDb, db } from '../src/config/secureDatabase'
import { initializeDatabase } from '../src/config/database'
import { FieldEncryption } from '../src/services/encryption'
dotenv.config()
initializeSecureDatabase()
initializeDatabase()
type SampleSkill = {
id: string
level: string
verified?: boolean
}
type SampleEmployee = {
firstName: string
lastName: string
username: string
email: string
role: 'admin' | 'superuser' | 'user'
department: string
position: string
employeeNumber: string
phone: string
mobile?: string
office?: string
availability?: string
skills: SampleSkill[]
languages?: { language: string; proficiency: string; certified?: number }[]
clearance?: { level: string; validUntil: string; issuedDate: string }
}
const SAMPLE_EMPLOYEES: SampleEmployee[] = [
{
firstName: 'Anna',
lastName: 'Meyer',
username: 'a.meyer',
email: 'anna.meyer@example.local',
role: 'admin',
department: 'Leitungsstab',
position: 'Leitung PMO',
employeeNumber: 'SM-001',
phone: '+49 201 123-1001',
mobile: '+49 171 2001001',
office: 'LS-2.14',
availability: 'available',
skills: [
{ id: 'communication.languages.de', level: '9', verified: true },
{ id: 'analytical.data_analysis.statistics', level: '7' },
{ id: 'technical.programming.python', level: '6' }
],
languages: [
{ language: 'de', proficiency: 'C2', certified: 1 },
{ language: 'en', proficiency: 'C1' }
],
clearance: {
level: 'Ü3',
validUntil: '2027-06-30',
issuedDate: '2022-07-01'
}
},
{
firstName: 'Daniel',
lastName: 'Schulz',
username: 'd.schulz',
email: 'daniel.schulz@example.local',
role: 'superuser',
department: 'Cybercrime',
position: 'Teamleiter Digitale Forensik',
employeeNumber: 'SM-002',
phone: '+49 201 123-1002',
mobile: '+49 171 2001002',
office: 'CC-3.04',
availability: 'available',
skills: [
{ id: 'technical.security.forensics', level: '8', verified: true },
{ id: 'analytical.intelligence.threat', level: '6' },
{ id: 'technical.programming.python', level: '5' }
],
languages: [
{ language: 'de', proficiency: 'C1' },
{ language: 'en', proficiency: 'B2' }
]
},
{
firstName: 'Miriam',
lastName: 'Koch',
username: 'm.koch',
email: 'miriam.koch@example.local',
role: 'user',
department: 'Kriminalprävention',
position: 'Referentin Prävention',
employeeNumber: 'SM-003',
phone: '+49 201 123-1003',
availability: 'busy',
skills: [
{ id: 'communication.interpersonal.presentation', level: '7' },
{ id: 'operational.investigation.interrogation', level: '4' }
],
languages: [
{ language: 'de', proficiency: 'C2' },
{ language: 'fr', proficiency: 'B2' }
]
},
{
firstName: 'Jonas',
lastName: 'Becker',
username: 'j.becker',
email: 'jonas.becker@example.local',
role: 'user',
department: 'Cybercrime',
position: 'Analyst OSINT',
employeeNumber: 'SM-004',
phone: '+49 201 123-1004',
skills: [
{ id: 'analytical.intelligence.osint', level: '8', verified: true },
{ id: 'analytical.intelligence.pattern', level: '6' }
],
languages: [
{ language: 'de', proficiency: 'C1' },
{ language: 'en', proficiency: 'C1' }
]
},
{
firstName: 'Leonie',
lastName: 'Graf',
username: 'l.graf',
email: 'leonie.graf@example.local',
role: 'superuser',
department: 'Organisierte Kriminalität',
position: 'Ermittlerin',
employeeNumber: 'SM-005',
phone: '+49 201 123-1005',
availability: 'available',
skills: [
{ id: 'operational.investigation.surveillance', level: '7' },
{ id: 'operational.tactical.planning', level: '6' }
],
clearance: {
level: 'Ü2',
validUntil: '2026-05-15',
issuedDate: '2021-05-16'
}
},
{
firstName: 'Yusuf',
lastName: 'Öztürk',
username: 'y.oeztuerk',
email: 'yusuf.oeztuerk@example.local',
role: 'user',
department: 'Cybercrime',
position: 'Incident Responder',
employeeNumber: 'SM-006',
phone: '+49 201 123-1006',
skills: [
{ id: 'technical.security.siem', level: '7' },
{ id: 'technical.security.malware', level: '5' }
],
languages: [
{ language: 'de', proficiency: 'C1' },
{ language: 'tr', proficiency: 'C1' }
]
},
{
firstName: 'Klara',
lastName: 'Heinrich',
username: 'k.heinrich',
email: 'klara.heinrich@example.local',
role: 'user',
department: 'Kriminalprävention',
position: 'Datenanalystin',
employeeNumber: 'SM-007',
phone: '+49 201 123-1007',
skills: [
{ id: 'analytical.data_analysis.statistics', level: '8' },
{ id: 'analytical.data_analysis.financial', level: '6' }
]
},
{
firstName: 'Sebastian',
lastName: 'Ulrich',
username: 's.ulrich',
email: 'sebastian.ulrich@example.local',
role: 'user',
department: 'Cybercrime',
position: 'Digitaler Spurensicherer',
employeeNumber: 'SM-008',
phone: '+49 201 123-1008',
availability: 'offline',
skills: [
{ id: 'operational.investigation.evidence', level: '7', verified: true },
{ id: 'technical.security.forensics', level: '6' }
]
},
{
firstName: 'Jana',
lastName: 'Reuter',
username: 'j.reuter',
email: 'jana.reuter@example.local',
role: 'superuser',
department: 'Nachrichtendienstliche Analyse',
position: 'Analystin Gefährdungsbewertung',
employeeNumber: 'SM-009',
phone: '+49 201 123-1009',
skills: [
{ id: 'analytical.intelligence.threat', level: '8', verified: true },
{ id: 'analytical.intelligence.risk', level: '7' }
],
languages: [
{ language: 'de', proficiency: 'C2' },
{ language: 'en', proficiency: 'C1' },
{ language: 'ru', proficiency: 'B2' }
]
},
{
firstName: 'Harald',
lastName: 'Pohl',
username: 'h.pohl',
email: 'harald.pohl@example.local',
role: 'user',
department: 'Mobiles Einsatzkommando',
position: 'Einsatzführer',
employeeNumber: 'SM-010',
phone: '+49 201 123-1010',
availability: 'available',
skills: [
{ id: 'operational.tactical.protection', level: '8' },
{ id: 'certifications.weapons.sniper', level: '7', verified: true }
],
clearance: {
level: 'Ü2',
validUntil: '2025-12-31',
issuedDate: '2020-01-01'
}
},
{
firstName: 'Melanie',
lastName: 'Franke',
username: 'm.franke',
email: 'melanie.franke@example.local',
role: 'user',
department: 'Kriminalprävention',
position: 'Projektmanagerin Prävention',
employeeNumber: 'SM-011',
phone: '+49 201 123-1011',
skills: [
{ id: 'communication.interpersonal.teamwork', level: '8' },
{ id: 'communication.interpersonal.conflict', level: '6' }
]
},
{
firstName: 'Farid',
lastName: 'Rahmani',
username: 'f.rahmani',
email: 'farid.rahmani@example.local',
role: 'user',
department: 'Cybercrime',
position: 'Entwickler Automatisierung',
employeeNumber: 'SM-012',
phone: '+49 201 123-1012',
skills: [
{ id: 'technical.programming.javascript', level: '7' },
{ id: 'technical.programming.python', level: '8' }
],
languages: [
{ language: 'de', proficiency: 'B2' },
{ language: 'fa', proficiency: 'C1' }
]
},
{
firstName: 'Lena',
lastName: 'Zimmer',
username: 'l.zimmer',
email: 'lena.zimmer@example.local',
role: 'user',
department: 'Kriminalprävention',
position: 'Datenvisualisierung',
employeeNumber: 'SM-013',
phone: '+49 201 123-1013',
availability: 'busy',
skills: [
{ id: 'analytical.data_analysis.network_analysis', level: '6' },
{ id: 'communication.presentation.presentation', level: '5' }
]
},
{
firstName: 'Erik',
lastName: 'Brandt',
username: 'e.brandt',
email: 'erik.brandt@example.local',
role: 'superuser',
department: 'Nachrichtendienstliche Analyse',
position: 'Projektleiter Prognosemodelle',
employeeNumber: 'SM-014',
phone: '+49 201 123-1014',
skills: [
{ id: 'analytical.intelligence.forecasting', level: '8' },
{ id: 'analytical.data_analysis.statistics', level: '7' }
],
languages: [
{ language: 'de', proficiency: 'C1' },
{ language: 'en', proficiency: 'C1' }
]
},
{
firstName: 'Sofia',
lastName: 'Lindner',
username: 's.lindner',
email: 'sofia.lindner@example.local',
role: 'user',
department: 'Cybercrime',
position: 'Malware Analystin',
employeeNumber: 'SM-015',
phone: '+49 201 123-1015',
skills: [
{ id: 'technical.security.malware', level: '8' },
{ id: 'technical.security.crypto', level: '6' }
],
languages: [
{ language: 'de', proficiency: 'C1' },
{ language: 'en', proficiency: 'B2' }
]
}
]
const PASSWORD = 'test123'
const deleteExistingByUsername = db.prepare('DELETE FROM users WHERE username = ?')
const deleteEmployeeById = db.prepare('DELETE FROM employees WHERE id = ?')
const selectUserByUsername = db.prepare('SELECT id, employee_id FROM users WHERE username = ?')
const deleteEmployeeSkills = db.prepare('DELETE FROM employee_skills WHERE employee_id = ?')
const deleteLanguageSkills = db.prepare('DELETE FROM language_skills WHERE employee_id = ?')
const insertSkill = db.prepare(`
INSERT INTO employee_skills (
employee_id, skill_id, level, verified, verified_by, verified_date
) VALUES (?, ?, ?, ?, ?, ?)
`)
const insertLanguage = db.prepare(`
INSERT INTO language_skills (
id, employee_id, language, proficiency, certified, certificate_type, is_native, can_interpret
) VALUES (?, ?, ?, ?, ?, ?, 0, 0)
`)
const insertUser = db.prepare(`
INSERT INTO users (
id, username, email, email_hash, password, role, employee_id, is_active, created_at, updated_at
) VALUES (?, ?, ?, ?, ?, ?, ?, 1, ?, ?)
`)
const nowIso = () => new Date().toISOString()
const hashPassword = (plain: string) => bcrypt.hashSync(plain, 12)
function upsertEmployee(sample: SampleEmployee) {
const existingUser = selectUserByUsername.get(sample.username) as { id: string; employee_id: string } | undefined
if (existingUser) {
deleteEmployeeSkills.run(existingUser.employee_id)
deleteLanguageSkills.run(existingUser.employee_id)
deleteEmployeeById.run(existingUser.employee_id)
deleteExistingByUsername.run(sample.username)
}
const employeeId = uuidv4()
const createdAt = nowIso()
const availability = sample.availability || 'available'
encryptedDb.insertEmployee({
id: employeeId,
first_name: sample.firstName,
last_name: sample.lastName,
employee_number: sample.employeeNumber,
photo: null,
position: sample.position,
department: sample.department,
email: sample.email,
phone: sample.phone,
mobile: sample.mobile || null,
office: sample.office || null,
availability,
clearance_level: sample.clearance?.level || null,
clearance_valid_until: sample.clearance?.validUntil || null,
clearance_issued_date: sample.clearance?.issuedDate || null,
primary_unit_id: null,
created_at: createdAt,
updated_at: createdAt,
created_by: 'system'
})
const verifiedBy = sample.role === 'admin' ? 'system-admin' : 'system'
for (const skill of sample.skills) {
insertSkill.run(
employeeId,
skill.id,
skill.level,
skill.verified ? 1 : 0,
skill.verified ? verifiedBy : null,
skill.verified ? createdAt : null
)
}
for (const language of sample.languages || []) {
insertLanguage.run(
uuidv4(),
employeeId,
language.language,
language.proficiency,
language.certified || 0,
language.certified ? 'Zertifikat' : null
)
}
const userId = uuidv4()
const encryptedEmail = FieldEncryption.encrypt(sample.email) || ''
const emailHash = FieldEncryption.hash(sample.email)
const hashedPassword = hashPassword(PASSWORD)
const timestamps = nowIso()
insertUser.run(
userId,
sample.username,
encryptedEmail,
emailHash,
hashedPassword,
sample.role,
employeeId,
timestamps,
timestamps
)
}
db.transaction(() => {
for (const employee of SAMPLE_EMPLOYEES) {
upsertEmployee(employee)
}
})()
console.log(`${SAMPLE_EMPLOYEES.length} Demo-Mitarbeitende mit Passwort "${PASSWORD}" angelegt.`)