# AssignRoleToUser

## Permission Scope

roleAssignment

## Overview

AssignRoleToUser creates an association between a role and a user, granting the user all permissions associated with that role. This command enables granting access to users by assigning them roles rather than managing permissions individually.

Only ACTIVE users can receive role assignments. The operation is idempotent - assigning the same role to a user twice does not create duplicate records or return an error.

## Business Rules

- User must exist in the system
- Role must exist in the system
- User must be in ACTIVE status
- Role must be in ACTIVE status
- Operation is idempotent (assigning same role twice is not an error)
- Creates UserRole association record if not already present
- Generates ROLE_ASSIGNED audit event with actor ID, user ID, role ID, and timestamp

## Process Flow

```mermaid
flowchart TD
    A[Receive assign request] --> B{User exists?}
    B -->|No| C[Return error: USER_NOT_FOUND]
    B -->|Yes| D{Role exists?}
    D -->|No| E[Return error: ROLE_NOT_FOUND]
    D -->|Yes| F{Role is ACTIVE?}
    F -->|No| F1[Return error: ROLE_NOT_ACTIVE]
    F -->|Yes| G{User is ACTIVE?}
    G -->|No| G1[Return error: USER_NOT_ACTIVE]
    G -->|Yes| H{Assignment exists?}
    H -->|Yes| I[Return success - idempotent]
    H -->|No| J[Create UserRole record]
    J --> K[Log ROLE_ASSIGNED audit event]
    K --> L[Return success]
```

## External Dependencies

- None

## Error Scenarios

- **USER_NOT_FOUND**: Specified user ID does not exist
- **ROLE_NOT_FOUND**: Specified role ID does not exist
- **ROLE_NOT_ACTIVE**: Role is not in ACTIVE status and cannot be used for this operation
- **USER_NOT_ACTIVE**: User is in PENDING or INACTIVE status - return error indicating only ACTIVE users can receive role assignments

## Test Cases

- throws when user does not exist
- throws when role does not exist
- throws when role is INACTIVE
- throws when user is PENDING
- throws when user is INACTIVE
- returns success when assignment already exists (idempotent)
- creates UserRole and recomputes permissions
