Some checks failed
Container-Image bauen und veröffentlichen / build-and-push (push) Failing after 21s
Gegen den geltenden Normbestand geprüft und berichtigt: - Landesbauordnung SH, neu gefasst zum 01.09.2022 und dabei umnummeriert. Bauvoranfrage § 61 -> § 75 (Vorbescheid), Befreiungs-/Abweichungsantrag § 61 -> § 67 LBO und § 31 BauGB, gemeindliches Einvernehmen § 61 -> § 36 BauGB und § 71 LBO. Beim Bauantrag § 68 ergänzt, § 64 bleibt. - Wohnberechtigungsschein: benannte das Dokument statt der Norm, jetzt § 27 WoFG i. V. m. § 5 WoBindG. - Bildung und Teilhabe: "BKKG" berichtigt zu § 6b BKGG, § 34 SGB XII präzisiert (drei Erklärungen). - Ausschreibungsunterlagen: überholte VOL/A entfernt. - Beihilfe, Mutterschutz und Arbeitsmedizin verarbeiten Gesundheitsdaten und haben zusätzlich Art. 9 Abs. 2 lit. b DSGVO erhalten. Nicht angefasst, weil ohne belegte Fassung: nicht zitierfähige Satzungen, die Anschlussbescheinigung, die Angelerlaubnis sowie alle fehlenden Fristen, Zwecke und Datenkategorien. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
214 lines
7.2 KiB
JavaScript
214 lines
7.2 KiB
JavaScript
/**
|
||
* Korrigiert einzelne fachrechtliche Zitate, die gegen den geltenden
|
||
* Normbestand geprüft wurden.
|
||
*
|
||
* node scripts/fix-legal-citations.js --dry-run
|
||
* node scripts/fix-legal-citations.js
|
||
*
|
||
* Geändert wird ausschließlich, wofür eine belegte, eindeutige Fassung
|
||
* vorliegt. Alles Übrige – nicht zitierfähige Satzungen, unklare Zuordnungen,
|
||
* fehlende Fristen – bleibt unangetastet und geht an die Datenschutz-
|
||
* beauftragte.
|
||
*
|
||
* Der Lauf ist wiederholbar und setzt nur an, wo der alte Wortlaut noch steht.
|
||
*/
|
||
const fs = require("fs")
|
||
const path = require("path")
|
||
const { PrismaClient } = require("@prisma/client")
|
||
|
||
const prisma = new PrismaClient()
|
||
const JSON_DIR = path.join(process.cwd(), "data", "policies")
|
||
|
||
/** Trennzeile, hinter der das Fachrecht in `legalBasis` steht. */
|
||
const MARKER = "Konkrete Rechtsgrundlage: "
|
||
|
||
/**
|
||
* Belegte Korrekturen. `von` muss exakt dem heutigen Fachrechts-Text
|
||
* entsprechen, sonst wird der Datensatz übersprungen.
|
||
*/
|
||
const KORREKTUREN = [
|
||
// --- Landesbauordnung SH, neu gefasst am 6.12.2021, gültig ab 01.09.2022 ---
|
||
// Die Paragraphen wurden dabei umnummeriert.
|
||
{
|
||
titel: "Bauantrag",
|
||
von: "§ 64 LBO",
|
||
nach: "§§ 64, 68 LBO",
|
||
grund:
|
||
"§ 64 LBO regelt das Baugenehmigungsverfahren, der Bauantrag selbst steht in § 68 LBO (Bauantrag, Bauvorlagen). Ergänzt statt ersetzt, da beide einschlägig sind.",
|
||
},
|
||
{
|
||
titel: "Bauvoranfrage",
|
||
von: "§ 61 LBO",
|
||
nach: "§ 75 LBO",
|
||
grund:
|
||
"§ 61 LBO ist seit 01.09.2022 „Verfahrensfreie Bauvorhaben“. Der Vorbescheid – die Bauvoranfrage – steht in § 75 LBO.",
|
||
},
|
||
{
|
||
titel: "Befreiungsantrag /Abweichungsantrag/Ausnahmeantrag",
|
||
von: "§ 61 LBO",
|
||
nach: "§ 67 LBO, § 31 BauGB",
|
||
grund:
|
||
"Abweichungen, Ausnahmen und Befreiungen stehen in § 67 LBO; bauplanungsrechtliche Befreiungen zusätzlich in § 31 BauGB.",
|
||
},
|
||
{
|
||
titel: "Stellungnahme Bauantrag",
|
||
von: "§ 61 LBO",
|
||
nach: "§ 36 BauGB, § 71 LBO",
|
||
grund:
|
||
"Das gemeindliche Einvernehmen regelt § 36 BauGB, seine Ersetzung § 71 LBO. § 61 LBO betrifft verfahrensfreie Vorhaben.",
|
||
},
|
||
|
||
// --- Wohnberechtigungsschein ---
|
||
{
|
||
titel: "Antrag auf Ausstellung eines Wohnberechtigungsscheines",
|
||
von: "Wohnberechtigungsschein",
|
||
nach: "§ 27 WoFG i. V. m. § 5 WoBindG",
|
||
grund:
|
||
"„Wohnberechtigungsschein“ benennt das Dokument, keine Norm. Der Schein wird nach § 27 WoFG i. V. m. § 5 WoBindG erteilt.",
|
||
},
|
||
|
||
// --- Bildung und Teilhabe ---
|
||
{
|
||
titel: "Antrag auf Hilfe für Bildung u. Teilhabe",
|
||
von: "SGB XII, BKKG",
|
||
nach: "§ 34 SGB XII, § 6b BKGG",
|
||
grund:
|
||
"„BKKG“ ist ein Schreibfehler für BKGG. Leistungen für Bildung und Teilhabe stehen in § 34 SGB XII bzw. § 6b BKGG.",
|
||
},
|
||
{
|
||
titel: "Antrag auf Hilfe für Bildung u. Teilhabe: Hilfe f. mehrtägige Klassenfahrten",
|
||
von: "SGB XII",
|
||
nach: "§ 34 SGB XII",
|
||
grund: "Präzisierung: Leistungen für Bildung und Teilhabe stehen in § 34 SGB XII.",
|
||
},
|
||
{
|
||
titel: "Änderungsmitteilung auf Hilfe für Bildung u. Teilhabe",
|
||
von: "SGB XII",
|
||
nach: "§ 34 SGB XII",
|
||
grund: "Präzisierung: Leistungen für Bildung und Teilhabe stehen in § 34 SGB XII.",
|
||
},
|
||
|
||
// --- Vergaberecht ---
|
||
{
|
||
titel: "Ausschreibungsunterlagen",
|
||
von: "VOL/VgV/UVGO/VGO S-H",
|
||
nach: "VgV/UVgO/VGO S-H",
|
||
grund:
|
||
"Die VOL/A ist für Liefer- und Dienstleistungen durch die UVgO abgelöst. Nur das überholte Kürzel entfernt; die Landesvorschrift sollte noch mit vollem Titel benannt werden.",
|
||
},
|
||
]
|
||
|
||
/**
|
||
* Zusätzliche Erlaubnisnorm, wo besondere Kategorien personenbezogener Daten
|
||
* verarbeitet werden. Art. 9 Abs. 1 DSGVO verbietet das grundsätzlich; die
|
||
* Verarbeitung braucht deshalb eine eigene Grundlage nach Art. 9 Abs. 2.
|
||
*/
|
||
const ART9_ZUSATZ =
|
||
"Soweit Gesundheitsdaten verarbeitet werden: **Art. 9 Abs. 2 lit. b DSGVO** i. V. m. **§ 15 LDSG SH** – Verarbeitung besonderer Kategorien personenbezogener Daten zur Erfüllung von Pflichten aus dem Arbeits- und Sozialrecht."
|
||
|
||
const ART9_TITEL = [
|
||
"Beihilferecht",
|
||
"Mutterschutz, Elternzeit",
|
||
"Arbeitsmedizinische Untersuchungen, Unfallfürsorge",
|
||
]
|
||
|
||
function fachrechtErsetzen(legalBasis, von, nach) {
|
||
const stelle = legalBasis.indexOf(MARKER)
|
||
if (stelle === -1) return null
|
||
|
||
const kopf = legalBasis.slice(0, stelle + MARKER.length)
|
||
const rest = legalBasis.slice(stelle + MARKER.length)
|
||
|
||
if (rest.trim() !== von) return null
|
||
return kopf + nach
|
||
}
|
||
|
||
async function main() {
|
||
const dryRun = process.argv.includes("--dry-run")
|
||
const policies = await prisma.privacyPolicy.findMany()
|
||
const nachTitel = new Map(policies.map((p) => [p.title, p]))
|
||
|
||
const geplant = []
|
||
const uebersprungen = []
|
||
|
||
for (const korrektur of KORREKTUREN) {
|
||
const policy = nachTitel.get(korrektur.titel)
|
||
if (!policy) {
|
||
uebersprungen.push(`${korrektur.titel} – Erklärung nicht gefunden`)
|
||
continue
|
||
}
|
||
|
||
const neu = fachrechtErsetzen(policy.legalBasis || "", korrektur.von, korrektur.nach)
|
||
if (!neu) {
|
||
uebersprungen.push(
|
||
`${korrektur.titel} – Wortlaut weicht ab (erwartet „${korrektur.von}“), bereits geändert?`
|
||
)
|
||
continue
|
||
}
|
||
|
||
geplant.push({ policy, korrektur, neu })
|
||
}
|
||
|
||
const art9 = []
|
||
for (const titel of ART9_TITEL) {
|
||
const policy = nachTitel.get(titel)
|
||
if (!policy) {
|
||
uebersprungen.push(`${titel} – Erklärung nicht gefunden`)
|
||
continue
|
||
}
|
||
if ((policy.legalBasis || "").includes("Art. 9 Abs. 2")) {
|
||
uebersprungen.push(`${titel} – Art. 9 bereits ergänzt`)
|
||
continue
|
||
}
|
||
art9.push({ policy, neu: `${policy.legalBasis}\n\n${ART9_ZUSATZ}` })
|
||
}
|
||
|
||
console.log(`=== Fachrechtliche Zitate (${geplant.length}) ===`)
|
||
for (const { korrektur } of geplant) {
|
||
console.log(`\n ${korrektur.titel}`)
|
||
console.log(` vorher : ${korrektur.von}`)
|
||
console.log(` nachher: ${korrektur.nach}`)
|
||
console.log(` Grund : ${korrektur.grund}`)
|
||
}
|
||
|
||
console.log(`\n=== Besondere Datenkategorien, Art. 9 Abs. 2 lit. b (${art9.length}) ===`)
|
||
art9.forEach(({ policy }) => console.log(` ${policy.title}`))
|
||
|
||
if (uebersprungen.length) {
|
||
console.log(`\n=== Übersprungen (${uebersprungen.length}) ===`)
|
||
uebersprungen.forEach((z) => console.log(` ${z}`))
|
||
}
|
||
|
||
if (dryRun) {
|
||
console.log("\n--dry-run: nichts geschrieben.")
|
||
return
|
||
}
|
||
|
||
const schreiben = async (policy, legalBasis) => {
|
||
await prisma.privacyPolicy.update({ where: { id: policy.id }, data: { legalBasis } })
|
||
const datei = path.join(JSON_DIR, `${policy.slug}.json`)
|
||
try {
|
||
if (fs.existsSync(datei)) {
|
||
const inhalt = JSON.parse(fs.readFileSync(datei, "utf8"))
|
||
inhalt.legalBasis = legalBasis
|
||
fs.writeFileSync(datei, JSON.stringify(inhalt, null, 2), "utf8")
|
||
}
|
||
} catch {
|
||
// Die Datenbank ist maßgeblich; die Ablage ist nur Nachweis.
|
||
}
|
||
}
|
||
|
||
for (const { policy, neu } of geplant) await schreiben(policy, neu)
|
||
for (const { policy, neu } of art9) await schreiben(policy, neu)
|
||
|
||
console.log(`\nZitate korrigiert: ${geplant.length}`)
|
||
console.log(`Art. 9 ergänzt: ${art9.length}`)
|
||
}
|
||
|
||
main()
|
||
.catch((e) => {
|
||
console.error(e)
|
||
process.exitCode = 1
|
||
})
|
||
.finally(() => prisma.$disconnect())
|