#P1395
POST /api/v2/exam/response
Route Info
| Method |
Endpoint |
Controller |
Middleware |
Purpose |
تگ Swagger |
| POST |
/api/v2/exam/response |
OfficialController@responseExam |
domainAccess, ipTrust |
ثبت پاسخ آزمون نظرسنجی (سفر یا ارزیابی ۳۶۰ درجه) |
tags={"Exam","V2"} |
توضیح عملکرد (Function Logic)
این متد پاسخ کامل آزمون را ثبت میکند. بر اساس نوع (trip یا 360_degree_feedback)، نوع ذخیره object_type تنظیم میشود (reference/personnel). ۱. رکورد اصلی exam_response با اطلاعات پایه: شعبه، شناسه آزمون، شیء، شناسه کاربر، نام، موبایل، ایمیل ۲. ثبت هر پاسخ تکی در جدول exam_responses_item؛ هر پاسخ شامل شناسه سوال و مقدار پاسخ که خودش میتواند آرایه یا رشته باشد (در صورت آرایه json_encode). ۳. اگر آزمون شامل جایزه باشد (فیلد gift در جدول exams)، ساخت کد جایزه و ارسال ساختار هدیه ۴. امتیازدهی خودکار با StaticController::getScoreOperator ۵. خروجی نهایی: status و زمان، و در صورت تخصیص هدیه، فیلد gift ۶. هندل کامل استثنا به صورت خروجی status=false و اطلاعات خطا
ورودیها (Request Body)
| فیلد |
نوع داده |
الزامی |
توضیح |
| type |
string |
بله |
نوع آزمون (trip یا 360_degree_feedback) |
| id |
int |
بله |
شناسه آزمون |
| object |
int |
بله |
شناسه سفر (type=trip) یا شناسه همکار (type=360) |
| branch |
string|int |
بله |
کد شعبه |
| operator |
object |
اختیاری |
شیء کاربر فعلی (در حالت ۳۶۰ درجه الزامی) |
| full_name |
string |
اختیاری |
نام کامل ثبتکننده |
| mobile |
string |
اختیاری |
شماره موبایل ثبتکننده |
| email |
string |
اختیاری |
ایمیل ثبتکننده |
| responses |
array |
بله |
آرایه پاسخ هر سوال. هر آیتم: {question: int, response: string|array} |
خروجی (Response Structure)
| فیلد |
نوع داده |
توضیح |
| status |
boolean |
نتیجه عملیات ثبت |
| time |
int |
زمان ثبت (unix timestamp) |
| gift |
object|false |
اگر آزمون جایزه دارد، شیء {"title", "code"} |
| message |
string |
توضیح خطا (در حالت failure) |
| trace |
array |
اطلاعات error (در حالت failure) |
نمونه درخواست:
POST /api/v2/exam/response
Content-Type: application/json
{
"type": "trip",
"id": 15,
"object": 1472,
"branch": "8",
"operator": { "id": 22 },
"responses": [
{ "question": 1, "response": "5" },
{ "question": 2, "response": ["Clean", "Comfort"] }
]
}
نمونه پاسخ موفق:
{
"status": true,
"time": 1693905251,
"gift": { "title": "تخفیف ویژه", "code": "140303-12345" }
}
نمونه پاسخ خطا:
{
"status": false,
"time": 1693905252,
"message": "SQLSTATE[23000]: Integrity constraint violation ...",
"trace": [ ... ]
}
تحلیل امنیتی
- ✅ حفاظت Realm با Middleware
domainAccess و ipTrust
- ⚠️ هیچ اعتبارسنجی برای صحت ساختار responses یا عدم وجود تکرار پاسخ وجود ندارد؛ نقطه ضعف قابل سوءاستفاده.
- ⚠️ برای آزمونهای "360"، اگر operator معتبر نباشد سیستم بدون خطای خوانا fail میکند.
- ⚠️ دادههای contact (نام، موبایل، ایمیل) بدون هیچ sanitation در DB ثبت میشود: ریسک تزریق و Spamming exists.
- ✅ Exception هندلینگ کامل انجام میشود؛ Error Trace در خروجی ثبت میشود.
- ⚠️ هیچ Throttling یا تکرارپذیری ضد اسپم روی این route دیده نمیشود.
وابستگیها (Dependencies)
- use Illuminate\Http\Request;
- use Illuminate\Support\Facades\DB;
- use Morilog\Jalali\Jalalian;
- use App\Http\Controllers\Api\Panel\V2\StaticController;
نکات کارایی و ضعف منطقی
- هر پاسخ به سرعت در DB ثبت میشود اما هیچ validation سمت سرور نیست (حتی اگر responses کاملاً بیربط باشند).
- فرایند تولید کد هدیه وابسته به id کلیدی است و قابل پیشبینی توسط مهاجم.
- در صورت خطای پایگاه داده، جزئیات با
trace به مشتری نمایش داده میشود که ریسک اطلاعاتی دارد.
پیوست نگهداری و توسعه بعدی
- افزودن اعتبارسنجی دقیق responses و sanitation اطلاعات مبتنی بر فیلدهای contact.
- افزودن throttling/limiting بر اساس operator و سفر برای جلوگیری از brute force و spam.
- تعریف وابستگی به احراز هویت JWT در نسخه بعدی.
- افزودن فیلدهای custom جهت اتوماسیون هدیه (مثلاً expiry/used count).