Files
yara724-api/docs/expert-claim-reply-submit-v2-frontend.fa.md
2026-09-19 12:11:43 +03:30

11 KiB
Raw Blame History

راهنمای فرانت‌اند: ثبت پاسخ کارشناس خسارت (V2)

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

PUT /v2/expert-claim/reply/submit/:claimRequestId
Authorization: Bearer <actor-token>
Content-Type: application/json

اگر محیط شما API را زیر پیشوند /api منتشر می‌کند، مسیر نهایی به‌صورت /api/v2/expert-claim/reply/submit/:claimRequestId است.

پیش‌نیازها

  • کاربر باید نقش کارشناس مجاز داشته باشد.
  • پرونده باید پیش از ارسال توسط همین کارشناس قفل شده باشد.
  • partId هر ردیف باید از damagedParts[].partId در جزئیات پرونده انتخاب شود؛ شناسه دلخواه ارسال نکنید.
  • دست‌کم یک ردیف در parts لازم است.

بدنه درخواست

تمام مبلغ‌ها باید string باشند. ارقام فارسی/انگلیسی و جداکننده هزارگان پذیرفته می‌شوند؛ برای نمونه هر دو مقدار "100000" و "۱۰۰,۰۰۰" معتبرند.

{
  "description": "تعویض درب جلو لازم است",
  "parts": [
    {
      "partId": 201,
      "typeOfDamage": "تعویض",
      "price": "2500000",
      "salary": "400000",
      "totalPayment": "2900000",
      "factorNeeded": false,
      "daghi": {
        "option": "ارزش لوازم بازیافتی",
        "price": "300000"
      }
    }
  ]
}

فیلدهای سطح بالا

فیلد الزامی توضیح
description خیر یادداشت متنی کارشناس. می‌تواند ارسال نشود.
parts بله آرایه‌ای با حداقل یک ردیف قیمت‌گذاری.

فیلدهای هر ردیف parts[i]

فیلد الزامی مقدار و قاعده
partId بله عدد صحیح؛ باید متعلق به قطعات آسیب‌دیده همان پرونده باشد.
typeOfDamage بله دقیقاً یکی از "تعمیر" یا "تعویض".
price برای "تعویض" بله؛ برای "تعمیر" اختیاری در صورت ارسال، مبلغ بین 100,000 تا 10,000,000,000 تومان.
salary بله مبلغ بین 100,000 تا 10,000,000,000 تومان.
totalPayment بله مبلغ بین 1,000,000 تا 100,000,000,000 ریال. فقط در جریان V1، مجموع این فیلدها در کل پرونده نباید از 530,000,000 ریال بیشتر شود.
factorNeeded بله مقدار Boolean واقعی (true یا false)؛ رشته ارسال نکنید.
daghi برای "تعویض" بله برای "تعمیر" لازم نیست و در ثبت نهایی حذف می‌شود.
daghi.option در صورت وجود daghi بله یکی از "ارزش لوازم بازیافتی"، "تحویل داغی"، "فاقد ارزش" یا "با احتساب داغی".
daghi.price فقط وقتی option برابر "ارزش لوازم بازیافتی" است مبلغ بین 100,000 تا 10,000,000,000 تومان.
daghi.branchId فقط وقتی option برابر "تحویل داغی" است Mongo ObjectId معتبرِ شعبه.

نکته‌ها:

  • مقدار 0 برای هیچ مبلغ ارسالی این endpoint معتبر نیست؛ حداقل مبلغ 100,000 تومان است.
  • محدودیت هر فیلد مبلغ مستقل است؛ سقف 530 میلیون ریال فقط برای مجموع totalPayment تمام ردیف‌های پرونده V1 اعمال می‌شود. جریان‌های V2 تا V6 سقف مجموع ندارند.
  • فیلدهای ناشناخته در body حذف می‌شوند. فرانت‌اند نباید برای انتقال داده به آن‌ها تکیه کند.

پاسخ موفق

پاسخ 200 شامل مسیر بعدی workflow است. نمونه:

{
  "claimRequestId": "66c...",
  "status": "COMPLETED",
  "claimStatus": "APPROVED",
  "currentStep": "CLAIM_COMPLETED",
  "workflowNextStep": "CLAIM_COMPLETED",
  "factorNeeded": false,
  "mixedPricingAndFactors": false,
  "allPartsFactorNeeded": false,
  "isFinalReplyAfterObjection": false
}

مقادیر status و step به این وابسته‌اند که ردیف factor داشته باشید یا نه؛ فرانت‌اند باید از مقادیر پاسخ استفاده کند، نه اینکه مسیر بعدی را فقط از payload حدس بزند.

قرارداد خطا

همه خطاهای این endpoint JSON هستند و NestJS مقدار statusCode را نیز به پاسخ اضافه می‌کند. برای نمایش پیام به کاربر از message استفاده کنید و برای منطق برنامه از code استفاده کنید؛ متن فارسی را با متن ثابت در فرانت‌اند جایگزین نکنید.

1. خطای ساختار DTO — 400

برای نبودن فیلد الزامی، نوع اشتباه، enum نامعتبر، آرایه خالی، یا فرمت مبلغ نامعتبر، پاسخ زیر برمی‌گردد:

{
  "statusCode": 400,
  "message": "اطلاعات ارسالی پاسخ کارشناسی معتبر نیست.",
  "error": "EXPERT_REPLY_VALIDATION_ERROR",
  "code": "EXPERT_REPLY_VALIDATION_ERROR",
  "validationErrors": [
    {
      "field": "parts[0].salary",
      "message": "باید مبلغ صحیح و غیرمنفی به تومان باشد."
    },
    {
      "field": "parts[0].factorNeeded",
      "message": "باید درست یا نادرست باشد."
    }
  ]
}

validationErrors ممکن است چند خطا داشته باشد. کلید field دقیقاً برای اتصال به کنترل فرم است؛ مانند parts[0].daghi.price یا parts[2].partId.

2. خطای قواعد مبلغ و قیمت‌گذاری — 400

این خطاها پس از اعتبارسنجی ساختار و پیش از تغییر وضعیت پرونده بررسی می‌شوند. برای مثال، مبلغ کمتر از حداقل:

{
  "statusCode": 400,
  "message": "قیمت قطعه 201 باید حداقل ۱۰۰٬۰۰۰ و حداکثر ۱۰٬۰۰۰٬۰۰۰٬۰۰۰ تومان باشد.",
  "error": "EXPERT_REPLY_VALIDATION_ERROR",
  "code": "EXPERT_REPLY_VALIDATION_ERROR",
  "field": "parts[0].price",
  "partId": "201",
  "rule": "amount_out_of_range",
  "minAmount": 100000,
  "maxAmount": 10000000000
}

rule یکی از این مقادیر است:

مقدار معنی
required فیلد لازم ارسال نشده است.
invalid_value مقدار enum یا شناسه معتبر نیست.
invalid_amount مبلغ، عدد صحیح غیرمنفی به تومان نیست.
amount_out_of_range مبلغ خارج از بازه minAmount و maxAmount است.

در صورت amount_out_of_range، برای نمایش محدوده از اعداد minAmount و maxAmount استفاده کنید، نه از parse کردن متن message.

3. سقف مجموع مبلغ‌ها — 400

{
  "statusCode": 400,
  "message": "مجموع مبلغ قطعات (۵۴۰٬۰۰۰٬۰۰۰) از سقف مجاز (۵۳۰٬۰۰۰٬۰۰۰) ریال بیشتر است.",
  "error": "PRICE_CAP_ERROR",
  "code": "PRICE_CAP_ERROR",
  "totalPrice": 540000000,
  "priceCap": 530000000
}

این خطا فقط برای پرونده‌های V1 رخ می‌دهد و به یک ردیف مشخص وصل نیست. آن را در بالای جدول قیمت‌ها نمایش دهید و از priceCap جزئیات پرونده/خطا برای پیام UI استفاده کنید. مقدار priceCap: null یعنی پرونده سقف مجموع ندارد.

4. خطاهای قواعد پرونده و workflow

این خطاها ساختار مشترک زیر را دارند:

{
  "statusCode": 400,
  "message": "قطعه با شناسه 201 در فهرست قطعات آسیب‌دیده پرونده وجود ندارد.",
  "error": "EXPERT_REPLY_SUBMISSION_ERROR",
  "code": "PART_NOT_ON_CLAIM",
  "field": "partId",
  "partId": 201
}

کدهای مهم:

HTTP code رفتار پیشنهادی فرانت‌اند
404 CLAIM_NOT_FOUND پیام خطا و بازگشت به فهرست پرونده‌ها.
400 CLAIM_NOT_REVIEWABLE جزئیات پرونده را refresh کنید؛ ثبت در وضعیت فعلی مجاز نیست.
403 CLAIM_NOT_LOCKED کاربر باید ابتدا پرونده را قفل کند.
403 CLAIM_LOCKED_BY_ANOTHER_EXPERT فرم را read-only کنید و پیام مناسب نمایش دهید.
400 PART_NOT_ON_CLAIM داده قطعات را refresh کنید و ردیف خطادار را اصلاح/حذف کنید.
400 PART_INVALID / PART_ID_INVALID ردیف دارای partId را اصلاح کنید.
400 DUPLICATE_PART ردیف تکراری را حذف کنید.
400 DAGHI_OPTION_REQUIRED فیلد daghi.option همان ردیف را نشان‌دار کنید.
400 DAGHI_PRICE_REQUIRED فیلد daghi.price همان ردیف را نشان‌دار کنید.
400 DAGHI_BRANCH_REQUIRED / DAGHI_BRANCH_INVALID فیلد daghi.branchId همان ردیف را نشان‌دار کنید.
409 FINAL_REPLY_ALREADY_SUBMITTED ثبت مجدد ممنوع است؛ داده پرونده را refresh کنید.

برای خطاهای داغی که از سرویس برمی‌گردند، field به شکل parts[<index>].daghi.<property> است.

الگوی پیشنهادی هندل کردن خطا در فرانت‌اند

type ApiErrorBody = {
  message?: string;
  code?: string;
  field?: string;
  validationErrors?: Array<{ field: string; message: string }>;
  minAmount?: number;
  maxAmount?: number;
  priceCap?: number;
};

function applySubmitError(body: ApiErrorBody) {
  if (body.validationErrors?.length) {
    for (const issue of body.validationErrors) {
      setFieldError(issue.field, issue.message);
    }
    return;
  }

  if (body.field) {
    setFieldError(body.field, body.message ?? "مقدار واردشده معتبر نیست.");
    return;
  }

  setFormError(body.message ?? "ثبت پاسخ کارشناسی انجام نشد.");
}

قبل از ارسال، فرانت‌اند می‌تواند همین بازه مبلغ را برای تجربه کاربری بهتر بررسی کند؛ با این حال اعتبار نهایی همیشه پاسخ API است. جمع totalPayment را فقط وقتی priceCap جزئیات پرونده عدد است با سقف مقایسه کنید؛ null یعنی V2 تا V6 و بدون سقف مجموع.