# برنامه جامع پروژه «دانشیار من»

> وضعیت فایل: سند مادر پروژه  
> زبان محصول: فارسی و راست‌به‌چپ  
> دامنه اصلی پیشنهادی: `mydaneshyar.ir`  
> دامنه پنل پیشنهادی: `dashboard.mydaneshyar.ir`  
> هدف: ساخت اتوماسیون هوشمند مدارس برای فروش اشتراک به مدارس، مدیریت کامل مدرسه، ارتباط مدرسه با دانش‌آموز، امتحان آنلاین، نمره‌دهی، کارنامه، برنامه هفتگی، پیام‌رسانی، گزارش‌گیری و کنترل کامل توسط Super Admin.

---

## 1. اصل‌های مهم پروژه

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

قوانین اصلی:

- کل پروژه در همین فولدر `Daneshyar` ساخته می‌شود.
- Backend پروژه با Laravel ساخته می‌شود.
- Frontend اصلی با React + TypeScript ساخته می‌شود.
- اتصال Laravel و React با Inertia.js انجام می‌شود.
- Build frontend با Vite انجام می‌شود.
- صفحه‌ها باید component-based، تمیز و جدا باشند؛ هیچ چیز نباید در یک فایل بزرگ ریخته شود.
- فایل‌های static مثل تصاویر، فونت‌ها، آیکون‌ها و فایل‌های PWA داخل `public/assets` قرار می‌گیرند.
- فایل‌های React/TypeScript داخل `resources/js` قرار می‌گیرند.
- فایل‌های CSS اصلی داخل `resources/css` قرار می‌گیرند و توسط Vite build می‌شوند.
- خروجی build داخل `public/build` ساخته می‌شود، اما URL کاربران همچنان تمیز می‌ماند مثل `/dashboard` و `/exams`.
- دیتابیس داخل فولدر `database` مستند و ساخته می‌شود.
- مستندات، ایده‌ها، آرشیوها و فایل‌های کمکی داخل `documentation` قرار می‌گیرند.
- پروژه باید responsive و mobile-first باشد.
- پروژه باید PWA داشته باشد تا روی موبایل مثل web application نصب شود.
- طراحی باید فارسی، RTL، روشن، تمیز، مدرن و مناسب مدرسه باشد.
- از emoji در UI استفاده نمی‌کنیم. برای آیکون‌ها از Bootstrap Icons یا آیکون‌های SVG اختصاصی استفاده می‌کنیم.
- همه تغییرات مهم باید log داشته باشند؛ مخصوصا تغییر نمره، تغییر نقش، تغییر دسترسی، تغییر اطلاعات مدرسه و reset password.
- همه تاریخ‌ها در UI باید شمسی باشند.
- تاریخ مرجع در داده‌ها و UI باید Jalali/Persian باشد؛ مثال سال جاری پروژه: `1405`.
- همه شماره تلفن‌ها باید اعتبارسنجی ایران داشته باشند.
- سیستم باید multi-school باشد؛ یعنی هر مدرسه داده‌های خودش را ببیند و از مدارس دیگر جدا باشد.
- Super Admin همه چیز را می‌بیند و مدیریت می‌کند.

---

## 1.1 تصمیم فنی اصلی پروژه

تصمیم فعلی:

```text
Backend: Laravel
Frontend: React
Language: TypeScript
Bridge: Inertia.js
Build Tool: Vite
Views: React pages + Laravel root Blade shell
Database: MySQL
PWA: فعال
Responsive: اجباری
Webserver: Apache
```

### چرا Laravel؟

این پروژه فقط چند صفحه ساده نیست. سیستم مدرسه نیاز به login، نقش‌ها، permission، امنیت، فایل، گزارش، دیتابیس، reset password، session، logs، API و multi-school دارد. Laravel این پایه‌ها را تمیز و استاندارد می‌دهد و باعث می‌شود پروژه بعدا شلوغ و خطرناک نشود.

### Inertia چیست؟

Inertia.js پل بین Laravel و React است. یعنی لازم نیست از اول یک API سنگین و جدا برای همه صفحه‌ها بسازیم. Laravel route، auth، permission و داده‌ها را کنترل می‌کند و React صفحه را نمایش می‌دهد.

مزیت‌ها:

- URLها عادی و تمیز می‌مانند.
- Laravel همچنان backend اصلی است.
- React برای dashboard و UI قوی استفاده می‌شود.
- TypeScript باعث امن‌تر و قابل نگهداری‌تر شدن frontend می‌شود.
- نیاز به ساخت SPA جداگانه و auth پیچیده جدا نداریم.

مثال مسیر کاربر:

```text
کاربر باز می‌کند: /dashboard
Laravel route را بررسی می‌کند.
Laravel permission و school scope را چک می‌کند.
Inertia داده را به React page می‌دهد.
React داشبورد را نمایش می‌دهد.
```

### Blade هنوز کجاست؟

در این معماری Blade فقط shell اصلی Laravel را نگه می‌دارد، مثل:

```text
resources/views/app.blade.php
```

این فایل root است و React داخل آن mount می‌شود. یعنی Blade حذف نمی‌شود، اما صفحه‌های واقعی dashboard و landing بیشتر با React/TypeScript ساخته می‌شوند.

مثال ساده:

```blade
@inertia
```

این یعنی Laravel صفحه React مربوطه را داخل app render می‌کند.

### چرا Vite؟

چون React + TypeScript برای browser باید compile شود. Browser مستقیم فایل `.tsx` را اجرا نمی‌کند.

کار Vite:

- compile کردن React و TypeScript
- minify کردن فایل‌های production
- ساخت فایل‌های cache-busted
- code splitting
- hot reload در development
- ساخت خروجی قابل deploy داخل `public/build`

Development:

```bash
npm run dev
```

Production:

```bash
npm run build
```

نکته مهم:

- کاربر هیچ‌وقت فایل‌هایی مثل `dashboard-a83kd.js` را باز نمی‌کند.
- کاربر همچنان `/dashboard` را باز می‌کند.
- فایل hashدار فقط asset داخلی browser است.

### چرا React + TypeScript؟

چون این پروژه dashboard-heavy است و بخش‌های زیادی interactive هستند:

- exam builder
- schedule builder
- grade table
- permission editor
- chat
- notifications
- PWA install flow
- charts
- online class UI
- file upload manager

TypeScript کمک می‌کند خطاهای frontend زودتر دیده شوند و componentها قابل نگهداری‌تر باشند.

تصمیم فعلی:

- [x] Laravel برای backend
- [x] Inertia.js برای اتصال backend و frontend
- [x] React برای frontend اصلی
- [x] TypeScript برای frontend
- [x] Vite برای build
- [x] Blade فقط برای root shell و fallbackهای لازم
- [x] Apache برای webserver production
- [x] PWA برای نصب روی گوشی

### 1.2 تصمیم‌های فنی قفل‌شده و تصمیم‌های موکول‌شده

تصمیم‌های قفل‌شده:

- [x] Backend: Laravel
- [x] Frontend: React + TypeScript
- [x] Bridge: Inertia.js
- [x] Build tool: Vite
- [x] Database: MySQL/MariaDB
- [x] Webserver: Apache
- [x] PWA: فعال
- [x] Theme: Spring Mint
- [x] فقط اطلاعات تماس پدر/مادر داخل پرونده دانش‌آموز ثبت می‌شود.

تصمیم‌های موکول‌شده به زمان پیاده‌سازی ماژول:

- [x] SMS Provider بعدا انتخاب می‌شود.
- [x] Payment Gateway بعدا انتخاب می‌شود.
- [x] نسخه دقیق Laravel/PHP/Node هنگام scaffold نهایی با توجه به محیط توسعه و سرور قفل می‌شود.
- [x] مستندات providerها و API keyها فقط وقتی همان ماژول را می‌سازیم از کارفرما گرفته می‌شود.

وقتی به SMS رسیدیم باید از کارفرما گرفته شود:

- نام provider پیامک
- مستندات API
- API key / username / password
- شماره خط یا sender number
- قیمت هر پیامک
- وضعیت delivery report
- محدودیت ارسال
- متن‌های مجاز/غیرمجاز

وقتی به Payment رسیدیم باید از کارفرما گرفته شود:

- نام درگاه پرداخت
- مستندات API
- merchant id / api key
- callback URL
- قوانین تسویه
- حالت sandbox/test
- کارمزد
- وضعیت فاکتور رسمی

قانون:

```text
تا وقتی provider واقعی انتخاب نشده، کد باید با interface/service نوشته شود تا بعدا provider عوض شود و کل سیستم نشکند.
```

### 1.3 مسیر packageها برای پیاده‌سازی

نسخه دقیق packageها هنگام scaffold با Composer/NPM قفل می‌شود، اما مسیر انتخابی این است:

- Auth/Inertia starter: Laravel Breeze با React + TypeScript + Inertia یا setup دستی معادل
- Permission: package استاندارد مثل `spatie/laravel-permission` یا ساختار custom اگر module entitlement پیچیده‌تر شد
- API tokens آینده: Laravel Sanctum برای API داخلی/mobile آینده
- Excel/CSV: package سازگار Laravel برای import/export مثل Laravel Excel
- PDF: package سازگار Laravel برای خروجی کارنامه/گزارش
- Queue: در ابتدا database queue، بعدا Redis اگر پروژه سنگین شد
- Charts: library React سبک و تمیز برای dashboard charts
- Date: service اختصاصی Jalali/Persian Date، با package معتبر اگر لازم شد

قانون:

```text
هیچ package نباید معماری module/permission/school scope را بشکند.
اگر package ساده جواب نداد، service داخلی خودمان اولویت دارد.
```

---

## 2. تصویر کلی محصول

«دانشیار من» یک SaaS فارسی برای مدارس است. مدیر مدرسه یا صاحب مدرسه وارد landing page می‌شود، امکانات را می‌بیند، قیمت‌ها را بررسی می‌کند، با ما تماس می‌گیرد یا اشتراک مدرسه می‌خرد. بعد از خرید، Super Admin برای آن مدرسه license و owner ایجاد می‌کند. صاحب مدرسه وارد پنل می‌شود و مدرسه را کامل مدیریت می‌کند.

کاربران اصلی:

- Super Admin
- Owner / مدیر اصلی مدرسه
- Principal / مدیر مدرسه
- Moaven / معاون
- Teacher / معلم
- Student / دانش‌آموز
- Support / پشتیبانی سیستم
- Finance / مالی سیستم

زیرسیستم‌های اصلی:

- landing page فروش و معرفی
- login panel
- داشبورد Super Admin
- داشبورد مدرسه
- مدیریت کاربران
- مدیریت کلاس‌ها
- مدیریت درس‌ها
- مدیریت برنامه هفتگی
- امتحانات آنلاین و تستی
- نمره‌دهی
- کارنامه
- حضور و غیاب
- پیام‌رسانی
- اطلاعیه‌ها
- اطلاعات تماس پدر/مادر داخل پرونده دانش‌آموز
- کلاس آنلاین
- فایل و تکلیف
- گزارش‌گیری
- امنیت و لاگ‌ها
- تنظیمات مدرسه
- سیستم اشتراک و license

---

## 3. دامنه‌ها و صفحات اصلی

### 3.1 دامنه عمومی

دامنه:

```text
mydaneshyar.ir
```

کاربرد:

- landing page
- معرفی امکانات
- pricing
- سوالات متداول
- تماس با ما
- فرم درخواست دمو
- فرم خرید اشتراک مدرسه
- قوانین و حریم خصوصی

عنوان مرورگر:

```text
دانشیار من | اتوماسیون هوشمند مدارس
```

### 3.2 دامنه پنل

دامنه:

```text
dashboard.mydaneshyar.ir
```

کاربرد:

- صفحه ورود
- فراموشی رمز عبور
- reset password
- پنل کاربران

---

## 4. طراحی landing page

### 4.1 هدف landing page

Landing page باید برای صاحب مدرسه، مدیر مدرسه یا مسئول خرید نرم‌افزار قانع‌کننده باشد. صفحه باید حس اعتماد، نظم، تکنولوژی، سرعت و سادگی بدهد.

متن مرکزی hero:

```text
دانشیار من
اتوماسیون هوشمند مدارس
مدیریت مدرسه، امتحان آنلاین، نمره‌دهی، کارنامه، پیام‌رسانی و ارتباط هوشمند با دانش‌آموزان در یک پنل فارسی و یکپارچه.
```

CTAهای اصلی:

- خرید اشتراک مدرسه
- درخواست دمو
- ورود به پنل
- تماس با ما

### 4.2 Header landing

Header باید سفید، تمیز، sticky و full width باشد.

سمت راست:

- لوگو یا متن «دانشیار من»
- زیرعنوان کوچک: «اتوماسیون هوشمند مدارس»

وسط:

- امکانات
- قیمت‌ها
- سوالات متداول
- تماس با ما

سمت چپ:

- ورود به پنل
- خرید اشتراک مدرسه

### 4.3 Hero section

اجزای hero:

- عنوان بزرگ
- توضیح کوتاه
- دو دکمه اصلی
- تصویر/Mockup از داشبورد مدرسه
- کارت‌های شناور کوچک مثل:
  - امتحان آنلاین فعال
  - نمره‌ها ثبت شد
  - پیام جدید از معلم
  - برنامه امروز

### 4.4 بخش امکانات

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

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

### 4.5 Pricing

پلن‌ها:

#### پلن پایه

برای مدارس کوچک.

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

#### پلن حرفه‌ای

برای مدارس متوسط.

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

#### پلن سازمانی

برای مدارس بزرگ یا مجموعه مدارس.

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

### 4.6 سوالات متداول

سوالات اولیه:

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

### 4.7 Footer

Footer باید روشن باشد، سنگین و تیره نباشد. رنگ پیشنهادی light sky یا mint خیلی ملایم.

محتوا:

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

### 4.8 تصمیم نهایی Footer و طراحی CTA

Footer نهایی:

- پس‌زمینه روشن با ترکیب `#F0FCF7` و `#E0F2FE`
- متن اصلی با `#111827`
- لینک‌ها با `#0EA678`
- hover لینک‌ها با `#0B8C66`
- border بالایی بسیار ملایم `#E2E8F0`
- بدون footer تیره
- بدون emoji
- آیکون‌ها فقط Bootstrap Icons یا SVG اختصاصی

ستون‌های footer:

1. معرفی کوتاه دانشیار من
2. امکانات اصلی
3. خرید و پشتیبانی
4. قوانین و حریم خصوصی

دکمه‌های footer:

- «درخواست دمو»
- «خرید اشتراک مدرسه»
- «ورود به پنل»

قانون طراحی:

```text
تمام دکمه‌ها، footer، کارت‌ها، فرم‌ها، جدول‌ها و modalها باید با Spring Mint هماهنگ باشند.
هیچ دکمه placeholder، غیرفعال بی‌دلیل، یا متفاوت از theme نباید باقی بماند.
```

---

## 5. پالت رنگی نهایی پروژه

پالت انتخاب‌شده برای پروژه:

```text
Palette 1: Spring Mint
```

تصویر پیش‌نمایش پالت‌ها حذف شد و دیگر در پروژه نگهداری نمی‌شود. از این مرحله به بعد، رنگ‌های زیر رنگ‌های رسمی طراحی «دانشیار من» هستند و باید در تمام UI، فایل‌های CSS، landing page و dashboard استفاده شوند.

### Palette نهایی: Spring Mint

حس: مدرن، آموزشی، سبز روشن، قابل اعتماد.

```css
--color-primary: #0EA678;
--color-primary-soft: #DFF8EF;
--color-bg: #FFFFFF;
--color-text: #111827;
--color-accent: #38BDF8;
```

### Design Tokens نهایی

این بخش باید بعدا دقیقا داخل `resources/css/root.css` پیاده‌سازی شود و با Vite داخل خروجی production ساخته شود.

```css
:root {
  --color-primary: #0EA678;
  --color-primary-hover: #0B8C66;
  --color-primary-active: #087756;
  --color-primary-soft: #DFF8EF;
  --color-primary-soft-2: #F0FCF7;

  --color-accent: #38BDF8;
  --color-accent-hover: #0EA5E9;
  --color-accent-soft: #E0F2FE;

  --color-bg: #FFFFFF;
  --color-bg-soft: #F8FAFC;
  --color-surface: #FFFFFF;
  --color-surface-muted: #F1F5F9;

  --color-text: #111827;
  --color-text-muted: #64748B;
  --color-text-soft: #94A3B8;
  --color-border: #E2E8F0;

  --color-success: #16A34A;
  --color-warning: #F59E0B;
  --color-danger: #DC2626;
  --color-info: #38BDF8;

  --shadow-soft: 0 16px 40px rgba(15, 23, 42, 0.08);
  --shadow-card: 0 10px 30px rgba(14, 166, 120, 0.12);

  --radius-sm: 10px;
  --radius-md: 16px;
  --radius-lg: 24px;
  --radius-xl: 32px;
}
```

کاربرد پیشنهادی:

- landing page اصلی
- دکمه‌های خرید
- کارت‌های امکانات
- داشبورد مدرسه

### Palette ردشده 2: Sky Pistachio

حس: شادتر، مدرسه‌ای، روشن، مناسب محصول عمومی.

```css
--color-primary: #16A34A;
--color-primary-soft: #E0F2FE;
--color-bg: #FFFFFF;
--color-text: #0F172A;
--color-accent: #FBBF24;
```

کاربرد پیشنهادی:

- landing page پرانرژی
- pricing
- بخش CTA

### Palette ردشده 3: Turquoise Lime

حس: تکنولوژی، هوشمند، کمی خاص‌تر.

```css
--color-primary: #06B6D4;
--color-primary-soft: #ECFCCB;
--color-bg: #FFFFFF;
--color-text: #134E4A;
--color-accent: #A7F3D0;
```

کاربرد پیشنهادی:

- پنل مدرن
- کلاس آنلاین
- صفحات گزارش

### Palette ردشده 4: Soft School

حس: امن، خیلی تمیز، سازمانی، قابل اعتماد.

```css
--color-primary: #22C55E;
--color-primary-soft: #F8FAFC;
--color-bg: #FFFFFF;
--color-text: #1E293B;
--color-accent: #93C5FD;
```

کاربرد پیشنهادی:

- انتخاب محافظه‌کارانه و حرفه‌ای
- مناسب برای مدارس رسمی

### تصمیم نهایی

- [x] انتخاب پالت نهایی توسط کارفرما: Spring Mint
- [x] ثبت رنگ‌ها در `resources/css/root.css`
- [x] ساخت theme variables
- [ ] ساخت dark mode اختیاری برای پنل

---

## 6. ساختار فولدر پروژه

ساختار نهایی پیشنهادی بر اساس Laravel:

```text
Daneshyar/
├── PLAN.md
├── composer.json
├── package.json
├── tsconfig.json
├── vite.config.ts
├── .env.example
├── app/
│   ├── Http/
│   │   ├── Controllers/
│   │   │   ├── LandingController.php
│   │   │   ├── AuthController.php
│   │   │   ├── SuperAdmin/
│   │   │   ├── School/
│   │   │   ├── Teacher/
│   │   │   ├── Student/
│   │   │   ├── Sms/
│   │   │   ├── Voting/
│   │   │   └── Modules/
│   │   ├── Middleware/
│   │   │   ├── EnsureSchoolIsActive.php
│   │   │   ├── EnsureRole.php
│   │   │   ├── EnsurePermission.php
│   │   │   └── EnsureSchoolScope.php
│   │   └── Requests/
│   │       ├── Auth/
│   │       ├── School/
│   │       ├── Exam/
│   │       └── Grade/
│   ├── Models/
│   │   ├── User.php
│   │   ├── School.php
│   │   ├── License.php
│   │   ├── Student.php
│   │   ├── Teacher.php
│   │   ├── Classroom.php
│   │   ├── Subject.php
│   │   ├── Schedule.php
│   │   ├── Exam.php
│   │   ├── Grade.php
│   │   ├── Attendance.php
│   │   ├── Message.php
│   │   ├── Announcement.php
│   │   ├── OnlineClass.php
│   │   ├── Module.php
│   │   ├── SchoolModule.php
│   │   ├── SmsWallet.php
│   │   ├── SmsMessage.php
│   │   ├── Voting.php
│   │   ├── VotingCandidate.php
│   │   ├── VotingVote.php
│   │   └── AuditLog.php
│   ├── Services/
│   │   ├── LicenseService.php
│   │   ├── ModuleEntitlementService.php
│   │   ├── PermissionService.php
│   │   ├── PersianDateService.php
│   │   ├── ExamService.php
│   │   ├── GradeService.php
│   │   ├── SmsService.php
│   │   ├── SmsWalletService.php
│   │   ├── VotingService.php
│   │   ├── ImportService.php
│   │   ├── ExportService.php
│   │   └── PwaService.php
│   └── Policies/
├── bootstrap/
├── config/
├── database/
│   ├── migrations/
│   ├── seeders/
│   ├── factories/
│   ├── schema.sql
│   ├── seed.sql
│   ├── backups/
│   └── ERD.md
├── documentation/
│   ├── api.md
│   ├── roles-permissions.md
│   ├── security.md
│   ├── pwa.md
│   ├── ui-guidelines.md
│   ├── test-plan.md
│   ├── changelog.md
│   └── archive/
├── public/
│   ├── index.php
│   ├── manifest.webmanifest
│   ├── service-worker.js
│   ├── offline.html
│   ├── build/
│   └── assets/
│       ├── images/
│       │   ├── logo/
│       │   ├── landing/
│       │   ├── dashboard/
│       │   ├── pwa/
│       │   └── placeholders/
│       ├── fonts/
│       │   ├── vazirmatn/
│       │   └── yekanbakh/
│       └── icons/
│           └── bootstrap-icons/
├── resources/
│   ├── css/
│   │   ├── app.css
│   │   ├── root.css
│   │   ├── landing.css
│   │   ├── auth.css
│   │   ├── dashboard.css
│   │   ├── forms.css
│   │   ├── tables.css
│   │   ├── exam.css
│   │   ├── pwa.css
│   │   └── responsive.css
│   ├── js/
│   │   ├── app.tsx
│   │   ├── bootstrap.ts
│   │   ├── types/
│   │   ├── lib/
│   │   │   ├── api.ts
│   │   │   ├── persianDate.ts
│   │   │   ├── validators.ts
│   │   │   └── permissions.ts
│   │   ├── Components/
│   │   │   ├── Layout/
│   │   │   ├── Forms/
│   │   │   ├── Tables/
│   │   │   ├── Charts/
│   │   │   └── Pwa/
│   │   └── Pages/
│   │       ├── Landing/
│   │       ├── Auth/
│   │       ├── Dashboard/
│   │       ├── SuperAdmin/
│   │       ├── School/
│   │       ├── Teacher/
│   │       ├── Student/
│   │       ├── Exams/
│   │       ├── Grades/
│   │       ├── Schedule/
│   │       ├── Messages/
│   │       ├── Sms/
│   │       ├── Voting/
│   │       ├── Modules/
│   │       └── Reports/
│   └── views/
│       └── app.blade.php
├── routes/
│   ├── web.php
│   ├── api.php
│   └── console.php
├── scripts/
│   ├── build.py
│   ├── apache_ready_check.py
│   ├── package_for_apache.py
│   ├── php_parse_check.cjs
│   ├── import_remote_database.py
│   ├── server_setup_ubuntu_apache.sh
│   ├── DEPLOY_APACHE.md
│   └── USAGE.md
└── storage/
    ├── uploads/
    ├── logs/
    ├── exports/
    └── private/
```

نکته مهم: چون Laravel انتخاب شد، دیگر فولدر جداگانه `api/` برای کل backend نمی‌سازیم. API داخل `routes/api.php` تعریف می‌شود و controllerها داخل `app/Http/Controllers` قرار می‌گیرند.

- صفحه‌ها داخل React/TypeScript و `resources/js/Pages` ساخته می‌شوند.
- Componentها داخل `resources/js/Components` ساخته می‌شوند.
- CSSهای اصلی داخل `resources/css` هستند و با Vite build می‌شوند.
- تصاویر، فونت‌ها و آیکون‌های خام داخل `public/assets` می‌مانند.
- خروجی production داخل `public/build` ساخته می‌شود.
- کاربر URLهای عادی مثل `/dashboard` را می‌بیند، نه نام فایل‌های build.
- Backend داخل ساختار استاندارد Laravel
- دیتابیس داخل `database`
- مستندات داخل `documentation`
- PWA داخل `public/manifest.webmanifest` و `public/service-worker.js`

---

## 6.1 فهرست کنترل فایل‌ها و جای درست هر فایل

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

وضعیت:

- `[x]` یعنی فایل الان در پروژه وجود دارد.
- `[ ]` یعنی باید در زمان پیاده‌سازی ساخته شود.

### فایل‌های ریشه پروژه

- [x] `PLAN.md` — سند مادر پروژه
- [x] `README.md` — راهنمای نصب، اجرا، build و deployment
- [x] `.env.example` — نمونه تنظیمات محیطی بدون اطلاعات حساس
- [x] `.gitignore` — جلوگیری از ورود `.env`, `vendor`, `node_modules`, logها و cacheها
- [x] `composer.json` — وابستگی‌های Laravel/PHP
- [x] `package.json` — وابستگی‌های React/TypeScript/Vite
- [x] `package-lock.json` — lockfile وابستگی‌های Node
- [x] `tsconfig.json` — تنظیمات TypeScript
- [x] `vite.config.ts` — تنظیمات Vite برای Laravel + React
- [x] `artisan` — فرمان اصلی Laravel

### Backend Laravel

- [x] `app/Http/Controllers/LandingController.php` — کنترل صفحه‌های landing
- [x] `app/Http/Controllers/AuthController.php` — login/logout/reset password
- [x] `app/Http/Controllers/ProfileCompletionController.php`
- [x] `app/Http/Controllers/SuperAdmin/DashboardController.php`
- [x] `app/Http/Controllers/SuperAdmin/SchoolController.php`
- [x] `app/Http/Controllers/SuperAdmin/LicenseController.php`
- [x] `app/Http/Controllers/SuperAdmin/ModuleController.php`
- [x] `app/Http/Controllers/SuperAdmin/SmsController.php`
- [x] `app/Http/Controllers/School/DashboardController.php`
- [x] `app/Http/Controllers/School/UserController.php`
- [x] `app/Http/Controllers/School/StudentController.php`
- [x] `app/Http/Controllers/School/TeacherController.php`
- [x] `app/Http/Controllers/School/ClassroomController.php`
- [x] `app/Http/Controllers/School/SubjectController.php`
- [x] `app/Http/Controllers/School/ScheduleController.php`
- [x] `app/Http/Controllers/School/AttendanceController.php`
- [x] `app/Http/Controllers/School/AttendanceApprovalController.php`
- [x] `app/Http/Controllers/School/UserActivityController.php`
- [x] `app/Http/Controllers/School/ReportController.php`
- [x] `app/Http/Controllers/Teacher/DashboardController.php`
- [x] `app/Http/Controllers/Teacher/ExamController.php`
- [x] `app/Http/Controllers/Teacher/GradeController.php`
- [x] `app/Http/Controllers/Teacher/HomeworkController.php`
- [x] `app/Http/Controllers/Student/DashboardController.php`
- [x] `app/Http/Controllers/Student/ExamController.php`
- [x] `app/Http/Controllers/Student/HomeworkController.php`
- [x] `app/Http/Controllers/Sms/SmsWalletController.php`
- [x] `app/Http/Controllers/Sms/SmsMessageController.php`
- [x] `app/Http/Controllers/Voting/VotingController.php`
- [x] `app/Http/Controllers/Voting/CandidateController.php`
- [x] `app/Http/Controllers/Modules/SchoolModuleController.php`
- [x] `app/Http/Controllers/FileController.php`
- [x] `app/Http/Controllers/ExportController.php`
- [x] `app/Http/Controllers/ImportController.php`

### Middleware و Requestها

- [x] `app/Http/Middleware/EnsureSchoolIsActive.php`
- [x] `app/Http/Middleware/EnsureRole.php`
- [x] `app/Http/Middleware/EnsurePermission.php`
- [x] `app/Http/Middleware/EnsureSchoolScope.php`
- [x] `app/Http/Middleware/EnsureModuleEnabled.php`
- [x] `app/Http/Middleware/EnsureProfileCompleted.php`
- [x] `app/Http/Middleware/PreventDashboardCache.php`
- [x] `app/Http/Requests/Auth/LoginRequest.php`
- [x] `app/Http/Requests/Auth/CompleteProfileRequest.php`
- [x] `app/Http/Requests/School/StoreStudentRequest.php`
- [x] `app/Http/Requests/School/ImportStudentsRequest.php`
- [x] `app/Http/Requests/Exam/StoreExamRequest.php`
- [x] `app/Http/Requests/Grade/StoreGradeRequest.php`
- [x] `app/Http/Requests/Sms/SendSmsRequest.php`
- [x] `app/Http/Requests/Voting/StoreVotingRequest.php`

### Models

- [x] `app/Models/User.php`
- [x] `app/Models/School.php`
- [x] `app/Models/License.php`
- [x] `app/Models/Plan.php`
- [x] `app/Models/Module.php`
- [x] `app/Models/ModuleDependency.php`
- [x] `app/Models/SchoolModule.php`
- [x] `app/Models/SchoolModuleLimit.php`
- [x] `app/Models/Student.php`
- [x] `app/Models/Teacher.php`
- [x] `app/Models/Classroom.php`
- [x] `app/Models/Subject.php`
- [x] `app/Models/Schedule.php`
- [x] `app/Models/Exam.php`
- [x] `app/Models/ExamQuestion.php`
- [x] `app/Models/ExamAnswer.php`
- [x] `app/Models/Grade.php`
- [x] `app/Models/ReportCard.php`
- [x] `app/Models/Attendance.php`
- [x] `app/Models/AttendanceSession.php`
- [x] `app/Models/AttendanceRecord.php`
- [x] `app/Models/AttendanceApprovalRequest.php`
- [x] `app/Models/AttendanceSmsLog.php`
- [x] `app/Models/Message.php`
- [x] `app/Models/Announcement.php`
- [x] `app/Models/OnlineClass.php`
- [x] `app/Models/SmsWallet.php`
- [x] `app/Models/SmsPackage.php`
- [x] `app/Models/SmsWalletTransaction.php`
- [x] `app/Models/SmsMessage.php`
- [x] `app/Models/SmsRecipient.php`
- [x] `app/Models/Voting.php`
- [x] `app/Models/VotingCandidate.php`
- [x] `app/Models/VotingEligibleVoter.php`
- [x] `app/Models/VotingVote.php`
- [x] `app/Models/FileUpload.php`
- [x] `app/Models/AuditLog.php`
- [x] `app/Models/UserHeartbeat.php`
- [x] `app/Models/UserUsageDaily.php`
- [x] `app/Models/ImportJob.php`
- [x] `app/Models/ExportJob.php`

### Services

- [x] `app/Services/LicenseService.php`
- [x] `app/Services/ModuleEntitlementService.php`
- [x] `app/Services/PermissionService.php`
- [x] `app/Services/PersianDateService.php`
- [x] `app/Services/ExamService.php`
- [x] `app/Services/GradeService.php`
- [x] `app/Services/AttendanceService.php`
- [x] `app/Services/ProfileCompletionService.php`
- [x] `app/Services/UserActivityService.php`
- [x] `app/Services/SmsService.php`
- [x] `app/Services/SmsWalletService.php`
- [x] `app/Services/VotingService.php`
- [x] `app/Services/ImportService.php`
- [x] `app/Services/ExportService.php`
- [x] `app/Services/AnalyticsService.php`
- [x] `app/Services/PwaService.php`
- [x] `app/Services/AuditLogService.php`

### Frontend React/TypeScript

- [x] `resources/js/app.tsx` — entry اصلی React/Inertia
- [x] `resources/js/bootstrap.ts` — تنظیمات اولیه frontend
- [x] `resources/js/types/index.ts` — typeهای مشترک
- [x] `resources/js/lib/api.ts`
- [x] `resources/js/lib/persianDate.ts`
- [x] `resources/js/lib/validators.ts`
- [x] `resources/js/lib/permissions.ts`
- [x] `resources/js/lib/formatters.ts`
- [x] `resources/js/lib/download.ts`
- [x] `resources/js/Components/Layout/AppLayout.tsx`
- [x] `resources/js/Components/Layout/DashboardSidebar.tsx`
- [x] `resources/js/Components/Layout/Topbar.tsx`
- [x] `resources/js/Components/Brand/BrandMark.tsx`
- [x] `resources/js/Components/Forms/TextInput.tsx`
- [x] `resources/js/Components/Forms/SelectInput.tsx`
- [x] `resources/js/Components/Tables/DataTable.tsx`
- [x] `resources/js/Components/Charts/UsageChart.tsx`
- [x] `resources/js/Components/Pwa/InstallPrompt.tsx`
- [x] `resources/js/Pages/Landing/Home.tsx`
- [x] `resources/js/Pages/Landing/Pricing.tsx`
- [x] `resources/js/Pages/Landing/Faq.tsx`
- [x] `resources/js/Pages/Landing/Contact.tsx`
- [x] `resources/js/Pages/Auth/Login.tsx`
- [x] `resources/js/Pages/Auth/ForgotPassword.tsx`
- [x] `resources/js/Pages/Auth/ResetPassword.tsx`
- [x] `resources/js/Pages/Auth/CompleteProfile.tsx`
- [x] `resources/js/Pages/Dashboard/Index.tsx`
- [x] `resources/js/Pages/SuperAdmin/Schools.tsx`
- [x] `resources/js/Pages/SuperAdmin/Modules.tsx`
- [x] `resources/js/Pages/SuperAdmin/SmsUsage.tsx`
- [x] `resources/js/Pages/School/Students.tsx`
- [x] `resources/js/Pages/School/Teachers.tsx`
- [x] `resources/js/Pages/School/Classes.tsx`
- [x] `resources/js/Pages/School/Reports.tsx`
- [x] `resources/js/Pages/Teacher/MyClasses.tsx`
- [x] `resources/js/Pages/Student/Home.tsx`
- [x] `resources/js/Pages/Exams/ExamBuilder.tsx`
- [x] `resources/js/Pages/Exams/TakeExam.tsx`
- [x] `resources/js/Pages/Grades/GradeTable.tsx`
- [x] `resources/js/Pages/Schedule/ScheduleBuilder.tsx`
- [x] `resources/js/Pages/Attendance/ClassSheet.tsx`
- [x] `resources/js/Pages/Attendance/ApprovalQueue.tsx`
- [x] `resources/js/Pages/Attendance/StudentStats.tsx`
- [x] `resources/js/Pages/Modules/SchoolModules.tsx`
- [x] `resources/js/Pages/Modules/ModuleStore.tsx`
- [x] `resources/js/Pages/Sms/Wallet.tsx`
- [x] `resources/js/Pages/Sms/SendToAbsents.tsx`
- [x] `resources/js/Pages/Voting/List.tsx`
- [x] `resources/js/Pages/Voting/Builder.tsx`
- [x] `resources/js/Pages/Voting/Vote.tsx`
- [x] `resources/js/Pages/Voting/Results.tsx`
- [x] `resources/js/Pages/Imports/ImportStudents.tsx`
- [x] `resources/js/Pages/Exports/ExportCenter.tsx`
- [x] `resources/js/Pages/Analytics/SchoolUsage.tsx`

### CSS

- [x] `resources/css/app.css`
- [x] `resources/css/root.css`
- [x] `resources/css/landing.css`
- [x] `resources/css/auth.css`
- [x] `resources/css/dashboard.css`
- [x] `resources/css/forms.css`
- [x] `resources/css/tables.css`
- [x] `resources/css/exam.css`
- [x] `resources/css/pwa.css`
- [x] `resources/css/responsive.css`

### Views و public

- [x] `resources/views/app.blade.php` — root shell برای Inertia
- [x] `public/index.php`
- [x] `public/.htaccess`
- [x] `public/manifest.webmanifest`
- [x] `public/service-worker.js`
- [x] `public/offline.html`
- [x] `public/assets/images/logo/`
- [x] `public/assets/images/pwa/`
- [x] `public/assets/images/pwa/icon-192.png`
- [x] `public/assets/images/pwa/icon-512.png`
- [x] `public/assets/fonts/vazirmatn/`
- [x] `public/assets/icons/bootstrap-icons/`
- [x] `public/build/manifest.json` — بعد از `npm run build`

### Database و documentation

- [x] `database/schema.sql`
- [x] `database/seed.sql`
- [x] `database/ERD.md`
- [x] `database/migrations/`
- [x] `database/seeders/`
- [x] `documentation/api.md`
- [x] `documentation/roles-permissions.md`
- [x] `documentation/security.md`
- [x] `documentation/pwa.md`
- [x] `documentation/import-export.md`
- [x] `documentation/apache-deployment.md`
- [x] `documentation/ui-guidelines.md`
- [x] `documentation/test-plan.md`
- [x] `documentation/changelog.md`
- [x] `documentation/templates/students-import-template.csv`
- [x] `documentation/templates/users-import-template.csv`
- [x] `documentation/templates/teachers-import-template.csv`

### Scripts

- [x] `scripts/build.py` — build پروژه برای development/production
- [x] `scripts/apache_ready_check.py` — بررسی آماده بودن برای Apache
- [x] `scripts/package_for_apache.py` — ساخت zip قابل deploy روی Apache
- [x] `scripts/php_parse_check.cjs` — بررسی syntax فایل‌های PHP با parser جاوااسکریپتی وقتی PHP روی سیستم نصب نیست
- [x] `scripts/import_remote_database.py` — ساخت دیتابیس از تنظیمات `.env` و import کردن `schema.sql` و `seed.sql`
- [x] `scripts/server_setup_ubuntu_apache.sh` — نصب پایه Apache/PHP/Composer/Node روی Ubuntu Server
- [x] `scripts/DEPLOY_APACHE.md` — دستورهای deploy روی سرور Apache با SSH port `2435`
- [x] `scripts/USAGE.md` — راهنمای استفاده از اسکریپت‌ها، build و اولین تست local/Apache

---

## 7. نقش‌ها و دسترسی‌ها

### 7.1 Super Admin

بالاترین سطح دسترسی.

امکانات:

- مشاهده همه مدارس
- ایجاد مدرسه جدید
- ویرایش مدرسه
- فعال/غیرفعال کردن مدرسه
- فروش license
- تمدید license
- توقف license
- فروش ماژول‌ها و قابلیت‌ها به مدرسه
- فعال/غیرفعال کردن ماژول‌های مدرسه
- تعیین limit برای ماژول‌های مدرسه
- فعال کردن SMS برای مدرسه
- شارژ دستی کیف پول SMS مدرسه
- فعال کردن Voting برای مدرسه
- مشاهده همه ownerها
- ساخت owner برای مدرسه
- reset password برای کاربران اصلی
- مشاهده تعداد کل دانش‌آموزان سیستم
- مشاهده تعداد کل معلمان
- مشاهده تعداد مدارس فعال
- مشاهده درآمد و اشتراک‌ها
- مشاهده logs مهم
- مشاهده خطاهای سیستم
- مدیریت پلن‌های قیمت
- مدیریت تنظیمات global
- مدیریت پیام‌های سیستمی
- مشاهده مصرف storage مدرسه‌ها
- مشاهده آمار امتحانات
- مشاهده آمار ورود کاربران
- خروجی گرفتن از گزارش‌ها

چیزهایی که باید log شوند:

- ایجاد مدرسه
- تغییر license
- فعال/غیرفعال کردن ماژول مدرسه
- تغییر limit ماژول مدرسه
- شارژ دستی SMS
- فعال/غیرفعال کردن Voting
- reset password
- تغییر owner
- ورود ناموفق زیاد
- تغییر پلن
- حذف یا غیرفعال‌سازی مدرسه

### 7.2 Owner / مدیر اصلی مدرسه

کسی که مدرسه را از Super Admin تحویل می‌گیرد.

امکانات:

- مشاهده داشبورد مدرسه
- مدیریت اطلاعات مدرسه
- مدیریت سال تحصیلی
- مدیریت پایه‌ها
- مدیریت کلاس‌ها
- import دانش‌آموزان
- ساخت دانش‌آموز
- ساخت معلم
- ساخت معاون
- تعریف سطح دسترسی معاون‌ها
- اختصاص معلم به کلاس
- اختصاص درس به کلاس
- ساخت برنامه هفتگی
- مشاهده نمرات
- تایید نمرات
- مشاهده کارنامه
- مدیریت حضور و غیاب
- ارسال اطلاعیه
- پیام به دانش‌آموز/معلم/کادر مدرسه
- مدیریت امتحانات
- مشاهده گزارش‌ها
- خروجی Excel/PDF
- تنظیم لوگو و رنگ مدرسه
- مدیریت پرداخت اشتراک در آینده
- مشاهده ماژول‌های فعال مدرسه
- مدیریت دسترسی کاربران به ماژول‌های فعال
- شارژ کیف پول SMS در صورت فعال بودن ماژول SMS
- مشاهده مصرف SMS مدرسه
- مدیریت رأی‌گیری در صورت فعال بودن ماژول Voting
- خرید/درخواست فعال‌سازی ماژول جدید از Super Admin

### 7.3 Principal / مدیر اجرایی

اگر مدرسه بخواهد owner جدا از مدیر اجرایی باشد.

امکانات:

- بیشتر امکانات مدیریتی مدرسه
- بدون دسترسی به billing/license
- بدون امکان حذف owner
- امکان تایید نمرات و کارنامه
- امکان مدیریت معاون‌ها طبق اجازه owner

### 7.4 Moaven / معاون

معاون‌ها باید قابل تعریف و قابل محدودسازی باشند.

انواع پیشنهادی:

- معاون آموزشی
- معاون پرورشی
- معاون اجرایی
- معاون انضباطی
- معاون فناوری

دسترسی‌های قابل تنظیم:

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

هر دسترسی باید checkbox داشته باشد.

### 7.5 Teacher / معلم

امکانات:

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

### 7.6 Student / دانش‌آموز

امکانات:

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

### 7.7 Support

نقش داخلی برای تیم دانشیار من.

امکانات:

- مشاهده tickets
- پاسخ به درخواست پشتیبانی
- مشاهده اطلاعات محدود مدرسه
- بدون دسترسی به نمرات حساس مگر با اجازه Super Admin

### 7.8 Finance

نقش داخلی برای امور مالی.

امکانات:

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

---

## 8. داشبوردها

### 8.1 داشبورد Super Admin

کارت‌های بالا:

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

تب‌ها:

- مدارس
- صاحبان مدارس
- اشتراک‌ها
- پلن‌ها
- کاربران
- گزارش‌ها
- لاگ‌ها
- خطاهای سیستم
- تنظیمات
- پشتیبانی

جدول مدارس:

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

### 8.2 داشبورد Owner

کارت‌ها:

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

تب‌ها:

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

### 8.3 داشبورد Teacher

کارت‌ها:

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

تب‌ها:

- برنامه من
- کلاس‌های من
- امتحانات
- نمره‌دهی
- تکالیف
- حضور و غیاب
- پیام‌ها

### 8.4 داشبورد Student

کارت‌ها:

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

تب‌ها:

- صفحه اصلی
- برنامه هفتگی
- امتحانات
- نمرات
- کارنامه
- تکالیف
- پیام‌ها
- کلاس آنلاین

---

## 9. سیستم ورود و احراز هویت

صفحات:

- `login.html`
- `forgot-password.html`
- `reset-password.html`

Login باید شامل:

- username
- password
- دکمه ورود
- فراموشی رمز عبور
- انتخاب «مرا به خاطر بسپار» در صورت نیاز

منبع username/password:

- کاربران مدرسه توسط Owner یا نقش مجاز ساخته می‌شوند.
- Super Admin دستی ساخته می‌شود یا با seed امن در دیتابیس ایجاد می‌شود.
- رمزها هرگز plain text ذخیره نمی‌شوند.

امنیت login:

- password hash با `password_hash`
- session امن
- CSRF
- rate limit
- قفل موقت بعد از تلاش ناموفق زیاد
- ثبت login موفق و ناموفق
- reset password با token زمان‌دار
- forced password change برای رمز اولیه

### 9.1 تکمیل اطلاعات در اولین ورود

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

قانون:

```text
کاربر با پروفایل ناقص فقط به صفحه تکمیل اطلاعات دسترسی دارد.
```

اطلاعات ضروری بر اساس نقش متفاوت است.

برای دانش‌آموز:

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

برای اطلاعات تماس پدر/مادر:

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

برای معلم:

- شماره موبایل
- کد ملی
- تخصص
- شماره تماس اضطراری اختیاری
- آدرس اختیاری

برای owner/moaven:

- شماره موبایل
- کد ملی
- ایمیل
- شماره تماس اضطراری

قابلیت‌ها:

- نمایش progress تکمیل پروفایل
- مشخص کردن فیلدهای اجباری توسط owner مدرسه
- امکان تایید اطلاعات توسط معاون/owner در صورت نیاز
- log شدن تغییر اطلاعات حساس مثل موبایل پدر/مادر
- اگر شماره موبایل تغییر کرد، در آینده امکان تایید با SMS وجود داشته باشد.

فیلدهای پیشنهادی در users:

```sql
profile_completed_at
must_complete_profile
must_change_password
last_profile_update_at
```

صفحه frontend:

```text
resources/js/Pages/Auth/CompleteProfile.tsx
```

---

## 10. ماژول مدرسه و license

هر مدرسه باید:

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

License باید:

- قابل تمدید باشد
- قابل توقف باشد
- قابل ارتقا باشد
- تاریخچه داشته باشد
- هشدار نزدیک پایان داشته باشد
- روی login مدرسه اثر بگذارد

### 10.1 سیستم فروش ماژول‌ها و Entitlement مدرسه

«دانشیار من» باید فقط یک license ساده نداشته باشد. باید بتوانیم برای هر مدرسه مشخص کنیم دقیقا چه ماژول‌هایی خریده یا اجازه استفاده دارد.

Super Admin باید بتواند برای هر مدرسه:

- ماژول‌ها را فعال کند.
- ماژول‌ها را غیرفعال کند.
- تاریخ شروع و پایان هر ماژول را مشخص کند.
- محدودیت هر ماژول را مشخص کند.
- قیمت هر ماژول را جداگانه بفروشد.
- بسته‌های آماده بسازد.
- افزونه‌های جدا مثل SMS، Voting یا Online Class بفروشد.
- ببیند کدام مدرسه چه امکاناتی دارد.
- تاریخچه تغییرات ماژول‌های مدرسه را ببیند.

قانون مهم:

```text
اگر مدرسه ماژولی را نخریده باشد، هیچ کاربر آن مدرسه حتی owner نباید آن ماژول را ببیند یا استفاده کند.
```

یعنی permission داخلی کاربر کافی نیست. دو لایه داریم:

1. مدرسه اصلا آن ماژول را خریده/فعال دارد یا نه؟
2. کاربر داخل آن مدرسه permission استفاده از آن ماژول را دارد یا نه؟

مثال:

```text
مدرسه A ماژول Voting ندارد.
پس owner، معاون، معلم و دانش‌آموز هیچ‌کدام voting را نمی‌بینند.

مدرسه B ماژول Voting دارد.
حالا owner می‌تواند مشخص کند چه کسی داخل مدرسه permission مدیریت رأی‌گیری داشته باشد.
```

### 10.2 ماژول‌های قابل فروش

ماژول‌های پایه:

- Core School System / سیستم اصلی مدرسه
- User Management / مدیریت کاربران
- Student Management / مدیریت دانش‌آموزان
- Teacher Management / مدیریت معلمان
- Class Management / مدیریت کلاس‌ها
- Subject Management / مدیریت درس‌ها

ماژول‌های آموزشی:

- Weekly Schedule / برنامه هفتگی
- Homework / تکلیف
- Online Exams / امتحانات آنلاین
- Grades / نمره‌دهی
- Report Cards / کارنامه
- Attendance / حضور و غیاب
- Online Class / کلاس آنلاین

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

- Messages / پیام‌رسانی داخلی
- Announcements / اطلاعیه‌ها
- Important Popups / پیام مهم popup
- Student Contacts / اطلاعات تماس پدر و مادر
- SMS System / سامانه پیامک

ماژول‌های مدیریتی و پیشرفته:

- Reports / گزارش‌ها
- Export PDF/Excel / خروجی‌ها
- Audit Logs / لاگ‌ها
- Import System / import دانش‌آموزان
- Voting / رأی‌گیری و شورای دانش‌آموزی
- Finance / پرداخت و کیف پول
- Support Tickets / پشتیبانی

### 10.3 ماژول‌های اجباری و وابستگی‌ها

بعضی ماژول‌ها بدون ماژول‌های پایه معنی ندارند. پس سیستم باید dependency داشته باشد.

ماژول‌های همیشه اجباری:

- Core School System
- User Management
- School Settings
- Auth
- Roles and Permissions
- Audit Logs پایه

وابستگی‌ها:

| ماژول | وابستگی اجباری |
|---|---|
| Student Management | Core, User Management |
| Teacher Management | Core, User Management |
| Class Management | Core, Student Management, Teacher Management |
| Subject Management | Core |
| Weekly Schedule | Class Management, Teacher Management, Subject Management |
| Homework | Class Management, Student Management, Teacher Management |
| Online Exams | Class Management, Student Management, Teacher Management, Subject Management |
| Grades | Student Management, Teacher Management, Subject Management |
| Report Cards | Grades, Student Management |
| Attendance | Class Management, Student Management |
| Student Contacts | Student Management |
| Messages | User Management |
| Announcements | User Management |
| SMS System | User Management, SMS Wallet |
| Online Class | Weekly Schedule یا Class Management |
| Voting | Student Management, Class Management |
| Reports | ماژول‌هایی که قرار است گزارش شوند |
| Export PDF/Excel | Reports |

مثال فروش:

اگر Super Admin بخواهد فقط این‌ها را به مدرسه بفروشد:

```text
Homework + Class System + Student System
```

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

- Homework به Class Management نیاز دارد.
- Homework به Student Management نیاز دارد.
- Homework به Teacher Management نیاز دارد.
- Class Management به Core و User Management نیاز دارد.

پس یا باید dependencyها خودکار اضافه شوند، یا Super Admin هشدار بگیرد که بدون وابستگی‌ها این ماژول قابل فعال‌سازی نیست.

قانون پیشنهادی:

- dependencyهای اجباری خودکار اضافه شوند.
- dependencyهای اختیاری با هشدار نشان داده شوند.

### 10.4 سطح دسترسی ماژولی داخل مدرسه

بعد از اینکه Super Admin ماژول را برای مدرسه فعال کرد، owner مدرسه باید بتواند داخل مدرسه permission بدهد.

مثال برای Voting:

- Super Admin ماژول Voting را برای مدرسه فعال می‌کند.
- Owner داخل مدرسه تعیین می‌کند:
  - چه کسی رأی‌گیری بسازد؟
  - چه کسی نتایج را ببیند؟
  - چه کسی رأی‌گیری را publish کند؟
  - دانش‌آموزان کدام کلاس‌ها رأی بدهند؟

مثال برای SMS:

- Super Admin ماژول SMS را برای مدرسه فعال می‌کند.
- Owner کیف پول SMS را شارژ می‌کند.
- Owner تعیین می‌کند معلم اجازه ارسال SMS داشته باشد یا نه.
- معاون آموزشی شاید اجازه ارسال به غایبین داشته باشد.
- معلم فقط بتواند به غایبین کلاس خودش SMS بزند.

### 10.5 بسته‌های فروش پیشنهادی

#### بسته پایه مدرسه

- Core
- User Management
- Student Management
- Teacher Management
- Class Management
- Weekly Schedule

#### بسته آموزشی

- بسته پایه
- Homework
- Online Exams
- Grades
- Report Cards
- Attendance

#### بسته ارتباطی

- Messages
- Announcements
- Student Contacts
- SMS System

#### بسته پیشرفته

- Reports
- Export PDF/Excel
- Online Class
- Voting
- Support Tickets

#### بسته کامل

- همه ماژول‌ها
- محدودیت بیشتر کاربران
- پشتیبانی ویژه
- storage بیشتر

### 10.6 جدول‌های پیشنهادی برای module entitlement

جدول‌ها:

- modules
- module_dependencies
- school_modules
- school_module_limits
- school_module_logs

نمونه `modules`:

```sql
id
key
name_fa
name_en
description
is_core
is_sellable
status
created_at
updated_at
```

نمونه `school_modules`:

```sql
id
school_id
module_id
enabled
starts_at
expires_at
enabled_by
disabled_by
price
notes
created_at
updated_at
```

نمونه limit:

```sql
id
school_id
module_id
limit_key
limit_value
created_at
updated_at
```

نمونه limitها:

- max_students
- max_teachers
- max_storage_mb
- max_online_exams_per_month
- max_sms_per_month
- max_votings_per_month

### 10.7 قوانین UI برای ماژول‌های غیرفعال

اگر ماژول برای مدرسه فعال نیست:

- route آن باید بسته باشد.
- API آن باید `403` بدهد.
- sidebar آن را نشان ندهیم.
- dashboard card آن را نشان ندهیم.
- owner یک پیام upgrade ببیند.
- کاربران عادی حتی پیام upgrade هم نبینند مگر لازم باشد.

پیام پیشنهادی برای owner:

```text
این قابلیت در اشتراک فعلی مدرسه شما فعال نیست. برای فعال‌سازی با پشتیبانی دانشیار من تماس بگیرید.
```

### 10.8 فروش permission و package به مدرسه

Super Admin فقط ماژول نمی‌فروشد؛ می‌تواند permissionهای دقیق‌تر را هم بفروشد یا محدود کند.

مثال:

```text
مدرسه A فقط Student Management + Class Management + Homework دارد.
مدرسه B Full Pack دارد.
مدرسه C Voting دارد ولی فقط برای پایه‌های 9 تا 12.
مدرسه D SMS دارد ولی فقط owner و معاون مجاز می‌توانند ارسال کنند.
```

لایه‌های کنترل:

1. `school_modules`: آیا اصل ماژول برای مدرسه فعال است؟
2. `school_permissions`: مدرسه چه permissionهایی را خریده/دارد؟
3. `role_permissions`: هر نقش داخل مدرسه چه permissionهایی دارد؟
4. `user_permissions`: استثناهای اختصاصی برای یک کاربر

قانون:

```text
اگر مدرسه permission را ندارد، حتی owner هم آن گزینه را نمی‌بیند.
اگر مدرسه permission را دارد، owner می‌تواند آن permission را به نقش‌ها/کاربران مجاز بدهد.
```

مثال permissionهای قابل فروش:

- exams.online.create
- exams.online.take
- grades.create
- grades.approve
- homework.create
- homework.submit
- attendance.create
- attendance.approve_absence_sms
- sms.send_to_absents
- sms.send_bulk
- voting.create
- voting.publish
- voting.view_results
- reports.export
- imports.students
- exports.school_full

### 10.9 dependency برای permissionها

بعضی permissionها بدون permissionهای پایه معنی ندارند.

نمونه‌ها:

| Permission | نیازمندی |
|---|---|
| homework.create | homework module, class management, student management |
| homework.submit | homework module, student management |
| exams.online.create | exams module, class management, subject management |
| grades.approve | grades module, grades.create یا grades.view |
| sms.send_to_absents | sms module, sms wallet, attendance module |
| voting.publish | voting module, voting.create |
| voting.view_results | voting module |
| exports.school_full | export module, reports module |

رفتار سیستم:

- هنگام فروش permission به مدرسه، dependencyها بررسی شوند.
- اگر dependency وجود ندارد، سیستم هشدار بدهد.
- dependencyهای اجباری خودکار اضافه شوند یا Super Admin مجبور شود تایید کند.
- در sidebar فقط گزینه‌هایی دیده شوند که هم module و هم permission آن برای مدرسه فعال است.

### 10.10 فروش پایه‌های تحصیلی به مدرسه

Super Admin باید بتواند مشخص کند یک مدرسه چه پایه‌هایی را دارد.

مثال:

```text
مدرسه A فقط پایه 1 تا 6 دارد.
مدرسه B فقط پایه 7 تا 9 دارد.
مدرسه C فقط پایه 9 تا 12 دارد.
مدرسه D پایه 1 تا 12 دارد.
```

قانون:

- owner فقط پایه‌هایی را می‌بیند که برای مدرسه فعال شده‌اند.
- owner فقط در پایه‌های فعال می‌تواند کلاس بسازد.
- import دانش‌آموز اگر پایه غیرمجاز داشته باشد خطا بدهد.
- Voting می‌تواند بر اساس پایه‌های فعال محدود شود.
- Exam، Homework، Grade و Report Card فقط برای پایه‌های فعال مدرسه ساخته شوند.

جدول‌های پیشنهادی:

- grade_levels
- school_grade_levels

نمونه `school_grade_levels`:

```sql
id
school_id
grade_level_id
enabled
enabled_by
created_at
updated_at
```

### 10.11 بسته‌های permission آماده

بسته‌ها:

- Starter Pack
- Education Pack
- Communication Pack
- Voting Pack
- SMS Pack
- Full Pack
- Custom Pack

هر pack باید شامل:

- modules
- permissions
- limits
- allowed grade levels
- price
- starts_at
- expires_at

قانون UI:

```text
قابلیت فروخته‌نشده نباید در sidebar، صفحه، API، جستجو، shortcut یا dashboard دیده شود.
```

---

## 11. مدیریت کاربران

فیلدهای مشترک:

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

اعتبارسنجی:

- موبایل ایران: `09xxxxxxxxx`
- username یکتا
- password قوی
- کد ملی در صورت فعال بودن validation
- ایمیل معتبر در صورت وارد شدن

عملیات:

- افزودن
- ویرایش
- غیرفعال‌سازی
- reset password
- تغییر نقش
- تغییر دسترسی
- خروجی گرفتن
- import گروهی

### 11.1 وضعیت آنلاین/آفلاین و فعالیت کاربر

سیستم باید بداند کاربر چه زمانی آنلاین بوده، آخرین بار کی دیده شده و چه مقدار از سیستم استفاده کرده است.

برای هر کاربر:

- آخرین login
- آخرین logout
- آخرین activity
- وضعیت فعلی: online/offline
- دستگاه/مرورگر
- IP آخرین ورود
- تعداد loginها
- مجموع زمان تقریبی استفاده
- تعداد روزهای فعال در ماه
- تعداد عملیات مهم انجام‌شده

قانون:

```text
وضعیت online/offline باید تقریبی باشد، نه ادعای صددرصد قطعی؛ چون کاربر ممکن است browser را بدون logout ببندد.
```

روش پیشنهادی:

- هر چند دقیقه یک heartbeat از frontend ارسال شود.
- اگر heartbeat کاربر در چند دقیقه اخیر وجود داشت، online محسوب شود.
- اگر heartbeat قطع شد، offline محسوب شود.
- logout رسمی جدا log شود.

موارد استفاده:

- owner ببیند معلم‌ها آخرین بار کی وارد شده‌اند.
- معلم ببیند دانش‌آموزان کلاس آنلاین حاضر هستند یا نه.
- Super Admin usage کلی مدارس را ببیند.
- گزارش دانش‌آموز کم‌فعال ساخته شود.

### 11.2 آمار فردی کاربر

برای دانش‌آموز:

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

برای معلم:

- تعداد login
- آخرین فعالیت
- تعداد کلاس‌ها
- تعداد حضور و غیاب ثبت‌شده
- تعداد نمرات ثبت‌شده
- تعداد امتحانات ساخته‌شده
- تعداد SMS ارسال‌شده در صورت permission

برای owner/moaven:

- تعداد عملیات مدیریتی
- تعداد تایید نمره
- تعداد تایید ارسال SMS غیبت
- تعداد export/import

### 11.3 جدول‌های پیشنهادی فعالیت کاربر

- user_sessions
- user_activity_logs
- user_heartbeats
- user_usage_daily

نمونه `user_heartbeats`:

```sql
id
school_id
user_id
last_seen_at
ip_address
user_agent
page
created_at
updated_at
```

نمونه `user_usage_daily`:

```sql
id
school_id
user_id
date
login_count
active_minutes
important_actions_count
created_at
updated_at
```

---

## 12. مدیریت دانش‌آموزان

فیلدها:

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

امکانات:

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

---

## 13. مدیریت معلمان

فیلدها:

- نام
- نام خانوادگی
- موبایل
- کد ملی
- تخصص
- درس‌ها
- کلاس‌ها
- وضعیت

امکانات:

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

---

## 14. کلاس‌ها، پایه‌ها و درس‌ها

### پایه‌ها

مثال:

- اول
- دوم
- سوم
- چهارم
- پنجم
- ششم
- هفتم
- هشتم
- نهم
- دهم
- یازدهم
- دوازدهم

### کلاس‌ها

فیلدها:

- نام کلاس
- پایه
- سال تحصیلی
- ظرفیت
- معلم راهنما اختیاری
- وضعیت

### درس‌ها

فیلدها:

- نام درس
- پایه
- ضریب
- نوع درس
- وضعیت

عملیات:

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

---

## 15. برنامه هفتگی

برنامه هفتگی باید برای:

- مدرسه
- کلاس
- معلم
- دانش‌آموز

قابل مشاهده باشد.

فیلدها:

- روز هفته
- ساعت شروع
- ساعت پایان
- کلاس
- درس
- معلم
- اتاق
- لینک کلاس آنلاین اختیاری

امکانات:

- ساخت برنامه با drag/drop در آینده
- جلوگیری از تداخل ساعت معلم
- جلوگیری از تداخل کلاس
- چاپ برنامه
- خروجی PDF
- نمایش «کلاس‌های امروز»

---

## 16. امتحانات آنلاین

انواع امتحان:

- تستی
- تشریحی
- ترکیبی
- فایل‌محور
- حضوری ثبت نمره

فیلدهای امتحان:

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

سوال‌ها:

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

هنگام آزمون:

- timer
- ذخیره خودکار پاسخ
- جلوگیری از submit دوباره
- نمایش سوالات
- ثبت زمان شروع
- ثبت زمان پایان
- ثبت IP و user agent

بعد آزمون:

- تصحیح خودکار تستی
- تصحیح دستی تشریحی
- ثبت نمره
- گزارش پاسخ‌ها
- تحلیل سوال

---

## 17. نمره‌دهی و کارنامه

### نمره‌دهی

فیلدها:

- دانش‌آموز
- درس
- کلاس
- معلم
- نوع نمره
- نمره
- توضیح
- وضعیت تایید
- تاریخ ثبت

وضعیت‌ها:

- draft
- submitted
- approved
- rejected

قوانین:

- معلم فقط کلاس‌ها و درس‌های خودش را ببیند.
- معاون با permission بتواند ثبت/ویرایش/تایید کند.
- owner بتواند تایید نهایی کند.
- تغییر نمره باید log کامل داشته باشد.

Log تغییر نمره:

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

### کارنامه

انواع:

- ماهانه
- نوبت اول
- نوبت دوم
- سالانه
- سفارشی

امکانات:

- مشاهده آنلاین
- خروجی PDF
- چاپ
- مهر و امضای دیجیتال در آینده
- توضیح معلم
- توضیح مدیر
- نمایش معدل
- نمایش رتبه اختیاری

---

## 18. حضور و غیاب

فیلدها:

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

وضعیت‌ها:

- حاضر
- غایب
- تاخیر
- موجه

امکانات:

- ثبت روزانه
- ثبت برای زنگ مشخص
- گزارش ماهانه
- اطلاع به شماره‌های پدر/مادر در صورت فعال بودن SMS
- خروجی Excel

### 18.1 فرم حضور و غیاب شبیه برگه کلاسی

UI حضور و غیاب باید مثل یک برگه/چارت کلاس باشد؛ همان چیزی که روی کاغذ داخل کلاس می‌آورند، اما دیجیتال.

ویژگی‌ها:

- نمایش نام کلاس، درس، معلم، تاریخ شمسی و ساعت
- نمایش لیست دانش‌آموزان کلاس به شکل جدول یا کارت
- ستون‌های سریع:
  - حاضر
  - غایب
  - تاخیر
  - موجه
  - توضیح
- دکمه «همه حاضر هستند»
- دکمه «ذخیره پیش‌نویس»
- دکمه «ثبت نهایی»
- امکان چاپ برگه خالی برای استفاده کاغذی
- امکان import نتیجه از روی برگه در آینده

حالت موبایل:

- هر دانش‌آموز به شکل card نمایش داده شود.
- دکمه‌های حاضر/غایب بزرگ و سریع باشند.
- برای معلم در کلاس با گوشی راحت باشد.

صفحه frontend:

```text
resources/js/Pages/Attendance/ClassSheet.tsx
```

### 18.2 حضور و غیاب جلسه‌ای

حضور و غیاب فقط روزانه نیست. باید بتواند برای هر جلسه/زنگ هم ثبت شود.

فیلدهای جلسه:

- school_id
- classroom_id
- subject_id
- teacher_id
- schedule_id
- date_jalali
- starts_at
- ends_at
- session_number
- status
- submitted_by
- submitted_at

وضعیت ثبت:

- draft
- submitted
- approved
- rejected

### 18.3 درخواست تایید غیبت و ارسال SMS

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

1. معلم حضور و غیاب کلاس را ثبت می‌کند.
2. سیستم غایبین را تشخیص می‌دهد.
3. برای owner یا معاون مجاز یک درخواست ارسال می‌شود.
4. owner/moaven لیست غایبین را بررسی می‌کند.
5. اگر تایید کرد، SMS به شماره پدر/مادر یا شماره دانش‌آموز غایب ارسال می‌شود.

حالت‌های قابل تنظیم توسط owner:

- ارسال SMS بلافاصله بعد از ثبت غیبت توسط معلم
- ارسال SMS فقط بعد از تایید معاون/owner
- عدم ارسال SMS، فقط ثبت در پنل
- ارسال SMS فقط برای غیبت غیرموجه

قانون:

```text
اگر SMS فعال نباشد یا موجودی کافی نباشد، سیستم فقط درخواست/هشدار ثبت می‌کند و SMS ارسال نمی‌کند.
```

### 18.4 متن پیامک غیبت

template قابل تنظیم:

```text
ولی محترم، دانش‌آموز {student_name} در تاریخ {date} در کلاس {class_name} / درس {subject_name} غایب ثبت شده است. مدرسه {school_name}
```

برای کلاس آنلاین:

```text
ولی محترم، دانش‌آموز {student_name} در کلاس آنلاین {subject_name} حاضر نشده است. مدرسه {school_name}
```

### 18.5 آمار حضور و غیاب دانش‌آموز

برای هر دانش‌آموز:

- تعداد حضور
- تعداد غیبت
- تعداد تاخیر
- تعداد غیبت موجه
- تعداد غیبت غیرموجه
- درصد حضور
- نمودار ماهانه
- جزئیات هر جلسه
- فیلتر بر اساس درس
- فیلتر بر اساس بازه تاریخ شمسی

برای معلم:

- آمار حضور و غیاب کلاس‌های خودش
- دانش‌آموزان پرغیبت
- خروجی Excel

برای owner/moaven:

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

### 18.6 جدول‌های پیشنهادی حضور و غیاب

- attendance_sessions
- attendance_records
- attendance_approval_requests
- attendance_sms_logs

نمونه `attendance_sessions`:

```sql
id
school_id
classroom_id
subject_id
teacher_id
schedule_id
date
starts_at
ends_at
session_number
status
submitted_by
submitted_at
approved_by
approved_at
created_at
updated_at
```

نمونه `attendance_records`:

```sql
id
school_id
attendance_session_id
student_id
status
delay_minutes
note
created_by
updated_by
created_at
updated_at
```

نمونه `attendance_approval_requests`:

```sql
id
school_id
attendance_session_id
requested_by
assigned_to
type
status
absent_count
sms_cost
approved_by
approved_at
rejected_by
rejected_at
created_at
updated_at
```

---

## 19. پیام‌رسانی و اطلاعیه

### پیام‌رسانی

امکانات:

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

### اطلاعیه‌ها

انواع:

- اطلاعیه عمومی مدرسه
- اطلاعیه کلاس
- اطلاعیه قابل ارسال به شماره‌های پدر/مادر با SMS
- اطلاعیه امتحان
- پیام خیلی مهم popup

پیام مهم برای دانش‌آموز:

- بالای داشبورد نمایش داده شود.
- اگر خیلی مهم بود modal باز شود.
- تا زمانی که دیده نشده، badge داشته باشد.

### 19.1 سامانه پیامک SMS

SMS یک ماژول قابل فروش است و فقط برای مدرسه‌هایی فعال می‌شود که Super Admin این ماژول را برایشان فعال کرده باشد.

کاربردهای SMS:

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

قانون اصلی:

```text
هیچ SMS بدون موجودی کیف پول SMS و بدون permission ارسال نمی‌شود.
```

قانون کسر موجودی:

```text
در نسخه اول، هر پیامک موفق به هر گیرنده = کسر 1 واحد از کیف پول SMS مدرسه.
پیامک ناموفق نباید از موجودی نهایی کم شود مگر provider آن را charged گزارش کند.
```

### 19.2 کیف پول SMS مدرسه

هر مدرسه باید یک SMS wallet داشته باشد.

فیلدها:

- موجودی پیامک
- تعداد پیامک مصرف‌شده
- تعداد پیامک رزرو شده
- آخرین شارژ
- وضعیت فعال/غیرفعال

Owner مدرسه باید بتواند:

- موجودی SMS را ببیند.
- مصرف ماهانه را ببیند.
- تاریخچه شارژها را ببیند.
- تاریخچه ارسال‌ها را ببیند.
- بسته شارژ SMS بخرد.
- فاکتور شارژ را ببیند.

Super Admin باید بتواند:

- موجودی SMS مدرسه را افزایش دهد.
- موجودی را اصلاح کند.
- بسته‌های SMS تعریف کند.
- قیمت بسته‌ها را تغییر دهد.
- مصرف همه مدارس را ببیند.
- ارسال‌های ناموفق را بررسی کند.

### 19.3 شارژ SMS

روش‌های شارژ:

- پرداخت آنلاین توسط owner مدرسه
- شارژ دستی توسط Super Admin
- شارژ هدیه/اعتباری توسط Super Admin
- شارژ قراردادی در پلن سازمانی

بسته‌های پیشنهادی:

- 500 پیامک
- 1000 پیامک
- 3000 پیامک
- 5000 پیامک
- بسته سفارشی

قانون پرداخت:

- بعد از پرداخت موفق، موجودی SMS افزایش یابد.
- فاکتور ایجاد شود.
- log ثبت شود.
- اگر پرداخت ناموفق بود، موجودی تغییر نکند.
- owner مدرسه فقط موجودی مدرسه خودش را شارژ می‌کند.
- Super Admin می‌تواند شارژ دستی یا اصلاح موجودی انجام دهد.

### 19.4 ارسال SMS به غایبین

سناریو:

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

قوانین:

- Teacher فقط برای کلاس‌های خودش بتواند SMS غیبت بفرستد.
- Moaven طبق permission بتواند به غایبین کلاس‌ها SMS بفرستد.
- Owner بتواند همه ارسال‌ها را ببیند.
- قبل از ارسال، تعداد گیرندگان و هزینه SMS نمایش داده شود.
- اگر موجودی کافی نیست، ارسال متوقف شود و پیشنهاد شارژ نشان داده شود.
- هر SMS باید log شود.
- اگر تنظیم مدرسه نیاز به تایید دارد، ارسال باید اول به صف تایید owner/moaven برود.
- owner/moaven بتواند درخواست ارسال SMS غیبت را تایید یا رد کند.
- در صورت رد، دلیل رد ثبت شود.
- اگر دانش‌آموز در کلاس آنلاین وارد نشده باشد، سیستم بتواند پیام «عدم حضور در کلاس آنلاین» ارسال کند.

نمونه متن:

```text
ولی محترم، دانش‌آموز {student_name} امروز در کلاس {class_name} غایب ثبت شده است. مدرسه {school_name}
```

نمونه متن برای کلاس آنلاین:

```text
ولی محترم، دانش‌آموز {student_name} در کلاس آنلاین {subject_name} حاضر نشده است. مدرسه {school_name}
```

صف تایید SMS غیبت:

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

permissionهای مرتبط:

- attendance.request_absence_sms
- attendance.approve_absence_sms
- attendance.reject_absence_sms
- attendance.auto_send_absence_sms

### 19.5 Permissionهای SMS

permissionهای پیشنهادی:

- sms.view_wallet
- sms.charge_wallet
- sms.view_logs
- sms.send_to_students
- sms.send_to_student_contacts
- sms.send_to_teachers
- sms.send_to_absents
- sms.send_bulk
- sms.manage_templates
- sms.manage_settings

### 19.6 امنیت و کنترل SMS

- جلوگیری از spam
- rate limit ارسال
- نیاز به تایید owner برای ارسال‌های انبوه بزرگ
- ثبت متن پیام
- ثبت گیرندگان
- ثبت هزینه
- ثبت وضعیت تحویل در صورت پشتیبانی provider
- mask کردن شماره‌ها برای کاربران غیرمجاز
- جلوگیری از ارسال به شماره‌های خارج از مدرسه
- امکان غیرفعال کردن SMS برای کاربر خاطی

### 19.7 جدول‌های پیشنهادی SMS

- sms_wallets
- sms_packages
- invoices
- payments
- sms_wallet_transactions
- sms_messages
- sms_recipients
- sms_templates
- sms_provider_logs

نمونه `sms_wallets`:

```sql
id
school_id
balance
reserved_balance
total_charged
total_used
status
created_at
updated_at
```

نمونه `sms_wallet_transactions`:

```sql
id
school_id
type
amount
balance_before
balance_after
payment_id
created_by
description
created_at
```

نمونه `sms_messages`:

```sql
id
school_id
sender_user_id
target_type
message_body
recipient_count
cost
status
provider_message_id
created_at
```

---

## 20. کلاس آنلاین

نسخه اول:

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

نسخه آینده:

- اتصال به سرویس داخلی یا خارجی
- حضور و غیاب خودکار از روی ورود
- ضبط کلاس
- فایل‌های کلاس
- chat کلاس

---

## 20.1 رأی‌گیری و شورای دانش‌آموزی

Voting یک ماژول قابل فروش است. یعنی Super Admin می‌تواند تصمیم بگیرد یک مدرسه اصلا این قابلیت را داشته باشد یا نه.

هدف:

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

قانون اصلی:

```text
اگر Super Admin ماژول Voting را برای مدرسه فعال نکرده باشد، هیچ کاربر آن مدرسه voting را نمی‌بیند.
```

### 20.1.1 فعال‌سازی Voting توسط Super Admin

Super Admin باید بتواند:

- ماژول Voting را برای مدرسه فعال کند.
- ماژول Voting را برای مدرسه غیرفعال کند.
- محدودیت تعداد رأی‌گیری تعیین کند.
- تاریخ شروع/پایان دسترسی به Voting تعیین کند.
- Voting را به صورت افزونه جداگانه بفروشد.
- ببیند هر مدرسه چند رأی‌گیری برگزار کرده است.
- log تغییرات Voting را ببیند.

### 20.1.2 مدیریت Voting توسط Owner

اگر Voting برای مدرسه فعال بود، owner باید بتواند:

- رأی‌گیری بسازد.
- رأی‌گیری را ویرایش کند.
- کاندیدا تعریف کند.
- زمان شروع و پایان رأی‌گیری را مشخص کند.
- مشخص کند چه کسانی حق رأی دارند.
- رأی‌گیری را publish کند.
- رأی‌گیری را pause یا close کند.
- نتیجه را ببیند.
- نتیجه را برای دانش‌آموزان منتشر کند یا نکند.
- permission ساخت رأی‌گیری را به معاون بدهد.

### 20.1.3 انواع Voting

- شورای دانش‌آموزی
- نماینده کلاس
- نظرسنجی مدرسه
- رأی‌گیری چندگزینه‌ای
- رأی‌گیری تک‌انتخابی
- رأی‌گیری محرمانه
- رأی‌گیری غیرمحرمانه

### 20.1.4 قوانین رأی‌دهی

- هر دانش‌آموز فقط یک بار رأی بدهد.
- رأی بعد از ثبت قابل تغییر نباشد مگر voting اجازه داده باشد.
- رأی‌ها باید قابل audit باشند ولی حریم رأی محرمانه حفظ شود.
- دانش‌آموز فقط رأی‌گیری‌های مجاز خودش را ببیند.
- رأی‌گیری می‌تواند محدود به پایه، کلاس، جنسیت یا گروه خاص باشد.
- Voting فقط برای پایه‌هایی قابل استفاده است که Super Admin برای مدرسه فعال کرده باشد.
- اگر مدرسه فقط پایه 9 تا 12 را خریده باشد، owner فقط برای پایه‌های 9، 10، 11 و 12 رأی‌گیری می‌سازد.
- شروع و پایان رأی‌گیری سمت server کنترل شود.
- نتایج تا قبل از پایان رأی‌گیری مخفی باشد مگر owner خلافش را تنظیم کند.

### 20.1.5 Candidate / کاندیدا

فیلدهای کاندیدا:

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

### 20.1.6 Permissionهای Voting

- voting.view
- voting.create
- voting.edit
- voting.delete
- voting.publish
- voting.pause
- voting.close
- voting.view_results
- voting.export_results
- voting.manage_candidates
- voting.vote
- voting.limit_by_grade
- voting.limit_by_class

قانون:

- `voting.vote` برای دانش‌آموزان واجد شرایط داده می‌شود.
- `voting.create` و `voting.publish` فقط برای owner یا کاربران مجاز.
- دیدن نتیجه باید permission جدا داشته باشد.

### 20.1.7 امنیت Voting

- جلوگیری از رأی تکراری
- جلوگیری از رأی دادن خارج از بازه زمانی
- جلوگیری از رأی دادن برای رأی‌گیری مدرسه دیگر
- ثبت IP و user agent در حد لازم
- school scope کامل
- محدود کردن نتایج برای کاربران غیرمجاز
- جلوگیری از تغییر کاندیدا بعد از شروع رأی‌گیری مگر با permission خاص
- log کامل publish، close و تغییرات حساس

### 20.1.8 جدول‌های پیشنهادی Voting

- votings
- voting_candidates
- voting_eligible_voters
- voting_votes
- voting_results_snapshots
- voting_logs

نمونه `votings`:

```sql
id
school_id
title
description
type
is_secret
starts_at
ends_at
status
created_by
published_by
published_at
closed_at
created_at
updated_at
```

نمونه `voting_votes`:

```sql
id
school_id
voting_id
candidate_id
student_id
vote_hash
ip_address
user_agent
created_at
```

برای رأی‌گیری محرمانه، باید طوری طراحی شود که نتیجه قابل شمارش باشد ولی رأی دانش‌آموز تا حد ممکن مستقیم قابل افشا نباشد.

---

## 21. فایل‌ها و upload

انواع فایل:

- عکس پروفایل
- لوگوی مدرسه
- فایل تکلیف
- فایل پاسخ امتحان
- فایل اطلاعیه
- فایل پیام

امنیت upload:

- محدودیت extension
- محدودیت MIME
- محدودیت حجم
- نام فایل random
- ذخیره فایل‌های حساس خارج از دسترسی مستقیم public
- بررسی permission هنگام دانلود
- جلوگیری از اجرای PHP در uploads

---

## 22. دیتابیس پیشنهادی

فایل اصلی:

```text
database/schema.sql
```

قانون دیتابیس:

```text
در این فاز یک schema اصلی داریم: database/schema.sql
هر بار ساختار تغییر کرد، همین یک فایل به‌روزرسانی می‌شود و روی دیتابیس replace/import می‌شود.
بعدا اگر پروژه production شد، migrationهای مرحله‌ای هم نگهداری می‌شوند.
```

قانون تاریخ:

- تاریخ‌های نمایشی و ورودی کاربر شمسی هستند.
- نمونه سال فعلی پروژه: `1405`.
- ستون‌های دیتابیس برای زمان دقیق می‌توانند Gregorian timestamp باشند، اما UI همیشه Jalali نشان می‌دهد.
- اگر نیاز به ذخیره تاریخ شمسی خام باشد، ستون جدا مثل `date_jalali` نگهداری می‌شود.

جدول‌های اصلی:

- users
- schools
- licenses
- plans
- modules
- module_dependencies
- school_modules
- school_module_limits
- school_module_logs
- permission_dependencies
- permission_packages
- permission_package_items
- school_permissions
- school_settings
- roles
- permissions
- user_permissions
- students
- teachers
- academic_years
- grade_levels
- school_grade_levels
- classrooms
- subjects
- class_students
- class_teachers
- schedules
- exams
- exam_questions
- exam_options
- exam_sessions
- exam_answers
- grades
- report_cards
- attendance
- attendance_sessions
- attendance_records
- attendance_approval_requests
- attendance_sms_logs
- messages
- message_recipients
- announcements
- online_classes
- sms_wallets
- sms_packages
- sms_wallet_transactions
- sms_messages
- sms_recipients
- sms_templates
- sms_provider_logs
- votings
- voting_candidates
- voting_eligible_voters
- voting_votes
- voting_results_snapshots
- voting_logs
- files
- audit_logs
- user_sessions
- user_activity_logs
- user_heartbeats
- user_usage_daily
- login_logs
- password_resets
- notifications
- imports
- exports

قانون tenant:

تقریبا همه جدول‌های مدرسه‌ای باید `school_id` داشته باشند تا داده‌های هر مدرسه جدا بماند.

### 22.1 Import / Export با فرمت اختصاصی CSV

سیستم باید import و export تمیز داشته باشد، مخصوصا برای کاربران، دانش‌آموزان، معلمان، رأی‌گیری‌ها و گزارش‌های مدرسه.

قانون اصلی:

```text
هر import باید template رسمی داشته باشد و هر export باید قابل دانلود در CSV و در صورت نیاز Excel/PDF باشد.
```

### 22.1.1 فرمت CSV اختصاصی دانش‌آموزان

فایل template:

```text
documentation/templates/students-import-template.csv
```

ستون‌های پیشنهادی:

```csv
student_code,first_name,last_name,national_code,mobile,father_mobile,mother_mobile,home_phone,birth_date_jalali,gender,grade_level,classroom_name,address,status
```

قوانین:

- `student_code` داخل مدرسه یکتا باشد.
- `national_code` اگر وارد شد validate شود.
- `mobile`, `father_mobile`, `mother_mobile` و `home_phone` باید فرمت معتبر ایران داشته باشند.
- `birth_date_jalali` با فرمت `1403/07/01` باشد.
- `classroom_name` اگر وجود نداشت، بسته به تنظیم مدرسه ساخته شود یا خطا بدهد.
- import باید preview داشته باشد.
- ردیف‌های خطادار باید جدا نشان داده شوند.
- import نهایی باید log داشته باشد.

نمونه CSV دانش‌آموزان:

```csv
student_code,first_name,last_name,national_code,mobile,father_mobile,mother_mobile,home_phone,birth_date_jalali,gender,grade_level,classroom_name,address,status
STU-1001,علی,رضایی,0012345678,09121234567,09129876543,09127654321,02144556677,1390/07/15,male,9,نهم A,تهران - خیابان مثال,active
STU-1002,سارا,محمدی,0012345679,09125554433,09124443322,09123332211,02144332211,1391/02/20,female,8,هشتم B,تهران - خیابان نمونه,active
```

### 22.1.2 فرمت CSV اختصاصی کاربران

فایل template:

```text
documentation/templates/users-import-template.csv
```

ستون‌ها:

```csv
username,first_name,last_name,mobile,email,role,status,temporary_password,password_hash,force_password_change,must_complete_profile
```

قوانین:

- `username` یکتا باشد.
- `role` باید یکی از roleهای مجاز مدرسه باشد.
- اگر `temporary_password` خالی بود، سیستم رمز موقت تولید کند.
- `force_password_change` برای کاربران جدید بهتر است true باشد.
- اگر `temporary_password` وارد شد، سیستم آن را hash می‌کند و سپس در دیتابیس ذخیره می‌کند.
- اگر `password_hash` وارد شد، فقط وقتی قبول شود که با الگوریتم‌های تاییدشده سازگار باشد.
- پیشنهاد امن‌تر: import با `temporary_password` انجام شود و سیستم خودش hash کند.
- پسورد خام هرگز بعد از import نباید در دیتابیس یا log ذخیره شود.
- فایل import بعد از پردازش باید امن نگهداری یا حذف شود چون ممکن است password خام داشته باشد.
- امکان reset password برای هر کاربر باید در پنل owner/moaven مجاز وجود داشته باشد.
- reset password باید گزینه تولید رمز موقت یا ارسال لینک reset داشته باشد.
- بعد از reset، `must_change_password=true` شود.
- reset password باید audit log داشته باشد.

قانون امنیتی مهم:

```text
CSV می‌تواند password خام را برای import اولیه بگیرد، اما database فقط hash ذخیره می‌کند.
```

نمونه CSV کاربران:

```csv
username,first_name,last_name,mobile,email,role,status,temporary_password,password_hash,force_password_change,must_complete_profile
teacher.ahmadi,رضا,احمدی,09121112233,ahmadi@example.com,teacher,active,Tmp@12345,,true,true
moaven.school,مینا,کریمی,09124445566,karimi@example.com,moaven,active,Tmp@98765,,true,true
```

### 22.1.3 فرمت CSV اختصاصی معلمان

فایل template:

```text
documentation/templates/teachers-import-template.csv
```

ستون‌ها:

```csv
teacher_code,first_name,last_name,national_code,mobile,email,subjects,status
```

قوانین:

- `subjects` می‌تواند با `|` جدا شود.
- مثال: `ریاضی|فیزیک|علوم`

نمونه CSV معلمان:

```csv
teacher_code,first_name,last_name,national_code,mobile,email,subjects,status
T-001,رضا,احمدی,0011111111,09121112233,ahmadi@example.com,ریاضی|فیزیک,active
T-002,مریم,اکبری,0022222222,09123334455,akbari@example.com,علوم|زیست,active
```

### 22.1.4 طراحی دکمه‌ها و تجربه import/export

خیلی مهم:

```text
تمام دکمه‌های import/export باید واقعی، functional، هم‌تم با Spring Mint و دارای وضعیت loading/success/error باشند.
```

دکمه‌های لازم:

- دانلود قالب CSV
- انتخاب فایل
- بررسی فایل
- نمایش preview
- نمایش خطاهای ردیف‌ها
- تایید import
- لغو import
- export CSV
- export Excel
- export PDF
- export ZIP
- دانلود خروجی

قواعد طراحی:

- دکمه اصلی با رنگ `--color-primary`
- دکمه ثانویه با border سبز/آبی ملایم
- دکمه خطر با رنگ danger
- loading spinner بدون emoji
- success state با Bootstrap Icon
- error state با پیام فارسی واضح
- جدول preview با همان طراحی dashboard
- هیچ دکمه placeholder یا غیرکاربردی نباید باقی بماند.

### 22.1.5 Export کامل داده‌های مدرسه

Owner مدرسه و Super Admin باید بتوانند export کامل بگیرند.

انواع export:

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

فرمت‌ها:

- CSV برای داده خام
- Excel برای استفاده اداری
- PDF برای گزارش چاپی
- ZIP برای export کامل مدرسه

قانون امنیتی:

- export کامل مدرسه فقط برای owner یا Super Admin مجاز باشد.
- export نمرات و کارنامه‌ها permission جدا داشته باشد.
- export پیام‌ها و audit logs بسیار حساس است و باید log شود.
- فایل export باید زمان‌دار باشد و بعد از مدت مشخص حذف شود.

### 22.1.6 Export رأی‌گیری، کاندیداها و نتایج

Voting باید export کامل داشته باشد.

فایل‌های خروجی:

- `voting-candidates.csv`
- `voting-results.csv`
- `voting-summary.pdf`
- `voting-audit.csv` فقط برای کاربران مجاز

ستون‌های `voting-candidates.csv`:

```csv
voting_title,candidate_name,student_code,classroom_name,total_votes,status
```

ستون‌های `voting-results.csv`:

```csv
voting_title,candidate_name,total_votes,percentage,rank
```

قوانین:

- در voting محرمانه نباید export عادی هویت رأی‌دهنده را افشا کند.
- export جزئیات رأی‌دهنده فقط در حالت غیرمحرمانه و با permission خاص مجاز است.
- خروجی نتایج باید بعد از پایان رأی‌گیری قابل انتشار باشد.

### 22.1.7 جدول‌های import/export

جدول‌های پیشنهادی:

- import_jobs
- import_job_rows
- import_templates
- export_jobs
- export_files

نمونه `import_jobs`:

```sql
id
school_id
type
file_path
status
total_rows
valid_rows
invalid_rows
created_by
started_at
finished_at
created_at
updated_at
```

نمونه `export_jobs`:

```sql
id
school_id
type
format
status
file_path
requested_by
expires_at
created_at
updated_at
```

نمونه ستون‌های audit_logs:

```sql
id
school_id
user_id
user_role
action
entity_type
entity_id
old_value
new_value
description
ip_address
user_agent
created_at
```

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

```sql
id
school_id
student_id
classroom_id
subject_id
teacher_id
exam_id
score
max_score
status
description
created_by
approved_by
approved_at
created_at
updated_at
```

نمونه جدول تغییر نمره:

```sql
id
school_id
grade_id
student_id
subject_id
changed_by
old_score
new_score
reason
ip_address
created_at
```

---

## 23. API و backend

قواعد API:

- همه endpointهای حساس نیاز به auth دارند.
- خروجی API باید JSON باشد.
- خطاها ساختار ثابت داشته باشند.
- validation سمت backend اجباری است.
- school scope باید همیشه بررسی شود.
- نقش و permission باید قبل از عملیات بررسی شود.

نمونه ساختار پاسخ موفق:

```json
{
  "success": true,
  "message": "عملیات با موفقیت انجام شد",
  "data": {}
}
```

نمونه ساختار خطا:

```json
{
  "success": false,
  "message": "دسترسی غیرمجاز",
  "errors": {}
}
```

Endpointهای اولیه:

- `POST /api/auth/login`
- `POST /api/auth/logout`
- `POST /api/auth/forgot-password`
- `GET /api/me`
- `GET /api/schools`
- `POST /api/schools`
- `GET /api/users`
- `POST /api/users`
- `GET /api/students`
- `POST /api/students`
- `POST /api/students/import`
- `GET /api/teachers`
- `POST /api/teachers`
- `GET /api/classes`
- `POST /api/classes`
- `GET /api/schedules`
- `POST /api/schedules`
- `GET /api/exams`
- `POST /api/exams`
- `POST /api/exams/{id}/submit`
- `GET /api/grades`
- `POST /api/grades`
- `POST /api/grades/{id}/approve`
- `GET /api/report-cards`
- `GET /api/attendance`
- `POST /api/attendance`
- `GET /api/messages`
- `POST /api/messages`
- `GET /api/announcements`
- `POST /api/announcements`
- `GET /api/audit-logs`

---

## 24. Frontend و UI

قواعد طراحی:

- RTL کامل
- فونت فارسی تمیز مثل Vazirmatn یا Yekan Bakh
- رنگ روشن
- کارت‌های نرم
- border radius متوسط
- shadow خیلی ملایم
- sidebar واضح
- table قابل خواندن
- فرم‌ها ساده و مرحله‌ای
- بدون emoji
- استفاده از Bootstrap Icons یا SVG اختصاصی
- responsive برای desktop، tablet و mobile
- mobile-first برای صفحات دانش‌آموز و معلم
- آماده برای PWA و نصب روی گوشی

Frontend stack:

```text
React + TypeScript + Inertia.js + Vite
```

قانون مهم:

- React جای HTML را از نظر خروجی نمی‌گیرد؛ React در نهایت HTML واقعی در browser می‌سازد.
- TypeScript جای JavaScript را نمی‌گیرد؛ TypeScript قبل از اجرا به JavaScript امن‌تر build می‌شود.
- CSS همچنان جدا و تمیز نوشته می‌شود.
- فایل‌ها در source جدا می‌مانند.
- Vite در production خروجی optimized داخل `public/build` می‌سازد.
- کاربر URLهای عادی را می‌بیند، مثل `/dashboard`، نه فایل‌های hashدار.

فایل‌های CSS source:

- `resources/css/root.css`: رنگ‌ها، spacing، typography، variables
- `resources/css/landing.css`: landing page
- `resources/css/auth.css`: login و reset password
- `resources/css/dashboard.css`: layout پنل
- `resources/css/forms.css`: inputها و فرم‌ها
- `resources/css/tables.css`: جدول‌ها
- `resources/css/exam.css`: امتحان آنلاین
- `resources/css/pwa.css`: حالت‌های نصب‌شده روی گوشی و offline
- `resources/css/responsive.css`: واکنش‌گرا

فایل‌های TypeScript/React:

- `resources/js/app.tsx`: ورودی اصلی Inertia/React
- `resources/js/bootstrap.ts`: تنظیمات اولیه frontend
- `resources/js/lib/api.ts`: wrapper ارتباط با backend
- `resources/js/lib/validators.ts`: اعتبارسنجی frontend
- `resources/js/lib/persianDate.ts`: تاریخ شمسی
- `resources/js/Components`: componentهای قابل استفاده مجدد
- `resources/js/Pages`: صفحه‌های اصلی

صفحه‌های پیشنهادی React:

- `Pages/Landing/Home.tsx`
- `Pages/Landing/Pricing.tsx`
- `Pages/Landing/Faq.tsx`
- `Pages/Landing/Contact.tsx`
- `Pages/Auth/Login.tsx`
- `Pages/Auth/ForgotPassword.tsx`
- `Pages/Dashboard/Index.tsx`
- `Pages/SuperAdmin/Schools.tsx`
- `Pages/School/Students.tsx`
- `Pages/Teacher/MyClasses.tsx`
- `Pages/Student/Home.tsx`
- `Pages/Exams/ExamBuilder.tsx`
- `Pages/Exams/TakeExam.tsx`
- `Pages/Grades/GradeTable.tsx`
- `Pages/Schedule/ScheduleBuilder.tsx`
- `Pages/Modules/SchoolModules.tsx`
- `Pages/Modules/ModuleStore.tsx`
- `Pages/Sms/Wallet.tsx`
- `Pages/Sms/SendToAbsents.tsx`
- `Pages/Voting/List.tsx`
- `Pages/Voting/Builder.tsx`
- `Pages/Voting/Vote.tsx`
- `Pages/Voting/Results.tsx`

Build:

```bash
npm run dev
npm run build
```

خروجی build:

```text
public/build/
```

---

## 24.1 PWA و Web Application موبایل

هدف:

کاربر بتواند «دانشیار من» را روی موبایل مثل اپلیکیشن نصب کند، مخصوصا دانش‌آموز، معلم و مدیر مدرسه.

فایل‌های PWA:

```text
public/manifest.webmanifest
public/service-worker.js
public/offline.html
resources/js/Components/Pwa/
resources/css/pwa.css
public/assets/images/pwa/
```

امکانات PWA:

- نصب روی Android و desktop browser
- نمایش آیکون اختصاصی «دانشیار من»
- splash screen
- theme color بر اساس Spring Mint
- صفحه offline
- cache کردن assetهای اصلی
- cache کردن landing page
- cache محدود صفحات dashboard فقط در صورت امن بودن
- عدم cache اطلاعات حساس مثل نمرات، پیام‌ها و امتحانات فعال
- پیام «اتصال اینترنت قطع است»
- تشخیص online/offline
- دکمه «نصب دانشیار من» در صورت امکان

قانون امنیتی PWA:

- پاسخ‌های شخصی و حساس نباید به شکل ناامن cache شوند.
- امتحان آنلاین نباید به cache خطرناک وابسته باشد.
- اگر اینترنت قطع شد، submit امتحان باید با پیام واضح مدیریت شود.
- session و token نباید داخل localStorage ناامن ذخیره شوند.

Responsive:

- mobile-first
- sidebar در موبایل تبدیل به bottom navigation یا drawer شود.
- جدول‌ها در موبایل card view شوند.
- فرم‌ها تک‌ستونه شوند.
- امتحان آنلاین در موبایل خوانا و بدون بهم‌ریختگی باشد.
- داشبورد دانش‌آموز و معلم باید با گوشی عالی کار کند.
- landing page باید روی موبایل سبک و سریع باشد.

---

## 25. Security

امنیت برای «دانشیار من» یک بخش جانبی نیست؛ چون سیستم با اطلاعات مدرسه، نمره، کارنامه، پیام، شماره‌های تماس پدر/مادر، دانش‌آموزان و فایل‌ها کار می‌کند. امنیت باید از روز اول داخل معماری باشد.

### 25.1 اصول اجباری امنیت

- password hashing با الگوریتم امن Laravel مثل `bcrypt` یا `argon2id`
- عدم ذخیره password به صورت plain text
- اجبار password قوی برای کاربران مدیریتی
- تغییر اجباری رمز اولیه بعد از اولین ورود
- CSRF protection برای همه فرم‌های web
- XSS protection با escape کردن خروجی‌ها در React و Blade shell
- جلوگیری از SQL injection با Eloquent ORM، Query Builder و prepared statements
- عدم ساخت query با string concatenation
- session security
- secure cookie
- HttpOnly cookie
- SameSite cookie
- HTTPS اجباری در production
- rate limiting
- role based access control
- permission based access control
- school scope isolation
- audit logs
- login logs
- upload validation
- file download authorization
- backup policy
- error logging بدون نمایش اطلاعات حساس
- جلوگیری از directory listing
- جلوگیری از اجرای فایل داخل uploads
- محدودیت حجم request
- validation سمت client و server
- soft delete برای داده‌های حساس
- عدم نمایش stack trace در production

### 25.2 احراز هویت Web با Session

برای dashboard اصلی، روش پیش‌فرض:

```text
Laravel Session Auth
```

قوانین session:

- session cookie باید `HttpOnly` باشد.
- session cookie باید در production فقط روی HTTPS ارسال شود.
- `SameSite=Lax` یا در صورت نیاز دقیق‌تر `Strict` استفاده شود.
- بعد از login باید session id regenerate شود.
- بعد از logout باید session invalidate و tokenها پاک شوند.
- بعد از تغییر password همه sessionهای قبلی کاربر invalidate شوند.
- بعد از reset password همه sessionهای قبلی کاربر invalidate شوند.
- برای نقش‌های حساس مثل Super Admin زمان inactivity کوتاه‌تر باشد.
- remember me فقط اگر لازم شد فعال شود و باید امن پیاده‌سازی شود.

### 25.3 جلوگیری از Session Hijacking

موارد لازم:

- regenerate کردن session id بعد از login
- invalidate کردن session بعد از logout
- استفاده از HTTPS
- استفاده از `Secure`, `HttpOnly`, `SameSite` برای cookie
- محدودیت زمان session
- ثبت IP و user agent در login logs
- تشخیص تغییر شدید user agent یا IP برای کاربران حساس
- امکان مشاهده sessionهای فعال در آینده
- امکان logout از همه دستگاه‌ها
- عدم ذخیره session token در localStorage
- عدم ذخیره اطلاعات حساس در browser storage
- جلوگیری از fixation attack
- rate limit روی login و reset password

### 25.4 JWT و API Tokens

برای dashboard web، session امن Laravel کافی است. اما برای API، PWA پیشرفته، mobile app آینده یا integration، باید token strategy داشته باشیم.

تصمیم فعلی:

- Web dashboard: Laravel Session
- API داخلی ساده: session یا Sanctum
- Mobile app / API خارجی آینده: JWT یا Laravel Sanctum/Passport

قوانین token:

- tokenها نباید plain داخل localStorage ذخیره شوند مگر با تصمیم امنیتی دقیق.
- اگر JWT استفاده شد، عمر access token کوتاه باشد.
- refresh token باید امن، قابل revoke و زمان‌دار باشد.
- token باید شامل role و school scope قابل اعتبارسنجی باشد، اما به اطلاعات داخل token کورکورانه اعتماد نشود.
- هر request حساس باید school access را از دیتابیس هم بررسی کند.
- token revoke برای logout، reset password و تغییر نقش لازم است.
- tokenها باید در audit/security log قابل ردیابی باشند.
- secret key باید داخل `.env` باشد و وارد git نشود.
- rotation برای token secret در آینده پیش‌بینی شود.

### 25.5 جلوگیری از SQL Injection

قوانین:

- استفاده از Eloquent و Query Builder
- استفاده از parameter binding
- ممنوعیت ساخت SQL با چسباندن مستقیم input کاربر
- validation همه inputها قبل از query
- allowlist برای sort، filter و column names
- جلوگیری از raw query مگر با دلیل مشخص
- بررسی import فایل‌ها قبل از ورود به دیتابیس
- محدود کردن دسترسی user دیتابیس به حداقل لازم

نمونه بد:

```php
"SELECT * FROM users WHERE username = '$username'"
```

نمونه درست:

```php
User::where('username', $username)->first();
```

### 25.6 جلوگیری از XSS

قوانین:

- در React داده‌ها به صورت پیش‌فرض escape می‌شوند.
- استفاده نکردن از `dangerouslySetInnerHTML` مگر برای HTML کاملا پاکسازی‌شده
- استفاده از `{{ }}` در Blade shell برای escape خروجی
- عدم استفاده از `{!! !!}` در Blade مگر برای HTML کاملا پاکسازی‌شده
- پاکسازی ورودی‌های rich text
- validation لینک‌ها و فایل‌ها
- Content Security Policy در production
- عدم تزریق مستقیم داده کاربر داخل JavaScript
- اگر لازم شد داده به JS برود، با JSON encoding امن منتقل شود.

### 25.7 CSRF

قوانین:

- همه فرم‌های POST/PUT/PATCH/DELETE باید CSRF token داشته باشند.
- endpointهای web باید middleware CSRF داشته باشند.
- API token-based جدا از CSRF طراحی شود.
- فرم login هم باید CSRF داشته باشد.
- فرم reset password هم باید CSRF داشته باشد.

### 25.8 Rate Limiting و Anti Brute Force

باید محدودیت داشته باشیم روی:

- login
- forgot password
- reset password
- ارسال پیام
- upload فایل
- submit امتحان
- APIهای حساس
- import دانش‌آموزان

قوانین:

- بعد از تلاش ناموفق زیاد، login موقتا قفل شود.
- Super Admin از تلاش‌های مشکوک مطلع شود.
- IPهای مشکوک log شوند.
- پیام خطا نباید بگوید username درست است یا password غلط؛ پیام باید عمومی باشد.

### 25.9 Authorization، Role و Permission

امنیت فقط login نیست. هر عملیات باید permission چک کند.

لایه‌های دسترسی:

- role
- permission
- school scope
- owner/admin scope
- teacher class scope
- student self scope

قوانین:

- Super Admin دسترسی global دارد.
- Owner فقط مدرسه خودش را مدیریت می‌کند.
- Moaven فقط طبق permission عمل می‌کند.
- Teacher فقط کلاس‌ها و درس‌های خودش را می‌بیند.
- Student فقط اطلاعات خودش را می‌بیند.
- هر endpoint حساس باید policy یا middleware داشته باشد.

### 25.10 School Scope Isolation

قانون طلایی:

```text
هیچ کاربر مدرسه‌ای نباید بتواند داده مدرسه دیگر را ببیند یا تغییر دهد.
```

موارد لازم:

- بیشتر جدول‌ها باید `school_id` داشته باشند.
- queryهای مدرسه‌ای باید همیشه با `school_id` محدود شوند.
- middleware یا global scope برای school isolation ساخته شود.
- import، export، report و download هم باید school scoped باشند.
- حتی اگر ID دستی در URL تغییر کرد، دسترسی باید fail شود.

### 25.11 امنیت فایل و Upload

قوانین:

- محدودیت extension
- محدودیت MIME type
- محدودیت حجم
- تغییر نام فایل به نام random
- ذخیره فایل‌های حساس خارج از public direct access
- download فقط از طریق controller امن
- بررسی permission قبل از download
- ممنوعیت اجرای PHP داخل uploads
- اسکن پایه برای فایل‌های خطرناک
- جلوگیری از path traversal مثل `../`
- جلوگیری از overwrite فایل
- ثبت log برای uploadهای حساس

### 25.12 امنیت امتحان آنلاین

موارد لازم:

- جلوگیری از شرکت دوباره بدون اجازه
- ذخیره زمان شروع و پایان
- محدودیت زمان سمت server، نه فقط JS
- ثبت IP و user agent
- جلوگیری از submit بعد از پایان زمان
- جلوگیری از تغییر answer متعلق به دانش‌آموز دیگر
- تصحیح خودکار تستی سمت server
- سوالات فقط برای دانش‌آموزان مجاز نمایش داده شود.
- فایل پاسخ فقط برای معلم/مدیر مجاز قابل دانلود باشد.
- auto-save باید امن و school scoped باشد.

### 25.13 امنیت نمره و کارنامه

قوانین:

- تغییر نمره همیشه log شود.
- log باید شامل old score و new score باشد.
- دلیل تغییر نمره برای تغییرات حساس لازم است.
- معلم فقط نمره کلاس/درس خودش را ثبت کند.
- تایید نهایی نمره فقط با permission انجام شود.
- بعد از تایید نهایی، ویرایش نیاز به permission جدا داشته باشد.
- دانش‌آموز فقط نمرات خودش را ببیند.
- خروجی PDF کارنامه باید permission check داشته باشد.

### 25.14 Audit Logs

مواردی که باید log شوند:

- login موفق
- login ناموفق
- logout
- reset password
- تغییر password
- تکمیل پروفایل اولین ورود
- تغییر شماره موبایل پدر/مادر
- import کاربر با password موقت
- reset password توسط owner/moaven
- ایجاد کاربر
- تغییر نقش
- تغییر permission
- ایجاد مدرسه
- تغییر license
- فعال/غیرفعال کردن مدرسه
- فعال/غیرفعال کردن ماژول مدرسه
- تغییر limit ماژول مدرسه
- تغییر dependency ماژول
- خرید یا درخواست فعال‌سازی ماژول
- شارژ کیف پول SMS
- اصلاح دستی موجودی SMS
- ارسال SMS انبوه
- ارسال SMS به غایبین
- تایید درخواست ارسال SMS غیبت
- رد درخواست ارسال SMS غیبت
- خطای ارسال SMS
- ثبت حضور و غیاب
- تغییر حضور و غیاب
- تایید حضور و غیاب
- رد حضور و غیاب
- ثبت عدم حضور در کلاس آنلاین
- ایجاد رأی‌گیری
- publish رأی‌گیری
- pause رأی‌گیری
- close رأی‌گیری
- تغییر کاندیدای رأی‌گیری
- مشاهده/خروجی نتایج رأی‌گیری توسط کاربر مدیریتی
- import دانش‌آموزان
- export اطلاعات
- upload فایل حساس
- download فایل حساس
- ایجاد امتحان
- تغییر امتحان
- submit امتحان
- ثبت نمره
- تغییر نمره
- تایید نمره
- رد نمره
- صدور کارنامه
- حذف یا غیرفعال‌سازی رکورد حساس

فیلدهای log:

- `id`
- `school_id`
- `user_id`
- `user_role`
- `action`
- `entity_type`
- `entity_id`
- `old_value`
- `new_value`
- `description`
- `ip_address`
- `user_agent`
- `created_at`

### 25.15 Security Headers

در production باید تنظیم شوند:

- `Content-Security-Policy`
- `X-Frame-Options`
- `X-Content-Type-Options`
- `Referrer-Policy`
- `Permissions-Policy`
- `Strict-Transport-Security`

هدف:

- کاهش XSS
- جلوگیری از clickjacking
- جلوگیری از MIME sniffing
- اجبار HTTPS
- محدودسازی دسترسی browser APIها

### 25.16 Environment و Secrets

قوانین:

- اطلاعات حساس فقط داخل `.env`
- `.env` نباید وارد git شود.
- database password، app key، jwt secret، sms api key، mail password داخل `.env`
- APP_DEBUG در production باید false باشد.
- APP_ENV در production باید production باشد.
- backup از `.env` باید امن باشد.

### 25.17 Backup و Recovery

موارد لازم:

- backup منظم دیتابیس
- backup فایل‌های upload
- encryption برای backupهای حساس
- تست restore
- محدودیت دسترسی به backup
- نگهداری نسخه‌های مختلف backup
- ثبت log برای export/backup دستی

### 25.18 PWA Security

قوانین:

- اطلاعات حساس در cache عمومی ذخیره نشود.
- service worker نباید responseهای خصوصی را بدون کنترل cache کند.
- logout باید cacheهای حساس را پاک کند.
- صفحه offline عمومی باشد و داده خصوصی نمایش ندهد.
- token و session داخل localStorage ناامن ذخیره نشود.

### 25.19 Checklist امنیتی قبل از production

- [ ] HTTPS فعال است.
- [ ] APP_DEBUG=false است.
- [ ] `.env` امن است.
- [ ] session cookie امن است.
- [ ] CSRF همه فرم‌ها فعال است.
- [ ] rate limit login فعال است.
- [ ] SQL injection تست شده است.
- [ ] XSS تست شده است.
- [ ] school scope تست شده است.
- [ ] teacher class scope تست شده است.
- [ ] upload امنیتی تست شده است.
- [ ] download permission تست شده است.
- [ ] audit log تغییر نمره تست شده است.
- [ ] reset password امن است.
- [ ] session hijacking defenses فعال است.
- [ ] backup و restore تست شده است.
- [x] security headers تنظیم شده‌اند.
- [ ] PWA cache اطلاعات حساس را ذخیره نمی‌کند.

موارد امنیتی حساس:

- دانش‌آموز مدرسه A نباید هیچ داده‌ای از مدرسه B ببیند.
- معلم فقط کلاس‌های خودش را ببیند.
- معاون فقط طبق permission عمل کند.
- تغییر نمره بدون log ممنوع.
- حذف hard delete برای داده‌های حساس ممنوع؛ از soft delete استفاده شود.

---

## 26. گزارش‌ها

گزارش‌های Super Admin:

- مدارس فعال
- مدارس نزدیک پایان license
- استفاده سیستم
- ورود کاربران
- خطاها
- درآمد
- تعداد کاربران کل سیستم
- تعداد دانش‌آموزان کل سیستم
- مصرف SMS همه مدارس
- شارژ SMS همه مدارس
- ماژول‌های فعال هر مدرسه
- درآمد از فروش ماژول‌ها
- usage هر مدرسه
- نمودار رشد مدارس
- نمودار رشد دانش‌آموزان
- نمودار استفاده از امتحانات آنلاین
- نمودار رأی‌گیری‌های برگزار شده

گزارش‌های مدرسه:

- آمار دانش‌آموزان
- آمار کلاس‌ها
- عملکرد معلمان
- نمرات کلاس
- کارنامه‌ها
- غیبت‌ها
- امتحانات
- پیام‌ها
- فعالیت کاربران
- مصرف SMS مدرسه
- موجودی SMS مدرسه
- شارژهای SMS مدرسه
- ماژول‌های فعال مدرسه
- میزان استفاده از هر ماژول
- storage مصرف‌شده
- تعداد فایل‌های upload شده
- تعداد login کاربران
- تعداد رأی‌گیری‌ها
- نتایج رأی‌گیری‌ها
- تعداد تکالیف ثبت‌شده
- تعداد تکالیف تحویل‌شده

گزارش‌های معلم:

- کلاس‌های من
- نمرات درس من
- امتحانات من
- تکالیف من
- حضور و غیاب کلاس‌های من

### 26.1 Dashboard Charts

داشبوردها باید نمودار داشته باشند، اما نمودارها نباید شلوغ و بی‌مصرف باشند.

نمودارهای Super Admin:

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

نمودارهای Owner:

- تعداد دانش‌آموزان، معلمان، کلاس‌ها
- حضور و غیاب امروز
- روند غیبت‌ها در ماه
- میانگین نمرات کلاس‌ها
- مصرف SMS ماه جاری
- موجودی SMS
- usage ماژول‌ها
- تعداد امتحانات برگزارشده
- تعداد تکالیف تحویل‌نشده
- نتایج رأی‌گیری‌ها
- فضای ذخیره‌سازی مصرف‌شده

نمودارهای Teacher:

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

نمودارهای Student:

- روند نمرات
- تکالیف انجام‌شده
- غیبت‌ها
- امتحانات آینده

### 26.2 Export Center

باید یک مرکز خروجی داشته باشیم:

```text
Reports → Export Center
```

امکانات:

- انتخاب نوع داده
- انتخاب بازه تاریخ شمسی
- انتخاب فرمت CSV/Excel/PDF/ZIP
- preview قبل از export
- صف export برای داده‌های سنگین
- نمایش status: pending, processing, completed, failed
- دانلود فایل خروجی
- حذف خودکار فایل‌های قدیمی

موارد قابل export:

- کاربران
- دانش‌آموزان
- معلمان
- کلاس‌ها
- درس‌ها
- نمرات
- کارنامه‌ها
- حضور و غیاب
- امتحانات
- تکالیف
- SMS logs
- SMS wallet transactions
- رأی‌گیری‌ها
- کاندیداها
- نتایج رأی‌گیری
- audit logs
- usage report مدرسه

### 26.3 توضیح Audit برای کاربران سیستم

Audit یعنی «گزارش دقیق اتفاقات مهم سیستم».

مثال ساده:

```text
چه کسی؟
چه کاری انجام داد؟
روی چه چیزی؟
قبلش چه بود؟
بعدش چه شد؟
چه زمانی؟
از چه IP؟
```

مثال تغییر نمره:

```text
معلم ریاضی نمره علی رضایی را از 16 به 18 تغییر داد.
دلیل: بررسی دوباره پاسخ تشریحی.
زمان: 1403/09/12 ساعت 10:34
```

Audit برای دانش‌آموزان نمایش داده نمی‌شود. این بخش برای Super Admin، owner و کاربران مدیریتی مجاز است.

---

## 27. تست‌ها

### تست UI

- landing در desktop
- landing در mobile
- login
- dashboard sidebar
- فرم‌ها
- جدول‌ها
- RTL
- فونت
- رنگ‌ها

### تست Backend

- login
- logout
- permission
- school scope
- CRUD کاربران
- CRUD مدرسه
- امتحان آنلاین
- ثبت نمره
- تغییر نمره و log
- پیام‌رسانی
- upload

### تست امنیت

- SQL injection
- XSS
- CSRF
- دسترسی بین مدارس
- download فایل بدون permission
- brute force login
- session fixation

### تست دیتابیس

- foreign keys
- indexes
- unique constraints
- seed data
- migration rollback در آینده

---

## 28. Bootstrap Icons

قانون:

- در UI از emoji استفاده نمی‌کنیم.
- Bootstrap Icons باید داخل پروژه import شود.
- مسیر پیشنهادی:

```text
assets/icons/bootstrap-icons/
```

کاربرد:

- sidebar
- buttons
- cards
- alerts
- empty states
- tables

اگر آیکون اختصاصی ساختیم:

```text
assets/icons/custom/
```

---

## 28.1 Apache Webserver و Production Build

هدف:

خروجی پروژه باید روی Apache webserver واقعی اجرا شود. کاربر فقط سایت را باز می‌کند؛ کنار آن چیز جداگانه‌ای لازم نیست. Backend با PHP/Laravel اجرا می‌شود و assetهای React/TypeScript از قبل با Vite build شده‌اند.

### معماری اجرا روی Apache

```text
Apache
└── DocumentRoot -> /path/to/Daneshyar/public
    ├── index.php
    ├── build/
    ├── assets/
    ├── manifest.webmanifest
    └── service-worker.js
```

نکته حیاتی:

- DocumentRoot باید روی `public` باشد، نه root پروژه.
- فایل `.env` نباید از web قابل دسترسی باشد.
- فولدرهای `app`, `storage`, `vendor`, `database`, `resources` نباید مستقیم public باشند.

### URL کاربران

کاربران این‌ها را باز می‌کنند:

```text
/
/login
/dashboard
/exams
/grades
/schedule
```

آن‌ها فایل‌های build مثل این را مستقیم باز نمی‌کنند:

```text
/build/assets/app-a83kd.js
```

این فایل‌ها فقط توسط browser در پشت صحنه load می‌شوند.

### نیازمندی‌های سرور

- Apache 2.4+
- PHP نسخه مناسب Laravel انتخابی
- MySQL یا MariaDB
- Composer
- Node.js فقط برای build، نه الزام runtime
- فعال بودن `mod_rewrite`
- SSL/HTTPS

PHP extensions مورد نیاز:

- `mbstring`
- `openssl`
- `pdo`
- `pdo_mysql`
- `tokenizer`
- `xml`
- `ctype`
- `json`
- `fileinfo`
- `curl`
- `zip`
- `intl`
- `bcmath`

### Build در production

فرآیند استاندارد:

```bash
composer install --no-dev --optimize-autoloader
npm ci
npm run build
php artisan migrate --force
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan storage:link
```

اگر روی سرور Node.js نداشتیم:

- build روی سیستم توسعه یا CI انجام می‌شود.
- فولدر `public/build` همراه پروژه upload می‌شود.
- روی سرور فقط PHP/Apache/Laravel اجرا می‌شود.

### Python build scripts

برای اینکه build تکرارپذیر باشد، فولدر `scripts` داریم:

```text
scripts/build.py
scripts/apache_ready_check.py
scripts/package_for_apache.py
scripts/server_setup_ubuntu_apache.sh
scripts/DEPLOY_APACHE.md
```

کاربرد:

```bash
python scripts/build.py --production --optimize
python scripts/apache_ready_check.py
python scripts/package_for_apache.py
```

برای سرور فعلی، SSH روی port `2435` است:

```bash
ssh -p 2435 root@91.107.131.171
```

پسورد سرور نباید داخل فایل، command یا log ذخیره شود. ورود production باید با وارد کردن دستی پسورد یا بهتر از آن با SSH key انجام شود.

### Apache VirtualHost نمونه

```apache
<VirtualHost *:80>
    ServerName mydaneshyar.ir
    ServerAlias www.mydaneshyar.ir dashboard.mydaneshyar.ir

    DocumentRoot /var/www/daneshyar/public

    <Directory /var/www/daneshyar/public>
        AllowOverride All
        Require all granted
        Options -Indexes
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/daneshyar_error.log
    CustomLog ${APACHE_LOG_DIR}/daneshyar_access.log combined
</VirtualHost>
```

در production باید SSL فعال شود:

```bash
sudo certbot --apache -d mydaneshyar.ir -d www.mydaneshyar.ir -d dashboard.mydaneshyar.ir
```

### فایل `.htaccess`

Laravel داخل `public/.htaccess` rewrite لازم را دارد. باید مطمئن شویم:

- requestهای frontend مثل `/dashboard` به `public/index.php` برسند.
- assetهای build مثل `/build/assets/...` مستقیم serve شوند.
- directory listing خاموش باشد.

### Permissionهای سرور

فولدرهای قابل نوشتن:

```text
storage/
bootstrap/cache/
```

نمونه:

```bash
sudo chown -R www-data:www-data storage bootstrap/cache
sudo chmod -R 775 storage bootstrap/cache
```

### Cloudflare / CDN

Cloudflare مشکلی با این معماری ندارد.

قوانین cache:

- cache کردن `public/build/assets/*`: بله
- cache کردن تصاویر عمومی landing: بله
- cache کردن landing page: با احتیاط
- cache کردن dashboard private pages: نه
- cache کردن API private responses: نه
- cache کردن login/reset password: نه

Header پیشنهادی برای assetهای build:

```text
Cache-Control: public, max-age=31536000, immutable
```

Header پیشنهادی برای صفحات private:

```text
Cache-Control: no-store, private
```

### Production Checklist

- [ ] Apache نصب است.
- [ ] PHP extensions نصب هستند.
- [ ] `mod_rewrite` فعال است.
- [x] DocumentRoot روی `public` است.
- [ ] HTTPS فعال است.
- [ ] `.env` امن و خارج از public است.
- [ ] `APP_ENV=production`
- [ ] `APP_DEBUG=false`
- [ ] `composer install --no-dev` اجرا شده است.
- [ ] `npm run build` اجرا شده است.
- [x] `public/build` وجود دارد.
- [ ] migration اجرا شده است.
- [ ] storage و bootstrap/cache قابل نوشتن هستند.
- [ ] `php artisan config:cache` اجرا شده است.
- [ ] `php artisan route:cache` اجرا شده است.
- [ ] `php artisan view:cache` اجرا شده است.
- [ ] PWA manifest و service worker تست شده‌اند.
- [ ] صفحات dashboard توسط Cloudflare cache نمی‌شوند.
- [ ] login و reset password cache نمی‌شوند.

---

## 29. مراحل اجرای پروژه

### Phase 0: تصمیم طراحی

- [x] انتخاب پالت رنگی: Spring Mint
- [x] انتخاب فونت: Vazirmatn
- [ ] نهایی کردن logo direction
- [ ] نهایی کردن نام صفحات
- [x] انتخاب backend: Laravel
- [x] انتخاب frontend: React
- [x] انتخاب زبان frontend: TypeScript
- [x] انتخاب bridge: Inertia.js
- [x] انتخاب build tool: Vite
- [x] استفاده از Blade فقط برای root shell لاراول
- [x] اضافه شدن PWA به scope پروژه
- [x] هدف deployment: Apache webserver

### Phase 1: اسکلت پروژه

- [x] ساخت ساختار فولدرها
- [x] ساخت همه فایل‌های بخش 6.1 در جای درست
- [x] نصب Laravel داخل همین فولدر `Daneshyar`
- [x] نصب Laravel Breeze یا setup مناسب Inertia + React + TypeScript
- [x] ساخت `vite.config.ts`
- [x] ساخت `tsconfig.json`
- [x] ساخت `package.json`
- [x] ساخت routeهای اولیه در `routes/web.php`
- [x] ساخت routeهای API در `routes/api.php`
- [x] ساخت `resources/views/app.blade.php`
- [x] ساخت `resources/js/app.tsx`
- [x] ساخت `resources/js/Pages/Landing/Home.tsx`
- [x] ساخت `resources/js/Pages/Auth/Login.tsx`
- [x] ساخت `resources/css/root.css`
- [x] ساخت `resources/js/lib/api.ts`
- [x] ساخت `public/manifest.webmanifest`
- [x] ساخت `public/service-worker.js`
- [x] ساخت `public/offline.html`
- [x] ساخت `database/schema.sql`
- [x] ساخت Python build scripts داخل `scripts`
- [ ] ساخت documentation اولیه برای import/export و Apache

### Phase 2: Landing Page

- [x] header
- [x] hero
- [x] features
- [x] pricing
- [x] FAQ
- [x] contact
- [x] footer
- [x] responsive

### Phase 3: Auth

- [x] login API
- [x] logout API
- [x] forgot password
- [x] session
- [x] rate limit
- [x] login logs
- [x] صفحه تکمیل اطلاعات در اولین ورود
- [x] middleware جلوگیری از ورود کاربر با پروفایل ناقص به پنل
- [x] forced password change برای رمزهای import شده یا reset شده
- [x] reset password برای کاربران توسط owner/moaven مجاز
- [x] heartbeat آنلاین/آفلاین کاربر

### Phase 4: Super Admin

- [x] داشبورد
- [x] مدیریت مدارس
- [x] مدیریت license
- [x] مدیریت ماژول‌های قابل فروش
- [x] فعال/غیرفعال کردن ماژول‌ها برای هر مدرسه
- [x] تعریف dependency برای ماژول‌ها
- [x] تعریف limit برای هر ماژول مدرسه
- [x] مدیریت ownerها
- [x] logs
- [x] reports
- [x] نمودارهای usage کل سیستم
- [x] نمودار مصرف SMS مدارس
- [x] نمودار درآمد module/license/SMS
- [x] export داده‌های هر مدرسه توسط Super Admin

### Phase 5: School Dashboard

- [x] owner dashboard
- [x] تنظیمات مدرسه
- [x] کاربران
- [x] معاون‌ها و permissions
- [x] دانش‌آموزان
- [x] معلمان
- [x] کلاس‌ها
- [x] درس‌ها
- [x] نمودار تعداد کاربران مدرسه
- [x] نمودار usage مدرسه
- [x] نمایش ماژول‌های فعال مدرسه
- [x] مرکز خرید/درخواست فعال‌سازی ماژول‌ها
- [x] آمار آنلاین/آفلاین کاربران مدرسه
- [x] آمار فعالیت هر کاربر
- [x] گزارش دانش‌آموزان پرغیبت
- [x] تنظیم فیلدهای اجباری تکمیل پروفایل

### Phase 6: Academic Modules

- [x] برنامه هفتگی
- [x] امتحانات آنلاین
- [x] نمره‌دهی
- [x] تایید نمره
- [x] کارنامه
- [x] حضور و غیاب
- [x] فرم حضور و غیاب شبیه برگه کلاسی
- [x] حضور و غیاب جلسه‌ای
- [x] حضور و غیاب کلاس آنلاین
- [x] صف تایید ارسال SMS غیبت
- [x] آمار حضور/غیاب/تاخیر دانش‌آموز
- [x] نمودار غیبت ماهانه
- [x] خروجی حضور و غیاب — CSV

### Phase 7: Communication

- [x] پیام‌رسانی
- [x] اطلاعیه
- [x] پیام مهم popup
- [x] فایل‌ها
- [x] سامانه SMS
- [x] کیف پول SMS مدرسه
- [x] شارژ SMS توسط Super Admin
- [x] ارسال SMS به غایبین
- [x] تایید/رد درخواست SMS غیبت توسط owner/moaven
- [ ] ارسال SMS عدم حضور در کلاس آنلاین
- [x] log مصرف SMS
- [x] templateهای SMS
- [ ] هشدار کم بودن موجودی SMS (background job)

### Phase 8: Online Class

- [x] ثبت لینک کلاس
- [x] نمایش در برنامه (student dashboard join links)
- [x] ورود دانش‌آموز (link-based join)
- [x] log ورود به کلاس آنلاین

### Phase 8.1: Voting و شورای دانش‌آموزی

- [x] ماژول Voting قابل فروش توسط Super Admin
- [x] فعال/غیرفعال‌سازی Voting برای مدرسه
- [x] ساخت رأی‌گیری توسط owner یا کاربر مجاز
- [x] تعریف کاندیدا
- [x] تعریف واجدان رأی
- [x] رأی‌دهی دانش‌آموز
- [x] جلوگیری از رأی تکراری
- [x] نمایش نتایج طبق permission
- [x] خروجی نتایج
- [x] log کامل رأی‌گیری

### Phase 9: Reports and Export

- [x] گزارش‌ها
- [x] PDF — کارنامه PDF با DomPDF و قالب Spring Mint
- [x] Excel — خروجی xlsx دانش‌آموزان، معلمان و کاربران با Maatwebsite Excel
- [x] print styles
- [x] Export Center
- [x] export کاربران — CSV + xlsx
- [x] export دانش‌آموزان — CSV + xlsx
- [x] export معلمان — CSV + xlsx
- [x] export داده کامل مدرسه
- [x] export SMS usage
- [x] export کاندیداهای رأی‌گیری
- [x] export نتایج رأی‌گیری
- [x] import دانش‌آموزان با CSV اختصاصی
- [x] import کاربران با CSV اختصاصی
- [x] hash کردن passwordهای import شده از CSV
- [x] حذف/امن‌سازی فایل import دارای password خام
- [x] import معلمان با CSV اختصاصی
- [x] preview و validation قبل از import
- [ ] queue برای export/import سنگین

### Phase 10: Security and Polish

- [ ] audit کامل
- [ ] تست امنیت
- [ ] تست PWA
- [ ] تست install روی گوشی
- [ ] تست offline page
- [ ] بهینه‌سازی performance
- [ ] responsive نهایی
- [ ] مستندات نصب
- [ ] backup strategy

### Phase 11: Build و Apache Deployment

- [ ] اجرای `python scripts/build.py --production --optimize`
- [x] اجرای `python scripts/apache_ready_check.py`
- [ ] اجرای `python scripts/package_for_apache.py`
- [x] بررسی وجود `public/build`
- [x] بررسی `public/index.php`
- [x] بررسی `public/.htaccess`
- [x] تنظیم Apache DocumentRoot روی `public`
- [ ] فعال کردن `mod_rewrite`
- [x] تنظیم permissionهای `storage` و `bootstrap/cache`
- [ ] اجرای migration روی production
- [ ] فعال کردن HTTPS
- [ ] تنظیم Cloudflare cache فقط برای static assets
- [ ] تست `/`, `/login`, `/dashboard`
- [ ] تست PWA روی موبایل

---

## 30. ایده‌های اضافه برای آینده

- اپلیکیشن موبایل
- پیامک
- اعلان مرورگر
- پرداخت آنلاین
- کیف پول مدرسه
- امضای دیجیتال کارنامه
- هوش مصنوعی برای تحلیل عملکرد دانش‌آموز
- پیشنهاد تمرین برای دانش‌آموز
- تشخیص افت تحصیلی
- ticketing پشتیبانی
- تقویم آموزشی
- مدیریت انضباطی
- فرم‌های نظرسنجی
- سیستم مشاوره
- کتابخانه فایل
- بانک سوالات
- import از Excel با preview
- export کامل backup مدرسه
- چند شعبه‌ای
- API برای اتصال به سیستم‌های دیگر

---

## 30.1 Backlog نهایی پذیرفته‌شده

این بخش دیگر صرفا پیشنهاد نیست. این‌ها موارد پذیرفته‌شده برای تکمیل محصول هستند. بعضی در MVP ساخته می‌شوند و بعضی در فازهای بعد، اما از scope محصول حذف نشده‌اند.

### Backlog فنی

- Queue برای کارهای سنگین مثل SMS، export، import، email و گزارش‌های بزرگ
- Job status برای import/export
- Notification center داخل پنل
- Realtime notifications در آینده با WebSocket یا polling سبک
- Feature flags داخلی برای فعال/غیرفعال کردن قابلیت‌های آزمایشی
- Health check endpoint برای بررسی سلامت سرور
- Error tracking داخلی یا اتصال به سرویس خارجی
- Backup scheduler
- Restore test checklist
- API versioning مثل `/api/v1`
- OpenAPI documentation برای APIها
- Seed data برای demo school
- Demo mode برای فروش به مدارس

### Backlog محصول

- Trial license برای مدرسه‌ها
- درخواست دمو از landing page
- مقایسه پلن‌ها
- صفحه upgrade داخل owner panel
- مرکز خرید ماژول‌ها برای owner
- پرداخت آنلاین برای اشتراک و SMS
- فاکتور رسمی
- اعلان نزدیک پایان اشتراک
- اعلان کم بودن موجودی SMS
- template آماده SMS
- بانک سوالات برای امتحانات
- آرشیو سال تحصیلی
- انتقال دانش‌آموزان به سال بعد
- سیستم ticket پشتیبانی
- راهنمای داخل پنل برای owner و معلم

### Backlog UI/UX

- طراحی mobile-first برای student و teacher
- empty state برای صفحات خالی
- skeleton loading برای جدول‌ها
- toast notification
- confirm modal برای عملیات خطرناک
- table filters حرفه‌ای
- ذخیره filterهای پرکاربرد
- keyboard shortcuts برای پنل مدیریتی در آینده
- print stylesheet برای کارنامه و گزارش‌ها
- accessibility پایه: contrast، focus state، aria-label

### Backlog امنیتی و مدیریتی

- دو مرحله‌ای کردن ورود Super Admin در آینده
- session list برای کاربر
- logout from all devices
- approve flow برای تغییرات خیلی حساس
- export approval برای داده‌های حساس
- محدودیت IP برای Super Admin در صورت نیاز
- data retention policy
- حذف خودکار exportهای قدیمی
- masking شماره موبایل برای کاربران غیرمجاز

### Backlog مربوط به مدارس

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

### Backlog مربوط به حضور و فعالیت کاربران

- هشدار خودکار برای دانش‌آموز پرغیبت
- هشدار خودکار برای دانش‌آموزی که چند روز وارد پنل نشده
- گزارش «دانش‌آموزان بدون فعالیت»
- گزارش «معلمانی که حضور و غیاب را ثبت نکرده‌اند»
- یادآوری ثبت حضور و غیاب به معلم
- قفل کردن ارسال SMS غیبت تا وقتی حضور و غیاب نهایی نشده
- امکان ثبت دلیل غیبت توسط کادر مدرسه
- امکان تایید/رد دلیل غیبت توسط معاون
- برگه چاپی حضور و غیاب با QR code جلسه در آینده
- import حضور و غیاب از فایل CSV در آینده
- خروجی سابقه حضور و غیاب برای پرونده دانش‌آموز
- هشدار به owner اگر موجودی SMS برای ارسال غیبت کافی نیست
- نمایش badge «پروفایل ناقص» برای کاربران
- گزارش کاربران با اطلاعات ناقص
- reminder تکمیل اطلاعات برای دانش‌آموزان و کاربران مدرسه

---

## 31. تصمیم‌های نهایی قبل از شروع کدنویسی

- [x] Palette نهایی: Spring Mint
- [x] فونت نهایی: Vazirmatn
- [x] Backend: Laravel
- [x] Frontend: React + TypeScript
- [x] Bridge: Inertia.js
- [x] Build tool: Vite
- [x] Webserver: Apache
- [x] PWA: فعال
- [x] فقط شماره و اطلاعات تماس پدر/مادر در پرونده دانش‌آموز ذخیره می‌شود؛ پنل جداگانه برای این مورد ساخته نمی‌شود.
- [x] SMS Provider هنگام شروع ماژول SMS انتخاب می‌شود و قبل از کدنویسی آن ماژول documentation/API key گرفته می‌شود.
- [x] Payment Gateway هنگام شروع ماژول پرداخت انتخاب می‌شود و قبل از کدنویسی آن ماژول documentation/merchant key گرفته می‌شود.
- [x] روش خرید اشتراک نسخه اول: درخواست دمو/تماس فروش + امکان صدور invoice دستی؛ پرداخت آنلاین بعد از انتخاب gateway فعال می‌شود.
- [x] قیمت پلن‌ها و ماژول‌ها در دیتابیس و پنل Super Admin قابل تنظیم است؛ قیمت hardcode نمی‌شود.
- [x] کلاس آنلاین نسخه اول: link-based است؛ سیستم داخلی کلاس آنلاین فقط در فاز آینده و به عنوان ماژول جدا اضافه می‌شود.
- [x] پیام‌رسانی دانش‌آموز: پیش‌فرض محدود است؛ دانش‌آموز فقط به معلم/مدیر/معاون طبق permission مدرسه پیام می‌دهد.
- [x] اطلاعات اجباری دانش‌آموز: نام، نام خانوادگی، کد دانش‌آموزی، پایه، کلاس، وضعیت، شماره پدر یا مادر، آدرس یا شماره خانه طبق تنظیم مدرسه.
- [x] قالب کارنامه نسخه اول: آنلاین + PDF/print، با Spring Mint، جدول نمرات، معدل، توضیح مدیر/معلم و تاریخ شمسی.
- [x] Super Admin دسترسی کامل فنی دارد، اما مشاهده داده‌های حساس مدرسه باید audit log شود و در آینده support access mode قابل اضافه شدن است.
- [x] Voting فقط اگر مدرسه ماژول/permission آن را خریده باشد دیده می‌شود.
- [x] Grade levels برای هر مدرسه قابل فروش/فعال‌سازی است؛ مثال مدرسه فقط پایه 9 تا 12.
- [x] SMS wallet برای owner مدرسه است و هر SMS موفق به هر گیرنده 1 واحد کم می‌کند.
- [x] database/schema.sql منبع اصلی دیتابیس در فاز توسعه است و هر بار کامل replace/import می‌شود.
- [x] همه دکمه‌ها و فرم‌ها باید functional و هم‌تم باشند؛ placeholder UI ممنوع است.

---

## 32. قانون به‌روزرسانی این فایل

هر بار که تصمیمی گرفته شد:

- در همین `PLAN.md` ثبت شود.
- اگر کاری انجام شد، checkbox مربوطه تیک بخورد.
- اگر ماژولی حذف شد، دلیل حذف نوشته شود.
- اگر ساختار عوض شد، بخش ساختار فولدر به‌روز شود.
- اگر دیتابیس تغییر کرد، بخش دیتابیس و `database/schema.sql` با هم هماهنگ شوند.

این فایل باید همیشه حقیقت پروژه باشد.

---

## 33. وضعیت اجرای واقعی پروژه تا این مرحله

این بخش خلاصه حقیقت فعلی کدنویسی است و باید بعد از هر phase به‌روز شود.

### 33.1 کارهای انجام‌شده

- [x] پروژه از صفر با ساختار Laravel + React + TypeScript + Inertia + Vite ساخته شد.
- [x] فایل‌های اصلی Laravel، routeها، configها، controllerها، modelها، serviceها، requestها و middlewareها ساخته شدند.
- [x] `database/schema.sql` به عنوان schema اصلی توسعه ساخته شد.
- [x] `database/seed.sql` برای داده‌های پایه مثل نقش‌ها، ماژول‌ها، permissionها، پایه‌ها و Super Admin آماده شد.
- [x] دیتابیس remote توسعه با نام `daneshyar_dev` ساخته و `schema.sql` + `seed.sql` داخل آن import شد.
- [x] `.env` توسعه ساخته شد و به دیتابیس remote توسعه وصل است؛ اطلاعات حساس نباید commit یا public شوند.
- [x] tab titleها به فرمت `دانشیار من | نام صفحه` تغییر کردند.
- [x] نام محصول از `مای دانشیار` به `دانشیار من` یکدست شد.
- [x] `resources/js/Components/Brand/BrandMark.tsx` ساخته شد و logo از مسیر `/assets/images/logo/logo.png` خوانده می‌شود.
- [x] Bootstrap Icons داخل `public/assets/icons/bootstrap-icons` کپی شد.
- [x] landing page phase اول طراحی شد: hero، معرفی امکانات، فرآیند راه‌اندازی، CTA و footer.
- [x] PWA manifest و offline page با نام جدید محصول به‌روز شد.
- [x] صفحات dashboard از hardcode خارج شدند و داده را از Inertia props می‌گیرند.
- [x] controllerهای اصلی برای dashboard، students، teachers، classes، reports، modules، SMS، voting، attendance، exams و grades داده واقعی دیتابیس را می‌خوانند.
- [x] فرم ثبت دانش‌آموز با backend store و validation ساخته شد.
- [x] فرم ثبت معلم با backend store و validation ساخته شد.
- [x] فرم ساخت کلاس با backend store، validation و بررسی پایه مجاز ساخته شد.
- [x] ساخت درخواست تایید SMS برای غایبین امروز ساخته شد.
- [x] ساخت رأی‌گیری با دامنه پایه/کلاس مجاز ساخته شد.
- [x] `scripts/USAGE.md` برای نصب، build، import دیتابیس و اولین تست نوشته شد.
- [x] `scripts/import_remote_database.py` برای ساخت/import دیتابیس از روی `.env` ساخته شد.
- [x] `scripts/php_parse_check.cjs` برای syntax check فایل‌های PHP بدون نصب PHP ساخته شد.
- [x] `npm run build` با موفقیت اجرا شد.
- [x] TypeScript و Vite production build پاس شدند.
- [x] PHP parse check پاس شد: `127 files, 0 errors`.
- [x] JSON/PWA manifest check پاس شد.
- [x] Plan file refs بررسی شد: missing refs برابر `0` و unchecked existing refs برابر `0`.

### 33.2 کارهای نیمه‌کامل / پیاده‌سازی‌شده در حد پایه

- [x] پیام‌رسانی داخلی مدرسه (School/Messages) — inbox، sent، compose با multi-recipient ساخته شد.
- [x] کلاس‌های آنلاین (School/OnlineClasses) — ثبت لینک کلاس برای هر classroom/subject ساخته شد.
- [x] شارژ SMS توسط Super Admin — فرم شارژ کیف پول SMS با audit transaction log ساخته شد.
- [x] هشدار موجودی کم SMS — روی صفحه کیف پول نمایش داده می‌شود.
- [x] هشدار انقضای license — روی داشبورد مدرسه نمایش داده می‌شود (۳۰ روز قبل از انقضا).
- [x] اطلاعیه‌های مهم (popup) — روی داشبورد مدرسه و داشبورد دانش‌آموز نمایش داده می‌شوند.
- [x] کلاس آنلاین در پنل دانش‌آموز — لینک‌های join برای کلاس‌های آینده نمایش داده می‌شود.
- [x] اطلاعیه‌ها در پنل دانش‌آموز — اطلاعیه‌های مخصوص students/all نمایش داده می‌شوند.
- [x] export حضور و غیاب CSV — به Export Center اضافه شد.
- [x] ویرایش نمره معلم با audit log — PUT /teacher/grades/{id}، فقط draft/submitted.
- [x] تایید نمرات (GradeController approve/reject) — ساخته شد.
- [x] کارنامه دانش‌آموز (ReportCard) — ساخته شد.
- [x] مدیریت کاربران مدرسه (School/Users) — ساخته شد با reset password و temp password flow.
- [x] ماژول‌های مدرسه توسط Super Admin — manageModules و toggleModule ساخته شدند.
- [x] ساخت مدرسه توسط Super Admin با owner و license و SMS wallet — ساخته شد.
- [x] تنظیمات مدرسه با مدیریت پایه‌های تحصیلی — ساخته شد.
- [x] اطلاعیه‌های مدرسه (School/Announcements) — CRUD کامل ساخته شد.
- [ ] SMS واقعی به provider وصل نشده است؛ فقط wallet، log و approval flow پایه آماده است.
- [ ] پرداخت آنلاین هنوز provider ندارد؛ invoice/payment schema آماده است.
- [ ] permission enforcement کامل روی همه actionها باید سخت‌گیرانه‌تر شود.
- [ ] module hiding در UI شروع شده، اما باید برای تمام route/actionها enforce شود.
- [x] report card PDF و print stylesheet کامل شدند.
- [x] فایل‌ها و file upload management کامل شد.
- [x] پنل دانش‌آموز کامل شد: برنامه هفتگی، امتحان آنلاین (شروع/ارسال/auto-grade MCQ)، تکالیف (مشاهده+ارسال+فایل)، نمرات، حضور و غیاب، رأی‌گیری.
- [x] TakeExam.tsx از stub به پیاده‌سازی کامل (timer، auto-save، progress bar، MCQ+تشریحی) تبدیل شد.
- [x] معلم می‌تواند تکالیف ثبت، مشاهده و حذف کند (Teacher/Homeworks).
- [x] معلم می‌تواند سوال‌های امتحان را اضافه/حذف کند و امتحان را منتشر یا به پیش‌نویس برگرداند (Teacher/ExamQuestions).
- [x] بعد از ساخت امتحان توسط معلم، مستقیم به صفحه مدیریت سوالات هدایت می‌شود.
- [x] route حضور و غیاب به گروه teacher اضافه شد تا معلمان هم بتوانند حضور ثبت کنند.
- [x] sidebar دانش‌آموز: برنامه هفتگی، امتحانات، تکالیف، نمرات، حضور و غیاب، رأی‌گیری.
- [x] sidebar معلم: تکالیف اضافه شد.

### 33.3 کارهایی که کاربر باید حتما انجام دهد / بررسی کند

- [x] فایل واقعی logo با نام دقیق `logo.png` باید داخل `public/assets/images/logo/logo.png` قرار داشته باشد.
- [ ] روی سیستم توسعه یا سرور باید PHP 8.3+ نصب شود.
- [ ] باید `composer install` اجرا شود تا `vendor/autoload.php` ساخته شود.
- [ ] برای production مقدار `APP_ENV=production` و `APP_DEBUG=false` شود.
- [ ] مقدار `APP_KEY` برای production جداگانه ساخته شود و از development جدا باشد.
- [ ] `.env` نباید commit یا داخل public upload شود.
- [ ] Apache DocumentRoot باید روی `public` باشد، نه ریشه پروژه.
- [ ] HTTPS باید قبل از production فعال شود.
- [ ] SMS provider و مستندات/API key باید هنگام شروع ارسال واقعی SMS انتخاب شود.
- [ ] Payment gateway و merchant key باید هنگام شروع پرداخت آنلاین انتخاب شود.
- [ ] بعد از نصب PHP/Composer باید تست واقعی Laravel runtime انجام شود: `/`, `/login`, `/dashboard`.

### 33.4 نتیجه آخرین بررسی آماده‌سازی Apache

آخرین اجرای `scripts/apache_ready_check.py`:

- [x] `public/build/manifest.json` وجود دارد.
- [x] `.env` وجود دارد.
- [x] `public/index.php` و `.htaccess` وجود دارند.
- [x] `storage` و `bootstrap/cache` قابل نوشتن هستند.
- [ ] `vendor/autoload.php` هنوز وجود ندارد، چون Composer/PHP در محیط فعلی نصب نیست.
- [ ] برای production باید `APP_DEBUG=false` و `APP_ENV=production` شود.
