docs: add pipeline merge design spec

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-12 20:07:09 +03:30
co-authored by Cursor
parent cba4ad6a49
commit ffae63edbf
@@ -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: نگاشت ناقص رد شود؛ برد→باز رد شود؛ تراکنش معامله + فرم + پیش‌فرض + حذف مبدأ.
- دستی: دو کاریز با چند معامله و یک فرم سرنخ؛ پس از ادغام فقط مقصد در سلکت دیده شود و فرم به مقصد اشاره کند.
## معیار پذیرش
- از تنظیمات مسیر فروش بتوان دو کاریز را ادغام کرد.
- همهٔ معاملات با نگاشت ستون منتقل شوند.
- فرم‌های سرنخ متصل به‌صورت پیش‌فرض به مقصد بروند.
- کاریز مبدأ حذف شود و اگر پیش‌فرض بود، مقصد پیش‌فرض شود.
- در خطا، دادهٔ قبلی حفظ شود.