arc/hesabixAPI/docs/BUSINESS_NOTIFICATION_SYSTEM.md
2026-04-14 19:34:55 +03:30

19 KiB
Executable file
Raw Permalink Blame History

📱 سیستم نوتیفیکیشن جامع کسب‌وکارها

📋 فهرست مطالب

  1. مقدمه
  2. معماری سیستم
  3. جداول دیتابیس
  4. نحوه استفاده
  5. مثال‌ها
  6. API Documentation

🎯 مقدمه

این سیستم یک راهکار جامع برای ارسال نوتیفیکیشن (پیامک و ایمیل) به مشتریان است که:

✅ برای هر کسب‌وکار: قالب‌های سفارشی
✅ برای هر رویداد: فاکتور، تعمیر، پرداخت، و...
✅ تایید خودکار با AI: جلوگیری از spam
✅ بدون نیاز به اعتبار: AI مدیریت می‌شود توسط سیستم
✅ قابل استفاده در همه بخش‌ها: فاکتور، تعمیرگاه، انبار، و...


🏗️ معماری سیستم

مراحل ارسال نوتیفیکیشن

┌─────────────┐
│  رویداد     │  مثلاً: ثبت فاکتور جدید
│ (Event)     │
└──────┬──────┘
       │
       ▼
┌─────────────────────────────┐
│ جستجوی قالب فعال           │
│ - business_id               │
│ - event_type                │
│ - channel (sms/email)       │
└──────┬──────────────────────┘
       │
       ▼
┌─────────────────────────────┐
│ بررسی محدودیت روزانه       │
│ - daily_limit check         │
└──────┬──────────────────────┘
       │
       ▼
┌─────────────────────────────┐
│ رندر قالب                   │
│ - جایگزینی {{ متغیرها }}   │
│ - اعمال فیلترها             │
└──────┬──────────────────────┘
       │
       ▼
┌─────────────────────────────┐
│ ارسال پیام                  │
│ - SMS Provider              │
│ - Email Provider            │
└──────┬──────────────────────┘
       │
       ▼
┌─────────────────────────────┐
│ ثبت لاگ و آمار              │
│ - notification_send_logs    │
│ - notification_daily_stats  │
└─────────────────────────────┘

Flow تایید قالب‌ها

[کسب‌وکار] ایجاد قالب
    ↓
[وضعیت: draft]
    ↓
ارسال برای تایید
    ↓
[وضعیت: pending_approval]
[صف: pending]
    ↓
────────────────────────────────
    AI Worker (هر 60 ثانیه)
────────────────────────────────
    ↓
بررسی محتوا:
  • Rule-based checks
  • Spam detection
  • LLM analysis
    ↓
┌─────────┬──────────┬───────────┐
│         │          │           │
│ Score>90│ 40<Score<90│ Score<40│
│         │          │           │
▼         ▼          ▼
[Approve] [Review]   [Reject]
[AI]      [Admin]    [Auto]
│         │          │
│         ▼          │
│    [مدیر سیستم]   │
│    تایید/رد       │
│         │          │
└─────────┴──────────┘
         │
         ▼
    [فعال شدن قالب]
    [is_active = TRUE]

📊 جداول دیتابیس

1. notification_event_types

تعریف انواع رویدادها و متغیرهای قابل استفاده

مثال رکوردها:

code name category requires_approval
invoice.created ثبت فاکتور فروش sales TRUE
repair_shop.received دریافت کالا repair_shop TRUE
payment.received دریافت پرداخت financial TRUE

2. business_notification_templates

قالب‌های هر کسب‌وکار

وضعیت‌های قالب:

  • draft: پیش‌نویس (غیرفعال)
  • pending_approval: در صف بررسی
  • approved: تایید شده (فعال)
  • rejected: رد شده
  • suspended: تعلیق شده

وضعیت تایید:

  • pending: در انتظار بررسی
  • ai_approved: تایید شده توسط AI
  • admin_approved: تایید شده توسط مدیر
  • rejected: رد شده

3. notification_moderation_queue

صف بررسی قالب‌ها

فیلدهای کلیدی:

  • ai_decision: approve, reject, review_required
  • ai_confidence: 0-100
  • ai_flags: لیست مشکلات یافت شده
  • admin_decision: approve, reject

4. notification_send_logs

لاگ کامل تمام ارسال‌ها

برای:

  • ردیابی ارسال‌ها
  • گزارش‌گیری
  • Debugging

5. notification_daily_stats

آمار روزانه برای Rate Limiting


🚀 نحوه استفاده

مرحله 1: ایجاد Event Types

python scripts/seed_notification_event_types.py

این اسکریپت 7 event type اولیه ایجاد می‌کند.

مرحله 2: اجرای Migration

alembic upgrade head

مرحله 3: ایجاد قالب توسط کسب‌وکار

API Call:

POST /api/v1/business-notifications/businesses/1/templates

{
  "code": "invoice_created_sms",
  "name": "پیامک ثبت فاکتور",
  "event_type": "invoice.created",
  "channel": "sms",
  "body": "سلام {{ customer_name }}، فاکتور {{ invoice_number }} به مبلغ {{ amount | format_currency }} ثبت شد. {{ business_name }}",
  "daily_limit": 100,
  "is_automated": true
}

Response:

{
  "data": {
    "id": 123,
    "code": "invoice_created_sms",
    "status": "draft",
    "message": "قالب ایجاد شد. برای فعال‌سازی باید آن را برای تایید ارسال کنید."
  }
}

مرحله 4: ارسال برای تایید

POST /api/v1/business-notifications/businesses/1/templates/123/submit-for-approval

قالب وارد صف می‌شود و:

  • ✅ اگر AI Worker فعال باشد → بررسی خودکار (کمتر از 1 دقیقه)
  • ⏳ اگر نیاز به بررسی داشته باشد → صف مدیر سیستم

مرحله 5: بررسی توسط AI Worker

# اجرای یک بار (تست)
python -m app.workers.notification_moderation_worker

# اجرای مداوم (production)
# این worker باید در background اجرا شود

خروجی:

🚀 شروع Notification Moderation Worker
✅ بررسی قالب 123 تکمیل شد
   Decision: approve
   Confidence: 95.0
   Flags: []

مرحله 6: ارسال نوتیفیکیشن

from app.services.business_notification_service import BusinessNotificationService

service = BusinessNotificationService(db)

result = service.send_to_person(
    business_id=1,
    person_id=customer.id,
    event_type="invoice.created",
    context={
        "invoice_number": "INV-2025-001",
        "customer_name": "علی احمدی",
        "amount": 1500000,
        "invoice_date": "1403/12/15",
        "due_date": "1403/12/30",
        "business_name": "فروشگاه پارس",
        "business_phone": "021-12345678"
    },
    triggered_by_user_id=user_id
)

💡 مثال‌های کاربردی

مثال 1: ارسال پیامک هنگام ثبت فاکتور

# در invoice_service.py، بعد از ایجاد فاکتور:

from app.services.business_notification_service import BusinessNotificationService

def create_invoice(...):
    # ... ایجاد فاکتور
    
    # ارسال نوتیفیکیشن
    try:
        notif_service = BusinessNotificationService(db)
        notif_service.send_to_person(
            business_id=business_id,
            person_id=invoice.person_id,
            event_type="invoice.created",
            context={
                "invoice_number": invoice.code,
                "customer_name": customer.name,
                "amount": float(invoice.total_amount),
                "invoice_date": invoice.document_date.isoformat(),
                "due_date": invoice.due_date.isoformat() if invoice.due_date else "",
            },
            triggered_by_user_id=user_id
        )
    except Exception as e:
        logger.error(f"خطا در ارسال نوتیفیکیشن: {e}")
        # ادامه می‌دهیم - عدم ارسال نوتیفیکیشن نباید مانع ثبت فاکتور شود

مثال 2: پیش‌نمایش قالب قبل از ذخیره

service = BusinessNotificationService(db)

preview = service.preview_template(
    business_id=1,
    template_id=123,
    sample_context={
        "customer_name": "علی احمدی",
        "invoice_number": "INV-001",
        "amount": 1500000
    }
)

print("متن نهایی:")
print(preview["rendered"]["body"])
# خروجی: سلام علی احمدی، فاکتور INV-001 به مبلغ 1,500,000 تومان ثبت شد.

مثال 3: ایجاد قالب با فیلترهای Jinja2

body = """
سلام {{ customer_name }} عزیز،

فاکتور شماره {{ invoice_number }} در تاریخ {{ invoice_date | format_date('%Y/%m/%d') }} ثبت شد.

مبلغ: {{ amount | format_currency('تومان') }}
سررسید: {{ due_date | format_date }}

لطفاً تا {{ days_remaining }} روز دیگر پرداخت فرمایید.

{{ business_name }}
"""

# فیلترهای موجود:
# - format_number: 1500000 → 1,500,000
# - format_date: datetime → 1403/12/15
# - format_currency: 1500000 → 1,500,000 تومان

🔐 امنیت و جلوگیری از Spam

سطوح بررسی

1️⃣ Rule-based Checks

  • طول محتوا (10-1000 کاراکتر)
  • استفاده صحیح از متغیرها
  • Syntax قالب

2️⃣ Spam Detection

کلمات ممنوع:

  • تخفیف ویژه، فقط امروز، رایگان
  • کلیک کنید، همین حالا، محدود
  • جایزه، مسابقه، قرعه‌کشی

Pattern های مشکوک:

  • \d+%\s*تخفیف → 50% تخفیف
  • فقط\s+\d+\s+روز → فقط 3 روز
  • تعداد زیاد لینک
  • استفاده بیش از حد از emoji/علامت تعجب

3️⃣ AI Review (با LLM)

  • تشخیص محتوای تبلیغاتی
  • شناسایی spam patterns پیچیده
  • بررسی تطابق با event_type
  • پیشنهادات بهبود

تصمیم‌گیری خودکار

Score Confidence تصمیم AI اقدام نهایی
> 90 High ✅ Approve فعال‌سازی خودکار
70-90 Medium ⏳ Review ارسال به مدیر
40-70 Low ⚠️ Review ارسال به مدیر با اولویت
< 40 Very Low ❌ Reject رد خودکار

📡 API Documentation

برای کسب‌وکار

دریافت لیست event types

GET /api/v1/business-notifications/event-types?category=sales

لیست قالب‌ها

GET /api/v1/business-notifications/businesses/{business_id}/templates

ایجاد قالب

POST /api/v1/business-notifications/businesses/{business_id}/templates
Content-Type: application/json

{
  "code": "unique_code",
  "name": "نام قالب",
  "event_type": "invoice.created",
  "channel": "sms",
  "body": "محتوا با {{ متغیرها }}",
  "daily_limit": 100
}

پیش‌نمایش قالب

POST /api/v1/business-notifications/businesses/{business_id}/templates/{id}/preview
Content-Type: application/json

{
  "sample_context": {
    "customer_name": "علی احمدی",
    "invoice_number": "INV-001"
  }
}

ارسال نوتیفیکیشن

POST /api/v1/business-notifications/businesses/{business_id}/send
Content-Type: application/json

{
  "person_id": 123,
  "event_type": "invoice.created",
  "context": {
    "invoice_number": "INV-001",
    "amount": 1500000
  }
}

مشاهده لاگ‌ها

GET /api/v1/business-notifications/businesses/{business_id}/logs?channel=sms&status=sent

برای مدیر سیستم

صف بررسی

GET /api/v1/admin/notification-moderation/queue?status=admin_reviewing

آمار صف

GET /api/v1/admin/notification-moderation/queue/stats

تایید قالب

POST /api/v1/admin/notification-moderation/queue/{queue_id}/approve
Content-Type: application/json

{
  "notes": "قالب مناسب است"
}

رد قالب

POST /api/v1/admin/notification-moderation/queue/{queue_id}/reject
Content-Type: application/json

{
  "reason": "محتوا تبلیغاتی است",
  "notes": "از کلمات 'تخفیف ویژه' استفاده نکنید"
}

🔧 تنظیمات و راه‌اندازی

تنظیمات AI (استفاده از AIService موجود)

توجه مهم: این سیستم از AIService موجود در نرم‌افزار استفاده می‌کند.

✅ مزایا:

  • یکپارچه با سیستم موجود
  • استفاده از تنظیمات OpenAI موجود
  • بدون نیاز به نصب Ollama
  • مدیریت یکپارچه اعتبار

✅ نحوه کار:

  • از اعتبار سیستم استفاده می‌کند (نه کاربر)
  • تنها superadmin ها بدون محدودیت از AI استفاده می‌کنند
  • هزینه moderation بر عهده سیستم است (رایگان برای کسب‌وکارها)

✅ پیش‌نیاز:

  • تنظیمات AI در پنل مدیر فعال باشد
  • حداقل یک کاربر superadmin وجود داشته باشد

راه‌اندازی Worker

# در production، با supervisor یا systemd:

[program:notification_moderation_worker]
command=python -m app.workers.notification_moderation_worker
directory=/var/www/ark/hesabixAPI
autostart=true
autorestart=true
user=www-data

📈 گزارشات و آمار

آمار روزانه

from adapters.db.repositories.business_notification_repo import NotificationDailyStatRepository
from datetime import date, timedelta

stat_repo = NotificationDailyStatRepository(db)
stats = stat_repo.get_stats(
    business_id=1,
    from_date=date.today() - timedelta(days=30),
    to_date=date.today()
)

for stat in stats:
    print(f"{stat.date}: {stat.total_sent} sent, {stat.total_failed} failed")

لاگ‌های ارسال

from adapters.db.repositories.business_notification_repo import NotificationSendLogRepository

log_repo = NotificationSendLogRepository(db)
logs, total = log_repo.list_by_business(
    business_id=1,
    filters={"status": "failed", "channel": "sms"},
    offset=0,
    limit=50
)

🛡️ امنیت

محدودیت‌ها

  1. Daily Limit: هر قالب حداکثر X ارسال در روز
  2. Template Approval: قالب‌ها قبل از فعال شدن بررسی می‌شوند
  3. Content Filtering: محتوای تبلیغاتی و spam فیلتر می‌شود
  4. Audit Trail: تمام ارسال‌ها ثبت می‌شوند

Best Practices

✅ DO:

  • از متغیرها استفاده کنید: {{ customer_name }}
  • پیام‌های کوتاه و واضح بنویسید
  • اطلاعات تماس کسب‌وکار را اضافه کنید

❌ DON'T:

  • از کلمات تبلیغاتی استفاده نکنید
  • محتوای طولانی ننویسید (SMS < 200 کاراکتر)
  • لینک‌های زیاد نگذارید

🔄 یکپارچه‌سازی با بخش‌های دیگر

فاکتور (Invoice)

# در invoice_service.py

from app.services.business_notification_service import BusinessNotificationService

def create_invoice(...):
    # ... ایجاد فاکتور
    
    # ارسال نوتیفیکیشن
    notif_service = BusinessNotificationService(db)
    notif_service.send_to_person(
        business_id=business_id,
        person_id=invoice.person_id,
        event_type="invoice.created",
        context={...},
        triggered_by_user_id=user_id
    )

تعمیرگاه (Repair Shop)

# در repair_shop_service.py

from app.services.repair_shop_notification import send_repair_notification

def create_repair_order(...):
    # ... ایجاد سفارش
    
    # ارسال نوتیفیکیشن
    send_repair_notification(
        db=db,
        business_id=business_id,
        repair_order=order,
        event_type="repair_shop.received",
        triggered_by_user_id=user_id
    )

پرداخت (Payment)

from app.services.business_notification_service import BusinessNotificationService

def record_payment(...):
    # ... ثبت پرداخت
    
    notif_service = BusinessNotificationService(db)
    notif_service.send_to_person(
        business_id=business_id,
        person_id=payment.person_id,
        event_type="payment.received",
        context={...}
    )

🎨 متغیرها و فیلترها

متغیرهای رایج

متغیر توضیح مثال
{{ customer_name }} نام مشتری علی احمدی
{{ business_name }} نام کسب‌وکار فروشگاه پارس
{{ business_phone }} تلفن کسب‌وکار 021-12345678
{{ invoice_number }} شماره فاکتور INV-2025-001
{{ amount }} مبلغ 1500000

فیلترهای Jinja2

فیلتر کاربرد مثال
format_number جداکننده هزارگان {{ 1500000 | format_number }} → 1,500,000
format_currency فرمت مبلغ با ارز {{ amount | format_currency }} → 1,500,000 تومان
format_date فرمت تاریخ {{ date | format_date('%Y/%m/%d') }} → 1403/12/15

🐛 Troubleshooting

قالب تایید نمی‌شود

  1. بررسی لاگ‌های Worker
  2. اجرای دستی Worker برای debug
  3. بررسی صف در پنل مدیر

پیام ارسال نمی‌شود

  1. بررسی وجود قالب فعال
  2. بررسی محدودیت روزانه
  3. بررسی لاگ‌های ارسال
  4. بررسی تنظیمات SMS Provider

خطای Template Syntax

  • از {{ variable }} استفاده کنید (نه { variable })
  • متغیرها case-sensitive هستند
  • از پیش‌نمایش استفاده کنید

📞 پشتیبانی

برای سوالات و مشکلات:

  1. بررسی این مستند
  2. بررسی لاگ‌های سیستم
  3. تماس با تیم پشتیبانی