Skip to content

behnam391/repair-saas-final

Repository files navigation

پنل تعمیرگاه موبایل (Repair Shop SaaS)

نرم‌افزار مدیریت تعمیرگاه موبایل با گردش‌کار چندتخصصی (سخت‌افزار / نرم‌افزار / تخصصی برد و هارد)، چندمستأجری (چند مغازه روی یک سیستم، با جداسازی کامل داده‌ها)، و ارسال خودکار پیامک هنگام آماده شدن دستگاه.

وضعیت فعلی این کد

✅ آماده:

  • مدل دیتابیس کامل (مغازه، کاربران با نقش، مشتری، تیکت تعمیر، تاریخچه گردش‌کار، انبار، فاکتور)

  • احراز هویت (ورود با شماره موبایل + رمز عبور)، هر کاربر فقط به داده‌های مغازه خودش دسترسی دارد

  • API کامل: پذیرش دستگاه، شروع کار، ارجاع بین بخش‌ها، تکمیل و ارسال پیامک، تحویل، انبار، فاکتور

  • داشبورد Kanban تیکت‌ها (صفحه /tickets) — کاملاً وصل به API واقعی

  • صفحه انبار قطعات (/inventory)

  • صفحه صدور و تاریخچه فاکتور (/invoices) — انتخاب تیکت آماده‌تحویل، افزودن قطعات از انبار، محاسبه خودکار جمع کل

  • پنل مدیریت (/admin, فقط برای نقش OWNER) — افزودن کارمند با نقش تخصصی، گزارش بهره‌وری و درآمد هر تعمیرکار، درآمد ۳۰ روز اخیر مغازه

  • بازار سراسری تعمیرکاران (/market) — پستِ درخواست/پیشنهاد برد، فایل فلش، قطعه یا مشاوره تخصصی، قابل مشاهده توسط همه تعمیرکاران عضو در سراسر ایران، با فیلتر استان/شهر/دسته و پاسخ‌دهی + تماس مستقیم

  • ثبت‌نام عمومی (/signup) — هر مغازه خودش می‌تواند ثبت‌نام کند و روی پلن رایگان شروع کند

  • پرداخت و ارتقای پلن (/admin/billing) — اتصال واقعی به درگاه زرین‌پال، ارتقا به پلن حرفه‌ای/تجاری

  • پنل مدیریت پلتفرم برای شما (/superadmin, لاگین جدا در /superadmin/login) — لیست همه مغازه‌های مشترک، درآمد کل از اشتراک‌ها، امکان تعلیق/فعال‌سازی هر مغازه. این پنل کاملاً از پنل /admin (مخصوص مدیر هر مغازه) جداست و با یک نوع لاگین متفاوت (PlatformAdmin) کار می‌کند

  • محدودیت سهمیه ماهانه بر اساس پلن (رایگان: ۱۰، حرفه‌ای: ۲۰۰، تجاری: عملاً نامحدود)

  • دکمه خروج از سیستم و حالت شب/روز (تم روشن و تیره، ذخیره در مرورگر کاربر)

  • پشتیبانی PWA پایه — قابل نصب روی صفحه اصلی گوشی، آیکون و صفحه شروع سفارشی، کش پایه برای اتصال ناپایدار

  • پرونده گوشی با IMEI (/device-lookup) — جستجوی سراسری تاریخچه تعمیر یک دستگاه در همه مغازه‌های عضو، به‌علاوه:

    • گزارش هشدار جمعی (مسروقه / بدهی قسط) — ⚠️ این یک استعلام رسمی و قانونی نیست، صرفاً گزارش‌های ثبت‌شده توسط سایر تعمیرکاران/فروشندگان است و باید همیشه با همین توضیح به کاربر نمایش داده شود
    • زنجیره خرید و فروش — فروشندگان می‌توانند معاملات (فروشنده → خریدار، قیمت، تاریخ) را روی یک IMEI ثبت کنند
    • مدل Shop.type اضافه شده (REPAIR | DEALER | BOTH) برای توسعه بعدی داشبورد جداگانه فروشندگان
  • بازیابی رمز عبور با کد پیامکی (/forgot-password) — کد ۵ رقمی به شماره موبایل ارسال می‌شود، معتبر ۱۰ دقیقه

  • آدرس مغازه — قابل ثبت در فرم ثبت‌نام یا بعداً از پنل مدیریت → اطلاعات مغازه

  • چت مستقیم مثل دیوار (/chats) — روی هر آگهی بازار سراسری دکمه «ارسال پیام»؛ گفتگوی خصوصی بین خریدار و فروشنده، جدا از کامنت‌های عمومی. به‌روزرسانی هر ۴ ثانیه (polling ساده، بدون WebSocket)

  • پنل مدیریت پلتفرم تکمیل‌تر شد: جستجو/فیلتر مغازه‌ها بر اساس نام و پلن، آمار مشترکین فعال/پولی

  • پاس گرافیکی سراسری: سایه و عمق بصری روی کارت‌ها، انیمیشن هاور دکمه‌ها، اسکرول‌بار سفارشی

  • هویت بصری اختصاصی «میز تعمیر»: پس‌زمینه با الگوی ظریف نقطه‌چین شبیه برد مدار (PCB)، تیتر صفحات با گرادیانت مسی، و کارت‌های تیکت به‌شکل «برچسب تعمیر واقعی» (با نقطه‌ی سوراخ و رنگ لبه بر اساس وضعیت: مسی=در صف، کهربایی=در حال انجام، فیروزه‌ای=آماده تحویل)

  • پنل کارمندان فیلترشده: تعمیرکاران تخصصی (سخت‌افزار/نرم‌افزار/برد) فقط تیکت‌های خودشان (اختصاص‌یافته یا در صف بخش خودشان) را می‌بینند، نه کل تیکت‌های مغازه. مدیر و پذیرش همچنان همه‌چیز را می‌بینند

  • کد ملی و تاریخ تولد در پروفایل هر کاربر (/profile)

  • نوار بالا: لینک اول با برچسب «🏠 صفحه اصلی» و ظاهر متمایز (رنگ مسی برجسته) به‌جای «تیکت‌ها»

  • دریافت رمز گوشی از مشتری در فرم پذیرش (فقط با تیک فعال می‌شود؛ برای تست بعد از تعمیر، فقط برای کارکنان همان مغازه قابل مشاهده است)

  • توضیحات مشتری درباره آسیب‌دیدگی یا تعمیر قبلی به‌عنوان یک فیلد جدا در پذیرش

  • سه گزینه تأیید پذیرش در انتهای فرم: رسید چاپی مغازه امضا شد / رسید چاپی سایت امضا شد / بدون امضا و بدون فیش پذیرش شد

  • ویرایش کارمند توسط مدیر — نام، نقش، و فعال/غیرفعال بودن حساب هر کارمند از پنل مدیریت قابل تغییر است

  • نوع رمز گوشی قابل انتخاب (پین/پسورد/الگو) — اگر «الگو» انتخاب شود، یک صفحه‌ی کشیدن الگو (شبیه قفل اندروید) نمایش داده می‌شود

  • صفحه سابقه و جستجو (/history) — جستجو بر اساس نام/شماره مشتری، مدل دستگاه، IMEI، وضعیت، یا بازه تاریخ

  • ثبت‌نام کامل‌تر مغازه: نوع کسب‌وکار (تک‌نفره/تیمی/مجموعه بزرگ)، تخصص‌های ارائه‌شده، تلفن ثابت، کد ملی و تاریخ تولد مدیر

  • اشتراک ۱/۳/۶/۱۲ ماهه با تخفیف پلکانی (۵٪ تا ۲۰٪ برای مدت‌های بلندتر)

  • سطح‌بندی احراز هویت (۱ تا ۳) — سطح ۱ به‌محض ثبت‌نام، سطح ۲ با تکمیل پروفایل و درخواست مدیر مغازه، سطح ۳ با تأیید پلتفرم از /superadmin/verification

  • انبار قطعات حالا ویرایش و حذف کامل دارد (حذفِ قطعه‌ای که در فاکتور استفاده شده، به‌جای حذف کامل، موجودی را صفر می‌کند تا تاریخچه مالی خراب نشود)

  • تغییر رمز عبور برای هر کاربر (مدیر یا کارمند) از صفحه پروفایل، با تأیید رمز فعلی

  • رفع باگ نوتیفیکیشن: دیگر با باز کردن زنگوله، همه به‌صورت خودکار خوانده‌شده علامت نمی‌خورند — هر اعلان با کلیک روی خودش خوانده می‌شود، یا دکمه صریح «علامت‌گذاری همه»

  • کد QR پذیرش مشتری (/kiosk/[shopId]) — مشتری با اسکن، مشخصات دستگاه خودش را ثبت می‌کند؛ کارمند از صفحه «پذیرش QR» تأیید یا رد می‌کند، تأیید خودکار تیکت واقعی می‌سازد

  • امتیازدهی مشتری + رتبه‌بندی سراسری (/rankings) — بعد از تحویل دستگاه، لینک امتیازدهی به مشتری پیامک می‌شود؛ رتبه‌بندی بر اساس میانگین امتیاز، قابل فیلتر بر اساس استان یا سراسر کشور (حداقل ۳ امتیاز برای ورود به رتبه‌بندی)

  • تبلیغات پاپ‌آپ علاوه بر بنر معمولی — قابل بستن، فقط یک‌بار در هر نشست نمایش داده می‌شود

  • ثبت‌نام با تب سربرگ برای انتخاب نوع کسب‌وکار (تک‌نفره/تیمی/مجموعه بزرگ)

  • نوار بالا بازطراحی شد — دسته‌بندی در منوهای کشویی (عملیات، ارتباطات، مشتریان، من، مدیریت) با برچسب پررنگ برای هر دسته، به‌جای یک ردیف شلوغ از لینک‌ها

  • راهنمای سایت و درباره ما — لینک راهنما و متن درباره‌ما از پنل مدیریت پلتفرم قابل تنظیم است (/superadmin/settings)، صفحه «درباره ما» عمومی در /about

  • تنظیمات ربات تلگرام در پنل پلتفرم (توکن + یوزرنیم) — فقط ذخیره می‌شود؛ ⚠️ ارسال واقعی هنوز پیاده نشده چون API تلگرام اجازه پیام به هر آیدی دلخواه را نمی‌دهد (کاربر باید ابتدا با ربات چت کرده باشد)

  • خروجی API برای سازمان‌های بیرونی (/superadmin/external-keys) — ⚠️ این یک API فقط‌خواندنیِ خودمان است (گزارش‌های مسروقه/بدهی و زنجیره مالکیت با کلید API)، نه یک اتصال رسمی و تأییدشده به سامانه‌های واقعی اصناف موبایل ایران، تعزیرات یا مالیات — چون چنین APIای عمومی برای اتصال در دسترس نبود؛ این فقط زیرساخت آماده برای روزی است که آن نهادها بخواهند متصل شوند

  • دسترسی پشتیبانی پلتفرم به پنل مغازه — یک کلید روشن/خاموش قابل کنترل هم توسط مدیر مغازه و هم مدیریت پلتفرم (Shop.supportAccessEnabled⚠️ این فقط یک فلگ رضایت است، هنوز مکانیزم واقعی «ورود به‌جای کاربر» (impersonation) پیاده نشده

  • موقعیت مکانی مغازه (عرض/طول جغرافیایی) قابل ثبت در پنل مدیریت، با لینک مستقیم به گوگل‌مپ — ⚠️ نقشه‌ی تعاملی برای انتخاب موقعیت با کلیک نیاز به کلید Google Maps API دارد که در این پروژه تعبیه نشده

  • مرجوعی: ویرایش کامل + وضعیت «حل‌شده/بازگشایی»

  • فراموشی رمز از طریق ایمیل — علاوه بر پیامک، اگر کاربر ایمیل ثبت کرده باشد می‌تواند کد را به ایمیل دریافت کند؛ ارسال واقعی ایمیل با تنظیمات SMTP از پنل مدیریت پلتفرم (/superadmin/settings) فعال می‌شود (مثلاً با Gmail App Password)

  • افزودن مشتری دستی به دفترچه مشتریان

  • در صفحه تأیید پذیرش QR، مشخص می‌شود کدام درخواست از مشتری جدید است (با تأیید، خودکار در دفترچه مشتریان ذخیره می‌شود)

  • درصد مالیات قابل‌تنظیم روی هر مغازه (پیش‌فرض ۱۰٪) — قابل تغییر در پنل مدیریت، و قابل روشن/خاموش‌کردن هنگام صدور هر فاکتور

  • فاکتور: ویرایش (اجرت، مالیات، وضعیت پرداخت)، حذف (قطعات مصرفی به‌صورت خودکار به انبار برمی‌گردند)، و چاپ فاکتور با یک صفحه‌ی تمیز و مخصوص چاپ (/invoices/[id]/print)

  • نقشه تعاملی نشان برای انتخاب دقیق موقعیت مغازه — کلیک روی نقشه یا کشیدن پین، مختصات خودکار ذخیره می‌شود. کلید نقشه از platform.neshan.org گرفته و در /superadmin/settings ثبت می‌شود؛ تا وقتی کلید ثبت نشده، فرم به‌جای نقشه یک هشدار نشان می‌دهد و ورودی عددی دستی هم‌چنان به‌عنوان جایگزین کار می‌کند

🚧 نیاز به تکمیل واقعی (این‌ها هنوز ساخته نشده‌اند):

  • ارسال واقعی پیام از طریق واتساپ/تلگرام — واتساپ نیاز به تأیید رسمی WhatsApp Business API از متا دارد؛ تلگرام هم محدودیت دارد (کاربر باید ابتدا خودش با ربات چت کرده باشد). فیلدهای مربوطه ذخیره می‌شوند، فقط ارسال غیرفعال است
  • آپلود واقعی فایل تصویر (عکس پروفایل، تصویر تبلیغات) — فعلاً فقط لینک تصویر پشتیبانی می‌شود؛ نیاز به یک سرویس ذخیره فایل مثل Vercel Blob دارد
  • اتصال رسمی به سامانه‌های دولتی (اصناف موبایل ایران، تعزیرات، مالیات) — آنچه ساخته شده فقط API خودمان است (/superadmin/external-keys)؛ اتصال واقعی نیاز به هماهنگی مستقیم با آن سازمان‌هاست
  • مکانیزم واقعی «ورود به‌جای کاربر» برای پشتیبانی پلتفرم — فعلاً فقط یک فلگ رضایت (supportAccessEnabled) داریم، نه ورود واقعی
  • داشبورد جداگانه برای فروشندگان موبایل (Dealer) — زیرساخت دیتابیسش (Shop.type) آماده است، ولی هنوز UI مجزا ندارد
  • صفحه برندینگ/لندینگ عمومی هر مغازه (برای اشتراک با مشتری، شامل آدرس، ساعت کاری، نمونه‌کار)
  • یادآوری خودکار تمدید اشتراک قبل از انقضا (پیامک/ایمیل)
  • سیستم حقوق و دستمزد جامع — فعلاً فقط دستمزد هر تعمیر جداگانه ثبت می‌شود، نه یک گزارش کلی حقوق ماهانه/هفتگی تجمیعی برای هر کارمند

دیپلوی (مرحله به مرحله)

⚠️ اگر قبلاً یک‌بار دیپلوی کرده‌اید: این آپدیت دیتابیس را باز هم تغییر داده (کلید نقشه نشان). یک‌بار دیگر بزنید:

npx prisma migrate dev --name neshan_map

همچنین چون پکیج react-neshan-map-leaflet تازه اضافه شده، قبل از migrate یک‌بار دیگر npm install بزنید. بعد از دیپلوی، برای فعال‌سازی نقشه، از platform.neshan.org ثبت‌نام کرده و کلید «نقشه وب» را در /superadmin/settings وارد کنید.

۱. دیتابیس Postgres رایگان

یکی از این دو را انتخاب کن و یک پروژه بساز:

از پنل، connection string را کپی کن.

۲. تنظیم متغیرهای محیطی

فایل .env.example را به .env تغییر نام بده و مقداردهی کن:

DATABASE_URL="..."          # از مرحله ۱
NEXTAUTH_SECRET="..."       # با دستور: openssl rand -base64 32
NEXTAUTH_URL="http://localhost:3000"
KAVENEGAR_API_KEY=""        # فعلاً خالی بگذار، مرحله ۵

۳. نصب و راه‌اندازی محلی

npm install
npx prisma migrate dev --name init
npm run seed     # یک مغازه نمونه با کاربر 09120000000 / رمز 123456 می‌سازد
npm run dev

حالا روی http://localhost:3000 بالا می‌آید.

۴. دیپلوی روی Vercel

npm i -g vercel
vercel

بعد در پنل Vercel، تمام متغیرهای .env را در Settings → Environment Variables وارد کن، و NEXTAUTH_URL را به آدرس نهایی سایت تغییر بده.

۵. اتصال پیامک واقعی (Kavenegar)

  1. در https://panel.kavenegar.com ثبت‌نام کن
  2. کلید API را از پنل بردار و در KAVENEGAR_API_KEY بگذار
  3. بدون این کلید، سیستم پیامک واقعی نمی‌فرستد ولی همه‌چیز دیگر طبیعی کار می‌کند (در لاگ سرور چاپ می‌شود)

۶. اتصال پرداخت واقعی (زرین‌پال)

  1. در https://www.zarinpal.com ثبت‌نام و مرچنت کد (Merchant ID) بگیر
  2. آن را در ZARINPAL_MERCHANT_ID بگذار
  3. بدون این مقدار، سیستم به‌صورت خودکار از درگاه sandbox زرین‌پال استفاده می‌کند — یعنی می‌توانی کل فرآیند پرداخت را بدون پول واقعی تست کنی

۷. ساخت حساب مدیریت پلتفرم (خودت)

دستور npm run seed یک حساب نمونه در جدول PlatformAdmin هم می‌سازد (شماره 09100000000، رمز 123456). حتماً قبل از انتشار عمومی سایت، این رمز را عوض کن یا از طریق Prisma Studio (npm run prisma:studio) یک حساب جدید با رمز امن بساز و نمونه را حذف کن. با این حساب وارد /superadmin/login شو تا لیست همه مغازه‌ها و درآمد کل را ببینی.

معماری چندمستأجری (Multi-tenant) — نکته مهم امنیتی

هر کوئری به دیتابیس باید با shopId کاربر لاگین‌شده فیلتر شود. این الزام در lib/tenant.ts (تابع requireSession) متمرکز شده — هر مسیر API باید این تابع را صدا بزند و shopId را از سشن بگیرد، نه از ورودی کاربر. این یعنی حتی اگر یک مغازه سعی کند با دستکاری درخواست به داده مغازه دیگر دسترسی پیدا کند، امکان‌پذیر نیست.

اگر بخش جدیدی به API اضافه می‌کنی، همیشه این الگو را رعایت کن:

const { shopId } = await requireSession();
await db.ticket.findMany({ where: { shopId, ...filters } });

استثنا: مسیرهای /api/market عمداً بدون فیلتر shopId روی خواندن هستند — چون بازار سراسری قرار است بین همه مغازه‌ها مشترک باشد. همچنان نیاز به لاگین دارند (requireSession صدا زده می‌شود)، فقط تفکیک تنانت روی این یک مسیر خاص اعمال نمی‌شود. این تنها استثنای عمدی در کل کدبیس است.

ساختار پوشه‌ها

app/
  api/              ← مسیرهای بک‌اند (REST)
  (dashboard)/       ← صفحات پنل (نیاز به لاگین)
  login/
lib/
  db.ts             ← اتصال Prisma
  auth.ts           ← تنظیمات NextAuth
  tenant.ts          ← لایه جداسازی چندمستأجری
  sms.ts            ← اتصال به Kavenegar
prisma/
  schema.prisma     ← مدل کامل دیتابیس
  seed.ts           ← داده نمونه برای تست

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors