Files
Projektwissen/docs/wissen/fallstricke.md
T
DanielandClaude Opus 5.5 abac5a015c Anzeigefenster ohne Vollbild: Testkonzept und Fallstrick (Verfahrensgebiet #56)
Befund aus dem QGIS-Test (Fenster immer auf dem Hauptbildschirm, im
Vollbild nicht zu verlassen) in fallstricke.md festgehalten; Testkonzept,
Modulkarte und Testkatalog an das Fenster mit Rahmen und die
Pfadanzeige der Korrektur-Datei angepasst.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 13:44:18 +02:00

164 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Fallstricke und Erkenntnisse
Gemeinsames Gedächtnis: Dinge, die man **nicht aus dem Code ablesen kann** und die schon einmal Zeit gekostet haben.
Kurz, konkret, mit Datum und Quelle. Neue Einträge oben in der passenden Rubrik. Veraltetes löschen, nicht auskommentieren.
## Umgebung und Werkzeuge
- **`qt_wrapper` meldet unter QGIS 3.44 `QT_VERSION == 6`, obwohl Qt5 läuft.** Der „PyQt6“-Zweig importiert
`qgis.PyQt`, das unter QGIS 3 PyQt5 ist; die Qt6-Schreibweise der Enums (`Qt.ItemFlag.ItemIsUserCheckable`)
funktioniert mit PyQt 5.15 trotzdem. `QT_VERSION` also nicht als Qt-Hauptversion verstehen, nur als
„echtes Qt (≠ 0)“. (02.10.2026, QGIS 3.44.4 geprüft, Basis #88)
- **Lücken im Mock-Modus:** `QgsGeometry` hat im Mock kein `fromRect`, `QgsLayoutPoint`/`QgsLayoutSize` haben
`x`/`width` als Attribute statt als Methoden; `QgsRectangle` hatte bis Basis #88 gar keinen Mock. Tests patchen
solche Stellen gezielt, statt die Produktionsfunktion umzubauen. (02.10.2026)
- **QGIS 3.40 ist seit Januar 2026 End of Life.** Aktueller LTR ist 3.44, Stable 4.2 (wird 25.09.2026 LTR). `workspace.toml` und alle `metadata.template` stehen noch auf `3.40` – offene Produktentscheidung, siehe `docs/konzept/07_qgis_tests_plan.md` Abschnitt 2. (04.09.2026, QGIS-Release-Fahrplan)
- **Zwei Qt-Welten.** QGIS 3.40/3.44 laufen mit Qt5/PyQt5, QGIS 4 mit Qt6/PyQt6. `qt_wrapper` lädt PyQt6 zuerst, dann PyQt5, sonst Mock. Enum-Zugriffe unterscheiden sich (`Qt.AlignmentFlag.AlignTop` statt `Qt.AlignTop`), deshalb nur Wrapper-Aliase verwenden. (09/2026, Code)
- **Mock-Modus ist kein QGIS.** `python scripts/run_tests.py` läuft in Sekunden, prüft aber nur Logik gegen Mock-Klassen. Geometrieoperationen, WFS, Layouts und Signale müssen in QGIS geprüft werden (`tests/test_qgis.bat` unter Windows). Manuelle QGIS-Tests im PR dokumentieren. (09/2026)
- **`openpyxl` ist eine harte Abhängigkeit** von `sn_basis` (Excel-Import) und unter Linux-QGIS oft nicht installiert (Issue Verfahrensgebiet #21). `requests` ist nur optionaler Fallback. Es gibt keine `requirements.txt`. (09/2026)
- **QGIS lädt Plugins in nicht garantierter Reihenfolge.** Fachplugins dürfen in `initGui()` nicht davon ausgehen, dass `sn_basis` fertig ist; `sn_basis` ruft `initGui()` aller `sn_*` nach. (Code `main.py`)
- **Exit-Crash unter QGIS 3.40** entstand durch nicht getrennte Projektsignale beim Unload. Regel: jeder Tab/Manager, der Signale verbindet, bietet `cleanup()`/`teardown_...()` und wird beim Schließen aufgerufen. (Basis, `assets/plan-qgis340ExitCrashFix.prompt.md`)
- **`docs/tests/testkatalog.html` (Dashboard „Prüfstand") lädt Mermaid von `cdnjs.cloudflare.com`.** Ohne
Internetverbindung beim Öffnen bleiben die Baumdiagramme leer, Text/Tabellen/Filter funktionieren trotzdem
(kein Server nötig, einfach lokal im Browser öffnen). Erzeugt zusammen mit `testkatalog.md` durch
`python scripts/testkatalog.py`; beide Dateien müssen zueinander passen (`--pruefen` prüft beide). (09/2026)
- **`.vscode/` gehört nicht ins Repository.** Im Projektwissen wurde er am 04.09.2026 entfernt; brauchbare Einstellungen stehen jetzt in `docs/leitfaden/04_werkzeuge_einrichten.md` Abschnitt 4.2 zum Kopieren in die Benutzereinstellungen. In `Plugin_SN_Basis`, `Plugin_SN_Plan41`, `Plugin_SN_Verfahrensgebiet` und `Plugin_SN_Widmung` liegt er noch und enthält Pfade eines einzelnen Arbeitsplatzes (OSGeo-Installationspfad, persönliches Benutzerprofil) – nicht als Vorgabe verstehen. (09/2026)
## QGIS-Tests (geplant, siehe `docs/konzept/07_qgis_tests_plan.md`)
- **Spike/Abnahme ohne QGIS-Oberfläche:** Skript mit `QT_QPA_PLATFORM=offscreen` über `python-qgis.bat` starten,
das Plugin-Repo per Junction (`mklink /J <tmp>\sn_basis <Plugin_SN_Basis>`) unter dem Paketnamen in `sys.path`
legen. Für Widgets und Dialoge `QgsApplication([], True)` (mit GUI) – ohne GUI stürzt z. B.
`QgsSymbolLayerUtils.symbolPreviewIcon` ab. Modale Dialoge: `exec_dialog` patchen und im Ersatz die Widgets
prüfen. Layout-Ergebnis mit `QgsLayoutExporter.renderRegionToImage` als PNG ansehen; ohne installierte Schriften
erscheinen Texte als Kästchen. `exportToImage` liefert bei Erfolg `0`. (02.10.2026, Basis #88)
- **`QT_QPA_PLATFORM=offscreen` muss gesetzt sein, bevor die `QgsApplication` erzeugt wird.** Danach wirkt es nicht mehr. (04.09.2026, Recherche)
- **`qgis.utils.iface` ist nach `start_app()` `None`.** Entweder `pytest-qgis` verwenden (patcht automatisch) oder selbst `qgis.utils.iface = get_iface()` setzen – und keine Module zu früh importieren. (04.09.2026)
- **`QgsProject.instance()` ist global.** Ohne Aufräumen zwischen den Tests beeinflussen sie sich gegenseitig. (04.09.2026)
- **Abstürze beim Beenden** sind ein bekanntes QGIS-Thema, wenn Layer- oder Canvas-Objekte noch referenziert werden. Gegenmittel: `pytest-qgis` oder `--qgis_disable_exit`. (04.09.2026)
- **`QgisTestCase.render_layout_check()` ist für Plugins nicht nutzbar**: es sucht Referenzbilder in einem einkompilierten Pfad des QGIS-Quellbaums. Nur `QgsRenderChecker` bietet `setControlImagePath()`. Referenzbilder immer im CI-Container erzeugen, nie unter Windows (Font- und Antialiasing-Unterschiede). (04.09.2026)
- **Modale Dialoge blockieren den Test.** Reihenfolge der Gegenmittel: modalen Aufruf per `monkeypatch` ersetzen, `open()` statt `exec()`, erst zuletzt `QTimer.singleShot`. (04.09.2026)
- **Unter Windows nur `python-qgis.bat`/`python-qgis-ltr.bat` verwenden** – ein normales `python -m pytest` findet die QGIS-Bindings nicht. (04.09.2026)
- **Gitea ordnet Commits über die E-Mail-Adresse zu.** Stimmt `user.email` nicht mit einer im Gitea-Konto hinterlegten Adresse überein, erscheinen die Commits ohne Zuordnung zum Benutzer. Für dieses Projekt gilt die dienstliche Adresse (`@lfulg.sachsen.de`). Wer den Rechner auch privat nutzt, setzt sie je Repository mit `git config --local` statt global. Nachträglich nur durch Umschreiben der Historie korrigierbar. (04.09.2026)
## Release und Versionen
- **Der Release-Workflow baut den Kopf des Kanal-Branches**, nicht den getaggten Commit (`git checkout "$CHANNEL"` in `Repository:hidden/workflows`). Tag nur setzen, wenn der Kanal-Branch auf dem gewünschten Stand ist. (09/2026)
- **`metadata.txt` nie von Hand pflegen.** Sie wird beim Release aus `.gitea/templates/metadata.template` erzeugt. Die im Repo liegende Datei ist ein Abbild des letzten Builds und kann irreführende Versionen/URLs zeigen (Issue Verfahrensgebiet #26). (09/2026)
- **Stable-Kanal ist leer**, ein Branch dafür existiert nicht; ein Tag ohne Suffix würde derzeit fehlschlagen. Der Branch muss **exakt `stable`** heißen, weil der Release-Workflow in `Repository:hidden/workflows` `git checkout "$CHANNEL"` ausführt und `$CHANNEL` aus dem Tag-Suffix stammt. Anlegen: `docs/konzept/08_repo_einrichten.md` (ADR 0007). (04.09.2026, Workflow gelesen)
- **Repo-Name ≠ Paketname.** `Plugin_SN_Basis` wird als `sn_basis` installiert (Gitea-Variable `ZIP_FOLDER`). Importe im Code verwenden immer den Paketnamen.
- **Bekannte Metadata-Fehler:** Plan41-Template verweist auf `Plugin_Test_Action` als Repository; FLT-Template auf `Plugin_SN_Neu`; Widmung trägt Version `4711-unstable`. (Gesamtüberblick 09/2026)
- **Workspace-Dateien in Release-ZIPs.** Der rsync-Schritt schließt nur `.git`, `.gitea`, `.gitignore`, `__pycache__` aus. `AGENTS.md`, `CLAUDE.md`, `.agents/`, `.claude/`, `docs/`, `tests/` werden mit ausgeliefert, bis die Excludes ergänzt sind (offener Punkt).
## Daten und Dienste
- **Punktlinien aus Mapbox-Styles sind in QGIS unsichtbar.** basemap.de (wie viele MapLibre-Stile) zeichnet Punktlinien
als `line-dasharray` mit Strichlänge 0 und `line-cap: round`. QGIS übernimmt das beim Import 1:1, Qt zeichnet
Striche der Länge 0 aber gar nicht – auch nicht als Punkt, weder in der Karte noch in der Legende. Betroffen
sind bei basemap.de 12 Styles (Baumreihe, Hecke, Durchlass, Seilbahnen …). Abhilfe: Strichlänge 0 durch 0,01
ersetzen (`sn_basis.modules.basemap_stilkorrektur`). Beim Prüfen solcher Effekte die Beschriftung abschalten –
sonst zählen Labels als „sichtbare Pixel“. (02.10.2026, QGIS 3.44 / PyQt 5.15, Basis #90; QGIS 4 ungeprüft)
- **basemap.de-Vektorkacheln (Basis #88):** QGIS zeigt für Vektorkachel-Layer keine Legende. Objekte im Gebiet
liefert `QgsVectorTileLayer.selectByGeometry()` (lädt die Kacheln selbst; `getRawTile` ist in Python gesperrt).
Kacheln enden bei Zoom 15. Der Renderer prüft Styles mit `scaleToZoomLevel(maßstab, False)` und setzt
`@vector_tile_zoom = scaleToZoom(maßstab)` – diese Variable fehlt in der Legende, zoomabhängige Strichmuster
sind dort sonst unsichtbar. Beim Import der Style-JSON werden Beschriftungen zu Labeling (Hausnummern =
Labeling-Style `Hauskoordinate`), `Nummer_*`-Schilder zu Renderer-Symbolen, `fill-extrusion` (3D) entfällt.
Der Legendenkatalog `sn_basis/data/basemap_legende.json` gehört zur Style-Version `bm_web_col` v2; nach einer
neuen Version `python modules/basemap_katalog.py` laufen lassen und Meldungen prüfen. Eine QML-Stilvorlage des
Layers ist rund 3,7 MB groß. (02.10.2026)
- **`symbol_stile` im Basemap-Legendenkatalog müssen alle Zoomstufen abdecken (Basis #98).** Viele basemap.de-Styles
gelten nur in einem Zoombereich (z. B. `*_Autobahn_getrennt` bis Zoom 13, ab Zoom 14
`*_Autobahn_getrennt_Fahrbahnachse`). Ist bei der Druck-Zoomstufe kein `symbol_stil` aktiv, nimmt
`waehle_symbolnamen` den ersten getroffenen Style – oft nur die graue Kontur. Deshalb je Zoombereich ein
Kontur-/Decker-Paar eintragen; inaktive werden übergangen. Lücken findet ein Abgleich der `minzoom`/`maxzoom`
der Style-JSON mit dem Katalog. Weitere Lücken im Druckbereich (Stand 06.10.2026): „Straße im Tunnel“
ab Zoom 14, „Biosphärenreservat“ ab Zoom 11. (06.10.2026)
- **basemap.de-Themen (Basis #100):** Angeboten werden Farbe (`bm_web_col`), Grau (`bm_web_gry`) und Relief
(`bm_web_top`); `bm_web_bin` liegt auf dem Server, steht aber nicht auf basemap.de. Farbe und Grau nutzen nur die
Kachelquelle `bm_web_de_3857`. **Relief braucht zusätzlich** die Höhenlinien-Kacheln `bm_web_hl_de_3857` und zwei
WMS-Schummerungen – ein einzelner QGIS-Vektorkachel-Layer hat nur eine Kachelquelle, Relief ist deshalb vorerst
nicht im Themen-Dropdown. Style-Version der JSONs am 05.10.2026: `basemapde:style-version` 5.1.0.
- **QGIS kennt kein „Darstellung geändert“-Kennzeichen pro Layer.** Für ungespeicherte Änderungen am Thema wird
deshalb ein Prüfwert der QML (Symbologie + Beschriftung, ohne `version`-Attribut) als Layer-Eigenschaft gemerkt
und vor dem Themenwechsel verglichen (`basemap_themen.aenderungsstand`). Die Berechnung schreibt die rund 3,7 MB
große QML in eine temporäre Datei. Dieselbe Darstellung ergibt in QGIS dieselbe QML, der Prüfwert ist also stabil
(manueller QGIS-Test 05.10.2026). Auch „Punktlinien korrigieren“ zählt als Änderung. (05.10.2026)
- **basemap.de P10 Vektor ist kein Kacheldienst (Basis #102).** Es ist ein bundesweites GeoPackage (60,3 GB, 40
Tabellen, **EPSG:25832**, Beta vom 14.08.2026, optimiert für QGIS 3.44.8). Die Basemap-Werkzeuge in `sn_basis`
(Erkennung, `selectByGeometry`, Legendenkatalog nach Style-IDs, Stilvorlagen über `renderer().styles()`) setzen
Vektorkacheln voraus und greifen dort nicht; die QGIS-Legende funktioniert dagegen selbst. Weitere Befunde der
Prüfung vom 06.10.2026:
- Stile gibt es nicht als `layer_styles`, sondern als ein in `qgis_projects` eingebettetes QGIS-Projekt (29 Layer).
Farbe/Grau steuert die Projektvariable `@project_theme` (`'gry'`) zusammen mit 73 benannten Projektfarben
(`project_color_object('Seeblau'|'Seeblau_gry')`). Wer nur die Layerstile übernimmt, verliert die Farben.
- Direktes Lesen aus dem Netz (`/vsicurl/`) ist zu langsam: Die Objekte liegen in der Datei nicht räumlich sortiert,
3 × 3 km und 5 Layer kosteten rund 3 900 Teilabrufe (etwa 8 min); nach einigen tausend Abrufen trennt der Server
die Verbindung. Nur nach vollständigem Download zuschneiden; `ogr2ogr` kopiert `qgis_projects` voraussichtlich nicht mit.
- Die Beta-Lizenz erlaubt die Nutzung nur „zu Testzwecken“ (Nr. 2.2). (06.10.2026)
- **WFS-Beschränkungen der sächsischen ALKIS-Dienste:** POST/GML-Filter werden blockiert, URL-Länge ist begrenzt, serverseitige Feature-Limits. Deshalb arbeiten Flurstücks- und Grenzpunktabrufe mit BBOX, gemarkungsweisen Batches und Nutzerdialogen. Nicht „vereinfachen“, ohne das gegen den Dienst zu testen. Vollständig mit erprobten Anfragen: `docs/wissen/wfs_dienste.md`, Objektarten/Attribute: `docs/wissen/alkis_objektarten.md`. (Verfahrensgebiet, Code)
- **Zwei Linklisten.** Zentrale `Linkliste/linkliste.csv` (Spalten `id;gruppe;ebene;inhalt;url;provider;stil`) und die vom Plugin genutzte `Plugin_SN_Plan41/assets/Linkliste.xlsx` (`ident, gruppe, kartenebene, inhalt, link, provider, stildatei`) sind nicht verbunden. Änderungen an Diensten in **beiden** nachziehen, bis die Zusammenführung entschieden ist. (09/2026)
- **ArcGIS-REST-Layer nicht nach Nummer deuten.** Gleiche Layer-URLs werden in der Linkliste und im Alternativansatz unterschiedlich benannt; Bedeutung und Geometrie immer gegen die Dienstmetadaten prüfen. (Vergleich Alternativansatz 09/2026)
- **CRS:** Plan41 und VLN-API arbeiten in EPSG:25833. Der Alternativansatz erzeugt EPSG:25832. Für neue Layer 25833 verwenden, bis eine Entscheidung dokumentiert ist.
- **Shape-Import erwartet Feld `FBSchl`** mit `901/10110F` (Neuordnungsgebiet) oder `901/10120F` (Neuvermessungsgebiet). Exporte mit abweichendem Feldnamen (`FBSchl.`) wurden bis 26.8.3 abgewiesen; seit PR Verfahrensgebiet #45 (02.09.2026, 26.8.4-unstable) ist die Feldsuche tolerant. Neue Exportvarianten trotzdem gegen die Erkennung testen.
- **Eigentümerdaten sind personenbezogen (Verfahrensgebiet #56).** Der Serienbriefexport wird vom Anwender von Hand als CSV-Layer geladen; das Plugin liest ihn nur. Namen und Anschriften gehören nicht in `print`, Meldungsleiste, Projektvariablen oder Testdaten (Tests nutzen erfundene Namen, `test_suche_gibt_nichts_aus` prüft die Konsole). Ein gespeichertes Projekt enthält nur den Pfad zur CSV, nicht die Daten. Die Korrektur-CSV (`<Eigentümerdatei>_korrekturen.csv`) enthält ebenfalls Personendaten und liegt deshalb neben dem Export, nicht im Projekt- oder Plugin-Ordner. Das Anzeigefenster für den Eigentümer zeigt nur Name, Anschrift und E-Mail; Konten, Personen-IDs und Kennzeichen bleiben im Tab. (06.10.2026)
- **Kein randloses Vollbild für eigene Fenster (Verfahrensgebiet #56).** Das Anzeigefenster für den Eigentümer sollte per `windowHandle().setScreen()`, `setGeometry()` und `showFullScreen()` auf dem zweiten Bildschirm erscheinen. Im QGIS-Test (06.10.2026, Windows) landete es trotzdem immer auf dem Hauptbildschirm und ließ sich im Vollbild weder verschieben noch schließen; es verdeckte QGIS, nur ein hartes Beenden von QGIS half. Seitdem öffnet es als normales Fenster mit Rahmen, der Bearbeiter schiebt es selbst auf den richtigen Bildschirm und kann es dort maximieren; `saveGeometry()`/`restoreGeometry()` merkt die Lage für die nächste Sitzung. Allgemein: Fenster, die QGIS verdecken können, brauchen immer einen Weg hinaus (Rahmen, Schließen-Knopf). (06.10.2026)
- **QGIS liest Zahlen-Spalten einer CSV als Zahl.** Beim Laden als Textdatei-Layer erkennt QGIS Feldtypen; eine PLZ `01067` wird dabei zur Ganzzahl `1067` – in Sachsen beginnt fast jede PLZ mit 0. `eigentuemer_suche._plz` stellt die Null wieder her. Kennungen wie `EIG_KONTO` oder `PER_ID` deshalb als Text vergleichen, nie als Zahl. (06.10.2026)
- **VLN-Upload ersetzt den Serverbestand der VKZ vollständig** (`PUT`). Vor dem Upload sicherstellen, dass alle Teillayer geladen sind.
- **API-Key liegt in `QSettings`** (Registry/Konfigurationsdatei), kein sicherer Schlüsselspeicher. Niemals in Logs oder Tests ausgeben.
## Code-Konventionen, die man kennen muss
- **`layer.extent()` steht im KBS des Layers, nicht im Projekt-KBS.** Solange das Projekt in EPSG:25833 steht wie
alle sächsischen Daten, fällt das nicht auf. Mit einem anderen Projekt-KBS landen `canvas.setExtent(layer.extent())`
und `map_item.setExtent(layer.extent())` an der falschen Stelle; die Layer selbst rendert QGIS trotzdem richtig
(Umprojektion beim Zeichnen). Immer `zoom_auf_layer` bzw. `transformiere_rechteck` verwenden (Basis #99).
Layoutkarten ohne `setCrs` folgen dem Projekt-KBS; Gitter (500 Karteneinheiten) und Maßstab setzen Meter voraus.
(05.10.2026)
- **Dock-Inhalt ohne Scroll-Bereich verlängert das QGIS-Fenster.** Qt verlangt für ein Dock mindestens die Höhe seines
Inhalts (beim `QTabWidget`: des höchsten Tabs). Ist sie größer als der Bildschirm, wächst das Hauptfenster nach unten
aus dem Bild, statt dass ein Scrollbalken erscheint. Abhilfe: Inhalt in `QScrollArea` mit `setWidgetResizable(True)`;
in den LNO-Docks erledigt das `BaseDockWidget.setWidget` (Basis #104). Die VLN-Plugins („VLN Karte“ 2.0, „VLN Karten“
0.5) haben keine eigene Lösung, ihr Inhalt ist nur kurz genug. (05.10.2026)
- **Legendenelemente im Layout (QGIS 3.44):** `QgsLayoutItemLegend.adjustBoxSize()` wirkt erst, nachdem das
Element einmal gezeichnet wurde – beim Anlegen per Code ändert es nichts. Platzbedarf vorher über
`QgsLegendRenderer(legende.model(), einstellungen).minimumSize(QgsLayoutUtils.createRenderContextForLayout(layout, None))`
berechnen; für mehrere Spalten zusätzlich `setSplitLayer(True)`, sonst bleibt ein Layer in einer Spalte.
Eine Legende mit `setLegendFilterByMapEnabled(True)` blendet Layer aus, die nicht in der Karte liegen, und ihre
Höhe steht erst nach dem Rendern fest. (02.10.2026, Spike Basis #88)
Auch `QgsLegendRenderer.minimumSize` liefert vor dem ersten Zeichnen die **ungefilterte** Höhe (Beispiel: 344 statt
177 mm). Verlässlich vermessen: Legende einmal mit geringer Auflösung zeichnen
(`QgsLayoutExporter(layout).renderRegionToImage(legende.sceneBoundingRect(), QSize(), 25)`), danach wirken
Filter und `adjustBoxSize`. (02.10.2026, Basis #93)
Mehrspaltige Legenden: Mit `setEqualColumnWidth(True)` bestimmt der längste Text die Breite **aller** Spalten.
Schmaler wird es mit ungleichen Spalten und `setAutoWrapLinesAfter(mm)`; der Legendentitel bricht dabei **nicht**
automatisch um und bestimmt die Mindestbreite – Zeilenumbruch (`\n`) im Titel setzen. (02.10.2026, Basis #96)
`setMinimumSize` an Layoutelementen wird **nicht im Projekt gespeichert**: Nach dem Neuladen schrumpft eine
Legende mit „an Inhalt anpassen“ bei der nächsten Größenberechnung wieder (gemessen 180 → 43,7 mm). Mindestgröße
am Layout vermerken und beim Laden (`readProject`) neu setzen. (02.10.2026, Basis #96)
- **Projektvariablen-Schlüssel ohne `sn_` übergeben.** `set_variable("sn_abdeckungslayer", ...)` erzeugt `sn_sn_abdeckungslayer` (Altlast in Druckmodulen; funktioniert nur, weil Lesen und Schreiben denselben Fehler machen).
- **Zwei Schreibweisen für den Verfahrensgebiet-Layer:** `verfahrensgebiet_layer` (Manager, Fachplugins) und `verfahrensgebietslayer` (`print_logic.py`). Bis zur Bereinigung nicht auf Gleichheit vertrauen.
- **Layer werden über Anzeigenamen gefunden** (`BROR_LAYER_NAME` usw.). Umbenennungen in der UI brechen Abläufe.
- **`print()` ist im Code verbreitet**, aber kein Logging. Neue Ausgaben über `message_wrapper` (Nutzer) oder gar nicht; Debug-`print` vor dem PR entfernen.
- **Testrunner pro Repo (`tests/run_tests.py`) und Workspace-Runner unterscheiden sich.** Für PR-Nachweise zählt `scripts/run_tests.py --baseline`.
- **Tests der Verfahrensgebiet-Suite sind teils veraltet** (erwarten Einzeldatei-/Einzellayer-Schnittstellen vor der Mehrfachauswahl). Vor dem Fixen prüfen, ob der Test oder der Code falsch ist; siehe Baseline.
- **Bezeichner (Layernamen, Dateinamen) nie mit eigenem Regex bereinigen.** `sanitize_bezeichner` aus
`sn_basis.functions.text_wrapper` verwenden – Umlaute, `ß`, `_` und `-` wurden in mehreren KI-generierten
Regexen vergessen (Plugin_SN_Basis #42).
- **Deutscher Text ohne Umlaute/ß ist ein eigenständiges Muster, kein Einzelfall.** Bei der Aufarbeitung von
#42 fanden sich über alle Fachplugins verteilt MessageBox-Texte, Labels und Docstrings, die wortwörtlich als
ASCII generiert wurden (`gueltig` statt `gültig`, `ueber` statt `über`, `Massstab`/`Groesse` als Anzeigetext
statt `Maßstab`/`Größe`) – typisch für KI-generierten Text, der Sonderzeichen vermeidet. Neuen deutschen Text
(Meldungen, Labels, Kommentare, Docstrings) immer mit echten Umlauten/ß schreiben, nicht mit `ae`/`oe`/`ue`/`ss`
behelfen. Vor dem Commit `python scripts/pruefe_umlaute.py [<repo>]` laufen lassen – findet genau dieses
Muster (String-Inhalte und Kommentare mit Leerzeichen, die einen bekannten ASCII-Wortstamm enthalten;
technische Bezeichner ohne Leerzeichen werden nicht angetastet). Die Wortstammliste im Skript ist bewusst
konservativ (keine Fehlalarme wichtiger als Vollständigkeit) – Ersatz fürs Lesen des eigenen Textes ist sie
nicht.
## Zusammenarbeit
- **Tool-Gedächtnis ist lokal.** Die Claude-Auto-Memory sieht niemand sonst. Geteiltes Wissen nur in diesem Ordner (siehe Issue Basis #36 „shared-memory-architektur“, Kai).
- **Issues sind teils Diskussionen**, nicht Aufträge (Label `Diskussion`). Vor der Umsetzung Konsens im Issue abwarten oder im PR als Annahme kennzeichnen.