سند نهایی بسیار کامل پروژه

📚 سند نهایی بسیار کامل پروژه

این فایل شامل دو بخش است:

  1. سند تفصیلی ساختار فایل‌ها، پنل‌ها، داشبوردها و امکانات ریز ماژول‌ها
  2. ادغام کامل ۹ فایل MD ویرایش‌شده

📘 سند تفصیلی ساختار، پنل‌ها، داشبوردها و امکانات ریز پروژه

پلتفرم مدیریت هوشمند مدارس — نسخه نهایی دیتابیس واحد

مشخصهمقدار
معماریSingle Database + Multi-School Management + Modular Packages
دیتابیسschool_platform_db
پنل سوپرادمینمستقل از پنل مدرسه
کنترل امکاناتپکیج + ماژول + محدودیت + Override اختصاصی مدرسه
طراحی داشبوردModern Light Aurora، بدون Glassmorphism

۱. خلاصه معماری نهایی

در نسخه نهایی پروژه، سیستم دیگر برای هر مدرسه دیتابیس جدا نمی‌سازد. تمام داده‌ها داخل یک دیتابیس واحد قرار می‌گیرند و داده‌های هر مدرسه با ستون school_id جدا می‌شوند.


school_platform_db
├── جداول پلتفرم و سوپرادمین
│   ├── super_admins
│   ├── schools
│   ├── module_catalog
│   ├── subscription_plans
│   ├── school_feature_overrides
│   ├── school_limit_overrides
│   ├── school_subscriptions
│   ├── invoices
│   ├── payments
│   ├── support_tickets
│   └── platform_logs
│
└── جداول مدرسه‌ای با school_id
    ├── users
    ├── academic_years
    ├── subjects
    ├── forms
    ├── exams
    ├── question_bank
    ├── assignments
    ├── grades
    ├── attendance
    ├── behavior_records
    ├── student_health
    ├── student_talents
    ├── surveys
    ├── messages
    └── ...

قوانین اجباری معماری


۱. هیچ دیتابیس جداگانه‌ای برای مدرسه ساخته نشود.
۲. همه جداول مدرسه‌ای school_id داشته باشند.
۳. همه کوئری‌های پنل مدرسه با school_id محدود شوند.
۴. سوپرادمین پنل مستقل داشته باشد.
۵. امکانات هر مدرسه با پکیج و ماژول کنترل شود.
۶. محدودیت‌ها مثل تعداد دانش‌آموز، آزمون، فرم و پیامک قبل از ایجاد رکورد بررسی شود.

۲. ساختار کامل فایل‌ها و پوشه‌ها


school-platform/
├── index.php
├── .htaccess
├── robots.txt
├── manifest.json
├── sw.js
│
├── config/
│   ├── database.php                  # اتصال PDO به دیتابیس واحد school_platform_db
│   ├── app.php                       # تنظیمات اپلیکیشن
│   └── constants.php                 # ثابت‌های عمومی
│
├── core/
│   ├── Router.php
│   ├── Request.php
│   ├── Response.php
│   ├── Session.php
│   └── Validator.php
│
├── includes/
│   ├── auth.php                      # ورود/خروج سوپرادمین و کاربران مدرسه
│   ├── security.php                  # CSRF, XSS, Rate Limit, Upload Security
│   ├── functions.php                 # توابع عمومی
│   ├── permissions.php               # کنترل نقش‌ها
│   ├── entitlements.php              # hasModule, requireModule, getSchoolLimit, enforceLimit
│   ├── school_provisioner.php        # تعریف مدرسه بدون ساخت DB جدا
│   ├── sms_handler.php
│   ├── pdf_generator.php
│   ├── excel_handler.php
│   ├── notification_handler.php
│   └── date_helper.php
│
├── database/
│   ├── schema.sql                    # تمام جداول دیتابیس واحد
│   ├── seed.sql                      # داده‌های اولیه
│   └── migrations/
│       ├── 001_initial.sql
│       ├── 002_modules_packages.sql
│       └── ...
│
├── api/
│   └── v1/
│       ├── auth/
│       ├── superadmin/
│       ├── schools/
│       ├── packages/
│       ├── students/
│       ├── forms/
│       ├── exams/
│       ├── assignments/
│       ├── attendance/
│       ├── surveys/
│       ├── messages/
│       └── reports/
│
├── views/
│   ├── layouts/
│   │   ├── auth.php
│   │   ├── dashboard.php             # Layout مشترک داشبوردها
│   │   ├── superadmin.php            # Layout مستقل سوپرادمین
│   │   └── print.php
│   │
│   ├── components/
│   │   ├── header.php
│   │   ├── sidebar.php
│   │   ├── breadcrumb.php
│   │   ├── stat_card.php
│   │   ├── chart_card.php
│   │   ├── data_table.php
│   │   ├── modal.php
│   │   ├── toast.php
│   │   └── empty_state.php
│   │
│   ├── auth/
│   │   ├── login.php
│   │   ├── login_admin.php
│   │   ├── forgot_password.php
│   │   └── change_password.php
│   │
│   ├── superadmin/
│   │   ├── dashboard.php
│   │   ├── schools.php
│   │   ├── school_create.php
│   │   ├── school_edit.php
│   │   ├── school_detail.php
│   │   ├── modules.php
│   │   ├── packages.php
│   │   ├── package_form.php
│   │   ├── subscriptions.php
│   │   ├── receipts.php
│   │   ├── invoices.php
│   │   ├── payments.php
│   │   ├── support_tickets.php
│   │   ├── settings.php
│   │   ├── theme_settings.php
│   │   ├── logs.php
│   │   └── backups.php
│   │
│   ├── school/
│   │   ├── dashboard.php
│   │   ├── students.php
│   │   ├── teachers.php
│   │   ├── counselors.php
│   │   ├── vice_principals.php
│   │   ├── classes.php
│   │   ├── subjects.php
│   │   ├── academic_years.php
│   │   ├── wallet.php
│   │   ├── package_status.php
│   │   ├── enabled_modules.php
│   │   ├── reports.php
│   │   ├── settings.php
│   │   └── support.php
│   │
│   ├── counselor/
│   │   ├── dashboard.php
│   │   ├── students.php
│   │   ├── student_profile.php
│   │   ├── forms.php
│   │   ├── form_builder.php
│   │   ├── form_preview.php
│   │   ├── results.php
│   │   ├── result_detail.php
│   │   ├── alerts.php
│   │   ├── assessment_library.php
│   │   ├── assessment_requests.php
│   │   ├── parent_meetings.php
│   │   └── reports.php
│   │
│   ├── teacher/
│   │   ├── dashboard.php
│   │   ├── my_classes.php
│   │   ├── question_bank.php
│   │   ├── question_form.php
│   │   ├── exams.php
│   │   ├── exam_builder.php
│   │   ├── exam_monitor.php
│   │   ├── exam_results.php
│   │   ├── exam_grading.php
│   │   ├── assignments.php
│   │   ├── grades.php
│   │   ├── attendance.php
│   │   └── reports.php
│   │
│   ├── vice_principal/
│   │   ├── dashboard.php
│   │   ├── coordinated_exams.php
│   │   ├── exam_builder.php
│   │   ├── exam_monitor.php
│   │   ├── class_comparison.php
│   │   ├── weak_students.php
│   │   └── reports.php
│   │
│   ├── parent/
│   │   ├── dashboard.php
│   │   ├── children.php
│   │   ├── child_profile.php
│   │   ├── fill_form.php
│   │   ├── form_results.php
│   │   ├── grades.php
│   │   ├── exams.php
│   │   ├── assignments.php
│   │   ├── attendance.php
│   │   ├── behavior.php
│   │   ├── surveys.php
│   │   └── chat.php
│   │
│   └── student/
│       ├── dashboard.php
│       ├── exams.php
│       ├── take_exam.php
│       ├── exam_results.php
│       ├── assignments.php
│       ├── grades.php
│       ├── attendance.php
│       ├── announcements.php
│       └── profile.php
│
├── assets/
│   ├── css/
│   │   ├── app.css
│   │   ├── dashboard.css              # Light Aurora solid cards
│   │   ├── rtl.css
│   │   └── print.css
│   └── js/
│       ├── app.js
│       ├── dashboard.js
│       ├── charts.js
│       ├── form-builder.js
│       ├── exam-builder.js
│       ├── exam-taker.js
│       ├── auto-save.js
│       ├── data-table.js
│       └── chat.js
│
├── uploads/
│   ├── platform/
│   └── schools/
│       └── {school_code}/
│           ├── avatars/
│           ├── logos/
│           ├── excel/
│           ├── questions/
│           ├── assignments/
│           ├── qrcodes/
│           └── exports/
│
├── cron/
│   ├── scheduler.php
│   ├── every_minute.php
│   ├── hourly.php
│   ├── daily.php
│   ├── weekly.php
│   └── monthly.php
│
└── logs/
    ├── error.log
    ├── cron.log
    └── activity.log

۳. پنل سوپرادمین — امکانات کامل

۳.۱ هدف پنل سوپرادمین

پنل سوپرادمین برای مدیریت کل سیستم است و از پنل مدیر مدرسه جداست. سوپرادمین می‌تواند مدرسه تعریف کند، پکیج بسازد، امکانات هر مدرسه را فعال/غیرفعال کند، محدودیت‌ها را تعیین کند، رنگ‌های داشبوردها را تنظیم کند و وضعیت مالی و پشتیبانی را ببیند.

۳.۲ داشبورد سوپرادمین

کارت‌ها و ویجت‌های اصلی:


- تعداد کل مدارس
- مدارس فعال
- مدارس تعلیق‌شده
- مدارس منقضی
- مدارس Trial
- فیش‌های در انتظار تأیید
- تیکت‌های باز
- درآمد ماه جاری
- نمودار رشد مدارس
- نمودار درآمد ماهانه
- نمودار استفاده از پکیج‌ها
- مدارس با بیشترین مصرف
- مدارس نزدیک به انقضا
- سلامت سیستم
- لاگ‌های حساس اخیر

۳.۳ مدیریت مدارس

امکانات:


- لیست مدارس با جستجو و فیلتر
- ساخت مدرسه جدید
- ویرایش اطلاعات مدرسه
- تعیین مدیر اولیه مدرسه
- تعیین پکیج اولیه
- تعیین وضعیت مدرسه: active, suspended, expired, deleted
- تعیین محدودیت اختصاصی دانش‌آموز/معلم/مشاور
- مشاهده امکانات فعال مدرسه
- Override فعال/غیرفعال کردن ماژول‌ها
- مشاهده مصرف مدرسه
- ورود موقت به پنل مدرسه با Impersonate
- ثبت تمام عملیات در Audit Log

۳.۴ مدیریت پکیج‌ها

امکانات:


- ساخت پکیج جدید
- ویرایش پکیج
- کپی پکیج
- فعال/غیرفعال کردن پکیج
- تعیین نام، توضیح، آیکون و رنگ پکیج
- انتخاب ماژول‌ها با سوییچ ON/OFF
- تعیین محدودیت‌ها
- قیمت ماهانه/سالانه
- قیمت به ازای دانش‌آموز
- هزینه راه‌اندازی
- Trial Plan
- پکیج مخفی یا ویژه

نمونه پکیج‌ها:


- فقط آزمون‌ساز
- فقط مشاوره
- پایه
- استاندارد
- حرفه‌ای
- سازمانی

۳.۵ تنظیم رنگ‌ها و طراحی داشبوردها

سوپرادمین باید بتواند رنگ‌های زیر را تنظیم کند:


- رنگ اصلی
- رنگ دوم
- رنگ accent
- رنگ موفقیت
- رنگ هشدار
- رنگ خطا
- رنگ info
- رنگ پس‌زمینه داشبورد
- رنگ‌های Aurora Background
- رنگ کارت‌ها
- رنگ border کارت‌ها
- رنگ Sidebar
- گرادینت دکمه‌ها
- گرادینت نمودارها
- گرادینت آیتم فعال منو

۴. پنل مدیر مدرسه — امکانات کامل

۴.۱ داشبورد مدیر مدرسه

ویجت‌ها:


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

۴.۲ مدیریت کاربران


- تعریف دانش‌آموز
- تعریف والدین
- ارتباط والد و فرزند
- تعریف معلم
- تعریف مشاور
- تعریف معاون
- آپلود اکسل دانش‌آموزان
- ویرایش گروهی کاربران
- فعال/غیرفعال کردن کاربر
- ریست رمز عبور
- انتساب معلم به درس و کلاس
- انتساب مشاور به پایه/کلاس
- انتساب معاون به پایه

۴.۳ ساختار آموزشی


- تعریف سال تحصیلی
- تعریف پایه و کلاس
- تعریف درس
- تعریف فصل درس
- تعریف مبحث فصل
- تعریف دوره نمره‌دهی
- تعریف دسته‌بندی نمرات
- ارتقاء پایه گروهی
- انتقال دانش‌آموز بین کلاس‌ها
- بایگانی سالانه

۴.۴ مشاهده امکانات فعال مدرسه

مدیر مدرسه باید در صفحه «امکانات فعال» ببیند:


- پکیج فعلی چیست
- چه ماژول‌هایی فعال هستند
- چه ماژول‌هایی غیرفعال هستند
- سقف دانش‌آموز چقدر است
- چند دانش‌آموز ثبت شده
- سقف آزمون ماهانه چقدر است
- سقف فرم مشاوره چقدر است
- سقف پیامک و فضای ذخیره‌سازی چقدر است

۵. پروفایل ۳۶۰ درجه دانش‌آموز — امکانات ریز

۵.۱ هدف پروفایل ۳۶۰

پروفایل ۳۶۰ یک صفحه جامع برای نمایش تمام ابعاد دانش‌آموز است؛ یعنی وضعیت تحصیلی، مشاوره، حضور و غیاب، رفتار، سلامت، استعداد، خانواده، اهداف، دستاوردها و تایم‌لاین رویدادها.

۵.۲ تب‌های اصلی پروفایل ۳۶۰


۱. نمای کلی
۲. اطلاعات فردی
۳. خانواده و والدین
۴. عملکرد تحصیلی
۵. آزمون‌ها
۶. تکالیف
۷. حضور و غیاب
۸. رفتار و انضباط
۹. مشاوره و روان‌سنجی
۱۰. سلامت
۱۱. استعداد و سبک یادگیری
۱۲. دستاوردها
۱۳. اهداف و برنامه رشد
۱۴. یادداشت‌ها
۱۵. تایم‌لاین
۱۶. فایل‌ها و گزارش‌ها

۵.۳ نمای کلی


- کارت مشخصات دانش‌آموز
- عکس پروفایل
- پایه و کلاس
- وضعیت فعال/انتقالی/فارغ‌التحصیل
- میانگین نمرات
- آخرین وضعیت حضور
- آخرین هشدار مشاوره
- شاخص ریسک دانش‌آموز
- خلاصه نقاط قوت و ضعف

۵.۴ عملکرد تحصیلی


- نمودار میانگین نمرات در طول زمان
- نمرات هر درس
- رتبه در کلاس
- رتبه در پایه
- مقایسه با میانگین کلاس
- دروس قوی
- دروس ضعیف
- روند افت یا رشد تحصیلی
- کارنامه PDF

۵.۵ آزمون‌ها


- آزمون‌های شرکت‌کرده
- آزمون‌های غایب
- نمره هر آزمون
- درصد پاسخ صحیح
- رتبه در کلاس/پایه
- تحلیل سوالات اشتباه
- نمودار پیشرفت آزمون‌ها

۵.۶ حضور و غیاب


- تقویم حضور و غیاب
- تعداد غیبت موجه
- تعداد غیبت غیرموجه
- تعداد تأخیر
- الگوی غیبت
- هشدار غیبت مکرر
- گزارش ماهانه PDF

۵.۷ رفتار و انضباط


- تشویق‌ها
- تذکرها
- امتیاز انضباط
- دسته‌بندی رفتارها
- رفتارهای مثبت پرتکرار
- رفتارهای منفی پرتکرار
- نمودار روند رفتاری
- اطلاع‌رسانی به والدین

۵.۸ مشاوره و روان‌سنجی


- فرم‌های مشاوره تکمیل‌شده
- نتایج آزمون‌های روان‌سنجی
- سطح شدت هر نتیجه
- هشدارهای بحرانی
- یادداشت خصوصی مشاور
- یادداشت قابل نمایش به والدین
- جلسات مشاوره
- درخواست‌های ارزیابی
- پیگیری‌های آینده
- گزارش PDF مشاور
- گزارش PDF والدین با اطلاعات فیلترشده

۵.۹ سلامت


- گروه خونی
- قد و وزن
- آلرژی‌ها
- بیماری‌های مزمن
- داروهای مصرفی
- محدودیت‌های جسمی
- وضعیت بینایی
- وضعیت شنوایی
- تماس اضطراری
- پزشک یا مرکز درمانی
- تاریخ آخرین بروزرسانی

۵.۱۰ استعداد و سبک یادگیری


- هوش‌های چندگانه
- سبک یادگیری دیداری/شنیداری/حرکتی
- علایق دانش‌آموز
- استعدادهای هنری/ورزشی/علمی
- نقاط قوت تحصیلی
- نقاط ضعف تحصیلی
- مهارت‌های نرم
- علاقه‌مندی شغلی آینده
- پیشنهاد مسیر رشد

۵.۱۱ دستاوردها


- دستاوردهای علمی
- دستاوردهای ورزشی
- دستاوردهای هنری
- مسابقات و المپیادها
- رتبه‌ها و مقام‌ها
- گواهینامه‌ها
- تصاویر و فایل پیوست

۵.۱۲ اهداف و برنامه رشد


- هدف تحصیلی
- هدف رفتاری
- هدف مهارتی
- هدف شخصی
- تعیین تاریخ هدف
- درصد پیشرفت
- وضعیت: فعال، انجام‌شده، لغوشده
- یادداشت پیگیری

۵.۱۳ یادداشت‌ها


- یادداشت معلم
- یادداشت مشاور
- یادداشت معاون
- سطح محرمانگی: عادی، حساس، محرمانه
- تعیین نقش‌های مجاز برای مشاهده
- پیوست فایل

۵.۱۴ تایم‌لاین


- ثبت‌نام
- تغییر کلاس
- آزمون مهم
- افت یا رشد نمره
- غیبت‌های مهم
- رفتار مثبت/منفی
- جلسه مشاوره
- دستاورد
- هدف جدید

۵.۱۵ کنترل دسترسی پروفایل ۳۶۰


- مدیر مدرسه: مشاهده کامل
- مشاور: مشاهده کامل بخش‌های مشاوره، سلامت، استعداد و یادداشت‌ها
- معلم: مشاهده محدود بر اساس role_permissions
- معاون: مشاهده تحصیلی، حضور، رفتار و گزارش‌ها
- والدین: مشاهده نسخه فیلترشده
- دانش‌آموز: مشاهده نسخه محدود خودش

۶. نظرسنجی ۳۶۰ درجه — امکانات ریز

۶.۱ هدف نظرسنجی ۳۶۰

نظرسنجی ۳۶۰ برای ارزیابی کیفیت عملکرد مدرسه، معلم، مشاور، کلاس، درس یا خدمات مدرسه از دید چند گروه پاسخ‌دهنده استفاده می‌شود.

۶.۲ انواع نظرسنجی


- ارزیابی معلم توسط دانش‌آموز
- ارزیابی معلم توسط والدین
- ارزیابی مشاور
- رضایت از مدرسه
- رضایت از کلاس یا درس
- رضایت از خدمات اجرایی
- نظرسنجی رویدادها
- نظرسنجی سفارشی

۶.۳ سازنده نظرسنجی


- عنوان نظرسنجی
- توضیحات
- نوع نظرسنجی
- تعیین پاسخ‌دهندگان
- تعیین پایه‌ها و کلاس‌ها
- تعیین ناشناس بودن یا نبودن
- تاریخ شروع و پایان
- تعریف ابعاد ارزیابی
- تعیین وزن هر بعد
- تعریف سوالات
- پیش‌نمایش
- انتشار

۶.۴ انواع سوالات


- لیکرت ۵ گزینه‌ای
- لیکرت ۷ گزینه‌ای
- ستاره‌ای ۱ تا ۵
- NPS از ۰ تا ۱۰
- تک‌انتخابی
- چندانتخابی
- متن کوتاه
- متن بلند

۶.۵ ابعاد ارزیابی نمونه

برای ارزیابی معلم:


- تسلط علمی
- روش تدریس
- ارتباط با دانش‌آموز
- عدالت در ارزیابی
- مدیریت کلاس
- ایجاد انگیزه
- استفاده از تکلیف و آزمون مناسب

برای رضایت از مدرسه:


- کیفیت آموزشی
- ارتباط با والدین
- نظم و انضباط
- امکانات مدرسه
- خدمات مشاوره
- امنیت و سلامت
- رضایت کلی

۶.۶ هدف‌گیری پاسخ‌دهندگان


- همه دانش‌آموزان
- دانش‌آموزان یک پایه
- دانش‌آموزان یک کلاس
- والدین یک پایه
- والدین یک کلاس
- معلمین
- مشاوران
- گروه سفارشی کاربران

۶.۷ نتایج و تحلیل‌ها


- تعداد پاسخ‌ها
- نرخ مشارکت
- میانگین کل
- میانگین هر بعد
- نمودار radar برای ابعاد
- نمودار bar برای سوالات
- نمودار NPS
- مقایسه کلاس‌ها
- مقایسه معلم‌ها
- رتبه‌بندی
- تحلیل پاسخ‌های متنی
- خروجی PDF
- خروجی Excel

۶.۸ تنظیمات ناشناس بودن


- کاملاً ناشناس
- ناشناس برای معلم، قابل مشاهده برای مدیر
- غیرناشناس
- نمایش فقط داده تجمیعی اگر تعداد پاسخ کمتر از حد مجاز باشد

۶.۹ داشبورد نظرسنجی ۳۶۰


- نظرسنجی‌های فعال
- نرخ مشارکت
- بهترین امتیازها
- ضعیف‌ترین ابعاد
- نمودار رضایت کلی
- لیست نظرسنجی‌های در انتظار پاسخ
- هشدار مشارکت پایین

۷. آزمون‌ساز معلم — امکانات ریز

۷.۱ هدف آزمون‌ساز

آزمون‌ساز باید به معلم اجازه دهد آزمون آنلاین، زمان‌دار، قابل تصحیح خودکار یا دستی بسازد و دانش‌آموز بتواند در پنل خودش آزمون را انجام دهد.

۷.۲ بانک سوالات

امکانات بانک سوال:


- ساخت سوال جدید
- ویرایش سوال
- حذف یا غیرفعال کردن سوال
- دسته‌بندی بر اساس درس، فصل و مبحث
- تعیین پایه
- تعیین سطح سختی
- تعیین سطح شناختی بلوم
- تگ‌گذاری
- افزودن تصویر به سوال
- افزودن تصویر به گزینه‌ها
- اشتراک‌گذاری سوال با سایر معلمین مدرسه
- آپلود گروهی سوال از Excel
- جستجو و فیلتر سوالات
- مشاهده آمار استفاده هر سوال
- درصد پاسخ صحیح هر سوال در آزمون‌های قبلی

۷.۳ انواع سوالات آزمون


- تک‌انتخابی
- چندانتخابی
- صحیح/غلط
- جای خالی
- جورکردنی
- مرتب‌سازی
- پاسخ کوتاه
- تشریحی
- سوال همراه تصویر
- گزینه همراه تصویر

۷.۴ ساخت آزمون

مراحل ساخت آزمون:


۱. انتخاب درس
۲. انتخاب پایه و کلاس هدف
۳. عنوان و توضیحات آزمون
۴. نوع آزمون: quiz, midterm, final, practice, homework
۵. انتخاب سوال از بانک سوال
۶. ایجاد سوال جدید داخل آزمون
۷. انتخاب تصادفی سوالات بر اساس فصل/سختی
۸. تعیین نمره هر سوال
۹. تعیین زمان شروع و پایان
۱۰. تعیین مدت آزمون
۱۱. تنظیمات امنیتی و نمایش
۱۲. پیش‌نمایش
۱۳. انتشار یا زمان‌بندی

۷.۵ انتخاب هوشمند سوال


- انتخاب تعداد سوال آسان/متوسط/سخت
- انتخاب از یک فصل خاص
- انتخاب از چند مبحث
- جلوگیری از سوالات تکراری در آزمون‌های اخیر
- تعیین مجموع نمره هدف
- تولید آزمون با blueprint

۷.۶ تنظیمات آزمون


- زمان شروع
- زمان پایان
- مدت آزمون
- نمره کل
- نمره قبولی
- نمره منفی
- درصد نمره منفی
- ترتیب تصادفی سوالات
- ترتیب تصادفی گزینه‌ها
- امکان برگشت به سوال قبل
- نمایش نتیجه بلافاصله
- نمایش پاسخ صحیح
- نمایش نتیجه بعد از زمان مشخص
- حداکثر دفعات تلاش
- محدودیت IP یا دستگاه در صورت نیاز
- پیام شروع و پایان آزمون

۷.۷ تجربه دانش‌آموز در آزمون


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

۷.۸ مانیتور زنده آزمون

برای معلم یا معاون:


- تعداد دانش‌آموزان حاضر
- تعداد شروع‌کرده‌ها
- تعداد ارسال‌کرده‌ها
- دانش‌آموزان در حال آزمون
- زمان باقی‌مانده هر دانش‌آموز
- وضعیت اتصال
- هشدار خروج یا اختلال
- ارسال پیام عمومی به شرکت‌کنندگان

۷.۹ تصحیح آزمون


- تصحیح خودکار تستی
- تصحیح چندانتخابی
- تصحیح صحیح/غلط
- تصحیح دستی تشریحی
- ثبت بازخورد برای پاسخ تشریحی
- نمره‌دهی جزئی
- بازبینی نمره
- قفل نمره بعد از انتشار

۷.۱۰ نتایج آزمون


- نمره کل
- درصد پاسخ صحیح
- تعداد صحیح/غلط/نزده
- رتبه در کلاس
- رتبه در پایه
- صدک
- میانگین کلاس
- مقایسه کلاس‌ها
- تحلیل سوال به سوال
- سوالات سخت
- سوالات آسان
- دانش‌آموزان ضعیف
- خروجی Excel
- خروجی PDF

۷.۱۱ آزمون هماهنگ معاون


- ساخت آزمون برای یک پایه یا چند کلاس
- انتخاب سوال از بانک سوال معلمین
- زمان‌بندی مشترک
- مانیتور زنده همه کلاس‌ها
- رتبه‌بندی پایه
- مقایسه کلاس‌ها
- تحلیل عملکرد معلم/کلاس

۸. فرم‌ساز مشاوره و روان‌سنجی — امکانات ریز

۸.۱ فرم‌ساز


- ایجاد فرم سفارشی
- بخش‌بندی فرم
- سوالات چندمرحله‌ای
- انواع سوال: تک‌انتخابی، چندانتخابی، لیکرت، اسلایدر، متن، عدد، تاریخ
- گزینه‌ها با امتیاز
- نمره‌گذاری معکوس
- خرده‌مقیاس‌ها
- محدوده‌های تفسیری
- هشدار خودکار برای نتایج بحرانی
- QR Code و لینک اختصاصی
- هدف‌گیری پایه/کلاس/دانش‌آموز خاص
- محدودیت زمان پاسخ‌دهی
- محدودیت تعداد تلاش
- ذخیره پیش‌نویس
- انتشار نتیجه برای والدین

۸.۲ نتایج مشاوره


- نمره کل
- نمره بخش‌ها
- نمره خرده‌مقیاس‌ها
- درصد
- سطح شدت
- تفسیر خودکار
- پیشنهادات خودکار
- یادداشت خصوصی مشاور
- یادداشت قابل نمایش به والدین
- تعیین بخش‌های قابل نمایش برای والدین
- خروجی PDF مشاور
- خروجی PDF والدین

۸.۳ هشدارها


- هشدار نتیجه بحرانی
- هشدار افت تحصیلی
- هشدار غیبت مکرر
- هشدار رفتار نگران‌کننده
- هشدار درخواست والدین یا معلم
- ثبت اقدام انجام‌شده
- وضعیت حل‌شده/درحال پیگیری

۹. تکالیف، نمرات، حضور و رفتار

۹.۱ تکالیف


- ساخت تکلیف
- پیوست فایل
- تعیین کلاس هدف
- تعیین مهلت تحویل
- تحویل متن و فایل توسط دانش‌آموز
- پذیرش یا رد تحویل دیرهنگام
- نمره‌دهی
- بازخورد متنی یا فایل
- نمایش به والدین

۹.۲ نمرات و کارنامه


- تعریف دوره نمره‌دهی
- تعریف دسته‌بندی نمره
- ثبت نمره تکی
- ثبت نمره گروهی
- محاسبه میانگین وزن‌دار
- کارنامه دانش‌آموز
- نمودار پیشرفت
- خروجی PDF

۹.۳ حضور و غیاب


- ثبت روزانه حضور و غیاب
- حاضر، غایب موجه، غایب غیرموجه، تأخیر، خروج زودتر
- ثبت دلیل
- اطلاع‌رسانی خودکار به والدین
- گزارش ماهانه
- نمایش در پروفایل ۳۶۰

۹.۴ رفتار و انضباط


- ثبت رفتار مثبت
- ثبت رفتار منفی
- امتیازدهی
- دسته‌بندی رفتار
- اطلاع‌رسانی به والدین
- گزارش انضباط
- نمایش روند رفتاری

۱۰. ارتباطات و اعلان‌ها


- چت والد با معلم
- چت والد با مشاور
- چت دانش‌آموز با معلم در صورت مجاز بودن
- اعلان گروهی مدرسه
- اعلان به کلاس خاص
- اعلان به والدین
- نوتیفیکیشن داخلی
- پیامک
- تنظیمات اعلان هر کاربر
- ساعات بی‌صدا

۱۱. داشبوردها — ساختار و امکانات

۱۱.۱ طراحی مشترک داشبوردها


- طراحی Light Aurora
- بدون Glassmorphism
- کارت‌های solid سفید/off-white
- سایه نرم
- border ظریف
- رنگ‌ها قابل تنظیم از سوپرادمین
- RTL کامل
- responsive برای موبایل، تبلت و دسکتاپ

۱۱.۲ داشبورد سوپرادمین


- آمار مدارس
- وضعیت مالی
- فیش‌ها
- تیکت‌ها
- پکیج‌ها
- نمودار درآمد
- نمودار رشد مدارس
- Health Score مدارس
- تنظیمات سریع

۱۱.۳ داشبورد مدیر مدرسه


- آمار کاربران
- وضعیت پکیج
- امکانات فعال
- محدودیت‌ها و مصرف
- کیف پول
- فعالیت اخیر
- اعلان‌های مهم

۱۱.۴ داشبورد مشاور


- فرم‌های فعال
- پاسخ‌های جدید
- هشدارهای بحرانی
- پیگیری‌های امروز
- دانش‌آموزان پرریسک
- نمودار شدت نتایج

۱۱.۵ داشبورد معلم


- کلاس‌های من
- آزمون‌های فعال
- تکالیف در انتظار بررسی
- آمار بانک سوال
- آخرین نمره‌دهی‌ها

۱۱.۶ داشبورد معاون


- وضعیت پایه‌ها
- آزمون‌های هماهنگ
- دانش‌آموزان ضعیف
- مقایسه کلاس‌ها
- حضور و غیاب کلی

۱۱.۷ داشبورد والدین


- فرزندان
- آخرین نمرات
- آزمون‌های پیش‌رو
- فرم‌های مشاوره در انتظار
- حضور و غیاب
- رفتار و انضباط
- پیام‌ها

۱۱.۸ داشبورد دانش‌آموز


- آزمون‌های پیش‌رو
- تکالیف
- آخرین نمرات
- حضور و غیاب
- اعلان‌ها
- پیام‌ها

۱۲. ماژول‌ها و کلیدهای دسترسی


{
  "counseling": "مشاوره و روان‌سنجی",
  "form_builder": "فرم‌ساز مشاوره",
  "assessment_library": "کتابخانه آزمون‌ها",
  "profile_360": "پروفایل ۳۶۰ درجه",
  "survey_360": "نظرسنجی ۳۶۰ درجه",
  "exam_builder": "آزمون‌ساز",
  "question_bank": "بانک سوالات",
  "coordinated_exam": "آزمون هماهنگ",
  "assignments": "تکالیف",
  "grades": "نمرات و کارنامه",
  "attendance": "حضور و غیاب",
  "behavior": "رفتار و انضباط",
  "chat": "چت داخلی",
  "announcements": "اعلان‌ها",
  "sms": "پیامک",
  "pdf_export": "خروجی PDF",
  "excel_export": "خروجی Excel",
  "api_access": "API"
}

۱۳. محدودیت‌های قابل تعریف در پکیج


{
  "max_students": 500,
  "max_teachers": 50,
  "max_counselors": 5,
  "max_vice_principals": 3,
  "max_classes": 30,
  "max_forms_monthly": 100,
  "max_submissions_monthly": 5000,
  "max_exams_monthly": 200,
  "max_questions": 5000,
  "max_assignments_monthly": 200,
  "max_sms_monthly": 1000,
  "max_storage_gb": 5,
  "max_api_calls_daily": 0
}

۱۴. قانون پیاده‌سازی کنترل امکانات


requireModule('exam_builder');

$count = countMonthlyExams($schoolId);
enforceLimit('max_exams_monthly', $count);

$stmt = db()->prepare("SELECT * FROM exams WHERE school_id = ? AND teacher_id = ?");
$stmt->execute([$schoolId, $teacherId]);

۱۵. جمع‌بندی

این سند تفصیلی برای تکمیل فایل HTML نهایی اضافه شده تا ساختار فایل‌ها، امکانات ریز پنل‌ها، داشبوردها و ماژول‌های اصلی مثل پروفایل ۳۶۰، نظرسنجی ۳۶۰ و آزمون‌ساز به‌صورت کامل و قابل فهم داخل خروجی نهایی وجود داشته باشد.


⚙️ تأکید اجباری: نسخه cPanel-Ready و مستندسازی پایان هر فاز

این بخش باید در پرامپت اصلی پروژه، پرامپت مادر فازها و دستور اجرای هر فاز به‌صورت صریح رعایت شود.


۱. نسخه اجرایی فقط cPanel-Ready باشد

پروژه فقط باید با پشته فنی ساده، قابل نصب روی cPanel و بدون ابزارهای build توسعه داده شود.

مشخصات فنی اجباری


نسخه cPanel-Ready (PHP + Vanilla JS + MySQL)

Frontend:
- PHP + HTML
- Vanilla JavaScript خالص
- بدون React
- بدون Vue
- بدون Angular
- بدون Alpine
- بدون TypeScript
- بدون npm / yarn
- بدون Vite / Webpack / Parcel
- بدون Build Process

Styling:
- Tailwind CSS فقط از CDN
- بدون build Tailwind
- بدون PostCSS
- بدون Sass/Less اجباری

Icons:
- Font Awesome فقط از CDN

Charts:
- Chart.js فقط از CDN

Confetti:
- canvas-confetti فقط از CDN

QR Code:
- qrcodejs فقط از CDN

Backend:
- PHP 7.4+
- Vanilla PHP
- بدون Laravel
- بدون Symfony
- بدون CodeIgniter
- بدون Framework سنگین

Database:
- MySQL 5.7+
- PDO
- Prepared Statements اجباری

Authentication:
- PHP Session
- بدون JWT برای ورود پنل‌ها

API:
- PHP فایل‌های مجزا
- بدون Router پیچیده
- بدون Node.js
- بدون Express
- بدون REST Framework سنگین

قانون مهم پیاده‌سازی

هر صفحه یا API باید با فایل PHP ساده قابل اجرا باشد. مسیرها می‌توانند با .htaccess مرتب شوند، اما نباید وابسته به Router پیچیده، Composer سنگین یا Build Process باشند.

نمونه ساختار API مجاز:


api/v1/auth/login.php
api/v1/schools/create.php
api/v1/students/list.php
api/v1/exams/create.php
api/v1/forms/submit.php
api/v1/reports/export.php

نمونه ساختار Frontend مجاز:


views/superadmin/dashboard.php
views/school/dashboard.php
views/teacher/exam_builder.php
views/counselor/form_builder.php

۲. موارد ممنوع در کل پروژه


ممنوع:
- React / Vue / Angular / Svelte
- Node.js / Express / NestJS
- Laravel / Symfony / CodeIgniter
- JWT برای احراز هویت پنل‌ها
- npm / yarn / pnpm
- Vite / Webpack / Parcel
- TypeScript
- Build Process
- Tailwind Build
- API Router پیچیده
- Docker به‌عنوان نیاز اجباری

۳. قانون اجباری بعد از پایان هر فاز

بعد از پایان هر فاز، توسعه‌دهنده یا هوش مصنوعی باید یک فایل Markdown مخصوص همان فاز بسازد تا وضعیت پروژه ذخیره شود و در ادامه پروژه مجبور نباشیم از اول کارها را بررسی یا تکرار کنیم.

مسیر پیشنهادی:


project_docs/phases/
├── PHASE_01_STATUS.md
├── PHASE_02_STATUS.md
├── PHASE_03_STATUS.md
└── ...

نام فایل باید مطابق شماره فاز باشد:


PHASE_XX_STATUS.md

مثال:


project_docs/phases/PHASE_05_STATUS.md

۴. محتوای اجباری فایل MD پایان هر فاز

هر فایل وضعیت فاز باید شامل این بخش‌ها باشد:


# گزارش وضعیت فاز X

## ۱. عنوان فاز
نام فاز و هدف اصلی آن.

## ۲. تاریخ انجام
تاریخ و ساعت انجام فاز.

## ۳. کارهای انجام‌شده
- مورد ۱
- مورد ۲
- مورد ۳

## ۴. فایل‌های ساخته‌شده
- path/to/file.php
- path/to/file.js
- path/to/file.css

## ۵. فایل‌های ویرایش‌شده
- path/to/edited-file.php

## ۶. جداول دیتابیس مرتبط
- جدول ۱
- جدول ۲

## ۷. APIهای ساخته‌شده
- api/v1/example/create.php
- api/v1/example/list.php

## ۸. صفحات ساخته‌شده
- views/example/page.php

## ۹. نکات امنیتی رعایت‌شده
- CSRF
- PDO Prepared Statements
- XSS escape
- Session check
- Role check

## ۱۰. تست‌های انجام‌شده
- تست ورود
- تست ثبت اطلاعات
- تست محدودیت پکیج

## ۱۱. کارهای باقی‌مانده
- مورد باقی‌مانده ۱
- مورد باقی‌مانده ۲

## ۱۲. خطاها یا ریسک‌های شناخته‌شده
- مورد ۱

## ۱۳. وابستگی به فازهای بعدی
- فاز X
- فاز Y

## ۱۴. دستور ادامه برای فاز بعد
یک پرامپت کوتاه برای ادامه کار از همین نقطه.

۵. قانون جلوگیری از دوباره‌کاری

قبل از شروع هر فاز جدید، ابتدا باید فایل‌های زیر خوانده شوند:


project_docs/phases/PHASE_01_STATUS.md
project_docs/phases/PHASE_02_STATUS.md
...

سپس فقط کارهای باقی‌مانده و فاز جدید انجام شود. هیچ فاز نباید از ابتدا بازنویسی شود مگر کاربر صراحتاً درخواست کند.


۶. چک‌لیست پایان هر فاز


□ فاز طبق معماری دیتابیس واحد انجام شد
□ هیچ ابزار غیر cPanel-Ready استفاده نشد
□ هیچ Framework ممنوع استفاده نشد
□ هیچ Build Process اضافه نشد
□ PHP Session برای احراز هویت استفاده شد
□ PDO Prepared Statements رعایت شد
□ CSRF در فرم‌ها رعایت شد
□ XSS Escape رعایت شد
□ فایل PHASE_XX_STATUS.md ساخته شد
□ کارهای انجام‌شده نوشته شد
□ کارهای باقی‌مانده نوشته شد
□ فایل‌های ساخته/ویرایش‌شده ثبت شد
□ دستور ادامه فاز بعد نوشته شد

📚 فایل کامل تمام ۹ فایل MD پروژه

مشخصهمقدار
نام پروژهپلتفرم مدیریت هوشمند مدارس
محتواادغام کامل ۹ فایل MD ویرایش‌شده
معماری نهاییSingle Database + Multi-School Management + Modular Packages
نسخه اجراییcPanel-Ready فقط با PHP + Vanilla JS + MySQL
تاریخ تولید2026-06-12 14:06:35

فهرست

  1. پرامپت جامع نهایی پروژه
  2. بخش ۱ — مقدمه، معماری، پشته فنی و طراحی داشبوردها
  3. بخش ۲ — دیتابیس واحد
  4. بخش ۳ — کاربران و ساختار آموزشی
  5. بخش ۴ — مشاوره و فرم‌ساز
  6. بخش ۵ — آزمون‌ساز، بانک سوال، تکالیف و نمرات
  7. بخش ۶ — پروفایل ۳۶۰، ارتباطات و نظرسنجی
  8. بخش ۷ — کدهای پایه PHP
  9. بخش ۸ — فازبندی، Cron و چک‌لیست‌ها

<a id="section-1"></a>


پرامپت جامع نهایی پروژه

منبع: PROJECT_PROMPT_UPDATED.md

📚 سند اصلاح‌شده پروژه: پلتفرم مدیریت هوشمند مدارس

نسخه بدون سیستم چندمستأجری Database-per-Tenant

مشخصهمقدار
نام پروژهپلتفرم مدیریت هوشمند مدارس
نوع معماریSingle Database + Multi-School Management + Modular Packages
طراحی و توسعهشرکت سایناوب
نسخه سند۳.۰.۰ — اصلاح‌شده طبق حذف چندمستأجری DB-per-Tenant
وضعیتآماده توسعه

۱. تعریف پروژه

یک پلتفرم مدیریت هوشمند مدارس بساز که با یک دیتابیس واحد کار کند، اما دارای داشبورد سوپرادمین مستقل برای تعریف و مدیریت مدارس، پکیج‌ها، امکانات قابل استفاده، تعداد مجاز کاربران/دانش‌آموزان و اشتراک هر مدرسه باشد.

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


۲. معماری جدید

۲.۱ معماری دیتابیس

در نسخه جدید فقط یک دیتابیس وجود دارد:


school_platform_db
├── جداول سطح پلتفرم
│   ├── super_admins
│   ├── schools
│   ├── module_catalog
│   ├── subscription_plans
│   ├── school_subscriptions
│   ├── school_feature_overrides
│   ├── invoices
│   ├── payments
│   ├── support_tickets
│   └── platform_logs
│
└── جداول مدرسه‌ای با school_id
    ├── users
    ├── academic_years
    ├── subjects
    ├── forms
    ├── exams
    ├── question_bank
    ├── assignments
    ├── grades
    ├── attendance
    ├── behavior_records
    ├── messages
    ├── surveys
    └── ...

۲.۲ نکته بسیار مهم

دیگر نباید این موارد وجود داشته باشد:

به جای آن:


۳. داشبورد سوپرادمین مستقل

سوپرادمین یک پنل مستقل دارد و نباید با پنل مدیر مدرسه یکی شود.

مسیرها


/superadmin/login
/superadmin/dashboard
/superadmin/schools
/superadmin/schools/create
/superadmin/schools/edit/{id}
/superadmin/packages
/superadmin/packages/create
/superadmin/modules
/superadmin/receipts
/superadmin/invoices
/superadmin/settings
/superadmin/logs

امکانات سوپرادمین


۴. پنل مدیر مدرسه

مدیر مدرسه فقط مدرسه خودش را می‌بیند و اجازه تغییر پکیج یا امکانات پایه سیستم را ندارد، مگر از طریق خرید یا درخواست فعال‌سازی.

مسیرها


/school/dashboard
/school/students
/school/teachers
/school/counselors
/school/vice-principals
/school/classes
/school/academic-years
/school/settings
/school/wallet
/school/support

محدودیت مهم

همه کوئری‌های پنل مدرسه باید شرط زیر را داشته باشند:


WHERE school_id = currentSchoolId()

۵. پکیج‌بندی امکانات

سوپرادمین باید بتواند پکیج بسازد و داخل آن مشخص کند:

  1. چه ماژول‌هایی فعال هستند.
  2. محدودیت هر ماژول چقدر است.
  3. قیمت ماهانه/سالانه چقدر است.
  4. تعداد مجاز دانش‌آموزان چقدر است.
  5. امکانات ویژه مثل API، دامنه اختصاصی، white-label فعال باشد یا نه.

مثال پکیج فقط آزمون‌ساز


{
  "plan_code": "exam_only",
  "plan_name": "فقط آزمون‌ساز",
  "modules": {
    "exam_builder": true,
    "question_bank": true,
    "coordinated_exam": false,
    "assignments": false,
    "grades": false,
    "counseling": false,
    "form_builder": false,
    "profile_360": false,
    "survey_360": false,
    "chat": false,
    "sms": true,
    "pdf_export": true,
    "excel_export": true
  },
  "limits": {
    "max_students": 300,
    "max_teachers": 30,
    "max_exams_monthly": 100,
    "max_questions": 5000,
    "max_sms_monthly": 500,
    "max_storage_gb": 3
  }
}

مثال پکیج فقط مشاوره


{
  "plan_code": "counseling_only",
  "plan_name": "فقط مشاوره",
  "modules": {
    "counseling": true,
    "form_builder": true,
    "assessment_library": true,
    "profile_360": true,
    "exam_builder": false,
    "question_bank": false,
    "assignments": false,
    "grades": false,
    "attendance": false,
    "survey_360": false,
    "chat": true,
    "sms": true,
    "pdf_export": true
  },
  "limits": {
    "max_students": 500,
    "max_counselors": 5,
    "max_forms_monthly": 100,
    "max_submissions_monthly": 5000,
    "max_sms_monthly": 1000,
    "max_storage_gb": 5
  }
}

۶. دیتابیس واحد — جداول اصلی

۶.۱ ایجاد دیتابیس


CREATE DATABASE IF NOT EXISTS `school_platform_db`
CHARACTER SET utf8mb4 COLLATE utf8mb4_persian_ci;

USE `school_platform_db`;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

۶.۲ جدول سوپرادمین‌ها


CREATE TABLE `super_admins` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `username` VARCHAR(100) NOT NULL,
    `password` VARCHAR(255) NOT NULL,
    `email` VARCHAR(255),
    `phone` VARCHAR(15),
    `first_name` VARCHAR(100) NOT NULL,
    `last_name` VARCHAR(100) NOT NULL,
    `role` ENUM('super_admin','admin','support','finance') DEFAULT 'super_admin',
    `permissions` JSON,
    `is_active` TINYINT(1) DEFAULT 1,
    `last_login_at` TIMESTAMP NULL,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY `uk_super_username` (`username`),
    UNIQUE KEY `uk_super_email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

۶.۳ جدول مدارس


CREATE TABLE `schools` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `school_code` VARCHAR(20) NOT NULL COMMENT 'کد یکتای مدرسه',
    `school_name` VARCHAR(255) NOT NULL,
    `school_type` ENUM('elementary','middle','high','all') DEFAULT 'all',
    `school_gender` ENUM('boys','girls','mixed') DEFAULT 'mixed',
    `education_type` ENUM('public','private','nonprofit','sampad','shahed') DEFAULT 'private',
    `province` VARCHAR(100),
    `city` VARCHAR(100),
    `district` VARCHAR(100),
    `address` TEXT,
    `phone` VARCHAR(20),
    `email` VARCHAR(255),
    `principal_name` VARCHAR(255),
    `principal_phone` VARCHAR(15),
    `logo_path` VARCHAR(255),
    `primary_color` VARCHAR(20) DEFAULT '#1e40af',
    `secondary_color` VARCHAR(20) DEFAULT '#64748b',
    `subdomain` VARCHAR(100),
    `custom_domain` VARCHAR(255),
    `status` ENUM('pending','active','suspended','expired','deleted') DEFAULT 'pending',
    `status_reason` VARCHAR(255),
    `is_trial` TINYINT(1) DEFAULT 0,
    `trial_started_at` TIMESTAMP NULL,
    `trial_expires_at` TIMESTAMP NULL,
    `current_plan_id` INT UNSIGNED,
    `subscription_started_at` TIMESTAMP NULL,
    `subscription_expires_at` TIMESTAMP NULL,
    `wallet_balance` DECIMAL(15,2) DEFAULT 0,
    `sms_balance` INT DEFAULT 0,
    `students_count` INT DEFAULT 0,
    `teachers_count` INT DEFAULT 0,
    `counselors_count` INT DEFAULT 0,
    `parents_count` INT DEFAULT 0,
    `last_activity_at` TIMESTAMP NULL,
    `admin_notes` TEXT,
    `created_by` INT UNSIGNED,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `deleted_at` TIMESTAMP NULL,
    UNIQUE KEY `uk_school_code` (`school_code`),
    UNIQUE KEY `uk_subdomain` (`subdomain`),
    UNIQUE KEY `uk_custom_domain` (`custom_domain`),
    INDEX `idx_status` (`status`),
    INDEX `idx_current_plan` (`current_plan_id`),
    CONSTRAINT `fk_schools_created_by` FOREIGN KEY (`created_by`) REFERENCES `super_admins`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

۶.۴ کاتالوگ ماژول‌ها


CREATE TABLE `module_catalog` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `module_key` VARCHAR(100) NOT NULL,
    `module_name` VARCHAR(255) NOT NULL,
    `module_group` ENUM('counseling','education','communication','reporting','commercial','system') NOT NULL,
    `description` TEXT,
    `icon` VARCHAR(50),
    `sort_order` INT DEFAULT 0,
    `is_active` TINYINT(1) DEFAULT 1,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY `uk_module_key` (`module_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

۶.۵ پکیج‌ها


CREATE TABLE `subscription_plans` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `plan_name` VARCHAR(255) NOT NULL,
    `plan_code` VARCHAR(50) NOT NULL,
    `description` TEXT,
    `icon` VARCHAR(50) DEFAULT 'fa-box',
    `color` VARCHAR(20) DEFAULT '#6366f1',
    `modules` JSON NOT NULL COMMENT 'فعال/غیرفعال بودن ماژول‌ها',
    `limits` JSON NOT NULL COMMENT 'محدودیت‌ها مثل max_students',
    `pricing_model` ENUM('flat','per_student','hybrid','custom') DEFAULT 'flat',
    `flat_price_monthly` DECIMAL(15,0),
    `flat_price_yearly` DECIMAL(15,0),
    `price_per_student_monthly` DECIMAL(12,0),
    `price_per_student_yearly` DECIMAL(12,0),
    `setup_fee` DECIMAL(15,0) DEFAULT 0,
    `is_active` TINYINT(1) DEFAULT 1,
    `is_featured` TINYINT(1) DEFAULT 0,
    `is_trial_plan` TINYINT(1) DEFAULT 0,
    `sort_order` INT DEFAULT 0,
    `created_by` INT UNSIGNED,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY `uk_plan_code` (`plan_code`),
    CONSTRAINT `fk_plans_created_by` FOREIGN KEY (`created_by`) REFERENCES `super_admins`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

۶.۶ override امکانات مدرسه

برای اینکه سوپرادمین بتواند خارج از پکیج یک قابلیت را برای یک مدرسه فعال یا غیرفعال کند:


CREATE TABLE `school_feature_overrides` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `school_id` INT UNSIGNED NOT NULL,
    `module_key` VARCHAR(100) NOT NULL,
    `override_value` ENUM('enabled','disabled') NOT NULL,
    `reason` VARCHAR(500),
    `starts_at` TIMESTAMP NULL,
    `expires_at` TIMESTAMP NULL,
    `created_by` INT UNSIGNED,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY `uk_school_module` (`school_id`, `module_key`),
    INDEX `idx_school` (`school_id`),
    CONSTRAINT `fk_sfo_school` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_sfo_admin` FOREIGN KEY (`created_by`) REFERENCES `super_admins`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

۶.۷ override محدودیت‌ها


CREATE TABLE `school_limit_overrides` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `school_id` INT UNSIGNED NOT NULL,
    `limit_key` VARCHAR(100) NOT NULL,
    `limit_value` INT NOT NULL,
    `reason` VARCHAR(500),
    `starts_at` TIMESTAMP NULL,
    `expires_at` TIMESTAMP NULL,
    `created_by` INT UNSIGNED,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY `uk_school_limit` (`school_id`, `limit_key`),
    CONSTRAINT `fk_slo_school` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_slo_admin` FOREIGN KEY (`created_by`) REFERENCES `super_admins`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

۷. قانون جداول مدرسه‌ای

همه جداول مدرسه‌ای باید school_id داشته باشند. مثال جدول کاربران:


CREATE TABLE `users` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `school_id` INT UNSIGNED NOT NULL,
    `username` VARCHAR(100) NOT NULL,
    `password` VARCHAR(255) NOT NULL,
    `role` ENUM('school_admin','vice_principal','counselor','teacher','parent','student') NOT NULL,
    `first_name` VARCHAR(100) NOT NULL,
    `last_name` VARCHAR(100) NOT NULL,
    `national_code` VARCHAR(10),
    `phone` VARCHAR(15) NOT NULL,
    `email` VARCHAR(255),
    `grade` VARCHAR(50),
    `class_name` VARCHAR(50),
    `student_code` VARCHAR(50),
    `is_active` TINYINT(1) DEFAULT 1,
    `last_login_at` TIMESTAMP NULL,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY `uk_school_username` (`school_id`, `username`),
    UNIQUE KEY `uk_school_student_code` (`school_id`, `student_code`),
    INDEX `idx_school_role` (`school_id`, `role`),
    INDEX `idx_school_phone` (`school_id`, `phone`),
    INDEX `idx_school_grade_class` (`school_id`, `grade`, `class_name`),
    CONSTRAINT `fk_users_school` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

نمونه جدول فرم‌ها:


CREATE TABLE `forms` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `school_id` INT UNSIGNED NOT NULL,
    `created_by` INT UNSIGNED NOT NULL,
    `title` VARCHAR(255) NOT NULL,
    `form_slug` VARCHAR(100) NOT NULL,
    `status` ENUM('draft','active','paused','closed','archived') DEFAULT 'draft',
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY `uk_school_slug` (`school_id`, `form_slug`),
    INDEX `idx_school_status` (`school_id`, `status`),
    CONSTRAINT `fk_forms_school` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_forms_creator` FOREIGN KEY (`created_by`) REFERENCES `users`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

نمونه جدول آزمون‌ها:


CREATE TABLE `exams` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `school_id` INT UNSIGNED NOT NULL,
    `teacher_id` INT UNSIGNED NOT NULL,
    `subject_id` INT UNSIGNED NOT NULL,
    `exam_title` VARCHAR(255) NOT NULL,
    `start_datetime` DATETIME NOT NULL,
    `end_datetime` DATETIME NOT NULL,
    `duration_minutes` INT NOT NULL,
    `status` ENUM('draft','scheduled','active','finished','cancelled') DEFAULT 'draft',
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX `idx_school_status` (`school_id`, `status`),
    INDEX `idx_school_teacher` (`school_id`, `teacher_id`),
    CONSTRAINT `fk_exams_school` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_exams_teacher` FOREIGN KEY (`teacher_id`) REFERENCES `users`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

۸. کد پایه PHP

۸.۱ اتصال دیتابیس واحد


<?php
// config/database.php

define('DB_HOST', 'localhost');
define('DB_PORT', 3306);
define('DB_NAME', 'school_platform_db');
define('DB_USER', 'root');
define('DB_PASS', '');
define('DB_CHARSET', 'utf8mb4');

function db(): PDO {
    static $pdo = null;
    if ($pdo === null) {
        $dsn = 'mysql:host=' . DB_HOST . ';port=' . DB_PORT . ';dbname=' . DB_NAME . ';charset=' . DB_CHARSET;
        $pdo = new PDO($dsn, DB_USER, DB_PASS, [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES => false,
            PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4 COLLATE utf8mb4_persian_ci",
        ]);
    }
    return $pdo;
}

۸.۲ دریافت مدرسه فعلی


function currentSchoolId(): ?int {
    return $_SESSION['school_id'] ?? null;
}

function requireSchoolContext(): int {
    $schoolId = currentSchoolId();
    if (!$schoolId) {
        http_response_code(403);
        die('مدرسه انتخاب نشده است');
    }
    return (int) $schoolId;
}

۸.۳ بررسی ماژول


function hasModule(string $moduleKey, ?int $schoolId = null): bool {
    $schoolId = $schoolId ?? currentSchoolId();
    if (!$schoolId) return false;

    $pdo = db();

    // اول override اختصاصی مدرسه بررسی شود
    $stmt = $pdo->prepare("\
        SELECT override_value
        FROM school_feature_overrides
        WHERE school_id = ? AND module_key = ?
          AND (starts_at IS NULL OR starts_at <= NOW())
          AND (expires_at IS NULL OR expires_at >= NOW())
    ");
    $stmt->execute([$schoolId, $moduleKey]);
    $override = $stmt->fetchColumn();

    if ($override === 'enabled') return true;
    if ($override === 'disabled') return false;

    // سپس پلن مدرسه
    $stmt = $pdo->prepare("\
        SELECT sp.modules
        FROM schools s
        JOIN subscription_plans sp ON sp.id = s.current_plan_id
        WHERE s.id = ? AND s.status IN ('active','expired')
    ");
    $stmt->execute([$schoolId]);
    $modulesJson = $stmt->fetchColumn();
    if (!$modulesJson) return false;

    $modules = json_decode($modulesJson, true) ?: [];
    return !empty($modules[$moduleKey]);
}

function requireModule(string $moduleKey): void {
    if (!hasModule($moduleKey)) {
        http_response_code(403);
        include __DIR__ . '/../views/errors/module_disabled.php';
        exit;
    }
}

۸.۴ بررسی محدودیت‌ها


function getSchoolLimit(string $limitKey, ?int $schoolId = null): int {
    $schoolId = $schoolId ?? currentSchoolId();
    if (!$schoolId) return 0;

    $pdo = db();

    // override محدودیت
    $stmt = $pdo->prepare("\
        SELECT limit_value
        FROM school_limit_overrides
        WHERE school_id = ? AND limit_key = ?
          AND (starts_at IS NULL OR starts_at <= NOW())
          AND (expires_at IS NULL OR expires_at >= NOW())
    ");
    $stmt->execute([$schoolId, $limitKey]);
    $override = $stmt->fetchColumn();
    if ($override !== false) return (int) $override;

    // محدودیت پلن
    $stmt = $pdo->prepare("\
        SELECT sp.limits
        FROM schools s
        JOIN subscription_plans sp ON sp.id = s.current_plan_id
        WHERE s.id = ?
    ");
    $stmt->execute([$schoolId]);
    $limitsJson = $stmt->fetchColumn();
    $limits = json_decode($limitsJson ?: '{}', true) ?: [];
    return (int) ($limits[$limitKey] ?? 0);
}

function enforceLimit(string $limitKey, int $currentCount): void {
    $limit = getSchoolLimit($limitKey);
    if ($limit > 0 && $currentCount >= $limit) {
        http_response_code(403);
        die('محدودیت پکیج شما برای این بخش تکمیل شده است.');
    }
}

۸.۵ مثال محدودیت تعداد دانش‌آموز


function canCreateStudent(int $schoolId): bool {
    $pdo = db();
    $stmt = $pdo->prepare("SELECT COUNT(*) FROM users WHERE school_id = ? AND role = 'student'");
    $stmt->execute([$schoolId]);
    $current = (int) $stmt->fetchColumn();
    $max = getSchoolLimit('max_students', $schoolId);
    return $max === 0 || $current < $max;
}

۹. SchoolProvisioner به جای SchoolInstaller


<?php
class SchoolProvisioner {
    private PDO $pdo;

    public function __construct() {
        $this->pdo = db();
    }

    public function createSchool(array $data): array {
        try {
            $this->pdo->beginTransaction();

            $schoolCode = $this->generateSchoolCode();

            $stmt = $this->pdo->prepare("\
                INSERT INTO schools (
                    school_code, school_name, school_type, school_gender,
                    province, city, phone, email, principal_name, principal_phone,
                    current_plan_id, status, is_trial, trial_started_at, trial_expires_at,
                    subscription_started_at, subscription_expires_at,
                    created_by, created_at
                ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'active', ?, ?, ?, ?, ?, ?, NOW())
            ");

            $isTrial = !empty($data['is_trial']);
            $trialDays = (int) getSystemSetting('trial_days', 14);
            $now = date('Y-m-d H:i:s');
            $trialExpires = $isTrial ? date('Y-m-d H:i:s', strtotime("+{$trialDays} days")) : null;

            $stmt->execute([
                $schoolCode,
                $data['school_name'],
                $data['school_type'] ?? 'all',
                $data['school_gender'] ?? 'mixed',
                $data['province'] ?? null,
                $data['city'] ?? null,
                $data['phone'] ?? null,
                $data['email'] ?? null,
                $data['principal_name'] ?? null,
                $data['principal_phone'] ?? null,
                $data['plan_id'] ?? null,
                $isTrial ? 1 : 0,
                $isTrial ? $now : null,
                $trialExpires,
                $now,
                $data['subscription_expires_at'] ?? $trialExpires,
                $_SESSION['admin_id'] ?? null,
            ]);

            $schoolId = (int) $this->pdo->lastInsertId();

            // ایجاد ادمین مدرسه در جدول users همان دیتابیس
            $stmt = $this->pdo->prepare("\
                INSERT INTO users (
                    school_id, username, password, role,
                    first_name, last_name, phone, email,
                    is_active, created_at
                ) VALUES (?, ?, ?, 'school_admin', ?, ?, ?, ?, 1, NOW())
            ");
            $stmt->execute([
                $schoolId,
                $data['admin_username'],
                password_hash($data['admin_password'], PASSWORD_BCRYPT),
                $data['admin_first_name'] ?? 'مدیر',
                $data['admin_last_name'] ?? 'مدرسه',
                $data['admin_phone'],
                $data['admin_email'] ?? null,
            ]);

            $this->createDefaultSchoolSettings($schoolId, $data['school_name']);
            $this->createSchoolDirectories($schoolCode);
            $this->log('school_created', $schoolId, ['school_code' => $schoolCode]);

            $this->pdo->commit();

            return [
                'success' => true,
                'school_id' => $schoolId,
                'school_code' => $schoolCode
            ];
        } catch (Exception $e) {
            $this->pdo->rollBack();
            return ['success' => false, 'message' => $e->getMessage()];
        }
    }

    private function generateSchoolCode(): string {
        do {
            $code = substr(md5(uniqid(mt_rand(), true)), 0, 8);
            $stmt = $this->pdo->prepare("SELECT COUNT(*) FROM schools WHERE school_code = ?");
            $stmt->execute([$code]);
        } while ((int) $stmt->fetchColumn() > 0);
        return $code;
    }

    private function createDefaultSchoolSettings(int $schoolId, string $schoolName): void {
        $settings = [
            ['school_name', $schoolName, 'string'],
            ['timezone', 'Asia/Tehran', 'string'],
            ['date_format', 'jalali', 'string'],
            ['grading_system', '20', 'number'],
            ['onboarding_completed', '0', 'boolean']
        ];
        $stmt = $this->pdo->prepare("INSERT INTO school_settings (school_id, setting_key, setting_value, setting_type) VALUES (?, ?, ?, ?)");
        foreach ($settings as $s) {
            $stmt->execute([$schoolId, $s[0], $s[1], $s[2]]);
        }
    }

    private function createSchoolDirectories(string $schoolCode): void {
        $base = __DIR__ . '/../uploads/schools/' . $schoolCode;
        foreach (['', '/avatars', '/logos', '/excel', '/qrcodes', '/attachments', '/exports'] as $dir) {
            if (!is_dir($base . $dir)) mkdir($base . $dir, 0755, true);
        }
        file_put_contents($base . '/.htaccess', "Options -Indexes\n<FilesMatch \\\"\\.php$\\\">\nDeny from all\n</FilesMatch>");
    }

    private function log(string $action, int $schoolId, array $details = []): void {
        $stmt = $this->pdo->prepare("INSERT INTO platform_logs (actor_type, actor_id, school_id, action, details, created_at) VALUES ('super_admin', ?, ?, ?, ?, NOW())");
        $stmt->execute([$_SESSION['admin_id'] ?? null, $schoolId, $action, json_encode($details, JSON_UNESCAPED_UNICODE)]);
    }
}

۱۰. احراز هویت

ورود سوپرادمین

ورود کاربران مدرسه


$stmt = db()->prepare("\
    SELECT * FROM users
    WHERE school_id = ? AND (username = ? OR phone = ? OR national_code = ?)
    LIMIT 1
");

۱۱. فازهای اصلاح‌شده ابتدایی

فاز ۱: پایه پروژه و دیتابیس واحد

معیار تأیید:

فاز ۲: احراز هویت مستقل

فاز ۳: سوپرادمین و تعریف مدرسه

فاز ۴: مدیریت پکیج‌ها و دسترسی ماژول‌ها


۱۲. چک‌لیست اجباری توسعه


۱۳. خلاصه نهایی

این پروژه دیگر Database-per-Tenant نیست. سیستم با یک دیتابیس واحد پیاده‌سازی می‌شود، اما قابلیت مدیریت چند مدرسه، تعریف پکیج، فعال/غیرفعال کردن ماژول‌ها و اعمال محدودیت‌های تجاری برای هر مدرسه حفظ می‌شود. سوپرادمین یک پنل مستقل دارد و از طریق آن مدرسه و سطح دسترسی مدرسه به امکانات اسکریپت را مدیریت می‌کند.


۱۴. دستور طراحی اختصاصی داشبوردها — Light Aurora بدون Glassmorphism

این بخش فقط مربوط به طراحی داشبوردهاست و باید برای همه پنل‌ها اعمال شود: سوپرادمین، مدیر مدرسه، معاون، مشاور، معلم، والدین و دانش‌آموز.

اصل طراحی

داشبوردها باید سبک Modern Light Aurora داشته باشند؛ یعنی پس‌زمینه روشن، نرم، مدرن و رنگی با حس Aurora. اما کارت‌ها و پنل‌ها نباید شیشه‌ای باشند.

استفاده از Glassmorphism ممنوع است:


ممنوع:
- glassmorphism
- frosted glass
- backdrop-filter
- backdrop-blur روی کارت‌ها
- کارت‌های خیلی شفاف
- متن روی پنل‌های نیمه‌شفاف ناخوانا

استفاده شود از:


مجاز و مطلوب:
- پس‌زمینه Aurora روشن با blobهای نرم و محو
- کارت‌های solid سفید یا off-white
- border ظریف و روشن
- سایه نرم و مدرن
- گوشه‌های گرد
- تایپوگرافی خوانا
- گرادینت‌های زیبا برای نمودارها، دکمه‌ها، progress barها و active stateها

Prompt طراحی داشبورد


Design modern, premium, responsive Dashboard UIs for a Smart School Management Platform using a Light Aurora aesthetic, but do not use glassmorphism.

The main background may include soft, blurred organic Aurora shapes with vibrant pastel colors such as mint green, soft peach, vivid pink, lavender, and electric blue. These colors should blend softly in the background only.

Dashboard cards and panels must be solid, readable, and not transparent. Do not use backdrop-filter or backdrop-blur for cards. Use solid white, off-white, or very light tinted card backgrounds with subtle borders, rounded corners, and soft shadows.

The UI should feel modern, bright, clean, educational, premium, and SaaS-like. Typography must be readable, dark slate or charcoal, and RTL-friendly. Use Vazirmatn or a similar Persian-friendly font.

Use vibrant gradients only for accents such as charts, buttons, badges, active sidebar items, and progress bars.

All dashboard layouts must be responsive and work well on desktop, tablet, and mobile.

رنگ‌ها باید از پنل سوپرادمین قابل تنظیم باشند

هیچ رنگ اصلی نباید داخل کامپوننت‌ها hard-code شود. همه رنگ‌های داشبورد باید از تنظیمات سیستم یا تنظیمات برندینگ مدرسه خوانده شوند.

سوپرادمین باید بتواند این موارد را تنظیم کند:

کلیدتوضیح
theme_primary_colorرنگ اصلی سیستم
theme_secondary_colorرنگ دوم
theme_accent_colorرنگ accent
theme_success_colorرنگ موفقیت
theme_warning_colorرنگ هشدار
theme_danger_colorرنگ خطا
theme_info_colorرنگ اطلاع‌رسانی
dashboard_bg_colorرنگ پایه پس‌زمینه داشبورد
aurora_color_1رنگ اول Aurora
aurora_color_2رنگ دوم Aurora
aurora_color_3رنگ سوم Aurora
aurora_color_4رنگ چهارم Aurora
card_bg_colorرنگ کارت‌ها
card_border_colorرنگ border کارت‌ها
sidebar_bg_colorرنگ Sidebar
active_menu_gradient_startشروع گرادینت آیتم فعال
active_menu_gradient_endپایان گرادینت آیتم فعال
chart_gradient_startشروع گرادینت نمودارها
chart_gradient_endپایان گرادینت نمودارها
button_gradient_startشروع گرادینت دکمه‌ها
button_gradient_endپایان گرادینت دکمه‌ها

CSS Variables پیشنهادی


:root {
  --color-primary: #2563eb;
  --color-secondary: #7c3aed;
  --color-accent: #ec4899;
  --color-success: #10b981;
  --color-warning: #f59e0b;
  --color-danger: #ef4444;
  --color-info: #06b6d4;

  --dashboard-bg: #f8fafc;
  --aurora-1: #99f6e4;
  --aurora-2: #fed7aa;
  --aurora-3: #f0abfc;
  --aurora-4: #93c5fd;

  --card-bg: #ffffff;
  --card-border: #e2e8f0;
  --text-main: #0f172a;
  --text-muted: #64748b;

  --chart-gradient-start: #2563eb;
  --chart-gradient-end: #ec4899;
  --button-gradient-start: #2563eb;
  --button-gradient-end: #7c3aed;
  --active-menu-gradient-start: #2563eb;
  --active-menu-gradient-end: #ec4899;
}

نمونه استایل کارت


.dashboard-card {
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: 24px;
  box-shadow: 0 18px 45px rgba(15, 23, 42, 0.08);
}
تأکید نهایی: فقط پس‌زمینه می‌تواند حالت Aurora و blur تزئینی داشته باشد. کارت‌ها و پنل‌های داشبورد شیشه‌ای نیستند.

🎨 استاندارد طراحی داشبوردها — Modern Light Aurora بدون Glassmorphism

این استاندارد برای همه داشبوردها اجباری است: سوپرادمین، مدیر مدرسه، معاون، مشاور، معلم، والدین و دانش‌آموز.

اصل طراحی

داشبوردها باید مدرن، روشن، نرم، premium و SaaS-like باشند. پس‌زمینه می‌تواند حالت Light Aurora داشته باشد: blobهای نرم و محو با رنگ‌های پاستلی مثل mint، peach، pink، lavender و electric blue. اما کارت‌ها و پنل‌ها نباید شیشه‌ای باشند.

ممنوع

مجاز و مطلوب

تنظیم رنگ‌ها از پنل سوپرادمین

تمام رنگ‌ها باید از پنل سوپرادمین قابل تنظیم باشند و در قالب CSS Variables خروجی داده شوند. رنگ‌ها نباید داخل کامپوننت‌ها hard-code شوند.

کلیدهای پیشنهادی تنظیمات:

کلیدتوضیح
theme_primary_colorرنگ اصلی
theme_secondary_colorرنگ دوم
theme_accent_colorرنگ accent
theme_success_colorموفقیت
theme_warning_colorهشدار
theme_danger_colorخطا
theme_info_colorاطلاع‌رسانی
dashboard_bg_colorپس‌زمینه پایه داشبورد
aurora_color_1 تا aurora_color_4رنگ‌های پس‌زمینه Aurora
card_bg_colorرنگ کارت‌ها
card_border_colorborder کارت‌ها
sidebar_bg_colorرنگ sidebar
active_menu_gradient_start/endگرادینت آیتم فعال
chart_gradient_start/endگرادینت نمودارها
button_gradient_start/endگرادینت دکمه‌ها

نمونه CSS Variables:


:root {
  --color-primary: #2563eb;
  --color-secondary: #7c3aed;
  --color-accent: #ec4899;
  --color-success: #10b981;
  --color-warning: #f59e0b;
  --color-danger: #ef4444;
  --color-info: #06b6d4;

  --dashboard-bg: #f8fafc;
  --aurora-1: #99f6e4;
  --aurora-2: #fed7aa;
  --aurora-3: #f0abfc;
  --aurora-4: #93c5fd;

  --card-bg: #ffffff;
  --card-border: #e2e8f0;
  --text-main: #0f172a;
  --text-muted: #64748b;

  --chart-gradient-start: #2563eb;
  --chart-gradient-end: #ec4899;
  --button-gradient-start: #2563eb;
  --button-gradient-end: #7c3aed;
  --active-menu-gradient-start: #2563eb;
  --active-menu-gradient-end: #ec4899;
}

.dashboard-card {
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: 24px;
  box-shadow: 0 18px 45px rgba(15, 23, 42, 0.08);
}

⚙️ تأکید اجباری: نسخه cPanel-Ready و مستندسازی پایان هر فاز

این بخش باید در پرامپت اصلی پروژه، پرامپت مادر فازها و دستور اجرای هر فاز به‌صورت صریح رعایت شود.


۱. نسخه اجرایی فقط cPanel-Ready باشد

پروژه فقط باید با پشته فنی ساده، قابل نصب روی cPanel و بدون ابزارهای build توسعه داده شود.

مشخصات فنی اجباری


نسخه cPanel-Ready (PHP + Vanilla JS + MySQL)

Frontend:
- PHP + HTML
- Vanilla JavaScript خالص
- بدون React
- بدون Vue
- بدون Angular
- بدون Alpine
- بدون TypeScript
- بدون npm / yarn
- بدون Vite / Webpack / Parcel
- بدون Build Process

Styling:
- Tailwind CSS فقط از CDN
- بدون build Tailwind
- بدون PostCSS
- بدون Sass/Less اجباری

Icons:
- Font Awesome فقط از CDN

Charts:
- Chart.js فقط از CDN

Confetti:
- canvas-confetti فقط از CDN

QR Code:
- qrcodejs فقط از CDN

Backend:
- PHP 7.4+
- Vanilla PHP
- بدون Laravel
- بدون Symfony
- بدون CodeIgniter
- بدون Framework سنگین

Database:
- MySQL 5.7+
- PDO
- Prepared Statements اجباری

Authentication:
- PHP Session
- بدون JWT برای ورود پنل‌ها

API:
- PHP فایل‌های مجزا
- بدون Router پیچیده
- بدون Node.js
- بدون Express
- بدون REST Framework سنگین

قانون مهم پیاده‌سازی

هر صفحه یا API باید با فایل PHP ساده قابل اجرا باشد. مسیرها می‌توانند با .htaccess مرتب شوند، اما نباید وابسته به Router پیچیده، Composer سنگین یا Build Process باشند.

نمونه ساختار API مجاز:


api/v1/auth/login.php
api/v1/schools/create.php
api/v1/students/list.php
api/v1/exams/create.php
api/v1/forms/submit.php
api/v1/reports/export.php

نمونه ساختار Frontend مجاز:


views/superadmin/dashboard.php
views/school/dashboard.php
views/teacher/exam_builder.php
views/counselor/form_builder.php

۲. موارد ممنوع در کل پروژه


ممنوع:
- React / Vue / Angular / Svelte
- Node.js / Express / NestJS
- Laravel / Symfony / CodeIgniter
- JWT برای احراز هویت پنل‌ها
- npm / yarn / pnpm
- Vite / Webpack / Parcel
- TypeScript
- Build Process
- Tailwind Build
- API Router پیچیده
- Docker به‌عنوان نیاز اجباری

۳. قانون اجباری بعد از پایان هر فاز

بعد از پایان هر فاز، توسعه‌دهنده یا هوش مصنوعی باید یک فایل Markdown مخصوص همان فاز بسازد تا وضعیت پروژه ذخیره شود و در ادامه پروژه مجبور نباشیم از اول کارها را بررسی یا تکرار کنیم.

مسیر پیشنهادی:


project_docs/phases/
├── PHASE_01_STATUS.md
├── PHASE_02_STATUS.md
├── PHASE_03_STATUS.md
└── ...

نام فایل باید مطابق شماره فاز باشد:


PHASE_XX_STATUS.md

مثال:


project_docs/phases/PHASE_05_STATUS.md

۴. محتوای اجباری فایل MD پایان هر فاز

هر فایل وضعیت فاز باید شامل این بخش‌ها باشد:


# گزارش وضعیت فاز X

## ۱. عنوان فاز
نام فاز و هدف اصلی آن.

## ۲. تاریخ انجام
تاریخ و ساعت انجام فاز.

## ۳. کارهای انجام‌شده
- مورد ۱
- مورد ۲
- مورد ۳

## ۴. فایل‌های ساخته‌شده
- path/to/file.php
- path/to/file.js
- path/to/file.css

## ۵. فایل‌های ویرایش‌شده
- path/to/edited-file.php

## ۶. جداول دیتابیس مرتبط
- جدول ۱
- جدول ۲

## ۷. APIهای ساخته‌شده
- api/v1/example/create.php
- api/v1/example/list.php

## ۸. صفحات ساخته‌شده
- views/example/page.php

## ۹. نکات امنیتی رعایت‌شده
- CSRF
- PDO Prepared Statements
- XSS escape
- Session check
- Role check

## ۱۰. تست‌های انجام‌شده
- تست ورود
- تست ثبت اطلاعات
- تست محدودیت پکیج

## ۱۱. کارهای باقی‌مانده
- مورد باقی‌مانده ۱
- مورد باقی‌مانده ۲

## ۱۲. خطاها یا ریسک‌های شناخته‌شده
- مورد ۱

## ۱۳. وابستگی به فازهای بعدی
- فاز X
- فاز Y

## ۱۴. دستور ادامه برای فاز بعد
یک پرامپت کوتاه برای ادامه کار از همین نقطه.

۵. قانون جلوگیری از دوباره‌کاری

قبل از شروع هر فاز جدید، ابتدا باید فایل‌های زیر خوانده شوند:


project_docs/phases/PHASE_01_STATUS.md
project_docs/phases/PHASE_02_STATUS.md
...

سپس فقط کارهای باقی‌مانده و فاز جدید انجام شود. هیچ فاز نباید از ابتدا بازنویسی شود مگر کاربر صراحتاً درخواست کند.


۶. چک‌لیست پایان هر فاز


□ فاز طبق معماری دیتابیس واحد انجام شد
□ هیچ ابزار غیر cPanel-Ready استفاده نشد
□ هیچ Framework ممنوع استفاده نشد
□ هیچ Build Process اضافه نشد
□ PHP Session برای احراز هویت استفاده شد
□ PDO Prepared Statements رعایت شد
□ CSRF در فرم‌ها رعایت شد
□ XSS Escape رعایت شد
□ فایل PHASE_XX_STATUS.md ساخته شد
□ کارهای انجام‌شده نوشته شد
□ کارهای باقی‌مانده نوشته شد
□ فایل‌های ساخته/ویرایش‌شده ثبت شد
□ دستور ادامه فاز بعد نوشته شد

<a id="section-2"></a>


بخش ۱ — مقدمه، معماری، پشته فنی و طراحی داشبوردها

منبع: 01_INTRODUCTION.md

📚 سند نهایی پروژه: پلتفرم مدیریت هوشمند مدارس

بخش ۱: مقدمه، معماری، پشته فنی، ساختار و طراحی داشبوردها

مشخصهمقدار
نام پروژهپلتفرم مدیریت هوشمند مدارس
معماری نهاییSingle Database + Multi-School Management + Modular Packages
وضعیتاصلاح‌شده نهایی — بدون Database-per-Tenant
طراحی و توسعهشرکت سایناوب

۱. تصمیم معماری نهایی

در نسخه نهایی، سیستم Database-per-Tenant نیست. یعنی برای هر مدرسه دیتابیس جدا ساخته نمی‌شود. کل پروژه روی یک دیتابیس واحد اجرا می‌شود:


school_platform_db

اما سیستم همچنان چندمدرسه‌ای است. هر مدرسه با school_id از بقیه جدا می‌شود و سوپرادمین از پنل مستقل خود می‌تواند مدرسه‌ها، پکیج‌ها، امکانات و محدودیت‌ها را مدیریت کند.

موارد حذف‌شده از معماری قبلی


حذف شده:
- ایجاد دیتابیس جدا برای هر مدرسه
- ایجاد MySQL User اختصاصی برای مدرسه
- config/school_connection.php
- SchoolInstaller با منطق ساخت دیتابیس
- school_schema.sql به‌عنوان دیتابیس جداگانه
- db_name / db_user / db_password / db_status در جدول schools

جایگزین نهایی


جایگزین:
- یک دیتابیس واحد
- ستون school_id در تمام جداول مدرسه‌ای
- SchoolProvisioner برای ثبت مدرسه و ادمین اولیه
- entitlements.php برای کنترل ماژول‌ها و محدودیت‌ها
- داشبورد مستقل سوپرادمین

۲. معماری دیتابیس واحد


school_platform_db
├── super_admins
├── schools
├── module_catalog
├── subscription_plans
├── school_feature_overrides
├── school_limit_overrides
├── school_subscriptions
├── invoices
├── payment_receipts
├── platform_logs
│
├── users                       ← دارای school_id
├── academic_years              ← دارای school_id
├── subjects                    ← دارای school_id
├── forms                       ← دارای school_id
├── exams                       ← دارای school_id
├── question_bank               ← دارای school_id
├── assignments                 ← دارای school_id
├── attendance                  ← دارای school_id
├── messages                    ← دارای school_id
└── ...                         ← تمام جداول مدرسه‌ای دارای school_id

۳. داشبورد سوپرادمین مستقل

پنل سوپرادمین از پنل مدیر مدرسه کاملاً جداست.


/superadmin/login
/superadmin/dashboard
/superadmin/schools
/superadmin/schools/create
/superadmin/packages
/superadmin/modules
/superadmin/settings
/superadmin/logs

امکانات سوپرادمین:


۴. پکیج‌بندی امکانات

هر مدرسه براساس پکیج خود به بخشی از امکانات دسترسی دارد.

نمونه کلیدهای ماژول:


{
  "counseling": true,
  "form_builder": true,
  "assessment_library": true,
  "exam_builder": true,
  "question_bank": true,
  "coordinated_exam": false,
  "assignments": false,
  "grades": false,
  "attendance": false,
  "profile_360": false,
  "survey_360": false,
  "chat": true,
  "sms": true,
  "pdf_export": true,
  "excel_export": true,
  "api_access": false
}

نمونه محدودیت‌ها:


{
  "max_students": 500,
  "max_teachers": 50,
  "max_counselors": 5,
  "max_forms_monthly": 100,
  "max_exams_monthly": 200,
  "max_questions": 5000,
  "max_sms_monthly": 1000,
  "max_storage_gb": 5
}

قبل از نمایش یا اجرای هر ماژول:


requireModule('exam_builder');

قبل از ایجاد رکوردهای محدود:


enforceLimit('max_students', $currentStudentsCount);

۵. پشته فنی


Frontend:
- HTML5 + PHP
- Tailwind CSS via CDN
- Vanilla JavaScript
- Chart.js via CDN
- Font Awesome via CDN
- بدون React/Vue/Angular
- بدون build process

Backend:
- PHP 7.4+ Vanilla
- MySQL 5.7+ / MariaDB
- PDO Prepared Statements
- PHP Session
- CSRF Token
- bcrypt password_hash

۶. ساختار پوشه نهایی


school-platform/
├── index.php
├── .htaccess
├── config/
│   ├── database.php              # اتصال به دیتابیس واحد
│   ├── app.php
│   └── constants.php
├── includes/
│   ├── auth.php
│   ├── security.php
│   ├── functions.php
│   ├── permissions.php
│   ├── entitlements.php          # hasModule / requireModule / limits
│   ├── school_provisioner.php    # ساخت مدرسه بدون ساخت DB
│   └── ...
├── database/
│   ├── schema.sql                # کل schema در یک فایل
│   └── seed.sql
├── views/
│   ├── superadmin/
│   ├── school/
│   ├── counselor/
│   ├── teacher/
│   ├── vice_principal/
│   ├── parent/
│   └── student/
├── assets/
│   ├── css/
│   └── js/
└── uploads/
    ├── platform/
    └── schools/{school_code}/

۷. نقش‌های کاربری

نقشمحل ورودمحدوده دسترسی
Super Adminجدول super_adminsکل سیستم
School Adminجدول users با school_idمدرسه خودش
Vice Principalجدول usersپایه/کلاس‌های مجاز
Counselorجدول usersدانش‌آموزان انتسابی
Teacherجدول usersکلاس‌ها و دروس خودش
Parentجدول usersفرزندان خودش
Studentجدول usersاطلاعات خودش

🎨 استاندارد طراحی داشبوردها — Modern Light Aurora بدون Glassmorphism

این استاندارد برای همه داشبوردها اجباری است: سوپرادمین، مدیر مدرسه، معاون، مشاور، معلم، والدین و دانش‌آموز.

اصل طراحی

داشبوردها باید مدرن، روشن، نرم، premium و SaaS-like باشند. پس‌زمینه می‌تواند حالت Light Aurora داشته باشد: blobهای نرم و محو با رنگ‌های پاستلی مثل mint، peach، pink، lavender و electric blue. اما کارت‌ها و پنل‌ها نباید شیشه‌ای باشند.

ممنوع

مجاز و مطلوب

تنظیم رنگ‌ها از پنل سوپرادمین

تمام رنگ‌ها باید از پنل سوپرادمین قابل تنظیم باشند و در قالب CSS Variables خروجی داده شوند. رنگ‌ها نباید داخل کامپوننت‌ها hard-code شوند.

کلیدهای پیشنهادی تنظیمات:

کلیدتوضیح
theme_primary_colorرنگ اصلی
theme_secondary_colorرنگ دوم
theme_accent_colorرنگ accent
theme_success_colorموفقیت
theme_warning_colorهشدار
theme_danger_colorخطا
theme_info_colorاطلاع‌رسانی
dashboard_bg_colorپس‌زمینه پایه داشبورد
aurora_color_1 تا aurora_color_4رنگ‌های پس‌زمینه Aurora
card_bg_colorرنگ کارت‌ها
card_border_colorborder کارت‌ها
sidebar_bg_colorرنگ sidebar
active_menu_gradient_start/endگرادینت آیتم فعال
chart_gradient_start/endگرادینت نمودارها
button_gradient_start/endگرادینت دکمه‌ها

نمونه CSS Variables:


:root {
  --color-primary: #2563eb;
  --color-secondary: #7c3aed;
  --color-accent: #ec4899;
  --color-success: #10b981;
  --color-warning: #f59e0b;
  --color-danger: #ef4444;
  --color-info: #06b6d4;

  --dashboard-bg: #f8fafc;
  --aurora-1: #99f6e4;
  --aurora-2: #fed7aa;
  --aurora-3: #f0abfc;
  --aurora-4: #93c5fd;

  --card-bg: #ffffff;
  --card-border: #e2e8f0;
  --text-main: #0f172a;
  --text-muted: #64748b;

  --chart-gradient-start: #2563eb;
  --chart-gradient-end: #ec4899;
  --button-gradient-start: #2563eb;
  --button-gradient-end: #7c3aed;
  --active-menu-gradient-start: #2563eb;
  --active-menu-gradient-end: #ec4899;
}

.dashboard-card {
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: 24px;
  box-shadow: 0 18px 45px rgba(15, 23, 42, 0.08);
}

۸. چک‌لیست اجباری


□ هیچ دیتابیس جداگانه‌ای برای مدرسه ساخته نشود
□ همه جداول مدرسه‌ای school_id داشته باشند
□ همه کوئری‌های مدرسه‌ای شرط school_id داشته باشند
□ Unique Keyهای مدرسه‌ای با school_id ترکیب شوند
□ پنل سوپرادمین مستقل باشد
□ رنگ‌های داشبورد از پنل سوپرادمین تنظیم شوند
□ کارت‌های داشبورد شیشه‌ای نباشند
□ requireModule قبل از هر ماژول اجرا شود
□ enforceLimit قبل از ایجاد رکوردهای محدود اجرا شود
□ PDO، CSRF و XSS Protection رعایت شود

<a id="section-3"></a>


بخش ۲ — دیتابیس واحد

منبع: 02_MASTER_DATABASE.md

📚 سند نهایی پروژه: پلتفرم مدیریت هوشمند مدارس

بخش ۲: دیتابیس واحد school_platform_db


۱. معرفی

در نسخه نهایی پروژه، فقط یک دیتابیس وجود دارد:


school_platform_db

این دیتابیس هم جداول سطح پلتفرم را نگهداری می‌کند و هم جداول مدرسه‌ای را. جداول مدرسه‌ای با ستون school_id از هم جدا می‌شوند.


۲. ایجاد دیتابیس


CREATE DATABASE IF NOT EXISTS `school_platform_db`
CHARACTER SET utf8mb4 COLLATE utf8mb4_persian_ci;

USE `school_platform_db`;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

۳. جدول تنظیمات سیستم


CREATE TABLE `system_settings` (
    `setting_key` VARCHAR(100) NOT NULL,
    `setting_value` TEXT,
    `setting_type` ENUM('string','number','boolean','json','html') DEFAULT 'string',
    `setting_group` VARCHAR(50) DEFAULT 'general',
    `description` VARCHAR(255),
    `is_public` TINYINT(1) DEFAULT 0,
    `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (`setting_key`),
    INDEX `idx_group` (`setting_group`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

تنظیمات رنگ داشبورد

این تنظیمات از پنل سوپرادمین قابل ویرایش هستند:


INSERT INTO `system_settings` (`setting_key`, `setting_value`, `setting_type`, `setting_group`, `description`, `is_public`) VALUES
('theme_primary_color', '#2563eb', 'string', 'theme', 'رنگ اصلی', 1),
('theme_secondary_color', '#7c3aed', 'string', 'theme', 'رنگ دوم', 1),
('theme_accent_color', '#ec4899', 'string', 'theme', 'رنگ accent', 1),
('theme_success_color', '#10b981', 'string', 'theme', 'رنگ موفقیت', 1),
('theme_warning_color', '#f59e0b', 'string', 'theme', 'رنگ هشدار', 1),
('theme_danger_color', '#ef4444', 'string', 'theme', 'رنگ خطا', 1),
('theme_info_color', '#06b6d4', 'string', 'theme', 'رنگ info', 1),
('dashboard_bg_color', '#f8fafc', 'string', 'theme', 'پس‌زمینه داشبورد', 1),
('aurora_color_1', '#99f6e4', 'string', 'theme', 'Aurora 1', 1),
('aurora_color_2', '#fed7aa', 'string', 'theme', 'Aurora 2', 1),
('aurora_color_3', '#f0abfc', 'string', 'theme', 'Aurora 3', 1),
('aurora_color_4', '#93c5fd', 'string', 'theme', 'Aurora 4', 1),
('card_bg_color', '#ffffff', 'string', 'theme', 'رنگ کارت', 1),
('card_border_color', '#e2e8f0', 'string', 'theme', 'border کارت', 1),
('chart_gradient_start', '#2563eb', 'string', 'theme', 'شروع گرادینت نمودار', 1),
('chart_gradient_end', '#ec4899', 'string', 'theme', 'پایان گرادینت نمودار', 1),
('button_gradient_start', '#2563eb', 'string', 'theme', 'شروع گرادینت دکمه', 1),
('button_gradient_end', '#7c3aed', 'string', 'theme', 'پایان گرادینت دکمه', 1);

۴. سوپرادمین‌ها


CREATE TABLE `super_admins` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `username` VARCHAR(100) NOT NULL,
    `password` VARCHAR(255) NOT NULL,
    `email` VARCHAR(255),
    `phone` VARCHAR(15),
    `first_name` VARCHAR(100) NOT NULL,
    `last_name` VARCHAR(100) NOT NULL,
    `avatar` VARCHAR(255),
    `role` ENUM('super_admin','admin','support','finance') DEFAULT 'super_admin',
    `permissions` JSON,
    `is_active` TINYINT(1) DEFAULT 1,
    `last_login_at` TIMESTAMP NULL,
    `last_login_ip` VARCHAR(45),
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY `uk_super_username` (`username`),
    UNIQUE KEY `uk_super_email` (`email`),
    INDEX `idx_role` (`role`),
    INDEX `idx_active` (`is_active`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

۵. مدارس

هیچ فیلد دیتابیس جداگانه‌ای در جدول مدارس وجود ندارد.

CREATE TABLE `schools` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `school_code` VARCHAR(20) NOT NULL,
    `school_name` VARCHAR(255) NOT NULL,
    `school_type` ENUM('elementary','middle','high','all') DEFAULT 'all',
    `school_gender` ENUM('boys','girls','mixed') DEFAULT 'mixed',
    `education_type` ENUM('public','private','nonprofit','sampad','shahed') DEFAULT 'private',
    `province` VARCHAR(100),
    `city` VARCHAR(100),
    `district` VARCHAR(100),
    `address` TEXT,
    `phone` VARCHAR(20),
    `email` VARCHAR(255),
    `principal_name` VARCHAR(255),
    `principal_phone` VARCHAR(15),
    `logo_path` VARCHAR(255),
    `primary_color` VARCHAR(20),
    `secondary_color` VARCHAR(20),
    `subdomain` VARCHAR(100),
    `custom_domain` VARCHAR(255),
    `status` ENUM('pending','active','suspended','expired','deleted') DEFAULT 'pending',
    `status_reason` VARCHAR(255),
    `is_trial` TINYINT(1) DEFAULT 0,
    `trial_started_at` TIMESTAMP NULL,
    `trial_expires_at` TIMESTAMP NULL,
    `current_plan_id` INT UNSIGNED,
    `subscription_started_at` TIMESTAMP NULL,
    `subscription_expires_at` TIMESTAMP NULL,
    `wallet_balance` DECIMAL(15,2) DEFAULT 0,
    `sms_balance` INT DEFAULT 0,
    `students_count` INT DEFAULT 0,
    `teachers_count` INT DEFAULT 0,
    `counselors_count` INT DEFAULT 0,
    `parents_count` INT DEFAULT 0,
    `last_activity_at` TIMESTAMP NULL,
    `admin_notes` TEXT,
    `created_by` INT UNSIGNED,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `deleted_at` TIMESTAMP NULL,
    UNIQUE KEY `uk_school_code` (`school_code`),
    UNIQUE KEY `uk_subdomain` (`subdomain`),
    UNIQUE KEY `uk_custom_domain` (`custom_domain`),
    INDEX `idx_status` (`status`),
    INDEX `idx_plan` (`current_plan_id`),
    CONSTRAINT `fk_schools_created_by` FOREIGN KEY (`created_by`) REFERENCES `super_admins`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

۶. کاتالوگ ماژول‌ها


CREATE TABLE `module_catalog` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `module_key` VARCHAR(100) NOT NULL,
    `module_name` VARCHAR(255) NOT NULL,
    `module_group` ENUM('counseling','education','communication','reporting','commercial','system') NOT NULL,
    `description` TEXT,
    `icon` VARCHAR(50),
    `sort_order` INT DEFAULT 0,
    `is_active` TINYINT(1) DEFAULT 1,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY `uk_module_key` (`module_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

۷. پکیج‌ها


CREATE TABLE `subscription_plans` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `plan_name` VARCHAR(255) NOT NULL,
    `plan_code` VARCHAR(50) NOT NULL,
    `description` TEXT,
    `icon` VARCHAR(50) DEFAULT 'fa-box',
    `color` VARCHAR(20) DEFAULT '#6366f1',
    `modules` JSON NOT NULL,
    `limits` JSON NOT NULL,
    `pricing_model` ENUM('flat','per_student','hybrid','custom') DEFAULT 'flat',
    `flat_price_monthly` DECIMAL(15,0),
    `flat_price_yearly` DECIMAL(15,0),
    `price_per_student_monthly` DECIMAL(12,0),
    `price_per_student_yearly` DECIMAL(12,0),
    `setup_fee` DECIMAL(15,0) DEFAULT 0,
    `is_active` TINYINT(1) DEFAULT 1,
    `is_featured` TINYINT(1) DEFAULT 0,
    `is_trial_plan` TINYINT(1) DEFAULT 0,
    `sort_order` INT DEFAULT 0,
    `created_by` INT UNSIGNED,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY `uk_plan_code` (`plan_code`),
    CONSTRAINT `fk_plans_created_by` FOREIGN KEY (`created_by`) REFERENCES `super_admins`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

Seed پکیج‌های اختصاصی


INSERT INTO `subscription_plans` (`plan_name`, `plan_code`, `description`, `pricing_model`, `modules`, `limits`, `is_active`, `sort_order`) VALUES
('فقط آزمون‌ساز', 'exam_only', 'دسترسی به آزمون‌ساز و بانک سوال', 'flat',
'{"exam_builder":true,"question_bank":true,"pdf_export":true,"excel_export":true,"sms":true,"counseling":false,"form_builder":false,"assignments":false,"attendance":false}',
'{"max_students":300,"max_teachers":30,"max_exams_monthly":100,"max_questions":5000,"max_sms_monthly":500,"max_storage_gb":3}', 1, 1),

('فقط مشاوره', 'counseling_only', 'دسترسی به مشاوره، فرم‌ساز و آزمون‌های استاندارد', 'flat',
'{"counseling":true,"form_builder":true,"assessment_library":true,"profile_360":true,"chat":true,"sms":true,"pdf_export":true,"exam_builder":false,"question_bank":false}',
'{"max_students":500,"max_counselors":5,"max_forms_monthly":100,"max_submissions_monthly":5000,"max_sms_monthly":1000,"max_storage_gb":5}', 1, 2);

۸. Override امکانات و محدودیت‌ها


CREATE TABLE `school_feature_overrides` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `school_id` INT UNSIGNED NOT NULL,
    `module_key` VARCHAR(100) NOT NULL,
    `override_value` ENUM('enabled','disabled') NOT NULL,
    `reason` VARCHAR(500),
    `starts_at` TIMESTAMP NULL,
    `expires_at` TIMESTAMP NULL,
    `created_by` INT UNSIGNED,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY `uk_school_module` (`school_id`, `module_key`),
    CONSTRAINT `fk_sfo_school` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_sfo_admin` FOREIGN KEY (`created_by`) REFERENCES `super_admins`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

CREATE TABLE `school_limit_overrides` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `school_id` INT UNSIGNED NOT NULL,
    `limit_key` VARCHAR(100) NOT NULL,
    `limit_value` INT NOT NULL,
    `reason` VARCHAR(500),
    `starts_at` TIMESTAMP NULL,
    `expires_at` TIMESTAMP NULL,
    `created_by` INT UNSIGNED,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY `uk_school_limit` (`school_id`, `limit_key`),
    CONSTRAINT `fk_slo_school` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_slo_admin` FOREIGN KEY (`created_by`) REFERENCES `super_admins`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

۹. قانون جداول مدرسه‌ای

تمام جداول مدرسه‌ای باید این ستون را داشته باشند:


`school_id` INT UNSIGNED NOT NULL,
INDEX `idx_school_id` (`school_id`),
CONSTRAINT `fk_TABLE_school` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE

Uniqueها باید scoped شوند:


UNIQUE KEY `uk_school_username` (`school_id`, `username`)
UNIQUE KEY `uk_school_form_slug` (`school_id`, `form_slug`)
UNIQUE KEY `uk_school_attendance` (`school_id`, `student_id`, `attendance_date`)

۱۰. پایان


SET FOREIGN_KEY_CHECKS = 1;

<a id="section-4"></a>


بخش ۳ — کاربران و ساختار آموزشی

منبع: 03_SCHOOL_DB_USERS.md

📚 سند نهایی پروژه: پلتفرم مدیریت هوشمند مدارس

بخش ۳: جداول مدرسه‌ای — کاربران و ساختار آموزشی در دیتابیس واحد


۱. اصل مهم

این بخش دیگر دیتابیس جداگانه مدرسه نیست. همه جداول داخل school_platform_db ساخته می‌شوند و با school_id به مدرسه مربوط می‌شوند.


۲. تنظیمات مدرسه


CREATE TABLE `school_settings` (
    `school_id` INT UNSIGNED NOT NULL,
    `setting_key` VARCHAR(100) NOT NULL,
    `setting_value` TEXT,
    `setting_type` ENUM('string','number','boolean','json') DEFAULT 'string',
    `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (`school_id`, `setting_key`),
    CONSTRAINT `fk_school_settings_school` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

۳. سال‌های تحصیلی


CREATE TABLE `academic_years` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `school_id` INT UNSIGNED NOT NULL,
    `year_name` VARCHAR(20) NOT NULL,
    `start_date` DATE NOT NULL,
    `end_date` DATE NOT NULL,
    `semesters` JSON,
    `is_current` TINYINT(1) DEFAULT 0,
    `is_archived` TINYINT(1) DEFAULT 0,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY `uk_school_year` (`school_id`, `year_name`),
    INDEX `idx_school_current` (`school_id`, `is_current`),
    CONSTRAINT `fk_academic_years_school` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

۴. کاربران مدرسه


CREATE TABLE `users` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `school_id` INT UNSIGNED NOT NULL,
    `username` VARCHAR(100) NOT NULL,
    `password` VARCHAR(255) NOT NULL,
    `role` ENUM('school_admin','vice_principal','counselor','teacher','parent','student') NOT NULL,
    `first_name` VARCHAR(100) NOT NULL,
    `last_name` VARCHAR(100) NOT NULL,
    `father_name` VARCHAR(100),
    `national_code` VARCHAR(10),
    `birth_date` DATE,
    `gender` ENUM('male','female'),
    `phone` VARCHAR(15) NOT NULL,
    `phone_secondary` VARCHAR(15),
    `home_phone` VARCHAR(15),
    `email` VARCHAR(255),
    `address` TEXT,
    `avatar` VARCHAR(255),
    `student_code` VARCHAR(50),
    `grade` VARCHAR(50),
    `class_name` VARCHAR(50),
    `employee_code` VARCHAR(50),
    `specialization` VARCHAR(255),
    `occupation` VARCHAR(255),
    `must_change_password` TINYINT(1) DEFAULT 0,
    `is_active` TINYINT(1) DEFAULT 1,
    `last_login_at` TIMESTAMP NULL,
    `failed_login_attempts` INT DEFAULT 0,
    `locked_until` TIMESTAMP NULL,
    `extra_data` JSON,
    `created_by` INT UNSIGNED,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY `uk_school_username` (`school_id`, `username`),
    UNIQUE KEY `uk_school_national_code` (`school_id`, `national_code`),
    UNIQUE KEY `uk_school_student_code` (`school_id`, `student_code`),
    INDEX `idx_school_role` (`school_id`, `role`),
    INDEX `idx_school_grade_class` (`school_id`, `grade`, `class_name`),
    INDEX `idx_school_phone` (`school_id`, `phone`),
    CONSTRAINT `fk_users_school` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_users_created_by` FOREIGN KEY (`created_by`) REFERENCES `users`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

۵. ارتباط والد و دانش‌آموز


CREATE TABLE `parent_student_relation` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `school_id` INT UNSIGNED NOT NULL,
    `parent_id` INT UNSIGNED NOT NULL,
    `student_id` INT UNSIGNED NOT NULL,
    `relation_type` ENUM('father','mother','guardian','other') DEFAULT 'father',
    `is_primary_contact` TINYINT(1) DEFAULT 0,
    `can_view_grades` TINYINT(1) DEFAULT 1,
    `can_view_exams` TINYINT(1) DEFAULT 1,
    `can_view_assignments` TINYINT(1) DEFAULT 1,
    `can_view_attendance` TINYINT(1) DEFAULT 1,
    `can_view_counseling` TINYINT(1) DEFAULT 1,
    `can_chat_teacher` TINYINT(1) DEFAULT 1,
    `can_chat_counselor` TINYINT(1) DEFAULT 1,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY `uk_school_parent_student` (`school_id`, `parent_id`, `student_id`),
    CONSTRAINT `fk_psr_school` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_psr_parent` FOREIGN KEY (`parent_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_psr_student` FOREIGN KEY (`student_id`) REFERENCES `users`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

۶. انتساب‌ها و ساختار آموزشی

تمام جداول زیر باید school_id داشته باشند و Uniqueها با school_id ترکیب شوند:


counselor_assignments
vice_principal_assignments
subjects
subject_chapters
chapter_topics
teacher_assignments
student_class_history
grading_periods
grade_categories
role_permissions
login_tokens
user_devices
notification_preferences

نمونه جدول دروس


CREATE TABLE `subjects` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `school_id` INT UNSIGNED NOT NULL,
    `subject_name` VARCHAR(255) NOT NULL,
    `subject_code` VARCHAR(20),
    `grade` VARCHAR(50) NOT NULL,
    `subject_type` ENUM('main','elective','workshop','extracurricular') DEFAULT 'main',
    `max_score` DECIMAL(5,2) DEFAULT 20,
    `pass_score` DECIMAL(5,2) DEFAULT 10,
    `is_active` TINYINT(1) DEFAULT 1,
    `sort_order` INT DEFAULT 0,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY `uk_school_subject_code` (`school_id`, `subject_code`),
    INDEX `idx_school_grade` (`school_id`, `grade`),
    CONSTRAINT `fk_subjects_school` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

۷. قوانین توسعه


□ هر INSERT در این جداول باید school_id داشته باشد
□ هر SELECT/UPDATE/DELETE باید با school_id محدود شود
□ قبل از ایجاد دانش‌آموز enforceLimit('max_students') اجرا شود
□ قبل از ایجاد معلم enforceLimit('max_teachers') اجرا شود
□ قبل از ایجاد مشاور enforceLimit('max_counselors') اجرا شود

<a id="section-5"></a>


بخش ۴ — مشاوره و فرم‌ساز

منبع: 04_SCHOOL_DB_COUNSELING.md

📚 سند نهایی پروژه: پلتفرم مدیریت هوشمند مدارس

بخش ۴: ماژول مشاوره و فرم‌ساز در دیتابیس واحد


۱. اصل مهم

ماژول مشاوره داخل همان دیتابیس واحد school_platform_db است و تمام جداول آن school_id دارند.

قبل از دسترسی به این ماژول باید بررسی شود:


requireModule('counseling');
requireModule('form_builder');

۲. جداول ماژول مشاوره


forms
form_sections
form_subscales
form_questions
form_question_options
score_ranges
form_submissions
submission_answers
section_scores
subscale_scores
counselor_notes
alerts
submission_drafts
assessment_requests

۳. جدول فرم‌ها


CREATE TABLE `forms` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `school_id` INT UNSIGNED NOT NULL,
    `created_by` INT UNSIGNED NOT NULL,
    `title` VARCHAR(255) NOT NULL,
    `description` TEXT,
    `instructions` TEXT,
    `form_slug` VARCHAR(100) NOT NULL,
    `qr_code_path` VARCHAR(255),
    `access_token` VARCHAR(64),
    `source_type` ENUM('custom','library','duplicate') DEFAULT 'custom',
    `library_assessment_id` INT UNSIGNED,
    `target_respondent` ENUM('parent','student','both') DEFAULT 'parent',
    `target_grades` JSON,
    `target_classes` JSON,
    `target_students` JSON,
    `start_date` DATETIME,
    `end_date` DATETIME,
    `time_limit_minutes` INT UNSIGNED,
    `max_attempts` INT UNSIGNED DEFAULT 1,
    `parent_can_see_total_score` TINYINT(1) DEFAULT 1,
    `parent_can_see_interpretation` TINYINT(1) DEFAULT 0,
    `parent_can_download_pdf` TINYINT(1) DEFAULT 1,
    `scoring_method` ENUM('sum','average','weighted','custom') DEFAULT 'sum',
    `has_subscales` TINYINT(1) DEFAULT 0,
    `status` ENUM('draft','active','paused','closed','archived') DEFAULT 'draft',
    `total_questions` INT DEFAULT 0,
    `total_submissions` INT DEFAULT 0,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY `uk_school_form_slug` (`school_id`, `form_slug`),
    INDEX `idx_school_status` (`school_id`, `status`),
    INDEX `idx_school_creator` (`school_id`, `created_by`),
    CONSTRAINT `fk_forms_school` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_forms_creator` FOREIGN KEY (`created_by`) REFERENCES `users`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

۴. بخش‌ها، سوالات و گزینه‌ها

تمام این جداول school_id دارند تا حتی در JOINهای مستقیم هم isolation حفظ شود.

نمونه سوالات فرم


CREATE TABLE `form_questions` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `school_id` INT UNSIGNED NOT NULL,
    `form_id` INT UNSIGNED NOT NULL,
    `section_id` INT UNSIGNED NOT NULL,
    `subscale_id` INT UNSIGNED,
    `question_text` TEXT NOT NULL,
    `question_type` ENUM('single_choice','multiple_choice','likert_3','likert_4','likert_5','likert_7','slider','yes_no','true_false','text_short','text_long','number','date','rating_stars') DEFAULT 'single_choice',
    `is_required` TINYINT(1) DEFAULT 1,
    `is_reverse_scored` TINYINT(1) DEFAULT 0,
    `sort_order` INT DEFAULT 0,
    INDEX `idx_school_form` (`school_id`, `form_id`),
    CONSTRAINT `fk_fq_school` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_fq_form` FOREIGN KEY (`form_id`) REFERENCES `forms`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

۵. پاسخ‌ها و نمره‌ها


CREATE TABLE `form_submissions` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `school_id` INT UNSIGNED NOT NULL,
    `form_id` INT UNSIGNED NOT NULL,
    `student_id` INT UNSIGNED NOT NULL,
    `respondent_id` INT UNSIGNED NOT NULL,
    `total_score` INT DEFAULT 0,
    `max_possible_score` INT DEFAULT 0,
    `percentage` DECIMAL(5,2) DEFAULT 0,
    `auto_severity` ENUM('normal','low','mild','moderate','high','severe','critical'),
    `auto_interpretation` TEXT,
    `status` ENUM('draft','completed','invalidated') DEFAULT 'completed',
    `started_at` TIMESTAMP NULL,
    `submitted_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `is_released` TINYINT(1) DEFAULT 0,
    `released_at` TIMESTAMP NULL,
    `released_by` INT UNSIGNED,
    INDEX `idx_school_form` (`school_id`, `form_id`),
    INDEX `idx_school_student` (`school_id`, `student_id`),
    CONSTRAINT `fk_sub_school` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_sub_form` FOREIGN KEY (`form_id`) REFERENCES `forms`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_sub_student` FOREIGN KEY (`student_id`) REFERENCES `users`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

۶. محدودیت‌های پکیج

قبل از ساخت فرم:


requireModule('form_builder');
$count = countMonthlyForms($schoolId);
enforceLimit('max_forms_monthly', $count);

قبل از ارسال پاسخ:


$count = countMonthlySubmissions($schoolId);
enforceLimit('max_submissions_monthly', $count);

۷. طراحی داشبورد مشاور

داشبورد مشاور باید از استاندارد Modern Light Aurora بدون Glassmorphism استفاده کند و شامل این کارت‌ها باشد:

<a id="section-6"></a>


بخش ۵ — آزمون‌ساز، بانک سوال، تکالیف و نمرات

منبع: 05_SCHOOL_DB_EXAMS.md

📚 سند نهایی پروژه: پلتفرم مدیریت هوشمند مدارس

بخش ۵: آزمون‌ساز، بانک سوال، تکالیف و نمرات در دیتابیس واحد


۱. اصل مهم

همه جداول این بخش داخل دیتابیس واحد هستند و school_id دارند.

ماژول‌های مرتبط:


requireModule('exam_builder');
requireModule('question_bank');

برای تکالیف و نمرات:


requireModule('assignments');
requireModule('grades');

۲. جداول این بخش


question_bank
question_bank_options
exams
exam_questions
exam_question_options
exam_submissions
exam_answers
coordinated_exams
coordinated_exam_questions
assignments
assignment_submissions
student_grades

۳. بانک سوالات


CREATE TABLE `question_bank` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `school_id` INT UNSIGNED NOT NULL,
    `teacher_id` INT UNSIGNED NOT NULL,
    `subject_id` INT UNSIGNED NOT NULL,
    `chapter_id` INT UNSIGNED,
    `topic_id` INT UNSIGNED,
    `question_text` TEXT NOT NULL,
    `question_image` VARCHAR(255),
    `question_type` ENUM('single_choice','multiple_choice','true_false','fill_blank','matching','ordering','short_answer','essay') NOT NULL,
    `difficulty` ENUM('easy','medium','hard') DEFAULT 'medium',
    `cognitive_level` ENUM('knowledge','comprehension','application','analysis','synthesis','evaluation') DEFAULT 'knowledge',
    `default_score` DECIMAL(5,2) DEFAULT 1,
    `times_used` INT DEFAULT 0,
    `is_shared` TINYINT(1) DEFAULT 0,
    `is_active` TINYINT(1) DEFAULT 1,
    `tags` JSON,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX `idx_school_teacher` (`school_id`, `teacher_id`),
    INDEX `idx_school_subject` (`school_id`, `subject_id`),
    CONSTRAINT `fk_qb_school` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_qb_teacher` FOREIGN KEY (`teacher_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_qb_subject` FOREIGN KEY (`subject_id`) REFERENCES `subjects`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

۴. آزمون‌ها


CREATE TABLE `exams` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `school_id` INT UNSIGNED NOT NULL,
    `teacher_id` INT UNSIGNED NOT NULL,
    `subject_id` INT UNSIGNED NOT NULL,
    `academic_year_id` INT UNSIGNED NOT NULL,
    `exam_title` VARCHAR(255) NOT NULL,
    `exam_description` TEXT,
    `exam_type` ENUM('quiz','midterm','final','practice','homework') NOT NULL,
    `target_grades` JSON,
    `target_classes` JSON,
    `start_datetime` DATETIME NOT NULL,
    `end_datetime` DATETIME NOT NULL,
    `duration_minutes` INT NOT NULL,
    `total_score` DECIMAL(5,2) NOT NULL,
    `negative_marking` TINYINT(1) DEFAULT 0,
    `shuffle_questions` TINYINT(1) DEFAULT 0,
    `shuffle_options` TINYINT(1) DEFAULT 0,
    `show_result_immediately` TINYINT(1) DEFAULT 0,
    `max_attempts` INT DEFAULT 1,
    `status` ENUM('draft','scheduled','active','finished','cancelled') DEFAULT 'draft',
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX `idx_school_status` (`school_id`, `status`),
    INDEX `idx_school_teacher` (`school_id`, `teacher_id`),
    INDEX `idx_school_dates` (`school_id`, `start_datetime`, `end_datetime`),
    CONSTRAINT `fk_exams_school` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_exams_teacher` FOREIGN KEY (`teacher_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_exams_subject` FOREIGN KEY (`subject_id`) REFERENCES `subjects`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_exams_year` FOREIGN KEY (`academic_year_id`) REFERENCES `academic_years`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

۵. تکالیف و نمرات

تمام جداول تکالیف و نمرات باید school_id داشته باشند:


assignments
assignment_submissions
student_grades
grading_periods
grade_categories

۶. محدودیت‌های پکیج

قبل از ساخت سوال:


requireModule('question_bank');
$count = countQuestions($schoolId);
enforceLimit('max_questions', $count);

قبل از ساخت آزمون:


requireModule('exam_builder');
$count = countMonthlyExams($schoolId);
enforceLimit('max_exams_monthly', $count);

۷. داشبوردهای مرتبط

داشبورد معلم

داشبورد معاون

هر دو داشبورد با سبک Modern Light Aurora بدون Glassmorphism طراحی شوند.

<a id="section-7"></a>


بخش ۶ — پروفایل ۳۶۰، ارتباطات و نظرسنجی

منبع: 06_SCHOOL_DB_PROFILE_COMMS.md

📚 سند نهایی پروژه: پلتفرم مدیریت هوشمند مدارس

بخش ۶: پروفایل ۳۶۰، ارتباطات، نظرسنجی و لاگ‌ها در دیتابیس واحد


۱. اصل مهم

تمام جداول این بخش داخل school_platform_db هستند و school_id دارند.


۲. جداول پروفایل ۳۶۰


attendance
behavior_records
student_health
student_talents
achievements
student_goals
student_notes

نمونه حضور و غیاب:


CREATE TABLE `attendance` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `school_id` INT UNSIGNED NOT NULL,
    `student_id` INT UNSIGNED NOT NULL,
    `academic_year_id` INT UNSIGNED NOT NULL,
    `attendance_date` DATE NOT NULL,
    `status` ENUM('present','absent_excused','absent_unexcused','late','late_excused','early_leave','sick','suspended') NOT NULL,
    `check_in_time` TIME,
    `late_minutes` INT DEFAULT 0,
    `reason` TEXT,
    `recorded_by` INT UNSIGNED NOT NULL,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY `uk_school_attendance` (`school_id`, `student_id`, `attendance_date`),
    INDEX `idx_school_date` (`school_id`, `attendance_date`),
    CONSTRAINT `fk_att_school` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_att_student` FOREIGN KEY (`student_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_att_year` FOREIGN KEY (`academic_year_id`) REFERENCES `academic_years`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_att_recorder` FOREIGN KEY (`recorded_by`) REFERENCES `users`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

۳. جداول ارتباطات


messages
announcements
notifications
sms_logs

نمونه پیام‌ها:


CREATE TABLE `messages` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `school_id` INT UNSIGNED NOT NULL,
    `sender_id` INT UNSIGNED NOT NULL,
    `receiver_id` INT UNSIGNED NOT NULL,
    `subject_id` INT UNSIGNED,
    `student_id` INT UNSIGNED,
    `message_text` TEXT NOT NULL,
    `attachment_path` VARCHAR(255),
    `is_read` TINYINT(1) DEFAULT 0,
    `read_at` TIMESTAMP NULL,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX `idx_school_conversation` (`school_id`, `sender_id`, `receiver_id`),
    INDEX `idx_school_unread` (`school_id`, `receiver_id`, `is_read`),
    CONSTRAINT `fk_msg_school` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_msg_sender` FOREIGN KEY (`sender_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_msg_receiver` FOREIGN KEY (`receiver_id`) REFERENCES `users`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

۴. جداول نظرسنجی


surveys
survey_dimensions
survey_questions
survey_responses
survey_answers

قبل از دسترسی:


requireModule('survey_360');

۵. لاگ فعالیت مدرسه


CREATE TABLE `activity_logs` (
    `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `school_id` INT UNSIGNED NOT NULL,
    `user_id` INT UNSIGNED,
    `user_role` VARCHAR(50),
    `action` VARCHAR(100) NOT NULL,
    `entity_type` VARCHAR(50),
    `entity_id` INT UNSIGNED,
    `details` JSON,
    `ip_address` VARCHAR(45),
    `user_agent` TEXT,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX `idx_school_created` (`school_id`, `created_at`),
    INDEX `idx_school_user` (`school_id`, `user_id`),
    CONSTRAINT `fk_activity_school` FOREIGN KEY (`school_id`) REFERENCES `schools`(`id`) ON DELETE CASCADE,
    CONSTRAINT `fk_activity_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_persian_ci;

۶. داشبوردهای والد و دانش‌آموز

والدین

دانش‌آموز

طراحی هر دو داشبورد باید solid-card، مدرن و Aurora روشن باشد، بدون Glassmorphism.

<a id="section-8"></a>


بخش ۷ — کدهای پایه PHP

منبع: 07_PHP_CORE_CODE.md

📚 سند نهایی پروژه: پلتفرم مدیریت هوشمند مدارس

بخش ۷: کدهای پایه PHP برای دیتابیس واحد


۱. فایل‌های اصلی


config/database.php
includes/security.php
includes/functions.php
includes/auth.php
includes/permissions.php
includes/entitlements.php
includes/school_provisioner.php

حذف شده:


config/school_connection.php
SchoolInstaller با ساخت دیتابیس

۲. اتصال دیتابیس واحد


<?php
// config/database.php

define('DB_HOST', 'localhost');
define('DB_PORT', 3306);
define('DB_NAME', 'school_platform_db');
define('DB_USER', 'root');
define('DB_PASS', '');
define('DB_CHARSET', 'utf8mb4');

function db(): PDO {
    static $pdo = null;
    if ($pdo === null) {
        $dsn = sprintf('mysql:host=%s;port=%d;dbname=%s;charset=%s', DB_HOST, DB_PORT, DB_NAME, DB_CHARSET);
        $pdo = new PDO($dsn, DB_USER, DB_PASS, [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES => false,
            PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4 COLLATE utf8mb4_persian_ci",
        ]);
    }
    return $pdo;
}

۳. احراز هویت سوپرادمین مستقل


function loginSuperAdmin(string $username, string $password): array {
    $pdo = db();
    $stmt = $pdo->prepare("SELECT * FROM super_admins WHERE (username = ? OR email = ?) AND is_active = 1 LIMIT 1");
    $stmt->execute([$username, $username]);
    $admin = $stmt->fetch();

    if (!$admin || !password_verify($password, $admin['password'])) {
        return ['success' => false, 'message' => 'نام کاربری یا رمز عبور اشتباه است'];
    }

    session_regenerate_id(true);
    $_SESSION['admin_id'] = $admin['id'];
    $_SESSION['admin_role'] = $admin['role'];
    $_SESSION['admin_name'] = trim($admin['first_name'] . ' ' . $admin['last_name']);
    $_SESSION['is_super_admin'] = true;
    $_SESSION['logged_in'] = true;

    $pdo->prepare("UPDATE super_admins SET last_login_at = NOW() WHERE id = ?")->execute([$admin['id']]);

    return ['success' => true, 'redirect' => '/superadmin/dashboard'];
}

۴. ورود کاربران مدرسه


function loginSchoolUser(string $schoolCode, string $username, string $password): array {
    $pdo = db();

    $stmt = $pdo->prepare("SELECT id, school_code, school_name, status, current_plan_id FROM schools WHERE (school_code = ? OR subdomain = ?) AND status != 'deleted' LIMIT 1");
    $stmt->execute([$schoolCode, $schoolCode]);
    $school = $stmt->fetch();

    if (!$school) return ['success' => false, 'message' => 'مدرسه یافت نشد'];
    if ($school['status'] !== 'active') return ['success' => false, 'message' => 'مدرسه فعال نیست'];

    $stmt = $pdo->prepare("SELECT * FROM users WHERE school_id = ? AND (username = ? OR phone = ? OR national_code = ?) LIMIT 1");
    $stmt->execute([$school['id'], $username, $username, $username]);
    $user = $stmt->fetch();

    if (!$user || !password_verify($password, $user['password'])) {
        return ['success' => false, 'message' => 'نام کاربری یا رمز عبور اشتباه است'];
    }

    if (!$user['is_active']) return ['success' => false, 'message' => 'حساب کاربری غیرفعال است'];

    session_regenerate_id(true);
    $_SESSION['user_id'] = $user['id'];
    $_SESSION['school_id'] = $school['id'];
    $_SESSION['school_code'] = $school['school_code'];
    $_SESSION['school_name'] = $school['school_name'];
    $_SESSION['role'] = $user['role'];
    $_SESSION['full_name'] = trim($user['first_name'] . ' ' . $user['last_name']);
    $_SESSION['logged_in'] = true;

    $pdo->prepare("UPDATE users SET last_login_at = NOW() WHERE id = ? AND school_id = ?")->execute([$user['id'], $school['id']]);
    return ['success' => true, 'redirect' => getDashboardUrl($user['role'])];
}

۵. کنترل ماژول‌ها و محدودیت‌ها


function currentSchoolId(): ?int {
    return $_SESSION['school_id'] ?? null;
}

function hasModule(string $moduleKey, ?int $schoolId = null): bool {
    $schoolId = $schoolId ?? currentSchoolId();
    if (!$schoolId) return false;
    $pdo = db();

    $stmt = $pdo->prepare("SELECT override_value FROM school_feature_overrides WHERE school_id = ? AND module_key = ? AND (starts_at IS NULL OR starts_at <= NOW()) AND (expires_at IS NULL OR expires_at >= NOW())");
    $stmt->execute([$schoolId, $moduleKey]);
    $override = $stmt->fetchColumn();
    if ($override === 'enabled') return true;
    if ($override === 'disabled') return false;

    $stmt = $pdo->prepare("SELECT p.modules FROM schools s JOIN subscription_plans p ON p.id = s.current_plan_id WHERE s.id = ? LIMIT 1");
    $stmt->execute([$schoolId]);
    $modules = json_decode($stmt->fetchColumn() ?: '{}', true) ?: [];
    return !empty($modules[$moduleKey]);
}

function requireModule(string $moduleKey): void {
    if (!hasModule($moduleKey)) {
        http_response_code(403);
        include __DIR__ . '/../views/errors/module_disabled.php';
        exit;
    }
}

function getSchoolLimit(string $limitKey, ?int $schoolId = null): int {
    $schoolId = $schoolId ?? currentSchoolId();
    if (!$schoolId) return 0;
    $pdo = db();

    $stmt = $pdo->prepare("SELECT limit_value FROM school_limit_overrides WHERE school_id = ? AND limit_key = ? AND (starts_at IS NULL OR starts_at <= NOW()) AND (expires_at IS NULL OR expires_at >= NOW())");
    $stmt->execute([$schoolId, $limitKey]);
    $override = $stmt->fetchColumn();
    if ($override !== false) return (int) $override;

    $stmt = $pdo->prepare("SELECT p.limits FROM schools s JOIN subscription_plans p ON p.id = s.current_plan_id WHERE s.id = ? LIMIT 1");
    $stmt->execute([$schoolId]);
    $limits = json_decode($stmt->fetchColumn() ?: '{}', true) ?: [];
    return (int) ($limits[$limitKey] ?? 0);
}

function enforceLimit(string $limitKey, int $currentCount): void {
    $limit = getSchoolLimit($limitKey);
    if ($limit > 0 && $currentCount >= $limit) {
        http_response_code(403);
        die('محدودیت مجاز پکیج برای این بخش تکمیل شده است.');
    }
}

۶. ساخت مدرسه بدون ساخت دیتابیس


class SchoolProvisioner {
    private PDO $pdo;

    public function __construct() {
        $this->pdo = db();
    }

    public function createSchool(array $data): array {
        try {
            $this->pdo->beginTransaction();
            $schoolCode = substr(md5(uniqid(mt_rand(), true)), 0, 8);

            $stmt = $this->pdo->prepare("INSERT INTO schools (school_code, school_name, school_type, city, province, phone, email, current_plan_id, status, created_by, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'active', ?, NOW())");
            $stmt->execute([
                $schoolCode,
                $data['school_name'],
                $data['school_type'] ?? 'all',
                $data['city'] ?? null,
                $data['province'] ?? null,
                $data['phone'] ?? null,
                $data['email'] ?? null,
                $data['plan_id'] ?? null,
                $_SESSION['admin_id'] ?? null,
            ]);
            $schoolId = (int) $this->pdo->lastInsertId();

            $stmt = $this->pdo->prepare("INSERT INTO users (school_id, username, password, role, first_name, last_name, phone, email, is_active, created_at) VALUES (?, ?, ?, 'school_admin', ?, ?, ?, ?, 1, NOW())");
            $stmt->execute([
                $schoolId,
                $data['admin_username'],
                password_hash($data['admin_password'], PASSWORD_BCRYPT),
                $data['admin_first_name'] ?? 'مدیر',
                $data['admin_last_name'] ?? 'مدرسه',
                $data['admin_phone'],
                $data['admin_email'] ?? null,
            ]);

            $this->pdo->commit();
            return ['success' => true, 'school_id' => $schoolId, 'school_code' => $schoolCode];
        } catch (Exception $e) {
            $this->pdo->rollBack();
            return ['success' => false, 'message' => $e->getMessage()];
        }
    }
}

۷. خروجی CSS Theme از تنظیمات سوپرادمین


function renderThemeVariables(): void {
    $settings = getPublicThemeSettings();
    echo '<style>:root{';
    echo '--color-primary:' . e($settings['theme_primary_color'] ?? '#2563eb') . ';';
    echo '--color-secondary:' . e($settings['theme_secondary_color'] ?? '#7c3aed') . ';';
    echo '--dashboard-bg:' . e($settings['dashboard_bg_color'] ?? '#f8fafc') . ';';
    echo '--aurora-1:' . e($settings['aurora_color_1'] ?? '#99f6e4') . ';';
    echo '--aurora-2:' . e($settings['aurora_color_2'] ?? '#fed7aa') . ';';
    echo '--card-bg:' . e($settings['card_bg_color'] ?? '#ffffff') . ';';
    echo '--card-border:' . e($settings['card_border_color'] ?? '#e2e8f0') . ';';
    echo '}</style>';
}

<a id="section-9"></a>


بخش ۸ — فازبندی، Cron و چک‌لیست‌ها

منبع: 08_PHASES_CRON_CHECKLISTS.md

📚 سند نهایی پروژه: پلتفرم مدیریت هوشمند مدارس

بخش ۸: فازبندی اجرایی اصلاح‌شده، Cron و چک‌لیست‌ها


۱. پرامپت مادر اصلاح‌شده


شما مسئول توسعه پلتفرم مدیریت هوشمند مدارس هستید.
معماری پروژه Database-per-Tenant نیست.
پروژه فقط یک دیتابیس واحد به نام school_platform_db دارد.
همه جداول مدرسه‌ای باید school_id داشته باشند.

داشبورد سوپرادمین باید کاملاً مستقل از پنل مدیر مدرسه باشد.
سوپرادمین می‌تواند مدرسه، پکیج، امکانات فعال، محدودیت دانش‌آموزان و سایر سقف‌ها را تعریف کند.

قوانین اجباری:
1. هیچ دیتابیس جداگانه‌ای برای مدرسه نساز.
2. هیچ SchoolConnection داینامیک پیاده‌سازی نکن.
3. همه داده‌های مدرسه‌ای را با school_id جدا کن.
4. پنل سوپرادمین مستقل باشد.
5. قبل از ورود به هر ماژول، requireModule اجرا شود.
6. قبل از ایجاد رکوردهای محدود، enforceLimit اجرا شود.
7. داشبوردها Modern Light Aurora باشند ولی Glassmorphism نداشته باشند.
8. رنگ‌های داشبورد از پنل سوپرادمین قابل تنظیم باشند.
9. همه کوئری‌ها PDO Prepared Statement باشند.
10. همه فرم‌ها CSRF داشته باشند.

۲. فازهای اصلی

فاز ۱: پایه پروژه و دیتابیس واحد


کارها:
  - ساخت ساختار پوشه‌ها
  - ساخت config/database.php
  - ساخت database/schema.sql برای کل دیتابیس واحد
  - ساخت database/seed.sql
  - ساخت includes/security.php
  - ساخت includes/functions.php
  - ساخت includes/entitlements.php
  - ساخت router

حذف از برنامه:
  - config/school_connection.php
  - school_schema.sql جداگانه
  - SchoolInstaller ساخت دیتابیس

معیار تأیید:
  □ دیتابیس واحد ایجاد شود
  □ سوپرادمین وارد شود
  □ هیچ DB جدیدی برای مدرسه ساخته نشود

فاز ۲: احراز هویت مستقل


کارها:
  - loginSuperAdmin
  - loginSchoolUser با school_code
  - سشن جدا برای سوپرادمین و مدرسه
  - requireSuperAdmin
  - requireLogin
  - requireRole

معیار تأیید:
  □ سوپرادمین وارد /superadmin/dashboard شود
  □ مدیر مدرسه وارد /school/dashboard شود

فاز ۳: پنل سوپرادمین و تعریف مدرسه


کارها:
  - داشبورد سوپرادمین مستقل
  - CRUD مدرسه
  - SchoolProvisioner
  - ساخت ادمین اولیه مدرسه
  - انتخاب پکیج اولیه
  - تنظیم محدودیت‌ها
  - فعال/تعلیق/حذف مدرسه
  - Impersonate با Audit Log

معیار تأیید:
  □ مدرسه در جدول schools ثبت شود
  □ ادمین مدرسه در users با school_id ثبت شود
  □ دیتابیس جدید ساخته نشود

فاز ۴: پکیج‌ها، ماژول‌ها و محدودیت‌ها


کارها:
  - module_catalog
  - subscription_plans
  - school_feature_overrides
  - school_limit_overrides
  - پنل ساخت پکیج
  - سوئیچ ماژول‌ها
  - limits
  - hasModule / requireModule
  - getSchoolLimit / enforceLimit

معیار تأیید:
  □ پکیج فقط آزمون‌ساز ساخته شود
  □ پکیج فقط مشاوره ساخته شود
  □ مدرسه فقط امکانات مجاز را ببیند

فاز ۵: طراحی Layout و داشبوردها


کارها:
  - طراحی layout مشترک داشبوردها
  - داشبورد سوپرادمین
  - داشبورد مدیر مدرسه
  - داشبورد مشاور
  - داشبورد معلم
  - داشبورد معاون
  - داشبورد والد
  - داشبورد دانش‌آموز
  - تنظیم رنگ‌ها از پنل سوپرادمین
  - تولید CSS Variables

مهم:
  - طراحی Modern Light Aurora
  - بدون Glassmorphism
  - بدون backdrop-blur روی کارت‌ها
  - کارت‌ها solid و خوانا باشند

فازهای بعدی


۶. پنل مدیر مدرسه و مدیریت کاربران
۷. سال تحصیلی و ساختار آموزشی
۸. فرم‌ساز مشاوره
۹. پاسخ‌دهی و تفسیر فرم‌ها
۱۰. بانک سوالات
۱۱. آزمون‌ساز معلم
۱۲. شرکت دانش‌آموز در آزمون
۱۳. تکالیف و نمرات
۱۴. پنل معاون و آزمون هماهنگ
۱۵. حضور و غیاب
۱۶. رفتار و انضباط
۱۷. پروفایل ۳۶۰
۱۸. نظرسنجی ۳۶۰
۱۹. چت و اعلان‌ها
۲۰. گزارش‌گیری PDF/Excel
۲۱. پرداخت‌ها و فاکتورها
۲۲. تیکت پشتیبانی
۲۳. API و Webhooks
۲۴. PWA
۲۵. Backup، Migration و بهینه‌سازی

🎨 استاندارد طراحی داشبوردها — Modern Light Aurora بدون Glassmorphism

این استاندارد برای همه داشبوردها اجباری است: سوپرادمین، مدیر مدرسه، معاون، مشاور، معلم، والدین و دانش‌آموز.

اصل طراحی

داشبوردها باید مدرن، روشن، نرم، premium و SaaS-like باشند. پس‌زمینه می‌تواند حالت Light Aurora داشته باشد: blobهای نرم و محو با رنگ‌های پاستلی مثل mint، peach، pink، lavender و electric blue. اما کارت‌ها و پنل‌ها نباید شیشه‌ای باشند.

ممنوع

مجاز و مطلوب

تنظیم رنگ‌ها از پنل سوپرادمین

تمام رنگ‌ها باید از پنل سوپرادمین قابل تنظیم باشند و در قالب CSS Variables خروجی داده شوند. رنگ‌ها نباید داخل کامپوننت‌ها hard-code شوند.

کلیدهای پیشنهادی تنظیمات:

کلیدتوضیح
theme_primary_colorرنگ اصلی
theme_secondary_colorرنگ دوم
theme_accent_colorرنگ accent
theme_success_colorموفقیت
theme_warning_colorهشدار
theme_danger_colorخطا
theme_info_colorاطلاع‌رسانی
dashboard_bg_colorپس‌زمینه پایه داشبورد
aurora_color_1 تا aurora_color_4رنگ‌های پس‌زمینه Aurora
card_bg_colorرنگ کارت‌ها
card_border_colorborder کارت‌ها
sidebar_bg_colorرنگ sidebar
active_menu_gradient_start/endگرادینت آیتم فعال
chart_gradient_start/endگرادینت نمودارها
button_gradient_start/endگرادینت دکمه‌ها

نمونه CSS Variables:


:root {
  --color-primary: #2563eb;
  --color-secondary: #7c3aed;
  --color-accent: #ec4899;
  --color-success: #10b981;
  --color-warning: #f59e0b;
  --color-danger: #ef4444;
  --color-info: #06b6d4;

  --dashboard-bg: #f8fafc;
  --aurora-1: #99f6e4;
  --aurora-2: #fed7aa;
  --aurora-3: #f0abfc;
  --aurora-4: #93c5fd;

  --card-bg: #ffffff;
  --card-border: #e2e8f0;
  --text-main: #0f172a;
  --text-muted: #64748b;

  --chart-gradient-start: #2563eb;
  --chart-gradient-end: #ec4899;
  --button-gradient-start: #2563eb;
  --button-gradient-end: #7c3aed;
  --active-menu-gradient-start: #2563eb;
  --active-menu-gradient-end: #ec4899;
}

.dashboard-card {
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: 24px;
  box-shadow: 0 18px 45px rgba(15, 23, 42, 0.08);
}

۳. چک‌لیست توسعه


□ هیچ DB جداگانه‌ای ساخته نشده
□ همه جداول مدرسه‌ای school_id دارند
□ همه کوئری‌های مدرسه‌ای school_id دارند
□ Uniqueها با school_id ترکیب شده‌اند
□ سوپرادمین مستقل است
□ requireModule اجرا شده
□ enforceLimit اجرا شده
□ رنگ داشبورد از تنظیمات خوانده می‌شود
□ کارت‌های داشبورد solid هستند و glass نیستند
□ CSRF فعال است
□ XSS کنترل شده است
□ PDO Prepared Statement استفاده شده

۴. Cron Jobs

Cronها در معماری دیتابیس واحد ساده‌تر هستند و نیازی به loop روی دیتابیس‌های جداگانه نیست.


هر دقیقه: پردازش صف پیامک، اعلان و webhook
هر ساعت: محاسبه آمار مدارس با GROUP BY school_id
روزانه: بررسی انقضای اشتراک‌ها، محاسبه Health Score، پاکسازی draftها
هفتگی: گزارش مدیریتی، بررسی فضای ذخیره‌سازی
ماهانه: MRR/ARR، آرشیو لاگ‌ها، حذف مدارس deleted

⚙️ تأکید اجباری: نسخه cPanel-Ready و مستندسازی پایان هر فاز

این بخش باید در پرامپت اصلی پروژه، پرامپت مادر فازها و دستور اجرای هر فاز به‌صورت صریح رعایت شود.


۱. نسخه اجرایی فقط cPanel-Ready باشد

پروژه فقط باید با پشته فنی ساده، قابل نصب روی cPanel و بدون ابزارهای build توسعه داده شود.

مشخصات فنی اجباری


نسخه cPanel-Ready (PHP + Vanilla JS + MySQL)

Frontend:
- PHP + HTML
- Vanilla JavaScript خالص
- بدون React
- بدون Vue
- بدون Angular
- بدون Alpine
- بدون TypeScript
- بدون npm / yarn
- بدون Vite / Webpack / Parcel
- بدون Build Process

Styling:
- Tailwind CSS فقط از CDN
- بدون build Tailwind
- بدون PostCSS
- بدون Sass/Less اجباری

Icons:
- Font Awesome فقط از CDN

Charts:
- Chart.js فقط از CDN

Confetti:
- canvas-confetti فقط از CDN

QR Code:
- qrcodejs فقط از CDN

Backend:
- PHP 7.4+
- Vanilla PHP
- بدون Laravel
- بدون Symfony
- بدون CodeIgniter
- بدون Framework سنگین

Database:
- MySQL 5.7+
- PDO
- Prepared Statements اجباری

Authentication:
- PHP Session
- بدون JWT برای ورود پنل‌ها

API:
- PHP فایل‌های مجزا
- بدون Router پیچیده
- بدون Node.js
- بدون Express
- بدون REST Framework سنگین

قانون مهم پیاده‌سازی

هر صفحه یا API باید با فایل PHP ساده قابل اجرا باشد. مسیرها می‌توانند با .htaccess مرتب شوند، اما نباید وابسته به Router پیچیده، Composer سنگین یا Build Process باشند.

نمونه ساختار API مجاز:


api/v1/auth/login.php
api/v1/schools/create.php
api/v1/students/list.php
api/v1/exams/create.php
api/v1/forms/submit.php
api/v1/reports/export.php

نمونه ساختار Frontend مجاز:


views/superadmin/dashboard.php
views/school/dashboard.php
views/teacher/exam_builder.php
views/counselor/form_builder.php

۲. موارد ممنوع در کل پروژه


ممنوع:
- React / Vue / Angular / Svelte
- Node.js / Express / NestJS
- Laravel / Symfony / CodeIgniter
- JWT برای احراز هویت پنل‌ها
- npm / yarn / pnpm
- Vite / Webpack / Parcel
- TypeScript
- Build Process
- Tailwind Build
- API Router پیچیده
- Docker به‌عنوان نیاز اجباری

۳. قانون اجباری بعد از پایان هر فاز

بعد از پایان هر فاز، توسعه‌دهنده یا هوش مصنوعی باید یک فایل Markdown مخصوص همان فاز بسازد تا وضعیت پروژه ذخیره شود و در ادامه پروژه مجبور نباشیم از اول کارها را بررسی یا تکرار کنیم.

مسیر پیشنهادی:


project_docs/phases/
├── PHASE_01_STATUS.md
├── PHASE_02_STATUS.md
├── PHASE_03_STATUS.md
└── ...

نام فایل باید مطابق شماره فاز باشد:


PHASE_XX_STATUS.md

مثال:


project_docs/phases/PHASE_05_STATUS.md

۴. محتوای اجباری فایل MD پایان هر فاز

هر فایل وضعیت فاز باید شامل این بخش‌ها باشد:


# گزارش وضعیت فاز X

## ۱. عنوان فاز
نام فاز و هدف اصلی آن.

## ۲. تاریخ انجام
تاریخ و ساعت انجام فاز.

## ۳. کارهای انجام‌شده
- مورد ۱
- مورد ۲
- مورد ۳

## ۴. فایل‌های ساخته‌شده
- path/to/file.php
- path/to/file.js
- path/to/file.css

## ۵. فایل‌های ویرایش‌شده
- path/to/edited-file.php

## ۶. جداول دیتابیس مرتبط
- جدول ۱
- جدول ۲

## ۷. APIهای ساخته‌شده
- api/v1/example/create.php
- api/v1/example/list.php

## ۸. صفحات ساخته‌شده
- views/example/page.php

## ۹. نکات امنیتی رعایت‌شده
- CSRF
- PDO Prepared Statements
- XSS escape
- Session check
- Role check

## ۱۰. تست‌های انجام‌شده
- تست ورود
- تست ثبت اطلاعات
- تست محدودیت پکیج

## ۱۱. کارهای باقی‌مانده
- مورد باقی‌مانده ۱
- مورد باقی‌مانده ۲

## ۱۲. خطاها یا ریسک‌های شناخته‌شده
- مورد ۱

## ۱۳. وابستگی به فازهای بعدی
- فاز X
- فاز Y

## ۱۴. دستور ادامه برای فاز بعد
یک پرامپت کوتاه برای ادامه کار از همین نقطه.

۵. قانون جلوگیری از دوباره‌کاری

قبل از شروع هر فاز جدید، ابتدا باید فایل‌های زیر خوانده شوند:


project_docs/phases/PHASE_01_STATUS.md
project_docs/phases/PHASE_02_STATUS.md
...

سپس فقط کارهای باقی‌مانده و فاز جدید انجام شود. هیچ فاز نباید از ابتدا بازنویسی شود مگر کاربر صراحتاً درخواست کند.


۶. چک‌لیست پایان هر فاز


□ فاز طبق معماری دیتابیس واحد انجام شد
□ هیچ ابزار غیر cPanel-Ready استفاده نشد
□ هیچ Framework ممنوع استفاده نشد
□ هیچ Build Process اضافه نشد
□ PHP Session برای احراز هویت استفاده شد
□ PDO Prepared Statements رعایت شد
□ CSRF در فرم‌ها رعایت شد
□ XSS Escape رعایت شد
□ فایل PHASE_XX_STATUS.md ساخته شد
□ کارهای انجام‌شده نوشته شد
□ کارهای باقی‌مانده نوشته شد
□ فایل‌های ساخته/ویرایش‌شده ثبت شد
□ دستور ادامه فاز بعد نوشته شد
کل محتوا کپی شد ✅