diff --git a/CLAUDE.md b/CLAUDE.md
index 46d9461..b400b67 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -11,7 +11,7 @@ Dieses Dokument beschreibt Architektur, Konventionen und wichtige Implementierun
- **Einstiegspunkt:** `index.html`
- **Styles:** `css/styles.css` (Layout & Komponenten) + `css/tokens.css` (Design-Tokens)
- **Logik:** `js/app.js` (eine einzige Datei)
-- **Aktuelle Version:** `v64` (Script-Tag: `
+
```
### Externe Aufrufe
@@ -66,7 +66,7 @@ Die App hat keinen Build-Schritt – getestet wird **die ausgelieferte App**, al
```bash
npm install # nur Dev: @playwright/test (exakt gepinnt)
npx playwright install chromium # einmalig
-npm test # 367 Tests, ~145 s
+npm test # 371 Tests, ~145 s
npm run test:ui # interaktiver Modus
```
@@ -75,15 +75,15 @@ npm run test:ui # interaktiver Modus
| Datei | Deckt ab |
|---|---|
| `tests/helpers.js` | `openApp()` (Dialog-Stubs via `addInitScript`, überleben `reload()`), `loadSample()`, Konsolenfehler-Sammler, `grabDownload()` |
-| `tests/smoke.spec.js` | Views/Routing, Dashboard-Sichtbarkeit, genau eine `
` je View, HTML-Validität der Buttons, **null externe Requests** |
+| `tests/smoke.spec.js` | Views/Routing, Dashboard-Sichtbarkeit, genau eine `
` je View, HTML-Validität der Buttons, **null externe Requests**, durchgehende Anrede „Sie" im sichtbaren Text |
| `tests/import.spec.js` | CSV-Parser (Umbruch im gequoteten Feld), Export-Round-Trip, Dedup + `_recipients`, Identifier-Kollision, Formel-Injection, Schutzbedarf→`accessRights` |
-| `tests/inventory.spec.js` | Karten, Suche/Filter/Sortierung, Editieren über gefilterter Teilmenge, XSS, Tab-Umschaltung, Lizenz-Register + Wegweiser |
+| `tests/inventory.spec.js` | Karten, Suche/Filter/Sortierung, Editieren über gefilterter Teilmenge, XSS, Tab-Umschaltung, Lizenz-Register + Wegweiser + Kompatibilität, **MQA-Güte** (Dimensionsgewichte gepinnt, jede Einzelprüfung einzeln gemessen) |
| `tests/clearing.spec.js` | `schutzKategorie()`, alle Pfade von `evaluateClearing()`, progressive Anzeige, Persistenz |
-| `tests/pseudonymize.spec.js` | jedes Regex-Muster, Determinismus, Platzhalter-Konsistenz, Falschtreffer-Freiheit, Unicode-Indizes |
+| `tests/pseudonymize.spec.js` | jedes Regex-Muster, Determinismus, Platzhalter-Konsistenz, Falschtreffer-Freiheit, Unicode-Indizes, Spaltenbereinigung, Verwerfen veralteter Ergebnisse (v61) |
| `tests/quality.spec.js` | `validateDataset()` (Fehler vs. Warnung), Werteprüfungen, Sortierung, Sprung ins Inventar |
| `tests/governance.spec.js` | Reifegrad-Gewichtung, RACI, Kompass-Score, Wissens-Center, Vorlagen |
| `tests/export.spec.js` | DCAT-NAL-URIs, Downloads, LocalStorage, Projekt-Round-Trip + Ablehnungen |
-| `tests/a11y.spec.js` | Skip-Link, Fokus-Falle, Tab-Order der Seitenleiste, ARIA-Tabs, Kontrast, Überlauf bei 360/375/390 px |
+| `tests/a11y.spec.js` | Skip-Link, Fokus-Falle, Tab-Order der Seitenleiste, ARIA-Tabs, Kontrast (Ampel-Text-Tokens, gemessen statt behauptet), `[hidden]` gegen **jede** Klasse mit eigenem `display`, Überlauf bei 360/375/390 px |
| `tests/hvd.spec.js` | amtliches Vokabular (96 Konzepte, sechs Codes wörtlich), Dropdown-Gruppierung, v46-Migration, Einstufung bleibt manuell, alle Pflichten der DVO (EU) 2023/138, Export nur gemeinsam, CSV-/Katalog-Round-Trip |
| `tests/risiko.spec.js` | k-Anonymität/l-Diversität gegen Handrechnung, Trenner-Kollision, Normalisierung, Ampelschwellen, Modellfehler (sensibles Merkmal = QI), Tab/ARIA, Übergabe aus der Bereinigung |
| `tests/tour.spec.js` | Rundgang: alle Schritte, Zielelemente existieren wirklich, Escape und Pfeiltasten, Schritte ohne Daten bieten den Import an |
@@ -280,7 +280,9 @@ Bis v62 zählte `completeness(d)` schlicht die gefüllten `REQUIRED_FIELDS`. Der
### Vollständigkeit (Ampel)
-`completeness(d)` misst den Anteil gefüllter `REQUIRED_FIELDS` (`title, description, publisher, contactPoint, accrualPeriodicity, license, accessRights`) als 0–100 %. Schwellen für die Badge-Farbe: ≥ 80 % `--ampel-gruen`, ≥ 50 % `--ampel-gelb`, sonst `--ampel-rot`. Eingaben werden per `input`-Listener live in `inventory[idx]` zurückgeschrieben und Badge + Durchschnitt sofort aktualisiert.
+Die Zahl hinter der Badge kommt seit v63 aus `mqaScore()` (siehe oben) – **nicht** mehr aus dem Anteil gefüllter `REQUIRED_FIELDS`. Unverändert geblieben sind Name (`completeness(d)`), Wertebereich (0–100 %) und die Schwellen für die Badge-Farbe: ≥ 80 % `--ampel-gruen`, ≥ 50 % `--ampel-gelb`, sonst `--ampel-rot`. Eingaben werden per `input`-Listener live in `inventory[idx]` zurückgeschrieben und Badge + Durchschnitt sofort aktualisiert.
+
+⚠️ **`REQUIRED_FIELDS` wird von der App selbst nicht mehr gelesen.** Es leitet sich weiterhin aus `DCAT_REQUIRED` ab (`DCAT_REQUIRED.map(([k]) => k)`, v29: eine Quelle für Pflicht vs. Empfehlung), war aber bis v62 die Grundlage von `completeness()` – seither greift die Qualitätsprüfung direkt auf `DCAT_REQUIRED` zu. Es steht nur noch als Handgriff für `tests/inventory.spec.js`. Wer hier aufräumt, muss den Test mitziehen.
### Erweiterte DCAT-AP.de-Felder (`.inv-more`)
@@ -461,7 +463,9 @@ Dazu drei Einträge in `PRUEF_WERKZEUGE` und einer in `METHOD_MODELS`:
| **OParl 1.1** (OKF Deutschland, CC BY 3.0 DE) | Schnittstelle für kommunale Ratsinformationssysteme; relevant, wenn Gremiendaten nachgenutzt oder beschrieben werden |
| **DigComp** (EU JRC, CC BY 4.0) | **Ergänzung, kein Ersatz** für Data Orchard: DigComp beschreibt die Kompetenzen einzelner Personen, die Dimension „Können & Kapazität" fragt nach der Organisation. Frei lizenziert, anders als CC BY-NC-SA |
-> ⚠️ **Herkunft und Grenze.** Alle Angaben stammen aus dem Recherchebericht des Nutzers. **Nicht** enthalten ist die Initiative Transparente Zivilgesellschaft – sie stammte aus einer eigenen Suche, nicht aus dem Bericht, und der Wortlaut ihrer zehn Punkte ließ sich nicht am Original prüfen. Ebenfalls **nicht** übernommen: die im Bericht erwähnte geplante IFG-Einschränkung. Sie beruht dort ausdrücklich nur auf zivilgesellschaftlichen Quellen, ein amtlicher Entwurf lag nicht vor – ein Werkzeug, das bewusst keine Jahreszahlen führt, darf erst recht keinen Gesetzentwurf behaupten, den es nicht gibt.
+> ⚠️ **Herkunft und Grenze.** Die Einträge aus v64 stammen aus dem Recherchebericht des Nutzers. Die **Initiative Transparente Zivilgesellschaft** und der Praxisleitfaden *Offene Daten der Zivilgesellschaft* kamen in v65 dazu und haben die **schwächste Quellenlage im ganzen Werkzeug**: sie stammen aus Suchergebnissen, nicht aus dem Volltext – die Netzwerkrichtlinie sperrt beide Seiten. Belegt sind fünf der zehn Punkte; der Eintrag kennzeichnet sie deshalb ausdrücklich als Ausschnitt („darunter …") und verweist für den Wortlaut auf die Quelle. Drei Tests halten das fest, damit niemand die Teilliste später zur Vollständigen erklärt. Für den Leitfaden steht **keine Lizenzangabe** – sie war aus den Suchergebnissen nicht belegt.
+>
+> **Nicht** übernommen: die im Bericht erwähnte geplante IFG-Einschränkung. Sie beruht dort ausdrücklich nur auf zivilgesellschaftlichen Quellen, ein amtlicher Entwurf lag nicht vor – ein Werkzeug, das bewusst keine Jahreszahlen führt, darf erst recht keinen Gesetzentwurf behaupten, den es nicht gibt.
⚠️ **Regel für `PRUEF_WERKZEUGE`:** jede Adresse zeigt auf die Stelle, die das Werkzeug bzw. den Normtext **selbst** herausgibt – nie auf eine Sekundärquelle. Der Test führt dafür seit v64 eine Zuordnung Name → Host statt einer Host-Liste: ein neuer Eintrag erzwingt eine bewusste Entscheidung.
@@ -487,7 +491,7 @@ Eine **einzige, optionale** Angabe unter dem Score (`renderKompassProfil()`, `#k
> ⚠️ **Bewusst nicht die Frage „Behörde oder NGO".** Dazwischen liegen Stadtwerke, Verkehrsbetriebe, Hochschulen, Sparkassen und Belehnte – ein Zwei-Wege-Schalter sortiert sie falsch ein, und die Sektor-Bezeichnung selbst ändert am Werkzeug nichts. Was tatsächlich etwas ändert, ist die **Pflicht**, und die lässt sich direkt fragen.
-Sie wirkt an **genau zwei** Stellen, beide bei `rechtspflicht === 'nein'`:
+Sie wirkt an **genau drei** Stellen, alle bei `rechtspflicht === 'nein'` (zwei seit v55, die dritte kam mit v56 dazu):
| Stelle | Wirkung |
|---|---|
@@ -601,6 +605,7 @@ Nach Änderungen an `app.js` `?v=N` im Script-Tag **und** die `v{N}` im Footer e
| Inventar-Ableitung | `deriveInventory(rows)`, `mapSchutzToAccess(schutz)`, `mapHaeufigkeit(h)`, `slug(s)` | — |
| Verteilungen | `ensureDistributions()`, `migrateInventory()`, `newDistribution()`, `hasLicense()`, `hasFormat()`, `distFormats()`, `distLicenseLabels()`, `fieldFilled()` | `.inv-dists`, `.inv-dist`, `[data-dist-field]`, `[data-dist-add]`, `[data-dist-del]` |
| Inventar-Rendering | `renderInventory()`, `renderInventoryBody()`, `completeness(d)`, `optionsHTML(opts, sel)` | `#inventory-view`, `#inventory-body`, `.inv-card`, `[data-field]` |
+| Metadaten-Güte nach MQA | `mqaScore(d)`, `completeness(d)` (= `mqaScore().prozent`), `renderMqaSummary()`, `MQA_DIMENSIONEN`, `MQA_OFFENE_FORMATE`, `MQA_MAX`, `empty(v)` | `#quality-mqa`, `.qual-mqa-dim`, `.qual-mqa-bar`, `.qual-mqa-hint`, `.qual-mqa-note` |
| Inventar Suche/Filter/Sortierung | `filteredInventory()`, `invMetaText()`, `invFilter` (State) | `.inv-controls`, `#inv-search`, `#inv-filter-schutz`, `#inv-filter-ampel`, `#inv-filter-qual`, `#inv-sort`, `.inv-empty` |
| Massenbearbeitung | `renderBulkBar()`, `applyBulk()`, `removeSelected()`, `updateSelectAllLabel()`, `invSelection`, `BULK_FIELDS` | `#inv-select-all`, `#inv-bulk`, `.inv-select`, `#bulk-field`, `#bulk-value`, `#bulk-apply`, `#bulk-remove` |
| Rückimport Inventar-CSV | `importAnyCSV()`, `importInventoryCSV()`, `looksLikeInventoryCSV()`, `INV_CSV_FIELDS` | `#btn-import-again` |
@@ -674,6 +679,7 @@ Nach Änderungen an `app.js` `?v=N` im Script-Tag **und** die `v{N}` im Footer e
| v16 | Daten-Kompass (Herzstück) – eigene View + Hero-Haupt-CTA (Topbar-„Loslegen" zeigt ebenfalls darauf): ausführliche Open-Data-Reifegrad-Checkliste nach ODRA / EU Open Data Maturity / 5-Sterne / DCAT-AP.de / DSGVO·FAIR (7 Dimensionen, Quellenangaben), Status je Item mit Score & Ampel, Vorbelegung aus dem App-Stand, adaptive Sprünge in die passenden Bausteine, Persistenz (`datenlotse_kompass`) und PDF-Export; leeres „Loslegen"-Platzhalter-Modal entfernt |
| v17 | Weiterer Ausbau (1/4) – Inventar Suche, Filter & Sortierung: `renderInventory()` in `renderInventory()` + `renderInventoryBody()` aufgeteilt; `.inv-controls` (Volltextsuche + Schutzbedarf-/Clearing-Ampel-Filter + Sortierung Titel/Vollständigkeit) über `invFilter`-State und `filteredInventory()`; der echte `idx` wird durch den Filter mitgeführt, sodass Editieren über gefilterten Teilmengen weiterhin den richtigen Datensatz trifft; Live-Meta „X von Y" + Empty-State |
| v18 | Weiterer Ausbau (2/4) – Pseudonymisierung erweitert: drei neue Muster (Sozialversicherungsnummer, Steuer-ID *kontextgetriggert*, Kfz-Kennzeichen), Aktenzeichen um Geschäftszeichen/„Gz." und buchstabenhaltige Kerne erweitert, zusätzliche Geburtsdatum-Trigger („Geburtsdatum"/„Geburtstag"); Mapping-Export als CSV (`buildPseudoMappingCSV` + Button im Mapping-Kopf); Demo-Text und Grenzen-Liste aktualisiert; verifiziert auf Determinismus, Platzhalter-Konsistenz und Null-Falschtreffer auf neutralem Verwaltungstext |
+| v65 | **Die Initiative Transparente Zivilgesellschaft – mit sichtbar gemachter Quellenlage.** Nachgezogen auf Wunsch: die freiwillige Selbstverpflichtung ist strukturell dasselbe wie ein Transparenzgesetz – ein fester Katalog, den man abarbeitet, nur eben freiwillig – und damit der passendste Anker für gemeinnützige Organisationen. Dazu der Praxisleitfaden von Bernhard Krabina (Bertelsmann Stiftung), der ausdrücklich für zivilgesellschaftliche Akteure geschrieben ist. **Beide haben die schwächste Quellenlage im ganzen Werkzeug:** die Angaben stammen aus Suchergebnissen, nicht aus dem Volltext, weil die Netzwerkrichtlinie beide Seiten sperrt. Belegt sind fünf der zehn Punkte. Der Eintrag behauptet deshalb keine Vollständigkeit, sondern nennt sie als Ausschnitt und verweist für den Wortlaut auf die Quelle – und **drei Tests halten genau diese Zurückhaltung fest**, damit sie beim nächsten Bearbeiten nicht verlorengeht. Beim Schreiben fiel auf, dass ich die Lizenz des Leitfadens in einer früheren Auswertung mit „CC BY 4.0" angegeben hatte, obwohl die Suche das nie hergab; der Eintrag führt deshalb keine Lizenzangabe, und ein Test verbietet sie. **Dazu ein Doku-Abgleich gegen den Code** nach der Methode aus v52 (Zahlen im Browser ausgelesen, nicht aus dem Gedächtnis geschrieben): die Zählwerte stimmten alle, die *Beschreibungen* nicht. In CLAUDE.md stand die Sektion „Vollständigkeit (Ampel)" seit v63 im Widerspruch zur MQA-Sektion drei Absätze darüber – sie behauptete weiter das Zählen gefüllter Pflichtfelder; die Rechtspflicht-Sektion kündigte „genau zwei" Stellen an und führte dann drei auf (v56 hatte die dritte ergänzt, ohne den Satz mitzuziehen); die Feature-Tabelle hatte keine MQA-Zeile. Im README fehlten `sample-verein.csv` (v58) sowie `risiko.spec.js` und `tour.spec.js` in der Dateistruktur, Font Awesome stand noch mit „solid, regular, brands", obwohl v45 die Brands-Familie ganz entfernt hat, an drei Stellen war von „Verwaltungstexten" die Rede, die v58 gerade aufgelöst hatte, und die Prüfwerkzeuge nannten vier von neun. Nebenbei kam heraus, dass **`REQUIRED_FIELDS` von der App gar nicht mehr gelesen wird** – seit v63 greift die Qualitätsprüfung direkt auf `DCAT_REQUIRED` zu, die Konstante steht nur noch als Handgriff für `tests/inventory.spec.js`; das ist jetzt an der Stelle vermerkt, statt als stille Falle liegen zu bleiben. |
| v64 | **Der zivilgesellschaftliche Anknüpfungspunkt – aus den Quellen, die wirklich vorlagen.** Die auffälligste Lücke war keine fehlende Liste, sondern eine fehlende Leserichtung: die 16 Landesgesetze standen nur als Pflicht der informationspflichtigen Stelle da. Für einen Verein sind dieselben Gesetze das Werkzeug, um an Daten zu kommen – der Lead benennt jetzt beide Richtungen und verweist auf FragDenStaat. Dazu drei Werkzeuge aus dem Bericht: der **Musterdatenkatalog** als Antwort auf „was veröffentlichen andere?", **ARX** als das, was DatenLotse bewusst nicht tut (generalisieren und unterdrücken statt nur messen), und **OParl 1.1** für Ratsinformationen. **DigComp** kommt als frei lizenzierte Ergänzung zu Data Orchard dazu – ausdrücklich nicht als Ersatz, denn es beschreibt einzelne Personen, während die Dimension nach der Organisation fragt. Nicht übernommen: die geplante IFG-Einschränkung (im Bericht selbst nur advocacy-belegt, kein amtlicher Entwurf) und die Initiative Transparente Zivilgesellschaft (stammte aus einer eigenen Suche, nicht aus dem Bericht). Beim Einfügen fiel auf, dass der Bestandstest für die Werkzeugliste eine **Host-Liste** kodierte; die eigentliche Regel ist „jede Adresse zeigt auf die herausgebende Stelle selbst" – der Test führt jetzt eine Zuordnung Name → Host, sodass ein neuer Eintrag eine Entscheidung erzwingt. 6 neue Tests. Ein Mutationslauf lief zunächst wirkungslos durch, weil das deutsche Schlusszeichen den Python-String beendete, ein zweiter blieb grün, weil mein Test auf „ergänzt" prüfte – das steht auch im mutierten Text. Erst die Prüfung auf „statt sie zu ersetzen" machte ihn rot. |
| v63 | **Die Vollständigkeits-Zahl war zu freundlich.** `completeness()` zählte gefüllte Pflichtfelder – ein Datensatz mit allen Pflichtangaben stand auf 100 %, auch ohne Schlagwörter, ohne Zeitraum und nur als PDF. Genau dagegen richtet sich der Leitgedanke der Metadata Quality Assurance von data.europa.eu. Die Zahl folgt jetzt deren Schema: fünf FAIR-Dimensionen, 405 Punkte, 18 Einzelprüfungen. **Ersatz statt drittes Maß** – der Funktionsname bleibt, damit Badge, Durchschnitt, Sortierung, Dashboard und Bericht weiter an genau einer graduellen Zahl hängen. Ein frischer Import fällt damit von ~83 % auf ~46 %; das ist der Zweck. Sauber getrennt ist, was übernommen wurde: die **Dimensionsgewichte** stammen aus der Methodik, die **Zuordnung der Einzelprüfungen** ist eigene Zutat – ein Test pinnt die Gewichte wörtlich und prüft, dass jede Dimension ihr Maximum ausschöpft. Ausdrücklich benannt ist auch, was der Wert **nicht** ist: die MQA ruft URLs ab, DatenLotse macht keine Netzaufrufe und prüft nur Vorhandensein und Wohlgeformtheit. Der stärkste Test geht die 18 Prüfungen einzeln durch und misst, ob jede ihre vollen Punkte ausmacht – eine wirkungslose Prüfung fällt sofort auf. Beim Bauen zeigte sich nebenbei, dass `empty()` zweimal wortgleich als lokale Hilfe existierte; jetzt einmal modulweit. 8 neue Tests, drei bestehende auf die neue Semantik umgeschrieben statt gelockert. Ein erster Mutationsversuch war zu schwach gewählt und lief grün durch – erst die schärfere Fassung (Positivliste akzeptiert alles) machte ihn rot. |
| v62 | **Rechtslage nachgezogen – mit offengelegter Herkunft.** `LEGAL_BASIS` kannte weder den **Data Act** noch den **Data Governance Act**, obwohl beide inzwischen anwendbar sind, und der Eintrag zu § 12a EGovG stand noch auf dem Stand vor dem OZG-Änderungsgesetz (Ausweitung auf die „Behörden des Bundes", Open-Data-Koordinatoren, Berichtspflicht). Der interessanteste Zugewinn ist **DGG Kapitel II**: das Statistische Bundesamt ist dort zentrale Informationsstelle für die Weiterverwendung geschützter Verwaltungsdaten und unterstützt ausdrücklich bei Anonymisierung und Pseudonymisierung – das ist der amtliche Anknüpfungspunkt zu Modul 3a und 3b. Beim Data Act war die Formulierung heikel: Kapitel V verpflichtet nur bei **außergewöhnlicher Notwendigkeit**, und ein Eintrag, der das verschweigt, weckt die Erwartung eines allgemeinen Datenzugangs; ein Test hält den Vorbehalt fest. **Zur Herkunft:** die Angaben stammen aus einem Recherchebericht des Nutzers, nicht aus eigener Prüfung an der amtlichen Quelle – die Netzwerkrichtlinie sperrt EUR-Lex und gesetze-im-internet.de. Verlinkt wurde deshalb nur, was sich aus dem dokumentierten CELEX-Schema sicher bilden lässt; DADG und DGG stehen im Text, aber ohne Link, damit keine geratene Fundstelle als amtliche Quelle erscheint. Dazu: die Prüfwerkzeuge nannten die **DCAT-AP.de-Spezifikation 2.0**, aktuell ist 3.0 – das Konventionenhandbuch bleibt dagegen ausdrücklich bei 2.0. 6 neue Tests, drei Mutationen geprüft. |
diff --git a/README.md b/README.md
index 56e7616..15b16bb 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
# DatenLotse – von der Datenkartierung zur Open-Data-Umsetzung
-**DatenLotse** ist ein browserbasiertes, datenbankfreies Werkzeug, das Organisationen – insbesondere die öffentliche Verwaltung – vom kartierten Datenökosystem in die konkrete Open-Data-Umsetzung führt. Es ist das Schwester-Tool zu [DatenGraf](https://datengraf.nozilla.net/): Wo DatenGraf zeigt, *wie* die Datenflüsse aussehen, beantwortet DatenLotse die Frage *„Was tue ich jetzt konkret?"* – Dateninventar nach DCAT-AP.de aufbauen, Risiken klären, Texte datenschutzkonform pseudonymisieren. Alles läuft lokal im Browser: kein Server, kein Account, keine Verarbeitung Ihrer Daten.
+**DatenLotse** ist ein browserbasiertes, datenbankfreies Werkzeug, das Organisationen vom kartierten Datenökosystem in die konkrete Open-Data-Umsetzung führt – Behörden, die einer Veröffentlichungspflicht unterliegen, ebenso wie Vereine, Stiftungen und Initiativen, die freiwillig offenlegen oder umgekehrt an Daten kommen wollen. Es ist das Schwester-Tool zu [DatenGraf](https://datengraf.nozilla.net/): Wo DatenGraf zeigt, *wie* die Datenflüsse aussehen, beantwortet DatenLotse die Frage *„Was tue ich jetzt konkret?"* – Dateninventar nach DCAT-AP.de aufbauen, Risiken klären, Texte datenschutzkonform pseudonymisieren. Alles läuft lokal im Browser: kein Server, kein Account, **Ihre Inhalte werden nicht übertragen**.
@@ -29,7 +29,7 @@
| 🗺️ | **Onboarding-Rundgang** | Elf Schritte durch alle Bausteine – der Rundgang wechselt selbst in die passende Ansicht und hebt hervor, worum es gerade geht. Wird **angeboten statt aufgedrängt** (wegklickbarer Hinweis, jederzeit über die Seitenleiste wiederholbar); Schritte, die Daten brauchen, bieten den Beispielimport an, statt ihn heimlich auszuführen |
| 📈 | **Kompass-Verlauf** | Reifegrad-Stände auf Knopfdruck festhalten und die Entwicklung als Balken samt Trend sehen – belegbarer Fortschritt gegenüber Leitung oder Gremium. Bewusst **kein automatischer Mitschnitt**: festgehalten wird, was man festhalten will |
| 🧭 | **Daten-Kompass** | Open-Data-Reifegrad-Checkliste nach anerkannten Modellen (ODRA, EU Open Data Maturity, 5-Sterne-Open-Data, DCAT-AP.de, DSGVO/FAIR, Data Orchard Data Maturity): **8 Dimensionen mit 33 Prüfpunkten**, Score + Ampel, Vorbelegung aus dem aktuellen Stand, adaptive Empfehlungen der nächsten Bausteine und PDF-Export – der Haupteinstieg |
-| ⚖️ | **Rechtspflicht der Organisation** | Eine einzige, **optionale** Angabe: Unterliegt Ihre Organisation einem Informationsfreiheits- oder Open-Data-Gesetz? Wer *nein* wählt (Verein, Stiftung, gGmbH), bekommt den Prüfpunkt zu den Rechtsgrundlagen als *nicht relevant* vorbelegt – er zählt dann nicht in den Reifegrad – und keine Vorschläge zu hochwertigen Datensätzen, weil die EU-Verordnung dazu öffentliche Stellen bindet. Bewusst **nicht** die Frage „Behörde oder NGO": dazwischen liegen Stadtwerke, Hochschulen und Belehnte, die ein Zwei-Wege-Schalter falsch einsortiert. Alles Übrige gilt unverändert |
+| ⚖️ | **Rechtspflicht der Organisation** | Eine einzige, **optionale** Angabe: Unterliegt Ihre Organisation einem Informationsfreiheits- oder Open-Data-Gesetz? Wer *nein* wählt (Verein, Stiftung, gGmbH), bekommt den Prüfpunkt zu den Rechtsgrundlagen als *nicht relevant* vorbelegt – er zählt dann nicht in den Reifegrad –, keine Vorschläge zu hochwertigen Datensätzen, weil die EU-Verordnung dazu öffentliche Stellen bindet, und einen Fehler bei der Lizenz „Amtliches Werk nach § 5 UrhG", deren Lizenzfreiheit an der amtlichen Herkunft hängt und nicht an einer Entscheidung des Herausgebers. Bewusst **nicht** die Frage „Behörde oder NGO": dazwischen liegen Stadtwerke, Hochschulen und Belehnte, die ein Zwei-Wege-Schalter falsch einsortiert. Alles Übrige gilt unverändert |
| 🛡️ | **Re-Identifikationsrisiko (k-Anonymität)** | Bereinigte Spalten sagen, *was* ersetzt wurde – nicht, ob das Ergebnis noch auf einzelne Personen zurückführt. Diese Prüfung bildet Gruppen aus den Merkmalen, die Sie wählen, und zählt, wie viele Zeilen in der kleinsten Gruppe stehen (**k-Anonymität**); optional misst sie die Vielfalt eines sensiblen Merkmals innerhalb dieser Gruppen (**l-Diversität**). Sie **misst nur** – generalisiert und unterdrückt wird nichts, denn das wäre eine Entscheidung über fremde Daten. Rein arithmetisch, kein ML |
| 🔗 | **DatenGraf-CSV-Import** | Liest exakt das CSV-Schema, das DatenGraf exportiert – die Datenkartierung wird ohne Umweg zur Umsetzungsgrundlage |
| 📦 | **Dateninventar (DCAT-AP.de)** | Aus jedem Datenfluss wird ein Dataset-Kandidat abgeleitet und in editierbaren Karten dargestellt: Beschreibung, Publisher, Ansprechpartner, **Kategorie** (EU-Datenthemen), **Schlagwörter**, Aktualisierungszyklus, **Lizenz** (volles DCAT-AP.de-Register), Zugriffsrechte und Info-/Zugriffs-URL – mit Live-Vollständigkeits-% in Ampelfarben. Dazu ein ausklappbarer Block **erweiterter DCAT-AP.de-Felder** (Veröffentlichungs-/Änderungsdatum, zeitliche und räumliche Abdeckung, Regionalschlüssel samt Gebietsebene, Kontributor-Kennung) und eine **Live-Vorschau des JSON-LD** je Datensatz. Der Export schreibt kontrollierte Werte als offizielle NAL-/Register-URIs |
@@ -46,13 +46,13 @@
| 🔗 | **Konsistenzprüfung über den Bestand** | Findet, was der Blick auf den einzelnen Datensatz nicht sieht: doppelte Identifier, doppelte Titel, zweimal dieselbe Zugriffs-URL und Schreibvarianten beim Publisher. Gemeldet wird jeweils der Abweichler, mit Sprung zur betroffenen Karte |
| ⚖️ | **Hochwertige Datensätze (HVD)** | Für Datensätze, die unter die Durchführungsverordnung (EU) 2023/138 fallen, gelten **verbindliche** Vorgaben: kostenfrei, maschinenlesbar, über eine API, Lizenz nicht restriktiver als CC BY 4.0. Die Qualitätsprüfung meldet Verstöße deshalb als Fehler statt als Warnung. Zur Auswahl steht das **vollständige amtliche Vokabular** der EU-Publikationsstelle (96 Konzepte, gruppiert nach den sechs Kategorien) – die Spezifikation empfiehlt den genauesten Begriff. Das Werkzeug **schlägt eine Einstufung vor, nimmt sie aber niemandem ab**: ob die Verordnung greift, ist eine Rechtsfrage |
| ✅ | **DCAT-AP.de-Qualitätsprüfung** | Publish-Ready-Check je Datensatz: fehlende Pflichtfelder als **Fehler**, fehlende Empfehlungsfelder und Werteprüfungen (offene Lizenz, kontrolliertes Vokabular, E-Mail im Ansprechpartner) als **Warnungen** – mit Ampel-Übersicht und direktem Sprung zum Bearbeiten im Inventar |
-| 📚 | **Wissens- & Methodik-Center** | In-App-Nachschlagewerk mit Live-Filter über alles: **20 Glossar-Begriffe**, **11 Rechtsgrundlagen** (Bund/EU mit amtlichen Links zu gesetze-im-internet.de bzw. EUR-Lex, inklusive der HVD-Durchführungsverordnung), **alle 16 Landesregelungen** (Transparenz- vs. Informationsfreiheitsgesetz, jeweils mit amtlicher Fundstelle und eigenem Bundesland-Filter), **kommunale Informationsfreiheitssatzungen** für die Länder ohne Landesgesetz, **Prüfwerkzeuge & Normtexte** (offizieller EU-SHACL-Validator, DCAT-AP.de-Spezifikation und Konventionenhandbuch) und die **7 Reifegrad-Modelle** hinter dem Kompass – lokal, ausdrücklich keine Rechtsberatung |
+| 📚 | **Wissens- & Methodik-Center** | In-App-Nachschlagewerk mit Live-Filter über alles: **20 Glossar-Begriffe**, **11 Rechtsgrundlagen** (Bund/EU mit amtlichen Links zu gesetze-im-internet.de bzw. EUR-Lex, inklusive der HVD-Durchführungsverordnung), **alle 16 Landesregelungen** (Transparenz- vs. Informationsfreiheitsgesetz, jeweils mit amtlicher Fundstelle und eigenem Bundesland-Filter), **kommunale Informationsfreiheitssatzungen** für die Länder ohne Landesgesetz, **9 Prüfwerkzeuge & Normtexte** (offizieller EU-SHACL-Validator, DCAT-AP.de-Spezifikation und Konventionenhandbuch, GovData-Metadatenschema, Musterdatenkatalog, ARX, OParl, Initiative Transparente Zivilgesellschaft, Praxisleitfaden zu offenen Daten der Zivilgesellschaft) und die **7 Reifegrad-Modelle** hinter dem Kompass – lokal, ausdrücklich keine Rechtsberatung. Die Landesgesetze stehen bewusst in **beiden Leserichtungen** da: als Veröffentlichungspflicht der informationspflichtigen Stelle *und* als Werkzeug, mit dem alle anderen an Daten kommen, die noch nicht offen liegen |
| 🧾 | **Status auf einen Blick** | Einseitige Zusammenfassung über alle Bausteine – Reifegrade, Inventar, Publikationsreife, Clearing-Verteilung und die nächsten Schritte. Für Leitungsrunden und Gremien; funktioniert auch ohne Inventar, weil der leere Stand ebenfalls eine Aussage ist |
| 🔒 | **Eigene Datenschutzerklärung** | Unter `/datenschutz/`, aus demselben Generator wie die Wissensseiten. Sie beschreibt, was das Werkzeug wirklich tut: Local Storage statt Server, GitHub Pages als Hoster samt US-Transfer, die anonyme Seitenzählung mit dem, was sie sieht und was nicht, keine Cookies, keine Schriften-CDN, kein KI-Dienst – und der Hinweis, dass sich all das im Quelltext nachprüfen lässt |
| 📄 | **Vorlagen & Musterdokumente** | Fertige Dokumente lokal erzeugt: Open-Data-Richtlinie und DSFA-Kurz-Checkliste (Muster) sowie aus dem Inventar generierte Veröffentlichungs-Freigabe-Formulare und ein VVT-Auszug der DSGVO-relevanten Datensätze – als PDF druckbar oder als Markdown/CSV ladbar |
| 📝 | **Notiz zur Clearing-Entscheidung** | Die automatische Begründung sagt, warum die Ampel so steht – für die Akte lässt sich je Datensatz eine eigene Notiz ergänzen (Abstimmung mit dem Datenschutz, vereinbarte Auflage). Sie geht nicht in den Entscheidungsbaum ein und erscheint im Bericht und im Freigabeformular |
| 🚦 | **Clearing-Ampel (Rot-Gelb-Grün)** | Transparenter, deterministischer Entscheidungsbaum je Datensatz (Schutzbedarf-Vorbelegung, Art.-9-/Rechtsgrundlage-/Anonymisierbarkeit-Prüfung) mit nachvollziehbarer Begründung, Gesamtübersicht und Ampel-Spalte im CSV-Export |
-| 🛡️ | **Client-Side-Pseudonymisierung** | Strukturerhaltende, deterministische Bereinigung deutscher Verwaltungstexte über **11 Muster**: Name (anrede-getriggert, akademische Titel werden übersprungen), Adresse, PLZ+Ort, Aktenzeichen/Geschäftszeichen, IBAN, E-Mail, Telefon, Geburtsdatum, Steuer-ID und Kfz-Kennzeichen (beide kontextgetriggert), Sozialversicherungsnummer. Konsistente Platzhalter, Mapping-Tabelle samt **CSV-Export** – rein per Regex, nichts verlässt den Browser |
+| 🛡️ | **Client-Side-Pseudonymisierung** | Strukturerhaltende, deterministische Bereinigung deutschsprachiger Texte über **11 Muster**: Name (anrede-getriggert, akademische Titel werden übersprungen), Adresse, PLZ+Ort, Aktenzeichen/Geschäftszeichen, IBAN, E-Mail, Telefon, Geburtsdatum, Steuer-ID und Kfz-Kennzeichen (beide kontextgetriggert), Sozialversicherungsnummer. Konsistente Platzhalter, Mapping-Tabelle samt **CSV-Export** – rein per Regex, nichts verlässt den Browser |
| 🧮 | **Spaltenweise CSV-Bereinigung** | Zweiter Modus für strukturierte Daten: CSV laden, je Spalte entscheiden – unverändert lassen, Muster erkennen oder **ganze Spalte ersetzen** (für Spalten wie „Name", die ohne Anrede kein Muster auslösen). Gleiche Werte erhalten zeilenübergreifend denselben Platzhalter; die CSV-Struktur bleibt erhalten und das Ergebnis ist wieder importierbar |
| 👥 | **Governance & RACI** | 8-Fragen-Reifegrad-Check (gewichtet, 0–100, **auch ohne Inventar nutzbar**) + automatisch aus dem Inventar abgeleitete RACI-Matrix (Domänen × Rollen) mit Lücken-Markierung; Export als CSV und PDF/Druck-Bericht. Jede Frage lässt sich als **„nicht relevant"** abwählen und fällt dann aus der Wertung, statt mit 0 zu zählen – wer nach § 38 BDSG rechtmäßig keine Datenschutzbeauftragte hat, bekommt dafür keinen Abzug |
| 💾 | **Projekt speichern & laden (.json)** | Kompletter Arbeitsstand (Inventar inkl. Clearing, Governance, Kompass und importierte DatenGraf-Zeilen) als eine versionierte JSON-Datei exportier- und wieder importierbar – für Backup, Gerätewechsel oder zum Teilen; Import prüft Herkunft und fragt vor dem Überschreiben |
@@ -116,7 +116,7 @@ Die App selbst bleibt abhängigkeitsfrei; für die Tests wird einmalig Playwrigh
```bash
npm install # nur Dev: @playwright/test
npx playwright install chromium
-npm test # 367 Tests, ~145 s
+npm test # 371 Tests, ~145 s
npm run test:ui # interaktiver Modus
```
@@ -134,7 +134,7 @@ DatenLotse begleitet den Weg von der fertigen DatenGraf-Karte in die operative O
| **1 · Fundament** | 👥 Governance & Rollen | 8-Fragen-Reifegrad-Check (gewichtet auf 100) + RACI-Matrix aus den Datendomänen. Der Fragebogen ist **unabhängig vom Inventar** und sofort ausfüllbar |
| **2 · Asset Management** | 📦 Dateninventar | DatenGraf-CSV importieren, Datenflüsse zu DCAT-AP.de-Datasets verdichten, Metadaten ergänzen, Qualität prüfen, als JSON-LD/CSV exportieren |
| **3 · Clearing** | 🚦 Risiko-Clearing | Rot/Gelb/Grün-Entscheidungsbaum je Datensatz – deterministisch, ohne ML |
-| **3 · Pseudonymisierung** | 🛡️ Textbereinigung | Deutsche Verwaltungstexte strukturerhaltend von personenbezogenen Daten befreien, vollständig client-seitig |
+| **3 · Pseudonymisierung** | 🛡️ Textbereinigung | Deutschsprachige Texte und CSV-Spalten strukturerhaltend von personenbezogenen Daten befreien und anschließend das Re-Identifikationsrisiko messen – vollständig client-seitig |
Begleitend: 📊 **Status-Dashboard** auf der Startseite, 📚 **Wissens- & Methodik-Center** (Glossar, Rechtsgrundlagen, Modelle) und 📄 **Vorlagen & Musterdokumente** (Richtlinie, DSFA-Checkliste, Freigabe-Formulare, VVT-Auszug).
@@ -160,6 +160,8 @@ Begleitend: 📊 **Status-Dashboard** auf der Startseite, 📚 **Wissens- & Meth
**Erzeugung der Verwaltungsdokumente.** Freigabeformular, VVT-Auszug, Richtlinienentwurf und DSFA-Checkliste entstehen aus dem bereits erfassten Stand, statt separat geschrieben zu werden.
+**Freiwillige Transparenz jenseits der Pflicht.** Ein Verein, eine Stiftung oder eine gGmbH unterliegt keinem Informationsfreiheitsgesetz und arbeitet trotzdem an derselben Sache – etwa entlang der Initiative Transparente Zivilgesellschaft, die strukturell dasselbe ist wie ein Transparenzgesetz: ein fester Katalog, den man abarbeitet, nur eben freiwillig. Der Kompass rechnet dann nur, was zählbar ist (die Angabe zur Rechtspflicht nimmt die Punkte heraus, die ohne Pflicht nicht erreichbar sind), der Governance-Check lässt Fragen als *nicht relevant* abwählen, und `data/sample-verein.csv` zeigt einen Bestand mit Spenden, Verwendungsnachweisen, Ehrenamtsstunden und Wirkungskennzahlen statt Bürgeramt und Kämmerei.
+
**Sensible Kontexte allgemein.** Überall dort, wo ein Upload auf einen fremden Dienst ausscheidet – Personaldaten, Sozialdaten, Verschlusssachen-nahe Bestände –, ist die Local-First-Architektur nicht bloß angenehm, sondern die Bedingung dafür, das Werkzeug überhaupt einsetzen zu dürfen.
---
@@ -230,7 +232,7 @@ Die Ausgabe erfolgt als JSON-LD mit `@context` auf das DCAT-AP.de-Profil, als **
| **Vanilla JS** | ES2020+ | Gesamte Anwendungslogik ohne Framework, eine Datei (`js/app.js`) |
| **CSS Custom Properties** | — | Design-System mit Glasmorphismus, Tokens in `css/tokens.css` |
| **Inter** | lokal | Schriftart (latin + latin-ext, 400/500/600/700) |
-| **Font Awesome** | 6.7.2 (lokal) | Icon-Library (solid, regular, brands) |
+| **Font Awesome** | 6.7.2 (lokal, zugeschnitten) | Icon-Library – ausgeliefert werden nur Solid und Regular als Teilmenge; die Brands-Familie steckte nur wegen des GitHub-Zeichens im Fuß in der Auslieferung und ist seit v45 ein Inline-SVG |
| **FileReader API** | — | Lokaler CSV-/Textimport ohne Upload |
| **LocalStorage API** | — | Persistenz ohne Backend |
| **Blob API** | — | DCAT-JSON-, CSV- und Text-Downloads |
@@ -261,7 +263,7 @@ Eine geordnete, deterministische Regelmenge bildet die Freigabeempfehlung je Dat
Strukturerhaltende Pseudonymisierung
-**11 Muster** für DE-Verwaltungstexte ersetzen erkannte Entitäten durch konsistente Platzhalter (`[PERSON_1]`, `[ADRESSE_1]`, `[STEUERID_1]` …). Pro Entitätstyp ein Zähler + Map `Originalwert → Platzhalter`: gleicher Wert ⇒ immer derselbe Platzhalter, deterministisch über das ganze Dokument.
+**11 Muster** für deutschsprachige Texte ersetzen erkannte Entitäten durch konsistente Platzhalter (`[PERSON_1]`, `[ADRESSE_1]`, `[STEUERID_1]` …). Pro Entitätstyp ein Zähler + Map `Originalwert → Platzhalter`: gleicher Wert ⇒ immer derselbe Platzhalter, deterministisch über das ganze Dokument.
**Konservativ durch Kontext-Trigger:** Namen nur nach Anrede (optionale akademische Titel werden übersprungen, damit bei „Frau Dr. Anna Beispiel" nicht der Titel statt des Namens erfasst wird), Geburtsdaten nur nach „geb."/„geboren am", Steuer-ID und Kfz-Kennzeichen nur nach Schlüsselwort. Letzteres verhindert, dass Lizenz- und Normkürzel wie `DL-DE 2.0` oder `DIN-EN 1090` zerstört werden – eine Sperrliste scheidet aus, weil `DL` und `EN` echte Unterscheidungszeichen sind.
@@ -281,9 +283,9 @@ Liegt ein Inventar vor, kommt die **RACI-Matrix** hinzu: Die Datendomänen werde
-Publish-Ready-Check statt reiner Vollständigkeits-%
+Publish-Ready-Check neben der Metadaten-Güte
-Die Prozentanzeige sagt nur, *wie viele* Felder gefüllt sind. Der dritte Inventar-Tab prüft zusätzlich die **Werte**: Ist die Lizenz nach der Open Definition offen? Stammen `accessRights`, `theme` und `accrualPeriodicity` aus dem kontrollierten Vokabular? Enthält der Ansprechpartner eine E-Mail-Adresse? Ist die Info-URL eine gültige http(s)-Adresse? Sind Titel und Beschreibung aussagekräftig lang?
+Die Prozentanzeige ist ein **gradueller** Wert nach dem MQA-Schema (fünf FAIR-Dimensionen, 405 Punkte) – sie sagt, wie gut ein Datensatz beschrieben ist, aber nicht, ob er durchs Harvesting kommt. Der dritte Inventar-Tab prüft deshalb zusätzlich **hart gegen die Werte**: Ist die Lizenz nach der Open Definition offen? Stammen `accessRights`, `theme` und `accrualPeriodicity` aus dem kontrollierten Vokabular? Enthält der Ansprechpartner eine E-Mail-Adresse? Ist die Info-URL eine gültige http(s)-Adresse? Sind Titel und Beschreibung aussagekräftig lang?
Fehlende Pflichtfelder sind **Fehler** (rot), fehlende Empfehlungsfelder und Wertprobleme **Warnungen** (gelb). Die Karten sind nach Schwere sortiert, jede springt per Klick zur betroffenen Stelle im Inventar. Deterministisch, kein ML.
@@ -305,19 +307,22 @@ datenlotse/
│ ├── sample-kommune.csv # Beispiel: fiktive Stadtverwaltung (12 Datensätze)
│ ├── sample-landkreis.csv # Beispiel: fiktive Kreisverwaltung (12 Datensätze)
│ ├── sample-landesbehoerde.csv # Beispiel: fiktive Landesebene (12 Datensätze)
+│ ├── sample-verein.csv # Beispiel: fiktiver gemeinnütziger Träger (12 Datensätze)
│ └── template.csv # Leere Vorlage zum eigenen Befüllen
-├── tests/ # Playwright-End-to-End-Tests (367 Tests)
+├── tests/ # Playwright-End-to-End-Tests (371 Tests in 14 Dateien)
│ ├── helpers.js # openApp/loadSample/Download-Helfer
-│ ├── smoke.spec.js # Views, Routing, Dashboard, HTML-Validität
+│ ├── smoke.spec.js # Views, Routing, Dashboard, HTML-Validität, Anrede
│ ├── import.spec.js # CSV-Parser, Ableitung, Formel-Injection
-│ ├── inventory.spec.js # Karten, Filter, Lizenz-Register & -Wegweiser
+│ ├── inventory.spec.js # Karten, Filter, MQA-Güte, Lizenz-Register & -Kompatibilität
│ ├── clearing.spec.js # Entscheidungsbaum Modul 3a
│ ├── pseudonymize.spec.js # Regex-Pack Modul 3b
+│ ├── risiko.spec.js # k-Anonymität & l-Diversität
│ ├── quality.spec.js # DCAT-AP.de-Publish-Ready-Check
│ ├── governance.spec.js # Modul 1, Kompass, Wissen, Vorlagen
│ ├── export.spec.js # DCAT-URIs, Downloads, Persistenz
│ ├── a11y.spec.js # Fokus, ARIA, Kontrast, Responsive
│ ├── hvd.spec.js # hochwertige Datensätze (DVO (EU) 2023/138)
+│ ├── tour.spec.js # Onboarding-Rundgang, Schritt-Ziele
│ ├── seo.spec.js # statische Wissensseiten, Metadaten, Sitemap
│ └── assets.spec.js # Icon-Zuschnitt, Ladegewicht der Startseite
├── playwright.config.js # Testkonfiguration (startet den Webserver selbst)
diff --git a/datenschutz/index.html b/datenschutz/index.html
index 7131936..907927b 100644
--- a/datenschutz/index.html
+++ b/datenschutz/index.html
@@ -42,7 +42,7 @@
}
-
+
diff --git a/index.html b/index.html
index bebcdb5..03da27f 100644
--- a/index.html
+++ b/index.html
@@ -125,10 +125,10 @@
-
+
-
-
+
+
@@ -893,7 +893,7 @@
Umsetzung besprechen
Brands-Familie und hätte dafür 116 KB Schrift nachgeladen. -->
- v64
+ v65
@@ -1109,7 +1109,7 @@