docs: add pipeline merge design spec
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
# ادغام کاریز (مسیر فروش)
|
||||
|
||||
تاریخ: ۲۰۲۶-۱۰-۱۲
|
||||
وضعیت: تأییدشده توسط کاربر
|
||||
|
||||
## هدف
|
||||
|
||||
ادغام یک کاریز مبدأ در کاریز مقصد با نگاشت دستی ستونها، بهروزرسانی وابستگیها، و حذف کاریز مبدأ — بدون از دست رفتن معامله یا قطع بیخبر اتصالها.
|
||||
|
||||
## محدوده
|
||||
|
||||
- فقط مسیر فروش (Pipeline / Deal)، نه بُرد پروژه یا میز کار.
|
||||
- محل ورود: تنظیمات مسیر فروش → مدیریت کاریزها → «ادغام کاریز».
|
||||
- دسترسی: همان نقشهایی که کاریز میسازند (`canManageSettings`).
|
||||
|
||||
## خارج از محدوده (نسخهٔ اول)
|
||||
|
||||
- ادغام خودکار ستونها بر اساس نام.
|
||||
- بازنویسی اتوماسیونها (فعلاً شناسهٔ کاریز/ستون معامله را نگه نمیدارند).
|
||||
- مهاجرت فیلترهای ذخیرهشدهٔ سمت کلاینت (پس از ادغام، UI روی مقصد میماند).
|
||||
|
||||
## جریان UI (ویزارد)
|
||||
|
||||
1. **مبدأ و مقصد:** انتخاب دو کاریز؛ مبدأ ≠ مقصد؛ حداقل یک کاریز دیگر برای مقصد لازم است.
|
||||
2. **پیشنمایش وابستگیها:** تعداد معاملات، تعداد فرمهای سرنخ متصل، آیا مبدأ پیشفرض است.
|
||||
3. **نگاشت ستونها:** برای هر ستون مبدأ یک ستون مقصد اجباری است.
|
||||
- ستون `isWon` مبدأ فقط به ستون `isWon` مقصد.
|
||||
- ستون `isLost` مبدأ فقط به ستون `isLost` مقصد.
|
||||
- بقیه به ستونهای باز (غیر برد/باخت) مقصد.
|
||||
4. **فرمهای سرنخ:** نسخهٔ اول فقط حالت `retarget_all` — همهٔ فرمهای متصل به مبدأ به مقصد منتقل میشوند. در پیشنمایش نام فرمها نشان داده میشود تا کاربر بداند چه چیزی جابهجا میشود.
|
||||
5. **پیشفرض:** اگر مبدأ `isDefault` است، پس از ادغام مقصد پیشفرض میشود.
|
||||
6. **تأیید:** خلاصهٔ قابلخواندن + اجرای عمل.
|
||||
|
||||
اگر صفحهٔ «تنظیمات مسیر فروش / مدیریت کاریزها» هنوز وجود ندارد، در همین کار اضافه میشود (لیست کاریزها، ساخت، و دکمهٔ ادغام).
|
||||
|
||||
## API
|
||||
|
||||
### پیشنمایش
|
||||
|
||||
`GET /pipelines/:sourceId/merge-preview`
|
||||
|
||||
پاسخ نمونه:
|
||||
|
||||
```json
|
||||
{
|
||||
"source": { "id": "...", "name": "...", "isDefault": false },
|
||||
"stages": [{ "id": "...", "name": "...", "isWon": false, "isLost": false, "dealCount": 12 }],
|
||||
"dealCount": 42,
|
||||
"leadForms": [{ "id": "...", "name": "...", "isActive": true }],
|
||||
"targets": [{ "id": "...", "name": "...", "isDefault": true, "stages": [...] }]
|
||||
}
|
||||
```
|
||||
|
||||
### اجرا
|
||||
|
||||
`POST /pipelines/:sourceId/merge`
|
||||
|
||||
بدنه:
|
||||
|
||||
```json
|
||||
{
|
||||
"targetPipelineId": "...",
|
||||
"stageMap": { "<sourceStageId>": "<targetStageId>" },
|
||||
"leadFormMode": "retarget_all"
|
||||
}
|
||||
```
|
||||
|
||||
همه در یک تراکنش Prisma:
|
||||
|
||||
1. اعتبارسنجی مبدأ/مقصد، نگاشت کامل ستونها، سازگاری برد/باخت.
|
||||
2. بهروزرسانی معاملات: `pipelineId` و `stageId` بر اساس `stageMap` (و در صورت نیاز `status` همراستا با ستون مقصد).
|
||||
3. فرمهای سرنخ با `pipelineId = source` → `target` (حالت `retarget_all`).
|
||||
4. اگر مبدأ پیشفرض بود: `isDefault` مقصد = true، مبدأ قبل از حذف false.
|
||||
5. حذف کاریز مبدأ (ستونهایش cascade).
|
||||
|
||||
خطاها با پیام فارسی خوانا؛ در صورت خطا هیچ تغییر نیمهکارهای نماند.
|
||||
|
||||
## مدل داده (موجود)
|
||||
|
||||
- `Pipeline` → `stages`, `deals`, `isDefault`
|
||||
- `Deal.pipelineId` / `Deal.stageId` (`stage` با `onDelete: Restrict`)
|
||||
- `LeadForm.pipelineId` (اختیاری، برای ساخت معامله از فرم)
|
||||
|
||||
حذف مستقیم کاریز بدون انتقال معامله خطرناک است؛ ادغام جایگزین حذف امن است.
|
||||
|
||||
## تست
|
||||
|
||||
- واحد API: نگاشت ناقص رد شود؛ برد→باز رد شود؛ تراکنش معامله + فرم + پیشفرض + حذف مبدأ.
|
||||
- دستی: دو کاریز با چند معامله و یک فرم سرنخ؛ پس از ادغام فقط مقصد در سلکت دیده شود و فرم به مقصد اشاره کند.
|
||||
|
||||
## معیار پذیرش
|
||||
|
||||
- از تنظیمات مسیر فروش بتوان دو کاریز را ادغام کرد.
|
||||
- همهٔ معاملات با نگاشت ستون منتقل شوند.
|
||||
- فرمهای سرنخ متصل بهصورت پیشفرض به مقصد بروند.
|
||||
- کاریز مبدأ حذف شود و اگر پیشفرض بود، مقصد پیشفرض شود.
|
||||
- در خطا، دادهٔ قبلی حفظ شود.
|
||||
Reference in New Issue
Block a user