# Permission Matrix

## Overview

This document defines what each user role can access across both Filament panels. The system uses **Spatie Permissions** with 9 defined roles. Access is enforced through:
- **Middleware** — Panel-level gatekeeping (ensure correct panel + verification)
- **Role checks** — `hasRole()` / `hasAnyRole()` checks in resources, pages, widgets
- **Policies** — `ParticipationPolicy` for event participation actions
- **Feature Gates** — Subscription-based feature entitlement `FeatureGate`

## System Roles

| Role | Code | Color | Icon | Level | Status |
|------|------|-------|------|-------|--------|
| System Administrator | `super-admin` | 🔴 Red | Shield Check | System-wide | Active |
| System Manager | `super-manager` | 🟡 Yellow | Cog | System-wide | Active |
| Program Administrator | `portal-admin` | 🔵 Blue | Stack | Program | Active |
| Program Manager | `portal-manager` | 🟦 Sky | Briefcase | Program | Active |
| Country Manager | `portal-country-manager` | 🟢 Green | Globe | Country | Defined only, not enforced |
| City Manager | `portal-city-manager` | 🟩 Teal | Building | City | Defined only, not enforced |
| Teacher | `portal-teacher` | 🟣 Indigo | Academic Cap | Teacher | Active |
| Teacher Assistant | `portal-teacher-assistant` | 🟪 Purple | User Group | Teacher | Partially enforced |
| Student | `portal-student` | ⚪ Gray | User | Student | Active |

> **Note:** `portal-country-manager` and `portal-city-manager` are defined in the Role model with translations and display properties but are not actively checked by any middleware, resource, or policy code. `portal-teacher-assistant` has limited checks in a few locations (trainings, announcements, video streaming).

---

## Panel Access

### Admin Panel (`/admin`)

| Middleware | super-admin | super-manager |
|------------|:-----------:|:-------------:|
| `EnsureUserIsSuper` | ✅ | ✅ |
| `EnsureUserIsVerified` | ✅ | ✅ |
| All others | ❌ 403 Forbidden | ❌ 403 Forbidden |

### Program Panel (`/program`)

| Middleware | super-admin | super-manager | portal-admin | portal-manager | portal-teacher | portal-teacher-assistant | portal-student | portal-country-manager | portal-city-manager |
|------------|:-----------:|:-------------:|:------------:|:--------------:|:--------------:|:------------------------:|:--------------:|:----------------------:|:-------------------:|
| `EnsureUserBelongsToProgram` | ✅ (via PanelSwitch) | ✅ (via PanelSwitch) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `EnsureUserIsVerified` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `UpdateLastActivity` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |

---

## Resource Access (Program Panel)

> **Note:** The tables below include only the 6 actively-enforced roles. Roles marked "Defined only, not enforced" (`portal-country-manager`, `portal-city-manager`) are omitted because no permission checks exist for them — they would show ❌ across all columns. `portal-teacher-assistant` has partial enforcement in a few locations.

| Resource | super-admin | super-manager | portal-admin | portal-manager | portal-teacher | portal-teacher-assistant | portal-student |
|----------|:-----------:|:-------------:|:------------:|:--------------:|:--------------:|:------------------------:|:--------------:|
| **ProgramLevelResource** | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
| **CourseResource** | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| **LessonResource** | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| **TrainingResource** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ (view) | ✅ (self only) |
| **ExamResource** | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| **VideoResource** | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| **UserResource** | ✅ | ✅ | ✅ (program) | ✅ (program) | ✅ (own students) | ❌ | ❌ |
| **ProgramResource** | ✅ | ✅ | ✅ (edit only) | ❌ | ❌ | ❌ | ❌ |
| **StudentResource** | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| **TeamResource** | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| **PathStepResource** | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| **ClassroomResource** | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| **AssessmentResource** | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ (view attempts) |
| **CompetitionResource** | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| **LevelClassificationResource** | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| **RankingTitleResource** | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| **MarathonResource** | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| **AnnouncementResource** | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |

### Admin Panel Resources

| Resource | super-admin | super-manager |
|----------|:-----------:|:-------------:|
| **CountryResource** | ✅ | ✅ |
| **ProgramResource** | ✅ | ✅ |
| **UserResource** | ✅ | ✅ |
| **NotificationSettingResource** | ✅ | ✅ |
| **SubscriptionRequestResource** | ✅ | ✅ |
| **PaymentResource** | ✅ | ✅ |

---

## Page Access

### Admin Panel Pages

| Page | super-admin | super-manager |
|------|:-----------:|:-------------:|
| Dashboard (default) | ✅ | ✅ |
| `ManageGeneral` | ✅ | ✅ |
| `WhatsappSettings` | ✅ | ✅ |
| `Subscriptions` | ✅ | ✅ |
| `Plans` | ✅ | ✅ |
| `ManageTranslations` | ✅ | ✅ |
| `SendCustomNotification` | ✅ (only super-admin) | ❌ |

### Program Panel Pages

| Page | super-admin | super-manager | portal-admin | portal-manager | portal-teacher | portal-student |
|------|:-----------:|:-------------:|:------------:|:--------------:|:--------------:|:--------------:|
| Dashboard (default) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `AssessmentRanking` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `MySubscription` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `AssessmentClassification` | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| `AssessmentsClassification` | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| `Activities` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ (limited) |
| `EligibilityManagerPage` | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| `ParticipationRequestManagementPage` | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| `PaymentVerificationPage` | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| `StudentEnrollmentPage` | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| `MentalMathTimer` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |

---

## Widget Access

### Admin Panel Widgets

| Widget | super-admin | super-manager |
|--------|:-----------:|:-------------:|
| `OnlineUsersStats` | ✅ | ✅ |
| `SubscriptionStatusWidget` | ✅ | ✅ |
| `ExpiringSubscriptionsWidget` | ✅ | ✅ |
| `PaymentQueueWidget` | ✅ | ✅ |
| `ParticipationPendingRequestsWidget` | ✅ | ✅ |

### Program Panel Widgets

| Widget | super-admin | super-manager | portal-admin | portal-manager | portal-teacher | portal-student |
|--------|:-----------:|:-------------:|:------------:|:--------------:|:--------------:|:--------------:|
| `OnlineUsersStats` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `SubscriptionStatusWidget` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `ExpiringSubscriptionsWidget` | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| `MarathonParticipationWidget` | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| `CompetitionParticipationWidget` | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| `StudentEnrollmentWidget` | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| `TeacherParticipationWidget` | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ |
| `ParticipationPendingRequestsWidget` | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |

---

## Action-Level Permissions (Participation Gates)

Defined in `AppServiceProvider` via `Gate::define()`:

| Gate | super-admin | super-manager | portal-admin | portal-manager | portal-teacher | portal-student |
|------|:-----------:|:-------------:|:------------:|:--------------:|:--------------:|:--------------:|
| `participation.approve` | ✅ | ✅ | ✅ (scope) | ✅ (scope) | ✅ (scope) | ❌ |
| `participation.enroll-student` | ✅ | ✅ | ✅ (scope) | ✅ (scope) | ✅ (scope) | ❌ |
| `participation.verify-payment` | ✅ | ✅ | ✅ (scope) | ✅ (scope) | ❌ | ❌ |
| `participation.view` | ✅ | ✅ | ✅ (scope) | ✅ (scope) | ✅ (scope) | ✅ (own only) |
| `participation.manage-eligibility` | ✅ | ✅ | ✅ (scope) | ✅ (scope) | ❌ | ❌ |
| `participation.student-can-join` | N/A | N/A | N/A | N/A | N/A | ✅ (scope) |
| `participation.manage-event` | ✅ | ✅ | ✅ (scope) | ✅ (scope) | ✅ (scope) | ✅ (scope=user) |

**Scope resolution** means the authority is resolved from `config/participation.php` based on the event type (marathon/competition) and scope (system/program/teacher):

| Event Scope | Approval Authority |
|-------------|-------------------|
| **system** (marathon) | super-admin, super-manager |
| **program** (marathon) | portal-admin, portal-manager |
| **teacher** (marathon) | portal-teacher |
| **system** (competition) | super-admin, super-manager |
| **program** (competition) | portal-admin, portal-manager, portal-teacher |
| **teacher** (competition) | portal-teacher |

---

## Feature Access (Subscription-based)

Feature access is controlled by the **FeatureGate** engine based on the subscriber's active plan. Each role's feature limits depend on their subscription plan, not their role directly:

| Feature | Scope | Checked Against | Role Group |
|---------|-------|-----------------|------------|
| `no_of_teachers` | Program | ProgramSubscription | portal-admin/manager |
| `no_of_marathons` | Program | ProgramSubscription | portal-admin/manager |
| `no_of_competition_per_marathon` | Program | ProgramSubscription | portal-admin/manager |
| `assessments_enabled` | Program | ProgramSubscription | portal-admin/manager |
| `certificates_enabled` | Program | ProgramSubscription | portal-admin/manager |
| `no_of_courses` | Teacher | TeacherSubscription | portal-teacher |
| `no_of_lessons` | Teacher | TeacherSubscription | portal-teacher |
| `no_of_groups` | Teacher | TeacherSubscription | portal-teacher |
| `no_of_competitions` | Teacher | TeacherSubscription | portal-teacher |
| `no_of_exams` | Teacher | TeacherSubscription | portal-teacher |
| `no_of_trainings` | Teacher | TeacherSubscription | portal-teacher |
| `available_storage_videos` | Teacher | TeacherSubscription | portal-teacher |
| `no_of_available_self_training` | Student | StudentSubscription | portal-student |
| `no_of_attempts_per_self_training` | Student | StudentSubscription | portal-student |

**Exception:** `super-admin` and `super-manager` bypass ALL feature limits via `FeatureGate::isSuperUser()`.

---

## Middleware Stack Summary

### Admin Panel Middleware Stack
```
EncryptCookies
AddQueuedCookiesToResponse
StartSession
AuthenticateSession
ShareErrorsFromSession
VerifyCsrfToken
SubstituteBindings
DisableBladeIconComponents
DispatchServingFilamentEvent
→ EnsureUserIsVerified    (must verify email or phone)
→ Authenticate             (must be logged in)
→ EnsureUserIsSuper        (must be super-admin or super-manager)
```

### Program Panel Middleware Stack
```
EncryptCookies
AddQueuedCookiesToResponse
StartSession
AuthenticateSession
ShareErrorsFromSession
VerifyCsrfToken
SubstituteBindings
DisableBladeIconComponents
DispatchServingFilamentEvent
RecordUserActivity         (activity tracking)
UpdateLastActivity          (online status)
→ EnsureUserIsVerified      (must verify email or phone)
→ Authenticate              (must be logged in)
→ EnsureUserBelongsToProgram (must belong to a program)
```

### Global Route Middleware (registered in `bootstrap/app.php`)
- `verified` → `EnsureUserIsVerified`
- `feature` → `CheckFeatureLimit`

---

## Special Cases

### Export Assessments (Routes)
Route: `/assessments/{assessment}/export-problems`
- **Allowed:** `super-admin`, `super-manager` only
- **Blocked:** All other roles (403)

### PanelSwitch (Admin Panel → Program Panel)
- **Visible:** `super-admin`, `super-manager` only
- **Hidden:** All other roles

### SendCustomNotification
- **Allowed:** `super-admin` only
- **Blocked:** `super-manager` and below

### User Menu Items (Program Panel)
| Menu Item | Visible To |
|-----------|------------|
| Teacher registration link | portal-admin, portal-manager |
| Student registration link | portal-teacher |
| Edit Profile | All (redirects based on role) |
| My Subscription | portal-admin, portal-teacher, portal-student |
| Program Edit | portal-admin only |

### BaseResource Scoping
The `BaseResource` applies program-scoped filtering to all resources:
- **super-admin / super-manager:** See all records across all programs
- **portal-admin / portal-manager:** See only their program's records
- **portal-teacher:** See only their own records (where `teacher_id = auth()->id()`)
- **portal-teacher-assistant:** Auto-set to their assigned teacher's ID
- **portal-student:** See only their own records

---

## Summary: Role Capability Overview

| Capability | super-admin | super-manager | portal-admin | portal-manager | portal-teacher | portal-student |
|------------|:-----------:|:-------------:|:------------:|:--------------:|:--------------:|:--------------:|
| Access Admin Panel | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
| Access Program Panel | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Manage Programs | ✅ | ✅ | ✅ (own) | ✅ (own) | ❌ | ❌ |
| Manage Courses/Lessons | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| Manage Assessments | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| Take Assessments | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Manage Teams/Groups | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| Manage Students | ✅ | ✅ | ✅ | ✅ | ✅ (own) | ❌ |
| Manage Videos | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| View Leaderboards | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Manage Subscriptions | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ (view own) |
| Approve Participation | ✅ | ✅ | ✅ (scope) | ✅ (scope) | ✅ (scope) | ❌ |
| Verify Payments | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| Send Notifications | ✅ (admin only) | ❌ | ❌ | ❌ | ❌ | ❌ |
| Export Assessment Problems | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
| Bypass Feature Limits | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
| Switch Panels | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
