30 KiB
PO-Cleanup: Chatbot-Entfernung + Neutralisierung (Quellen/Felder & Denormalisierung) + Dokumentengenerierung
Beschreibung und Kontext
Vier zusammenhaengende Aufraeum-/Verbesserungsarbeiten an der Plattform:
- A0 (Cleanup, dringend): Das Feature
chatbotwird nicht mehr benoetigt und soll vollstaendig aus dem Code entfernt werden (UI + Backend: Routen, Interfaces, Datamodels, Methoden, RBAC-/i18n-/Registry-Hooks, Tests). Zusaetzlich: LangChain/LangGraph komplett entfernen (Deps + Code) und die verbleibenden Nutzer (realEstate-BZO-Extraktion,ChatStreamingHelper) auf die regulaere AI-Service-Nutzung umstellen, wie alle anderen Nutzer im System. Wiki nachfuehren: Chatbot-Komponente in der aktuellen Doku entfernen bzw. ins Archiv verschieben. Scope: keine DB-Zeilen-Bereinigung (Feature-/Instanz-Rows, RBAC-Rollen, Droppoweron_chatbotseparat). - A1 (Neutralisierung — Anreicherung/Denormalisierung): Pruefen, dass denormalisierte (rueckuebersetzte) Inhalte nie persistiert werden, und einen sicheren Agent-Pfad bereitstellen, der Platzhalter ausschliesslich lokal (Private-LLM-Mapping) rueckuebersetzt und zum Download ohne Speicherung zurueckgibt.
- A2 (Neutralisierung — Quellen/Felder): Die Feld-Neutralisierung bei
FeatureDataSource-Abfragen so korrigieren, dass Datensaetze nicht unbrauchbar werden: Strings immer (substring-basiert) neutralisieren, Binary droppen, andere Typen nur bei explizitem Feld-Flag — vererbungs- und typbewusst. - A3 (Dokumentengenerierung): Dokumente sehen heute alle gleich aus (ein Standard-Style). Typ-spezifisches Styling (z. B. Klageschrift vs. Marketing mit Bildern) ermoeglichen und die Eignung der Renderer fuer sehr grosse Dokumente (z. B. 1000-seitiges Word-Buch mit eingebetteten Bildern) klaeren/verbessern.
Business-Treiber: Reports/Dokumente sind das sichtbare Endprodukt beim Kunden; Neutralisierung ist Compliance-kritisch (kein Klartext-Leak in Storage). Chatbot-Reste erhoehen Wartungslast und RBAC-/i18n-Rauschen.
Risiko bei Nicht-Umsetzung: A0 — toter Code + verwirrende Admin-UI. A1 — Datenschutzrisiko (Klartext im Storage) und ein dokumentierter, aber nicht implementierter Pfad. A2 — neutralisierte DB-Datensaetze sind fuer den Sub-Agent unbrauchbar bzw. inkonsistent gegenueber der UI. A3 — Reports wirken unprofessionell und grosse Dokumente koennen OOM/Timeout verursachen.
Abhaengigkeiten: A1 und A2 nutzen dieselbe NeutralizationService-Engine; aenderungen an der dokumentierten Invariante in b-reference/platform/neutralization.md + e-compliance/neutralisierung-detail.md. A3 beruehrt den ADR aus 4-done/2026-04-ai-reports-theming-and-pipeline.md (bewusste Entscheidung GEGEN Theme-Presets).
Fokus und kritische Details
A0
- Feature-Discovery ist glob-basiert (
loadFeatureRouters/loadFeatureMainModulesinmodules/system/registry.py) — Loeschen des Ordners ist boot-sicher; der Loader ueberspringt fehlende Module. chatbot-Feature (featureCode=chatbot, LangGraph, DBpoweron_chatbot,ChatbotConversation/Message/Document/Log) ist klar getrennt vom generischen Agent-Chat (datamodelChat.py:ChatWorkflow/ChatMessage, Workspace). Letzteres bleibt.methodChatbotist chatbot-spezifisch und wird entfernt;methodAiist unabhaengig und bleibt.WorkflowModeEnum.WORKFLOW_CHATBOTindatamodelChat.pywird ausserhalb der Datei nicht referenziert — Datei bleibt, nur das Enum-Element +frontend_options-Eintrag entfernen.- LangChain/LangGraph wird komplett entfernt. Die einzigen Nicht-Chatbot-Nutzer sind:
realEstate/bzoExtractionLangGraph.py: nutztlanggraph.graph.StateGraphnur als triviale Orchestrierung.create_bzo_extraction_graph()ist eine lineare 4-Knoten-Pipeline aus reinen Python-/Regex-Funktionen (classify_and_assemble->extract_zones_and_tables->extract_rules) ohne LLM -> ersetzbar durch sequenzielle Funktionsaufrufe.create_bzo_params_extraction_graph()ist ein Ein-Knoten-Graph umllm_extract_bauzone_params_node, der den LLM-Call bereits ueberai_service.callAiPlanning(...)macht (also schon regulaerer AI-Service) -> Knoten direkt awaiten. Es ist keine LangChain-Model-Bridge noetig.serviceCenter/core/serviceStreaming/helpers.py(ChatStreamingHelper): nutztlangchain_core.messages; einzige Konsumenten sind die Chatbot-Module (mainChatbot/service/chatbot, in A0 entfernt) -> nach A0 unbenutzt, kann mithelpers.py+ denserviceStreaming-Exports entfernt werden.
requirements.txt:langchain,langchain-core,langgraph,langchain-tavily,nest-asyncio(nur fuer LangGraph) entfernen;requirements.lockneu erzeugen.AdminFeatureAccessPage.tsxtraegt die meisten UI-Referenzen (~82) — chirurgisch, nicht Datei loeschen.
A1
- Reverse-Resolution ist ein DB-Mapping-Lookup (
NeutralizationService.resolveText:[typ.uuid]->DataNeutralizerAttributes.originalText), kein LLM-Call. Der Private-LLM macht nur die Vorwaerts-Erkennung. Das ist der datenschutzsichere Pfad (lokal, deterministisch, kein externes Modell sieht Klartext). _rehydrateResponse()inmainServiceAi.pyist toter Code (keine Call-Sites), die Docstrings behaupten aber automatische Rehydration — Chat persistiert die Modell-Antwort wie geliefert (kein Re-Save mit Klartext). Doc/Impl-Mismatch.- Tatsaechliche Klartext-Risiken liegen NICHT bei der Denormalisierung, sondern bei:
downloadFromDataSource(Roh-Bytes at rest),writeFile/renderDocument(agent-komponierter Inhalt),RoundMemory.fullData.
A2
- Aktuell:
_neutralizeRowFieldsersetzt den ganzen Feldwert durch[NEUT.<field>.<hash>], nur fuer explizit gelisteteneutralizeFields; die Maskenliste in_featureSubAgentTools.pyignoriert vererbteneutralize-Flags zur Query-Zeit; keine Typ-Verzweigung; Binary wird zu"<binary N bytes>"stringifiziert und ggf. gehasht (nicht gedroppt). - Das ist die heute dokumentierte Invariante (neutralization.md Failsafe 5/6) — A2 aendert sie bewusst.
- Substring-Neutralisierung pro String-Zelle via Private-LLM erzeugt Latenz/Kosten bei grossen Result-Sets — Batching + bestehender 5-Min-Result-Cache als Mitigation.
A3
- JSON-Dokumentmodell + Unified-Style-Schema sind ein Asset, nicht das Problem.
- Ursache "alle Dokumente gleich":
resolveStyle(None)injiziert immerDEFAULT_STYLEund reicht es truthy an die Renderer (mainServiceGeneration.py~L410/L475); der Agent setztstyleselten;documentThemeist deklariert, aber nicht verkabelt (methodAi.py). Renderer sind in Ordnung — Orchestrierung ist die Luecke. - ADR-Spannung: 2026-04-ai-reports-theming-and-pipeline.md entschied bewusst GEGEN Theme-Presets/Mandate-CI und FUER "Agent fuellt generischen Style-Block". Der Wunsch nach typ-spezifischem Styling (Klageschrift/Marketing) wird damit nur erreicht, wenn der Agent den Style wirklich treibt. Vorschlag (ADR-konform): Presets als smarte Defaults, die der Agent waehlt und ueberschreiben kann — nicht als harte Vorgabe.
- Grosse Dokumente: voll in-memory, Bilder als base64 im JSON, kein Streaming (reportlab
doc.build, python-docxDocument()). Das ist der echte Blocker fuer 1000 Seiten + Bilder.
A3 Grossdokument-Analyse & Empfehlung (2026-06-02, AC15 — Schritt 1+2 UMGESETZT)
Status: Schritt 1+2 umgesetzt+getestet; Schritt 3 (HTML-Backend) bewusst geschlossen (nein). Theming (AC13) ist umgesetzt+getestet.
Konkrete Engpaesse (mit Fundstellen):
- Ein grosses JSON haelt ALLE Bild-Bytes gleichzeitig.
_mediaTools._renderDocument(L110–185) loestfile:fileId-Bilder VORrenderReportzubase64Dataim JSON auf; PDF/DOCX-Renderer (_renderJsonImage) lesen ausschliesslichbase64Data/Data-URI. → Peak-Memory ~ Summe aller Bilder (base64 ≈ +33%). - Voll-in-memory Build:
rendererPdfbaut komplettestory-Liste +doc.build(L198–245);rendererDocxbautDocument()unddoc.save(L122–180). Keine Section-/Seiten-Chunking, kein Flush.
Umsetzungsplan (jeweils einzeln testbar):
- Lazy File-Ref-Bilder — UMGESETZT 2026-06-02: Block-Bilder behalten
fileIdstatt vorab-base64Data.renderReport(imageResolver=fileId->bytes)setzt einen Per-Render-Resolver am Renderer (BaseRenderer._lazyResolveImageBase64); PDF/DOCX_renderJsonImageloesen on-demand auf.renderDocumenthaelt fuer pdf/docx Bilder als Referenz und speist den Resolver aus Knowledge-Chunks/chat.getFileData. DOCX: echter Ein-Bild-Speicher (python-docx kopiert Bytes sofort ins Package). PDF: vermeidet base64-Overhead + JSON-Retention; voll-streamendes PDF (reportlab haelt Image-Flowables bisdoc.build) erst mit Temp-File-Bildern in Schritt 2. Tests:tests/serviceGeneration/test_large_document_render.py(7 Tests, gruen) — Resolver-Aufrufe == N, Bilder eingebettet, JSON bleibt base64-frei. - Temp-File-Bilder fuer PDF — UMGESETZT 2026-06-02: PDF nutzt datei-basierte
Image(tmpPath)-Flowables (rendererPdf._renderJsonImageschreibt Bytes intempfile.NamedTemporaryFile, reportlab liest erst beimdoc.buildvon Disk; Cleanup infinallyvia_cleanupTempImageFiles). Damit sind nicht mehr alle Bild-Bytes gleichzeitig resident — echtes Streaming auch fuer PDF. python-docx bleibt single-save(Lib-Grenze), kopiert Bytes aber bereits beimadd_picture(Ein-Bild-Speicher). Section-Chunking ueber mehreredoc.build-Passes wurde NICHT umgesetzt: reportlab braucht die Story fuer eineSimpleDocTemplate.buildohnehin komplett, und Text-Flowables sind gegenueber den (jetzt datei-basierten) Bildern vernachlaessigbar — der eigentliche OOM-Treiber ist beseitigt. Tests:test_pdf_images_are_file_backed_and_cleaned. - Optionales HTML-first-Backend — ENTSCHIEDEN: nein (2026-06-02): WeasyPrint/Chrome wird NICHT als Zusatz-Backend eingefuehrt. Begruendung: Lazy- + Temp-File-Bilder beseitigen den Memory-Engpass fuer die unterstuetzten Formate; ADR 2026-04 sprach explizit gegen einen WeasyPrint-Ersatz. Bleibt als optionaler Future-Pfad ohne aktuellen Bedarf.
Bis dahin gilt als Mitigation der bestehende writeFile+renderDocument(sourceFileId=…)-Pfad (vermeidet riesige Tool-JSONs), und der PDF-Overflow-Guard (_buildPdfWithOverflowGuard) verhindert Layout-Abbrueche durch uebergrosse Bilder.
Ziel und Nicht-Ziele
Ziel
- A0: Keine lebenden
chatbot-Symbole/Referenzen mehr im Code (Backend + UI); kein LangChain/LangGraph-Import oder -Dep mehr;realEstate-BZO-Extraktion +ChatStreamingHelper-Pfad auf regulaeren AI-Service/Std-Python umgestellt; aktuelle Wiki-Doku ohne Chatbot-Komponente; Boot, Tests, Build gruen. - A1: Korrekte/ehrliche Doku + neues Agent-Tool, das Platzhalter via lokalem Mapping rueckuebersetzt und transient (Download, kein Save/Index/RoundMemory) zurueckgibt; toter Rehydrate-Code entfernt.
- A2: Feld-Neutralisierung gemaess Regeln 1–4 (siehe unten), vererbungs- und typbewusst, konsistent zwischen Query-Pfad und RAG-Bootstrap.
- A3:
documentThemeend-to-end verkabelt + kleine Preset-Bibliothek (agent-ueberschreibbar); Layout-Primitive fuer echte Dokumenttypen; Grossdokument-Pfad (File-Referenz-Bilder + Chunked/Streamed-Render).
Explizit NICHT
- A0: keine DB-Zeilen loeschen, kein Drop von
poweron_chatbot. z-archive-Inhalte NICHT inhaltlich anpassen — nur Dokumente ins Archiv verschieben, wo noetig. Keine funktionale Aenderung an derrealEstate-BZO-Logik (nur Orchestrierung/Imports), keine Aenderung am Extraktions-Ergebnis. - A1: keine automatische Rehydration der Modell-Antwort wieder einfuehren; kein externer LLM fuer Reverse-Resolution.
- A2: keine Aenderung an der Engine selbst (
NeutralizationService), nur an Aufruf/Policy infeatureDataProvider/Sub-Agent-Tool; externe Connector-Quellen (Folder-Level) bleiben unveraendert. - A3: kein vollstaendiger Renderer-Austausch als Pflicht; HTML-first-Backend nur als zusaetzliches, format-waehlbares Backend (Entscheidung offen).
Betroffene Module
A0 — Gateway (loeschen)
modules/features/chatbot/(gesamt: mainChatbot, routeFeatureChatbot, interfaceFeatureChatbot, service, chatbot, config, chatbotConstants,bridges/*,__init__)modules/workflows/methods/methodChatbot/(methodChatbot,actions/queryDatabase,__init__)scripts/script_db_init_chatbot.pytests/demo/test_demo_uc3_chatbot.pydocs/althaus-bot-v2-aufwandsschaetzung.md,-fragenkatalog.md,-preprocessor-assessment.md
A0 — Gateway (chirurgisch)
modules/routes/routeSystem.py(_getUiObjectsForFeature("chatbot")-Branch)modules/routes/routeAdminFeatures.py(Config-Cache-Invalidierung ~L781 + Docstrings)modules/shared/gdprDeletion.py(Chatbot-Interface-Branch ~L578)modules/interfaces/interfaceRbac.py(DATA_OBJECT_NAMESPACE_MAPChatbot*-Eintraege +USER_OWNED_NAMESPACES"chatbot")modules/shared/i18nRegistry.py(mainChatbotin beiden_featureModulePaths-Tupeln)modules/datamodels/datamodelChat.py(WORKFLOW_CHATBOT-Enum +frontend_options-Eintrag)tests/unit/methods/test_action_signature_validator.py(L267),tests/demo/test_demo_bootstrap.py(test_*NoChatbot),tests/demo/README.mdscripts/script_migrate_user_uid.py,scripts/script_db_export_migration.py(poweron_chatbot/DB_CHATBOT)- Nur Kommentare (kein Verhalten):
modules/aicore/aicoreModelRegistry.py,app.py,modules/workflows/methods/methodAi/methodAi.py,requirements.txt
A0 — Frontend (loeschen)
src/api/chatbotApi.ts,src/hooks/useChatbot.tssrc/pages/views/chatbot/(ChatbotConversationsView, ChatbotViews.module.css, index)src/pages/admin/ChatbotConfigSection.tsxwork-around/chatbot.ts
A0 — Frontend (chirurgisch)
src/App.tsx(Legacy-Redirectchatbot)src/pages/FeatureView.tsx(Import,ChatbotSettings,FEATURE_VIEWS.chatbot, DEBUG)src/config/pageRegistry.tsx(Icon-Keys)src/types/mandate.ts(FEATURE_VIEW_REGISTRY.chatbot)src/pages/admin/AdminFeatureAccessPage.tsx(Import + State/Config-Builder + JSX-Bloecke)src/pages/admin/Admin.module.css(.chatbotConfigSection),src/styles/pages.module.css(.chatbot*)src/stores/featureStore.tsx,src/api/featuresApi.ts(inkl. Mock-Fallback),src/hooks/useInstancePermissions.tsx(DEBUG + Keys)
A0 — LangChain/LangGraph-Entfernung + Migration (Gateway)
modules/features/realEstate/bzoExtractionLangGraph.py-> umbenennen zubzoExtraction.py:from langgraph.graph import StateGraph, START, ENDentfernen;create_bzo_extraction_graph()/graph.invoke(state)durch sequenziellen Aufruf (classify_and_assemble->extract_zones_and_tables->extract_rules) ersetzen;create_bzo_params_extraction_graph()/graph.ainvoke(state)durch direktesawait llm_extract_bauzone_params_node(state)ersetzen (LLM-Call bleibtai_service.callAiPlanning)modules/features/realEstate/mainRealEstate.py(L281 Import anpassen; Kommentare L2334/L2492/L2546 "LangGraph" entfernen)modules/features/realEstate/routeFeatureRealEstate.py(Docstrings L709/L790 "LangGraph"),modules/routes/routeRealEstate.py(Docstrings L2237/L2243)modules/serviceCenter/core/serviceStreaming/helpers.py(loeschen —ChatStreamingHelper/langchain_core),serviceStreaming/__init__.py(Export entfernen),serviceStreaming/mainServiceStreaming.py(getChatStreamingHelper()entfernen)requirements.txt(langchain/langchain-core/langgraph/langchain-tavily/nest-asyncio entfernen) +requirements.lockneu erzeugen
A0 — Wiki nachfuehren (aktive Doku; z-archive-Inhalte unveraendert)
- Chatbot-Referenzen aus aktiven Docs entfernen:
b-reference/product.md(Feature-Zeile + Repo-/Tech-Stack),b-reference/platform/database-architecture.md(poweron_chatbot),b-reference/platform-core/workflow.md,b-reference/platform-core/architecture.md,b-reference/platform/platform-diagrams.md,b-reference/ui-nyla/architecture.md,e-compliance/security-overview.md,README.md(Verweis auf nicht-existentesfeatures/chatbot.md) - LangChain/LangGraph aus Tech-Stack-/Architektur-Doku entfernen, wo erwaehnt (
b-reference/product.md,b-reference/platform-core/architecture.md) a-strategy/roadmap.md: Chatbot-Erwaehnungen pruefen/streichen (Strategie-Doc — nur wenn als aktive Komponente gefuehrt)- Falls ein aktives Doc rein Chatbot-spezifisch ist: nach
z-archive/verschieben (keine inhaltliche Aenderung). Aktuell existiert kein dediziertes aktives Chatbot-Reference-Doc -> ueberwiegend chirurgische Entfernung c-work/_CHANGELOG.md: Eintraege fuer Chatbot-Removal + LangChain-Removal
A1 — Gateway
modules/serviceCenter/services/serviceAgent/coreTools/_mediaTools.py(neues Tool, z. B.revealDocument)modules/serviceCenter/services/serviceAgent/toolboxRegistry.py(restriktive Toolbox)modules/serviceCenter/services/serviceAi/mainServiceAi.py(_rehydrateResponseentfernen, Docstrings korrigieren)modules/features/neutralization/serviceNeutralization/mainServiceNeutralization.py(resolveTextwiederverwenden)
A2 — Gateway
modules/serviceCenter/services/serviceAgent/featureDataProvider.py(_neutralizeRowFields,_applyFieldNeutralization,_serializeRow)modules/serviceCenter/services/serviceAgent/coreTools/_featureSubAgentTools.py(Maskenliste-Aufbau)modules/serviceCenter/services/serviceKnowledge/udbNodes.py(FdsFieldNode.getEffectiveFlag),_inheritFlags.py(Resolver)modules/serviceCenter/services/serviceKnowledge/subFeatureBootstrap.py(_serializeRowToTextangleichen)
A3 — Gateway
modules/serviceCenter/services/serviceGeneration/styleDefaults.py(THEME_PRESETS,resolveTheme)modules/serviceCenter/services/serviceGeneration/mainServiceGeneration.py(Theme-Aufloesung)modules/serviceCenter/services/serviceGeneration/renderers/*(Layout-Primitive, File-Ref-Bilder, Chunking)modules/serviceCenter/services/serviceAgent/coreTools/_mediaTools.py(renderDocument: Theme/Style aus Intent,aiServicedurchreichen)modules/workflows/methods/methodAi/methodAi.py+actions/generateDocument.py(documentThemedurchreichen)modules/datamodels/datamodelJson.py(Layout-Section-Typen)
DB-Migration
- A0: nein (Code-only; DB-Cleanup separat). A1: nein. A2: nein (Verhalten, keine Schema-Aenderung). A3: ggf. additive Schema-Erweiterung im JSON-Modell (kein DB-Pflichtfeld).
Andere Komponenten
service-llm-private,service-preprocessing,service-teams-browser-bot: keine chatbot-spezifischen Anpassungen noetig (A0). A1/A2 nutzen Private-LLM-Ratings (bereits vorhanden).- Deployment: nach LangChain-Removal Build/Image ohne diese Deps verifizieren (kleinere Image-Size, keine
nest-asyncio-Patches).
Entscheidungen
| Datum | Entscheidung | Begruendung |
|---|---|---|
| 2026-06-02 | A0 nur Code (keine DB/Wiki/Archive) | User-Scope-Entscheid; DB-Cleanup separat |
| 2026-06-02 | datamodelChat.py bleibt; nur WORKFLOW_CHATBOT-Enum entfernen |
Agent-Chat ist unabhaengig vom Chatbot-Feature |
| 2026-06-02 | LangChain/LangGraph komplett entfernen, verbleibende Nutzer migrieren | User-Entscheid; Nutzung ist trivial ersetzbar (realEstate-LLM laeuft schon ueber callAiPlanning, ChatStreamingHelper nur vom Chatbot genutzt) |
| 2026-06-02 | bzoExtractionLangGraph.py -> bzoExtraction.py: StateGraph durch sequenzielle Aufrufe ersetzen |
Graphen sind lineare/Ein-Knoten-Pipelines; kein Funktionsverlust |
| 2026-06-02 | Aktive Wiki-Doku ohne Chatbot/LangChain; z-archive nur verschieben, nicht anpassen | User-Entscheid (Wiki nachfuehren) |
| 2026-06-02 | A1: Reverse-Resolution bleibt DB-Mapping-Lookup (kein externer LLM) | Datenschutzsicher, deterministisch; "Private LLM" = lokal/intern |
| 2026-06-02 | A1: Neues Tool gibt transient zum Download zurueck, niemals Save/Index/RoundMemory | Klartext darf nicht at-rest landen |
| 2026-06-02 | A1: _rehydrateResponse entfernen statt verkabeln |
Toter Code + Doc/Impl-Mismatch; Auto-Rehydration ist Datenschutzrisiko |
| 2026-06-02 | A2: String-Zellen substring-neutralisieren (Feldname als Typ-Hint) statt Whole-Value-Hash | Datensaetze bleiben brauchbar; Platzhalter-Typ passend zum Feld |
| 2026-06-02 | A2: Binary droppen statt maskieren | Spez-Regel 2; Binary nie neutralisieren |
| 2026-06-02 | A2: number/date/bool nur bei EXPLIZITEM Feld-Flag (nicht vererbt) | Spez-Regel 3 |
| 2026-06-02 | A2: Query-Maske aus effektivem Flag (Vererbung) statt nur neutralizeFields-Liste |
UI-Effektivwert = Laufzeitverhalten |
| 2026-06-02 | A3: Presets als agent-ueberschreibbare Defaults (kein Hard-Mandate) | Reconciliation mit 2026-04-ADR |
| 2026-06-02 | A3: Theme-Wahl agent-getrieben via documentTheme-Tool-Param (Enum + Beschreibung), kein serverseitiges Auto-Select |
ADR-konform (Agent treibt Style); kein zusaetzlicher LLM-Call noetig |
| 2026-06-02 | A3: Layout-Primitive = cover_page + image_grid (Markdown-Fenced-Bloecke); letterhead/multi-column zurueckgestellt |
Hoechster Nutzen (Klageschrift-Titelseite, Marketing-Bildraster); multi-column ist Page-Template-Thema, nicht Block-Primitive |
| 2026-06-02 | A3: HTML-first-Backend (WeasyPrint/Chrome) — ENTSCHIEDEN: nein | Lazy+Temp-File-Bilder loesen Memory-Engpass; ADR sagte "kein WeasyPrint-Ersatz" |
Umsetzungs-Checkliste
A0 — Chatbot entfernen (Code)
- Backend-Verzeichnisse/Dateien loeschen (siehe Betroffene Module)
- Backend chirurgische Edits (routeSystem, routeAdminFeatures, gdprDeletion, interfaceRbac, i18nRegistry, datamodelChat, Tests, Scripts)
- Frontend-Dateien loeschen
- Frontend chirurgische Edits (App, FeatureView, pageRegistry, mandate, AdminFeatureAccessPage, CSS, Stores/Hooks/Api DEBUG+Keys)
- LangChain/LangGraph entfernen + migrieren:
bzoExtractionLangGraph.py->bzoExtraction.py(StateGraph raus),mainRealEstate.py-Import,ChatStreamingHelper/helpers.py+serviceStreaming-Exports entfernen,requirements.txt - Wiki nachfuehren: Chatbot + LangChain aus aktiven b-reference/e-compliance-Docs entfernen; ggf. Doc nach z-archive verschieben;
_CHANGELOG.md - Verifikation: Boot ok,
pytestgruen,tsc/vite buildgruen, keine lebendenchatbot/langchain/langgraph-Referenzen im Code; BZO-Extraktion liefert identisches Ergebnis wie vorher - [~]
requirements.lockNICHT noetig (Projekt nutzt nurrequirements.txt) — Punkt gestrichen (User-Entscheid 2026-06-02)
A1 — Denormalisierung sicher
- Agent-Tool
revealDocument(resolveText, mandate/instance-scoped, transient/no-save,readOnly=True) - In restriktiver Toolbox registrieren (
neutralization-Toolbox,isDefault=False-> explizit viarequestToolbox); RBAC ueber bestehende Neutralisierungs-Feature-Access _rehydrateResponseentfernen + Docstrings incallAi/callAiStreamkorrigieren- Doku: neutralization.md (Failsafe 8 + Tool), neutralisierung-detail.md
- Leak-Pfade dokumentieren (downloadFromDataSource/RoundMemory) + Folge-Ticket-Hinweis (neutralization.md "Bekannte Klartext-at-rest-Pfade")
A2 — Feld-Neutralisierung
_resolveFieldsToMaskForTable/neutralizePolicy(spiegeltFdsFieldNode.getEffectiveFlag)- Regel 1: String-Zellen substring-neutralisieren via
NeutralizationServicemit Feldname-Typ-Hint - Regel 2: Binary-Spalten vor Serialisierung droppen
- Regel 3: number/float/int/date/bool nur bei explizitem Feld-Flag
- RAG-Bootstrap
_serializeRowToTextan denselben Resolver/dieselbe Platzhalter-Policy angleichen (finalizeRowsAsync/_neutralizeAndSerializeRows) - Doku: neutralization.md Failsafe 5/6 + neutralisierung-detail.md Abschnitt 3
A3 — Dokumentengenerierung
THEME_PRESETS+resolveTheme(name)instyleDefaults.py(deep-merge auf DEFAULT_STYLE, agent-ueberschreibbar)documentThemeend-to-end verkabeln (Node/Action ->renderReport(documentTheme=...))renderDocument: Theme agent-getrieben via Tool-Param (Enum+Beschreibung); kein serverseitiges Auto-Select (ADR-konform)- JSON-Layout-Primitive
cover_page+image_grid(Markdown-Fenced-Bloecke) + PDF/DOCX-Handler;letterhead/multi-columnzurueckgestellt - Grossdokumente: File-Referenz-Bilder statt base64 (Schritt 1) + Temp-File-PDF-Bilder (Schritt 2)
- HTML-first-Backend evaluiert -> ENTSCHIEDEN: nein (nicht benoetigt)
Querschnitt
- RBAC / Permissions: A0 entfernt Chatbot-RBAC-Objekte/Template-Rollen aus Code; A1 Tool-Zugriff ueber bestehende Neutralisierungs-Rechte
- Neutralisierung betroffen? A1 + A2 = ja (Doku-Update Pflicht — erledigt)
- Navigation / Routing: A0 entfernt Chatbot-Feature-Views/Routen
- Billing-Impact? Nein (A2 nutzt bestehende AI-Call-Billing)
Akzeptanzkriterien
| # | Kriterium (Given-When-Then) | Prio |
|---|---|---|
| 1 | Given Codebase nach A0, When rg -i chatbot (ohne wiki/z-archive), Then keine lebenden Symbole/Routen/Interfaces |
must |
| 2 | Given Backend-Boot nach A0, When Worker startet, Then keine ImportError, Feature-Registry laedt ohne Chatbot | must |
| 3 | Given UI-Build nach A0, When vite build/tsc, Then keine dangling Imports/Typfehler |
must |
| 1b | Given Codebase nach A0, When `rg -i "langchain | langgraph"im Code, Then keine Treffer;requirements.txt` ohne diese Deps |
| 1c | Given dieselbe BZO-PDF vor/nach Migration, When run_extraction/run_bzo_params_extraction, Then identisches fakten/zones/rules-Ergebnis |
must |
| 1d | Given aktive Wiki-Doku nach A0, When durchsucht, Then keine Chatbot-Komponente/LangChain im Tech-Stack; z-archive-Inhalte unveraendert | should |
| 4 | Given Datei mit neutralisiertem Inhalt, When Agent revealDocument(fileId) aufruft, Then Klartext wird transient zurueckgegeben und NICHTS gespeichert/indexiert |
must |
| 5 | Given revealDocument, When ausgefuehrt, Then keine externe LLM-API beteiligt (nur DB-Mapping) |
must |
| 6 | Given mainServiceAi.py, When Code-Review, Then _rehydrateResponse ist entfernt und Docstrings korrekt |
should |
| 7 | Given FDS-Tabelle mit neutralize=True (vererbt, leere neutralizeFields), When queryTable, Then String-Felder sind substring-neutralisiert (Platzhalter im Text) |
must |
| 8 | Given String-Feld "Name"/"Adresse", When neutralisiert, Then Platzhalter-Typ entspricht dem Feldnamen-Hint | should |
| 9 | Given Binary-Spalte bei aktiver Neutralisierung, When queryTable, Then Spalte wird gedroppt (nicht maskiert) |
must |
| 10 | Given numerisches Feld nur via Vererbung (nicht explizit), When queryTable, Then Wert bleibt unveraendert |
must |
| 11 | Given numerisches Feld mit explizitem Feld-Flag, When queryTable, Then Wert wird neutralisiert |
must |
| 12 | Given RAG-Bootstrap einer FDS-Tabelle, When indexiert, Then dieselbe Policy/Platzhalter wie Query-Pfad | should |
| 13 | Given renderDocument mit documentTheme="legal", When gerendert, Then typ-spezifischer Style (nicht DEFAULT_STYLE) |
must |
| 14 | Given renderDocument ohne Theme/Style, When gerendert, Then neutrale Defaults (kein Crash) |
must |
| 15 | Given ~1000-seitiges Dokument mit Bildern, When gerendert, Then kein OOM/Timeout (Chunked + File-Ref-Bilder) | must |
Testplan
| ID | AC | Art | Automatisiert | Repo-Pfad | Status |
|---|---|---|---|---|---|
| T1 | 1,2,1b | smoke | ja | platform-core (boot + pytest tests/demo) |
pending |
| T2 | 3 | build | ja | ui-nyla (tsc, vite build) |
pending |
| T1b | 1c | regression | ja | platform-core/tests/features/realEstate/test_bzo_extraction_parity.py | pending |
| T3 | 4,5 | integration | offen | revealDocument no-persist: durch Tool-Design (transient SSE, kein Save/Index) + Code-Review abgedeckt; dedizierter Integrationstest braucht volle services-Plumbing -> als Folge-Ticket |
deferred |
| T4-T6 | 7-11 | unit | ja | platform-core/tests/unit/serviceAgent/test_field_neutralization.py (8 Tests: string/hint/binary-drop/inherited-skip/explicit/failsafe/dedup) | done |
| T7 | 12 | unit | ja | platform-core/tests/unit/serviceAgent/test_field_neutralization.py::test_rag_bootstrap_parity_with_query_path (gemeinsame _neutralizeAndSerializeRows-Policy; _serializeRowToText leakt nicht) |
done |
| T8 | 13,14 | unit | ja | platform-core/tests/serviceGeneration/test_style_resolver.py (Theme-Presets + Praezedenz) | done |
| T9 | 15 | unit | ja | platform-core/tests/serviceGeneration/test_large_document_render.py (8 Tests: PDF/DOCX lazy file-ref, Resolver-Count, JSON base64-frei, Temp-File-Bilder Schritt 2 + Cleanup) | done (Schritt 1+2) |
| T10 | 13 | unit | ja | platform-core/tests/serviceGeneration/test_layout_primitives.py (8 Tests: cover_page/image_grid Markdown-Parse + PDF/DOCX-Handler) | done |
Links
- Wiki Neutralisierung: b-reference/platform/neutralization.md, e-compliance/neutralisierung-detail.md
- Wiki AI-Agent/Tools: b-reference/platform-core/ai-agent.md
- ADR Doc-Theming: 4-done/2026-04-ai-reports-theming-and-pipeline.md
- Lokale Renderer-Referenz:
pamocreate/projects/_shared/html_to_pdf.py,md_to_pdf.py - PR: TBD
- Issue: TBD
Abschluss
b-reference/platform/neutralization.mdaktualisiert (A1 Failsafe 8 + reveal-Tool + Leak-Pfade; A2 Failsafe 5/6)b-reference/platform-core/ai-agent.mdaktualisiert (revealDocument-Tool + neutralization-Toolbox + Doc-Theming/Layout-Primitive)e-compliance/neutralisierung-detail.mdaktualisiert (A1/A2)b-reference/product.md+ Architektur-/DB-/Diagramm-Docs: Chatbot-Komponente + LangChain/LangGraph aus aktiver Doku entfernt (Teil A0)c-work/_CHANGELOG.mdje Change 1 ZeileTOPICS.mdgeprueft- [~] Dokument-Move nach
2-build//z-archive/: Verschiebung dem User ueberlassen (Arbeit fachlich abgeschlossen)