mirror of
https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools.git
synced 2026-06-18 15:29:36 +00:00
Platform Services Layer (10 modules) — برج التحكم بالنمو - event_bus: 27 typed events (whatsapp/email/calendar/lead/payment/review/social/partner/sheet/crm/action) - identity_resolution: cross-channel merge (phone+email+CRM+social) with confidence scoring - channel_registry: 11 channels (WA, Gmail, Calendar, Moyasar, LinkedIn, X, IG, GBP, Sheets, CRM, Forms) with capabilities/risk/PDPL notes - action_policy: 9 rules (block_cold_whatsapp, block_payment_no_confirm, block_secrets, external_send_needs_approval, calendar_insert_needs_approval, social_dm_needs_explicit, unknown_source_review, high_value_deal_review, draft_only_safe) - tool_gateway: single execution chokepoint, env-flag-gated live actions (default OFF) - unified_inbox: 8 card types, ≤3 buttons enforced, Arabic - action_ledger: requested→approved→executed audit trail - proof_ledger: leads/meetings/drafts/sends/payments/revenue/risks_blocked/time_saved per channel - service_catalog: 12 sellable services - router api/routers/platform_services.py — 13 endpoints under /api/v1/platform/ Intelligence Layer (10 modules) — الشبكة العصبية للنمو - growth_brain: per-customer Brain + is_ready_for_autopilot() (≥30 signals + ≥40% accept) - command_feed: 9 daily card types (opportunity/revenue_leak/partner_suggestion/meeting_prep/review_response/competitive_move/customer_reactivation/ai_visibility_alert/action_required) - action_graph: 10 typed edges (signal→action→outcome) with what_works_summary - mission_engine: 7 missions, KILL FEATURE first_10_opportunities (10 فرص في 10 دقائق) - decision_memory: learns from accept/skip/edit/block, returns preferences (channels, tones, sectors, rejected actions, accept_rate) - trust_score: composite 0-100 (source+opt_in+channel+content+freq+approval) → safe/needs_review/blocked - revenue_dna: best_channel/segment/angle + common_objection + avg_cycle_days - opportunity_simulator: 9 Saudi sectors, expected_replies/meetings/deals/pipeline_sar + risk_score - competitive_moves: 8 move types with Arabic recommended_action_ar - board_brief: weekly Founder Shadow Board (3 decisions + 3 opportunities + 3 risks + relationship + experiment + metric) - router api/routers/intelligence_layer.py — 12 endpoints under /api/v1/intelligence/ Tests - tests/unit/test_platform_services.py — 31 tests covering catalog/channels/events/policy/gateway/identity/inbox/ledger/proof - tests/unit/test_intelligence_layer.py — 29 tests covering brain/feed/graph/missions/memory/trust/dna/simulator/competitive/brief - 60/60 new tests pass; full suite 587 passed, 2 skipped Docs - docs/PLATFORM_SERVICES_STRATEGY.md (Arabic) - docs/INTELLIGENCE_LAYER_STRATEGY.md (Arabic) - docs/DEALIX_100_PERCENT_LAUNCH_PLAN.md — added §32 Platform Services + §33 Intelligence Layer Safety - No live send by default (all WA/Gmail/Calendar/Moyasar guarded by env flags, all OFF) - All external actions go through Tool Gateway → Action Policy → draft/approval_required - No secrets allowed in payloads (block_secrets policy) - PDPL-aware: cold WhatsApp without consent is hard-blocked - Existing 477+ tests untouched (no breaking changes) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
299 lines
9.9 KiB
Python
299 lines
9.9 KiB
Python
"""Unit tests for the Platform Services Layer."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from auto_client_acquisition.platform_services import (
|
|
ALL_CHANNELS,
|
|
EVENT_TYPES,
|
|
POLICY_RULES,
|
|
SELLABLE_SERVICES,
|
|
build_card_from_event,
|
|
build_demo_feed,
|
|
build_demo_platform_proof,
|
|
evaluate_action,
|
|
get_channel,
|
|
invoke_tool,
|
|
list_services,
|
|
make_event,
|
|
resolve_identity,
|
|
)
|
|
from auto_client_acquisition.platform_services.action_ledger import ActionLedger
|
|
from auto_client_acquisition.platform_services.channel_registry import channels_summary
|
|
from auto_client_acquisition.platform_services.unified_inbox import CARD_TYPES, InboxCard
|
|
|
|
|
|
# ── Service catalog ──────────────────────────────────────────
|
|
def test_service_catalog_returns_all_services():
|
|
out = list_services()
|
|
assert out["total"] == len(SELLABLE_SERVICES) >= 12
|
|
|
|
|
|
def test_service_catalog_includes_critical_services():
|
|
out = list_services()
|
|
keys = {s["key"] for s in out["services"]}
|
|
for required in (
|
|
"growth_operator_subscription", "channel_setup_service",
|
|
"lead_intelligence_service", "partnership_sprint",
|
|
"ai_visibility_aeo_sprint", "customer_success_operator",
|
|
):
|
|
assert required in keys
|
|
|
|
|
|
# ── Channel registry ─────────────────────────────────────────
|
|
def test_channels_include_core_channels():
|
|
keys = {c.key for c in ALL_CHANNELS}
|
|
for required in (
|
|
"whatsapp", "gmail", "google_calendar", "moyasar",
|
|
"linkedin_lead_forms", "x_api", "instagram_graph",
|
|
"google_business_profile", "google_sheets", "crm", "website_forms",
|
|
):
|
|
assert required in keys
|
|
|
|
|
|
def test_channels_summary_aggregates():
|
|
s = channels_summary()
|
|
assert s["total"] == len(ALL_CHANNELS)
|
|
assert "by_beta_status" in s and "by_risk_level" in s
|
|
|
|
|
|
def test_get_channel_unknown():
|
|
assert get_channel("bogus_channel") is None
|
|
|
|
|
|
def test_whatsapp_blocks_cold_send():
|
|
"""Channel registry asserts cold send is blocked."""
|
|
wa = get_channel("whatsapp")
|
|
assert wa is not None
|
|
assert "cold_send_without_consent" in wa.blocked_actions
|
|
|
|
|
|
# ── Event bus ────────────────────────────────────────────────
|
|
def test_event_types_include_payment_lifecycle():
|
|
for et in ("payment.initiated", "payment.paid", "payment.failed"):
|
|
assert et in EVENT_TYPES
|
|
|
|
|
|
def test_make_event_validates():
|
|
with pytest.raises(ValueError):
|
|
make_event(event_type="totally.fake", channel="whatsapp", customer_id="c")
|
|
|
|
|
|
def test_make_event_round_trip():
|
|
e = make_event(
|
|
event_type="lead.form_submitted", channel="website_forms",
|
|
customer_id="c", payload={"company": "X"},
|
|
)
|
|
d = e.to_dict()
|
|
assert d["event_type"] == "lead.form_submitted"
|
|
assert d["payload"]["company"] == "X"
|
|
|
|
|
|
# ── Action policy ────────────────────────────────────────────
|
|
def test_policy_blocks_cold_whatsapp():
|
|
d = evaluate_action(
|
|
action="send_whatsapp",
|
|
context={"source": "cold_list", "consent": False},
|
|
)
|
|
assert d.decision == "blocked"
|
|
|
|
|
|
def test_policy_blocks_payment_without_confirmation():
|
|
d = evaluate_action(
|
|
action="charge_payment",
|
|
context={"user_confirmed": False},
|
|
)
|
|
assert d.decision == "blocked"
|
|
|
|
|
|
def test_policy_blocks_secrets_in_payload():
|
|
d = evaluate_action(
|
|
action="create_draft",
|
|
context={"payload": {"api_key": "ghp_xxx"}},
|
|
)
|
|
assert d.decision == "blocked"
|
|
|
|
|
|
def test_policy_external_send_needs_approval():
|
|
d = evaluate_action(
|
|
action="send_email",
|
|
context={"approval_status": "pending"},
|
|
)
|
|
assert d.decision == "approval_required"
|
|
|
|
|
|
def test_policy_calendar_insert_needs_approval():
|
|
d = evaluate_action(
|
|
action="calendar_insert_event",
|
|
context={"approval_status": "pending"},
|
|
)
|
|
assert d.decision == "approval_required"
|
|
|
|
|
|
def test_policy_high_value_deal_review():
|
|
d = evaluate_action(
|
|
action="send_whatsapp",
|
|
context={
|
|
"deal_value_sar": 250_000, "approval_status": "approved",
|
|
"source": "existing_customer",
|
|
},
|
|
)
|
|
assert d.decision == "approval_required"
|
|
|
|
|
|
def test_policy_safe_internal_action_allowed():
|
|
d = evaluate_action(action="read_data", context={})
|
|
assert d.decision == "allow"
|
|
|
|
|
|
# ── Tool gateway ─────────────────────────────────────────────
|
|
def test_gateway_blocks_unsupported_tool():
|
|
r = invoke_tool(tool="bogus.action")
|
|
assert r.status == "unsupported"
|
|
|
|
|
|
def test_gateway_blocks_cold_whatsapp():
|
|
r = invoke_tool(
|
|
tool="whatsapp.send_message",
|
|
context={"source": "cold_list", "consent": False, "approval_status": "pending"},
|
|
)
|
|
assert r.status == "blocked"
|
|
|
|
|
|
def test_gateway_external_send_default_draft_only():
|
|
"""No live env flag → drafts even when policy allows."""
|
|
import os
|
|
os.environ.pop("WHATSAPP_ALLOW_LIVE_SEND", None)
|
|
r = invoke_tool(
|
|
tool="whatsapp.send_message",
|
|
context={
|
|
"source": "existing_customer", "consent": True,
|
|
"approval_status": "approved",
|
|
},
|
|
)
|
|
# Either draft_created (no flag) or approval_required (defensive)
|
|
assert r.status in ("draft_created", "approval_required")
|
|
|
|
|
|
def test_gateway_internal_action_passes():
|
|
r = invoke_tool(tool="gmail.read_thread", context={})
|
|
assert r.status in ("draft_created", "approval_required")
|
|
|
|
|
|
def test_gateway_payment_charge_needs_confirmation():
|
|
r = invoke_tool(
|
|
tool="moyasar.refund",
|
|
context={"user_confirmed": False, "approval_status": "approved"},
|
|
)
|
|
assert r.status == "blocked"
|
|
|
|
|
|
# ── Identity resolution ──────────────────────────────────────
|
|
def test_identity_resolves_multi_signal():
|
|
out = resolve_identity(signals=[
|
|
{"phone": "+966500000001", "company": "X", "source": "wa"},
|
|
{"email": "x@example.sa", "company": "X", "source": "gmail"},
|
|
{"crm_id": "crm_1", "company": "X", "source": "crm"},
|
|
])
|
|
assert out.primary_phone == "+966500000001"
|
|
assert out.primary_email == "x@example.sa"
|
|
assert out.crm_id == "crm_1"
|
|
assert out.confidence > 0
|
|
assert "wa" in out.sources
|
|
|
|
|
|
def test_identity_empty_signals():
|
|
out = resolve_identity(signals=[])
|
|
assert out.confidence == 0
|
|
|
|
|
|
# ── Unified inbox ────────────────────────────────────────────
|
|
def test_inbox_card_validates_button_count():
|
|
with pytest.raises(ValueError):
|
|
InboxCard(
|
|
card_id="c", type="opportunity", channel="whatsapp",
|
|
title_ar="x", summary_ar="x", why_it_matters_ar="x",
|
|
recommended_action_ar="x", risk_level="low",
|
|
buttons_ar=("a", "b", "c", "d"), # 4 → invalid
|
|
)
|
|
|
|
|
|
def test_inbox_card_validates_card_type():
|
|
with pytest.raises(ValueError):
|
|
InboxCard(
|
|
card_id="c", type="bogus_type", channel="x",
|
|
title_ar="x", summary_ar="x", why_it_matters_ar="x",
|
|
recommended_action_ar="x", risk_level="low",
|
|
)
|
|
|
|
|
|
def test_build_card_from_event_payment_failed():
|
|
e = make_event(
|
|
event_type="payment.failed", channel="moyasar", customer_id="c",
|
|
payload={"customer_id": "c1", "amount_sar": 2999},
|
|
)
|
|
card = build_card_from_event(e)
|
|
assert card is not None
|
|
assert card.type == "payment"
|
|
assert len(card.buttons_ar) <= 3
|
|
|
|
|
|
def test_build_card_from_event_review_low_rating_high_risk():
|
|
e = make_event(
|
|
event_type="review.created", channel="google_business_profile",
|
|
customer_id="c", payload={"rating": 1, "text": "bad"},
|
|
)
|
|
card = build_card_from_event(e)
|
|
assert card is not None
|
|
assert card.risk_level == "high"
|
|
|
|
|
|
def test_demo_feed_arabic_and_buttons_capped():
|
|
feed = build_demo_feed()
|
|
assert feed["feed_size"] >= 5
|
|
for card in feed["cards"]:
|
|
assert len(card["buttons_ar"]) <= 3
|
|
# Has Arabic content somewhere
|
|
text = card["title_ar"] + card["summary_ar"]
|
|
assert any("" <= ch <= "ۿ" for ch in text)
|
|
|
|
|
|
def test_card_types_cover_inbox_cases():
|
|
assert {"opportunity", "email_lead", "whatsapp_reply", "payment",
|
|
"meeting_prep", "review_response", "partner_suggestion"}.issubset(set(CARD_TYPES))
|
|
|
|
|
|
# ── Action ledger ────────────────────────────────────────────
|
|
def test_action_ledger_append_and_summary():
|
|
led = ActionLedger()
|
|
led.append(
|
|
customer_id="c1", action_type="send_whatsapp",
|
|
channel="whatsapp", stage="requested",
|
|
)
|
|
led.append(
|
|
customer_id="c1", action_type="send_whatsapp",
|
|
channel="whatsapp", stage="approved",
|
|
)
|
|
s = led.summary("c1")
|
|
assert s["total"] == 2
|
|
assert s["by_stage"]["requested"] == 1
|
|
assert s["by_stage"]["approved"] == 1
|
|
|
|
|
|
def test_action_ledger_unknown_stage_raises():
|
|
led = ActionLedger()
|
|
with pytest.raises(ValueError):
|
|
led.append(customer_id="c1", action_type="x", channel="y", stage="bogus")
|
|
|
|
|
|
# ── Platform proof ledger ────────────────────────────────────
|
|
def test_platform_proof_demo_structure():
|
|
p = build_demo_platform_proof()
|
|
d = p.to_dict()
|
|
assert "totals" in d and "by_channel" in d
|
|
assert d["totals"]["leads_created"] > 0
|
|
assert d["totals"]["risks_blocked"] > 0
|
|
# Cross-channel coverage
|
|
assert "whatsapp" in d["by_channel"] or "gmail" in d["by_channel"]
|