gateway/modules/datamodels/datamodelDataSource.py
2026-04-10 12:33:27 +02:00

95 lines
4 KiB
Python

# Copyright (c) 2025 Patrick Motsch
# All rights reserved.
"""DataSource and ExternalEntry models for external data integration.
DataSource links a UserConnection to an external path (SharePoint folder,
Google Drive folder, FTP directory, etc.) for agent-accessible data containers.
"""
from typing import Dict, Any, Optional
from pydantic import BaseModel, Field
from modules.datamodels.datamodelBase import PowerOnModel
from modules.shared.i18nRegistry import i18nModel
import uuid
@i18nModel("Datenquelle")
class DataSource(PowerOnModel):
"""Konfigurierte externe Datenquelle verknuepft mit einer UserConnection."""
id: str = Field(
default_factory=lambda: str(uuid.uuid4()),
description="Primary key",
json_schema_extra={"label": "ID"},
)
connectionId: str = Field(
description="FK to UserConnection",
json_schema_extra={"label": "Verbindungs-ID"},
)
sourceType: str = Field(
description="sharepointFolder, googleDriveFolder, outlookFolder, ftpFolder, clickupList (path under /team/...)",
json_schema_extra={"label": "Quellentyp"},
)
path: str = Field(
description="External path (e.g. '/sites/MySite/Documents/Reports')",
json_schema_extra={"label": "Pfad"},
)
label: str = Field(
description="User-visible label (often the last path segment)",
json_schema_extra={"label": "Bezeichnung"},
)
displayPath: Optional[str] = Field(
default=None,
description="Human-readable full path for UI (connection-relative, slash-separated)",
json_schema_extra={"label": "Anzeigepfad"},
)
featureInstanceId: Optional[str] = Field(
default=None,
description="Scoped to feature instance",
json_schema_extra={"label": "Feature-Instanz"},
)
mandateId: Optional[str] = Field(
default=None,
description="Mandate scope",
json_schema_extra={"label": "Mandanten-ID"},
)
userId: str = Field(
default="",
description="Owner user ID",
json_schema_extra={"label": "Benutzer-ID"},
)
autoSync: bool = Field(
default=False,
description="Automatically sync on schedule",
json_schema_extra={"label": "Auto-Sync"},
)
lastSynced: Optional[float] = Field(
default=None,
description="Last sync timestamp",
json_schema_extra={"label": "Letzter Sync"},
)
scope: str = Field(
default="personal",
description="Data visibility scope: personal, featureInstance, mandate, global",
json_schema_extra={"label": "Sichtbarkeit", "frontend_type": "select", "frontend_readonly": False, "frontend_required": False, "frontend_options": [
{"value": "personal", "label": {"en": "Personal", "de": "Persönlich"}},
{"value": "featureInstance", "label": {"en": "Feature Instance", "de": "Feature-Instanz"}},
{"value": "mandate", "label": {"en": "Mandate", "de": "Mandant"}},
{"value": "global", "label": {"en": "Global", "de": "Global"}},
]},
)
neutralize: bool = Field(
default=False,
description="Whether this data source should be neutralized before AI processing",
json_schema_extra={"label": "Neutralisieren", "frontend_type": "checkbox", "frontend_readonly": False, "frontend_required": False},
)
class ExternalEntry(BaseModel):
"""An item (file or folder) from an external data source."""
name: str = Field(description="Item name")
path: str = Field(description="Full path within the source")
isFolder: bool = Field(default=False, description="True if directory/folder")
size: Optional[int] = Field(default=None, description="File size in bytes")
mimeType: Optional[str] = Field(default=None, description="MIME type (files only)")
lastModified: Optional[float] = Field(default=None, description="Last modification timestamp")
metadata: Dict[str, Any] = Field(default_factory=dict, description="Provider-specific metadata")