# Security System Refactor: From Roles to Positions

## Overview
The security system has been refactored to use **positions** as the primary security mechanism instead of roles. This allows for more granular control based on job titles rather than abstract role assignments.

## Key Changes

### 1. Database Structure
- **New Table**: `position_permissions` - Maps positions to permissions
  - `position_id` INT - References the position
  - `permission_id` INT - References the permission
  - Replaces the old role-based `role_permissions` table for position-based access

- **Users Table**: 
  - Added `position_id` column (if not already present)
  - `position_id` now directly references positions, replacing role-based security

- **Migration**: `030_refactor_security_to_positions.sql`
  - Creates the `position_permissions` table
  - Migrates existing role permissions to positions
  - Updates users to have `position_id` set from employees data

### 2. Core Classes Updated

#### Auth Class (`core/Auth.php`)
- **login()**: Now fetches user position instead of role
- **loadUserPermissions()**: Changed to query `position_permissions` instead of `role_permissions`
- **Session**: Sets `user_position` instead of `user_role`

#### Session Class (`core/Session.php`)
- `getUser()` now returns `position` instead of `role`
- All permission checks remain the same, just query different tables

#### User Model (`models/User.php`)
- `getById()`: Now joins with positions table instead of roles
- `getAll()`: Updated to fetch position data
- Removed `getRoles()` and `assignRole()` methods (no longer needed)
- Position data now directly available from `position_id`

### 3. UserController Changes (`controllers/UserController.php`)
- **create()**: Shows positions list instead of roles
- **store()**: Stores `position_id` instead of `role_id`
- **edit()**: Fetches positions for the dropdown
- **update()**: Updates `position_id` instead of `role_id`
- **delete()**: No longer needs to clean up `user_roles` table

### 4. Views Updated

#### users/edit.php
- Replaced "Role" dropdown with "Position (Security Role)" dropdown
- Position field is now required for all users
- Shows position title with department (e.g., "Senior Developer (Engineering)")
- Help text explains that position determines permissions

## Security Permissions Flow

### Before (Role-Based)
```
User -> Role -> Role Permissions -> Access Control
```

### After (Position-Based)
```
User -> Position -> Position Permissions -> Access Control
```

## Managing Permissions

To assign permissions to a position:

1. Go to the positions management page
2. Select a position
3. Assign permissions to that position via the `position_permissions` table
4. All users with that position automatically get those permissions

## Migration Steps

1. Run migration: `030_refactor_security_to_positions.sql`
2. Update existing user assignments (if not using employees table)
3. Test that users can still access their respective areas
4. Archive or deprecate the old role_permissions table

## Benefits

- **Clarity**: Position titles are more descriptive than abstract roles
- **Alignment**: Security model aligns with organizational structure
- **Granularity**: Different positions can have fine-grained permissions
- **Scalability**: Easy to create new positions and assign permissions

## Breaking Changes

- `user_roles` table is no longer used for the main security system
- All references to user roles in code should use position instead
- Permission checks automatically work with position_permissions table
- Old code using `$userModel->getRoles()` will not work (method removed)

## Code Examples

### Before
```php
$roles = $userModel->getRoles();
$userModel->assignRole($userId, $roleId);
```

### After
```php
// Simply set position_id on user
$data = ['position_id' => $positionId];
$userModel->update($userId, $data);
```

## Next Steps

1. Create a Position Permissions management interface (if not already present)
2. Assign permissions to each position based on your security model
3. Test that permission checks work correctly with the new system
4. Update any documentation referencing the old role system
