# Teaching Institution Management Dashboard API Production-ready Express.js & MongoDB backend API for an internal management dashboard of a teaching institution. Built with a strict layered architecture, JWT authentication with refresh token rotation, Joi validation, native Node.js EventEmitter, dynamic localization (English & Persian), background jobs, multi-channel notifications (Email, SMS, Bale Bot), custom Role-Based Access Control (RBAC), and private AWS S3 / MinIO object storage with presigned temporary URLs. --- ## Technical Features & Domain Architecture - **Private S3 / MinIO Storage System**: - Bucket Privacy: All buckets are strictly private; no public static file URLs are exposed. - **Presigned URLs**: Dynamic presigned temporary URLs generated via `@aws-sdk/s3-request-presigner` (`getSignedUrl`). - **Two-Stage Temp Upload Workflow**: 1. **Upload**: User/Admin uploads file to `POST /files/user/upload-temp` (or `/files/admin/upload-temp`), streaming directly to `S3_TEMP_BUCKET`. Returns `tempFileName`. 2. **Commit**: When submitting changes (e.g. creating/updating Certificate), the server copies the file from `S3_TEMP_BUCKET` to `S3_STORAGE_BUCKET` and removes the temp file. - **Daily Temp Bucket Cleanup**: Scheduled cron job running daily at 3:00 AM (`tempBucketCleanupJob`), deleting files in `S3_TEMP_BUCKET` older than 10 minutes. - **Courses & Classes**: - Each **Course** can contain multiple **Class** sections (e.g. "AutoDesk Farvardin A", "AutoDesk Farvardin B"). - Each **Class** maintains a `registeredUsers` array. - **Sessions & Attendance**: - Embedded `attendanceList` array inside each Session model. - **Strict Layered Architecture**: `Router` → `Controller` → `Service` → `Model` per component. --- ## Endpoints Overview | Component | Scope | Verb | Route | Description | Permission | | :--- | :--- | :--- | :--- | :--- | :--- | | **Auth** | Public | `POST` | `/auth/login` | Login with username & password | Public | | | Public | `POST` | `/auth/refresh` | Refresh access & refresh tokens | Public | | | Auth | `POST` | `/auth/logout` | Revoke refresh token | Authenticated | | **Files** | User | `POST` | `/files/user/upload-temp` | Upload file to S3 temp bucket | `files:upload` | | | User | `GET` | `/files/user/signed-url/:filename` | Get presigned temporary GET URL | `files:read` | | | Admin | `POST` | `/files/admin/upload-temp` | Admin upload file to S3 temp bucket | `files:upload` | | | Admin | `GET` | `/files/admin/signed-url/:filename` | Admin get presigned GET URL | `files:read` | | | Admin | `DELETE` | `/files/admin/delete/:filename` | Delete file from bucket | `files:delete` | | **Users** | User | `POST` | `/users/user/sign-up` | Self-register as a student | Public | | | User | `GET` | `/users/user/get-self` | Get self profile | Authenticated | | | User | `PUT` | `/users/user/update-self` | Update self profile | Authenticated | | | Admin | `POST` | `/users/admin/create` | Create user with specific role | `users:create` | | | Admin | `GET` | `/users/admin/get-all` | Get paginated users | `users:read` | | | Admin | `GET` | `/users/admin/search` | Search users | `users:search` | | | Admin | `GET` | `/users/admin/get-one/:id` | Get single user by ID | `users:read` | | | Admin | `PUT` | `/users/admin/update/:id` | Update user details | `users:update` | | | Admin | `DELETE` | `/users/admin/delete/:id` | Delete user | `users:delete` | | | Admin | `POST` | `/users/admin/:userId/enroll` | Enroll student into course | `users:enroll` | | **Professors** | Admin | `POST` | `/professors/admin/create` | Create professor | `professors:create` | | | Admin | `GET` | `/professors/admin/get-all` | List professors | `professors:read` | | | Admin | `GET` | `/professors/admin/search` | Search professors | `professors:search` | | | Admin | `GET` | `/professors/admin/get-one/:id` | Get professor details | `professors:read` | | | Admin | `PUT` | `/professors/admin/update/:id` | Update professor | `professors:update` | | | Admin | `DELETE` | `/professors/admin/delete/:id` | Delete professor | `professors:delete` | | **Courses** | User | `GET` | `/courses/user/get-all` | List public courses | Public / Auth | | | User | `GET` | `/courses/user/get-one/:id` | Get public course details | Public / Auth | | | Admin | `POST` | `/courses/admin/create` | Create new course | `courses:create` | | | Admin | `GET` | `/courses/admin/get-all` | List all courses | `courses:read` | | | Admin | `GET` | `/courses/admin/search` | Search courses | `courses:search` | | | Admin | `GET` | `/courses/admin/get-one/:id` | Get course by ID | `courses:read` | | | Admin | `PUT` | `/courses/admin/update/:id` | Update course details | `courses:update` | | | Admin | `DELETE` | `/courses/admin/delete/:id` | Delete course | `courses:delete` | | **Classes** | User | `GET` | `/classes/user/my-classes` | View enrolled student classes | Authenticated | | | Admin | `POST` | `/classes/admin/create` | Create class section | `classes:create` | | | Admin | `GET` | `/classes/admin/get-all` | List class sections | `classes:read` | | | Admin | `GET` | `/classes/admin/search` | Search class sections | `classes:search` | | | Admin | `GET` | `/classes/admin/get-one/:id` | Get class details | `classes:read` | | | Admin | `PUT` | `/classes/admin/update/:id` | Update class details | `classes:update` | | | Admin | `DELETE` | `/classes/admin/delete/:id` | Delete class section | `classes:delete` | | | Admin | `PUT` | `/classes/admin/:id/registered-users` | Edit registered users list | `classes:register_users` | | **Sessions** | User | `GET` | `/sessions/user/my-sessions` | Enrolled student sessions | Authenticated | | | Admin | `POST` | `/sessions/admin/create` | Schedule session | `sessions:create` | | | Admin | `GET` | `/sessions/admin/get-all` | List sessions | `sessions:read` | | | Admin | `GET` | `/sessions/admin/search` | Search sessions | `sessions:search` | | | Admin | `GET` | `/sessions/admin/get-one/:id` | Get session details | `sessions:read` | | | Admin | `PUT` | `/sessions/admin/update/:id` | Update/Cancel session | `sessions:update` | | | Admin | `DELETE` | `/sessions/admin/delete/:id` | Delete session | `sessions:delete` | | | Admin | `PUT` | `/sessions/admin/:id/attendance` | Record session attendance list | `sessions:attendance` | | **Payments** | User | `GET` | `/payments/user/my-payments` | View user payments | Authenticated | | | User | `POST` | `/payments/user/pay/:id` | Add payment transaction | Authenticated | | | Admin | `POST` | `/payments/admin/create` | Create payment ledger | `payments:create` | | | Admin | `GET` | `/payments/admin/get-all` | List payments | `payments:read` | | | Admin | `GET` | `/payments/admin/search` | Search payments | `payments:search` | | | Admin | `GET` | `/payments/admin/get-one/:id` | Get payment details | `payments:read` | | | Admin | `PUT` | `/payments/admin/update/:id` | Update payment details | `payments:update` | | | Admin | `DELETE` | `/payments/admin/delete/:id` | Delete payment ledger | `payments:delete` | | **Roles** | Admin | `POST` | `/roles/admin/create` | Create custom role | `roles:create` | | | Admin | `GET` | `/roles/admin/get-all` | List custom roles | `roles:read` | | | Admin | `GET` | `/roles/admin/search` | Search roles | `roles:search` | | | Admin | `GET` | `/roles/admin/get-one/:id` | Get role by ID | `roles:read` | | | Admin | `PUT` | `/roles/admin/update/:id` | Update role permissions | `roles:update` | | | Admin | `DELETE` | `/roles/admin/delete/:id` | Delete non-system role | `roles:delete` | | **Notifications**| User | `GET` | `/notifications/user/my-notifications` | View received notifications | Authenticated | | | Admin | `POST` | `/notifications/admin/create` | Send notification | `notifications:create` | | | Admin | `GET` | `/notifications/admin/get-all` | List all notifications | `notifications:read` | | | Admin | `GET` | `/notifications/admin/search` | Search notifications | `notifications:search` | | | Admin | `GET` | `/notifications/admin/get-one/:id` | Get notification by ID | `notifications:read` | | | Admin | `PUT` | `/notifications/admin/update/:id` | Update notification | `notifications:update` | | | Admin | `DELETE` | `/notifications/admin/delete/:id` | Delete notification | `notifications:delete` | | | Admin | `POST` | `/notifications/admin/:id/retry` | Manually retry failed dispatch | `notifications:retry` | | **Certificates** | User | `GET` | `/certificates/user/my-certificates` | View personal certificates | `certificates:read` | | | User | `POST` | `/certificates/user/upload` | Upload & commit certificate | `files:upload` | | | Admin | `POST` | `/certificates/admin/create` | Issue official certificate | `certificates:create` | | | Admin | `GET` | `/certificates/admin/get-all` | List all certificates | `certificates:read` | | | Admin | `GET` | `/certificates/admin/search` | Search certificates | `certificates:search` | | | Admin | `GET` | `/certificates/admin/get-one/:id` | Get certificate details | `certificates:read` | | | Admin | `PUT` | `/certificates/admin/update/:id` | Update certificate | `certificates:update` | | | Admin | `DELETE` | `/certificates/admin/delete/:id` | Delete certificate | `certificates:delete` | --- ## Verification Check code syntax: ```bash node --check app.js && node --check seed.js ```