D16 بخشهای (b) و (c) — خلاصه gapها
این سند خلاصه بررسی field-by-field بخشهای باقیمانده فاز ۱ هست.
طبق D16: «قبل از fix، خلاصه gap به صاحبکار نشون داده بشه.»
تاریخ: ۱۳۸۵/۰۷/۱۷ (2026-10-08)
(b) محصولات / دستهبندی / واریانت
نتیجه: ✅ تقریباً کامل — gap عملکردی بحرانی نداره
| عملیات |
reference |
target |
وضعیت |
| CRUD محصول |
ProductController store/update/destroy |
admin-products.service.ts create/update/remove |
✅ |
| لیست/ساخت/ویرایش واریانت |
addVariant, getVariants |
createVariant, listVariants, variantsOf |
✅ |
| تصاویر محصول (۴ slot) |
gallery + mobile featured |
imageCreateData + syncImages با ۴ role |
✅ |
| تصویر واریانت |
image_id روی واریانت |
imageId در variantCreateData |
✅ |
| اجرت (percentage_pay) |
percentage_pay |
defaultWagePercent |
✅ |
| تغییر دستهجمعی اجرت |
changePercent |
changePercent / changePercentCount |
✅ |
| برند CRUD |
BrandController |
admin-misc brands |
✅ |
| دستهبندی CRUD |
CategoryController |
admin-categories |
✅ |
| Collection (ciny) |
CinyController |
collections در product service |
✅ |
| حذف محصول + حفاظت |
حذف بدون بررسی |
حذف با بررسی سفارش |
✅ بهتر |
product_code unique |
implicit در DB |
@unique در schema |
✅ |
offer_day toggle |
changeOffer |
ندارد |
⏸️ ← فیلد در schema نیست |
is_exist toggle |
changeIsExist |
ندارد |
⏸️ ← فیلد در schema نیست |
has_warranty toggle |
changeHasWarranty |
ندارد |
⏸️ ← فیلد در schema نیست |
توضیح toggleها:
سه فیلد offer_day, is_exist, has_warranty در reference وجود دارن ولی:
- هیچکدوم در Prisma schema تعریف نشدن
- اینا فیلدهای خردهفروشی/فروشگاه اینترنتی هستن (پیشنهاد ویژه، موجود در سایت، دارای گارانتی)
- طبق D16 و D13، فروشگاه اینترنتی خارج از scope فاز ۱ هست → ⏸️ نیازی به اقدام نیست
(c) اسناد مالی / کاربران / شهرها / شعب / کارگاهها / پروموشن / SMS / اعلان / گزارش
§5 — اسناد مالی (Cash → AdminDocuments)
| عملیات |
reference (CashController) |
target (admin-documents.service.ts) |
وضعیت |
| لیست اسناد |
index + TableEngine |
list با TableService |
✅ |
| ساخت سند |
store با ۴ نوع |
create با LedgerService delegation |
✅ |
| ویرایش سند |
update |
update (با قفل تایید) |
✅ بهتر |
| toggle تایید |
toggleConfiremCash + SMS/notification |
toggleConfirm با LedgerService |
✅ |
| حذف سند |
destroy |
remove (رد تاییدشده) |
✅ بهتر |
| تبدیل عیار (ayar) |
type 1: value*ayar/750 |
در LedgerService |
✅ |
| تبدیل نقد→طلا |
type 4: price/(pricePerGram/4.331802) |
در LedgerService |
✅ |
| SMS تایید سند |
sendSms در toggleConfiremCash |
❓ باید بررسی بشه |
⚠️ کوچک |
| کیفپول |
ندارد |
listWallet / queryCustomers |
➕ اضافه |
Gap واقعی: ارسال SMS هنگام تایید/عدم تایید سند. بررسی لازم — ممکنه از طریق D26 relay انجام بشه.
§6 — مشتریان (Customers)
قبلاً انجام شده — بخش (a) فاز ۱. Gap ندارد.
§7 — کاربران / دسترسیها / شهرها / شعب / کارگاهها
کاربران (Users)
| عملیات |
reference (UserController) |
target (admin-users.service.ts) |
وضعیت |
| CRUD کاربر |
store/update/destroy + validation |
create/update/remove + D0 name parts |
✅ بهتر |
fname + lname |
جداگانه |
D0 fullName + nameFirst/nameLast |
✅ |
| رمز عبور min 6 |
validation rule |
passwordHash با bcrypt |
✅ |
| mobile unique |
validation rule |
@unique در schema |
✅ |
ut (نوع کاربر) |
must exist in config_statics |
AdminRole enum |
✅ |
| غیرفعالسازی |
ندارد |
session revocation + audit trail |
➕ بهتر |
| SalesExpertProfile |
ندارد |
D17 — ➕ اضافه |
➕ |
دسترسیها (Permissions)
| عملیات |
reference (PermissionController) |
target (admin-users.service.ts + IAM) |
وضعیت |
| خواندن دسترسیها |
get() / getByUt() |
findPermissions |
✅ |
| ثبت/حذف دسترسی |
create diff + store firstOrCreate + destroy |
syncPermissions |
✅ |
has() check |
وجود بررسی |
guard middleware |
✅ |
شهرها (Cities)
| عملیات |
reference (CitiesController) |
target (admin-misc) |
وضعیت |
| CRUD شهر |
store/update/destroy |
create/update/remove + loop prevention |
✅ بهتر |
| parent/level |
parent, level |
parentId |
✅ |
| percent/percent_aux |
هر دو فیلد |
هر دو فیلد |
✅ |
_getP() (inherit percent) |
walk up tree |
getCityPercent walk up tree |
✅ |
| referential integrity |
ندارد |
بررسی فرزند قبل از حذف |
➕ بهتر |
| CityTreeSelect |
dropdown ساده |
✅ component درختی جدید |
✅ بهتر |
شعب (Branches)
| عملیات |
reference (BranchController) |
target (admin-branches.service.ts) |
وضعیت |
| لیست + table |
POST branch/table |
listBranches با TableService |
✅ |
| ساخت شعبه |
POST branch |
createBranch |
✅ |
| ویرایش شعبه |
PUT branch/{id} |
updateBranch |
✅ |
| toggle فعال/غیرفعال |
GET branch/active/{id} |
toggleBranchActive |
✅ |
| مدیر شعبه |
user_id → branch_id update |
assignBranchManager transaction |
✅ بهتر |
| شهر شعبه |
city_id |
cityId |
✅ |
کارگاهها (Workshops)
| عملیات |
reference (WorkshopController) |
target (admin-branches.service.ts) |
وضعیت |
| لیست + table |
POST workshop/table |
listWorkshops با TableService |
✅ |
| ساخت کارگاه |
POST workshop (+ inline supervisor) |
createWorkshop + upsertSupervisor |
✅ |
| ویرایش کارگاه |
PUT workshop/{id} |
updateWorkshop |
✅ |
| toggle فعال/غیرفعال |
GET workshop/active/{id} |
toggleWorkshopActive |
✅ |
| سرپرست inline |
user_fname/lname/phone |
upsertSupervisor + mobile clash check |
✅ بهتر |
§8 — پروموشن / SMS / اعلان / خبرنامه / ثابتها
پروموشن (Promotions)
| عملیات |
reference (PromotionController) |
target (admin-promotions.service.ts) |
وضعیت |
| CRUD |
store/update/destroy |
create/update/remove |
✅ |
| ۴ نوع scope |
product/category/brand/customer |
enum mapping |
✅ |
| PromotionItem denorm |
PromotionProduct |
via Prisma relations |
✅ |
| exclusion management |
IgnoreController |
admin-promotions exclusions |
✅ |
| auto-promotion (id=17) |
hardcoded |
Setting key |
✅ بهتر |
SMS
| عملیات |
reference (SmsController) |
target (admin-misc) |
وضعیت |
| ارسال دستهجمعی |
batch (type 0,1,2,9) |
sendSms با audience resolution |
✅ |
| لیست SMSهای امروز |
index |
listSms |
✅ |
%name substitution |
در batch |
❓ |
⚠️ بررسی لازم |
getCustomer campaign |
hardcoded promo |
❌ ندارد |
⏸️ dead code در reference |
sendSmsToOther |
arbitrary number |
❓ covered by type 9? |
⚠️ بررسی لازم |
| SMS gateway |
Trez driver |
relay driver (D26) |
✅ |
اعلان (Notifications)
| عملیات |
reference (NotifyController) |
target (admin-misc) |
وضعیت |
| ساخت اعلان |
store (6 type_send) |
createNotification + notifyCustomer |
✅ |
| لیست/خواندن |
index/show/read |
listNotifications / findNotification / markRead |
✅ |
| Firebase push |
Notify::store() |
❌ ندارد |
⚠️ Firebase push ندارد |
خبرنامه (Newsletter)
| عملیات |
reference |
target |
وضعیت |
| لیست مشترکین |
NewsletterController |
listNewsletter |
✅ |
ثابتها و تنظیمات (Consts/Settings)
| عملیات |
reference |
target |
وضعیت |
| خواندن/نوشتن/حذف |
ConfigStaticController |
getConst / setConst / removeConst |
✅ |
| اسلایدر موبایل |
بخشی از consts |
endpoint مجزا با permission مجزا |
✅ بهتر |
| برندها |
BrandController |
admin-misc brands |
✅ |
§9 — گزارشها (Reports)
| عملیات |
reference (ReportController) |
target |
وضعیت |
| Excel export (32 ستون) |
getOrderItemWithDetails → xlsx |
❌ ندارد |
❌ gap |
| date filter |
start_date / end_date |
❌ |
❌ |
| Jalali dates |
Jalalian::forge |
❌ |
❌ |
این بزرگترین gap باقیماندهست. یه Excel export که ۳۲ ستون از OrderItem + Cash ترکیب میکنه. ولی:
- این گزارش فقط خروجی xlsx هست و هیچ UI مدیریتی خاصی نداره
- target از سیستم Ledger استفاده میکنه نه Cash مستقیم
- پیادهسازی Excel export نیازمند وابستگی جدید هست (مثل
exceljs)
جمعبندی gapها
Gapهایی که نیاز به اقدام دارن:
| # |
gap |
اولویت |
حجم کار |
| 1 |
Excel report — ۳۲ ستونی ندارد |
متوسط |
بزرگ (endpoint جدید + exceljs) |
| 2 |
Firebase push notification — ارسال push به موبایل ندارد |
کم (PWA port) |
متوسط |
| 3 |
SMS تایید سند — ارسال SMS هنگام confirm/unconfirm |
کم |
کوچک |
| 4 |
SMS %name substitution — جایگزینی نام مشتری در متن |
کم |
کوچک |
Gapهایی که خارج از scope فاز ۱ هستن (⏸️):
| # |
gap |
دلیل |
| 1 |
offer_day / is_exist / has_warranty toggles |
فروشگاه اینترنتی (D13) |
| 2 |
getCustomer campaign SMS |
dead code در reference |
| 3 |
Firebase push |
نیازمند PWA port |
نتیجه:
بخش (b): ✅ کامل — هیچ gap عملکردی B2B ندارد.
بخش (c): ✅ تقریباً کامل — فقط Excel report واقعاً ندارد.
بقیه gapها (SMS confirm، Firebase) یا خارج از scope هستن یا خیلی کوچک.
اقدامات انجام شده (2026-10-08):
۱. ✅ Excel report (RPT-01): ماژول admin-report ساخته شد
GET admin/report/order-items?start_date=...&end_date=...
- ۳۲ ستون فارسی، ترکیب OrderItem + LedgerEntry
- Jalali dates، RTL sheet، فیلتر تاریخ
- وابستگی
exceljs اضافه شد
- بازبینی بعدی:
- وزن: سیستم قدیم در این گزارش وزن هر قلم را دوباره بر تعداد تقسیم میکرد، در حالی که وزن ذخیرهشده خودش وزن یک عدد است: ۸۱ از ۸۲ ردیف چندتایی در دیتای قدیم این را نشان میدهند. در نتیجه ستون «بدهکار» کمتر از واقع بود. این خطا تکرار نشد.
- «درصد»: مثل سیستم قدیم، اجرت منهای تخفیف است.
- تاریخ: «تا تاریخ» کل همان روز را شامل میشود، و تاریخ نامعتبر خطای روشن برمیگرداند.
- دکمه: «دریافت فایل اکسل» در صفحهی گزارش تجمیعی گذاشته شد.
۲. ✅ SMS تایید سند (SMS-01): notifyDocumentConfirm در admin-documents.service.ts
- تایید: «سند مالی شما توسط مدیر سیستم تایید شد.»
- رد: «سند مالی شما توسط مدیر سیستم رد شد.»
۳. ✅ SMS %name (SMS-02): جایگزینی نام در sendSms در admin-misc.service.ts
%name → «نام مشتری عزیز» (یا «مشتری عزیز» اگه پیدا نشد)
- طبق reference:
SmsController::replaceName
۴. ⏸️ Firebase push (PUSH-01): به فاز PWA موکول شد.