This commit is contained in:
@@ -1,4 +1,33 @@
|
||||
"""KAB content ingestion agent."""
|
||||
from .models import Document, ConnectorConfig, SyncCursor
|
||||
from .models import (
|
||||
ACL,
|
||||
Change,
|
||||
ConnectorConfig,
|
||||
Document,
|
||||
IngestionRequest,
|
||||
IngestionResult,
|
||||
NormalizedDocument,
|
||||
Provenance,
|
||||
SourceDocument,
|
||||
SyncCursor,
|
||||
)
|
||||
from .github import GitHubConnector
|
||||
from .sharepoint import SharePointConnector
|
||||
from .orchestrator import Orchestrator, RunResult
|
||||
|
||||
__all__ = ["Document", "ConnectorConfig", "SyncCursor"]
|
||||
__all__ = [
|
||||
"ACL",
|
||||
"Change",
|
||||
"ConnectorConfig",
|
||||
"Document",
|
||||
"GitHubConnector",
|
||||
"IngestionRequest",
|
||||
"IngestionResult",
|
||||
"NormalizedDocument",
|
||||
"Orchestrator",
|
||||
"Provenance",
|
||||
"RunResult",
|
||||
"SharePointConnector",
|
||||
"SourceDocument",
|
||||
"SyncCursor",
|
||||
]
|
||||
|
||||
@@ -9,3 +9,14 @@ def publish(batch, publisher, tenant_id):
|
||||
def deletion(ids,publisher,tenant_id): publisher.delete(ids,tenant_id); return {"deleted":len(ids),"tenant_id":tenant_id,"at":now()}
|
||||
|
||||
def audit(event,run_id,tenant_id): return {"event":event,"run_id":run_id,"tenant_id":tenant_id,"at":now()}
|
||||
|
||||
class GovernedPublisher:
|
||||
def __init__(self, publisher, audit_log=None):
|
||||
self.publisher = publisher
|
||||
self.audit_log = audit_log if audit_log is not None else []
|
||||
|
||||
def publish(self, batch):
|
||||
for doc in getattr(batch, "documents", []):
|
||||
if getattr(doc, "tenant_id", None) != getattr(batch, "tenant_id", None):
|
||||
raise PermissionError("Tenant isolation failure")
|
||||
return publish(getattr(batch, "documents", []), self.publisher, batch.tenant_id)
|
||||
|
||||
@@ -3,10 +3,11 @@ from typing import Any
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ACL:
|
||||
tenant_id: str
|
||||
tenant_id: str = ""
|
||||
principals: tuple[str, ...] = ()
|
||||
groups: tuple[str, ...] = ()
|
||||
visibility: str = "restricted"
|
||||
public: bool = False
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Provenance:
|
||||
@@ -32,6 +33,21 @@ class Document:
|
||||
metadata: dict[str, Any] = field(default_factory=dict)
|
||||
deleted: bool = False
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class NormalizedDocument:
|
||||
document_id: str
|
||||
tenant_id: str
|
||||
title: str
|
||||
body: str
|
||||
mime_type: str
|
||||
source_path: str
|
||||
content_hash: str
|
||||
updated_at: Any
|
||||
acl: ACL
|
||||
provenance: dict[str, Any]
|
||||
metadata: dict[str, Any] = field(default_factory=dict)
|
||||
deleted: bool = False
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ConnectorConfig:
|
||||
connector_id: str
|
||||
@@ -55,3 +71,27 @@ class Change:
|
||||
revision: str | None = None
|
||||
event_id: str | None = None
|
||||
payload: dict[str, Any] = field(default_factory=dict)
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class IngestionRequest:
|
||||
source: str
|
||||
locator: str
|
||||
requested_by: str = "system"
|
||||
metadata: dict[str, Any] = field(default_factory=dict)
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class SourceDocument:
|
||||
identifier: str
|
||||
title: str
|
||||
body: str
|
||||
source: str
|
||||
url: str | None = None
|
||||
metadata: dict[str, Any] = field(default_factory=dict)
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class IngestionResult:
|
||||
document: Document | SourceDocument | None
|
||||
accepted: bool
|
||||
status: str
|
||||
reason: str | None = None
|
||||
published_url: str | None = None
|
||||
|
||||
Reference in New Issue
Block a user