mirror of
https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools.git
synced 2026-06-17 23:09:35 +00:00
- API routers, ACA modules, integrations (draft operators) - Docs, landing pages, scripts (launch readiness, scorecard) - Tests and CI workflow updates for Dealix Co-authored-by: Cursor <cursoragent@cursor.com>
186 lines
6.7 KiB
Python
186 lines
6.7 KiB
Python
"""Platform Services API — Growth Control Tower (no live external sends)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from fastapi import APIRouter, Body
|
|
|
|
from auto_client_acquisition.platform_services import (
|
|
build_proof_summary,
|
|
evaluate_action,
|
|
event_to_inbox_card,
|
|
execute_tool,
|
|
get_action_ledger,
|
|
get_service_catalog,
|
|
list_channels,
|
|
validate_event,
|
|
)
|
|
from auto_client_acquisition.innovation.proof_ledger import build_demo_proof_ledger
|
|
from auto_client_acquisition.platform_services.contact_import_preview import build_import_preview
|
|
from auto_client_acquisition.platform_services.identity_resolution import resolve_identity_demo
|
|
from auto_client_acquisition.platform_services.inbox_feed import build_inbox_feed
|
|
from auto_client_acquisition.platform_services.lead_form_ingest import ingest_lead_form
|
|
from auto_client_acquisition.platform_services.proof_overview import build_proof_overview
|
|
|
|
router = APIRouter(prefix="/api/v1/platform", tags=["platform_services"])
|
|
|
|
|
|
@router.get("/service-catalog")
|
|
async def service_catalog() -> dict[str, Any]:
|
|
return get_service_catalog()
|
|
|
|
|
|
@router.get("/services/catalog")
|
|
async def services_catalog_alias() -> dict[str, Any]:
|
|
"""Alias path for product docs compatibility."""
|
|
return get_service_catalog()
|
|
|
|
|
|
@router.get("/channels")
|
|
async def channels() -> dict[str, Any]:
|
|
return list_channels()
|
|
|
|
|
|
@router.post("/events/validate")
|
|
async def events_validate(payload: dict[str, Any] = Body(default_factory=dict)) -> dict[str, Any]:
|
|
return validate_event(payload or {})
|
|
|
|
|
|
@router.post("/events/ingest")
|
|
async def events_ingest(payload: dict[str, Any] = Body(default_factory=dict)) -> dict[str, Any]:
|
|
"""Validate normalized event and return inbox card — no persistence."""
|
|
v = validate_event(payload or {})
|
|
if not v["valid"]:
|
|
return {"ok": False, "errors": v["errors"], "approval_required": True}
|
|
ev = v.get("normalized") or {}
|
|
return {"ok": True, "event": ev, "card": event_to_inbox_card(ev), "approval_required": True}
|
|
|
|
|
|
@router.post("/actions/approve")
|
|
async def actions_approve(payload: dict[str, Any] = Body(default_factory=dict)) -> dict[str, Any]:
|
|
"""Record human approval/rejection in the in-memory action ledger — no live side effects."""
|
|
ledger = get_action_ledger()
|
|
action_id = str(payload.get("action_id") or payload.get("request_id") or "unspecified")
|
|
actor = str(payload.get("actor") or "operator")
|
|
approved = payload.get("approved")
|
|
is_approved = True if approved is None else bool(approved)
|
|
entry = ledger.append_decision(
|
|
tool="human_approval",
|
|
outcome="approved" if is_approved else "rejected",
|
|
detail={
|
|
"action_id": action_id,
|
|
"actor": actor,
|
|
"notes": payload.get("notes"),
|
|
},
|
|
)
|
|
return {
|
|
"ok": True,
|
|
"ledger_entry": entry,
|
|
"detail_ar": "سُجّل القرار في دفتر MVP — لا يُطلق إرسالاً أو دفعاً تلقائياً من هذا المسار.",
|
|
"approval_required": False,
|
|
}
|
|
|
|
|
|
@router.post("/actions/evaluate")
|
|
async def actions_evaluate_alias(payload: dict[str, Any] = Body(default_factory=dict)) -> dict[str, Any]:
|
|
"""Alias of ``POST /policy/evaluate`` for docs that refer to ``actions/evaluate``."""
|
|
return evaluate_action(
|
|
action=str(payload.get("action") or ""),
|
|
channel_id=str(payload.get("channel_id") or ""),
|
|
context=payload.get("context") if isinstance(payload.get("context"), dict) else {},
|
|
)
|
|
|
|
|
|
@router.post("/inbox/from-event")
|
|
async def inbox_from_event(
|
|
payload: dict[str, Any] = Body(default_factory=dict),
|
|
) -> dict[str, Any]:
|
|
event = payload.get("event") if isinstance(payload.get("event"), dict) else payload
|
|
merge = bool(payload.get("merge_demo_hint"))
|
|
return {"card": event_to_inbox_card(event or {}, merge_demo_hint=merge)}
|
|
|
|
|
|
@router.post("/policy/evaluate")
|
|
async def policy_evaluate(payload: dict[str, Any] = Body(default_factory=dict)) -> dict[str, Any]:
|
|
return evaluate_action(
|
|
action=str(payload.get("action") or ""),
|
|
channel_id=str(payload.get("channel_id") or ""),
|
|
context=payload.get("context") if isinstance(payload.get("context"), dict) else {},
|
|
)
|
|
|
|
|
|
@router.post("/tools/execute")
|
|
async def tools_execute(payload: dict[str, Any] = Body(default_factory=dict)) -> dict[str, Any]:
|
|
return execute_tool(str(payload.get("tool_name") or ""), payload.get("payload") if isinstance(payload.get("payload"), dict) else {})
|
|
|
|
|
|
@router.get("/proof/summary")
|
|
async def proof_summary() -> dict[str, Any]:
|
|
return build_proof_summary()
|
|
|
|
|
|
@router.get("/proof-ledger/demo")
|
|
async def proof_ledger_demo() -> dict[str, Any]:
|
|
"""Demo ledger events — same source as innovation demo."""
|
|
return build_demo_proof_ledger()
|
|
|
|
|
|
@router.get("/identity/resolve-demo")
|
|
async def identity_resolve_demo(
|
|
phone: str | None = None,
|
|
email: str | None = None,
|
|
company_hint: str | None = None,
|
|
) -> dict[str, Any]:
|
|
return resolve_identity_demo(phone=phone, email=email, company_hint=company_hint)
|
|
|
|
|
|
@router.get("/proof/overview")
|
|
async def proof_overview() -> dict[str, Any]:
|
|
return build_proof_overview()
|
|
|
|
|
|
@router.get("/inbox/feed")
|
|
async def inbox_feed() -> dict[str, Any]:
|
|
return build_inbox_feed()
|
|
|
|
|
|
@router.post("/contacts/import-preview")
|
|
async def contacts_import_preview(body: dict[str, Any] = Body(default_factory=dict)) -> dict[str, Any]:
|
|
return build_import_preview(body or {})
|
|
|
|
|
|
@router.get("/action-ledger/recent")
|
|
async def action_ledger_recent(limit: int = 50) -> dict[str, Any]:
|
|
lim = max(1, min(limit, 200))
|
|
return {"entries": get_action_ledger().recent(lim)}
|
|
|
|
|
|
@router.post("/ingest/lead-form")
|
|
async def ingest_lead_form_route(body: dict[str, Any] = Body(default_factory=dict)) -> dict[str, Any]:
|
|
return ingest_lead_form(body or {})
|
|
|
|
|
|
# --- Wave 4: draft payloads only (re-export from aca.integrations) ---
|
|
|
|
|
|
@router.post("/integrations/gmail/draft")
|
|
async def gmail_draft(payload: dict[str, Any] = Body(default_factory=dict)) -> dict[str, Any]:
|
|
from auto_client_acquisition.integrations.gmail_operator import build_gmail_draft_payload
|
|
|
|
return build_gmail_draft_payload(payload or {})
|
|
|
|
|
|
@router.post("/integrations/calendar/draft")
|
|
async def calendar_draft(payload: dict[str, Any] = Body(default_factory=dict)) -> dict[str, Any]:
|
|
from auto_client_acquisition.integrations.calendar_operator import build_calendar_draft_payload
|
|
|
|
return build_calendar_draft_payload(payload or {})
|
|
|
|
|
|
@router.post("/integrations/moyasar/payment-draft")
|
|
async def moyasar_payment_draft(payload: dict[str, Any] = Body(default_factory=dict)) -> dict[str, Any]:
|
|
from auto_client_acquisition.integrations.moyasar_draft import build_moyasar_payment_draft
|
|
|
|
return build_moyasar_payment_draft(payload or {})
|