Commit Graph

1417 Commits

Author SHA1 Message Date
Agent Zero 4a25ac1379 fix(arch): externes Audit — 13 Backend-Fixes (Workspace-Modules, Tenant-Manifeste, Lifecycle, Contracts, Permissions)
Check Cross-Plugin Imports / check (push) Has been cancelled
Verifikation: Alle 17 Audit-Findings gegen den Code geprueft — alle bestaetigt.
Backend-Lifecycle-Fixes umgesetzt; 4 Frontend-Plugin-Architektur-Punkte
als Phase Q in die Roadmap eingeplant.

- P1 list_workspaces: Module + User-Counts gebuendelt laden (Editor-Overwrite-Bug)
- P1 active-manifests: Tenant-Deaktivierung (tenant_plugin_activation) filtern
- P1 uninstall: volle Service-Deactivation VOR registry.uninstall()
- P1 ContractRegistry: DB-Aktivstatus-Guard (Restart-Edge-Case) + Re-Activate
- P1/P2 Field-Definitions: voller Lifecycle (register/unregister) im Service
- P1/P2 Contact-Felddefinitionen (39) ins ContactsPlugin-Manifest verschoben
- P1 12 fehlende Permission-Keys registriert (AST-Scan: 0 fehlend)
- P2 contact_folder -> ContactsPlugin; ENTITY_PLUGIN_OWNERS wird befuellt
- P2 Entity-Permission-Fallback fail-closed statt contacts:read
- P2 forgejo_error_reporter is_core=False; DMS is_core=True (ADR-020)
- P2 Worker: Contacts-Trash-Cleanup ins Plugin (get_job_modules-Discovery)
- P1/P2 DSGVO-Export delegiert an DSAR-Collector (kein Core->Contacts)
- P2 False-green Tests korrigiert (or True, veraltete Route-Count-Assertion)

Verifikation: tests/test_audit_architecture_fixes.py 17/17; Regressionen
gruen (contacts_lifecycle, entity_registry, workspace_scopes, rbac,
lifecycle_service); Combo-Order-Test 35/35; Cross-Plugin-Checker 497/0;
compileall sauber; ruff auf 7-Error-Baseline.

Doku: PROGRESS.md Audit-Section, PLATFORM_ROADMAP.md Phase Q (Q1-Q4),
plugin-development-guide.md Lifecycle, permissions.md Katalog.
2026-09-13 02:25:01 +02:00
Agent Zero 86cea5d6c4 fix(frontend): Interceptor normalisiert ALLE apiClient-URLs — auch Direktaufrufe und Cache-Alte-Chunks
Der apiX-Wrapper-Fix (744f2a1) heilte nur Wrapper-Aufrufe. Produktion-Logs
zeigten: POST /api/v1/api/v1/ai-proactive/context → 405 (4x vom User-
Browser mit alten gecachten Chunks). Der Request-Interceptor strippt jetzt
redundante /api/v1-Präfixe auf Transport-Ebene — heilt auch Direkt-
apiClient-Calls und stale Cache-Artefakte transparent.
2026-09-12 00:32:42 +02:00
Agent Zero ac5edef3dc docs(progress): UI-Backlog-Tracking — 16 UI-lose Module, Modul 1 (Approvals) erledigt (#369) 2026-09-08 23:33:43 +02:00
Agent Zero ecc7a24c1c feat(approvals): UI für Freigaben — Review-Queue mit Approve/Reject (Modul 1/16)
Backend:
- Phantom-Permission-Bug gefixt: approvals:read/write/approve fehlten in
  CORE_PERMISSIONS (Rollen konnten sie nie zugewiesen bekommen — gleiche
  Fehlerklasse wie dashboard:read in M2)

Frontend:
- api/approvals.ts: TanStack Hooks (list/detail/approve/reject/expire/create)
- pages/Approvals.tsx: Review-Queue — Status-Tabs (Offen/Alle/Genehmigt/
  Abgelehnt/Abgelaufen), Karten mit Aktion/Entity/Requester/Metadata,
  Approve/Reject mit Kommentar-Modal, Permission-Gating (approvals:approve)
- Route /approvals (PermissionRoute approvals:read), Sidebar-Eintrag
- i18n approvals.* + nav.approvals (de/en)

Verifikation: Vitest 10/10 (Rendering, Tabs, Approve/Reject-Flow,
Kommentar, Permission-Gating, Resolved-Zustände), RBAC-Regression 102/102,
tsc clean, Build OK
2026-09-08 23:26:56 +02:00
Agent Zero 4eb05d96ad fix(frontend): downloadIcsFile rief nicht existierenden Endpoint auf — auf echten ics-feed umgestellt
- Vorher: apiClient.get('/calendar/{id}/ics-feed-public') — Endpoint
  existiert im Backend nie (live 404 bewiesen via curl; Reverse-Check aus
  der Frontend-Backend-Gegenüberstellung)
- Jetzt: nutzt getIcsFeedUrl() mit optionalem Token — derselbe Fluss wie
  IcsControls (Backend auto-generiert ics_token beim ersten Hit)
- Funktion war tot (kein Aufrufer), aber garantiert kaputt für jeden
  künftigen Nutzer des Download-Buttons
2026-09-08 23:05:57 +02:00
Agent Zero 744f2a1dbf fix(frontend): URL-Normalisierung gegen Doppel-Präfix — Workspace-UI & Permission-Refresh in Produktion repariert
Problem: Axios baseURL '/api/v1' + 16 apiX-Calls mit vollem Präfix
('/api/v1/workspaces/...') ergaben '/api/v1/api/v1/...' → 404 live
(bewiesen per curl + Node). Betroffen: komplette Workspace-UI
(Switcher, Manager, Phase-N-Scope-Editor) + Permission-Refresh.

Fix (Defense-in-Depth):
- normalizeApiUrl() in client.ts: alle apiX-Wrapper strippen redundanten
  '/api/v1'-Präfix — deckt auch DYNAMISCHE Backend-Contract-Endpoints
  (N2-Scope-Editor-Wertquellen) ab, die Call-Sites nicht umschreiben können
- workspaces.ts + useUserPermissions.ts auf relative Pfade gesäubert (16 Calls)

Tests: clientUrl 8/8 neu (Normalisierung + Wrapper-Beweis), tsc clean,
Build OK, Workspace-Regression 3 Dateien grün
2026-09-08 22:53:11 +02:00
Agent Zero 03dd477899 feat(N4): Restliche Module — Tasks/Kommunikation/Wiki/Reports/Agents/Tags/Search + Navigation + Dashboard-Schnittstelle (#368)
Check Cross-Plugin Imports / check (push) Has been cancelled
- Scope-Deklarationen: tasks only_mine, kommunikation conversation_ids, wiki category_ids (NEUE contracts.py), report_generator template_ids, automation agent_ids (module_key agents), tags tag_ids, unified_search entity_types dynamisch aus Provider-Registry
- Core-Beiträge: navigation default_route (Startseite) + dashboard widget_app_ids (Widget-TYP-Angebot, Layout bleibt Phase M)
- Backend-Filter (additive UND): /tasks (only_mine), /comm/conversations, /wiki/articles+/categories (Subtree), /reports/print-templates, /agents, /tags, /search GET+POST (entity_types-Schnitt), /miniapps?host=dashboard
- apply_entity_type_scope-Helper (requested ∧ scope)
- Frontend: WorkspaceSwitcher default_route-Navigation, Sidebar workspace-menu_order-Sortierung, workspaceStore moduleMenuOrder()
- Tests: 18/18 Deklarationen + 11/11 Filter (TDD), Frontend 2/2 + Store 18/18, tsc clean, Build OK
- Regression 64 passed (4 Kombi-Failures = Suite-Isolation, solo-bewiesen); Checker 0; Ruff = Vorbestand (Stash-bewiesen)
2026-09-01 23:23:15 +02:00
Agent Zero 26506a5027 feat(N3): Backend respektiert X-Workspace-ID bei Listen — contacts/dms/mail/calendar (#367)
Check Cross-Plugin Imports / check (push) Has been cancelled
- Core-Resolver resolve_workspace_scope(): Zuweisungs-Check, leere Werte fallen weg; Exemptions System-Admin + workspaces:configure_modules (Editor-Deadlock)
- require_workspace_scope(module_key) FastAPI-Dependency (deps.py)
- expand_folder_scope(): Ordner-Subtree (zyklensicher) für ContactFolder + DMS Folder; scope_uuid_set() fail-closed
- contacts: folder_ids-Subtree + contact_types auf GET /contacts, List-Cache bei aktivem Scope deaktiviert (Cache-Leak-Gefahr)
- dms: folder_ids-Subtree + file_types (semantische Matcher) auf /files, Baum-Reduktion auf /folders
- mail: account_ids auf /mails, /threads, /accounts
- calendar: calendar_ids auf /calendar/entries, /calendars
- Frontend-Defaults: getModuleConfig() im workspaceStore, ContactsList default_saved_view_id, Calendar default_view
- Tests: 21/21 neu (TDD rot→grün), Regression 81 passed, Checker 0, tsc clean, Vitest grün, Build OK
2026-09-01 10:27:23 +02:00
Agent Zero b40adfdd3a feat(N2): Dynamischer Scope-Editor — WorkspaceScopeEditor ersetzt JSON-Textarea (#366)
- WorkspaceScopeEditor.tsx: generisches Filter-UI aus /scope-definitions (multiselect mit value_source-Fetch, select mit Keine-Einschränkung-Placeholder, toggle) — WidgetSettingsForm-Philosophie
- resolveScopeItems: Wertequellen-Auflösung (items-Wrapper, Root-Listen, DMS-Ordner-Baum-Flattening), nie-crashend
- Hooks: useWorkspaceScopeDefinitions + useScopeValues (TanStack Query, staleTime 60s)
- WorkspaceManager: JSON-Textarea entfernt, Scope-Editor inline pro sichtbarem Modul, Speicherung in workspace_modules.config
- i18n: workspaces.scopeEditor.* 5 Keys de/en (Security-Invariante im UI: nichts ausgewählt = keine Einschränkung)
- Tests: 21/21 (TDD rot 4→grün), tsc clean, Production-Build OK
2026-09-01 08:31:30 +02:00
Agent Zero c25356c257 feat(N1): Scope-Registry via Contract — workspace_scopes() Deklarationen + /scope-definitions Endpoint (#365)
Check Cross-Plugin Imports / check (push) Has been cancelled
- workspace_scopes() Contract-Hook (document_placeholders-Muster): Plugins deklarieren Scope-Dimensionen inkl. Wertequellen
- Deklarationen: contacts (Ordner/Typen/Saved-View), dms (Ordner/Datei-Typen), mail (Postfächer), calendar (Kalender/Standard-Ansicht)
- Pydantic fail-closed (schemas/workspace.py): ScopeOption, ScopeValueSource (nur interne /api/v1-Pfade, SSRF-sicher), WorkspaceScopeDimension, WorkspaceModuleScopes
- Aggregator workspace_scope_service.py: discovered-Plugins, ARCH-014-safe, Crash-sicher, ungültige Deklarationen verworfen
- GET /api/v1/workspaces/scope-definitions (workspaces:configure_modules) vor /{workspace_id} registriert
- Security-Invariante: Scope = reine UND-Einschränkung (Workspace ∧ RLS ∧ ABAC ∧ Permissions)
- Tests: 18/18 neu (TDD rot→grün), Regression 17/17, Checker 0 Verstöße, Ruff clean
- Doku: api-documentation.md Workspaces-Sektion, PROGRESS.md Phase N1
2026-08-31 23:17:54 +02:00
Agent Zero 6ed4bb7f98 docs(progress): M6 abgeschlossen — PHASE M KOMPLETT (M1-M6, alle Hosts live, send_miniapp in Produktion verifiziert) 2026-08-31 01:10:16 +02:00
Agent Zero 04e92794de fix(M6): agents/tools-Endpoint — list_for_api statt nichtexistenter list_tools (#364)
Check Cross-Plugin Imports / check (push) Has been cancelled
- Vorbestands-Bug (live gemessen: 500 "ToolRegistry has no attribute list_tools"):
  automation/agent_routes.py rief registry.list_tools() auf, ToolRegistry
  bietet get_all()/list_for_api() — Route auf list_for_api() mit korrektem
  Feld-Mapping (plugin_name -> plugin) umgestellt
- Regressionstest gesichert (test_agents_tools_route_uses_list_for_api)
- M6-Suite 8/8 gruen
2026-08-31 01:07:56 +02:00
Agent Zero 335762dd3d feat(M6): Weitere Hosts — MiniApps in Fenstern + AI-Agenten-Ausgabe-Bloecke (#364)
- Windows-Host: openMiniAppWindow-Helper + MiniAppWindowContent (windowStore);
  Oeffnen-Buttons im Chat-Block (MiniAppBlock) und Dashboard-Widget
- AI-Agenten-Host: Core-Tool send_miniapp (app/ai/miniapp_tools.py) —
  miniapp-Block in Agent-Chat (approval_request-Praezedenz), Permission
  fail-closed gegen aufrufenden User pro App; Registrierung im lifespan
- agent_loop: tool_context + agent_name (Raum-Aufloesung)
- Fix: MiniAppBlock nutzt useMiniapps (component-Feld) statt Legacy /comm/miniapps
- Tests: M6 7/7 (TDD rot->gruen), Backend-Regression 57/57, Vitest 26/26
  (4 neue Window-Tests), tsc clean, build OK
2026-08-31 01:04:33 +02:00
Agent Zero 63aa0cf788 docs(progress): M5 Plugin-MiniApps abgeschlossen — 11/17 renderbare Apps live, automation-Legacy-Bug gefixt 2026-08-31 00:18:08 +02:00
Agent Zero cd34bab3a8 fix(M5): automation-MiniApp-Registrierung — Legacy-Doppelregistrierung entfernt (#363)
Check Cross-Plugin Imports / check (push) Has been cancelled
- on_activate re-registrierte Manifest-MiniApps OHNE component/permission und
  ueberschrieb die korrekte M1-Registrierung aus super().on_activate()
  (live gemessen: automation_status comp=no/perm=- auf Produktion)
- Regressionstest sichert das Entfernen (test_automation_legacy_reregistration_removed)
- Regression: M5 8/8 + lifecycle + registry 26/26
2026-08-31 00:15:44 +02:00
Agent Zero 7ed5349e86 feat(M5): Plugin-MiniApps — dms, mail, wiki, graph_rag, automation (#363)
Check Cross-Plugin Imports / check (push) Has been cancelled
- 5 Manifest-Beiträge (MiniAppContribution): dms_folders (dms:read), mail_unread (mail:read), wiki_recent (wiki:read), graph_overview (graph:read), automation_status (automation:read) — je settings_schema max_items, order 60-100
- 5 Frontend-Widgets auf bestehenden API-Clients (keine neuen Backend-Endpoints): DmsFoldersWidget, MailUnreadWidget, WikiRecentWidget, GraphOverviewWidget, AutomationStatusWidget
- MiniAppHost-Registry +5; tsc clean, build OK
- Tests: M5 7/7 (TDD rot->gruen), Backend-Regression 53/53, Vitest 22/22
2026-08-31 00:10:31 +02:00
Agent Zero 24dc78977c docs(progress): M4 System-Rueckbau abgeschlossen — 6/12 renderbare Apps live, Core reiner Host 2026-08-30 22:24:38 +02:00
Agent Zero 3c496f4b6a feat(M4): System-Rueckbau — Dashboard-Inhalte als MiniApps, Core = reiner Host (#362)
Check Cross-Plugin Imports / check (push) Has been cancelled
- system_miniapps.py: audit_activity (audit:read, settings max_items) + system_metrics (settings:read) als Core-Apps in Registry
- base.py-Fix: native Manifest-MiniApps reichen component durch (M1-Luecke)
- contacts-Manifest: contacts_stats (ContactsStatsWidget, contacts:read, show_companies/show_persons)
- Seed-Fix: nur renderbare Apps (component) landen im Dashboard-Layout
- Frontend: ContactsStatsWidget, AuditActivityWidget, SystemMetricsWidget; MiniAppHost-Registry +3
- Dashboard.tsx = reiner Host (26 Z.); Page-Tests auf Pure-Host umgeschrieben
- Tests: M4 7/7 (TDD rot->gruen), Backend-Regression 46/46, Vitest 22/22, tsc clean, build OK
2026-08-30 22:22:20 +02:00
Agent Zero 9e254176c9 docs(progress): M3 Produktions-Verifikation nachgetragen — Frontend-Deploy 26948fd live, renderbare Apps 3/9 2026-08-30 21:30:10 +02:00
Agent Zero 26948fdb51 feat(M3): Dashboard-Builder — Edit-Modus, Drag&Drop, Palette, Tabs (#361)
- DashboardBuilder: @dnd-kit 12-Spalten-Flow-Grid (seed-konsistent), View/Edit-Schalter, Resize, Tab-Verwaltung, Dashboard-CRUD + Set-Default, Dirty-Save
- MiniAppHost ersetzt DashboardWidgetLoader (lazy Registry + settings-Props); Palette nur renderbare Apps (component-Filter)
- WidgetSettingsForm generisch aus settings_schema; Bestands-Widgets settings-fähig (RecentContacts: limit)
- api/miniapps.ts + api/dashboards.ts (TanStack-Query-Hooks, documents.ts-Muster)
- Dashboard.tsx = Builder-Host (StatCards/SystemMetrics bleiben bis M4); Legacy-Grid/Loader gelöscht, Geister-Test ersetzt
- Tests: Builder 13/13, Page 11/11, i18n de/en, tsc clean, build OK
2026-08-30 21:28:40 +02:00
Agent Zero 74827156d0 docs(progress): M2 Produktions-Verifikation nachgetragen — Deploy b3e259f healthy, RLS konvergiert, Lazy-Seed bewiesen 2026-08-30 16:24:12 +02:00
Agent Zero b3e259fc25 feat(M2): Persönliche Dashboards — Tabelle, CRUD, Lazy-Seed, RLS (#360)
Check Cross-Plugin Imports / check (push) Has been cancelled
- dashboards-Tabelle (Layout JSONB, Tabs, is_default, partial unique name index)
- 6 CRUD-Endpoints /api/v1/dashboards, Owner-only (saved_views-Präzedenz), Audit
- Lazy Default-Seed aus MiniApp-Registry (permission-gefiltert, 12-Spalten-Flow)
- CORE_PERMISSIONS dashboard:read/write (fixt Phantom-Permission in dashboard.py)
- Migration 0144: RLS crm_api+crm_worker + konvergenter Fix der 3 Phase-L-Policies
- Tests: test_dashboards_backend.py 23/23 (TDD rot->grün); Regression 162/163
2026-08-30 16:21:34 +02:00
Agent Zero 7a755d32e6 docs(progress): Uebergabe-Konsistenz — M1 done, naechster Schritt M2; Phase-M-Status in_progress statt not_started 2026-08-30 14:06:11 +02:00
Agent Zero 84cb82d2c4 feat(M1): Universal-MiniApp-Registry — Plugin-Layer, permission fail-closed, Lifecycle, /api/v1/miniapps
Check Cross-Plugin Imports / check (push) Has been cancelled
- app/plugins/miniapp_registry.py: Registry aus kommunikation in Plugin-Layer gehoben (Plattform-Konzept, hosts chat/dashboard/window)
- MiniAppDef: permission (fail-closed) + settings_schema + col/row_span + hosts + component + order + builtin
- MiniAppContribution + FrontendDashboardWidget (Manifest-Schema) um M1-Felder erweitert — dashboard_widgets ist Alias von miniapps (ein Contribution-Typ, #359-Philosophie)
- BasePlugin.on_activate: automatische Manifest-Registrierung; on_deactivate: unregister_plugin (nur eigene Apps)
- GET /api/v1/miniapps (server-seitig permission-gefiltert, ?host=) + GET /api/v1/miniapps/{app_id} (403/404 fail-closed)
- kommunikation/miniapp_registry.py = Kompatibilitaets-Bruecke (Bestands-Importer unveraendert)
- Doku: api-documentation.md + plugin-development-guide.md (MiniApp-Beitragsmuster)

TDD: Rot 16 failed -> Gruen 16/16; Regressionen: contracts 23/23, lifecycle+route_order 4/4; ruff clean (M1-Dateien, Vorbestand per Stash bewiesen); create_app OK
2026-08-30 13:00:33 +02:00
Agent Zero 5eade3e005 docs(roadmap): Phase P — Page-Lock-Konzept user-bestaetigt (is_locked, 409 page_locked, Lock-Button, Owner/Admin-only) 2026-08-30 12:47:20 +02:00
Agent Zero 65c22e9200 docs(roadmap): Phase P — Notizen-App (Notion-artig, ersetzt Wiki komplett)
- P1 Datenmodell (WikiPage: blocks JSONB, parent_id-Hierarchie, Migration Markdown->Text-Bloecke)
- P2 Sidebar Seiten-Baum (dnd-kit, Favoriten, Suche)
- P3 Inline-Block-Editor (Live-Editing ohne Mode-Toggle wie Notion, Slash-Menue, Auto-Save, Quer-Verweise, Drag&Drop)
- P4 MiniApp-Bloecke (erster MiniApp-Konsument) + wiki_blocks()-Contract (Plugin-Erweiterbarkeit, Basis fuer spaeteren Datenbank-Block)
- P5 Vollstaendige Such-Indexierung (content_tsv + Embedding-Chunks, hybrid FTS/vector, Re-Index bei Auto-Save)
- Edit-Konzept recherchiert: Notion hat keinen separaten Edit-Modus (Live-Inline-Editing, Auto-Save); Lese-Ansicht via Permissions + optional Page-Lock
- User-Entscheidungen: Wiki komplett ersetzen, keine Notion-Datenbanken erstmal, MiniApps als Bloecke
2026-08-30 12:42:42 +02:00
Agent Zero 3e5ce47798 chore(cleanup): Chaos-Beseitigung — Doppel-Phase-L aufgeloest, PROGRESS-stand modernisiert
- Roadmap: UI-Overhaul umbenannt zu Phase O (L war doppelt vergeben), Bug-Verifikation Phase 1 eingetragen (5/7 bereits erledigt: 1.1+1.4+1.5+1.6+1.7; offen: 1.2 Kontakte-Drag-Drop Ordner, 1.3 MoveDialog)
- AI-Assistant-Konflikt-Notiz entschieden: Option (b) — Seite bleibt, Phase-2-Vorschlag ueberholt
- Phase L Dokumente-Generator als ABGESCHLOSSEN markiert (b311ab7 + 559bba6, deployed, Alembic 0143)
- PROGRESS.md 'Weitermachen': veraltete Paketliste (alle 6 erledigt) + falscher Produktionsstand (20ff5e2/0142) ersetzt durch realen Stand (L-Deploy, 0143) + offene Phasen M/N/O + Vorbestands-Findings
- Lokale Artefakte entfernt: dump.rdb, frontend/test-results (4.3MB, beides war korrekt ignoriert)
2026-08-30 09:23:30 +02:00
Agent Zero f6516e48ca docs(roadmap): Phase N Workspace-Scopes + Workspace/Dashboard-Abgrenzung (user-korrigiert)
- Phase N: Modul-Teilmengen pro Workspace (N1 Scope-Registry via Contract, N2 dynamischer Scope-Editor, N3 Contacts/DMS/Mail/Calendar, N4 restliche Module)
- KLARE TRENNUNG Workspace vs Dashboard: Workspace = Admin-Gruppen-Kontext (was verfuegbar ist, workspace_widgets); Dashboard = persoenlich (Phase M, dashboards-Tabelle)
- 0 Umbau: config JSONB + X-Workspace-ID + /context + Sidebar-Consumer existieren bereits
- Security-Invariante dokumentiert: Scope = reine UND-Einschraenkung zu RLS/ABAC/Permissions
2026-08-30 09:18:00 +02:00
Agent Zero dfe46dff16 docs(roadmap): Phase M — MiniApp-Plattform & Dashboard-Builder verankert (M1-M6, user-abgestimmt)
- M1 Universal-Registry (permission fail-closed + settings_schema, /api/v1/miniapps, Server-seitiger Permission-Filter, Lifecycle-Cleanup)
- M2 Dashboard-Backend (dashboards-Tabelle pro User, Tabs, Layout JSONB, RLS, Dual-Path)
- M3 Builder-Frontend (Edit-Modus, dnd-kit Grid, Resize, Tabs, Settings-Form aus settings_schema)
- M4 System-Rueckbau (StatCards->contacts, ActivityFeed->audit, System-Metrics->System-MiniApp, alte Widgets migrieren)
- M5 Plugin-MiniApps (contacts, tasks, calendar, wiki, dms, mail, knowledge, automation)
- M6 Weitere Hosts (AI-Agenten-Tool-Ausgabe, Windows, Wiki-Eval)
- Basis-Live-Bestand dokumentiert inkl. bewiesener Luecken (MiniAppContribution ohne permission, FrontendDashboardWidget ohne settings_schema)
- dashboard_widgets wird Alias von miniapps (ein Contribution-Typ, #359-Philosophie)
2026-08-29 23:06:35 +02:00
Agent Zero 559bba69a4 feat(L4-L5): KI-Steuerung + XRechnung-Format-Layer (EN16931/CII)
Check Cross-Plugin Imports / check (push) Has been cancelled
L5 Format-Layer (User-Klaerung: Verkaufsmodul spaeter, Format JETZT):
- einvoice.py: EN16931/XRechnung CII-XML-Generator (ElementTree, XML-Escaping gratis), Pflichtfeld-Validierung mit BT/BG-Codes, Decimal-kommerzielles Rounding, Header-Tax-Breakdown pro VAT-Satz, Profile en16931|xrechnung (XRechnung 3.0)
- POST /einvoice/render (inline->XML), /einvoice/validate (422 mit BT-Fehlliste), /einvoice/render-for (Contract-Resolver einvoice_data() — Andockpunkt Verkaufsmodul, 404 no_data_source ohne Beitrag)

L4 KI-Steuerung:
- POST /documents/suggest: Natuerliche Sprache -> Block-Komposition via zentralem llm_complete (Cost-Tracking, Tenant-Budget), Registry-Sanitizing (ungueltige KI-Bloecke gefiltert, IDs serverseitig), Code-Fence-Stripping, 502 ai_unavailable/invalid_ai_response
- Frontend: KI-Vorschlag-Panel im PrintTemplateEditor (Sparkles-Icon, Prompt-Textarea, Bloecke werden angehaengt), i18n de/en

TDD: Rot 25 failed -> Gruen 25/25 (Validierung, XML-Struktur/Escaping/Summen, Contract-Mocks, API 200/422/403/404, Suggest Mock-LLM/Fence/502). tsc exit 0, Build OK, ruff clean. Doku: api-documentation.md, plugin-development-guide.md (einvoice_data-Contract), PROGRESS.md
2026-08-29 18:05:55 +02:00
Agent Zero b311ab7aa1 feat(L1-L3): Dokumente-Generator — Briefpapier+Block-System+Drag&Drop-Editor+Renderer
Check Cross-Plugin Imports / check (push) Has been cancelled
- Briefpapier (letterheads): Seiten-Setup (A4/A5/Letter, Ränder), Header/Footer-Blöcke, Wasserzeichen, Logo-Upload (DocumentAsset, data:-URI-only)
- Druckvorlagen (print_templates): Block-Komposition mit Briefpapier-Ref + entity_type
- Block-Registry (document_blocks.py): text/image/shape(line/rect/circle)/table/spacer/divider/placeholder/pagebreak + Modul-Beiträge via document_blocks()-Contract
- Renderer (document_renderer.py): Blocks→HTML→PDF via WeasyPrint (SSRF-Sandbox data:-URI-only), @page-Frame mit running header/footer, Placeholder-Beispiel-Defaults gegen StrictUndefined
- Contract-Beitrag contacts: document_placeholders/document_data (#359-Muster wie importexport_entities)
- 13 neue Endpoints in documents.py: Letterhead-CRUD, Template-CRUD, Assets, document-blocks, document-placeholders, preview (HTML), render (PDF)
- Migration: Plugin-SQL 0003 (idempotent) + Alembic 0143 (Dual-Path, RLS fail-closed crm_api)
- Frontend: api/documents.ts, Settings→Dokumente (settings_pages), BlockEditor (@dnd-kit Palette/Canvas/Config/Live-Preview-iframe), LetterheadEditor, PrintTemplateEditor, DocumentGenerationDialog (global, ContactDetailPage-Integration)
- i18n de/en, api-documentation.md, plugin-development-guide.md, PROGRESS.md

Verifikation: 32/32 neue Tests + 9/9 Regressionen, tsc exit 0, Build OK 2.79s, Alembic-Fresh-DB 0143 mit RLS bewiesen, ruff clean
2026-08-29 09:49:16 +02:00
Agent Zero fa429c3a88 docs(progress): Paket-6-Eintrag + offene Findings gepflegt (Frontend-Vorbestand erledigt, neuer Core-FK-Vorbestandsfund: entity_attachments.dms_file_id -> files blockiert alembic check) 2026-08-29 02:52:42 +02:00
Agent Zero 67c0dcd34c feat(#357): Paket 6 — Contact-Model ins ContactsPlugin (physischer Move + PEP-562-Lazy-Re-Export-Bruecke, ALEMBIC_OWNED_TABLES gegen Schema-Dual-Ownership, outbox-Vorbestands-Fix in models/__init__)
Check Cross-Plugin Imports / check (push) Has been cancelled
2026-08-29 02:48:31 +02:00
Agent Zero df85fdcb5b feat(#358): Paket 5 — statische /contacts-Routen entfernt nach bewiesenem PluginRouteRenderer (nested Routes, :id-Matching, useParams), Contacts-Seiten in STATIC_COMPONENT_MAP (ARCH-019) 2026-08-29 02:10:32 +02:00
Agent Zero b5036a1fc0 feat(#357): custom_field_definitions generisch — W4b-Muster (422/403-Entity-Checks, {items,total}-Shape, ACL-Fix), zentrale Helper, Plural-Ableitungs-Fix 2026-08-29 01:27:24 +02:00
Agent Zero 36dd7c5101 test(#357): Router-Test gefixt (QueryClientProvider+Mocks, 2/2 passed); Geister-Test ContactEditModal nach §10 gelöscht (Komponente weg seit db4701b) 2026-08-28 23:38:01 +02:00
Agent Zero d9ca8af7e0 docs(progress): Weitermachen-Block fuer naechstes Modell ergaenzt — 7 offene Pakete mit Live-Messung + Repro-Steps, Offene-Findings aktualisiert 2026-08-28 22:49:40 +02:00
Agent Zero 20ff5e2142 feat(#358): W3c — /contacts Sidebar-Sonderfall entfernt (P10)
Check Cross-Plugin Imports / check (push) Has been cancelled
- ContactsPlugin-Manifest: menu_items + page_routes ergänzt
  (/contacts, /contacts/:id, /contacts/dedup — contacts:read-Gate)
- FrontendMenuItem/FrontendPageRoute-Imports in plugin.py ergänzt
- Sidebar.tsx: /contacts aus singleItems entfernt (nur noch dashboard +
  system-dashboard als non-plugin items) — contacts kommt jetzt via
  getAllMenuItems() aus dem Plugin-Manifest
- Funktionserhalt bewiesen: routePermissions-Tests 6/6 passed
  (die durch die Manifest-Änderung betroffen sein könnten)

fixes #358 (P10-Teil)
2026-08-28 22:08:46 +02:00
Agent Zero eebc2cf4de docs(roadmap): Phase L — Dokumente-Generator geplant (Briefpapier+Blöcke+Drag/Drop+KI+E-Rechnung, Basis: report_generator, Contract-Muster wie Import/Export) 2026-08-28 21:57:30 +02:00
Agent Zero ad848a5053 feat(#359): export_service.py konsolidiert — /export via ContactsContract
Check Cross-Plugin Imports / check (push) Has been cancelled
Der 78-Zeilen-Duplikat-Export (app/services/export_service.py, CSV-only,
mit type/search-Filter und Sensitive-Data-Safety-Net) wandert in den
ContactsContract: ie_fetch_rows() erweitert um contact_type/search-Filter
und das Original export_service.py CSV-Profil (17 Spalten inkl.
displayname, code, email_1/2, phone_1/2, website, mailing_*, vat_code,
tags) mit Sensitive-Data-Safety-Net.

contacts/routes.py /export nutzt jetzt den Contract statt export_service.
app/services/export_service.py geloescht.

Funktionserhalt bewiesen: 15/15 tests/test_performance.py passed
(inkl. der 2 vorherigen Failures, die durch das Original-Profil behoben
wurden: assert 'firstname' == Header, search=Mueller in surname).

fixes #359 (export_service-Konsolidierung)
2026-08-28 20:31:27 +02:00
Agent Zero b7194f0d58 docs(progress): W4c Custom-Fields-Routen in ContactsPlugin migriert dokumentiert — Funktionserhalt 11/11 bewiesen (#357) 2026-08-28 13:25:44 +02:00
Agent Zero c6decf5556 feat(#357): W4c — Custom-Fields-Routen aus Core in ContactsPlugin migriert
Check Cross-Plugin Imports / check (push) Has been cancelled
Kritikpunkt 14: app/routes/custom_fields.py war 100% Contact-spezifisch
(importiert Contact, nutzt contacts:read/write, Route /{contact_id}/custom-fields)
aber lag als scheinbar generischer Core-Service.

Fix: Die komplette Logik (2 Endpoints GET/PATCH /{contact_id}/custom-fields,
_collect_custom_field_definitions, _merge_definitions_with_values) wandert in
app/plugins/builtins/contacts/routes.py (gleicher Router-Prefix /api/v1/contacts).
app/routes/custom_fields.py geloescht, main.py bereinigt.

generischer custom_field_definitions.py-Endpoint bleibt im Core (echtes Core-
Entity). Frontend-Endpoint-Shapes unveraendert.

Funktionserhalt bewiesen: 11/11 tests/test_custom_fields.py passed.

fixes #357 (W4c-Teil)
2026-08-28 13:20:54 +02:00
Agent Zero d7b3c7c1b5 chore: Root node_modules aus Repo entfernt + .gitignore ergänzt (versehentlich committet durch vitest-worker) 2026-08-28 12:42:09 +02:00
Agent Zero cd988d6163 fix: versehentlich committetes node_modules/.vite entfernt 2026-08-28 12:41:41 +02:00
Agent Zero 0d052ab604 fix(#357): Zwei bewiesene Vorbestand-Fixes
1. Saved-Views/Filters: invalid entity_type wirft jetzt 422 (FastAPI-
   Validierungs-Konvention) statt 400 — Test-Expectation war korrekt.
   Beweis: test_create_saved_filter_invalid_entity_returns_422 passed.

2. AppShell.test.tsx: useCurrentUser-Export im @/api/hooks-Mock ergaenzt
   (fehlt seit jeher — Vorbestand). Der urspruengliche 'No useCurrentUser
   export' Error ist weg.

fixes #357 (Vorbestand-Teil)
2026-08-28 12:41:25 +02:00
Agent Zero b7b7d41c0c feat(#357): W4b — Saved-Views/Filters von contacts:read entkoppelt
Check Cross-Plugin Imports / check (push) Has been cancelled
- ENTITY_PLUGIN_OWNERS-Registry: trackt, welches Plugin welche Entity registriert
- get_entity_read_permission(): leitet die modul-korrekte Permission ab
  (contacts -> contacts:read, tasks -> tasks:read, ...) mit Core-Fallback
- registry.activate(): uebergibt plugin_name an register_entity_model
- saved_views.py + saved_filters.py: statische contacts:read-Dependencies
  durch dynamische _check_entity_read() ersetzt — Saved Views/Filters fuer
  fremde Entities brauchen jetzt die richtige modul-spezifische Permission

Verifikation: 10/11 tests/test_saved_filters.py passed (1 Vorbestand-
Failure per Stash bewiesen), create_app OK, ruff modified-files gruen.

fixes #357 (W4b-Teil)
2026-08-28 12:07:57 +02:00
Agent Zero 9bb1dbae03 docs(progress): W3b Settings Contribution-Wahrheit dokumentiert — 3 Plugin-Duplikate aus hardcodedNavItems entfernt, Dashboard-Loader als Vite-Technik verifiziert 2026-08-28 07:14:14 +02:00
Agent Zero b1a75510d6 refactor(#358): W3b Settings Contribution-Wahrheit — hardcoded mail/ai/notifications Nav-Items entfernt (7 Plugins liefern settings_pages via Manifest, Dedup greift nicht mehr); Dashboard-Verify: Loader-Registry ist Vite-Code-Splitting-Technik, Widgets kommen via Manifest-API (Kritikpunkt 20a teilweise widerlegt) 2026-08-28 07:13:01 +02:00
Agent Zero 1acef9669a docs(progress): Suite-Isolation behoben (#357) — close_engine nullt globale Engines, Engine-Restore nach Teardown, ACL-Batch 130 passed 2026-08-28 00:03:03 +02:00
Agent Zero b691dd36c0 fix(#357): Suite-Isolation behoben — close_engine() nullt globale Engines
Mechanismus (Live-Messung): Die mail_app-Fixture in tests/test_rbac_comprehensive.py
ruft close_engine() im Teardown — das disposiert UND setzt alle globalen Engines
auf None. Jede nachfolgende Test-Suite brach mit 'relation "users" does not exist'.

Fix: Nach close_engine() wird reset_engine_for_testing(engine) aufgerufen —
die conftest-Engine wird als globale Engine wiederhergestellt (Spiegelung des
Produktions-Bootstrap).

Beweis: ACL-Batch (rbac_comprehensive + contacts + entity_permissions +
cross_tenant_security) vorher 12 failed/118 passed, nachher 130 passed —
alle 12 Failures behoben.

fixes #357 (Isolation-Teil)
2026-08-28 00:02:15 +02:00