decomposer: generate deliverable files for Define the normalized ingestion contract and pluggable source-connector interface for SCM, CMS, and other content sources.; Implement a GitHub SCM connector that conforms to the normalized ingestion contract and supports scoped full and incremental ingestion of Markdown, plain-text, and source files with webhook and revision metadata.; Implement a SharePoint CMS connector that conforms to the normalized ingestion contract and supports scoped full and incremental ingestion of PDF, DOCX, and HTML files with webhook and revision metadata.; Implement ingestion orchestration and triggers; Normalize, govern, and publish ingested content to the shared knowledge store.; Add deployment/configuration, tests, and documentation for the ingestion agent.; Validate end-to-end ingestion and downstream content availability.
Some checks failed
ci / test (push) Failing after 7s
Some checks failed
ci / test (push) Failing after 7s
This commit is contained in:
@@ -1,14 +1,11 @@
|
||||
from __future__ import annotations
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from .models import Document
|
||||
from .util import now
|
||||
|
||||
class GovernedPublisher:
|
||||
def __init__(self, store, audit, retention_days=30): self.store, self.audit, self.retention_days = store, audit, retention_days
|
||||
def publish(self, batch):
|
||||
if any(d.tenant_id != batch.tenant_id for d in batch.documents): raise PermissionError('tenant mismatch')
|
||||
self.store.upsert(batch.documents)
|
||||
self.audit.append({'tenant_id': batch.tenant_id, 'run_id': batch.run_id, 'action': 'publish', 'count': len(batch.documents), 'at': datetime.now(timezone.utc).isoformat()})
|
||||
def purge_expired_tombstones(self, docs):
|
||||
cutoff = datetime.now(timezone.utc) - timedelta(days=self.retention_days)
|
||||
ids = [d.document_id for d in docs if d.deleted and d.updated_at < cutoff]
|
||||
if ids: self.store.delete(ids, docs[0].tenant_id)
|
||||
return ids
|
||||
def publish(batch, publisher, tenant_id):
|
||||
accepted=[d for d in batch if d.tenant_id==tenant_id and d.acl.tenant_id==tenant_id and not d.deleted]
|
||||
publisher.upsert(accepted)
|
||||
return {"published":len(accepted),"rejected":len(batch)-len(accepted),"tenant_id":tenant_id,"at":now()}
|
||||
|
||||
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()}
|
||||
|
||||
Reference in New Issue
Block a user