Rollback - PDF Import funzt so semi

Dieser Commit ist enthalten in:
Claude Project Manager
2025-09-23 22:40:37 +02:00
Ursprung 26f95d2e4a
Commit 2cabd4c0c6
27 geänderte Dateien mit 4455 neuen und 41 gelöschten Zeilen

Datei anzeigen

@ -0,0 +1,386 @@
const Database = require('better-sqlite3')
const path = require('path')
const { v4: uuidv4 } = require('uuid')
// Open database
const dbPath = path.join(__dirname, '..', 'skillmate.dev.encrypted.db')
const db = new Database(dbPath)
// Enable foreign keys
db.pragma('foreign_keys = ON')
console.log('🏢 Seeding LKA NRW Organizational Structure...')
const now = new Date().toISOString()
// Helper function to insert organizational unit
function insertUnit(code, name, type, level, parentId = null, options = {}) {
const id = uuidv4()
db.prepare(`
INSERT OR REPLACE INTO organizational_units (
id, code, name, type, level, parent_id,
color, order_index, has_fuehrungsstelle,
fuehrungsstelle_name, is_active, created_at, updated_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`).run(
id, code, name, type, level, parentId,
options.color || null,
options.orderIndex || 0,
options.hasFuehrungsstelle || 0,
options.fuehrungsstelleName || null,
1, now, now
)
return id
}
// Clear existing data
console.log('Clearing existing organizational data...')
db.prepare('DELETE FROM deputy_delegations').run()
db.prepare('DELETE FROM deputy_assignments').run()
db.prepare('DELETE FROM special_positions').run()
db.prepare('DELETE FROM employee_unit_assignments').run()
db.prepare('DELETE FROM organizational_units').run()
// Create Direktor
const direktorId = insertUnit('DIR', 'Direktor LKA NRW', 'direktion', 0, null, {
color: '#1e3a8a',
orderIndex: 0
})
// Create Leitungsstab
const leitungsstabId = insertUnit('LStab', 'Leitungsstab', 'stabsstelle', 1, direktorId, {
color: '#6b7280',
orderIndex: 1
})
// Leitungsstab Sub-units
insertUnit('LStab 1', 'Grundsatzangelegenheiten, Gremien, internationale polizeiliche Zusammenarbeit', 'sachgebiet', 2, leitungsstabId)
insertUnit('LStab 2', 'Strategische Steuerung, Qualitätsmanagement, Controlling', 'sachgebiet', 2, leitungsstabId)
insertUnit('LStab 3', 'Presse- und Öffentlichkeitsarbeit', 'sachgebiet', 2, leitungsstabId)
// Create Special Units (Beauftragte)
const personalratId = insertUnit('PR', 'Personalrat', 'sondereinheit', 1, direktorId, {
color: '#059669',
orderIndex: 2
})
const schwerbehindertenId = insertUnit('SBV', 'Schwerbehindertenvertretung', 'sondereinheit', 1, direktorId, {
color: '#059669',
orderIndex: 3
})
// Create Abteilungen with color gradients
const abteilungen = [
{ code: 'Abt 1', name: 'Organisierte Kriminalität', color: '#dc2626' },
{ code: 'Abt 2', name: 'Terrorismusbekämpfung und Staatsschutz', color: '#ea580c' },
{ code: 'Abt 3', name: 'Strategische Kriminalitätsbekämpfung', color: '#0891b2' },
{ code: 'Abt 4', name: 'Cybercrime (CCCC)', color: '#7c3aed' },
{ code: 'Abt 5', name: 'Kriminalwissenschaftliches und -technisches Institut', color: '#0d9488' },
{ code: 'Abt 6', name: 'Fachaufsicht und Ermittlungsunterstützung', color: '#be185d' },
{ code: 'ZA', name: 'Zentralabteilung', color: '#6b7280' }
]
const abteilungIds = {}
abteilungen.forEach((abt, index) => {
abteilungIds[abt.code] = insertUnit(abt.code, abt.name, 'abteilung', 1, direktorId, {
color: abt.color,
orderIndex: 10 + index * 10,
hasFuehrungsstelle: abt.code !== 'ZA' ? 1 : 0,
fuehrungsstelleName: abt.code !== 'ZA' ? `Führungsstelle ${abt.code}` : null
})
})
// Create Dezernate for Abteilung 1 (Organisierte Kriminalität)
const dezernate1 = [
{ code: '11', name: 'Ermittlungen OK, OK Rauschgift' },
{ code: '12', name: 'Wirtschaftskriminalität' },
{ code: '13', name: 'Finanzermittlungen' },
{ code: '14', name: 'Auswerte- und Analysestelle OK' },
{ code: '15', name: 'Korruption, Umweltkriminalität' },
{ code: '16', name: 'Finanzierung Organisierter Kriminalität und Terrorismus' }
]
dezernate1.forEach((dez, index) => {
const dezId = insertUnit(`Dezernat ${dez.code}`, dez.name, 'dezernat', 2, abteilungIds['Abt 1'], {
orderIndex: index
})
// Add sample Sachgebiete
if (dez.code === '11') {
insertUnit('SG 11.1', 'Grundsatzfragen/Koordination/Auswertung', 'sachgebiet', 3, dezId)
}
if (dez.code === '12') {
insertUnit('SG 12.1', 'Grundsatzfragen/Koordination/Auswertung', 'sachgebiet', 3, dezId)
}
if (dez.code === '13') {
insertUnit('SG 13.1', 'GFG 1', 'sachgebiet', 3, dezId)
insertUnit('SG 13.2', 'GFG 2', 'sachgebiet', 3, dezId)
insertUnit('SG 13.3', 'Verfahrensintegrierte Finanzermittlungen/Vermögensabschöpfung', 'sachgebiet', 3, dezId)
insertUnit('SG 13.4', 'Zentrale Informations- und Koordinierungsstelle Finanzermittlung', 'sachgebiet', 3, dezId)
}
if (dez.code === '14') {
insertUnit('TD 14.1', 'Operative Auswertung und Analyse', 'teildezernat', 3, dezId)
insertUnit('SG 14.2', 'Strategische Auswertung und Analyse', 'sachgebiet', 3, dezId)
insertUnit('SG 14.3', 'Technische Informationssysteme', 'sachgebiet', 3, dezId)
insertUnit('SG 14.4', 'Auswertung und Analyse Rockerkriminalität', 'sachgebiet', 3, dezId)
insertUnit('SG 14.5', 'Auswertung und Analyse Clankriminalität', 'sachgebiet', 3, dezId)
}
if (dez.code === '15') {
insertUnit('SG 15.1', 'Grundsatzangelegenheiten, Korruption', 'sachgebiet', 3, dezId)
insertUnit('SG 15.2', 'Vernetzungsstelle Umweltkriminalität', 'sachgebiet', 3, dezId)
}
if (dez.code === '16') {
insertUnit('SG 16.1', 'Grundsatzfragen/Auswertung/Analyse', 'sachgebiet', 3, dezId)
}
})
// Create Dezernate for Abteilung 2 (Terrorismusbekämpfung)
const dezernate2 = [
{ code: '21', name: 'Ermittlungen' },
{ code: '22', name: 'Auswertung/Analyse, ZMI, OSINT, Wissenschaftlicher Dienst PMK' },
{ code: '23', name: 'PMK Rechts und PMK SZ' },
{ code: '24', name: 'PMK Religiöse Ideologie' },
{ code: '25', name: 'PMK Links, Ausländische Ideologie, ZSÜ' }
]
dezernate2.forEach((dez, index) => {
const dezId = insertUnit(`Dezernat ${dez.code}`, dez.name, 'dezernat', 2, abteilungIds['Abt 2'], {
orderIndex: index
})
if (dez.code === '21') {
insertUnit('TD 21.1', 'Ermittlungskommissionen VSTGB', 'teildezernat', 3, dezId)
}
if (dez.code === '22') {
insertUnit('SG 22.1', 'Auswertung/Analyse, ZMI', 'sachgebiet', 3, dezId)
insertUnit('TD 22.2', 'Open Source Intelligence (OSINT)', 'teildezernat', 3, dezId)
insertUnit('TD 22.3', 'Wissenschaftlicher Dienst PMK', 'teildezernat', 3, dezId)
insertUnit('SG 22.4', 'PMK Meldedienste, KPMD', 'sachgebiet', 3, dezId)
}
if (dez.code === '23') {
insertUnit('SG 23.1', 'KoSt Gefährder, GETZ-Rechts', 'sachgebiet', 3, dezId)
insertUnit('SG 23.2', 'Prüffallbearbeitung, Gefahrensachverhalte', 'sachgebiet', 3, dezId)
insertUnit('TD 23.3', 'PMK SZ, Spionage', 'teildezernat', 3, dezId)
}
if (dez.code === '24') {
insertUnit('SG 24.1', 'KoST Gefährder, SiKo', 'sachgebiet', 3, dezId)
insertUnit('TD 24.2', 'Gemeinsames Terrorismusabwehrzentrum (GTAZ) NRW', 'teildezernat', 3, dezId)
insertUnit('SG 24.3', 'Prüffallbearbeitung, islamistisch-terroristisches Personenpotential', 'sachgebiet', 3, dezId)
}
if (dez.code === '25') {
insertUnit('SG 25.1', 'KoSt Gefährder Links', 'sachgebiet', 3, dezId)
insertUnit('SG 25.2', 'KoSt Gefährder Ausländische Ideologie', 'sachgebiet', 3, dezId)
insertUnit('SG 25.3', 'Zentrale Stelle NRW für ZSÜ', 'sachgebiet', 3, dezId)
}
})
// Create Dezernate for Abteilung 3 (Strategische Kriminalitätsbekämpfung)
const dezernate3 = [
{ code: '31', name: 'Kriminalitätsauswertung und Analyse' },
{ code: '32', name: 'Kriminalprävention, KKF, Evaluation' },
{ code: '33', name: 'Fahndung, Datenaustausch, Kriminalaktenhaltung' },
{ code: '34', name: 'Digitalstrategie, Polizeifachliche IT' },
{ code: '35', name: 'Verhaltensanalyse und Risikomanagement' }
]
dezernate3.forEach((dez, index) => {
const dezId = insertUnit(`Dezernat ${dez.code}`, dez.name, 'dezernat', 2, abteilungIds['Abt 3'], {
orderIndex: index
})
if (dez.code === '31') {
insertUnit('SG 31.1', 'Grundsatzangelegenheiten/KoST MAfEx', 'sachgebiet', 3, dezId)
insertUnit('SG 31.2', 'Auswertung und Analyse 1', 'sachgebiet', 3, dezId)
insertUnit('SG 31.3', 'Auswertung/Analyse 2', 'sachgebiet', 3, dezId)
insertUnit('SG 31.4', 'Polizeiliche Kriminalstatistik (PKS)', 'sachgebiet', 3, dezId)
}
if (dez.code === '32') {
insertUnit('SG 32.1', 'Kriminalprävention und Opferschutz', 'sachgebiet', 3, dezId)
insertUnit('TD 32.2', 'Kriminalistisch-Kriminologische Forschungsstelle (KKF)', 'teildezernat', 3, dezId)
insertUnit('SG 32.3', 'Zentralstelle Evaluation (ZEVA)', 'sachgebiet', 3, dezId)
}
if (dez.code === '33') {
insertUnit('SG 33.1', 'Datenstation, Polizeiliche Beobachtung', 'sachgebiet', 3, dezId)
insertUnit('SG 33.2', 'Datenaustausch Polizei/Justiz', 'sachgebiet', 3, dezId)
insertUnit('SG 33.3', 'Rechtshilfe, PNR, internationale Fahndung', 'sachgebiet', 3, dezId)
}
if (dez.code === '34') {
insertUnit('TD 34.1', 'Grundsatz, Gremien, Fachliche IT-Projekte', 'teildezernat', 3, dezId)
insertUnit('TD 34.2', 'Zentralstelle Polizei 2020', 'teildezernat', 3, dezId)
insertUnit('TD 34.3', 'IT FaKo Fachbereich Kriminalität', 'teildezernat', 3, dezId)
}
if (dez.code === '35') {
insertUnit('SG 35.1', 'Zentralstelle KURS NRW', 'sachgebiet', 3, dezId)
insertUnit('SG 35.2', 'Operative Fallanalyse (OFA/ViCLAS)', 'sachgebiet', 3, dezId)
insertUnit('SG 35.3', 'Zentralstelle PeRiskoP', 'sachgebiet', 3, dezId)
}
})
// Create Dezernate for Abteilung 4 (Cybercrime)
const dezernate4 = [
{ code: '41', name: 'Zentrale Ansprechstelle Cybercrime, Grundsatz, Digitale Forensik' },
{ code: '42', name: 'Cyber-Recherche- und Fahndungszentrum' },
{ code: '43', name: 'Zentrale Auswertungs- und Sammelstelle (ZASt)' },
{ code: '44', name: 'Telekommunikationsüberwachung (TKÜ)' }
]
dezernate4.forEach((dez, index) => {
const dezId = insertUnit(`Dezernat ${dez.code}`, dez.name, 'dezernat', 2, abteilungIds['Abt 4'], {
orderIndex: index
})
if (dez.code === '41') {
insertUnit('SG 41.1', 'Grundsatzangelegenheiten, Prävention', 'sachgebiet', 3, dezId)
insertUnit('TD 41.2', 'Software und KI-Entwicklung', 'teildezernat', 3, dezId)
insertUnit('SG 41.3', 'Forensik Desktop Strategie', 'sachgebiet', 3, dezId)
insertUnit('SG 41.4', 'Forensik Desktop Datenaufbereitung', 'sachgebiet', 3, dezId)
insertUnit('TD 41.5', 'Forensik Desktop Betrieb', 'teildezernat', 3, dezId)
}
if (dez.code === '42') {
insertUnit('SG 42.1', 'Personenorientierte Recherche in Datennetzen', 'sachgebiet', 3, dezId)
insertUnit('SG 42.2', 'Sachorientierte Recherche in Datennetzen', 'sachgebiet', 3, dezId)
insertUnit('TD 42.3', 'Interventionsteams Digitale Tatorte', 'teildezernat', 3, dezId)
}
if (dez.code === '43') {
insertUnit('SG 43.1', 'ZASt Grundsatz', 'sachgebiet', 3, dezId)
insertUnit('SG 43.2', 'ZASt NCMEC/Landeszentrale Bewertung 1', 'sachgebiet', 3, dezId)
insertUnit('SG 43.3', 'ZASt NCMEC/Landeszentrale Bewertung 2', 'sachgebiet', 3, dezId)
insertUnit('SG 43.4', 'ZASt NCMEC/Landeszentrale Bewertung 3', 'sachgebiet', 3, dezId)
}
if (dez.code === '44') {
insertUnit('SG 44.1', 'Grundsatzaufgaben, operative TKÜ', 'sachgebiet', 3, dezId)
insertUnit('SG 44.2', 'TKÜ Betrieb und Service', 'sachgebiet', 3, dezId)
insertUnit('TD 44.3', 'Digitale Forensik, IUK-Ermittlungsunterstützung', 'teildezernat', 3, dezId)
}
})
// Create Dezernate for Abteilung 5 (Kriminalwissenschaftliches Institut)
const dezernate5 = [
{ code: '51', name: 'Chemie, Physik' },
{ code: '52', name: 'Serologie, DNA-Analytik' },
{ code: '53', name: 'Biologie, Materialspuren, Urkunden' },
{ code: '54', name: 'Zentralstelle Kriminaltechnik, Forensische Medientechnik' },
{ code: '55', name: 'Waffen und Werkzeug, DNA-Analyse-Datei' },
{ code: '56', name: 'Daktyloskopie, Gesichts- und Sprechererkennung' }
]
dezernate5.forEach((dez, index) => {
const dezId = insertUnit(`Dezernat ${dez.code}`, dez.name, 'dezernat', 2, abteilungIds['Abt 5'], {
orderIndex: index
})
if (dez.code === '51') {
insertUnit('TD 51.1', 'Schussspuren, Explosivstoffe, Brand', 'teildezernat', 3, dezId)
insertUnit('TD 51.2', 'Betäubungsmittel', 'teildezernat', 3, dezId)
}
if (dez.code === '52') {
insertUnit('TD 52.1', 'DNA-Probenbearbeitung', 'teildezernat', 3, dezId)
insertUnit('TD 52.2', 'DNA-Spurenbearbeitung II', 'teildezernat', 3, dezId)
insertUnit('TD 52.3', 'DNA-Spurenbearbeitung III', 'teildezernat', 3, dezId)
insertUnit('TD 52.4', 'DNA-Spurenbearbeitung IV', 'teildezernat', 3, dezId)
}
if (dez.code === '53') {
insertUnit('TD 53.1', 'Forensische Textilkunde, Botanik', 'teildezernat', 3, dezId)
insertUnit('SG 53.2', 'Urkunden, Handschriften', 'sachgebiet', 3, dezId)
}
if (dez.code === '54') {
insertUnit('SG 54.1', 'Zentralstelle Kriminaltechnik', 'sachgebiet', 3, dezId)
insertUnit('SG 54.2', 'Tatortvermessung, Rekonstruktion und XR-Lab', 'sachgebiet', 3, dezId)
insertUnit('SG 54.3', 'Entschärfung von USBV', 'sachgebiet', 3, dezId)
}
if (dez.code === '55') {
insertUnit('SG 55.1', 'Waffen und Munition', 'sachgebiet', 3, dezId)
insertUnit('SG 55.2', 'Werkzeug-, Form-, Passspuren', 'sachgebiet', 3, dezId)
insertUnit('SG 55.3', 'DNA-Analyse-Datei', 'sachgebiet', 3, dezId)
}
if (dez.code === '56') {
insertUnit('SG 56.1', 'Daktyloskopisches Labor', 'sachgebiet', 3, dezId)
insertUnit('SG 56.2', 'AFIS I/Daktyloskopische Gutachten', 'sachgebiet', 3, dezId)
insertUnit('SG 56.3', 'AFIS II/Daktyloskopische Gutachten', 'sachgebiet', 3, dezId)
insertUnit('TD 56.4', 'Gesichts- und Sprechererkennung', 'teildezernat', 3, dezId)
}
})
// Create Dezernate for Abteilung 6 (Fachaufsicht)
const dezernate6 = [
{ code: '61', name: 'Kriminalitätsangelegenheiten der KPB, Fachcontrolling' },
{ code: '62', name: 'Fahndungsgruppe Staatsschutz' },
{ code: '63', name: 'Verdeckte Ermittlungen, Zeugenschutz' },
{ code: '64', name: 'Mobiles Einsatzkommando, TEG, Zielfahndung' }
]
dezernate6.forEach((dez, index) => {
const dezId = insertUnit(`Dezernat ${dez.code}`, dez.name, 'dezernat', 2, abteilungIds['Abt 6'], {
orderIndex: index
})
if (dez.code === '61') {
insertUnit('TD 61.1', 'Kriminalitätsangelegenheiten der KPB', 'teildezernat', 3, dezId)
insertUnit('SG 61.2', 'Lagedienst', 'sachgebiet', 3, dezId)
}
if (dez.code === '62') {
for (let i = 1; i <= 9; i++) {
if (i === 9) {
insertUnit(`SG 62.${i}`, 'Technische Gruppe', 'sachgebiet', 3, dezId)
} else {
insertUnit(`SG 62.${i}`, `Fahndungsgruppe ${i}`, 'sachgebiet', 3, dezId)
}
}
}
if (dez.code === '63') {
insertUnit('SG 63.1', 'Einsatz VE 1', 'sachgebiet', 3, dezId)
insertUnit('SG 63.2', 'Einsatz VE 2', 'sachgebiet', 3, dezId)
insertUnit('SG 63.3', 'Scheinkäufer, Logistik', 'sachgebiet', 3, dezId)
insertUnit('SG 63.4', 'VP-Führung, Koordinierung VP', 'sachgebiet', 3, dezId)
insertUnit('TD 63.5', 'Zeugenschutz, OpOS', 'teildezernat', 3, dezId)
}
if (dez.code === '64') {
insertUnit('SG 64.1', 'MEK 1', 'sachgebiet', 3, dezId)
insertUnit('SG 64.2', 'MEK 2', 'sachgebiet', 3, dezId)
insertUnit('SG 64.3', 'Technische Einsatzgruppe', 'sachgebiet', 3, dezId)
insertUnit('SG 64.4', 'Zielfahndung', 'sachgebiet', 3, dezId)
}
})
// Create Dezernate for Zentralabteilung
const dezernateZA = [
{ code: 'ZA 1', name: 'Haushalts-, Wirtschafts-, Liegenschaftsmanagement' },
{ code: 'ZA 2', name: 'Personalangelegenheiten, Gleichstellungsbeauftragte' },
{ code: 'ZA 3', name: 'Informationstechnik und Anwenderunterstützung' },
{ code: 'ZA 4', name: 'Vereins- und Waffenrecht, Innenrevision' },
{ code: 'ZA 5', name: 'Polizeiärztlicher Dienst' }
]
dezernateZA.forEach((dez, index) => {
const dezId = insertUnit(`Dezernat ${dez.code}`, dez.name, 'dezernat', 2, abteilungIds['ZA'], {
orderIndex: index
})
if (dez.code === 'ZA 1') {
insertUnit('SG ZA 1.1', 'Haushalts- und Wirtschaftsangelegenheiten', 'sachgebiet', 3, dezId)
insertUnit('SG ZA 1.2', 'Liegenschaftsmanagement', 'sachgebiet', 3, dezId)
insertUnit('SG ZA 1.3', 'Zentrale Vergabestelle', 'sachgebiet', 3, dezId)
}
if (dez.code === 'ZA 2') {
insertUnit('SG ZA 2.1', 'Personalentwicklung, Arbeitszeit', 'sachgebiet', 3, dezId)
insertUnit('SG ZA 2.2', 'Personalverwaltung Beamte', 'sachgebiet', 3, dezId)
insertUnit('TD ZA 2.3', 'Personalverwaltung Regierungsbeschäftigte', 'teildezernat', 3, dezId)
insertUnit('SG ZA 2.4', 'Fortbildung', 'sachgebiet', 3, dezId)
}
if (dez.code === 'ZA 3') {
insertUnit('SG ZA 3.1', 'IT-Grundsatz, Planung und Koordinierung', 'sachgebiet', 3, dezId)
insertUnit('SG ZA 3.2', 'Netzwerk/TK-Anlage', 'sachgebiet', 3, dezId)
insertUnit('SG ZA 3.3', 'Server/Client, Logistik', 'sachgebiet', 3, dezId)
insertUnit('SG ZA 3.4', 'Kfz-, Waffen- und Geräteangelegenheiten', 'sachgebiet', 3, dezId)
}
})
console.log('✅ LKA NRW Organizational Structure seeded successfully!')
// Close database
db.close()
console.log('🎉 Done! Run the backend to see the organizational structure.')