Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:** `v67` (Script-Tag: `<script src="js/app.js?v=67">`)
- **Aktuelle Version:** `v68` (Script-Tag: `<script src="js/app.js?v=68">`)

---

Expand All @@ -26,7 +26,7 @@ python3 -m http.server 8080

**Cache-Busting:** Nach Änderungen an `app.js` die Versionsnummer im Script-Tag in `index.html` erhöhen und die sichtbare `v{N}` im Footer mitziehen. **Auch die CSS-Links (`css/tokens.css?v=N`, `css/styles.css?v=N`) tragen denselben `?v=N`** – bei reinen CSS-/Layout-Änderungen unbedingt mitziehen, sonst liefert GitHub Pages das alte Stylesheet:
```html
<script src="js/app.js?v=67"></script>
<script src="js/app.js?v=68"></script>
```

### Externe Aufrufe
Expand Down Expand Up @@ -142,7 +142,6 @@ Präfix `datenlotse_` (analog DatenGrafs `datengraf_`). Immer try/catch um JSON-
| `datenlotse_inventory` | Inventar inkl. Clearing-Antworten/-Ergebnis (`d._clearing`, `d.clearing`) als JSON |
| `datenlotse_governance` | Governance-Fragebogen-Antworten (`governanceAnswers`) als JSON |
| `datenlotse_kompass` | Daten-Kompass-Status je Checklisten-Item (`kompassState`, `"dim.item" → status`) als JSON |
| `datenlotse_tour` | `'done'`, sobald der Rundgang beendet oder der Hinweis weggeklickt wurde |
| `datenlotse_kompass_verlauf` | Festgehaltene Reifegrad-Stände (`kompassHistory`, `[{ date, score }]`) als JSON |
| `datenlotse_kompass_profil` | Angabe zur Rechtspflicht (`kompassProfil`, `{ rechtspflicht: ''\|'ja'\|'nein'\|'unklar' }`) als JSON |

Expand Down Expand Up @@ -450,7 +449,9 @@ Geführter Durchlauf durch die Bausteine (`TOUR_STEPS`, `tour = { i, active }`).

> ⚠️ **Die Stapelreihenfolge ist dreiteilig und hängt an einer Eigenheit von `position: fixed`.** Ein fixiertes Element bildet einen **eigenen Stapelkontext** – die Karte in `#tour-layer` kann dessen `z-index` also nie überbieten, egal welchen Wert sie selbst trägt. Bis v65 stand das Abdunkeln am Layer (1200) und `.tour-highlight` darüber (1201); das hervorgehobene Zielelement zeichnete damit **in die Karte hinein** (bei Schritt 3 stand der Fragebogentext über Titel und Knöpfen) und fing dort auch die Klicks ab. Seit v66 gilt: **Abdunkeln `body.tour-on::before` (1200) < Hervorhebung (1201) < Layer mit Karte (1202)**. Das Abdunkeln muss dafür *außerhalb* des Layers liegen – daher die Body-Klasse, die `startTour()` setzt und `endTour()` entfernt (sonst bliebe die Seite dauerhaft dunkel).

**Bewusst kein Auto-Start als Modal beim ersten Laden** – das nimmt Erstnutzern die Kontrolle. Stattdessen ein wegklickbarer Hinweis `#tour-hint` auf der Startseite (`refreshTourHint()` in `showView('home')` + beim Laden) und ein Dauer-Einstieg `#sidebar-tour`. Gesehen-Status unter `datenlotse_tour` (`'done'`).
**Bewusst kein Auto-Start als Modal beim ersten Laden** – das nimmt Erstnutzern die Kontrolle. Angeboten wird er an zwei dauerhaften Stellen: `#hero-tour-btn` im Hero und `#sidebar-tour` in der Seitenleiste.

> ⚠️ **Der wegklickbare Hinweis `#tour-hint` ist mit v68 entfallen** – seit der Hero den Rundgang dauerhaft anbietet, war er die zweite Einladung auf derselben Seite. Mit ihm entfiel sein **einziger Leser**: `datenlotse_tour` wurde danach nur noch geschrieben. Der Schlüssel, `tourSeen()`, `markTourSeen()` und `refreshTourHint()` sind deshalb mit entfernt worden, statt als toter Zustand liegen zu bleiben (dieselbe Lehre wie bei `REQUIRED_FIELDS`). Ein Test hält fest, dass nach einem vollständigen Rundgang **nichts** mehr in den Speicher geschrieben wird.

Schritte mit `needsData` brauchen ein Inventar. Statt still Beispieldaten zu laden – eine Nebenwirkung, die niemand bestellt hat – bietet der Schritt den Import an (`#tour-sample`) und lässt die Entscheidung beim Menschen. Ein Test prüft, dass jedes `target` in der jeweiligen View wirklich existiert; sonst zeigt der Rundgang ins Leere, sobald sich Markup ändert.

Expand Down Expand Up @@ -634,7 +635,7 @@ Nach Änderungen an `app.js` `?v=N` im Script-Tag **und** die `v{N}` im Footer e
| Hochwertige Datensätze (HVD) | `hvdIssues()`, `guessHvd()`, `hvdVorschlaege()`, `hvdCategoryUri()`, `hvdFromURI()`, `hvdSelectHTML()`, `migrateHvd()`, `renderHvdHinweise()`, `HVD_CATEGORIES`, `HVD_META`, `HVD_LICENSES`, `HVD_ELI`, `HVD_BNA` | `[data-field="hvd"]`, `.inv-hvd`, `.inv-hvd-uri`, `#quality-hvd`, `.qual-hvd` |
| DCAT-AP.de-Qualitätsprüfung | `validateDataset(d)`, `qualityStatus()`, `renderQuality()`, `jumpToInventoryCard(idx)` | `#tab-quality`, `#quality-panel`, `#quality-summary`, `.qual-card`, `.qual-fix` |
| Wissens- & Methodik-Center | `renderWissen()`, `GLOSSARY`, `LEGAL_BASIS`, `LEGAL_BASIS_LAENDER`, `LAENDER_KIND`, `KOMMUNAL_SATZUNGEN`, `METHOD_MODELS`, `wissenFilter` | `#wissen-view`, `#wissen-search`, `#wissen-land`, `#wissen-glossary`, `#wissen-laws`, `#wissen-laender`, `#wissen-kommunal`, `#wissen-models` |
| Onboarding-Rundgang | `startTour()`, `endTour()`, `tourGo()`, `renderTour()`, `refreshTourHint()`, `TOUR_STEPS`, `tour` (State) | `#tour-layer`, `#tour-card`, `#tour-hint`, `#sidebar-tour`, `.tour-highlight`, `datenlotse_tour` |
| Onboarding-Rundgang | `startTour()`, `endTour()`, `tourGo()`, `renderTour()`, `TOUR_STEPS`, `tour` (State) | `#tour-layer`, `#tour-card`, `#hero-tour-btn`, `#sidebar-tour`, `.tour-highlight` |
| Vorlagen & Musterdokumente | `generateDoc(doc, fmt)`, `printDoc()`, `docShell()`, `policyBodyHTML/Markdown`, `dsfaBodyHTML/Markdown`, `freigabeBodyHTML`, `vvtBodyHTML/CSV`, `orgName()` | `#vorlagen-view`, `.vorlage-card`, `[data-doc][data-fmt]` |
| Status-Einseiter | `statusKennzahlen()`, `statusNaechsteSchritte()`, `statusBodyHTML()` | `[data-doc="status"]` |
| PDF-Bericht Inventar/Clearing | `buildInventoryReportHTML()`, `printInventoryReport()` | `#btn-print-inventory` |
Expand Down Expand Up @@ -696,6 +697,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 |
| v68 | **Zwei Einladungen für dieselbe Sache, zwei Knöpfe mit demselben Ziel.** Nachdem v67 den Rundgang dauerhaft in den Hero gestellt hatte, stand der wegklickbare Hinweis `#tour-hint` als zweite Einladung darunter – und die Topbar bot „Loslegen" an, das dasselbe tat wie „Sofort loslegen" zwei Zeilen tiefer. Beides bereinigt: der Hinweis ist weg, der Topbar-Knopf heißt jetzt „Daten-Kompass" und benennt sein Ziel. **Mit dem Hinweis entfiel sein einziger Leser:** `datenlotse_tour` wurde danach nur noch geschrieben und von niemandem mehr gelesen. Der Schlüssel und die drei Funktionen darum sind deshalb mit entfernt worden, statt als toter Zustand liegen zu bleiben – dieselbe Lehre wie bei `REQUIRED_FIELDS` in v65, diesmal aber gleich mit aufgeräumt. In der DatenGraf-Brücke ersetzt das DatenGraf-Zeichen (`fa-circle-nodes`, dasselbe wie in Topbar und Seitenleiste) das CSV-Zeichen, und der lila Rand links ist weg. ⚠️ **Nicht das echte DatenGraf-Logo:** die Netzwerkrichtlinie sperrt `datengraf.nozilla.net`, und der Repo-Zugriff dieser Sitzung reicht nicht über `daimpad/datenlotse` hinaus – die Datei war nicht zu beschaffen. Wer sie ins Repo legt, tauscht in `.graf-bridge-icon` das `<i>` gegen ein `<img>`. **Ein eigener Fehler, den erst der Test fand:** beim Herausschneiden der `.tour-hint`-Regeln nahm mein Schnitt die direkt danebenstehende Abdunkel-Regel `body.tour-on::before` mit – der Rundgang wäre ohne Abdunkeln erschienen. Der Test aus v66 machte es rot, weil er die Farbe **misst** statt die Regel zu suchen. 1 neuer Test. |
| v67 | **Der Einstieg sagte nicht, wer hier spricht – und der Hauptknopf nur die Hälfte.** Drei gemeldete Punkte, alle am ersten Bildschirm. **(1)** Titel und Aussage standen als *ein* Satz mit Doppelpunkt in einer Farbe und einer Größe; die Marke „DatenLotse" ging in ihrer eigenen Überschrift unter. Jetzt trägt sie 46 px in der Akzentfarbe, der Claim steht kleiner und in der Textfarbe darunter, durch eine dünne Linie abgesetzt. Der Test **misst** Größe und Farbe – eine Prüfung auf Klassennamen bliebe grün, wenn beide wieder gleich aussähen, und genau das ist die Regression, um die es geht. **(2)** Der Hero bot nur „Daten-Kompass starten". Wer sich erst orientieren wollte, fand dort keinen Weg zum Rundgang – der lag im wegklickbaren Hinweis und in der Seitenleiste, also genau an den zwei Stellen, an denen ein Erstnutzer nicht sucht. Jetzt stehen beide Einstiege nebeneinander: „Sofort loslegen" und „Rundgang starten". **(3)** Die DatenGraf-Zeile stand als graues Kleingedrucktes unter dem Hauptknopf – an der prominentesten Stelle der Seite, für eine Minderheit, und ohne zu erklären, was die Brücke eigentlich leistet. Sie ist jetzt ein eigener Abschnitt **unterhalb der Modul-Karten** mit Erklärung (Schema 1:1, Vorbelegung aus der Kartierung, was nachzuerfassen bleibt) und zwei Wegen – Import direkt in den Dateidialog, ohne das Erklär-Modal, das hier niemand mehr braucht, und ein Verweis auf DatenGraf für alle, die noch nicht kartiert haben. 3 neue Tests, drei Mutationen einzeln geprüft. |
| v66 | **Ein Darstellungs-Durchgang – und dreimal dieselbe Lehre: eine Regel, die nicht greift, fällt niemandem auf.** Der auffälligste Fund kam aus der Benutzung: im Rundgang zeichnete das hervorgehobene Zielelement **in die Karte hinein** – bei Schritt 3 stand der Fragebogentext über Titel und Knöpfen, und Klicks dort trafen den Fragebogen statt „Weiter". Ursache ist eine Eigenheit von `position: fixed`: der Layer bildet einen **eigenen Stapelkontext**, die Karte darin kann dessen `z-index` also nie überbieten, egal welchen Wert man ihr gibt. Ein höherer Wert an der Karte wäre wirkungslos geblieben – das Abdunkeln musste **aus dem Layer heraus** (jetzt `body.tour-on::before`), damit die Reihenfolge Abdunkeln < Hervorhebung < Karte überhaupt darstellbar ist. Zweiter Fund derselben Art: der Wissens-Generator schrieb `<footer class="footer">`, und **eine solche Regel gibt es im Stylesheet gar nicht** – die App heißt `site-footer`. Die neun statischen Seiten trugen ihre Linkzeile also seit jeher ungestylt und ohne Grund am unteren Rand. Dritter: `showView()` führte eine **Liste von IDs** plus einen Sonderfall für `.consult-cta`; der neue Startseiten-Abschnitt wäre auf allen sechs Unterseiten stehen geblieben, ohne dass etwas rot geworden wäre – jetzt entscheidet die Klasse `.home-only`, und ein Test geht alle Unterseiten durch. Dazu der inhaltliche Teil: der Hero trug sieben Bausteine (Logo, Titel, Einleitung, Chips, Zusage, Aktion, Import-Zeile) und sagte in Titel wie Einleitung „Datenmanagement" – **wofür das Werkzeug gebaut ist, nämlich Daten zu öffnen, kam nirgends vor**. Die vier Schritte stehen jetzt in einem eigenen Abschnitt, Titel, Einleitung und die drei Meta-Beschreibungen benennen Open Data. 5 neue Tests, sechs Mutationen einzeln geprüft. |
| 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. |
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

| | Feature | Beschreibung |
|---|---|---|
| 🗺️ | **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 |
| 🗺️ | **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** – kein Auto-Start, sondern zwei dauerhafte Einstiege (Hero und Seitenleiste); 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 –, 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 |
Expand Down
Loading
Loading