35 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-04-28
-
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 | 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-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