mirror of
https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools.git
synced 2026-06-18 15:29:36 +00:00
- Rename all SalesMatic references to Dealix (ديل اي اكس) across frontend, backend, configs, and SVG logos - Add complete automated affiliate recruitment system with: - Job posting templates (Arabic/English) with ad variations for social media, LinkedIn, job boards - Full onboarding package: welcome guide, company profile, step-by-step guide, FAQ (60+ Q&A), targets & earnings - Sales scripts: phone calls, WhatsApp, in-person, email templates, objection handling (15+), closing techniques - Targeting guides: social media, AI tools, Google, LinkedIn, local business, referral strategies - Legal agreements: freelance contract, employment offer (10+ deals/month auto-hire), commission structure - AI chatbot for affiliates: config, knowledge base, conversation flows - Add professional sector presentations for 10 industries (healthcare, real estate, restaurants, retail, education, beauty, automotive, legal, construction, e-commerce) - Add Gold Guarantee system (30-day full refund) with terms and conditions - Add AI Sales Agents system: lead generation, WhatsApp/voice/email outreach, lead scoring, auto-booking - Add backend: Affiliate & AI Conversation models, API endpoints, Celery worker tasks - Update landing page with Gold Guarantee, Affiliate CTA, and AI Agents sections https://claude.ai/code/session_01KnJgK7RwyeCvRZTRThHtfU
215 lines
7.0 KiB
Python
215 lines
7.0 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy import select, func
|
|
from typing import Optional
|
|
from datetime import datetime, timezone
|
|
from pydantic import BaseModel, EmailStr
|
|
from uuid import UUID
|
|
import uuid
|
|
|
|
from app.database import get_db
|
|
from app.models.affiliate import AffiliateMarketer, AffiliatePerformance, AffiliateDeal, AffiliateStatus
|
|
|
|
router = APIRouter(prefix="/affiliates", tags=["affiliates"])
|
|
|
|
|
|
# ─── Schemas ─────────────────────────────────────────────
|
|
|
|
class AffiliateRegisterRequest(BaseModel):
|
|
full_name: str
|
|
full_name_ar: Optional[str] = None
|
|
email: EmailStr
|
|
phone: str
|
|
whatsapp: Optional[str] = None
|
|
city: Optional[str] = None
|
|
national_id: Optional[str] = None
|
|
|
|
|
|
class AffiliateResponse(BaseModel):
|
|
id: UUID
|
|
full_name: str
|
|
email: str
|
|
phone: str
|
|
status: str
|
|
referral_code: str
|
|
total_deals_closed: int
|
|
total_commission_earned: float
|
|
current_month_deals: int
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class AffiliateDealRequest(BaseModel):
|
|
client_company: str
|
|
client_contact: Optional[str] = None
|
|
client_phone: Optional[str] = None
|
|
client_email: Optional[str] = None
|
|
plan_type: str # basic, professional, enterprise
|
|
|
|
|
|
class AffiliatePerformanceResponse(BaseModel):
|
|
month: str
|
|
leads_generated: int
|
|
calls_made: int
|
|
meetings_booked: int
|
|
deals_closed: int
|
|
commission_earned: float
|
|
bonus_earned: float
|
|
payment_status: str
|
|
|
|
|
|
# ─── Commission Rates ────────────────────────────────────
|
|
|
|
COMMISSION_RATES = {
|
|
"basic": {"price": 299, "rate": 0.15},
|
|
"professional": {"price": 699, "rate": 0.20},
|
|
"enterprise": {"price": 1499, "rate": 0.25},
|
|
}
|
|
|
|
BONUS_TIERS = [
|
|
{"min_deals": 5, "bonus": 500},
|
|
{"min_deals": 10, "bonus": 1500},
|
|
{"min_deals": 15, "bonus": 3000},
|
|
]
|
|
|
|
|
|
def generate_referral_code() -> str:
|
|
return f"DLX-{uuid.uuid4().hex[:8].upper()}"
|
|
|
|
|
|
# ─── Endpoints ───────────────────────────────────────────
|
|
|
|
@router.post("/register", response_model=AffiliateResponse, status_code=status.HTTP_201_CREATED)
|
|
async def register_affiliate(data: AffiliateRegisterRequest, db: AsyncSession = Depends(get_db)):
|
|
"""Register a new affiliate marketer."""
|
|
existing = await db.execute(
|
|
select(AffiliateMarketer).where(AffiliateMarketer.email == data.email)
|
|
)
|
|
if existing.scalar_one_or_none():
|
|
raise HTTPException(status_code=400, detail="Email already registered")
|
|
|
|
affiliate = AffiliateMarketer(
|
|
full_name=data.full_name,
|
|
full_name_ar=data.full_name_ar,
|
|
email=data.email,
|
|
phone=data.phone,
|
|
whatsapp=data.whatsapp or data.phone,
|
|
city=data.city,
|
|
national_id=data.national_id,
|
|
status=AffiliateStatus.PENDING,
|
|
referral_code=generate_referral_code(),
|
|
)
|
|
db.add(affiliate)
|
|
await db.commit()
|
|
await db.refresh(affiliate)
|
|
return affiliate
|
|
|
|
|
|
@router.get("/{affiliate_id}", response_model=AffiliateResponse)
|
|
async def get_affiliate(affiliate_id: UUID, db: AsyncSession = Depends(get_db)):
|
|
"""Get affiliate details."""
|
|
result = await db.execute(
|
|
select(AffiliateMarketer).where(AffiliateMarketer.id == affiliate_id)
|
|
)
|
|
affiliate = result.scalar_one_or_none()
|
|
if not affiliate:
|
|
raise HTTPException(status_code=404, detail="Affiliate not found")
|
|
return affiliate
|
|
|
|
|
|
@router.post("/{affiliate_id}/activate", response_model=AffiliateResponse)
|
|
async def activate_affiliate(affiliate_id: UUID, db: AsyncSession = Depends(get_db)):
|
|
"""Activate an affiliate after onboarding."""
|
|
result = await db.execute(
|
|
select(AffiliateMarketer).where(AffiliateMarketer.id == affiliate_id)
|
|
)
|
|
affiliate = result.scalar_one_or_none()
|
|
if not affiliate:
|
|
raise HTTPException(status_code=404, detail="Affiliate not found")
|
|
|
|
affiliate.status = AffiliateStatus.ACTIVE
|
|
affiliate.onboarded_at = datetime.now(timezone.utc)
|
|
await db.commit()
|
|
await db.refresh(affiliate)
|
|
return affiliate
|
|
|
|
|
|
@router.post("/{affiliate_id}/deals", status_code=status.HTTP_201_CREATED)
|
|
async def submit_deal(
|
|
affiliate_id: UUID,
|
|
data: AffiliateDealRequest,
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
"""Submit a new deal for commission tracking."""
|
|
result = await db.execute(
|
|
select(AffiliateMarketer).where(AffiliateMarketer.id == affiliate_id)
|
|
)
|
|
affiliate = result.scalar_one_or_none()
|
|
if not affiliate:
|
|
raise HTTPException(status_code=404, detail="Affiliate not found")
|
|
|
|
if data.plan_type not in COMMISSION_RATES:
|
|
raise HTTPException(status_code=400, detail="Invalid plan type")
|
|
|
|
rate_info = COMMISSION_RATES[data.plan_type]
|
|
commission = rate_info["price"] * rate_info["rate"]
|
|
|
|
deal = AffiliateDeal(
|
|
affiliate_id=affiliate_id,
|
|
client_company=data.client_company,
|
|
client_contact=data.client_contact,
|
|
client_phone=data.client_phone,
|
|
client_email=data.client_email,
|
|
plan_type=data.plan_type,
|
|
plan_price=rate_info["price"],
|
|
commission_rate=rate_info["rate"],
|
|
commission_amount=commission,
|
|
)
|
|
db.add(deal)
|
|
|
|
# Update affiliate counters
|
|
affiliate.total_deals_closed += 1
|
|
affiliate.current_month_deals += 1
|
|
affiliate.total_commission_earned += commission
|
|
|
|
# Auto-employ if target reached (10 deals/month)
|
|
if affiliate.current_month_deals >= 10 and affiliate.status == AffiliateStatus.ACTIVE:
|
|
affiliate.status = AffiliateStatus.EMPLOYED
|
|
affiliate.employed_at = datetime.now(timezone.utc)
|
|
|
|
await db.commit()
|
|
return {"message": "Deal submitted successfully", "commission": commission}
|
|
|
|
|
|
@router.get("/{affiliate_id}/performance", response_model=list[AffiliatePerformanceResponse])
|
|
async def get_performance(affiliate_id: UUID, db: AsyncSession = Depends(get_db)):
|
|
"""Get affiliate performance history."""
|
|
result = await db.execute(
|
|
select(AffiliatePerformance)
|
|
.where(AffiliatePerformance.affiliate_id == affiliate_id)
|
|
.order_by(AffiliatePerformance.month.desc())
|
|
)
|
|
return result.scalars().all()
|
|
|
|
|
|
@router.get("/leaderboard/top")
|
|
async def get_leaderboard(limit: int = 10, db: AsyncSession = Depends(get_db)):
|
|
"""Get top performing affiliates."""
|
|
result = await db.execute(
|
|
select(AffiliateMarketer)
|
|
.where(AffiliateMarketer.status.in_([AffiliateStatus.ACTIVE, AffiliateStatus.EMPLOYED]))
|
|
.order_by(AffiliateMarketer.total_deals_closed.desc())
|
|
.limit(limit)
|
|
)
|
|
affiliates = result.scalars().all()
|
|
return [
|
|
{
|
|
"name": a.full_name,
|
|
"deals": a.total_deals_closed,
|
|
"commission": a.total_commission_earned,
|
|
"status": a.status.value,
|
|
}
|
|
for a in affiliates
|
|
]
|