Skip to main content
#P1397

POST /api/v2/trade/search

Route Info

Method Endpoint Controller Middleware Purpose
POST /api/v2/trade/search V2TradeController@searchTrades authWithJwt جستجوی معاملات/فاکتورها با فیلترهای چندلایه و ترجمه خودکار مسیرها

منطق عملکرد و مسیر داده

تابع searchTrades، درخواست را بر اساس فیلترهای search و paginate پردازش می‌کند:
  • تبدیل فیلدهای عددی به رشته خالی برای جلوگیری از فیلترینگ بی‌هدف.
  • بررسی کامل ورود from و to؛ در صورت نبود خروجی error (code 1000).
  • ساخت ترکیبی از جستجوهای پیشرفته روی معاملات—فیلدهای: تاریخ، شماره رزرو، اپراتور، تعهد‌کننده، شماره/تاریخ پرواز، محصول، وضعیت، مسیر، درآمد و اطلاعات مسافر؛ از کوئری‌های فشرده با شرط‌های تو در تو استفاده می‌شود.
  • تمام توصیف‌های مسیر (route) با ترجمه‌های فارسی/انگلیسی زده می‌شوند؛ مثل "هتل"، "مسیر"، "تور"، "پرواز" با ترکیب‌های محصول و جزئیات.
  • اطلاعات تکمیلی هر آیتم از Redis یا DB و کلاس‌های کمکی خوانده و کش می‌شود.
  • نتیجه نهایی آرایه‌ای از معاملات با جزییات کامل مسیر و اطلاعات مالی است—پاسخ با meta ساختار یافته و صفحه‌بندی.

ورودی‌ها (Request Fields)

نام فیلد نوع داده ضروری توضیح
branch int|string بله شناسه شعبه فعال
operator object بله اپراتور (از JWT middleware)
search object بله شی جستجو با فیلدهایی مانند: r، from، to، op، flightno، dt_departure، passenger، status و...
paginate object بله پارامترهای صفحه بندی: start، length

نمونه Search Structure:

{
  "branch": 8,
  "search": {
    "from": "2025-02-01", "to": "2025-02-12",
    "status": "1", "flightno": "W51005",
    "op": 22, "pledger": "operator-12"
  },
  "paginate": {
    "start": 0,
    "length": 15
  }
}

خروجی (Response Structure)

فیلد نوع داده توضیح
items array آرایه‌ای از معاملات (ساختار زیر)
meta object شاخص‌های صفحه‌بندی (timestamp, total, page, per_page, last_page, current_page)

ساختار هر آیتم در خروجی:

فیلد نوع توضیح
datetime object تاریخ و ساعت صدور معامله
type object نوع محصول و مسیر
income string نوع درآمد
route_type string نوع اصلی خدمت (aircraft, bus, hotel, ...)
pledger array|null تعهدکنندگان معامله با جزئیات
route_title string توضیح مسیر یا هتل یا سرویس، با ترجمه فارسی یا انگلیسی هوشمند
operator object اطلاعات اپراتور ثبت‌کننده
leader object لیدر مسیر (در صورت وجود)
count_passengers int تعداد مسافرها
status int وضعیت معامله
description string|false توضیح در صورت status=2,5
serial int شماره رزرو سیستمی
factor_id int شماره رزرو پایه
system_serial int شماره داخلی فاکتور
slug string شناسه مسیر یکتا
suppliers array فهرست تامین‌کننده‌ها

نمونه پاسخ موفق:

{
  "items": [
    {
      "date": { "title": "11/22", "placeholder": "سه‌شنبه، 1404/12/23 14:32" },
      "route_title": "تهران به کیش | W51005",
      "type": { "title": "aircraft", "placeholder": "هواپیما" },
      "pledger": [ { "Id": 12, "Title": "جواد مقیمی", "Amount": 250000 } ],
      "suppliers": [],
      ...
    }
  ],
  "meta": {
    "timestamp": 1693905251,
    "total": 29,
    "page": 15,
    "per_page": 15,
    "last_page": 2,
    "current_page": 2
  }
}

نمونه پاسخ خطا (تاریخ ناقص):

{
  "error": {
    "code": 1000,
    "message": "لطفا تاریخ شروع جستجو و پایان جستجو را وارد نمائید."
  },
  "meta": {
    "timestamp": 1693905251
  }
}

تحلیل امنیتی و کنترل خطا

  • ورود به Route کاملاً وابسته به JWT؛ اگر توکن معتبر نباشد یا کاربر مجاز نباشد، خطای 1002/1003/1004 یا 1005/1006 برمی‌گردد.
  • ساختار ورودی به هیچ‌وجه با Schema validate نمی‌شود، زمینه‌ساز حملات Injection یا نقض منطق جستجو است.
  • اطلاعات تکمیلی و ترجمه‌شده مسیر از Redis بدون TTL ذخیره می‌شود—cache poisoning یا stale data ممکن است رخ دهد.
  • در پاسخ خطا (date missing)، هیچ جزئیات sensitive داده نمی‌شود اما سایر باگ‌های منطقی ممکن است باعث لو رفتن ساختار پایگاه داده شوند.
  • اگر سایز صفحه‌بندی خیلی بزرگ تنظیم شود، منجر به لحظه‌ای شدن مصرف RAM می‌شود و هیچ کنترل فشاری ندارد.

نکات کارایی و ضعف طراحی

  • استفاده مکرر و نادرست از Redis بدون TTL باعث رشد بی‌رویه cache و سنگین‌شدن حافظه سرور می‌شود.
  • رجوع مکرر به DB برای اطلاعات supplement (hotel, airline) در هر جستجو، در مسیرهای حجیم باعث افت عملکرد است.
  • ساختار جستجو تو در تو باعث سردرگمی منطق ذخیره نتیجه و ترکیب شروط‌ها می‌شود؛ لازم است Refactor سرویس جستجو انجام شود.

وابستگی‌های کلیدی

  • use Carbon\Carbon;
  • use Morilog\Jalali\Jalalian;
  • use Illuminate\Support\Facades\Redis;
  • use App\Models\{Factor, FactorItem, Pledger, User, Colleague, Hotel, Airport, City};
  • use App\Http\Controllers\Api\Panel\V2\ApiTradeController;
  • use App\Http\Controllers\Api\Panel\V2\StaticController;
  • use App\Helpers\Functions;
  • use CalendarUtils;

کدهای خطا و خروجی‌های Exception

کد خطا شرح منبع
1000 لطفا تاریخ شروع جستجو و پایان جستجو را وارد نمائید. searchTrades (application logic)
1002, 1003, 1004 User does not have access permission authWithJwt
1005 Token not provided authWithJwt
1006 Your token is invalid or expired authWithJwt
500 Database / Redis Exception → Trace searchTrades, middleware

پیشنهادهای بهبود

  • افزودن TTL برای کلیدهای Redis، با حذف اتوماتیک پس از ۵ دقیقه.
  • اعمال validation ساختاری روی ورودی‌ها قبل از اجرای search (JSON Schema/DTO).
  • جداسازی سرویسی جستجو و ترجمه route برای کد محصول.
  • کنترل حد نهایی صفحه‌بندی (length & start) جهت جلوگیری از سوءاستفاده.

جمع‌بندی

این Endpoint جستجو، یکی از پرریسک‌ترین و پیچیده‌ترین نقاط جریان معاملاتی است. قدرت زیادی با منطق ترکیبی و ترجمه هوشمند دارد، اما ضعف‌های امنیتی و عملکردی باعث می‌شود اگر مهندسی نشده باشد، اثرش کشنده باشد. پیشنهاد اکید: جداسازی سرچ‌سرویس، اعتبارسنجی ورودی، و مهار cache.