arc/docs/CUSTOMER_CLUB_PLUGIN_PRODUCTION.md
2026-04-25 02:31:13 +03:30

150 lines
7.8 KiB
Markdown
Executable file
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# افزونه باشگاه مشتریان (Customer Club) — سند اجرایی تولید
این سند برای پیاده‌سازی **سطح تجاری و تولید (Production)** در محصول Hesabix تهیه شده است. معماری با الگوی افزونه‌های موجود (`product_warranty`, `repair_shop_management`) و بازار افزونه (`MarketplacePlugin` / `BusinessPlugin`) هم‌خوان است.
---
## ۱. هدف و محدوده
### ۱.۱ هدف
- افزایش وفاداری مشتری با **امتیازدهی خودکار** بر اساس فاکتور فروش و برگشت از فروش.
- مدیریت متمرکز **قوانین امتیاز**، **ماندهٔ امتیاز** بر اساس شخص (`Person`)، و **دفتر تراکنش** قابل حسابرسی.
### ۱.۲ محدودهٔ نسخهٔ اول (همین پیاده‌سازی)
| قابلیت | وضعیت |
|--------|--------|
| ثبت افزونه در بازار با کد ثابت `customer_club` | بله |
| تنظیمات برنامهٔ باشگاه به ازای هر کسب‌وکار | بله |
| امتیاز از فاکتور **فروش** (`invoice_sales`) و کسر متناسب از **برگشت از فروش** (`invoice_sales_return`) | بله |
| به‌روزرسانی امتیاز هنگام **ویرایش** فاکتور (هم‌تراز با مبلغ جدید) | بله |
| برگشت امتیاز هنگام **حذف** فاکتور | بله |
| رد شدن فاکتور **پیش‌فاکتور** (`is_proforma`) | بله |
| تراکنش دستی اصلاحی (با مجوز `adjust`) | بله |
| مصرف امتیاز در بدنهٔ فاکتور فروش (تخفیف از کیف امتیاز) | **خیر** (فاز بعد؛ نیاز به تغییر payload فاکتور و UI فروش) |
---
## ۲. معماری فنی
### ۲.۱ کد افزونه و لایسنس
- **کد بازار:** `customer_club`
- فعال‌سازی از طریق جدول `business_plugins` و رکورد `marketplace_plugins` (اسکریپت `scripts/add_customer_club_plugin.py`).
- تمام endpointهای اختصاصی باشگاه با `require_business_access` + وابستگی پلاگین (`customer_club_plugin_dependency`) محافظت می‌شوند.
### ۲.۲ مجوزهای کسب‌وکار (JSON در `business_permissions`)
| کلید سکشن | معنی |
|-----------|------|
| `customer_club` | باشگاه مشتریان |
| اکشن | کاربرد |
|------|--------|
| `view` | مشاهدهٔ داشبورد، مانده و لیست تراکنش‌ها (پیش‌نیاز سایر اکشن‌ها در UI) |
| `manage` | تغییر تنظیمات برنامهٔ امتیاز |
| `adjust` | ثبت تراکنش دستی اصلاحی در دفتر |
مالک کسب‌وکار (`isOwner`) طبق منطق موجود `AuthStore` به همه دسترسی دارد.
### ۲.۳ مدل داده
1. **`customer_club_settings`** — یک ردیف به ازای هر `business_id` (تنظیمات قوانین).
2. **`customer_club_balance`** — ماندهٔ تجمیعی امتیاز به ازای هر `(business_id, person_id)` با قفل ردیفی هنگام به‌روزرسانی.
3. **`customer_club_ledger`** — دفتر append-only با `delta_points`, `balance_after`, نوع تراکنش، ارجاع به سند.
4. **`customer_club_invoice_snapshot`** — آخرین امتیاز محاسبه‌شده برای هر `document_id` جهت **ایدمپوتنت** بودن همگام‌سازی با ویرایش فاکتور و حذف تمیز.
### ۲.۴ محاسبهٔ مبلغ مبنا
از `document.extra_info.totals` خوانده می‌شود:
- **`net`**: جمع بعد از تخفیف، قبل از مالیات (هم‌راستا با فیلدهای متداول گزارش‌ها).
- **`total_with_tax`**: در صورت انتخاب مبنا در تنظیمات، از `net + tax`، با تکیه بر همان شیء `totals`.
در نبود `totals`، از محاسبهٔ خطوط `InvoiceItemLine.extra_info` (همان منطق کمکی موجود در خدمات فاکتور) استفاده می‌شود.
### ۲.۵ دو حالت کسب امتیاز
| حالت (`earn_mode`) | فرمول |
|-------------------|--------|
| `percent_basis` | `points = basis_amount × (percent_of_basis / 100)` سپس گرد طبق `rounding` |
| `points_per_currency` | `points = (basis_amount / step_amount) × points_per_step` با گرد |
تنظیمات `rounding`: `floor` | `ceil` | `round`.
### ۲.۶ هوک‌های فاکتور (`invoice_service.py`)
| رویداد | رفتار |
|--------|--------|
| ایجاد فاکتور قطعی (فروش/برگشت) بعد از `on_sales_invoice_document_finalized` | `sync_customer_club_for_invoice` در همان تراکنش commitشدهٔ بلاک سود دفتر |
| به‌روزرسانی فاکتور قطعی بعد از سود دفتر | همان `sync_customer_club_for_invoice` قبل از `db.commit()` نهایی |
| حذف فاکتور قبل از `db.delete(document)` | `reverse_customer_club_on_invoice_delete` برای بازگرداندن مانده بر اساس snapshot |
خطاهای باشگاه **نباید** مانع ثبت حسابداری شوند؛ در صورت خطا فقط `warning` لاگ می‌شود (هم‌سبک workflow).
---
## ۳. API (خلاصه)
پیشوند پیشنهادی: `/api/v1/customer-club/business/{business_id}/...`
- `GET /settings` — نیاز به `view`
- `PUT /settings` — نیاز به `manage`
- `GET /persons/{person_id}/balance` — `view`
- `GET /ledger` — صفحه‌بندی، فیلتر `person_id` — `view`
- `POST /adjustments` — بدنه: `person_id`, `delta_points`, `description` — `adjust`
پاسخ‌ها با `success_response` و در صورت نیاز `format_datetime_fields`.
---
## ۴. فرانت‌اند (Flutter)
- مسیرها زیر شِل کسب‌وکار: `/business/:id/customer-club` (داشبورد با تب‌ها)، `/customer-club/settings`.
- منوی کناری: نمایش فقط اگر پلاگین فعال و `customer_club.view`.
- صفحهٔ دسترسی‌ها: گروه «باشگاه مشتریان» با اکشن‌های `view`, `manage`, `adjust`.
---
## ۵. استقرار (Operations)
1. اجرای مهاجرت Alembic برای جداول جدید.
2. اجرای اسکریپت ثبت افزونه در بازار (یا ثبت دستی معادل در پنل ادمین بازار در صورت وجود).
3. اعطای مجوز به نقش‌ها از مسیر کاربران کسب‌وکار.
4. پایش لاگ برای خطاهای غیرمسدودکنندهٔ باشگاه پس از استقرار.
---
## ۶. پیروی از مقررات و حسابرسی
- تمام تغییرات مانده از طریق `ledger` با `balance_after` ثبت می‌شود.
- تراکنش‌های دستی با نوع `adjustment` و توضیح الزامی در API.
---
## ۷. نقشهٔ راه بعدی (خارج از این نسخه)
- مصرف امتیاز در فاکتور فروش و جلوگیری از ماندهٔ منفی.
- سطح‌بندی (Tier) و کمپین‌ها.
- اعلان خودکار و اتصال به Workflow برای پیامک/ایمیل.
---
**نسخهٔ سند:** ۱.۰ — هم‌تراز با پیاده‌سازی مخزن در تاریخ ایجاد فایل.
---
## ۸. دستورات استقرار (خلاصهٔ عملیاتی)
در ریشهٔ پروژهٔ API (`hesabixAPI`):
```bash
cd hesabixAPI
alembic upgrade head
python scripts/add_customer_club_plugin.py
```
سپس اپلیکیشن وب و API را طبق روال استقرار شما بازنشانی کنید.
پس از استقرار، از مسیر «کاربران و دسترسی‌ها» برای نقش‌های غیرمالک، دسترسی‌های `customer_club.view`، `manage` و در صورت نیاز `adjust` را فعال کنید.