86 KiB
Changelog (c-work)
Eine Zeile pro Change, NEUESTE EINTRAEGE ZUOBERST. Begruendungen gehoeren ins zugehoerige
c-work/<phase>/<feature>.md oder die PR-Beschreibung.
Format: - YYYY-MM-DD | <type> | <scope> | <Kurzbeschreibung> [(c-work: <relPfad>)] [(PR: #123)]
type: feat fix refactor docs test chore build · scope: gateway frontend-nyla private-llm teams-bot wiki infra *
Skip: reine Refactors, Formatting, Lint, Dep-Bumps, Test-only, Wiki-Tippfehler.
2026-05-08
- 2026-05-08 | chore | frontend-nyla | config/.env.{dev,int,prod}: keep only VITE_API_BASE_URL and VITE_APP_NAME; removed unused flags and duplicated Entra/secret keys (backend owns secrets). env.d.ts aligned.
- 2026-05-08 | refactor | frontend-nyla | Remove MSAL from UI: deleted authConfig.ts + AuthProvider.tsx, rewrote ProtectedRoute (sessionStorage-only), removed useMsalRegister, simplified logout, uninstalled @azure/msal-browser + @azure/msal-react. All auth logic lives in gateway.
- 2026-05-08 | chore | frontend-nyla | Rename env files:
.env.{dev,int,prod}→env-poweron-nyla-{dev,int,prod}.env(naming matches workflow). Updated workflows, .gitignore, README.
2026-05-06
- 2026-05-06 | fix | frontend | UDB tab "Chatverläufe" renamed to "Dossiers" (UnifiedDataBar.tsx + i18n seed for xx/de/en/fr)
- 2026-05-06 | fix | gateway | PDF rendering: (1) _convertUnifiedStyleToInternal now maps spaceBeforePt/spaceAfterPt for headings, lineSpacing for paragraphs, bulletChar for lists — previously dropped silently; (2) DEFAULT_STYLE heading spacing increased (h1: 24pt before, h2: 20pt) for professional visual hierarchy; (3) _renderJsonBulletList uses dedicated BulletItem ParagraphStyle with leftIndent/firstLineIndent from bullet_list config — was identical to paragraph normalStyle
2026-05-05
- 2026-05-05 | fix | gateway | 4 warning fixes: (1) mainServiceAgent skips getWorkflow for synthetic workflowIds with ":" prefix (commcoach billing keys); (2) ActionNodeExecutor + actionToolAdapter inject parentOperationId so ai.process progress nests correctly; (3) ChatService.interfaceDbComponent now receives featureInstanceId — root cause was missing scope causing getFile to miss featureInstance-scoped files during graph execution; (4) IMAGE_GENERATE sections use concise _buildImagePrompt instead of full 700KB userPrompt — eliminates DALL-E truncation
- 2026-05-05 | fix | gateway | _getOrCreateTempFolder rewritten to use ComponentObjects.getOwnFolderTree/createFolder instead of raw db.getRecordset bypass; added explicit logging for all code paths; _persistLargeDocument now logs updateFields before updateFile call
- 2026-05-05 | fix | frontend+gateway | AI-generated files not visible: (1) useCommcoach.ts sendMessage documentCreated handler used undefined
sessionIdinstead ofsession.idcausing ReferenceError silently swallowed by SSE parser catch-all — system note never shown; (2) SSE parser catch blocks narrowed to JSON.parse only so handler errors propagate; (3) _getOrCreateTempFolder re-implemented to find/create user Temp folder; (4) all file-update call sites consolidated into single updateFile call to avoid RBAC scope conflict - 2026-05-05 | fix | gateway | CommCoach completeSession: session.get("contextId") → session.get("moduleId") — stale field name caused sessionCount to never update (always 0); getModules now computes live sessionCount from sessions table
- 2026-05-05 | fix | gateway | actionToolAdapter: _persistLargeDocument now handles bytes documentData (PDF/DOCX/PPTX were silently discarded); _formatActionResult returns sideEvents for fileCreated; scope set to featureInstance when featureInstanceId available; CommCoach+TeamsBot _runAgent forward FILE_CREATED as documentCreated SSE; silent warnings elevated to errors for data-loss scenarios
2026-05-04
- 2026-05-04 | feat | * | CommCoach Persona-Management: Gespraechspartner konfigurierbar. Backend: 5 neue Builtin-Personas (Paartherapeutin, Psychologe, Rechtsanwalt, Mediatorin, HR-Managerin), ModulePersonaMapping M:N-Tabelle mit DB-Migration M8, GET/PUT Module-Persona-Zuordnung. Frontend: Settings-Tab 'Gespraechspartner' mit FormGeneratorTable CRUD (Create/Edit/Delete custom Personas, Inline-Toggle isActive), Modul-Edit-Dialog mit Persona-Multi-Select, Session-Persona-Picker filtert nach Modul-Zuordnung. (c-work:
2-build/2026-04-comcoach-greenfield-ia.md)
2026-05-03
- 2026-05-03 | feat | * | ComCoach + TeamsBot Greenfield-IA: Implementierung abgeschlossen. Backend: CoachingContext -> TrainingModule (Rename, moduleType Enum, kpiTargets, category entfernt), neue Module-CRUD-Routes. TeamsBot: TeamsbotMeetingModule Entity (additiv), Module-CRUD, agentRun SSE-Events sichtbar, Stats-Karten, adaptives Dashboard-Polling (3s/30s). Frontend: Beide Features 5-Tab-IA (Dashboard, Assistent, Module, Session, Settings), neue View-Komponenten (AssistantView Wizard, ModulesView CRUD), KeepAlive nur noch fuer Session-Tab, Settings Statistik entfernt, Dashboard navigiert zu Modules statt Dossier. (c-work:
2-build/2026-04-comcoach-greenfield-ia.md,2-build/2026-04-teamsbot-greenfield-ia-and-live-update.md) - 2026-05-03 | docs | wiki | ComCoach + TeamsBot Greenfield-IA: Plaene verifiziert und in
2-build/verschoben. Alle Zeilennummern und Code-Referenzen gegen aktuelle Codebase geprueft (alle korrekt). ComCoach-Plan ergaenzt:goals-Feld existiert bereits (JSON->Freitext-Migration),category-Enum wird durchmoduleTypeersetzt,description-Feld bleibt. TeamsBot-Plan ergaenzt: NamenskonventionstartedByUserIddokumentiert. Beide Plaene:<!-- status: build -->,<!-- verified: 2026-05-03 -->. (c-work:2-build/2026-04-comcoach-greenfield-ia.md,2-build/2026-04-teamsbot-greenfield-ia-and-live-update.md) - 2026-05-03 | fix | gateway | AI Step Output:
contextFeld zeigte Prompt statt Input-Context.actionNodeExecutor.pybauteout["context"]falsch auspromptText + extractedContextzusammen. Wenn AI ein Binary-Dokument erzeugte (z.B. Excel), warextractedContextleer undcontextwurde identisch mitprompt. Jetzt wird der tatsaechliche aufgeloestecontext-Input-Parameter gespeichert. - 2026-05-03 | fix | frontend-nyla | FormGeneratorTree: Auto-Scroll bei Expand am unteren Bildschirmrand. Wenn ein Gruppenobjekt in der unteren Haelfte des sichtbaren Bereichs expanded wird, scrollt der Container den Parent-Node zur Mitte, damit Kinder ohne manuelles Scrollen sichtbar sind.
- 2026-05-03 | fix | frontend-nyla | Automation > Workspace Tab: Polling fuer laufende Runs.
_WorkspaceTabpolltfetchWorkspaceRunDetailalle 3s solange Run-Status nicht terminal. Stoppt automatisch bei completed/failed/cancelled. - 2026-05-03 | fix | gateway | executeCode Sandbox:
typeentblockt,iorestricted, Modul-Liste dynamisch.type()aus_PYTHON_BLOCKED_BUILTINSentfernt.import ioliefert eingeschraenktes Modul (nur StringIO/BytesIO, kein io.open). Tool-Beschreibung dynamisch ausSANDBOX_ALLOWED_MODULESgeneriert.type()war faelschlich in_PYTHON_BLOCKED_BUILTINS(harmlos ohne exec/eval).StringIO/BytesIOals sichere Builtins (io.open wird nicht exponiert). Tool-Beschreibung aktualisiert. - 2026-05-03 | fix | gateway | AI Agent: docItem-Resolution Root Cause + executeCode readFile. (1)
coerceDocumentReferenceList: Dict-Pfad strippt jetztdocItem:/docList:Prefix korrekt viafrom_string_list(war: Prefix blieb indocumentId, erzeugte Doppel-Prefix beito_string()). (2)process.py:DocumentItemReferencewird nur im Automation2-Kontext (kein Chat-Workflow) an_resolve_file_refs_to_content_partsgeroutet; im Agent-Kontext fliessen sie korrekt durchgetChatDocumentsFromDocumentList(war: alle Refs wurden abgefangen und fehlerhaft als File-Store-IDs behandelt). Gebrochenen_resolveChatDocIdToFileId-Fallback entfernt. (3) executeCode Sandbox:readFile(fileId)Built-in fuer Workspace-Dateizugriff (kein open(), nur managed Files via interfaceDbComponent). - 2026-05-03 | fix | gateway | AI Agent + Rendering: 9 Issues geloest. (1) Sandbox
time-Modul erlaubt. (2) ActionToolAdapter: grosse Docs als Workspace-Files persistiert. (3) downloadFromDataSource: Debug-Logging fuer Filename-Swap. (4) clickup_listTasks: Datums-/Custom-Field-Filter. (5) Renderer style-Bug:styleKeyword auf allen 8 Renderern akzeptiert (CSV, Text, JSON, Markdown, Image, CodeXml, CodeJson, CodeCsv). (6) _ServicesAdapter: workflow-Setter fuer Agent-Kontext (getChatDocumentsFromDocumentList braucht workflow). (7) _ServicesAdapter: interfaceDbComponent Property (ai_process file-ref Resolution). (8) Auto-index nach Neutralize: mandateId/featureInstanceId an _autoIndexFile durchgereicht. (9) Kombination: Agent sollte AI-Workspace-Aufgaben effizient loesen. - 2026-05-03 | chore | frontend-nyla | Stage 4: FolderTree Dead-Code geloescht + Tree-Assessment. Gesamter
components/FolderTree/-Ordner entfernt (FolderTree.tsx 1170 LOC, SharepointBrowseTree.tsx 319 LOC, actions/, CSS -- alles Dead Code). ESLint-Deprecation-Regel entfernt. Assessment aller verbleibenden Tree-Kandidaten: DataPicker, InstanceHierarchyView, AccessRulesEditor, TreeNavigation, redmineTreeLogic -- alle SKIP (kein Entity-Tree-Paradigma). (c-work:4-done/2026-05-formgenerator-tree-and-folder-recovery.md) - 2026-05-03 | docs | wiki | Stage 5: FormGeneratorTree Wiki-Dokumentation.
formgenerator.md: neuer Abschnitt FormGeneratorTree (Provider-Interface, Features, Props, Verwendung, Tree-vs-Table-Vergleich).architecture.md: FolderTree-Referenzen durch FormGeneratorTree ersetzt.TOPICS.md: FormGenerator-Eintrag ergaenzt. Plan nach4-done/verschoben. (c-work:4-done/2026-05-formgenerator-tree-and-folder-recovery.md) - 2026-05-03 | docs | wiki | FormGeneratorTree Plan: Stage 3 deferred, Stage 0-2 abgeschlossen. Stage 3.A/3.B (SourcesTab/ChatsTab-Refactor auf FormGeneratorTree) deferred -- domaen-spezifische Tree-Logik passt nicht sinnvoll auf generische TreeNodeProvider-Abstraktion. Plan-Status auf
donegesetzt. Stage 2.C Checkliste aktualisiert mit allen 2.C-Fixes (405-Fix, typeMap, Refresh-Icon, confirm-Dialoge, FilesPage-Sync). (c-work:4-done/2026-05-formgenerator-tree-and-folder-recovery.md)
2026-05-02
- 2026-05-02 | fix | frontend-nyla | Tree batch-delete: separate Ordner/Dateien-Aktionen.
TreeBatchAction.typeFilterintypes.ts;FormGeneratorTree.tsxfiltertselectedIdsnach Typ und zeigt Counts pro Button.FolderFileProvider.tsxliefert zwei getrennte Batch-Aktionen (Ordner-Cascade-Delete vs. File-Delete/Batch-Delete). FilesPage tree-table Sync wiederhergestellt:selectedFolderIdfiltert Tabelle nach Ordner; File-Klick im Tree scrollt+highlighted die Tabellenzeile (2.5s auto-clear). (c-work:1-plan/2026-05-formgenerator-tree-and-folder-recovery.md)
2026-05-01
- 2026-05-01 | feat | gateway | Stage 1.B FormGenerator Folder RBAC: FileFolder in TABLE_NAMESPACE, 11 folder methods in interfaceDbManagement (CRUD, move, cascade-delete, scope, neutralize), 6 routes in routeDataFiles replacing 501 stubs
- 2026-05-01 | feat | frontend-nyla | Stage 2.A + 2.B: FilesTab + FilesPage tree integration.
FilesTab.tsxrewritten fromFormGeneratorTableto twoFormGeneratorTreesections (Eigene/Geteilt mit mir) with drag-drop upload, refresh-by-key, and workflow-import on node click.FilesPage.tsxupdated with split-view layout: 300px tree panel (left, own+shared trees) andFormGeneratorTable(right) with view-mode toggle (Tree-Sicht / Liste mit Gruppen); groupingConfig applied only in grouped mode; upload and refresh sync both tree and table. (c-work:1-plan/2026-05-formgenerator-tree-and-folder-recovery.md) - 2026-05-01 | feat | gateway | FormGeneratorTree Plan Stage 0 + 1.A: Schema-Check-Skript
scripts/stage0_filefolder_schema_check.py;FileFolderPydantic +FileItem.folderIdindatamodelFiles.py; StubgetOwnFolderTree/getSharedFolderTree; RoutenGET /api/files/folders/tree(leere Liste) + Folder-Mutationen 501 bis Stage 1.B;migrate_folders_to_groups.pynachmodules/migrations/_archive/mit README. (c-work:1-plan/2026-05-formgenerator-tree-and-folder-recovery.md) - 2026-05-01 | docs | wiki | Plan FormGeneratorTree: Stages packetisiert nach LLM. Stages 1-3 in Sub-Packets aufgeteilt (1.A BE-Boilerplate / 1.B BE RBAC-Kern / 1.C FE Greenfield / 2.A FE-Boilerplate / 2.B FE-Komposition / 2.C manuelle Verifikation / 3.A Provider-Refactors / 3.B Tab-Umbau). Pro Packet: Modell-Hinweis (Opus 4.6 fuer Architektur/RBAC/Greenfield, Composer 2 Fast fuer Boilerplate/Recovery/Doku), Eingang/Lieferumfang/Abnahme. Eskalations-Regel ergaenzt. (c-work:
1-plan/2026-05-formgenerator-tree-and-folder-recovery.md) - 2026-05-01 | docs | wiki | Plan FormGeneratorTree + Folder-Recovery konsolidiert. Neuer FormGenerator-Familienteil
FormGeneratorTree(Provider-Pattern, Cascade-Multiselect, DnDapplication/x-poweron-tree-items, Backend-Attribut-Resolution) zur Konsolidierung der ~8 parallelen Tree-Implementierungen. Recovery der Folder/File-Funktionen ueber Modell A (FileFolder+FileItem.folderIdreaktivieren; DB-Schema unveraendert). RBAC-/Sichtbarkeitsmodell verbindlich: Default-Scopepersonal; Sharing nur ueber Owner-Scope-Patch; geteilte Objekte read-only fuer Nicht-Owner (analogupdateFile/deleteFile); UI rendert inFilesTab/FilesPagezwei getrennte Trees (Eigene/CRUD + Geteilt mit mir/read-only); Files ohne sichtbaren Folder-Kontext fallen in den Root mitcontextOrphan-Hint; Folder-Scope-Cascade auf Files = opt-in; Folder-Neutralize-Vererbung beim Drop = nein; Drag aus Geteilt in Eigenes = gesperrt. 22 konsolidierte Entscheidungen (D1-D22), keine offenen Backlog-Punkte mehr. UDB hat fix drei Tabs (Files, Sources, Chats) aufFormGeneratorTree.FormGeneratorTable.groupingConfigbleibt unveraendert. KeinFormGeneratorChart-- Berichte =FormGeneratorReport(Komponenten-Zeile inb-reference/frontend-nyla/formgenerator.md). 6 Stages (0 Schema-Sanity-Check optional, 1 Backend+Skeleton, 2 FilesTab/FilesPage Recovery, 3 SourcesTab/ChatsTab Konsolidierung, 4 optional weitere Trees, 5 Doku). (c-work:1-plan/2026-05-formgenerator-tree-and-folder-recovery.md)
2026-05-01
- 2026-05-01 | docs | wiki | Plan D (AI Reports Pipeline) abgeschlossen ->
4-done/. Alle Checklisten-Items auf[x], Testplan-Status aufdone, Headerstatus: done,completed: 2026-05-01. Wiki-Referenz-Updates (ai-agent.md,workflow.md,neutralization.md) als TODO fuer naechste Review-Runde markiert. (c-work:4-done/2026-04-ai-reports-theming-and-pipeline.md)
2026-04-30
- 2026-04-30 | refactor | gateway | GraphEditor: Hidden DataRefs sichtbar gemacht fuer alle
ai.*Nodes.frontendType: "hidden"->"dataRef"fuerdocumentListinai.prompt,ai.summarizeDocument,ai.translateDocument,ai.convertDocument(gateway/modules/features/graphicalEditor/nodeDefinitions/ai.py). Zwei neue sichtbare Parameter aufai.prompt:context(dataRef, beliebiger Upstream-Output, wird vom Action zu JSON serialisiert) +documentTheme(select, finance/legal/...). Action-Definitionai.process(gateway/modules/workflows/methods/methodAi/methodAi.py) deklariertcontextunddocumentThemejetzt explizit, statt sie als undeklarierte Pass-Through-Keys mitlaufen zu lassen. Effekt: Trustee-Templates (Budget-Vergleich, KPI, Cashflow, Forecast, Year-end) zeigen ihre bisher unsichtbaren DataRef-Bindings (trigger.payload.documentList,refresh.data.accountingData) jetzt im Properties-Panel als gruene Bindungs-Boxen, der User kann sie via DataPicker veraendern. Kein Frontend-Code-Change noetig: bestehenderDataRefRenderer+DataPickerrendern die JSON-DataRef-Werte direkt. Runtime unveraendert --resolveParameterReferencesverarbeitet{"type":"ref",...}wie bisher.
2026-04-29
-
2026-04-29 | test | gateway | Phase 7 AI-Reports: 19 unit tests for MD-to-JSON parser (inlineRuns), styleDefaults resolver, AiCallOptions allowedModels whitelist, inline-image paragraphs
-
2026-04-29 | feat | gateway, frontend-nyla | D: AI Reports Pipeline komplett umgebaut. Phase 1: MD->JSON konsolidiert (Inline-Run-Modell,
_parseInlineRuns). Phase 2: Generisches Style-System (styleDefaults.py,resolveStyle,renderDocumentstyle-Param). Phase 3: Alle 5 Renderer auf Style-Lookups + Inline-Runs umgestellt. Phase 4: Inline-Bilder in Paragraph/Tabelle/Liste. Phase 5:allowedModelsinAiCallOptions+_calculateEffectiveModelsim AI-Gate. Phase 5a:WorkspaceUserSettingsPersistenz (GET/PUT Endpoint). Phase 5b:modelMultiSelectim FlowEditor + Workspace-Settings UI. Phase 6: Trustee-Templates mitrequireNeutralization+ Finance-Style-Hint. Phase 7: 19 Unit-Tests. (c-work:1-plan/2026-04-ai-reports-theming-and-pipeline.md) -
2026-04-29 | feat | gateway, frontend-nyla | B: Trustee Budget-Vergleich auf Excel umgestellt.
mainTrustee.pyTemplate:resultType: "xlsx"+documentTheme: "finance"hart gesetzt. Prompt komplett refaktoriert: 1 Tabelle alle Konten, 1 Uebersichts-Chart (kein pro-Konto-Chart), Management-Summary. Frontend: Hinweistext "Excel-Bericht" im Budget-Tab ergaenzt. XLSX-Renderer (PNG-unter-Tabelle) verifiziert. (c-work:3-validate/2026-04-trustee-budget-comparison-refactor.md) -
2026-04-29 | feat | gateway, frontend-nyla | A2 Workflow-Run-Workspace + targetFeatureInstanceId implementiert. Phase 1:
AutoWorkflow.targetFeatureInstanceId(Pydantic + DB), createWorkflow-Fallback, Save-Validation (400 fuer non-template ohne targetId), Execute-RBAC-Check,executeGraphPlaceholder-Substitution ({{featureInstanceId}}), Scheduler-Durchreichung,_copyTemplateWorkflowsexplizites Setzen, idempotente Boot-Backfill-Migration. Phase 2: FlowEditor CanvasHeader "Ziel-Instanz" Dropdown mit FeatureStore-Integration, Save/Load mittargetFeatureInstanceId. Phase 3: Neuer Backend-EndpointGET /api/automations/runs+GET /api/automations/runs/{runId}/detail(RBAC via FeatureAccess), neuer "Workspace" Tab in AutomationsDashboardPage mit Run-Liste + Detail-View (Steps, Files, Download). Phase 4: TrusteeAnalyseView inline-Results durch "Im Workspace ansehen"-Link ersetzt, TrusteeAbschlussView Workspace-Link nach Completion ergaenzt. (c-work:1-plan/2026-04-trustee-workflow-audit-and-run-workspace.md) -
2026-04-29 | docs | wiki | Plan A2 finalisiert: Trustee Workflow-Audit + Generischer Workflow-Run-Workspace. Cross-Check gegen Codebase (12 Punkte verifiziert, 4 Korrekturen eingearbeitet):
executeGraphhat keine Placeholder-Substitution (muss neu gebaut werden),_copyTemplateWorkflowssetztfeatureInstanceIdnicht im Payload (implizit via GE-Interface),TrusteeAbschlussViewhat keinresultText/resultDocuments(nur status/summary), 7 Trustee-Templates statt 5 im Audit. Risiko-Sektion ergaenzt. (c-work:1-plan/2026-04-trustee-workflow-audit-and-run-workspace.md) -
2026-04-29 | chore | gateway |
gateway/scripts/aufgeraeumt: 5 obsolete one-shot-Scripts archiviert + 1 Ad-hoc-Snippet geloescht. Im Anschluss an den Bootstrap-Cleanup. Neuer Unter-Ordnergateway/scripts/_archive/mit eigenem README beschreibt Inhalt + Begruendung pro Datei. Verschoben (mit User-Bestaetigung pro File):check_orphan_featureinstance.py(hardcoded Vor-Ort-UUIDs),script_db_cleanup_duplicate_roles.py(IS NULL-Bug-Cleanup, Bug laengst gefixt),migrate_async_to_sync.py(one-shotasync def->defCodemod, Refactor durch),i18n_rekey_plaintext_keys.py(Frontend Klartext-Keys, Migration durch siehe4-done/2026-04-ui-i18n-dynamic-language-sets.md),script_db_migrate_accessrules_objectkeys.py(Navigation-API-Migration MIGRATION_MAP nur fuer trustee+realestate hardcoded, durch). Geloescht:_listMandates.py(26-Zeilen Ad-hoc-Debug-Snippet, jederzeit aus Git rekonstruierbar). Status danach: 21 aktive Scripts ingateway/scripts/(inkl. neuesscript_db_audit_legacy_state.py) + 5 archivierte Scripts. Dev-Boot 20:24:09 bestaetigt das aufgeraeumte interfaceBootstrap.py + Telemetrie-Hook laufen sauber durch (kein WARN, kein Restbestand, neue Code-Pfad-Line-Refs). (c-work:4-done/2026-04-bootstrap-migrations-cleanup.md) -
2026-04-29 | refactor | gateway | Bootstrap-Cleanup ausgefuehrt: 4 idempotente Migrations-Routinen + 1 Aggregations-Fallback aus dem Boot-Pfad entfernt. Vor Removal Audit-Skript
gateway/scripts/script_db_audit_legacy_state.py(NEU, lese-only, exit-code-gated) gegen Dev-DB gelaufen -> 4/5 GREEN sofort, Check 5 (RAG-Orphans) RED mit 20 verwaistenFileContentIndex-Rows ohnemandateId/featureInstanceId-> via--purge-rag-orphansbereinigt -> Re-Audit 5/5 GREEN. Dann entfernt ausgateway/modules/interfaces/interfaceBootstrap.py:_migrateMandateDescriptionToLabel(Funktion + Aufruf),_migrateMandateNameLabelSlugRules(Funktion + Aufruf, ~64 Zeilen),initRootMandate-Legacy-Block (name="Root"-Migration, 7 Zeilen; Funktion selbst bleibt),_migrateAndDropSysAdminRole(Funktion + Aufruf, ~95 Zeilen). IninterfaceDbKnowledge.py:aggregateMandateRagTotalBytes-Fallback-Block (try/exceptmit FileItem-ID-Korrelation aus Management-DB, ~27 Zeilen) entfernt -- die Funktion bleibt aktiv, da sie 4 externe Caller hat. Ersatz: neuer Helpergateway/modules/interfaces/_legacyMigrationTelemetry.pymit 4 lese-only WARN-Checks (gleiche Logik wie Audit-Skript, prozessweit gecached) wird am Ende voninitBootstrapeinmalig aufgerufen -- falls je doch Restbestand auftauchen sollte (alter DB-Restore o.ae.), gibt's klare WARN-Logs mit Routine-Name + IDs. Teststests/unit/bootstrap/test_mandateNameMigration.py(8 Tests) undtests/unit/rbac/test_sysadmin_migration.py(5 Tests) geloescht (referenzierten entfernte Funktionen, wuerden ImportError werfen). Smoke-Test: 17/17 verbliebene rbac+bootstrap-Tests GREEN, Imports aller drei Module GREEN. User-Statement zur Risk-Lage: "die codebase lief bereits auf int und main/prod" -- d.h. die idempotenten Migrations sind dort schon mehrfach durchgelaufen, das Removal-Risiko = 0; das Audit-Skript bleibt fuer pre-deploy-Gating. Plan urspruenglich in1-plan/, jetzt direkt in4-done/2026-04-bootstrap-migrations-cleanup.md. (c-work:4-done/2026-04-bootstrap-migrations-cleanup.md) -
2026-04-29 | feat | frontend-nyla, gateway | Generischer
frontendType: templateTextareafuer Freitext mit{{nodeId.path}}-Variablen (DataPicker-Insert);email.draftEmail.contextundai.prompt.aiPromptnutzen ihn statt reiner Textarea -- Aufloesung ausschliesslich via bestehendesresolveParameterReferences(kein Loop-Spezialcode im Executor). Loop-Preview-Enrichment + IfElse/AI-responseData-Picker bleiben. Unit-Testtest_legacy_string_template_loop_current_item_nestedintest_automation2_graphUtils.py. -
2026-04-29 | docs | wiki | 6 neue UX-/Architektur-Plaene angelegt in
wiki/c-work/1-plan/aus Topics-TODO A-F: (A1+A2) Trustee-Workflow-Audit (alle 5 Reporting-Workflows GREEN auf Pick-not-Push) + generischerWorkflowRunWorkspace-Tab unter/automationsals Single-Source-of-Truth fuer Workflow-Resultate, plus Pflicht-BindingWorkflow.featureInstanceId(2026-04-trustee-workflow-audit-and-run-workspace.md); (B) Budget-Vergleich auf Excel-only mit eindeutigem 1-Tabelle-1-Chart-Prompt, Word-Pfad raus (2026-04-trustee-budget-comparison-refactor.md); (C) Inventar idempotenter Boot-Routinen, Removal-Plan fuer 5 b-Kandidaten via Audit-Skript + 30-Tage-Telemetrie (2026-04-bootstrap-migrations-cleanup.md-- noch am gleichen Tag umgesetzt, siehe Eintrag oben, jetzt unter4-done/); (D) Theme-System fuer AI-Reports pro Workflow (4 Themes standard/finance/marketing/presentation + Mandate-CI-Overlay), MD->JSON-Konsolidierung, Renderer-Refactor, Bilder-in-Tabellenzellen (2026-04-ai-reports-theming-and-pipeline.md); (E) ComCoach Greenfield-IA mitTrainingModule-Datenmodell (RenameCoachingContext) + 5-Tab-Struktur Dashboard/Assistent/Module/Session/Einstellungen, dossier=coaching-Doppelung weg,?context=-Bug fix (2026-04-comcoach-greenfield-ia.md); (F) TeamsBot Greenfield-IA analog mit neuerMeetingModule-Entity + 5-Tab-Struktur und 4 Live-Update-Fixes (SSE-Reconnect-Hook, agentRun-Status-Bubble, stats-Karten, adaptives Dashboard-Polling) (2026-04-teamsbot-greenfield-ia-and-live-update.md). Empfohlene Reihenfolge der Bauphase: C -> A2-Phase-1 (FeatureInstance-Pflicht) -> A2-Phase-2/3 (Workspace) -> B -> D -> E/F parallel. (c-work: 6 neue Dateien in1-plan/) -
2026-04-29 | fix | gateway |
checkForDuplicateFilemacht jetzt einen RBAC-Cross-Check und liefert keine "Geister-Duplicate" mehr aus. Ursache desFile with ID ... not found-Fehlers indownloadFromDataSourcedirekt nachDuplicate detected for user ...:interfaceDbComponentwird ueberserviceHubohnefeatureInstanceIdinitialisiert,checkForDuplicateFilefaellt deshalb auf denmandateId-Filter zurueck und benutztedb.getRecordset(kein RBAC) -- damit konnte er ein File aus einer FREMDEN featureInstance returnen. Der nachfolgendeupdateFile-Aufruf prallte dann am RBAC-gefiltertengetFileab und crashte den ganzen Tool-Call. Sauberer Fix an der Wurzel: nach dem Recordset-Treffer zwingendself.getFile(fileId)als RBAC-Cross-Check; wennNone, gilt als kein Duplicate fuer den aktuellen Scope und der Caller (saveUploadedFile/createFile) erstellt eine frische per-Scope-Kopie. Damit entfaellt jeglicher Workaround inupdateFile(die in der Vorgaenger-Session gebaute Try/Except-Schleife wurde gestern bereits ausgebaut, weil sie in einer Sackgasse stand). Folge: identische Files koennen pro Mandate mehrfach existieren -- eines pro featureInstance -- was gewollt ist, da sie pro Scope eigene Folder-/Tag-/Neutralize-Metadaten brauchen. Symptom-Doku inwiki/b-reference/gateway/agent-file-bridge.md(Section "Ghost-Duplicate-Fix"). (c-work: Begleitfix zum Agent-File-Bridge-Build vom selben Tag) -
2026-04-29 | fix | gateway | Agent-Tools binden jetzt jede produzierte Datei als ChatDocument an den aktiven Workflow -- damit funktioniert der
documentList-Resolver fuer Agent-Outputs. Bisher erzeugtendownloadFromDataSource,writeFile mode=create,renderDocument,generateImageundcreateChartzwar eineFileItem(viasaveUploadedFile/saveGeneratedFile), liessen den Workflow-Document-Graph aber unberuehrt -- statt einesChatDocumentfloss nur einsideEvent fileCreatedan die UI. Folge:getChatDocumentsFromDocumentList(und damitai_summarizeDocument/ai_process/context_extractContent/context_neutralizeData) konnte die FileItem-IDs nicht aufloesen, weil der Resolver ausschliesslichworkflow.messages[*].documents[*].idmatcht. Symptom war "Building structure prompt with 0 valid ContentParts" und entsprechend leere Summaries direkt nach einem Agent-Download. Loesung: zentraler Helper_attachFileAsChatDocument(services, fileItem, label, userMessage)incoreTools/_helpers.py, der intern eine ChatMessage (Rolleassistant, Statusstep, generierterdocumentsLabel) inklusive einem ChatDocument (mitroundNumber/taskNumber/actionNumberaus dem aktiven Workflow) viachatService.storeMessageWithDocumentspersistiert -- exakt das Pattern, dasworkflowProcessor.persistTaskResultundmethodTrustee.extractFromFilesschon laenger benutzen. Helper wird jetzt aus allen fuenf File-erzeugenden Agent-Tools aufgerufen; der ToolResult-Text traegt einheitlich beide IDs (documentList ref: docItem:<chatDocId>fuer AI-Tools,file id: <fileId>fuerreadFile/Embeds). Tool-Descriptions +conversationManager.buildSystemPromptergaenzt um die explizite Anweisung "use docItem: in documentList, NOT the file id, NOT a{"documents":[...]}wrapper". Zusatzlich:mainServiceAgent.runAgentpropagiert das Workflow-Object jetzt in alle Service-Contexts (chat._context.workflowetc.) -- bisher tat das nurworkflowManager._propagateWorkflowToContext, weshalb der Agent ueber die Workspace-Route ohne aktiven Workflow-Context lief undchatService._workflowNonewar. Folge: der Helper konnte ohne diesen Propagations-Fix nie greifen. Die in der vorhergehenden Session eingebaute RBAC-toleranteupdateFile-Try/Except-Schleife in_downloadFromDataSourceist jetzt obsolet und wieder ausgebaut -- mit korrektem ChatDocument-Bind kommt derfeatureInstanceIdueber den Workflow-Pfad und die Duplicate-File-RBAC-Probleme verschwinden an der Wurzel. Pattern-Doc neu unterwiki/b-reference/gateway/agent-file-bridge.md. (c-work: kein dedizierter Eintrag, kritischer Fix on top der documentList-Coercer-Aenderung) -
2026-04-29 | fix | gateway |
ai_process/context_extractContent/context_neutralizeDataakzeptieren jetzt LLM-typische Dict-Wrapper-Formate fuerdocumentList. Der Agent serialisiertdocumentListregelmaessig als{"documents":[{"id":"<uuid>","name":"<file>"}]}(Folge dertype=DocumentList-Schema-Definition, das LLMs als generic Object lesen). Bisher fielen alle drei Actions in denelse: Invalid documentList type: <class 'dict'>-Branch und liefen mit leerer Document-Liste weiter -- der Folder-Summarize-Workflow produzierte dann eine Zusammenfassung "ueber 0 Dokumente". Loesung: zentraler HelpercoerceDocumentReferenceList(value)indatamodelDocref.pyder ALLE praktisch vorkommenden Shapes parst --None,str,DocumentReferenceList,list[str],list[dict mit id/documentId/label],dict mit "documents"/"references"/"items"/"files"-Wrapper, unddict mit id/documentId(single item). Alle vier Aufrufstellen (process.py + extractContent.py + neutralizeData.py x2) auf den Helper umgezogen; die Inline-ActionDocument-Sonderbehandlung inprocess.pybleibt davor. Helper wirft NIE -- gibt im worst case eine leere Liste mit WARN-Log zurueck, der Caller entscheidet ob das fatal ist. (c-work: kein dedizierter Eintrag, Begleitfix zum Infomaniak-Test) -
2026-04-29 | fix | gateway |
listFiles-Tool: dict-vs-attribute-Mismatch inmainServiceChat.listFilesbehoben.interfaceDbComponent.getAllFiles()returnt seit dem Pydantic-RefactorList[dict](jeder Eintrag ist einFileItem.model_dump()mit Label-Spalten), abermainServiceChat.listFiles()griff weiter mitfileItem.fileName/fileItem.idzu (Pydantic-Style) -- daher'dict' object has no attribute 'fileName'und'dict' object has no attribute 'id'aus demlistFiles-Agent-Tool. Komplette Methode auf.get(...)umgestellt; Type-Annotation ingetAllFiles(Union[List[FileItem], PaginatedResult]) ist immer noch irrefuehrend -- das ist ein orthogonaler Tech-Debt-Punkt, kein Blocker. (c-work: kein dedizierter Eintrag) -
2026-04-29 | fix | gateway | kDrive: Single-File-DataSources funktionieren jetzt sauber (Browse + Download). Wenn der User eine einzelne Datei als DataSource anhaengt (z.B.
path=/2980592/12, wo12die kDrive-File-ID einer.html-Datei ist), brachten browseDataSource und downloadFromDataSource bisher Folgefehler: (1) Browse rief blind/2/drive/{driveId}/files/{fileId}/filesauf -> kDrive antwortet400 destination_not_a_directory-> Adapter loggte das als Empty-Folder -> Agent dachte "leerer Ordner" und konstruierte einen Pseudo-Pfad/2980592/12/platform-overview.html. (2)download(/2980592/12/platform-overview.html)nahm dannsegments[-1] = "platform-overview.html"als File-ID ->/2/drive/2980592/files/platform-overview.html->404 method_not_found. Saubere Loesung: (a) Neuer Helper_lastNumericSegment(segments)zieht aus einem Pfad immer die letzte rein-numerische ID -- kDrive-IDs sind grundsaetzlich Integer; haengt der Agent einen Filename dran, wird dieser ignoriert. (b)KdriveAdapter.browseholt vor dem Children-Listing die Item-Metadata (/files/{id}); beitype=filewird ein Single-Entry mit Name/Size/MimeType/Modified zurueckgegeben statt children aufzurufen. (c)KdriveAdapter.downloadbenutzt denselben Helper + denselben Metadata-Fetch (jetzt extrahiert in_fetchItemMeta). Folge: Single-File-Quellen sind jetzt browse-/downloadbar; Folder-Quellen verhalten sich unveraendert. (c-work:c-work/2-build/2026-04-infomaniak-connector.md) -
2026-04-29 | fix | gateway | downloadFromDataSource: Metadata-Updates auf Duplicate-Files werfen den Tool-Call nicht mehr aus dem Tritt.
saveUploadedFilereturnt bei Hash+Name-Match das EXISTIERENDE FileItem -- das kann aber in einem anderenfeatureInstanceId/Folder-Scope leben als die aktuelle Anfrage. Die nachfolgendenupdateFile-Aufrufe (featureInstanceId/neutralize/folderId) prallten dann am RBAC-gefiltertengetFileab und warfenFile with ID ... not found-- obwohl der Download korrekt war (File ist in der DB, addressierbar viafileItem.id). Fix: die drei Metadata-Updates laufen jetzt in einer Schleife mit individuellem Try/Except und WARN-Log; der Tool-Call meldet weiter Success mit der File-ID. (c-work: kein dedizierter Eintrag, Folge des kDrive-Fixes oben) -
2026-04-29 | fix | gateway | Agent-Tools:
kdriveFolder/calendarFolder/contactFolderwerden jetzt korrekt auf die Connector-Serviceskdrive/calendar/contactgemappt. DerSourcesTab.tsxschreibt diese FE-seitigen Source-Type-Literals beim Anhaengen einer Datenquelle ansDataSource-Record;_dataSourceTools._resolveDataSource(und parallelrouteFeatureWorkspace._SOURCE_TYPE_TO_SERVICE) hatten aber nur Eintraege fuer SharePoint/OneDrive/Drive/Outlook/Gmail/FTP/ClickUp -- daher kamenService 'kdriveFolder' not available. Options: ['kdrive', 'calendar', 'contact']ausbrowseDataSource/searchDataSource/downloadFromDataSourcesobald der Agent eine Infomaniak/Calendar/Contact-Quelle anfasste. Beide Maps um die drei Eintraege erweitert;DataSource.sourceType-Field-Description ergaenzt; Inline-Kommentar im_dataSourceTools.pywarnt vor Drift gegenueber FE und_SERVICE_MAP. BestehendeDataSource-Records funktionieren ohne Migration (dassourceType-Literal bleibt gleich). (c-work:c-work/2-build/2026-04-infomaniak-connector.md) -
2026-04-29 | fix | gateway | kDrive-Download folgt jetzt dem 302-Redirect. Der Endpoint
/2/drive/{driveId}/files/{fileId}/downloadantwortet bandwidth-bedingt mit302 Found -> presigned CDN URL(Standard fuer File-Bytes); unser_infomaniakDownload-Helper hatte aberallow_redirects=False(kopiert vom_infomaniakGet-Helper, wo das wichtig ist um nicht versehentlich auf OAuth-Login-Pages zu landen). Folge: jeder kDrive-Download lieferteNone->Tool result: downloadFromDataSource FAILED -> Download returned emptyim Agent-Log. Fix: nur fuer Downloadsallow_redirects=True, mit Doc-String der erklaert warum (gleiches Pattern bei Calendar/Contacts-Export-Endpoints, gleicher Host = Authorization-Header bleibt erhalten). Listing/Metadata-Calls bleiben weiterallow_redirects=False, damit nicht-PAT-faehige Routes als302sichtbar bleiben statt eine HTML-Login-Page zu liefern. (c-work:c-work/2-build/2026-04-infomaniak-connector.md) -
2026-04-29 | fix | gateway | Anthropic-Plugin:
temperaturewird fuer Extended-Thinking-Modelle (Claude 4.7 Opus, spaeter 4.7 Sonnet/Haiku, alle 5.x) nicht mehr gesendet. Anthropic antwortet seit dem 4.7-Release mit400 invalid_request_error: 'temperature' is deprecated for this model.-- nur der modellinterne Default ist akzeptiert. Analog zum gestrigen_supportsCustomTemperature-Helper im OpenAI-Plugin (gpt-5/o-Serie) jetzt auch hier: Praefix-Match aufclaude-opus-4-7/-sonnet-4-7/-haiku-4-7undclaude-*-5*->temperatureweglassen. Wirkt in allen drei Anthropic-Pfaden (callAiBasic,callAiBasicStream,callAiImage). Aeltere Modelle (Claude 4.5/4.6) bekommentemperatureweiter wie gehabt. (c-work: kein dedizierter c-work-Eintrag -- analog OpenAI gpt-5-Fix vom 2026-04-28) -
2026-04-29 | fix | gateway, frontend-nyla, wiki | Infomaniak-Connector: kDrive findet jetzt auch Drives, in denen der User nur
role: userist (stattaccount_admin). Live-Beweis vom User mit Files inhttps://ksuite.infomaniak.com/1696919/kdrive/app/drive/2980592/files/11: das Drive haengt korrekt an account_id 1696919, aber/2/drive?account_id=1696919antwortet trotzdem200 [] -- empty, weil dieser Endpoint zur Drive-Manager-Admin-Sicht gehoert (filtered aufaccount_admin: true) und nicht zur Endbenutzer-Sicht. Direkt-Aufrufe wie/2/drive/2980592/filesfunktionieren fuer denselben User mitrole: usereinwandfrei (PDF "Start_with_kDrive.pdf", Ordner "Nyla-Analysen" und "Onboarding" alle sichtbar). Root-Endpoint gefunden:GET /2/drive/init?with=drives-- enumeriert ALLE Drives die der User sehen kann, unabhaengig von der Admin-Rolle, braucht NUR dendrive-Scope (verifiziert mit PAT deraccounts-Scope explizit nicht hat). Implementierung: (a) Neuer HelperlistAccessibleDrives(token) -> List[dict]imconnectorInfomaniak.py-- ein einzelner/2/drive/init?with=drives-Call, raisedInfomaniakIdentityErrormit Scope-Message wenndrive-Scope fehlt. (b)KdriveAdapterhaelt jetzt_drives: Optional[List[Dict]](statt_accountId/_accountIds);_listDrives()mappt direkt aus dem gecachten Init-Response. (c)submit_infomaniak_tokenvalidiert in zwei Schritten:listAccessibleDrives(drive-Scope) undresolveOwnerIdentity(workspace:calendar/workspace:contact-Scope). (d) Der zwischenzeitlicheresolveAccessibleAccountIds()+accounts-Scope-Workaround wieder ENTFERNT (war eine Sackgasse:/1/accountslistet Manager-Organizations, nicht Drive-Accounts). (e)_probeDriveScope()-httpx-Helper im Submit-Route entfernt;httpx-Import +INFOMANIAK_API_BASE-Konstante raus. Frontend: PAT-Setup-Modal wieder auf 4 Pflicht-Scopes zurueck (accountsraus). Doku: Status-Tabelle, Validation-Section und "How the kDrive adapter discovers your drives" komplett auf deninit-Endpoint umgeschrieben. Bestehende Connections sollten ohne User-Aktion sofort funktionieren -- es ist kein neuer Scope und keine Token-Rotation noetig, der Adapter wechselt nur den Discovery-Endpoint. (c-work:c-work/2-build/2026-04-infomaniak-connector.md) -
2026-04-29 | fix | gateway | Infomaniak-Connector: Calendar-Events und Contacts-Download auf die echten PAT-faehigen Pfade gezogen. Live-Tests gegen die Vendor-API zeigten zwei Pfad-Mismatches im gestrigen Build: (1) Calendar-Events: der nested Route
/api/pim/calendar/{id}/event302t zur OAuth-Login-Seite (also nicht PAT-faehig); korrekter Endpoint ist/api/pim/event?calendar_id={id}&from=YYYY-MM-DD HH:MM:SS&to=...mit Pflicht-Range max 3 Monate (Vendor-Constraintrange_must_be_lower_than_3_months) -- Adapter waehlt jetzt fix 90-Tage-Window (heute -30 / +60), URL-Encoding viaurllib.parse.quote. Event-Detail und.ics-Export laufen ueber/api/pim/event/{eventId}und.../export(also ohne calendar-Praefix). (2) Contacts-Download:/addressbook/{book}/contact/{id}antwortet mit500 unexpected_errorund.../export302t zu OAuth -- beide Detail-Endpoints sind also nicht PAT-faehig. Listing dagegen funktioniert, liefert aber per Default nur Stammdaten -- ohnewith=emails,phones,addresses,detailskommen Email/Phone/Adresse leer. Loesung: ContactAdapter holt das Listing mit demwith-Param und rendert die.vcfselbst via_renderInfomaniakVcard()(vCard 3.0, escaped, mit N/FN/ORG/EMAIL/TEL/ADR/URL/NOTE) -- konsistent mit MSFT/Google-Adapter, die ihre.vcfs ebenfalls selbst synthetisieren. Plus: Helper_safeFileNameaus dem Calendar-Adapter zu modullokal hochgezogen, von beiden Adaptern genutzt; ungenutzteimport re/import json-Inline-Imports raus. kDrive-Adapter ist im Live-Test korrekt:/2/drive?account_id=1696919antwortet 200 mit leerem Array fuer den Test-Account (kein kDrive-Produkt aktiviert). (c-work:c-work/2-build/2026-04-infomaniak-connector.md)
2026-04-28
-
2026-04-28 | refactor | gateway | Infomaniak-Connector:
account_idist Adapter-State, nicht Connection-State. Symptom im Log:Infomaniak GET https://api.infomaniak.com/2/drive?account_id=pat-XXXXXXXX -> 422 validation_rule_integer "The account id must be an integer.". Root cause: derKdriveAdapterlasconnection.externalIdalsaccount_id-Quelle, und bei kaputten Submits konnte dort der Token-Fingerprint ("pat-59ee48d9") statt deraccount_idstehen. Saubere Loesung statt Fingerprint-Migration: (a) Neuer modullokaler HelperresolveOwnerIdentity(token) -> InfomaniakOwnerIdentityimconnectorInfomaniak.py-- versucht PIM Calendar (workspace:calendar-Scope), faellt auf PIM Contacts (workspace:contact-Scope) zurueck, raisedInfomaniakIdentityErrorwenn keine Owner-Records gefunden. (b)KdriveAdapterhat keinenaccountId-Konstruktor-Parameter mehr, sondern resolvt zur Laufzeit ueber_ensureAccountId()(gecached auf der Adapter-Instanz). Damit ist der Adapter self-contained und liest nichts mehr aus der Connection --externalIdist reiner UI-State. (c)submit_infomaniak_tokenruft denselbenresolveOwnerIdentity()als Pre-Flight-Check, dann/2/drive?account_id={resolved}als sauberer 200-Probe. Der frueher noetige_probeScope-422-Tolerance-Hack ist entfallen. (d)getServiceAdapterhat keine kDrive-Sonderbehandlung mehr; alle drei Adapter werden uniform mitaccessTokenkonstruiert. (e)_PIM_PREFIXist auf Modul-Ebene definiert; CalendarAdapter und ContactAdapter haben keine Klassen-Konstanten mehr. Konsequenz: jede existierende Infomaniak-Connection arbeitet ohne User-Aktion sofort wieder, auch wennexternalIdhistorisch einen Fingerprint enthaelt -- der Adapter zieht dieaccount_iddeterministisch aus der API. Setup-Guide um Architektur-Abschnitt erweitert. (c-work:c-work/2-build/2026-04-infomaniak-connector.md) -
2026-04-28 | feat | gateway, frontend-nyla | MSFT- und Google-Connector: CalendarAdapter + ContactsAdapter neu, plus Reconnect-Button. Nachdem Infomaniak heute Calendar/Contacts kann, ziehen MSFT und Google nach. Backend: (a)
oauthProviderConfig.googleDataScopesumcalendar.readonly+contacts.readonlyerweitert,msftDataScopesumCalendars.Read+Contacts.Read. (b)connectorMsft.CalendarAdapter(Graph:me/calendars,me/calendars/{id}/events?$top&$orderby=start/dateTime desc, Pagination via@odata.nextLink,.ics-Download als selbstgebautes RFC-5545 VCALENDAR/VEVENT da Graph keinen$value-Endpoint fuer Events kennt;$searchfuer query). (c)connectorMsft.ContactsAdapter(Graph:me/contactFolders+ virtuellerdefault-Ordner fuerme/contacts,me/contactFolders/{id}/contacts?$orderby=displayName,.vcfals vCard-3.0 selbstgebaut mit N/FN/ORG/TITLE/EMAIL/TEL/ADR/NOTE). Helper_eventToIcs,_contactToVcard,_safeFileName,_personLabelplus_icsEscape/_icsDateTime. (d)connectorGoogle.CalendarAdapter(Calendar v3:users/me/calendarList,calendars/{id}/events?singleEvents=true&orderBy=startTime,.icsaus Event-Detail). (e)connectorGoogle.ContactsAdapter(People API:contactGroups+ virtuellerall-Folder ueberpeople/me/connections, fuer Gruppenpeople:batchGet?resourceNames=..., Search viapeople:searchContacts,.vcfauspersonFields=names,emailAddresses,phoneNumbers,organizations,addresses,biographies). (f)_SERVICE_MAPvon beiden Connectoren um"calendar"/"contact"ergaenzt;routeFeatureWorkspaceundrouteFeatureGraphicalEditorService-Label-/Icon-Maps umkdrive,calendar,contactergaenzt, damit die UDB sinnvolle Anzeigen macht. (g) Reconnect-Flow:POST /api/connections/{id}/connectakzeptiert optionalen Body{"reauth": true}und haengt&reauth=1an die Auth-URL.routeSecurityMsft.auth_connectsetzt beireauth=1prompt=consent(sonst select_account/login),routeSecurityGoogle.auth_connectdroppt beireauth=1include_granted_scopes=truedamit Google strikt fuer die aktuelle Scope-Liste neu signiert (sonst werden neue Scopes still uebersprungen). Frontend:connectionApi.connectService(id, reauth?)-> POST mit Body,useConnections.connectWithPopup(id, reauth?)reicht durch,ConnectionsPagezeigt fuer aktive MSFT/Google/ClickUp-Connections einenFaSyncAlt-Button "Erneut verbinden (neue Scopes erteilen)" mit eigenem Loading-Set. Bestehende Connections muessen einmal reconnected werden, damit Calendar/Contacts in der UDB auftauchen. (c-work:c-work/2-build/2026-04-msft-google-calendar-contacts.md) -
2026-04-28 | fix | gateway | OpenAI-Connector:
temperaturefuer GPT-5.x / o-Serie aus dem Payload nehmen. Symptom im Log: jede AI-Anfrage failt mit HTTP 400Unsupported value: 'temperature' does not support 0.2 with this model. Only the default (1) value is supported., der Failover spricht 14 Modelle durch und schreibtRecorded failure for gpt-5.5, cooldown 60.0s. Root cause: die GPT-5-Familie (gpt-5, gpt-5.4*, gpt-5.5*) und die o-Serie (o1/o3/o4) sind Reasoning-Modelle; OpenAI akzeptiert dort -- analog zurmax_tokens->max_completion_tokens-Restriction -- nur den Default (1). Wir senden aber unverhandelttemperature=0.2aus jedemAiModel-Eintrag. Fix: Helper_supportsCustomTemperature(modelName)und incallAiBasic/callAiBasicStream/callAiImageden Key nur conditional ins Payload aufnehmen (Modellnamen mit Praefixgpt-5,o1,o3,o4lassen ihn weg). Der vom User im UI gesetzte Override ueberAiCallOptions.temperaturewird auf den nicht unterstuetzten Modellen still verworfen statt einen 400 zu erzwingen. Tests:tests/unit/aicore/test_aicorePluginOpenai_temperature.py(18 Tests, parametrisiert ueber Legacy-Modelle vs. Reasoning-Familie). Suite gesamt: 530 passed. -
2026-04-28 | docs | wiki | Infomaniak-Connector: Mail-Adapter formal als "blocked by vendor" markiert. Erschoepfende Pfad-Tests am 2026-04-28 zeigen: alle 7 plausiblen Mail-Endpoints sind heute nicht PAT-faehig.
api.infomaniak.com/{1,2}/mail-> 404 nginx (existiert nicht);mail.infomaniak.com/api/mail[?account_id=...],/api/pim/mail,/api/pim/mailbox,/api/pim/folder-> 302 zulogin.infomaniak.com/authorize(nur OAuth-Web-Session, Bearer-PAT wird abgelehnt);mail.infomaniak.com/api/mail/?account_id=...-> 301 zuhttp://mail.infomaniak.com:5000(interner Cyrus-IMAP-Port, von aussen nicht erreichbar). Derworkspace:mail-Scope bleibt im PAT-Standard-Setup, damit der MailAdapter spaeter ohne Token-Rotation freigeschaltet werden kann; Setup-Guide und c-work-Doku zementieren den Befund. Kein Code-Change. (c-work:c-work/2-build/2026-04-infomaniak-connector.md) -
2026-04-28 | feat | gateway, frontend-nyla | Infomaniak-Connector: ContactAdapter neu. Nachfolge-Tests gegen die Contacts-PIM-API zeigten, dass
https://contacts.infomaniak.com/api/pim/addressbook(Singular!) mit dem PAT-Scopeworkspace:contactund Bearer-Auth200+ JSON liefert -- gleiche Antwort-Struktur wie Calendar (addressbooks[].id/name/account_id/...). Die Plural- und/contact*-Pfade (/api/pim/contacts,/api/pim/contact/addressbook) sind weiterhin OAuth-only bzw. 404. NeuerContactAdapter1:1 analogCalendarAdapter:browse("/")-> Adressbuecher,browse("/{bookId}")-> Kontakte (Display-Name, Email, Phone, Organization in Metadata),download("/{bookId}/{contactId}")->.vcfvia/contact/{id}/exportmit JSON-Fallback,search()als kostenguenstiger Client-Filter. Geteilte Organisations-Adressbuecher (name="",is_dynamic_organisation_member_directory=true) bekommen "Organisation" als Anzeigename, sonst waere der Tree-Knoten leer. Neue Konstante_CONTACTS_BASE,ContactAdapterin_SERVICE_MAPregistriert. Frontend:SourcesTabkenntcontact-Icon (👤), -Color und Mapping; PAT-Modal nennt Contacts als heute aktiv (Mail bleibt "in Vorbereitung"). Setup-Guide: Status-Tabelle, UDB-Verifikations-Liste und Validation-Beschreibung aktualisiert. (c-work:c-work/2-build/2026-04-infomaniak-connector.md) -
2026-04-28 | feat | gateway, frontend-nyla | Infomaniak-Connector: kDrive PAT-Fix + Calendar-Adapter neu. Nach den ersten echten PAT-Test-Calls aufgeraeumt: (a)
/2/drivebraucht einaccount_id-Query-Arg, sonst422 account_id required. Fix:account_ideinmalig beim Token-Submit aus dem Calendar-PIM-Endpoint (https://calendar.infomaniak.com/api/pim/calendar-- liefertaccount_id,user_id, Anzeigename) ziehen, inUserConnection.externalIdpersistieren und ueberInfomaniakConnector.getServiceAdapterals Konstruktor-Parameter in denKdriveAdapterinjizieren./1/profile(haetteuser_info-Scope verlangt) und/1/mail(existiert nicht: 404 nginx) raus aus den Probes. (b)_probeScopetoleriert jetzt 4xx ausser 401/403 (z.B. 422validation_failed) als "Scope ist da, Endpoint braucht nur weitere Args". (c) NeuerCalendarAdapter(browse-> Calendars/Events uebercalendar.infomaniak.com/api/pim/calendar,download->.icsvia/event/{id}/export, JSON-Fallback)._infomaniakGetund_infomaniakDownloadakzeptieren ein optionalesbaseUrl, sodass Calendar gegencalendar.infomaniak.comund kDrive gegenapi.infomaniak.comlaufen koennen. (d)MailAdapteraus_SERVICE_MAPentfernt:mail.infomaniak.com/api/mailredirected mit 302 zulogin.infomaniak.com/authorize, akzeptiert also keine PATs; gleiches gilt fuercontacts.infomaniak.com/api/pim/contact. Beide Scopes werden weiterhin ingrantedScopesgespeichert, damit kuenftige Adapter ohne Token-Rotation aufgeschaltet werden koennen. (e) Frontend:SourcesTabkenntcalendar-Icon, -Color und_SERVICE_TO_SOURCE_TYPE-Mapping; PAT-Modal inConnectionsPagezeigt Calendar als zweiten aktiven Service, Mail/Contact als "in Vorbereitung, Scope schon mitnehmen". (f) Setup-Guide aktualisiert (Status-Tabelle + Validation-Beschreibung). (c-work:c-work/2-build/2026-04-infomaniak-connector.md) -
2026-04-28 | refactor | gateway, frontend-nyla | Infomaniak-Connector: OAuth -> Personal Access Token. Infomaniaks
login.infomaniak.com/authorizeakzeptiert nur Identity-Scopes (openid,profile,email,phone); Versuche mitkdrive/mail-Scopes quittieren miterror=invalid_scope. Datenzugriff geht ausschliesslich ueber manuell im Manager erstellte PATs. Umbau: (a) BackendrouteSecurityInfomaniakkomplett neu -- ein EndpointPOST /api/infomaniak/connections/{id}/token, validiert PAT viaGET https://api.infomaniak.com/1/profile, persistiert Bearer mit 10-Jahres-Horizont (analog ClickUp), entfernt OAuth-Connect/Callback-Pfade. (b)tokenManager.refreshInfomaniakToken+tokenRefreshService._refresh_infomaniak_tokenentfernt, AuthAuthority.INFOMANIAK aus den Background-Refresh-Filtern raus -- PATs sind langlebig. (c)oauthProviderConfig.infomaniakDataScopes+infomaniakDataScopesForRefreshentfernt. (d)routeDataConnections.connect_serviceantwortet bei Infomaniak jetzt mit 400 + Hinweis auf den PAT-Endpoint. (e) Env-Cleanup:Service_INFOMANIAK_DATA_CLIENT_ID/SECRETundService_INFOMANIAK_OAUTH_REDIRECT_URIaus.env+env_dev/int/prod[_forgejo].envraus. (f) Frontend:useConnections.createInfomaniakConnectionAndAuth(OAuth-Popup) ersetzt durchcreateInfomaniakConnection+submitInfomaniakToken;ConnectionsPagezeigt PAT-Modal mit Schritt-Anleitung + Deeplink zumanager.infomaniak.com/v3/ng/accounts/token/list; Cancel rollt PENDING-Connection per DELETE zurueck. (g) Doku:wiki/d-guides/infomaniak-oauth-setup.mdgeloescht,wiki/d-guides/infomaniak-token-setup.mdneu. (c-work:c-work/2-build/2026-04-infomaniak-connector.md) -
2026-04-28 | refactor | gateway | Cleanup der zwei tieferliegenden Defensive-Programming-Schichten, die den Trustee-Bug (vorheriger Eintrag) ueberhaupt erst durchgelassen haben.
- (1) DB-Connector: fail-loud statt swallow.
connectorDbPostgre.getRecord/getRecordset/getRecordsetPaginated/getDistinctColumnValues/_loadTable/semanticSearchhaben bisher jede Exception perexcept Exception → log → return [](bzw.None/leeres Pagination-Resultat) verschluckt. Folge: jeder echte DB-Fehler (Postgres-Adapt, UndefinedTable, UndefinedColumn, OperationalError, etc.) wurde fuer den Caller ununterscheidbar von "0 Rows" -- darauf basierten misleading downstream Errors wie "No active accounting configuration found". Neu: typisierte ExceptionDatabaseQueryError(table, message, original)plus zentrales_rollbackQuietly(connection)(Postgres setzt die Connection in Error-State nach jedem fehlgeschlagenen Statement). Empty Result Sets liefern weiterhin[]/None/{items: [], totalItems: 0, totalPages: 0}(= Normalpfad uebercursor.fetchall()/fetchone()), aber jede Exception innerhalb des Query-Pfads wird hochgereicht. Tests:tests/unit/connectors/test_connectorDbPostgre_failLoud.py(9 Tests). - (2) Action-Parameter: zentrale Validierung statt impliziter Kontrakt. Workflow-Actions haben
parameters: Dict[str, Any]ohne Schema-Enforcement bekommen; die Aktionsimplementationen mussten ad-hocisinstance-Branches haben oder mit Postgres-Errors abstuerzen (siehe Trustee-Bug). Neues Modulgateway/modules/workflows/processing/shared/parameterValidation.pymitInvalidActionParameterError(ValueError)+validateAndCoerceParameters(actionDef, parameters). Zentral aufgerufen inActionExecutor.executeAction-- gilt fuer alle Aufrufpfade (Agent, Workflow-Graph, REST). Logik:- Required-Parameter erzwungen (typisierter Fehler statt opaque downstream).
- Ref-Schemas (
FeatureInstanceRef/ConnectionRef/...) -- Dict mitidwird auf String-UUID kollabiert; Pass-Through fuer bereits-Strings; Dict ohneidraisst kontrolliert. - Primitive-Coercion (
bool/int/float) aus haeufigen String-Formen ("true"/"12"/"3.14"). Unbekannte Extra-Keys (parentOperationId,expectedDocumentFormats, ...) bleiben unangetastet. Die in der vorherigen Iteration inactionToolAdaptereingebaute Ref-Normalisierung wurde komplett entfernt (Single Source of Truth inparameterValidation). Tests:tests/unit/workflows/test_parameterValidation.py(19 Tests).
- Gesamttest-Suite: 512 passed (vorher 503, plus 9 neue DB-Tests; +19 neue Validation-Tests; -7 obsolete Adapter-Tests, da Logik umgezogen).
- (1) DB-Connector: fail-loud statt swallow.
-
2026-04-28 | fix | gateway | Agent-Tool-Calls auf Workflow-Actions mit
*Ref-Parametern (z.B.trustee_refreshAccountingData(featureInstanceId=...)) brachen mit irrefuehrendem "No active accounting configuration found" ab. Root cause: das Tool-Schema (Phase-3 Typed Action Architecture) exponiertFeatureInstanceRef/ConnectionRefabsichtlich als typisiertes Objekt mitid+Diskriminator (featureCode/authority), damit der LLM bei mehreren Instanzen die richtige picken kann -- aber die Action-Implementierungen verwenden den Wert direkt als String-UUID inrecordFilter={"featureInstanceId": <value>, ...}. Der LLM uebergibt korrekt das Dict{id, featureCode, label, mandateId}, Postgres-Adapter scheitert mitcan't adapt type 'dict', der DB-Connector swallowed den Fehler (soft-fail mit[]), und die Action interpretiert das leere Resultset als "Konfiguration fehlt". Initial-Fix inactionToolAdapter(Ref-Dict -> id-String). Diese Adapter-Normalisierung wurde im Folgeschritt zur zentralenparameterValidationmigriert (siehe naechster Eintrag).
2026-04-27
- 2026-04-27 | fix | gateway | Trustee-Subagent gab fuer "Banksaldo per 31.12.2025" CHF 11'861'162.50 zurueck statt der echten 48'507.41 (Konto 1020) und identifizierte 5400 (Materialaufwand) + 3434 (Erloeskorrekturen) als "Bankkonten". Root cause war doppelt: (1)
closingBalanceist bereits ein Saldo pro Periode -- der Agent riefaggregateTable(SUM, closingBalance, GROUP BY accountNumber)ohne periodYear/periodMonth-Filter und summierte 7 Jahre x 13 Perioden auf (~90x echter Saldo); (2) er hatte kein Wissen darueber, dass Schweizer KMU-Bankkonten dem Praefix102xfolgen undperiodMonth=0das Jahres-Total bedeutet. Fix in zwei Teilen: (a) generische Regel infeatureDataAgent._buildSchemaContextSystem-Prompt -- "NEVER apply SUM/AVG to columns that already represent a balance, closing/opening total or aggregate" mit konkreten BeispielenclosingBalance/openingBalance/debitTotal/creditTotal; (b) Pro-Feature-HookgetAgentDomainHints() -> strinmainXxx.py: wenn die Funktion existiert, wird ihr Rueckgabetext ans Ende des Subagent-Prompts angehaengt. Trustee liefert jetzt einen kompakten Domain-Guide mit KMU-Kontoplan-Praefixen (1xxx/2xxx/3xxx/4xxx, 100x/102x), Periodenkonvention (periodMonth=0= Jahr, 1-12 = Monat), drei kanonischen Query-Patterns (Banksaldo, Konto-Saldo, Buchungen-im-Monat) und einer Anti-Pattern-Liste (kein SUM auf closingBalance, debitTotal/creditTotal sind keine Salden). Loader in_loadFeatureDomainHintsnutztloadFeatureMainModules()und ist tolerant gegen fehlende Hooks/Module. Unit-Tests intests/unit/services/test_featureDataAgent_schema.py(4 neue: Generische Regel, Trustee-Hints angehaengt, kein Hints-Block fuer Features ohne Hook, Anti-Pattern-Erwaehnungen)
2026-04-26
- 2026-04-26 | fix | gateway+frontend | Automation Workflow-Tab:
Automation2WorkflowViewerstellt damit sysCreatedAt (timestamp) und lastStartedAt korrekt als PeriodPicker-Spalten erkannt werden; lastStartedAt nutzt jetzt AutoRun.startedAt statt sysCreatedAt; computed-field Filter/Sort via applyFiltersAndSort in-memory; Runs-Tab auf startedAt/completedAt umgestellt statt System-Audit-Felder - 2026-04-26 | perf | gateway | routeWorkflowDashboard get_system_workflows: N+1 AutoRun-Abfragen ersetzt durch LEFT JOIN + Subquery-Aggregation (eine Daten- + eine Count-Query); FK-Sort-Pfad nutzt eine gebündelte Run-Stats-Query; lastStartedAt/runCount/isRunning-Filter im Join-Pfad in SQL
- 2026-04-26 | fix | gateway | Feature-Data-Subagent (
queryFeatureInstance) Schema-Prompt war zu duenn: Agent erhielt nur Tabellennamen + flache Spalten-Liste, ohne Typen / Beschreibungen / FK-Beziehungen. Folge: bei Trustee-Saldo-Queries summierte erTrusteeDataJournalLine.debitAmount/creditAmountohne Datumsfilter (JournalLine hat gar keinbookingDate!) statt die Periode-bezogenenTrusteeDataAccountBalance.closingBalancezu nutzen; ISO-Date-Strings wurden gegen Float-Unix-Timestamps gefiltert (bookingDate <= '2025-12-31'). Fix infeatureDataAgent._buildSchemaContext: pro Tabelle wird jetzt der zugehoerige Pydantic-Klasse viaMODEL_REGISTRYresolved und pro selektiertem Feld eine angereicherte Zeile gerendert -- Python-Typ ausfield.annotation, deutsches Label ausjson_schema_extra.label, Description ausField(description=...), FK-Target ausfk_target. Dazu drei neue Regeln im System-Prompt: (a) Float-Felder mit "unix timestamp" in der Description sind Sekunden-seit-Epoch (Beispiel'2025-12-31' -> 1735603200.0), (b) Tools koennen nicht JOINen -- FK-Tabellen separat abfragen, (c) Periode-aggregierte Tabellen (Opening/Closing-Balances) bevorzugt vor SUM ueber Rohdaten. Fallback auf flache Feldliste wenn die Tabelle nicht im Pydantic-Registry ist. Unit-Tests intests/unit/services/test_featureDataAgent_schema.py - 2026-04-26 | feat | gateway+frontend-nyla | Infomaniak-Connector (kDrive + Mail) als neuer ProviderConnector analog Google/MSFT/ClickUp. Backend:
AuthAuthority.INFOMANIAK,providerInfomaniak/connectorInfomaniak.pymitKdriveAdapter+MailAdapter(httpx, OAuth-Bearer, Path-Konvention/{driveId}/{fileId}bzw./{mailboxId}/{folderId}/{uid}),routeSecurityInfomaniak.pymit_FLOW_CONNECT-only (kein Login -- pure DATA_CONNECTION), Token-Refresh viatokenManager.refreshInfomaniakToken+tokenRefreshService._refresh_infomaniak_token,connectorResolver-Registry-Eintrag, Authority-Map/Labels/Dispatch inrouteDataConnections, Router-Mount inapp.py. Refresh-Token-Persistierung holt bei fehlendemrefresh_token-Response aus dem letzten gespeicherten Token (analog Google). Frontend:connectionApi.tsAuthority-Typ erweitert,useConnections.createInfomaniakConnectionAndAuth+infomaniak_connection_success/error-Event-Listener,ConnectionsPagemit Infomaniak-Button (FaCloud),SourcesTabIcons/Colors/Service-Mapping fuerinfomaniak/kdrive/mail-- inkl. Fix der bisher fehlenden ClickUp-Eintraege in_SERVICE_ICONS+_SERVICE_TO_SOURCE_TYPE. Setup-Guide unterwiki/d-guides/infomaniak-oauth-setup.md(c-work: c-work/2-build/2026-04-infomaniak-connector.md) - 2026-04-26 | fix | gateway | Feature-Data-Subagent (
queryFeatureInstance) hat seine Loop hardcoded auf 8 Runden begrenzt, unabhaengig vom WorkspacemaxAgentRounds. Im int-System brachen Trustee-Saldo-Queries deshalb mitMaximum rounds reached. Progress after 8 roundsab, obwohl der Parent-Agent z.B. mit 25 Runden konfiguriert war. Fix:agentLoop._executeToolCallspropagiert jetztparentMaxRounds+parentMaxCostCHFueber den Tool-Context;_featureSubAgentTools._queryFeatureInstanceliest sie aus und reicht sie anrunFeatureDataAgent(maxRounds=, maxCostCHF=)weiter. Default fuer Direktaufrufer/Tests bleibt 8. Cost-Cap skaliert linear (_MAX_COST_CHF_PER_ROUND = 0.02 * maxRounds), damit nicht der 0.15-CHF-Guard die Loop vor Erreichen der konfigurierten Runden abschiesst (25 Runden -> 0.50 CHF). Subagent-Start loggt jetzt effektivemaxRounds/maxCostCHFzur Diagnose - 2026-04-26 | feat | gateway+frontend-nyla | Database-Health Orphan-Cleanup: neue Checkbox
Ohne FK-Referenzen zu UserInDB.id(default ON). Deleted-User-Reste in Audit/Billing/Membership-Tabellen sammeln sich natuerlich an wenn ein User geloescht wird und gehoeren in den separaten User-Purge-Workflow, nicht in die generische FK-Bereinigung. Backend:_isUserIdFk(targetTable, targetColumn)-Helper (case-insensitive auf Tabellenname);_cleanAllOrphans(force, excludeUserFks)ueberspringt entsprechende Relationen;/orphans?excludeUserFks=truefiltert Scan-Resultate;OrphanCleanAllRequest.excludeUserFksfiltert clean-all. Frontend: Checkbox nebenNur Probleme, default checked, mit Tooltip; URL-Param + clean-all Body-Field synchron;Alle bereinigen-Counter zeigt jetzt nur Non-User-FK-Orphans - 2026-04-26 | fix | gateway | aicorePluginOpenai:
max_tokensdurchmax_completion_tokensersetzt incallAiBasicundcallAiBasicStream. Hintergrund: OpenAI lehntmax_tokensfuer gpt-5.x / o-series Modelle mit HTTP 400unsupported_parameterab (Use 'max_completion_tokens' instead). Im Loglog_app_20260426.log(L741-764) sichtbar:gpt-5.4-nanofailover scheiterte sofort, ModelSelector wechselte aufclaude-opus-4-6. Per OpenAI API-Reference akzeptieren ALLE aktuellen Chat-Completions-Modelle (legacy gpt-4o/gpt-4.1, gpt-5.x, o1/o3/o4)max_completion_tokens, daher universeller Wechsel statt Modell-spezifischer Verzweigung - 2026-04-26 | feat | gateway | PDF-Renderer Emoji-Support: Noto Emoji (monochrome, OFL) als Fallback-Font registriert. Bisher rendern WinAnsi-Core-Fonts (Helvetica/Courier) Emoji-Codepoints (U+2600+, U+1F300+) als fehlende Glyphen-Quadrate. Neu unter
gateway/assets/fonts/NotoEmoji-Regular.ttf(~419 KB, 887 Codepoints) +_pdfFontFallback.pyHelper: registriert die TTF einmalig bei reportlab, scannt deren cmap, undwrapEmojiSpansInXmlumschliesst zusammenhaengende Emoji-Runs (codepoint >= U+2000 ∧ in cmap) mit<font name="NotoEmoji">…</font>— nestet sauber in<b>/<i>/<font name="Courier">.rendererPdf._markdownInlineToReportlabXmlwendet das am Ende an, also greift es ueberall wo Paragraph-Markup gebaut wird (Headings, Paragraphs, Bullet-Lists, Table-Cells, extracted_text).Preformatted(Code-Blocks) ist Single-Font-only und bleibt unveraendert — Emojis in Code-Bloecken sind selten, Box-Drawing wird wie bisher zu ASCII normalisiert. Smoke-Test intest_renderer_pdf_smoke.py - 2026-04-26 | fix | gateway | FK Orphan-Scanner loeschte korrekte Trustee-Workflows:
AutoWorkflow.templateSourceIdenthaelt teils Sentinel-IDs (z.B."trustee-receipt-import"ausfeatureModule.getTemplateWorkflows()), die absichtlich keine DB-Zeile haben — wurden faelschlich als Orphans markiert und mitforce=true(oder unter 50%-Schwelle) geloescht. NeuersoftFk: TrueFlag infk_target:fkRegistry.FkRelationshiptraegt das Flag,databaseHealth._scanOrphans/_cleanOrphans/_listOrphansueberspringen soft FKs komplett (kein Display, kein Cleanup). Label-Resolution unveraendert.templateSourceIdalssoftFk: Truemarkiert. Wikib-reference/platform/database-architecture.mdaktualisiert - 2026-04-26 | refactor | gateway+frontend-nyla | Letzte 4 hardcoded Cell-Label-Stellen entfernt: (1)
RoleView.scopeType(select mitfrontend_optionsSystem-Template/Template/Mandant) +RoleView.userCount->AdminMandateRolesPagezieht Attribute jetzt vonRoleView, kein lokalerscopeType-Formatter mehr; (2)Invitation.expiredFlagals Pydantic@computed_field(live ausexpiresAt+time.time()) mitfrontend_format_labels=["Ja","-","Nein"]; (3)Invitation.emailSent->emailSentFlagumbenannt + neuesemailSentAt-Feld (Persistenz im DB-Record),routeInvitations.create_invitationsetzt beide nach erfolgreichem Mailversand; (4)TrusteePositionViewmitsyncStatus(select Ausstehend/Synchronisiert/Fehler/Abgebrochen) +syncErrorMessage->routeFeatureTrustee.get_positionsenriched Rows ausTrusteeAccountingSync,useTrusteelookt Attribute via neuemattributesEntityName-Override,TrusteePositionsViewhat eigenen Sync-State + Custom-Renderer geloescht.attributeUtils.getModelAttributeDefinitionsundi18nRegistry.@i18nModelverarbeiten jetzt auchmodel_computed_fields(Labels +frontend_format_labelswerden registriert) - 2026-04-26 | refactor | gateway+frontend-nyla | Hardcoded Cell-Labels aus FormGeneratorTable-Pages entfernt: Boolean-Formatter ("Ja"/"Nein", "OK"/"Fehler") und Enum-Maps (
_STATUS_LABELS,scopeLabels) ausGraphicalEditorWorkflowsPage,GraphicalEditorTemplatesPage,AutomationsDashboardPage,ComplianceAuditPageersatzlos geloescht. Stattdessen Pydantic-Modelle (AutoWorkflow.active|sharedReadOnly|isTemplate|notifyOnFailure|templateScope,AutoRun.status,AutoStep.status,AutoTask.status,AutoVersion.status,Automation2WorkflowView.isRunning,AuditLogEntry.success) mitfrontend_format_labels/frontend_optionsausgestattet.resolveColumnTypesmerged jetzt auchlabelundoptionsaus dem Backend;FormGeneratorTablerendert Cells UND Filter-Dropdowns uebercolumn.optionsautomatisch — Pages duerfen Labels nicht mehr im Frontend hardcoden - 2026-04-26 | feat | frontend-nyla | FormGeneratorTable + columnTypeResolver:
ColumnConfig.options(ausfrontend_optionsder Pydantic-Felder) ist jetzt erste Klasse; Cell-Renderer und Filter-Liste resolven Value -> Label automatisch;column.labelist optional und wird vom Backend-Attribut gefuellt - 2026-04-26 | fix | gateway+frontend-nyla | GraphicalEditor Workflows-Tabelle:
createdAt-Alias ausrouteFeatureGraphicalEditor.get_workflowsentfernt — Frontend nutzt nun das kanonischesysCreatedAt.GraphicalEditorWorkflowsPage+GraphicalEditorTemplatesPageholen Attribute jetzt vonAutomation2WorkflowView(mitfrontend_type=timestampfuersysCreatedAt/lastStartedAtundfrontend_type=numberfuerrunCount); Spalten haben explizitsortable/filterablegesetzt — fehlende Sort-Icons und Zahl-statt-PeriodPicker behoben.Automation2Workflow-TS-Interface aufsysCreatedAtumgestellt - 2026-04-26 | refactor | frontend-nyla | RealEstate Parcels+Projects + GraphicalEditor Workflows+Templates:
apiEndpointauf den jeweiligen Listenroute gesetzt — Backend-Routen unterstuetzenmode=filterValues&column=Xundmode=idsueberhandleFilterValuesInMemory/handleIdsInMemory; FormGeneratorTable holt Filter-Werte jetzt sauber vom Backend (kein Local-Mode mehr noetig) - 2026-04-26 | feat | gateway | routeFeatureGraphicalEditor:
/workflowsund/templatesEndpunkte unterstuetzen jetztmode=filterValues&column=Xundmode=ids(FormGeneratorTable Backend-Pattern) ueberhandleFilterValuesInMemory/handleIdsInMemoryaus routeHelpers - 2026-04-26 | fix | frontend-nyla | AdminLanguagesPage:
hookData.fetchFilterValuesimplementiert (offizielles Pattern fuer In-Memory-Tabellen ohne Backend-Endpunkt) — distinct Filter-Werte ausdisplayRowsmit Cross-Filter-Support; ersetzt das zuvor versuchte FormGeneratorTable-Local-Mode - 2026-04-26 | revert | frontend-nyla | FormGeneratorTable: Local-Mode-Fallback in
getUniqueValuesForColumnund das Entfernen der console.warn rueckgaengig gemacht — silent Fallbacks verstossen gegen das Prinzip "klare Datenstrukturen + Modelle im Backend"; Tabellen muessen stattdessenapiEndpoint(Backend) oderhookData.fetchFilterValues(explizit) setzen - 2026-04-26 | fix | frontend-nyla | AutomationsDashboardPage Workflows-Tab: Spalten
isRunningundrunCountalssortable+filterablemarkiert (Backend unterstuetzt JOIN-basierte Sortierung/Filterung dieser computed fields) - 2026-04-26 | fix | gateway | Automation2 ExecutionEngine:
AutoRun.startedAtwird jetzt increateRungesetzt;AutoRun.completedAtwird inupdateRunautomatisch gesetzt sobald Status terminal wird (completed/failed/stopped/cancelled); routeWorkflowDashboard.stopRun setztcompletedAtebenfalls. Bisher wurden diese Felder nie befuellt — daher warenstarted/completedSpalten in der Runs-Tabelle leer - 2026-04-26 | fix | frontend-nyla | PeriodPicker in FormGeneratorTable: Preset-Kind (
thisMonth,thisQuarteretc.) wird im Filter-Wert mitgespeichert, damit es beim Round-Trip erhalten bleibt undisValueAllowednicht faelschlicherweise aufytdzurueckfaellt - 2026-04-26 | fix | gateway | routeAudit: 500-Fehler bei Datumsfilter behoben —
PaginationParams(pageSize=999999)verletztele=1000-Constraint; nutzt jetztmodel_construct+SortField-Konvertierung - 2026-04-26 | refactor | gateway | 5 Pattern-Inkonsistenzen aus FormGeneratorTable-Audit behoben: routeDataUsers stiller Fallback entfernt; routeFeatureRealEstate Projekte+Parzellen nutzen jetzt
applyFiltersAndSortstatt nur Sorting; routeAdminRbacRules custom filter/sort durch shared Helper ersetzt +enrichRowsWithFkLabelsergaenzt - 2026-04-26 | fix | frontend-nyla | ComplianceAuditPage: Fallback-Formatter fuer
instanceLabelundusernamezeigen jetztNA(uuid)statt abgeschnittener UUID ohne Kontext - 2026-04-26 | fix | gateway | aicoreModelRegistry: Race-Condition in
refreshModelsbehoben — Lock verhindert konkurrierende Refreshes; harmlose Duplikate (gleicher Name+Connector) werden toleriert statt als Fehler geworfen - 2026-04-26 | fix | gateway | routeDataFiles:
mode=filterValuesnutzt jetztenrichRowsWithFkLabels+handleFilterValuesInMemorystatt direktemgetDistinctColumnValues— FK-Spalten (mandateId, featureInstanceId) zeigen wieder Labels statt UUIDs - 2026-04-26 | fix | gateway | routeFeatureTrustee: 3x
mode=filterValues(Documents, Positions, generisch) vongetDistinctColumnValuesWithRBACaufenrichRowsWithFkLabels+handleFilterValuesInMemoryumgestellt — FK-Spalten (organisationId, roleId, userId, contractId etc.) zeigen Labels statt UUIDs; generischer Endpunkt nutzt zusaetzlich_buildFeatureInternalResolversfuer Feature-interne FKs - 2026-04-26 | fix | gateway | routeAudit:
_enrichUserAndInstanceLabelssetzt jetztNA(uuid)als Fallback stattNonefuer nicht aufloesbare FeatureInstance/User-IDs — Filter-Dropdown fuer Feature-Instanz war leer weil alle LabelsNonewaren - 2026-04-26 | fix | gateway | Zwei Filter-Bugs: (1)
applyFiltersAndSortin routeHelpers:value is Nonefiltert jetzt auf leere Felder statt den Filter zu ueberspringen ("Leer"-Option funktioniert); (2)routeAudit._applySortFilterSearchdurch Delegation an sharedapplyFiltersAndSortersetzt — Datumsbereich-Filter (between-Operator) und Null-Filter funktionieren jetzt konsistent - 2026-04-26 | fix | gateway | Stille
except Exception-Fallbacks inmode=filterValuesentfernt:routeFeatureTrustee(_handleDocumentMode, _handlePositionMode, _paginatedReadEndpoint),routeDataFiles,routeDataMandates— Fehler bubblen jetzt hoch statt stillschweigend auf teuren In-Memory-Pfad auszuweichen - 2026-04-26 | fix | gateway | Filter-Dropdown-UUID-Bug:
enrichRowsWithFkLabelsfehlte immode=filterValues-Pfad bei 8 Routen (routeDataConnections, routeInvitations, routeAdminFeatures, routeSubscription, routeFeatureRealEstate x2); Wikifk-label-resolution.mdmit Filter-Enrichment-Regel fuer AI-Agent ergaenzt - 2026-04-26 | refactor | gateway | FK-Metadaten konsolidiert: alle Datamodels nutzen
fk_targetmit Pflicht-Keysdb/table/labelField;fk_model/fk_label_fieldentfernt;_BUILTIN_FK_RESOLVERS["UserInDB"];_buildLabelResolversFromModelskip ohnelabelField;attributeUtilssetztdisplayFieldnur bei gesetztemlabelField;validateFkTargets()Startup-Validierung infkRegistry.py+app.py lifespan; Wikifk-label-resolution.md+database-architecture.mdaktualisiert - 2026-04-26 | fix | gateway |
connectorDbPostgre._ensureTableExists: TEXT->DOUBLE PRECISION Spalten-Migration schlug fehl fuer ISO-Datetime-Strings — Regex\\d{{4}}korrigiert zu\\d{4}(doppelte Klammern waren kein f-string-Escaping sondern literal),::timestampauf::timestamptz(Timezone-Offset korrekt parsen), SAVEPOINT pro ALTER (eine fehlgeschlagene Migration killt nicht mehr die gesamte Transaktion) — betraf MandateSubscription (6 Spalten) und BackgroundJob (3 Spalten) - 2026-04-26 | refactor | frontend-nyla | FlowEditor Form-Field-Type-Zentralisierung:
FORM_FIELD_TYPES+FORM_FIELD_TYPE_LABELSinattributeTypeMapper.ts;FormStartNodeConfig,FormNodeConfig,FieldBuilderEditorbeziehen Feldtypen aus zentraler Library statt hardcoded Listen; ClickUp-spezifische Typen (clickup_status,clickup_tasks) und zugehoerige UI (Connection-Picker, Status-Hinweis) entfernt; sharedFormField-Typ aufAttributeType+ generischesoptionsumgestellt;TriggerFormFieldRoweliminiert;clickupFormSync.tsgeloescht (dead code, nirgends importiert) - 2026-04-26 | refactor | gateway+frontend-nyla | Column-Type-Refactoring Schritte 1-10 abgeschlossen: 6 Pydantic View-Modelle (
UserMandateView,FeatureAccessView,BillingTransactionView,MandateSubscriptionView,UiLanguageSetView,DataNeutralizerAttributesView) indatamodelViews.py;createdAt/createdByAliase in Invitation- und Billing-DTOs aufsysCreatedAt/sysCreatedBystandardisiert;_COL_MAP-Remapping ininterfaceDbBillingentfernt; 7 Admin/Billing/Compliance-Seiten beziehen Spaltentypen viaresolveColumnTypes+fetchAttributes('<ViewModelName>')statt hardcodedtype:— tsc + Grep-Completeness-Check bestanden - 2026-04-26 | refactor | frontend-nyla | Schritt 8: Vollstaendigkeits-Grep — verbleibende hardcoded
type:in ComplianceAuditPage entfernt (username/instanceLabel/ipAddress im Modell); alle anderen type:-Werte berechtigt dokumentiert (enriched View-Spalten, synthetische Zaehler, Alias-Keys) - 2026-04-26 | refactor | frontend-nyla | Schritt 7: weitere FormGenerator-Tabellen (AdminUsers, Connections, Files/Prompts, Mandate-Hook, RealEstate*, Trustee*) bauen Spaltentypen nur noch via
resolveColumnTypesstatttype: attr.typeim Column-Map - 2026-04-26 | feat | gateway |
attributeUtils.getModelClasses: Feature-datamodel*.pyuntermodules/features/**rekursiv importieren (Trustee, Teamsbot, GraphicalEditor, …) fuer/api/attributes/{entityType} - 2026-04-26 | refactor | frontend-nyla | Workflow-Seiten (GraphicalEditorWorkflowsPage, AutomationsDashboardPage) beziehen Spaltentypen via
resolveColumnTypes+fetchAttributesvom Backend statt hardcodedtype:im Frontend; neuer Shared-UtilitycolumnTypeResolver.ts - 2026-04-26 | feat | frontend-nyla |
attributesApi.AttributeDefinition.typenutztAttributeTypeausattributeTypeMapper; Mapper um Backend-Typobject(JSON/Dict) ergaenzt - 2026-04-26 | feat | gateway | Pydantic CHECK-Cleanup: fehlendes
frontend_type: "timestamp"bei float-Zeitfeldern (UAM resetTokenExpires, DataSource, Security Token, Chat ChatLog/publishedAt/ActionItem/TaskItem/TaskHandover, Knowledge extractedAt); Redmine*OnTsvonnumberauftimestamp; Redmine DTOs (RedmineSyncResultDto,RedmineSyncStatusDto,RedmineConfigDto);UsageStatistics.periodStartmitfrontend_type: "date"; allefrontend_type: "datetime"auf"timestamp"(Audit, AuthEvent, GraphicalEditor Auto*, Messaging sentAt) — konsistent mitattributeTypeMapper.isDateTimeType - 2026-04-26 | refactor | gateway | Boot-Optimierung: Chatbot-Duplikat-Prewarm entfernt (
routeFeatureChatbot), Stripe-Bootstrap parallelisiert via ThreadPoolExecutor (stripeBootstrap) — erwartete Bootzeit-Reduktion ~8s - 2026-04-26 | fix | gateway |
interfaceRbac: Pagination-Dict-Filter (getRecordsetPaginatedWithRBAC/getDistinctColumnValuesWithRBAC) nutzen_rbacAppendPaginationDictFilter— numerischegt/gte/lt/lte/betweenmit::double precision, ISO-Datum + numerische Spalte als Unix-Bounds wie Connector - 2026-04-26 | feat | frontend-nyla |
FormGeneratorTable: Datum-Filter nutzt PeriodPicker (Presets + Kalender) statt primitiver<input type="date">; PeriodPicker rendert ausserhalbfilterDropdownOptions(Popover nicht durchoverflow-y: autogeclippt) - 2026-04-26 | fix | gateway |
TrusteeDataJournalEntry.bookingDate:Optional[str]->Optional[float](unix timestamp); Konvertierung in_persistJournalvia_isoDateToTimestamp(ValueError bei ungueltigem Datum, kein Fallback);_aggregateLocalMovementsliest float; FK-Label-Resolver formatiert float als ISO; Demo-Daten konvertiert; DB-Migration TEXT->DOUBLE PRECISION in_ensureTableExists - 2026-04-26 | fix | gateway |
datamodelFeatureTrustee:lastSyncAt/chartCachedAt/syncedAtbekommtfrontend_type: "timestamp",lastSyncDateFrom/lastSyncDateTofrontend_type: "date"— damit Frontend Date-Filter statt Text anzeigt - 2026-04-26 | fix | frontend-nyla |
FormGeneratorTable: Filter-Dropdown peruseLayoutEffectalsposition: fixedin den Viewport geklemmt; Audit-Timestamp-Spalten (sysCreatedAtetc.) bei numerischemtypeals Datums-UI + kein distinct-Fetch - 2026-04-26 | feat | frontend-nyla |
FormGeneratorTable: typbezogene Spaltenfilter — Zahlen (integer/int/number/float) mit Operator (=, >, >=, <, <=, Zwischen) undAnwenden; Datum-Filter mit CSS-Panel; keinfilterValues-Fetch mehr fuer bool/date/number-Spalten - 2026-04-26 | fix | gateway |
routeHelpers._matchesBetween: numerischefrom/tonach fehlgeschlagenem Datums-Parse (korrekte BETWEEN-Logik fuer Zahlenspalten);connectorDbPostgre:gt/gte/lt/lteundbetweenauf INTEGER/DOUBLE PRECISION mit::double precisionstatt lexikographischem TEXT-Vergleich
2026-04-25
- 2026-04-25 | feat | * | Phase 4 FK:
frontend_fk_*und FormGenerator-fkSource/Client-Cache entfernt;fk_label_field+displayFieldonly;_resolveRoleLabels;getRecordsetPaginated+getRecordsetPaginatedWithRBAC+ FK-Sort-Pfad mit_enrichRowsWithFkLabels;attributeUtils+ betroffene Datamodels + Pages auf reines Backend-Enrichment - 2026-04-25 | fix | gateway | Trustee Account Balances: echte Schlusssalden aus Buchhaltungssystem importieren (RMA via
/gl/saldo; Bexio via Journal-Aggregation; Abacus via OData-Aggregation); korrigierte kumulative Fallback-Berechnung in_persistBalances; neuesAccountingPeriodBalance-Modell +getAccountBalances-Methode inBaseAccountingConnector; Bug "Banksaldo per Stichtag falsch" (BuHa SoHa Konto 1020) geloest (c-work: c-work/4-done/2026-04-trustee-account-balances-import.md) - 2026-04-25 | test | gateway | Unit-Tests fuer Trustee-Balance-Import: RMA-Connector (BuHa-SoHa-Szenario + ER-Reset), Bexio-Connector (kumulative Aggregation + Carry-Over), Abacus-Connector (OData-Aggregation), AccountingDataSync (Connector-Path + Local-Fallback)
- 2026-04-25 | feat | gateway | FK-Resolution Phase 2 (A1+A2): Neue zentrale
_enrichRowsWithFkLabels()inrouteHelpers.py— bulk-resolved FK-Labels als{field}Label-Spalten pro Row;_resolveMandateLabels/_resolveInstanceLabels/_resolveUserLabelsliefernNonestatt ID bei fehlender Aufloesung;routeWorkflowDashboard,routeAudit,routeBilling(Transactions + Billing-Aggregation),routeSubscriptionauf zentrale Funktion migriert (or mid[:8]/or uid[:8]/or iid-Fallbacks entfernt) - 2026-04-25 | feat | gateway | FK-Resolution Phase 2 (B2):
_enrichedFilterValuesinrouteWorkflowDashboardliefert{value, label}Objekte fuer FK-Spalten (mandateId, featureInstanceId) — Frontend zeigt Labels im Filter-Dropdown ohne separatefkSource-Aufloesung; Leerwerte (null) fuer "(Leer)"-Filter inkludiert - 2026-04-25 | fix | gateway+frontend | FK-Resolution Korrektur:
routeWorkflowDashboardruns/workflows-Enrichment benenntmandateIdLabel→mandateLabelum (Frontend-Interface-Kompatibilitaet);AutomationsDashboardPageSpalten mandateId/featureInstanceId nutzendisplayField: 'mandateLabel'/'instanceLabel' - 2026-04-25 | feat | gateway | FK-Resolution Phase 2 (B1):
getDistinctColumnValues+getDistinctColumnValuesWithRBAC+_extractDistinctValues+_distinctColumnValuesliefernnullals letzten Eintrag wenn NULL/Leer-Zeilen existieren — Frontend kann "(Leer)"-Filter anbieten - 2026-04-25 | feat | frontend-nyla | FK-Resolution Phase 3 (C1+C2):
FormGeneratorTable.ColumnConfig.displayField— neues Pattern: Cell rendertrow[displayField]stattrow[key], CSV nutztdisplayField;fkSource/fkDisplayFieldals@deprecatedmarkiert (Legacy-Pfad funktioniert weiterhin) - 2026-04-25 | feat | frontend-nyla | FK-Resolution Phase 3 (B3):
FilterValuesListakzeptiertstring | null | {value, label}Eintraege;FilterValue-Typ eingefuehrt;_normalizeFilterValuenormalisiert alle 3 Formate; Backend-null-Eintraege werden als "(Leer)"-Option gerendert - 2026-04-25 | fix | gateway | Fallback-Cleanup Phase 1 (D1+D2): Pagination-Parsing in
routeWorkflowDashboard(runs/workflows) undrouteDataMandateswirft 400 bei kaputtem JSON statt silent default;runsByStatus/Run-Enrichment in/metrics+/workflowspropagieren DB-Fehler stattlogger.warning+200;delete_system_workflowCallback-Trigger meldet Listener-Bugs (500 stattexcept: pass);routeBilling._isAdminOfMandate/_isMemberOfMandateundrouteSubscription._assertMandateAdminfail-loud (kein "DB-Down → 403"-Mask mehr); StripeSubscription.retrieveim Checkout-Webhook re-raised statt silent skip - 2026-04-25 | fix | gateway | Fallback-Cleanup Phase 1 (D2):
routeInvitationsRollen-Zuweisung —addRoleToFeatureAccess/addRoleToUserMandatesind bereits idempotent, dahertry/except: pass # Role might already be assignedentfernt → echte FK-/DB-Fehler beim Einladungs-Akzept werden jetzt sichtbar - 2026-04-25 | fix | frontend-nyla | Fallback-Cleanup Phase 1 (D3+D4):
AutomationsDashboardPage._handleExecutezeigt "Workflow gestartet" nur noch, wenn die 1s-Beobachtungs-Phase weder Erfolg noch Fehler beobachtet hat (kein Doppel-Toast "gestartet" + "fehlgeschlagen" mehr);_loadMetricstoast-t Backend-Fehler statt nurconsole.error;Automation2FlowEditor.handleWorkflowRenamezeigt Fehler-Toast statt unsichtbaremconsole.error - 2026-04-25 | feat | frontend-nyla |
FormGeneratorTable: Leerwert-Filter(Leer)in allen Filter-Dropdowns — filtert aufIS NULL OR = ''(Backend unterstützt bereitsnullin Pagination-Filtern); Filter-Icon/Clear-Button erkennennull-Filter korrekt viakey in filters - 2026-04-25 | fix | frontend-nyla | NodeConfigPanel/RequiredAttributePicker/FeatureInstancePicker: Texte (Type-Badges, Bound-Refs, Vorschlag-Labels, Beschreibungen) verlassen den 280px-Panel-Frame nicht mehr — Header-Layout
label flex:1 1 100 %lässt Badge umbrechen;box-sizing: border-box,overflow-x: hidden,overflow-wrap: anywhereals Safety-Net auf.nodeConfigPanel; Bound-Chip/Vorschlag-Button mitwhitespace: normal+word-break - 2026-04-25 | fix | frontend-nyla | KeepAlive-Wrapper (
GraphicalEditor,Workspace,Commcoach): Persistenz strikt pro(mandateId, instanceId)—key={mandate:instance}an die gehaltene Page; Wechsel der Mandanten-/Instanz-Tupel unmountet den alten Editor (kein Cross-Tenant-Save mehr, "not found"-Bug behoben); Unit-TestGraphicalEditorKeepAlive.test.tsx - 2026-04-25 | fix | frontend-nyla |
DataPicker: percreatePortalnachdocument.body(entkoppelt von.nodeConfigPanel button-Primary-Override); neues List-Row-Layout/Theme (dataPickerNodeHeaderneutral), Header-Badge/Filter/Close-Styles, höheres z-index - 2026-04-25 | fix | frontend-nyla | Flow-Editor
CanvasHeader: Zwei-Spalten-Layout (Kontext: fester Workflow-Dropdown + Titel mit Ellipsis | Aktionspanel); Run-Buttonmin-width; Version-Zeile getrennt;retryButton-Margin im Toolbar-Panel neutralisiert - 2026-04-25 | fix | gateway | Trustee-Template
trustee-receipt-import:documentListals DataRefextract→process→sync(Pick-not-Push), nicht leere Listen; Unit-Testtest_trustee_template_workflows.py - 2026-04-25 | feat | gateway | Trustee + Redmine Nodes auf typisierten
FeatureInstanceRef[<code>]-Param +frontendType: featureInstancemigriert (c-work: c-work/4-done/2026-04-feature-instance-ref-adapter-migration.md) - 2026-04-25 | feat | gateway | Neuer Endpoint
GET /api/workflows/{instanceId}/options/feature.instance?featureCode=…fuer Mandanten-gefilterte FeatureInstance-Auswahl (c-work: c-work/4-done/2026-04-feature-instance-ref-adapter-migration.md) - 2026-04-25 | feat | frontend-nyla |
FeatureInstancePicker(0/1/N) als Renderer fuerfrontendType: featureInstance; Sysadmin-Toggle "Schema-Details" im CanvasHeader (c-work: c-work/4-done/2026-04-feature-instance-ref-adapter-migration.md) - 2026-04-25 | fix | frontend-nyla | NodeConfigPanel-Banner zeigt
param.namestatt der ausschweifenden Description (Tooltip enthaelt vollen Text); hidden-Pflicht-Params werden zentral infindRequiredErrorsgefiltert (kein Phantom-Pflichtfeld mehr) (c-work: c-work/4-done/2026-04-feature-instance-ref-adapter-migration.md) - 2026-04-25 | fix | frontend-nyla | DataPicker-Modal auf CSS-Variablen umgestellt; Hover-Safety-Net
dataPickerLeaf:hover *haelt Type-Hints auf blauem Hintergrund lesbar (c-work: c-work/4-done/2026-04-feature-instance-ref-adapter-migration.md) - 2026-04-25 | docs | wiki | Audit
2026-04-node-typization-audit.mdarchiviert; Folge-Track-Doc2026-04-feature-instance-ref-adapter-migration.mddirekt in4-done/als erledigt - 2026-04-25 | docs | wiki | Changelog-Konvention im
_CHANGELOG.mdeingefuehrt; inREADME.md+doc-sync.mdcreferenziert - 2026-05-05 | fix | frontend-nyla | FormGeneratorTree:
window.confirm()durchuseConfirm-Modal ersetzt; Hover-Icons ueberlappen jetzt die Dateigroesse statt daneben zu stehen (spart Breite im File-Tree) - 2026-05-07 | fix | gateway | sandboxExecutor:
opendurch In-Memory-VirtualFS ersetzt (statt geblockt); AI-generierter Code kann jetzt Dateien lesen/schreiben ohne echten Dateisystem-Zugriff - 2026-05-07 | feat | gateway | RedmineTicketMirror + RedmineTicketDto: Feld
doneRatio(% erledigt) ergaenzt; Sync-Mapping und DTO-Konvertierung aktualisiert - 2026-05-07 | feat | gateway | Neues Agent-Tool
redmine.listRelationsfuer direkte Abfrage der Beziehungstabelle (Filter: issueId, relationType, pagination) - 2026-05-07 | feat | gateway |
redmine.listTickets:offset-Parameter ergaenzt fuer echte Pagination; Response liefertoffset+hasMorestatttruncated