# Dashboard Widget Permission Filtering
**Date**: November 11, 2024  
**Status**: Complete

## Overview
Implemented permission-based filtering for dashboard widgets/stat cards, ensuring users only see dashboard elements for modules they have access to.

## Changes Made

### 1. Database Migration: 049_add_stat_card_permissions.sql
Added `permission_required` values to all stat cards in the `dashboard_stat_cards` table:

**Main Dashboard Cards:**
- `total_customers` → `crm.view`
- `total_products` → `inventory.view`
- `sales_month` → `sales.view`
- `pending_invoices` → `invoices.view`

**Module Dashboard Cards:**
- CRM dashboard (4 cards) → `crm.view`
- HR dashboard (4 cards) → `hr.view`
- Inventory dashboard (4 cards) → `inventory.view`
- Manufacturing dashboard (4 cards) → `manufacturing.view`
- Sales dashboard (4 cards) → `sales.view`
- Product categories (4 cards) → `inventory.view`
- Lot tracking (4 cards) → `inventory.view`

**Result**: 32 stat cards now have permission filtering (100% coverage)

### 2. Main Dashboard Hardcoded Cards: views/dashboard/index.php
Wrapped 4 hardcoded stat cards with permission checks:
```php
<?php if (hasPermission('crm.view')): ?>
    <!-- Customers card -->
<?php endif; ?>

<?php if (hasPermission('inventory.view')): ?>
    <!-- Products card -->
<?php endif; ?>

<?php if (hasPermission('sales.view')): ?>
    <!-- Sales card -->
<?php endif; ?>

<?php if (hasPermission('invoices.view')): ?>
    <!-- Invoices card -->
<?php endif; ?>
```

### 3. Existing Infrastructure (No Changes Needed)
The following components already had permission checking built-in:

**DashboardStatCard Model** (`models/DashboardStatCard.php`, lines 29-31):
```php
// Check permission if required
if (!empty($card['permission_required']) && !hasPermission($card['permission_required']) && !is_admin()) {
    continue;
}
```

**Helper Function** (`includes/dashboard_helpers.php`):
- `render_stat_cards($section)` - Automatically filters cards by permission

**Module Dashboards** (11 files):
- All use `render_stat_cards()` helper, which respects permissions
- Files: accounting, approvals, crm, helpdesk, hr, hr/recruitment, inventory, manufacturing, manufacturing/analytics, payroll, purchases, sales

## Results

### Coverage Statistics
- **Database-driven stat cards**: 32/32 (100%) have permissions
- **Module dashboards**: 11/11 (100%) use permission-aware helper
- **Hardcoded main dashboard cards**: 4/4 (100%) wrapped with permission checks

### User Experience
Users now experience consistent permission filtering:
1. **Sidebar menu**: Only shows items they can access (from Migration 048)
2. **Dashboard widgets**: Only shows stat cards for modules they can access
3. **No "access denied" surprises**: If they see it, they can access it

## Technical Notes

### Permission Mapping
| Dashboard Section | Permission Required | Card Count |
|-------------------|---------------------|------------|
| main | varies by card | 4 |
| crm | crm.view | 4 |
| hr | hr.view | 4 |
| inventory | inventory.view | 4 |
| manufacturing | manufacturing.view | 4 |
| sales | sales.view | 4 |
| product_categories | inventory.view | 4 |
| lot_tracking | inventory.view | 4 |

### Admin Bypass
Admins (checked via `is_admin()`) bypass all permission checks and see all widgets.

### Dependencies
- Requires all `.view` permissions to exist in `permissions` table
- Uses `hasPermission()` helper function from `includes/helpers.php`
- Relies on session-based authentication and role system

## Testing Checklist
- [ ] Create test user with limited permissions (e.g., only `crm.view`)
- [ ] Verify main dashboard only shows customer card
- [ ] Verify CRM dashboard is accessible and shows stat cards
- [ ] Verify Sales/Inventory/Manufacturing dashboards are not accessible (redirect to main dashboard with "access denied")
- [ ] Verify admin sees all widgets on all dashboards

## Related Migrations
- **048_add_menu_permissions.sql**: Added permissions to menu items (same UX principle)
- **049_add_stat_card_permissions.sql**: This migration

## Files Modified
1. `/database/migrations/049_add_stat_card_permissions.sql` - Created
2. `/views/dashboard/index.php` - Modified (added permission checks to 4 hardcoded cards)

## Files Reviewed (No Changes Needed)
- `/models/DashboardStatCard.php` - Already had permission filtering
- `/includes/dashboard_helpers.php` - Already used permission-aware model
- All 11 module dashboard view files - All use the permission-aware helper

## Conclusion
Dashboard permission filtering is now fully implemented and consistent with menu permission filtering. Users will only see dashboard widgets for modules they have access to, providing a clean, focused user experience.
