feat: Complete code integration of modules (#18)

The complete code integration is done.

Co-authored-by: Sagnik <sagnik7896@gmail.com>
Reviewed-on: #18
This commit was merged in pull request #18.
This commit is contained in:
2026-04-12 19:20:14 +05:30
parent 248d92042f
commit 4645ff737b
27 changed files with 3393 additions and 50 deletions

View File

@@ -0,0 +1,26 @@
from __future__ import annotations
import pytest
from backend.oracle.persona_service import persona_service
@pytest.mark.asyncio
async def test_persona_plan_recommends_templates_for_pipeline_prompt() -> None:
plan = await persona_service.plan_for_prompt(
prompt="Show me a pipeline map and broker trend view for marina whales",
tenant_id="tenant_velocity",
actor_role="sales_director",
)
assert "tpl_pipeline_board_v2" in plan["recommendedTemplates"]
assert plan["canvasBlocks"][0]["type"] == "textCanvas"
@pytest.mark.asyncio
async def test_persona_render_uses_existing_prompt_files() -> None:
rendered = await persona_service.render_prompt(
prompt_name="qd_calculator",
variables={"lead_name": "Amina", "query": "Summarize buyer intent"},
)
assert rendered["promptName"] == "qd_calculator"
assert "Amina" in rendered["renderedPrompt"] or rendered["unresolvedVariables"] is not None

View File

@@ -0,0 +1,94 @@
from __future__ import annotations
from fastapi import FastAPI
from fastapi.testclient import TestClient
from backend.api.routes_catalyst import router
from backend.services.ad_network_service import BidAction, Platform
def _build_client() -> TestClient:
app = FastAPI()
async def _broadcast_live_event(*_args, **_kwargs):
return None
app.state.broadcast_live_event = _broadcast_live_event
app.include_router(router, prefix="/api/catalyst")
return TestClient(app)
def test_catalyst_campaigns_and_google_budget_routes(monkeypatch) -> None:
client = _build_client()
async def fake_list_campaigns(platform=None):
return [
type(
"Campaign",
(),
{
"id": "google-camp-001",
"name": "Search Investors",
"platform": Platform.GOOGLE,
"status": type("Status", (), {"value": "active"})(),
"daily_budget": 5000,
"spent": 0,
"objective": "SEARCH",
"bid_strategy": "TARGET_ROAS",
},
)()
]
async def fake_get_insights(**_kwargs):
return [
{
"campaign_id": "google-camp-001",
"spend": 2400,
"impressions": 120000,
"clicks": 4200,
"conversions": 38,
}
]
async def fake_update_budget(_payload):
return {"status": "ok", "platform": "google", "mode": "simulated"}
async def fake_update_bid_strategy(_payload):
return BidAction(
action_id="act-1",
campaign_id="google-camp-001",
platform=Platform.GOOGLE,
old_strategy="TARGET_CPA",
new_strategy="TARGET_ROAS",
target_value=8.5,
executed_at="2026-04-12T00:00:00Z",
)
monkeypatch.setattr("backend.api.routes_catalyst.ad_network_service.list_campaigns", fake_list_campaigns)
monkeypatch.setattr("backend.api.routes_catalyst.ad_network_service.get_insights", fake_get_insights)
monkeypatch.setattr("backend.api.routes_catalyst.ad_network_service.update_budget", fake_update_budget)
monkeypatch.setattr("backend.api.routes_catalyst.ad_network_service.update_bid_strategy", fake_update_bid_strategy)
campaigns = client.get("/api/catalyst/campaigns")
assert campaigns.status_code == 200
assert campaigns.json()["data"][0]["platform"] == "google"
assert campaigns.json()["data"][0]["conversions"] == 38
budget = client.put(
"/api/catalyst/budget",
json={"campaign_id": "google-camp-001", "platform": "google", "daily_budget": 6500},
)
assert budget.status_code == 200
assert budget.json()["data"]["platform"] == "google"
bid = client.put(
"/api/catalyst/bid-strategy",
json={
"campaign_id": "google-camp-001",
"platform": "google",
"strategy": "TARGET_ROAS",
"target_value": 8.5,
},
)
assert bid.status_code == 200
assert bid.json()["data"]["new_strategy"] == "TARGET_ROAS"

View File

@@ -0,0 +1,215 @@
from __future__ import annotations
from contextlib import asynccontextmanager
from datetime import datetime, timezone
from typing import Any
from fastapi import FastAPI
from fastapi.testclient import TestClient
from backend.api.routes_crm import analytics_router, crm_router
def _now() -> datetime:
return datetime.now(timezone.utc)
class FakeConn:
def __init__(self) -> None:
self.leads: dict[str, dict[str, Any]] = {}
self.chat_logs: dict[str, dict[str, Any]] = {}
async def execute(self, query: str, *args):
normalized = query.strip()
if "CREATE TABLE IF NOT EXISTS leads" in normalized or "CREATE TABLE IF NOT EXISTS chat_logs" in normalized:
return "CREATE"
if "CREATE INDEX IF NOT EXISTS" in normalized:
return "CREATE INDEX"
if normalized.startswith("DELETE FROM leads WHERE id = $1"):
existed = self.leads.pop(args[0], None)
return "DELETE 1" if existed else "DELETE 0"
raise AssertionError(f"Unexpected execute query: {query}")
async def fetchrow(self, query: str, *args):
normalized = query.strip()
if "INSERT INTO leads" in normalized:
row = {
"id": args[0],
"name": args[1],
"email": args[2],
"phone": args[3],
"source": args[4],
"notes": args[5],
"qualification": args[6],
"score": args[7],
"kanban_status": args[8],
"budget": args[9],
"unit_interest": args[10],
"metadata": {},
"created_at": _now(),
"updated_at": _now(),
}
self.leads[row["id"]] = row
return row
if normalized.startswith("UPDATE leads") and "SET kanban_status" in normalized:
lead = self.leads.get(args[0])
if not lead:
return None
lead["kanban_status"] = args[1]
lead["updated_at"] = _now()
if lead["score"] >= 90:
lead["qualification"] = "WHALE"
elif lead["score"] >= 70:
lead["qualification"] = "POTENTIAL"
elif lead["score"] >= 45:
lead["qualification"] = "HOT"
return lead
if normalized.startswith("UPDATE leads") and "RETURNING" in normalized:
lead = self.leads.get(args[0])
if not lead:
return None
lead.update(
{
"name": args[1],
"email": args[2],
"phone": args[3],
"source": args[4],
"notes": args[5],
"qualification": args[6],
"score": args[7],
"kanban_status": args[8],
"budget": args[9],
"unit_interest": args[10],
"updated_at": _now(),
}
)
return lead
if normalized.startswith("SELECT id FROM leads WHERE id = $1"):
lead = self.leads.get(args[0])
return {"id": lead["id"]} if lead else None
if "INSERT INTO chat_logs" in normalized:
row = {
"id": args[0],
"lead_id": args[1],
"sender": args[2],
"channel": args[3],
"content": args[4],
"metadata": {},
"created_at": _now(),
}
self.chat_logs[row["id"]] = row
return row
raise AssertionError(f"Unexpected fetchrow query: {query}")
async def fetch(self, query: str, *args):
normalized = query.strip()
if "FROM leads" in normalized and "GROUP BY source" not in normalized and "GROUP BY qualification" not in normalized:
rows = list(self.leads.values())
if "WHERE kanban_status = $1" in normalized:
rows = [row for row in rows if row["kanban_status"] == args[0]]
return rows
if "FROM chat_logs" in normalized:
rows = list(self.chat_logs.values())
if "WHERE lead_id = $1" in normalized:
rows = [row for row in rows if row["lead_id"] == args[0]]
return rows
if "GROUP BY source" in normalized:
grouped: dict[str, dict[str, Any]] = {}
for lead in self.leads.values():
slot = grouped.setdefault(lead["source"], {"source": lead["source"], "lead_count": 0, "avg_score": 0.0})
slot["lead_count"] += 1
slot["avg_score"] += float(lead["score"])
for slot in grouped.values():
slot["avg_score"] = slot["avg_score"] / slot["lead_count"]
return list(grouped.values())
if "GROUP BY qualification" in normalized:
grouped: dict[str, dict[str, Any]] = {}
for lead in self.leads.values():
slot = grouped.setdefault(lead["qualification"], {"qualification": lead["qualification"], "lead_count": 0})
slot["lead_count"] += 1
return list(grouped.values())
raise AssertionError(f"Unexpected fetch query: {query}")
class FakePool:
def __init__(self) -> None:
self.conn = FakeConn()
@asynccontextmanager
async def acquire(self):
yield self.conn
def _build_client() -> tuple[TestClient, FakePool]:
app = FastAPI()
pool = FakePool()
app.state.db_pool = pool
app.include_router(crm_router, prefix="/api")
app.include_router(analytics_router, prefix="/api/analytics")
return TestClient(app), pool
def test_crm_crud_and_analytics_flow() -> None:
client, _pool = _build_client()
create_response = client.post(
"/api/leads",
json={
"name": "Amina Rahman",
"email": "amina@example.com",
"phone": "+971500000001",
"source": "website",
"notes": "Cash buyer interested in marina penthouse",
"score": 92,
"kanban_status": "qualified",
"budget": "AED 12M",
"unit_interest": "Penthouse",
"metadata": {"campaign": "meta-velocity-marina"},
},
)
assert create_response.status_code == 201
lead_id = create_response.json()["data"]["id"]
list_response = client.get("/api/leads")
assert list_response.status_code == 200
assert list_response.json()["meta"]["count"] == 1
chat_response = client.post(
"/api/chat-logs",
json={
"lead_id": lead_id,
"sender": "oracle",
"channel": "whatsapp",
"content": "Lead requested a private marina walkthrough.",
"metadata": {"sentiment": "positive"},
},
)
assert chat_response.status_code == 201
board_response = client.get("/api/kanban/board")
assert board_response.status_code == 200
board = board_response.json()["data"]
qualifying_column = next(column for column in board if column["status"] == "Qualifying")
assert qualifying_column["count"] == 1
move_response = client.put("/api/kanban/move", json={"lead_id": lead_id, "target_status": "negotiation"})
assert move_response.status_code == 200
assert move_response.json()["data"]["kanban_status"] == "Negotiation"
scatter_response = client.get("/api/analytics/sentiment-scatter")
assert scatter_response.status_code == 200
scatter = scatter_response.json()
assert scatter[0]["qualification"] == "WHALE"
assert scatter[0]["kanban_status"] == "Negotiation"
def test_lead_demographics_groups_by_source_and_qualification() -> None:
client, _pool = _build_client()
client.post("/api/leads", json={"name": "Lead One", "source": "website", "score": 80})
client.post("/api/leads", json={"name": "Lead Two", "source": "walkin", "score": 45})
response = client.get("/api/leads/demographics")
assert response.status_code == 200
payload = response.json()["data"]
assert len(payload["by_source"]) == 2
assert any(row["qualification"] == "POTENTIAL" for row in payload["by_qualification"])

View File

@@ -0,0 +1,20 @@
from __future__ import annotations
import os
from fastapi.testclient import TestClient
os.environ.setdefault("VELOCITY_JWT_SECRET", "test-secret")
from backend.main import app
def test_crm_websocket_ack_roundtrip() -> None:
with TestClient(app) as client:
with client.websocket_connect("/ws/crm") as websocket:
first = websocket.receive_json()
assert first["type"] == "crm_presence"
websocket.send_text("ping")
second = websocket.receive_json()
assert second["type"] == "crm_ack"
assert second["data"] == "ping"

View File

@@ -0,0 +1,20 @@
from backend.services.mcp_registry import mcp_registry
from backend.services.nemoclaw_runtime import nemoclaw_runtime
def test_nemoclaw_runtime_builds_workflow_dispatch() -> None:
dispatch = nemoclaw_runtime.build_workflow_dispatch(
prompt="Build a marketing-ready Oracle canvas",
tenant_id="tenant_velocity",
actor_role="sales_director",
component_templates=["tpl_pipeline_board_v2"],
)
assert dispatch["runtime"] == "python_native_nemoclaw"
assert dispatch["workflow"] == "oracle_canvas_generation"
def test_mcp_registry_lists_root_python_tools() -> None:
tools = mcp_registry.list_tools()
names = {tool["name"] for tool in tools}
assert "crm_search" in names
assert "external_search" in names

View File

@@ -0,0 +1,64 @@
from __future__ import annotations
from fastapi import FastAPI
from fastapi.testclient import TestClient
from backend.api.routes_oracle import router
def _build_client() -> TestClient:
app = FastAPI()
app.state.db_pool = object()
async def _broadcast_crm_event(*_args, **_kwargs):
return None
app.state.broadcast_crm_event = _broadcast_crm_event
app.include_router(router, prefix="/api/oracle")
return TestClient(app)
def test_oracle_mcp_execute_and_writeback(monkeypatch) -> None:
client = _build_client()
async def fake_execute(tool_name, query, *, crm_pool=None):
return {"tool": tool_name, "query": query, "status": "ok", "results": [{"title": "Match"}]}
async def fake_apply_writeback(payload):
return {
"actionId": payload["action_id"],
"status": "applied",
"targetEntityType": payload["target_entity_type"],
"targetEntityId": payload["target_entity_id"],
"resultPayload": {"lead_id": payload["target_entity_id"], "score": 88},
}
async def fake_list_actions(*, status=None, limit=50):
return [{"actionId": "act-1", "status": status or "planned", "targetEntityType": "lead"}]
monkeypatch.setattr("backend.api.routes_oracle.mcp_registry.execute", fake_execute)
monkeypatch.setattr("backend.api.routes_oracle.oracle_action_service.apply_writeback", fake_apply_writeback)
monkeypatch.setattr("backend.api.routes_oracle.oracle_action_service.list_actions", fake_list_actions)
mcp_response = client.post(
"/api/oracle/mcp/execute",
json={"tool_name": "external_search", "query": "luxury marina inventory dubai"},
)
assert mcp_response.status_code == 200
assert mcp_response.json()["data"]["tool"] == "external_search"
writeback_response = client.post(
"/api/oracle/actions/writeback",
json={
"action_id": "act-1",
"target_entity_type": "lead",
"target_entity_id": "lead-1",
"writeback_payload": {"score_delta": 12},
},
)
assert writeback_response.status_code == 200
assert writeback_response.json()["data"]["status"] == "applied"
list_response = client.get("/api/oracle/actions")
assert list_response.status_code == 200
assert list_response.json()["meta"]["count"] == 1