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)
This commit is contained in:
Agent Zero
2026-08-28 20:31:27 +02:00
parent b7194f0d58
commit ad848a5053
3 changed files with 42 additions and 110 deletions
+9 -4
View File
@@ -35,7 +35,6 @@ from app.schemas.contact import (
ContactUpdate,
)
from app.services import contact_service, dedup_service
from app.services.export_service import export_service
router = APIRouter(prefix="/api/v1/contacts", tags=["contacts"])
@@ -99,14 +98,20 @@ async def export_contacts(
db: AsyncSession = Depends(get_db),
current_user: dict = Depends(require_permission("contacts:read")),
):
"""Stream contacts as CSV."""
"""Stream contacts as CSV (W4c: via ContactsContract, export_service.py removed)."""
tenant_id = uuid.UUID(current_user["tenant_id"])
user_id = uuid.UUID(current_user["user_id"])
is_admin = current_user.get("is_system_admin", False)
csv_data = await export_service.export_contacts_csv(
db, tenant_id, contact_type=type, search=search,
from app.plugins.builtins.contacts.contracts import ContactsContract
headers, rows = await ContactsContract.ie_fetch_rows(
db, tenant_id, "contacts",
user_id=user_id, is_system_admin=is_admin,
contact_type=type, search=search,
)
from app.services.import_export_helpers import write_csv
csv_data = write_csv(rows, headers).decode("utf-8")
return StreamingResponse(
io.StringIO(csv_data),
media_type="text/csv",