# Dashboard Module — Architecture Map

> **Last updated:** 2026-06-10
> **Status:** Living document — incrementally updated as new information is discovered

---

## 1. Purpose & Responsibilities

The Dashboard module is the **main landing page** after login. It provides a real-time operational overview by aggregating key metrics from across the ERP:

- Active member count
- New members this month
- Monthly revenue (from Payments)
- Pending interviews
- Overdue installments
- Members by branch distribution
- Monthly revenue trend (6-month chart)
- Recent audit trail activity
- Contextual alert notifications (children aging, expiring forms, overdue installments, honorary expiry)

It also **registers sidebar menu separators** that structure the global navigation (Operations, Finance, Supply Chain, Administration, Reports & System sections).

It does **NOT**:
- Provide any data mutation (read-only module)
- Have its own database tables
- Register any permissions (accessible to all authenticated users)
- Dispatch or listen to events

---

## 2. Directory & File Structure

```
app/Modules/Dashboard/
├── bootstrap.php                          # Menu registration + sidebar separators
├── Routes.php                             # Single route: GET /dashboard
├── Controllers/
│   └── DashboardController.php           # Minimal — delegates to DashboardDataService
├── Services/
│   └── DashboardDataService.php          # All data aggregation logic (8 queries + alerts)
└── Views/
    ├── index.php                          # Main dashboard view (cards, charts, alerts, activity)
    └── _partials/
        └── widgets.php                    # Reusable widget components
```

---

## 3. Database Schema (Production — Source of Truth)

The Dashboard module **does not own any tables**. It performs read-only queries against tables owned by other modules:

| Table Queried | Owner Module | Data Extracted |
|--------------|--------------|----------------|
| members | Members | COUNT active, COUNT new this month |
| payments | Payments | SUM amount for monthly revenue |
| interviews | Interviews | COUNT pending/scheduled |
| installment_plans + installment_schedule | Installments | COUNT overdue installments |
| branches | Branches | Member distribution by branch |
| audit_trail | Audit | Recent 15 activity entries |
| children | Children | Males approaching age 25 |
| form_submissions | Forms | Forms expiring within 3 days |
| honorary_members | Honorary | Memberships expiring within 30 days |

---

## 4. Routes

| Method | Path | Handler | Middleware | Permission |
|--------|------|---------|------------|------------|
| GET | /dashboard | DashboardController@index | auth | null (any authenticated user) |

---

## 5. Events Dispatched

None.

---

## 6. Events Consumed

None.

---

## 7. Cross-Module Dependencies

### 7.1 Dashboard IMPORTS FROM (via direct SQL queries):

| Module | What it queries |
|--------|----------------|
| Members | `members` table — active count, new this month, branch distribution |
| Payments | `payments` table — monthly revenue aggregation |
| Interviews | `interviews` table — pending interview count |
| Installments | `installment_plans` + `installment_schedule` — overdue count |
| Branches | `branches` table — branch names for distribution chart |
| Audit | `audit_trail` table — recent 15 activity entries |
| Children | `children` table — males nearing age 25 |
| Forms | `form_submissions` table — expiring forms |
| Honorary | `honorary_members` table — expiring honorary memberships |

### 7.2 Other modules that IMPORT FROM Dashboard:

None. The Dashboard module is a pure consumer — no other module depends on it.

### 7.3 Sidebar Separator Registration

The Dashboard bootstrap.php registers **global menu separators** that other modules rely on for navigation structure:

| Separator Key | Label | Order |
|--------------|-------|-------|
| `_sep_operations` | العمليات (Operations) | 50 |
| `_sep_finance` | المالية (Finance) | 295 |
| `_sep_supply` | سلسلة التوريد (Supply Chain) | 395 |
| `_sep_hr` | الشئون الإدارية (Administration) | 495 |
| `_sep_reports` | التقارير والنظام (Reports & System) | 595 |

---

## 8. Permissions

None registered. The dashboard route has `permission: null`, meaning any authenticated user can access it.

---

## 9. Background Processes (Cron)

None.

---

## 10. High-Risk Areas

### 10.1 Query Performance on Large Datasets

`DashboardDataService::getData()` executes **8 separate database queries** plus up to 4 alert-checking queries on every page load. No caching layer exists.

- Monthly revenue query scans payments for last 6 months
- Branch distribution query uses LEFT JOIN across all active branches
- Overdue installments query joins two tables
- If tables grow large (10K+ members, 50K+ payments), dashboard load time will degrade

### 10.2 Silent Failure Pattern

Every query is wrapped in `try/catch (\Throwable)` with a fallback to 0 or empty array. This means:
- Database connection issues will produce a dashboard with all zeros
- Schema changes that break queries will fail silently
- No logging of query failures — hard to diagnose production issues

### 10.3 Alert Queries Duplicate Logic

The `getAlerts()` method re-implements alert logic that also exists in:
- `AlertProcessorService` (Alerts module)
- `AutoFreezeService` (Members module)

If business rules change (e.g., children aging threshold), this duplicated logic may not be updated consistently.

---

## 11. Known Patterns & Gotchas

1. **No permission check**: Any logged-in user sees all dashboard data regardless of their role — there is no branch-level or permission-level filtering of the metrics
2. **Static SQL aggregation**: Revenue is `SUM(amount)` without filtering by branch — shows club-wide totals
3. **Audit trail displays employee_name directly**: If an employee name changes, old audit entries show the old name
4. **View uses inline styles heavily**: The index.php view has no CSS classes — all styling is inline, making it difficult to theme
5. **Chart is pure CSS**: Revenue chart uses CSS height percentages, not a JS charting library — limited interactivity
6. **Alert links assume routes exist**: Links like `/reports/view/RPT_CHILDREN_25` and `/installments?overdue_only=1` will 404 if those modules are disabled

---

## 12. Configuration Dependencies

None. The Dashboard module has no system_config, rule engine, or service catalog dependencies.
