# 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.

PENDING and ACTIVE users can receive role assignments; INACTIVE users are rejected. 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 not be in INACTIVE status (PENDING and ACTIVE are allowed)
- 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 INACTIVE?}
    G -->|Yes| G1[Return error: USER_NOT_ACTIVE]
    G -->|No| 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 INACTIVE status and cannot receive role assignments

## Test Cases

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