> **تیم فنی کوئرا** در تمامی این سالها، همواره سعی کرده تا **خارقالعادهترین** ویژگیها را به **زیباترین** شکل به کاربران در تمام بخشهای کوئرا از جمله **کانتست، کالج و بوتکمپ** ارائه کند. **لود زیاد تیم فنی کوئرا** در تمام این سالها باعث شده تا توسعهدهندگانش همواره **تنها و تنها** به فکر توسعه فیچرهای مختلف باشند. آن هم **به هر قیمتی که شده!** حتی به قیمت خلق **کدبِیسی** *(Code Base)* **بسیار کثیف** و **آشفته**...
**ممزواد** *(Mamzavad)،* **مدیرفنی** *(CTO)* و از **محبوبترین** شخصیتهای سوالات مسابقات برنامهنویسی کوئرا، به تازگی و پس از پیوستن شخصیت محبوب دیگر، یعنی **آمین** *(Aaaamin)،* به تیم فنیاش در کوئرا، شدیدا دچار **تحول** شده و بالاخره تصمیم گرفته است تا **کدبِیس کثیف کوئرا** را بعد از نزدیک به یک دهه **بازنویسی** کند! ممزواد که قرار است به زودی **لود سنگین** و **جدید** دیگری را نیز که [**سری دوم #المپیکفناوری پردیس**](https://quera.org/events/techolympics-0407) است را تحمل کند، تصمیم گرفته تا **توسعه فیچرهای جدید** را مستقل از **بازنویسی کدبِیس کثیف کوئرا** انجام دهد.
اگر از **روزهای نخستین کوئرا** چیزی به یاد داشته باشید، **کوئرای اولیه** از **پروژهی قدیمی** و **معروف** [**شریفجاج** *(Sharif Judge)*](https://github.com/mjnaderi/Sharif-Judge) شکل گرفته و به ترتیب در تمام یک دهه فعالیتش، بخشهای زیادی از آن **بازنویسی** شده و ویژگیهای بسیاری که امروزه نیز شما در حال استفاده از بسیاری از ویژگیها هستید، به آن **افزوده** شدند. ممزواد نیز که تصمیم به **بازنویسی کدبِیس کوئرا** افتاده اینبار اما با الهام از **روزهای قدیمی کوئرا،** این پروژه جدید را با نام رمزی *جاجِ مَمجَجاد* تعریف کرده است. آمین، که خود نیز از الهامبخشان شروع پروژه **بازنویسی کدبیس کوئرا** و **جاج مَمجَجاد** بوده است میخواهد خود شخصا دست به کار شود تا چرخ این پروژه نیز مانند سایر پروژههای تعریف شده در کوئرا، به حرکت در بیاید.

از آنجایی که کار **جاج مَمجَجاد** باید همزمان با آمادهسازی **ویژگیهای جدید کوئرا** برای سری جدید مسابقات المپیکفناوری پردیس پیشروی کند و **آمین** نیز به تازگی و پس از مدت زیادی **کوئراکاری،** حسابی خسته شده و تصمیم به **سفری طولانی مدت** و **بیبازگشت** از مبدا کوئرا گرفته، با تهیه **مستنداتی کامل** از تمام **اندپوینتها** *(Endpoints)* و **سرویسها** در کوئرا، پروژه مهم و اساسی **جاج مَمجَجاد** را به شما، که با عبور از تمام سوالات سخت و مردافکن این مسابقه تا به این سوال رسیدهاید، سپرده است.
# **پروژه اولیه**
برای دانلود **پروژهی اولیه** روی این [این لینک](/contest/assignments/84123/download_problem_initial_project/305471/) کلیک کنید.
<details class="yellow">
<summary>
**ساختار فایلها**
</summary>
```
mini-quera
├── Dockerfile
├── <mark class="orange" title="این اپلیکیشن باید پیاده سازی شود">accounts</mark>
├── <mark class="orange" title="این اپلیکیشن باید پیاده سازی شود">contests</mark>
├── <mark class="orange" title="این اپلیکیشن باید پیاده سازی شود">core</mark>
├── db.sqlite3
├── docker-compose.yml
├── entrypoint.sh
├── <mark class="orange" title="این اپلیکیشن باید پیاده سازی شود">judge</mark>
├── judge-worker.Dockerfile
├── <mark class="orange" title="این اپلیکیشن باید پیاده سازی شود">lms</mark>
├── manage.py
├── mini_quera
├── <mark class="orange" title="این اپلیکیشن باید پیاده سازی شود">plagiarism</mark>
├── <mark class="orange" title="این اپلیکیشن باید پیاده سازی شود">problems</mark>
├── requirements.txt
├── static
├── submission_files
├── <mark class="orange" title="این اپلیکیشن باید پیاده سازی شود">submissions</mark>
└── templates
```
</details>
<details class="grey">
<summary>
**راهاندازی پروژه**
</summary>
برای **اجرای پروژه،** باید **پایتون** و **ابزار داکر** را از قبل نصب کرده باشید.
+ ابتدا فایل **پروژهی اولیه** را از قسمت لینک بالا **دانلود** و **استخراج** کنید.
+ برای اجرای پروژه با **داکر کامپوز،** دستور زیر را در **مسیر پوشهی اصلی پروژه** اجرا کنید. این دستور سرویسهای *پروژهی جنگویی جاج مَمجَجاد، Celery، RabbitMQ و محیط داوری کد* را در سیستم شما بالا میآورد:
```bash docker docker
docker compose up --build
```
+ بعد از بالا آمدن کانتینرها و توسعه مدلهای جدید، **مایگریشنهای دیتابیس** را **اجرا** کنید تا **جداول مورد نیاز** ایجاد شوند:
```bash docker docker
docker compose exec web python manage.py migrate
```
+ برای **جمعآوری فایلهای استاتیک** و **آمادهسازی پروژه،** دستور زیر را اجرا کنید:
```bash docker docker
docker compose exec web python manage.py collectstatic --noinput
```
+ در صورتی که **تغییراتی در وابستگیها** ایجاد شد یا سرویسها به مشکل برخوردند، کانتینرها را میتوانید با استفاده از دستور زیر مجدداً اجرا کنید:
```bash docker docker
docker compose up --build -d
```
+ پس از اجرای موفق، **وباپلیکیشن جاج مَمجَجاد** از طریق **آدرس** http://localhost:8000 در دسترس است و **ادمین پنل مدیریت سرویس** *RabbitMQ* از طریق **آدرس** http://localhost:15672 با **نام کاربری** `rabbitmq_user` و **رمز عبور** `rabbitmq_pass` قابل مشاهده خواهد بود.
</details>
# **جزئیات پروژه**
**پروژه جاج مَمجَجاد،** دقیقا عملکردی مشابه آنچه امروزه شما به عنوان کوئرا میشناسید را دارد. این پروژه امکانات مختلفی از جمله **احراز هویت کاربران، ساخت و مدیریت سوالات و تستکیسها، ساخت مسابقات و کلاسهای جدید و افزودن سوالات ساخته شده به آنها، ارسال کد و داوری در سرویس جدا و مخصوص** `judge_worker` که با داشتن وابستگیهای مختلف، امکان اجرای **کدهای پایتونی، جاوا، سی و سیپلاسپلاس** را امکان پذیر میکند.
معماری این پروژه بهصورت **ماژولار** و **مبتنی بر صف** طراحی شده است؛ **سرویس** `web` مسئول مدیریت کاربران و اندپوینتهای مختلف است، یک **ورکر** *Celery* با استفاده از *RabbitMQ* وظایف **داوری** را بهصورت **غیرهمزمان** اجرا میکند و **سرویس** `judge_worker` **محیطی ایزوله** و **امن** برای اجرای کدها فراهم میسازد. این ساختار امکان داوری سریع، ایمن و مقیاسپذیر را برای زبانهای مختلف برنامهنویسی فراهم کرده و جاج مَمجَجاد را بیشتر از قبل به **کوئرای واقعی** شبیهتر میکند.
<details class="olive">
<summary>
**معرفی سرویسهای پروژه** `mini-quera`
</summary>
## **سرویس** `web`
**سرویس** `web` **هسته اصلی جاج مَمجَجاد** است و مسئول ارائه **APIها** و **رابط کاربری** میباشد. این سرویس با *Gunicorn* اجرا شده و تمامی **درخواستهای کاربران** را مدیریت میکند. **جاج مَمجَجاد** به **سرویس** `rabbitmq` و `judge_worker` متصل است تا **وظایف داوری** و **پردازش پسزمینه** را ارسال کند. **تمامی اندپوینتها، شامل ثبت نام، ارسال کد و دسترسی به مسابقات و مشکلات، از طریق این سرویس قابل دسترسی هستند.**
## **سرویس** `celery`
**سرویس** `celery` **وظایف پسزمینه** و زمانبر جاج را مدیریت میکند. این سرویس از *RabbitMQ* به عنوان **پیامرسان** *(Message Broker)* استفاده میکند تا تسکها را **بدون مسدود کردن سرویس** `web` اجرا کند. وظایفی مانند **داوری کدها** و **بررسی سرقت ادبی** توسط این سرویس پردازش میشوند. با استفاده از این سرویس، **اجرای همزمان چندین تسک** بدون ایجاد تداخل یا کندی در پروژه امکانپذیر است.
## **سرویس** `judge_worker`
**سرویس** `judge_worker` برای **اجرای کدهای کاربران در محیط ایزوله** طراحی شده است. این سرویس با نصب داشتن **انواع وابستگیهای مورد نیاز** برای اجرای امن *کدهای پایتون، C، C++ و جاوا* استفاده میشود.خروجی و وضعیت اجرای کدها به سرویس `web` و `celery` بازگردانده میشود تا **نتایج داوری ثبت** و **نمایش** داده شوند. **سرویس** `judge_worker` **به طور مستقل عمل میکند** تا از تاثیر اجرای کدهای کاربران بر سرویس اصلی **جلوگیری** شود.
## **سرویس** `rabbitmq`
**سرویس** `rabbitmq` **پیامرسان** *(Message Broker)* اصلی پروژه است که ارتباط بین **سرویسهای** `web`، `celery` و `judge_worker` را برقرار میکند. این سرویس وظیفه مدیریت صفها و **ارسال پیامهای مربوط به وظایف پسزمینه** را دارد. **بدون** *RabbitMQ،* Celery **نمیتواند** تسکها را دریافت و اجرا کند و **هماهنگی بین سرویسها از بین میرود. سرویس** *RabbitMQ* امکان پردازش همزمان چندین تسک و مدیریت اولویتها را فراهم میکند.
</details>
---
<details class="teal">
<summary>
**معرفی و پیادهسازی اپلیکیشن** `core` **(پیادهسازی اندپوینت** `health` **الزامی است!)**
</summary>
**اپلیکیشن** `core` **باید شامل اندپوینت سلامت سرویس، مدیریت سیگنالهای سیستم و تنظیمات تعامل با سرویس** `celery` برای پردازش پسزمینه باشد.
## **بررسی سلامت سرویس** (`/health/`)
**این اندپوینت وضعیت کلی سرویس را بیان میکند و برای اطمینان از فعال بودن سرویس مورد استفاده قرار میگیرد. هیچ ورودی پیچیدهای نیاز ندارد و پاسخ آن ساده و سریع است.**
```bash terminal terminal
curl -X GET http://localhost:8000/health/
```
**پاسخ موفق:**
```bash terminal terminal
{
"status": "ok"
}
```
## **جدول پیادهسازی**

</details>
<details class="blue">
<summary>
**معرفی و پیادهسازی اپلیکیشن** `accounts`
</summary>
**اپلیکیشن** `accounts` مسئول **مدیریت کاربران سامانه** است. این اپ که **بر پایه مدل** `AbstractUser` جنگویی باید توسعه یابد، **امکان ثبت نام کاربران جدید** و **مشاهده فهرست کاربران موجود** را فراهم میکند. ثبت نام **برای همه کاربران** قابل دسترسی است، در حالی که مشاهده لیست کاربران **فقط برای مدیران** امکانپذیر است.
## **ثبت نام کاربر جدید** (`/api/accounts/register/`)
**ورودی** اندپوینت ثبت نام کاربر جدید (`/api/accounts/register/`) شامل **فیلدهای** `username`، `email`، `password`، `password2` و `role` است. مقدار فیلد `role` مشخص میکند کاربر چه نقشی در سامانه خواهد داشت، به عنوان مثال اگر مقدار آن برابر با `admin` باشد، کاربر با **سطح دسترسی مدیریتی** (`is_staff`) ایجاد میشود و در غیر این صورت سطح دسترسی معمولی مانند دانشجو یا استاد به او اختصاص مییابد. در صورت موفقیت در ثبت نام، پاسخ شامل **اطلاعات کاربر** تازه ایجاد شده به همراه شناسه کاربر است. اگر **مقدارهای** `password` و `password2` با یکدیگر مطابقت نداشته باشند، سیستم **خطای اعتبارسنجی** را بازمیگرداند تا کاربر از اصلاح ورودی خود مطمئن شود.
```bash terminal terminal
curl -X POST http://localhost:8000/api/accounts/register/ \
-H "Content-Type: application/json" \
-d '{
"username": "example_user",
"email": "user@example.com",
"password": "password123",
"password2": "password123",
"role": "student"
}'
```
+ در صورتی که **رمز عبور** و **تکرار آن** مطابقت **نداشته** باشند، **خطای اعتبارسنجی** با متن زیر بازگردانده میشود:
```bash terminal terminal
{
"password": "رمز عبور مطابقت ندارد."
}
```
+ در **پاسخ موفقیتآمیز ثبت نام،** اطلاعات کاربر جدید **بدون رمز عبور** به شکل زیر نمایش داده میشود:
```bash terminal terminal
{
"id": 1,
"username": "example_user",
"email": "user@example.com",
"role": "student"
}
```
## **مشاهده لیست کاربران** (`/api/accounts/users/`)
**اندپوینت مشاهده لیست کاربران** (`/api/accounts/users/`) تنها در صورتی قابل دسترسی است که **کاربر دارای نقش مدیر** باشد. در صورت پاسخ موفق، **لیستی از کاربران** موجود را بازمیگرداند که هر کاربر با **شناسه، نام کاربری، ایمیل و نقش خود** نمایش داده میشود. در صورتی که کاربر نقش مدیر نداشته باشد یا توکن معتبر ارسال نکند، پاسخ شامل **خطای عدم دسترسی** خواهد بود تا از مشاهده اطلاعات سایر کاربران **جلوگیری** شود.
```bash terminal terminal
curl -X GET http://localhost:8000/api/accounts/users/ \
-H "Authorization: Bearer <YOUR_TOKEN>"
```
+ در **پاسخ موفق** برای مشاهده لیست کاربران، فهرست کاربران موجود بازگردانده میشود، **هر آیتم شامل** `id`, `username`, `email` و `role` است:
```bash terminal terminal
[
{
"id": 1,
"username": "example_user",
"email": "user@example.com",
"role": "student"
},
{
"id": 2,
"username": "admin_user",
"email": "admin@example.com",
"role": "admin"
}
]
```
+ در صورتی که **کاربر غیرمدیر** به این اندپوینت دسترسی پیدا کند، خطای زیر بازگردانده میشود:
```bash terminal terminal
{
"detail": "You do not have permission to perform this action."
}
```
## **جدول پیادهسازی**

</details>
<details class="pink">
<summary>
**معرفی و پیادهسازی اپلیکیشن** `problems`
</summary>
**اپلیکیشن** `problems` **مسئول مدیریت سوالات** *(Problems)* و **تستکیسهای** *(TestCases)* **جاج** است. این اپ **امکان ایجاد و مشاهده سوالات و مدیریت تستکیسها** را فراهم میکند. ایجاد **سوالات و تستکیسها** فقط برای مدیران امکانپذیر است، اما مشاهده جزئیات و فهرست مسائل برای همه کاربران **قابل دسترسی** است.
## **ایجاد سوال جدید** (`/api/problems/create/`)
**ورودی** اندپوینت **ایجاد سوال جدید** (`/api/problems/create/`) شامل **فیلدهای** `title` به عنوان عنوان سوال، `description` برای توضیح کامل سوال، `input_description` و `output_description` برای تشریح دادههای ورودی و خروجی و **محدودیتهای زمان** (`time_limit`) و **حافظه** (`memory_limit`) است. **تنها مدیران** میتوانند از این اندپوینت استفاده کنند و در پاسخ موفق، **تمام جزئیات مسئله شامل** `id`، `title`، `description`، `input_description`، `output_description`، `time_limit`، `memory_limit` و آرایهای از **تستکیسهای سوال** (`testcases`) بازگردانده میشود. در صورتی که **مقادیر** `time_limit` یا `memory_limit` **نامعتبر** باشند، **خطای اعتبارسنجی** مناسب صادر میشود تا اطمینان حاصل شود که محدودیتها مثبت و معتبر هستند.
```bash terminal terminal
curl -X POST http://localhost:8000/api/problems/create/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-d '{
"title": "Sum of Numbers",
"description": "Calculate the sum of given numbers",
"input_description": "Two integers",
"output_description": "Sum of integers",
"time_limit": 1,
"memory_limit": 64
}'
```
+ در صورت موفقیت، **اطلاعات سوال** ایجاد شده بازگردانده میشود:
```bash terminal terminal
{
"id": 1,
"title": "Sum of Numbers",
"description": "Calculate the sum of given numbers",
"input_description": "Two integers",
"output_description": "Sum of integers",
"time_limit": 1,
"memory_limit": 64,
"testcases": []
}
```
+ در صورت **ارسال مقدار نامعتبر** برای `time_limit` یا `memory_limit`، **خطای اعتبارسنجی** بازگردانده میشود:
```bash terminal terminal
{
"time_limit": ["Time limit must be greater than 0 seconds."]
}
```
## **مشاهده فهرست سوالات** (`/api/problems/`)
**اندپوینت مشاهده فهرست سوالات** (`/api/problems/`) خروجی را به صورت **آرایهای از سوالات** بازمیگرداند که هر عنصر شامل `id`، `title`، `description`، `input_description`، `output_description`، `time_limit`، `memory_limit` و **آرایهای از تستکیسها** (`testcases`) است. این اندپوینت **برای همه کاربران** قابل دسترسی است و امکان مشاهده **سوالات** و **تستکیسهای مرتبط با آنها** را فراهم میکند. **هر تستکیس شامل** `id`، `input_data`، `expected_output` و `is_sample` است که مشخص میکند **آیا تستکیس در نتیجه اصلی محاسبه میشود و یا صرفا به عنوان نمونه است و در سیستم داوری مورد استفاده قرار نمیگیرد.**
```bash terminal terminal
curl -X GET http://localhost:8000/api/problems/
```
+ **نمونه پاسخ موفق:**
```bash terminal terminal
[
{
"id": 1,
"title": "Sum of Numbers",
"description": "Calculate the sum of given numbers",
"input_description": "Two integers",
"output_description": "Sum of integers",
"time_limit": 1,
"memory_limit": 64,
"testcases": [
{
"id": 1,
"input_data": "2 3",
"expected_output": "5",
"is_sample": true
}
]
}
]
```
## **مشاهده جزئیات سوال** (`/api/problems/<int:pk>/`)
**اندپوینت مشاهده جزئیات سوال** (`/api/problems/<int:pk>/`) **اطلاعات یک مسئله مشخص را بر اساس شناسه آن ارائه میدهد و شامل تمام فیلدهای مسئله مانند** `id`، `title`، `description`، `input_description`، `output_description`، `time_limit`، `memory_limit` **و آرایهای از تستکیسها** (`testcases`) است. این اندپوینت **برای همه کاربران** قابل دسترسی است و اگر مسئلهای با شناسه مشخص وجود نداشته باشد، **پاسخ شامل خطای استاندارد** `{"detail": "Not found."}` خواهد بود.
```bash terminal terminal
curl -X GET http://localhost:8000/api/problems/1/
```
+ **نمونه پاسخ موفق مشابه نمونه پاسخ فهرست سوالات است،** اما **فقط اطلاعات یک سوال** بازگردانده میشود.
## **ایجاد تستکیسها** (`/api/problems/testcases/create/`)
**ورودی** اندپوینت ایجاد نمونه داده تست (`/api/problems/testcases/create/`) **شامل** `problem` **به عنوان شناسه مسئله مرتبط،** `input_data`، `expected_output` و `is_sample` برای مشخص کردن نمونه بودن یا اصلی بودن تستکیس است *(تستکیسهای نمونه در سیستم داوری مورد استفاده قرار نخواهند گرفت).* **تنها مدیران** میتوانند از این اندپوینت استفاده کنند و در پاسخ موفق، **تمام جزئیات تستکیس** شامل `id`، شناسه مسئله (`problem`)، `input_data`، `expected_output` و `is_sample` بازگردانده میشود.
```bash terminal terminal
curl -X POST http://localhost:8000/api/problems/testcases/create/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-d '{
"problem": 1,
"input_data": "2 3",
"expected_output": "5",
"is_sample": true
}'
```
+ در پاسخ موفق، **اطلاعات تستکیس ایجاد شده** بازگردانده میشود:
```bash terminal terminal
{
"id": 1,
"problem": 1,
"input_data": "2 3",
"expected_output": "5",
"is_sample": true
}
```
## **مشاهده تستکیسهای یک سوال** (`/api/problems/<int:problem_id>/testcases/`)
**اندپوینت مشاهده تستکیسهای یک سوال** (`/api/problems/<int:problem_id>/testcases/`) خروجی را **به صورت آرایهای از تستکیسهای مرتبط** به سوال مشخص شده بازمیگرداند و **هر تستکیس شامل** `id`، `input_data`، `expected_output` و `is_sample` است. **تنها مدیران** قادر به دسترسی به این اندپوینت هستند و در صورت تلاش کاربران غیرمجاز، **پاسخ شامل خطای** `{"detail": "You do not have permission to perform this action."}` خواهد بود.
```bash terminal terminal
curl -X GET http://localhost:8000/api/problems/1/testcases/ \
-H "Authorization: Bearer <YOUR_TOKEN>"
```
+ **نمونه پاسخ موفق:**
```bash terminal terminal
[
{
"id": 1,
"input_data": "2 3",
"expected_output": "5",
"is_sample": true
}
]
```
+ در صورت **عدم دسترسی کاربر غیرمدیر،** خطای زیر بازگردانده میشود:
```bash terminal terminal
{
"detail": "You do not have permission to perform this action."
}
```
## **جدول پیادهسازی**

</details>
<details class="yellow">
<summary>
**معرفی و پیادهسازی اپلیکیشن** `submissions`
</summary>
**اپلیکیشن** `submissions` مسئول **مدیریت ارسال کد کاربران** و **بررسی وضعیت** اجرای آنهاست. کاربران میتوانند کد خود را ارسال کنند و وضعیت اجرای آن شامل **موفقیت، خطا، خروجی و زمان اجرا** را مشاهده کنند.
## **ارسال کد برای اجرا** (`/api/submissions/submit/`)
**اندپوینت ارسال کد برای اجرا** (`/api/submissions/submit/`) **ورودی را به صورت** `multipart/form-data` دریافت میکند که **شامل فیلد** `problem` **برای مشخص کردن شناسه سوال،** `code_file` **به عنوان فایل کد کاربر و** `language` **برای تعیین زبان برنامهنویسی است.** کاربران ثبتنام شده با **توکن معتبر** میتوانند از این اندپوینت استفاده کنند و در پاسخ موفق، **شناسه ارسال** (`submission_id`) و **وضعیت اولیه** `submitted` بازگردانده میشود تا سیستم داوری بتواند ارسال را پیگیری کند. در صورتی که هر یک از فیلدها خالی یا نامعتبر باشند، **خطای مناسب شامل پیامهایی مانند** `This field is required.` یا `No file was submitted.` نمایش داده میشود.
سیگنالهای ایجاد شده توسط این اندپوینت وضعیت اجرای کد را در **سه وضعیت** `ACCEPTED` ,`FAILED` و `ERROR` ثبت میکنند. هر لاگ مرتبط با یک اجرای کد شامل **وضعیت کلی**، **خروجی تولید شده**، **خطا در صورت وجود** و **زمان اجرای کد** است. سیستم داوری باید با استفاده از سرویس `judge_worker` و **سیگنالهایی** که توسط **سرویس** `celery` پردازش خواهند شد، هنگام داوری سوال هر **تستکیس غیر نمونهای** را جداگانه اجرا کند و نتیجه آن با مقایسه خروجی واقعی و خروجی مورد انتظار ثبت شود. اگر **تمام** تستکیسها درست باشند، **وضعیت نهایی** `ACCEPTED` خواهد بود، در صورت **عدم شباهت خروجیها** در **حداقل یک تستکیس** وضعیت نهایی `FAILED` میشود و اگر اجرای کد با **خطا** مواجه شود یا **زبان پشتیبانی نشود، وضعیت** `ERROR` باید ثبت گردد.
```bash terminal terminal
curl -X POST http://localhost:8000/api/submissions/submit/ \
-H "Content-Type: multipart/form-data" \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-F "problem=1" \
-F "code_file=@solution.py" \
-F "language=python"
```
+ در صورت **موفقیتآمیز بودن ارسال،** پاسخ شامل شناسه ارسال و **وضعیت اولیه** است:
```bash terminal terminal
{
"submission_id": 42,
"status": "submitted"
}
```
+ در صورتی که دادههای ارسالی **نامعتبر** باشند، **خطاهای** زیر بازگردانده میشود:
```bash terminal terminal
{
"problem": ["This field is required."],
"code_file": ["No file was submitted."],
"language": ["This field is required."]
}
```
## **مشاهده وضعیت ارسال** (`/api/submissions/status/<int:submission_id>/`)
**اندپوینت مشاهده وضعیت ارسال** (`/api/submissions/status/<int:submission_id>/`) **تمام لاگهای یک ارسال** مشخص را برای کاربر ارسال بازمیگرداند**. هر لاگ شامل وضعیت اجرای کد** (`ACCEPTED`, `FAILED`, `ERROR`)، **خروجی تولید شده، خطا در صورت وجود، زمان اجرای کد و زمان ثبت لاگ** است. پاسخ به صورت لیست از لاگها بازگردانده میشود و ترتیب آن بر اساس **ترتیب صعودی زمان ثبت لاگ** (`created_at`) است. **تنها کاربر صاحب ارسال** یا **مدیر** با **توکن معتبر** میتواند به این اندپوینت دسترسی داشته باشد و اگر شناسه ارسال **وجود نداشته باشد** یا **متعلق به کاربر دیگری** باشد، پاسخ شامل **خطای** `{"error": "Submission not found"}` خواهد بود.
همچنین توجه داشته باشید که در این اندپوینت، **کلید** `output` شامل **نتایج اجرای کد برای تستکیسهای غیر نمونهی تعریف شده** برای هر سوال **به شکل دقیقا** `TestCase #n: {PASS, FAIL}` خواهد بود که همگی باید توسط `\n` به یکدیگر متصل شده و نمایش داده شوند.
```bash terminal terminal
curl -X GET http://localhost:8000/api/submissions/status/42/ \
-H "Authorization: Bearer <YOUR_TOKEN>"
```
+ **نمونه پاسخ موفق:**
```bash terminal terminal
[
{
"id": 6,
"submission": 42,
"status": "ERROR",
"output": null,
"error": "Some error text",
"created_at": "2025-09-25T06:07:17.911261Z"
},
{
"id": 7,
"submission": 42,
"status": "ACCEPTED",
"output": "TestCase #1: PASS\nTestCase #2: PASS",
"error": null,
"created_at": "2025-09-25T06:07:23.145892Z"
}
]
```
+ در صورتی که شناسه ارسال **وجود نداشته باشد** یا متعلق به کاربر دیگری باشد، خطای زیر بازگردانده میشود:
```bash terminal terminal
{
"error": "Submission not found"
}
```
## **جدول پیادهسازی**

</details>
<details class="red">
<summary>
**معرفی و پیادهسازی اپلیکیشن** `contests`
</summary>
**اپلیکیشن** `contests` **مسئول مدیریت مسابقات** است. این اپ **قابلیت ایجاد مسابقه جدید، مشاهده جزئیات مسابقه، فهرست مسابقات و مشاهده ردهبندی زنده مسابقات** را فراهم میکند. همه اندپوینتها **نیازمند احراز هویت کاربر** هستند و **تنها کاربران وارد شده** قادر به استفاده از آنها هستند.
## **ایجاد مسابقه جدید** (`/api/contests/create/`)
**ورودی** اندپوینت ایجاد مسابقه جدید (`/api/contests/create/`) **شامل فیلدهای** `name` **به عنوان نام مسابقه،** `start_time` **و** `end_time` **به صورت تاریخ و زمان** است. تمام این فیلدها باید معتبر باشند و شرط اصلی این است که `end_time` بعد از `start_time` باشد؛ در غیر این صورت **خطای اعتبارسنجی** با پیام `End time must be after start time` بازمیگرداند. در پاسخ موفق، **تمام اطلاعات مسابقه شامل** `id` و `name`، `start_time`، `end_time`، `description` نمایش دهد. این اندپوینت تنها برای کاربران وارد شده با **توکن معتبر** قابل دسترسی است و سریالایزر اعتبار دادهها را تضمین میکند.
```bash terminal terminal
curl -X POST http://localhost:8000/api/contests/create/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-d '{
"name": "Sample Contest",
"start_time": "2025-09-14T10:00:00Z",
"end_time": "2025-09-14T12:00:00Z"
}'
```
+ **خطای اعتبارسنجی در صورت اشتباه بودن زمانها:**
```bash terminal terminal
{
"end_time": "End time must be after start time"
}
```
+ در پاسخ موفق، **جزئیات مسابقه** ایجاد شده برگردانده میشود:
```bash terminal terminal
{
"id": 1,
"name": "Sample Contest",
"start_time": "2025-09-14T10:00:00Z",
"end_time": "2025-09-14T12:00:00Z",
}
```
## **مشاهده جزئیات مسابقه** (`/api/contests/<int:pk>/`)
**اندپوینت مشاهده جزئیات مسابقه** (`/api/contests/<int:pk>/`) **اطلاعات کامل یک مسابقه** مشخص را بر اساس شناسه آن ارائه میدهد. خروجی شامل `id`، `name`، `start_time`، `end_time`، `description` میباشد. کاربران برای دسترسی باید وارد سامانه باشند و در صورت درخواست برای کانتستی که وجود ندارد، **پاسخ شامل خطای** `{"detail": "Not found."}` خواهد بود. این اندپوینت به کاربر امکان میدهد جزئیات کامل مسابقه را مشاهده کند.
```bash terminal terminal
curl -X GET http://localhost:8000/api/contests/1/ \
-H "Authorization: Bearer <YOUR_TOKEN>"
```
+ **در صورت عدم وجود مسابقه با شناسه مورد نظر، خطای زیر بازگردانده میشود:**
```bash terminal terminal
{
"detail": "Not found."
}
```
+ در پاسخ موفق، جزئیات مسابقه شامل تمام فیلدهای آن نمایش داده میشود.
## **مشاهده لیست مسابقات** (`/api/contests/`)
**اندپوینت مشاهده فهرست مسابقات** (`/api/contests/`) تمام مسابقات موجود در جاجِ مَمجَجاد را به صورت آرایهای بازمیگرداند. هر عنصر آرایه شامل `id`، `name`، `start_time`، `end_time`، `description` میباشد. این اندپوینت نیز محدود به کاربران وارد شده است و به آنها اجازه میدهد تمام مسابقات فعال و گذشته را مشاهده کنند.
```bash terminal terminal
curl -X GET http://localhost:8000/api/contests/ \
-H "Authorization: Bearer <YOUR_TOKEN>"
```
+ در پاسخ موفق، **آرایهای از اطلاعات مسابقات شامل** `id`, `name`, `start_time` و `end_time` بازگردانده میشود:
```bash terminal terminal
[
{
"id": 1,
"name": "Sample Contest",
"start_time": "2025-09-14T10:00:00Z",
"end_time": "2025-09-14T12:00:00Z"
},
{
"id": 2,
"name": "Another Contest",
"start_time": "2025-09-15T09:00:00Z",
"end_time": "2025-09-15T11:00:00Z"
}
]
```
## **مشاهده ردهبندی زنده مسابقه** (`/api/contests/<int:contest_id>/standings/live/`)
**اندپوینت مشاهده ردهبندی زنده مسابقه** (`/api/contests/<int:contest_id>/standings/live/`) امکان **دریافت امتیازات شرکتکنندگان** به صورت **لحظهای** *(Streaming)* را فراهم میکند. کاربران وارد شده میتوانند با ارسال **توکن معتبر،** جریان داده را در هر ثانیه دریافت کنند که شامل **آرایهای از دیکشنریها** است و هر دیکشنری **شامل کلید** `user` **و مقدار نام کاربری شرکتکننده و کلید** `score` **به عنوان امتیاز فعلی او میباشد.** اگر مسابقه با شناسه مورد نظر وجود نداشته باشد، پاسخ **شامل خطای** `{"detail": "No Contest matches the given query."}` خواهد بود. همچنین ردهبندی بر اساس **امتیازات بدست آمده از ارسالهای در سوالات مسابقه** مشخص شده **به صورت نزولی** است.
```bash terminal terminal
curl -N http://localhost:8000/api/contests/1/standings/live/ \
-H "Authorization: Bearer <YOUR_TOKEN>"
```
+ **در صورتی که مسابقهای با شناسه مورد نظر وجود نداشته باشد، خطای زیر بازگردانده میشود:**
```bash terminal terminal
{
"detail": "No Contest matches the given query."
}
```
+ **در پاسخ موفق، دادهها به صورت استریم هر ثانیه بروزرسانی میشوند:**
```bash terminal terminal
data: [{"user": "user1", "score": 100}, {"user": "user2", "score": 90}]
```
## **جدول پیادهسازی**

</details>
<details class="grey">
<summary>
**معرفی و پیادهسازی اپلیکیشن** `lms`
</summary>
**اپلیکیشن** `lms` **مسئول مدیریت کلاسها، درسها و مسائل مرتبط با درسها** است. این اپ قابلیت *ایجاد و مدیریت کلاسها، ایجاد درسها و مسائل و ثبتنام دانشآموزان در کلاسها* را فراهم میکند. همه اندپوینتها **نیازمند احراز هویت** هستند و **بسیاری از آنها فقط برای مدیران قابل دسترسی هستند.**
## **لیست و ایجاد کلاسها** (`/api/lms/classes/`)
**ورودی** اندپوینت لیست و ایجاد کلاسها (`/api/lms/classes/`) **شامل فیلد** `name` **به عنوان نام کلاس،** `teacher` **به عنوان شناسه استاد مرتبط با کلاس و** `students` **به صورت آرایهای از شناسههای دانشآموزان است.** این اندپوینت **تنها برای مدیران** قابل دسترسی است و در پاسخ موفق، تمام جزئیات کلاس شامل `id`، `name`، **شناسه استاد** (`teacher`) **و آرایه شناسههای دانشآموزان** (`students`) بازگردانده میشود. **نام کلاس نباید خالی باشد و استاد و دانشآموزان باید همگی موجود باشند.**
```bash terminal terminal
curl -X POST http://localhost:8000/api/lms/classes/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-d '{
"name": "Sample Class",
"teacher": 1,
"students": [1]
}'
```
+ **در پاسخ موفق، جزئیات کلاس ایجاد شده برگردانده میشود:**
```bash terminal terminal
{
"id": 1,
"name": "Sample Class",
"teacher": 1,
"students": [1]
}
```
## **جزئیات کلاس** (`/api/lms/classes/<int:pk>/`)
**اندپوینت جزئیات کلاس** (`/api/lms/classes/<int:pk>/`) **اطلاعات کامل یک کلاس مشخص** را بر اساس شناسه آن ارائه میدهد و **شامل** `id`، `name`، **شناسه استاد** (`teacher`) **و آرایه دانشآموزان** (`students`) است. این اندپوینت **تنها برای مدیران** قابل دسترسی است و در صورتی که کلاس با شناسه مورد نظر وجود نداشته باشد، **پاسخ شامل خطای** `{"detail": "Not found."}` خواهد بود.
```bash terminal terminal
curl -X GET http://localhost:8000/api/lms/classes/1/ \
-H "Authorization: Bearer <YOUR_TOKEN>"
```
+ **در صورت عدم وجود کلاس، خطای زیر بازگردانده میشود:**
```bash terminal terminal
{
"detail": "Not found."
}
```
## **افزودن دانشآموز در کلاس** (`/api/lms/classes/<int:class_id>/enroll/`)
**اندپوینت افزودن دانشآموز در کلاس** (`/api/lms/classes/<int:class_id>/enroll/`) **شامل فیلد** `student_id` برای مشخص کردن شناسه دانشآموز است. **تنها مدیران** میتوانند از این اندپوینت استفاده کنند و در پاسخ موفق، پیغام `{"status": "enrolled"}` بازگردانده میشود. در صورتی که کلاس یا دانشآموز **وجود نداشته باشند،** پاسخ شامل خطای `{"error": "Class not found"}` یا `{"error": "Student not found"}` خواهد بود و اگر `student_id` ارسال نشود، خطای `{"error": "student_id is required"}` بازگردانده میشود. این اندپوینت امکان مدیریت ثبتنام دانشآموزان در کلاس مورد نظر را فراهم میکند.
```bash terminal terminal
curl -X POST http://localhost:8000/api/lms/classes/1/enroll/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-d '{
"student_id": 2
}'
```
+ **در پاسخ موفق:**
```bash terminal terminal
{
"status": "enrolled"
}
```
+ **در صورت عدم وجود کلاس یا دانشآموز:**
```bash terminal terminal
{"error": "Class not found"}
{"error": "Student not found"}
```
+ **و اگر** `student_id` **ارسال نشود:**
```bash terminal terminal
{"error": "student_id is required"}
```
## **لیست و ایجاد درسها** (`/api/lms/lessons/`)
**ورودی اندپوینت لیست و ایجاد درسها** (`/api/lms/lessons/`) **شامل** `name` **به عنوان نام درس و** `class_obj` **به عنوان شناسه کلاس** مرتبط است. این اندپوینت **تنها برای مدیران** قابل دسترسی است و در پاسخ موفق، **تمام جزئیات درس شامل** `id`، `name` و **شناسه کلاس** (`class_obj`) بازگردانده میشود تا امکان مدیریت و پیگیری درسها فراهم شود.
```bash terminal terminal
curl -X POST http://localhost:8000/api/lms/lessons/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-d '{
"name": "Lesson 1",
"class_obj": 1
}'
```
- **در پاسخ موفق، جزئیات درس جدید بازگردانده میشود.**
## **جزئیات درس** (`/api/lms/lessons/<int:pk>/`)
**اندپوینت جزئیات درس** (`/api/lms/lessons/<int:pk>/`) **اطلاعات کامل یک درس مشخص** را ارائه میدهد و **شامل** `id`، `name` و **شناسه کلاس مرتبط** (`class_obj`) است. **تنها مدیران** قادر به دسترسی به این اندپوینت هستند و در صورت **عدم وجود درس** با **شناسه مشخص،** پاسخ شامل خطای `{"detail": "Not found."}` خواهد بود.
```bash terminal terminal
curl -X GET http://localhost:8000/api/lms/lessons/1/ \
-H "Authorization: Bearer <YOUR_TOKEN>"
```
- **در صورت عدم وجود درس:**
```bash terminal terminal
{
"detail": "Not found."
}
```
## **لیست و ایجاد مسائل درس** (`/api/lms/lesson-problems/`)
**ورودی** اندپوینت لیست و ایجاد مسائل درس (`/api/lms/lesson-problems/`) **شامل** `title` **برای عنوان مسئله،** `lesson` **به عنوان شناسه درس مرتبط** و `problem` **به عنوان شناسه مسئله** دریافت میکند. **تنها مدیران** میتوانند از این اندپوینت استفاده کنند و در پاسخ موفق، جزئیات مسئله شامل `id`، `title`، **شناسه درس** (`lesson`) و **شناسه مسئله** (`problem`) بازگردانده میشود.
```bash terminal terminal
curl -X POST http://localhost:8000/api/lms/lesson-problems/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-d '{
"title": "Problem 1",
"lesson": 1,
"problem": 1
}'
```
## **جدول پیادهسازی**

</details>
<details class="green">
<summary>
**معرفی و پیادهسازی اپلیکیشن** `plagiarism`
</summary>
**اپلیکیشن** `plagiarism` مسئول **بررسی شباهت کدهای ارسال شده** توسط کاربران و تشخیص موارد **سرقت ادبی کد** *(Code Plagiarism)* است. این اپ امکان **اجرای بررسی سرقت ادبی برای یک مسئله خاص** یا **تمامی ارسالها** و **مشاهده نتایج بررسیها** را فراهم میکند. **همه اندپوینتها فقط برای مدیران قابل دسترسی هستند.**
## **اجرای بررسی تقلب** (`/api/plagiarism/run/`)
**ورودی** اندپوینت اجرای بررسی تقلب (`/api/plagiarism/run/`) **شامل فیلد اختیاری** `problem_id` برای **محدود کردن بررسی به یک مسئله** مشخص است. اگر این فیلد ارسال نشود، بررسی **روی تمامی ارسالها** انجام میشود. **تنها مدیران** میتوانند از این اندپوینت استفاده کنند و در پاسخ موفق، **پیغام** `{"status": "Plagiarism check completed"}` بازگردانده میشود تا مشخص شود فرآیند بررسی به پایان رسیده است. **در پسزمینه، جاجِ مَمجَجاد تمامی ارسالها را مقایسه میکند** و با استفاده از **مقایسه ساختار درختی** *AST،***میزان شباهت بین هر جفت ارسال** را محاسبه میکند. اگر **درصد شباهت بین دو ارسال بیشتر یا مساوی** `70%` باشد، ارسالها **به عنوان تقلب** علامتگذاری *(Flagged)* میشوند. **این روش تضمین میکند که شباهتهای ساده ناشی از تغییر نام متغیر یا فرمتبندی، باعث تشخیص تقلب نادرست نشوند و تنها شباهتهای واقعی در ساختار کد مشخص شوند.**
```bash terminal terminal
curl -X POST http://localhost:8000/api/plagiarism/run/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-d '{
"problem_id": 5
}'
```
+ اگر `problem_id` **ارسال نشود،** بررسی روی تمام ارسالها انجام میشود.
```bash terminal terminal
{
"status": "Plagiarism check completed"
}
```
## **مشاهده نتایج بررسی تقلب** (`/api/plagiarism/results/`)
**اندپوینت مشاهده نتایج بررسی تقلب** (`/api/plagiarism/results/`) خروجی را **به صورت آرایهای از نتایج** بازمیگرداند که **هر آیتم شامل** `id` به عنوان شناسه رکورد، `submission1` و `submission2` **به عنوان شناسههای دو ارسال مقایسه شده،** `similarity` **به صورت درصد شباهت بین دو کد،** `flagged` **به صورت بولین که مشخص میکند آیا دو ارسال به عنوان تقلب علامتگذاری شدهاند یا خیر و** `created_at` **به عنوان زمان ثبت نتیجه** است. **تنها مدیران** قادر به دسترسی به این اندپوینت هستند و در صورت عدم دسترسی کاربر غیرمدیر، **پاسخ شامل پیغام خطای** `{"detail": "You do not have permission to perform this action."}` خواهد بود. این خروجی به سیستم داوری امکان میدهد تا به صورت دقیق و خودکار تشخیص دهد کدام ارسالها از نظر شباهت کد **به هم نزدیک** هستند و **کدام موارد نیاز به بررسی دستی برای تعیین تقلب دارند.**
```bash terminal terminal
curl -X GET http://localhost:8000/api/plagiarism/results/ \
-H "Authorization: Bearer <YOUR_TOKEN>"
```
+ **در پاسخ موفق، آرایهای از نتایج بازگردانده میشود:**
```bash terminal terminal
[
{
"id": 1,
"submission1": 10,
"submission2": 15,
"similarity": 85.5,
"flagged": true,
"created_at": "2025-09-14T12:00:00Z"
},
{
"id": 2,
"submission1": 11,
"submission2": 12,
"similarity": 45.0,
"flagged": false,
"created_at": "2025-09-14T12:05:00Z"
}
]
```
+ **در صورت عدم دسترسی کاربر غیرمدیر:**
```bash terminal terminal
{
"detail": "You do not have permission to perform this action."
}
```
## **جدول پیادهسازی**

</details>
# **آنچه باید آپلود کنید**
+ **توجه**: **تمام مواردی** که در سیستم داوری سوال مورد ارزیابی قرار میگیرند، **به جزئیات** و **به صورت مفصل** در متن سوال به همراه ذکر مثالها توضیح داده شدهاند. مواردی که در متن سوال به انها اشارهای نشده است، مانند **نحوه پیادهسازی مدلها، سیگنالها، سریالایزرها و ...** در سیستم داوری به صورت مستقیم مورد ارزیابی قرار **نخواهند گرفت** و میتوانند به **دلخواه** شما، اما در **چارچوب سوال** پیادهسازی شوند.
+ **توجه**: سرویسهایی که در این سوال از آنها میتوانید استفاده کنید و در **فایل** `docker-compose.yml` تعریف شدهاند، همگی در **بخش معرفی سرویسهای پروژه** مشخص شده و **تعریف سرویس جدید** و یا **شخصی سازی سرویسهای موجود** با استفاده از تغییر فایل داکر کامپوز، **امکان پذیر نیست!**
+ **توجه**: شما در این سوال مجاز به ایجاد **هر گونه تغییرات جدیدی در داکرفایلها، فایل** `docker-compose.yml` **و تنظیمات از پیش انجام شدهی پروژه جنگویی نیستید** و پیادهسازیهای شما صرفا باید به **اپلیکیشنهای مشخص شده** در بخش ساختار فایلها **محدود** شود. **همچنین شما در این سوال مجاز به ایجاد اپلیکیشن جدیدی نیز نیستید.**
+ **توجه**: **کدهای وضعیت** در سیستم داوری دارای اهمیت بوده و بررسی خواهند شد. کدهای وضعیت زیر، کدهایی که هستند در پیادهسازی اندپوینتهای مختلف باید **به صورت منطقی** و **با توجه به اطلاعات هر بخش** مورد استفاده قرار گیرند:
- **کد** `403` – **Forbidden**: کاربر مجوز دسترسی به این منابع یا عملیات را ندارد.
- **کد** `400` – **Bad Request**: درخواست ارسال شده نامعتبر است یا دادهها ناقص هستند.
- **کد** `200` – **OK**: درخواست موفق بوده و پاسخ مورد انتظار بازگردانده شده است.
- **کد** `201` – **Created**: منبع جدید با موفقیت ایجاد شده است (مانند ارسال کد یا ساخت کلاس جدید).
- **کد** `401` – **Unauthorized**: کاربر احراز هویت نشده یا توکن معتبر ندارد.
- **کد** `404` – **Not Found**: منبع مورد نظر وجود ندارد یا کاربر دسترسی به آن ندارد.
+ **توجه**: پس از پیادهسازی موارد خواسته شده، **کل فایلهای را زیپ کرده و ارسال کنید.**
+ **توجه**: شما مجاز به افزودن فایل جدیدی در این ساختار **نیستید** و تنها باید تغییرات را در فایلهای موجود اعمال کنید.
+ **توجه**: که نام فایل _Zip_ اهمیتی **ندارد**.
ارسال پاسخ برای این سؤال
در حال حاضر شما دسترسی ندارید.