# Donor Information Dashboard - Portfolio Access Control

## Overview
This implementation provides flexible access control for the Donor Information Dashboard, allowing users to access portfolios through a many-to-many relationship system rather than hardcoded roles.

## Access Control Implementation

### 1. Dashboard Access Control
- **Location**: `app/Filament/Pages/DonorInformationDashboard.php`
- **Method**: `canAccess()` static method
- **Logic**: Users can access the dashboard if they have:
  - `page_DonorInformationDashboard` permission
  - `view_any_donor_financial_portfolio` permission

### 2. Portfolio Data Scoping
- **Location**: `app/Scopes/DonorPortfolioAccessScope.php`
- **Applied to**: `DonorFinancialPortfolio` model automatically
- **Logic**:
  - **Super Admin** or users with `view_any_donor_financial_portfolio`: See all portfolios
  - **Regular Users**: See only portfolios they have been explicitly linked to via the `user_donor_financial_portfolio` pivot table

### 3. Portfolio-User Relationship
- **Many-to-Many Relationship**: Users can be linked to multiple portfolios
- **Pivot Table**: `user_donor_financial_portfolio`
- **Auto-linking**: When a user creates a portfolio, they are automatically linked to it
- **Manual Management**: Administrators can manage portfolio access through the User resource

### 4. Widget Data Filtering
Both dashboard widgets automatically respect the portfolio access scope:
- **DonorPortfolioStatsOverview**: Calculates statistics only from accessible portfolios
- **DonorProjectStatusTable**: Shows only orders linked to accessible portfolios

## User Management Integration

### Portfolio Access Management
- **Location**: `app/Filament/Resources/UserResource/RelationManagers/DonorFinancialPortfoliosRelationManager.php`
- **Features**:
  - View portfolios linked to a user
  - Attach/detach portfolios from users
  - Search and filter available portfolios
  - Displays portfolio balance and status information

### Access in User Resource
The User resource now includes a "Donor Financial Portfolios" tab where administrators can:
1. View all portfolios linked to a user
2. Attach new portfolios to the user
3. Remove portfolio access from the user
4. See portfolio details and balances

## Setup Instructions

### 1. Run Database Migrations
```bash
php artisan migrate
```

### 2. Create Permissions
```bash
php artisan db:seed --class=DonorViewerRoleSeeder
```

### 3. Migrate Existing Portfolio Access (if upgrading)
```bash
php artisan db:seed --class=MigrateDonorPortfolioAccessSeeder
```

### 4. Create Roles and Assign Permissions
```php
// Create a role for donor dashboard users
$role = Role::create(['name' => 'donor_dashboard_user']);

// Assign necessary permissions
$role->givePermissionTo([
    'page_DonorInformationDashboard',
    'widget_DonorPortfolioStatsOverview', 
    'widget_DonorProjectStatusTable',
    'view_donor_financial_portfolio'
]);

// Assign role to user
$user->assignRole('donor_dashboard_user');
```

### 5. Link Users to Portfolios
```php
// Via code
$user->donorFinancialPortfolios()->attach($portfolioId);

// Or via Filament UI - go to Users > Edit User > Donor Financial Portfolios tab
```

## Security Features

- **Relationship-based access**: No hardcoded role checks, flexible assignment
- **Automatic scoping**: All portfolio queries are automatically scoped by default
- **Override capability**: Admins can use `DonorFinancialPortfolio::withoutAccessScope()` when needed
- **Auto-linking**: Portfolio creators are automatically given access
- **Granular permissions**: Uses FilamentShield for fine-grained permission control

## Testing

Run the authorization tests:
```bash
php artisan test tests/Feature/DonorInformationDashboardAuthorizationTest.php
```

Tests cover:
- Dashboard access by different user permissions
- Portfolio visibility scoping
- Super admin override capabilities
- Many-to-many relationship functionality

## Usage Examples

### For Regular Users
```php
// User linked to specific portfolios
$user = User::find(1);

// They will only see portfolios they're linked to
$portfolios = DonorFinancialPortfolio::all(); // Automatically scoped
$userPortfolios = $user->donorFinancialPortfolios; // Same result
```

### For Administrators
```php
// Link a user to a portfolio
$user->donorFinancialPortfolios()->attach($portfolioId);

// Remove access
$user->donorFinancialPortfolios()->detach($portfolioId);

// See all portfolios (bypass scope)
$allPortfolios = DonorFinancialPortfolio::withoutAccessScope()->get();

// Grant permission to see all portfolios
$user->givePermissionTo('view_any_donor_financial_portfolio');
```

### Creating New Portfolios
```php
// When authenticated user creates a portfolio, they're automatically linked
auth()->login($user);
$portfolio = DonorFinancialPortfolio::create([
    'name' => 'New Portfolio',
    'balance' => 50000.00,
    'operating_percentage' => 5.0
]);
// User is automatically linked to this portfolio
```

## Database Schema

### user_donor_financial_portfolio (Pivot Table)
- `id` - Primary key
- `user_id` - Foreign key to users table
- `donor_financial_portfolio_id` - Foreign key to donor_financial_portfolios table
- `created_at`, `updated_at` - Timestamps
- `unique(user_id, donor_financial_portfolio_id)` - Prevents duplicate links

## Future Enhancements

The system is designed to be flexible for future enhancements:
- **Association-based access**: Could extend to automatically link users based on association membership
- **Department-based access**: Could scope by department relationships
- **Project-specific access**: Could allow access based on project involvement
- **Time-based access**: Could add temporal restrictions to portfolio access
- **Permission inheritance**: Could inherit access from organizational hierarchy