- 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)
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)