Motoshub · Delivery Plan · Backend
همهی تسکهای بکاند با subtask، تخمین، User Story و معیار پذیرش. مرجع رفتار: demo.shub.ir · خط لولهی الزامی تحویل: فرآیند تحویل و کیفیت · تسکهای Front
legacy/). قرارداد پاسخ ثابت: پاکت {data, links, meta}، خطاهای ۴۰۱/۴۰۳/۴۰۴/۴۲۲ با بدنهی یکسان — مرجع: Swagger زندهی PHP در motonext.shub.ir/api/v1/docs.OW_PASSWORD_PEPPER و claims {iat, exp, sub} — توکن صادرشده توسط PHP باید در Django معتبر باشد و برعکس (تست سازگاری متقابل در B2.4 اجباری است).دو مسیرِ موازی. چون PHP api/v1 همین حالا هر ۲۹۳ عملیات را پاسخ میدهد، تیم Front از فاز ۱ بهبعد به آن وصل میشود و منتظرِ Django نمیماند؛ Backend بهموازات همان قرارداد را در Django بازمیسازد و Gateway هر مسیرِ آماده را سوییچ میکند.
| فاز | محتوا | Front | Backend | موازی |
|---|---|---|---|---|
| ۰ | پایه: axios/design-system · REST-infra/auth-JWT/deploy/data-model | ۵.۵ روز | ۹ روز | ~۹ روز |
| ۱ | احراز هویت، پوسته و ناوبری، لایهی داده · endpointهای auth + مدلها | ۹.۵ روز | ۶ روز | ~۱۰ روز |
| ۲ | هسته: داشبورد، تازهها، بلاگ، کاربران/پروفایل | ۱۷ روز | ۱۳ روز | ~۱۷ روز |
| ۳ | اجتماعی: گروهها، اخبار، رویدادها، رسانه، فروم | ۱۸.۵ روز | ۲۵ روز | ~۲۵ روز |
| ۴ | ارتباط: چت، دانش، پروژه · پیامرسان، دوستان/اعلان، دانش/پروژه | ۱۵.۵ روز | ۱۶ روز | ~۱۶ روز |
| ۵ | سازمانی: قرارداد/صندوق/پژوهش/آموزش · نظرسنجی/مسابقات | ۸ روز | ۱۳ روز | ~۱۳ روز |
| ۶ | راهبری، ظاهر، گزارش، اعلان، جستجو، راهنما، دستیار، پولیش، تست | ۱۶ روز | ۴ روز | ~۱۶ روز |
| مجموع (تکنفره، بدون همپوشانی) | ~۹۰ روز | ~۸۶ روز | ~۱۰۶ روز | |
| ترکیب تیم | MVP (فاز ۰-۲) | پروتوتایپ کامل | ملاحظات |
|---|---|---|---|
| ۱ Front + ۱ Backend | ~۹-۱۰ هفته | ~۲۲-۲۶ هفته | ارزانترین؛ ریسک گلوگاه تکنفره و ریزش. توصیه نمیشود. |
| ۲ Front + ۲ Backend (خط پایه) | ۵-۶ هفته | ۱۳-۱۶ هفته | ترکیب فعلی. هر فاز دو workstream موازی؛ review متقابل ممکن است. |
| ۲F + ۲B + ۱ نفر QA/تستخودکار | ۵-۶ هفته | ۱۲-۱۴ هفته | زمان زیاد کم نمیشود اما دوبارهکاری و باگِ برگشتی بهشدت کم میشود؛ پیشنهاد PO. |
| ۳ Front + ۳ Backend + QA | ۴-۵ هفته | ۹-۱۱ هفته | بازده نزولی: مسیر بحرانی (auth→چت realtime→گزارش) کوتاهتر از این نمیشود. |
| تیم واقعی: ۴F + ۳B + ۱QA + ۱DevOps | ~۴ هفته | ~۹-۱۱ هفته | ترکیب فعلی ما. DevOps تسکهای B3/استقرار/CI را برمیدارد و Backend خالص فیچر میزند؛ QA از هفتهی ۱ گیتهای ۸ و ۹ پایپلاین را مالک است. |
| نقش | مالکیت (رشتهی کاری ثابت) | تسکها به ترتیب |
|---|---|---|
| Front ۱ (لید) | زیرساخت فرانت، auth، لایهی داده، سپس چت | F1 → F3 → F5 → F15 → F20.5 |
| Front ۲ | پوسته/ناوبری + هستهی محتوا | F2 → F4 → F6 → F7 → F8 |
| Front ۳ | فضاهای اجتماعی | F9 → F10 → F11 → F12 → F13 → F14 |
| Front ۴ | دانش/پروژه + ماژولهای سازمانی + راهبری | F16 → F17 → F18 → F19 → F20.1-3 |
| Backend ۱ (لید) | زیرساخت REST + auth مشترک + پیامرسان | B1 → B2 → B4 → B5 → B14 |
| Backend ۲ | هستهی محتوا: کاربران/فید/بلاگ/اخبار | B6 → B7 → B8 → B9 → B15 |
| Backend ۳ | اجتماعی + سازمانی: گروه/رویداد/رسانه/فروم → دانش/پروژه → سازمانی | B10 → B11 → B12 → B13 → B16 → B17 → B18 |
| QA | مالک گیتهای ۸-۹ پایپلاین: کالکشن Postman هر ماژول، تست قرارداد، E2E (Playwright) مسیرهای حیاتی، رگرسیون هفتگی | از هفته ۱ موازی با همه؛ B19.2 و F20.6 با اوست |
| DevOps | B3 کامل + CI enforcement + staging دو سرویس + مانیتورینگ/لاگ + بکاپ + سوییچ Gateway | B3 → CI هر دو ریپو → B19.3 → پایداری production |
پیشفرضهایی که هر دو تیم باید رعایت کنند تا کارها به هم برسند.
api/v1 کار میکند؛ نباید بداند پاسخ از PHP میآید یا Django. همهی مسیرها از libs/axios.ts با baseURL=/api/v1 و rewrite در next.config.ts.
OW_PASSWORD_PEPPER و claims {iat, exp, sub:userId}. Django باید همین را verify (و در فاز بعد صادر) کند، نه صرفاً خواندنِ ow_base_user_auth_token.
{data, links, meta} با meta.current_page/per_page/total؛ خطاها با کدهای 401/403/404/422 و بدنهی یکسان. مرجعِ فیلدها: Swagger روی motonext.shub.ir/api/v1/docs/index — که در راستیآزماییِ ۱۴۰۵/۰۵/۱۱ پاسخِ ۴۰۴ داد و باید بازگردانده شود (جزئیات). تا آن زمان مرجعِ فیلدها = کنترلرها و Resourceهای ow_plugins/*/src/Http در برنچ API..
پیشنیازِ هر چیزِ دیگر. بدون اینها هر تسکِ بعدی روی شن ساخته میشود. دو تیم موازی کار میکنند.
قبل از هر منبع، لایههای عرضیِ DRF باید ساخته شوند تا همهی endpointها دقیقاً قراردادِ PHP را بدهند. الان هیچکدام وجود ندارد.
EARS: هرگاه یک درخواستِ فهرست پردازش شود، سامانه باید پاسخ را در پاکتِ {data, links, meta} با meta.current_page/per_page/total بازگرداند.
| # | کار | جزئیات فنی | تخمین |
|---|---|---|---|
| B1.1 | Pagination class | PageNumberPagination سفارشی با خروجیِ دقیقِ data/links/meta | ۵ ساعت |
| B1.2 | Exception handler | هندلرِ سراسری برای فرمتِ یکسانِ خطا در ۴۰۱/۴۰۳/۴۰۴/۴۲۲ | ۵ ساعت |
| B1.3 | فیلتر/جستجو/مرتبسازی | backendهای مشترک با نامپارامترهای یکسان با PHP | ۶ ساعت |
| B1.4 | CORS و هدرها | نصب/پیکربندی django-cors-headers (نصب نیست)، هدرهای امنیتی | ۳ ساعت |
| B1.5 | آپلود فایل/رسانه | MultiPartParser، اعتبارسنجی نوع/اندازه، مسیرِ سازگار با اکسوال | ۶ ساعت |
| B1.6 | پایهی تست | راهاندازی pytest-django + factory + APIClient مبنا | ۵ ساعت |
بلوکِ SIMPLE_JWT در config/settings/base.py نیست. Django باید همان JWT HS256 با رازِ مشترک و claimهای اکسوال را verify کند تا توکنِ PHP در Django معتبر باشد و بالعکس.
| # | کار | جزئیات فنی | تخمین |
|---|---|---|---|
| B2.1 | پیکربندی SimpleJWT | HS256، SIGNING_KEY = sha256(OW_PASSWORD_PEPPER)، claim sub→userId، طولِ عمرِ منطبق | ۶ ساعت |
| B2.2 | Authentication class | کلاسِ سفارشیِ DRF: verify JWTِ PHP و resolve کاربرِ legacy | ۶ ساعت |
| B2.3 | Permission mapping | ترجمهی مجوزِ پلاگینیِ اکسوال (isAuthorized) به permissionهای DRF | ۶ ساعت |
| B2.4 | تستِ سازگاری متقابل | توکنِ رازِ PHP در Django بپذیرد؛ بدونامضا/منقضی رد شود | ۶ ساعت |
production.py خالی است؛ docker/Dockerfile ENTRYPOINT اشتباه دارد (shub.asgi، Celery SharifAutoEDA — کپی از پروژهی دیگر)؛ requirements فاقد gunicorn/uvicorn/pytest است.
| # | کار | جزئیات فنی | تخمین |
|---|---|---|---|
| B3.1 | production.py | DEBUG=False، ALLOWED_HOSTS، DB از env، static/media، logging | ۴ ساعت |
| B3.2 | Dockerfile | اصلاحِ ENTRYPOINT، حذف ارجاعِ Celery غلط، multi-stage تمیز | ۴ ساعت |
| B3.3 | requirements و env | افزودن gunicorn/uvicorn/pytest؛ اصلاحِ .env.example برای دو DB | ۳ ساعت |
| B3.4 | healthcheck و اجرای محلی | تأیید بالاآمدنِ کانتینر، /api/v1/health، اتصالِ دو DB | ۵ ساعت |
دروازهی ورود و اسکلتِ همهی صفحههای بعدی. تا اینجا تمام نشود، هیچ صفحهی محتوایی قابلِاتکا نیست.
فقط /me و /health هست. مجموعهی کاملِ auth منطبق بر قراردادِ PHP، روی مدلِ کاربرِ legacy.
| # | کار | جزئیات فنی | تخمین |
|---|---|---|---|
| B4.1 | login | POST /auth/login: راستیِ رمز بهشیوهی اکسوال (pepper+hash)، صدور JWT | ۶ ساعت |
| B4.2 | refresh + logout | POST /auth/refresh، ابطال، چرخشِ refresh | ۵ ساعت |
| B4.3 | register | POST /auth/register: اعتبارسنجی، ایجادِ کاربر در جداولِ اکسوال | ۶ ساعت |
| B4.4 | change-password + permissions | PATCH /auth/change-password، GET /auth/permissions | ۴ ساعت |
| B4.5 | تست | login/refresh/register/۴۲۲؛ برابری با پاسخِ PHP | ۳ ساعت |
الان فقط ۲ جدول (ow_base_user, ow_base_user_auth_token) با managed=False نگاشت شده. سیاستِ داده تثبیت شود: خواندنِ مستقیم از ow_ در برابر مهاجرت به motoshub_new؛ و مدلهای پایه ساخته شوند.
| # | کار | جزئیات فنی | تخمین |
|---|---|---|---|
| B5.1 | سندِ تصمیمِ داده (ADR) | کدام منابع مستقیم از ow_، کدام مهاجرت؛ روترِ DB | ۴ ساعت |
| B5.2 | introspect جداول | inspectdb روی جداولِ کلیدی، پاکسازیِ مدلها، managed=False | ۶ ساعت |
| B5.3 | مدلِ کاربر و پروفایل | تکمیلِ LegacyUser، پروفایل/آواتار، رابطهها | ۶ ساعت |
| B5.4 | سرویسهای مشترک | لایهی سرویسِ پایه، تراکنش روی دو DB، تستِ اتصال | ۴ ساعت |
پرتکرارترین بخشهایی که کاربر روزانه میبیند: داشبورد، تازهها، بلاگ، کاربران/پروفایل. رسیدن تا اینجا = «محصولِ قابلِنمایش».
منبعِ پرکاربردِ همهی بخشها. مطابقِ endpointهای PHP: فهرست، پروفایل، ویرایش، آواتار، مسدودها و نشستها.
| # | کار | جزئیات فنی | تخمین |
|---|---|---|---|
| B6.1 | Model + Serializer | نگاشتِ کاربر/پروفایل/فیلدهای پویا (ow_base_question*) | ۶ ساعت |
| B6.2 | list + detail | GET /users، GET /users/:id با فیلتر/جستجو/صفحهبندی | ۶ ساعت |
| B6.3 | update + avatar | PATCH /users/me، POST /users/me/avatar | ۶ ساعت |
| B6.4 | blocked + sessions | /users/blocked، /sessions | ۴ ساعت |
| B6.5 | تست + مجوز | تستهای دسترسی/مالکیت، برابری با PHP | ۴ ساعت |
پیچیدهترین منبعِ فاز: فید، انتشار با پیوست، لایک/نظر/فوروارد و دستهبندیِ انتشارِ عمومی (منطبق با فیچرِ iisnewsfeedpin).
| # | کار | جزئیات فنی | تخمین |
|---|---|---|---|
| B7.1 | مدلهای فید | نگاشتِ ow_newsfeed_*، اکشن/آیتم/محتوا | ۶ ساعت |
| B7.2 | list فید | GET /feed با scope (feed/site/user)، صفحهبندی | ۶ ساعت |
| B7.3 | create + attachment | POST /feed، پیوستِ PDF/Word/عکس | ۸ ساعت |
| B7.4 | لایک/نظر/فوروارد | endpointهای تعامل منطبق بر PHP | ۸ ساعت |
| B7.5 | دستهبندیِ انتشار | منبعِ دستهی درختی + فیلترِ فیدِ عمومی بر اساس دسته | ۸ ساعت |
| B7.6 | تست | انتشار/تعامل/فیلترِ دسته | ۴ ساعت |
| # | کار | جزئیات فنی | تخمین |
|---|---|---|---|
| B8.1 | Model + Serializer | نگاشتِ ow_blogs_post و نظرات/برچسب | ۴ ساعت |
| B8.2 | CRUD | GET/POST/PATCH/DELETE /blogs، GET /blogs/:id | ۸ ساعت |
| B8.3 | مالکیت/مجوز | چکِ مالکیت در ویرایش/حذف، منطبق بر منطقِ PHP | ۴ ساعت |
| B8.4 | تست | lifecycle + دسترسی | ۴ ساعت |
بخشهای تعاملیِ سازمان: گروهها، اخبار، رویدادها، رسانه، فروم. الگوهای فاز ۲ اینجا تکرار و مقیاسپذیر میشوند.
| # | کار | جزئیات فنی | تخمین |
|---|---|---|---|
| B9.1 | Model + Serializer | نگاشتِ منبعِ خبر و دسته/رسانه | ۴ ساعت |
| B9.2 | CRUD + list | GET/POST/PATCH /news، /news/:id | ۸ ساعت |
| B9.3 | مجوزِ انتشار | محدودسازیِ انتشار به نقشِ مدیرِ محتوا | ۴ ساعت |
| B9.4 | تست | lifecycle + دسترسی | ۴ ساعت |
| # | کار | جزئیات فنی | تخمین |
|---|---|---|---|
| B10.1 | مدلها | گروه/عضویت/نقش/دعوت، نگاشتِ جداولِ اکسوال | ۶ ساعت |
| B10.2 | CRUD گروه | GET/POST/PATCH/DELETE /groups، /groups/:id | ۸ ساعت |
| B10.3 | اعضا/عضویت | /members، /join، /invites، نقش/مجوز | ۸ ساعت |
| B10.4 | دیوار/فایل | فیدِ گروه، /files آپلود/دانلود | ۸ ساعت |
| B10.5 | تست | عضویت/مجوز/فایل | ۴ ساعت |
قراردادِ PHP و تستهای Pest موجودند (نمونه: EventControllerTest). این تسک بازسازیِ همان در Django است.
| # | کار | جزئیات فنی | تخمین |
|---|---|---|---|
| B11.1 | مدلها | رویداد/دعوت/شرکتکننده/فایل | ۶ ساعت |
| B11.2 | CRUD | GET/POST/PATCH/DELETE /events، اعتبارسنجیِ زمان | ۸ ساعت |
| B11.3 | دعوت/RSVP | /invites، حضور، سطحِ دید/دعوت | ۸ ساعت |
| B11.4 | تست معادلِ Pest | پورتِ سناریوهای EventControllerTest به pytest | ۴ ساعت |
در PHP کامل و امنشده است (اصلاحاتِ IDOR و چکِ مالکیت در PhotoService/AlbumService). Django باید همان قرارداد و چکهای مالکیت را بدهد.
| # | کار | جزئیات فنی | تخمین |
|---|---|---|---|
| B12.1 | مدلها | عکس/آلبوم/کاور/ویدیو، نگاشتِ ow_photo_* | ۶ ساعت |
| B12.2 | آلبوم CRUD | /albums با چکِ مالکیت (مثلِ PHP: مالک یا ناظر) | ۸ ساعت |
| B12.3 | عکس CRUD + آپلود | /photos، آپلود، بهروزرسانیِ کاور، PATCH جزئی (بدون nullکردن) | ۸ ساعت |
| B12.4 | ویدیو | /videos CRUD + پردازش/embed | ۶ ساعت |
| B12.5 | تست IDOR | عدمِ دسترسیِ غیرمالک به ویرایش/حذف | ۴ ساعت |
| # | کار | جزئیات فنی | تخمین |
|---|---|---|---|
| B13.1 | مدلها | بخش/موضوع/پست، نگاشتِ ow_forum_* | ۶ ساعت |
| B13.2 | موضوعها | GET/POST /forum/topics، دستهبندی | ۸ ساعت |
| B13.3 | پستها | /topics/:id/posts، پاسخ/نقلقول | ۸ ساعت |
| B13.4 | مدیریت + تست | قفل/پین/انتقال با مجوز؛ تست | ۴ ساعت |
ابزارهای کارِ روزمره: پیامرسان، مدیریت دانش، مدیریت پروژه (کانبان).
| # | کار | جزئیات فنی | تخمین |
|---|---|---|---|
| B14.1 | مدلها | گفتگو/پیام/عضو/وضعیتِ خوانده، نگاشتِ ow_mailbox_* | ۶ ساعت |
| B14.2 | گفتگوها | GET /conversations، ساخت، شمارشِ نخوانده | ۶ ساعت |
| B14.3 | پیامها | /messages ارسال/فهرست، صفحهبندیِ تاریخچه | ۸ ساعت |
| B14.4 | بیدرنگ | Channels/WebSocket یا long-poll؛ پیوست | ۱۰ ساعت |
| B14.5 | تست | ارسال/خواندن/دسترسیِ عضو | ۴ ساعت |
| # | کار | جزئیات فنی | تخمین |
|---|---|---|---|
| B15.1 | دوستان | /friends: درخواست/تأیید/حذف، نگاشتِ ow_friends_* | ۸ ساعت |
| B15.2 | اعلانها | GET /notifications، علامتِ خوانده، شمارش | ۸ ساعت |
| B15.3 | تولیدِ اعلان | hookهای رویداد (لایک/نظر/دعوت) → اعلان | ۶ ساعت |
| B15.4 | تست | چرخهی دوستی/اعلان | ۴ ساعت |
| # | کار | جزئیات فنی | تخمین |
|---|---|---|---|
| B16.1 | دانش | /knowledge/documents CRUD + دسته + آپلود | ۸ ساعت |
| B16.2 | پروژه | /projects CRUD + اعضا + وضعیت | ۸ ساعت |
| B16.3 | وظیفه/کانبان | ستون/کارت/ترتیب، endpointِ جابهجایی و تخصیص | ۸ ساعت |
| B16.4 | تست | CRUD + persistِ ترتیب | ۴ ساعت |
motoshub_new.)بخشهای تخصصیِ سازمان: قراردادها، صندوقِ نوآوری، پژوهش، آموزش، نظرسنجی/مسابقات/ارزیابی.
| # | کار | جزئیات فنی | تخمین |
|---|---|---|---|
| B17.1 | قراردادها/تیکت | /tickets و منبعِ قرارداد، گردشکارِ وضعیت | ۱۲ ساعت |
| B17.2 | صندوق | /cfps، /grants: فراخوان/درخواست/داوری | ۱۲ ساعت |
| B17.3 | پژوهش/فناوری | /technologies، /journal-* | ۱۲ ساعت |
| B17.4 | آموزش | دوره/ثبتنام/پیشرفت | ۱۲ ساعت |
| B17.5 | تست | CRUD + گردشکار | ۴ ساعت |
| # | کار | جزئیات فنی | تخمین |
|---|---|---|---|
| B18.1 | نظرسنجی | /polls: ساخت/رأی/نتیجه | ۸ ساعت |
| B18.2 | مسابقات | /competitions: ثبت/داوری | ۸ ساعت |
| B18.3 | ارزیابی | /evaluations | ۶ ساعت |
| B18.4 | تست | رأی/نتیجه/دسترسی | ۴ ساعت |
بخشهای مدیریتی و پایانی که محصول را «کامل» و آمادهی تحویل میکنند.
| # | کار | جزئیات فنی | تخمین |
|---|---|---|---|
| B19.1 | جستجوی سراسری | GET /search چنددسته (کاربر/بلاگ/فروم/...)، صفحهبندی | ۸ ساعت |
| B19.2 | برابریِ قرارداد | تستِ diffِ پاسخِ Django با PHP روی endpointهای کلیدی | ۶ ساعت |
| B19.3 | سوییچِ Gateway | مستندِ گذارِ مسیربهمسیر از PHP به Django بدونِ downtime | ۶ ساعت |
| B19.4 | OpenAPI + تحویل | همترازیِ drf-spectacular با قراردادِ v1، انتشارِ داکِ نهایی | ۶ ساعت |
تطبیقِ صفحههای demo.shub.ir با فهرستِ B1–B19 نشان داد ماژولِ تیکت در هیچکدام از دو تیم تسک نداشت، با اینکه در PHP آماده است. مانندِ سمتِ Front، این تسک با شمارهی تازه آمده و در جمعِ فازهای ۰ تا ۶ حساب نشده است.
۱۲ عملیاتِ آماده در برنچ API (/tickets، /tickets/{id}، /ticket-categories، /ticket-orders) که هنوز روی production مستقر نشدهاند. کارِ Backend اینجا = استقرارِ همانها و سپس بازسازی در Django طبقِ همان قرارداد.
| # | کار | جزئیات فنی | تخمین |
|---|---|---|---|
| B20.1 | استقرارِ مسیرهای PHP | فعالسازیِ iisticketing در استقرارِ production و تاییدِ پاسخها | ۴ ساعت |
| B20.2 | مدل و فهرست | تیکت/دسته/پاسخ، GET /tickets با فیلترِ وضعیت و صفحهبندی | ۵ ساعت |
| B20.3 | ایجاد و گردشِ وضعیت | POST /tickets، تغییرِ وضعیت، مجوزِ مالک/پشتیبان (IDOR) | ۵ ساعت |
| B20.4 | تست | سناریوی موفق + ۴۰۱/۴۰۳/۴۲۲ + دسترسیِ کاربرِ دیگر | ۲ ساعت |
api/v1 فقط auth/login، auth/me و auth/permissions دارد — refresh، logout، register و change-password در PHP وجود ندارند. چون F3 (فاز ۱، P1) به هر چهارِ اینها وابسته است، B4 عملاً روی مسیرِ بحرانیِ کلِ برنامه قرار میگیرد. جزئیات: وضعیت زنده.