# 7. Core Workflows

### 7.1 Authentication Flow

```mermaid
sequenceDiagram
    participant User
    participant CLI
    participant AuthService
    participant ConfigManager
    participant CacheManager
    participant MSAL
    participant EntraID as Microsoft Entra ID

    User->>CLI: auth login --tenant contoso
    CLI->>ConfigManager: get_tenant("contoso")
    ConfigManager-->>CLI: TenantProfile
    CLI->>AuthService: login(tenant_profile)

    AuthService->>CacheManager: get_token("contoso")
    alt Token cached and valid
        CacheManager-->>AuthService: CachedToken
        AuthService-->>CLI: AuthToken (from cache)
    else Token missing or expired
        AuthService->>MSAL: acquire_token_for_client(scopes)
        MSAL->>EntraID: POST /token (certificate or secret)
        EntraID-->>MSAL: Access Token + Refresh Token
        MSAL-->>AuthService: TokenResponse
        AuthService->>CacheManager: save_token("contoso", token)
        AuthService-->>CLI: AuthToken (fresh)
    end

    CLI->>User: Authenticated to Contoso Ltd (expires in 59 min)
```

### 7.2 User Lookup Flow

```mermaid
sequenceDiagram
    participant User
    participant CLI
    participant UserService
    participant GraphClient
    participant AuthService
    participant GraphAPI as Microsoft Graph API

    User->>CLI: users show john@contoso.com
    CLI->>UserService: resolve_user("john@contoso.com")
    UserService->>GraphClient: get("/admin/teams/userConfigurations/{id}")

    GraphClient->>AuthService: get_token()
    AuthService-->>GraphClient: Bearer Token

    GraphClient->>GraphAPI: GET /admin/teams/userConfigurations/{id}
    GraphAPI-->>GraphClient: 200 OK + UserConfiguration JSON

    GraphClient-->>UserService: Response dict
    UserService-->>UserService: Validate with Pydantic model
    UserService-->>CLI: UserConfiguration

    CLI->>User: Display formatted table with phone, policies, status
```

### 7.3 Assign Phone Number Flow (Async)

```mermaid
sequenceDiagram
    participant User
    participant CLI
    participant NumberService
    participant LocationService
    participant GraphClient
    participant GraphAPI as Microsoft Graph API

    User->>CLI: numbers assign john@contoso.com +12065551234 --location "Seattle-HQ"

    CLI->>LocationService: validate_location("Seattle-HQ")
    LocationService->>LocationService: Search CSV cache
    LocationService-->>CLI: location_id = "93cb8a70-..."

    CLI->>NumberService: assign_number(user_id, phone, "callingPlan", location_id)

    NumberService->>GraphClient: post("/assignNumber", body)
    GraphClient->>GraphAPI: POST /assignNumber
    GraphAPI-->>GraphClient: 202 Accepted + Location header
    GraphClient-->>NumberService: operation_id from Location header

    loop Poll until complete (max 60s)
        NumberService->>GraphClient: get("/operations/{id}")
        GraphClient->>GraphAPI: GET /operations/{id}
        GraphAPI-->>GraphClient: {status: "running"}
        NumberService->>CLI: Update progress spinner
        NumberService->>NumberService: Wait 2-3 seconds
    end

    GraphAPI-->>GraphClient: {status: "succeeded"}
    GraphClient-->>NumberService: AsyncOperation (succeeded)
    NumberService-->>CLI: Success result

    CLI->>User: Assigned +12065551234 to john@contoso.com
```

### 7.4 Bulk Assign Flow

```mermaid
sequenceDiagram
    participant User
    participant CLI
    participant NumberService
    participant LocationService
    participant GraphClient
    participant GraphAPI as Microsoft Graph API

    User->>CLI: numbers bulk-assign users.csv --continue-on-error

    CLI->>CLI: Parse CSV file
    CLI->>CLI: Validate all rows (dry-run internally)

    loop For each row in CSV
        CLI->>LocationService: validate_location(row.location)
        LocationService-->>CLI: location_id or error
    end

    CLI->>User: Validated 50 rows, 2 warnings. Proceed? [Y/n]
    User->>CLI: Y

    loop For each valid row
        CLI->>NumberService: assign_number(...)
        NumberService->>GraphClient: post("/assignNumber", body)
        GraphClient->>GraphAPI: POST /assignNumber
        GraphAPI-->>GraphClient: 202 Accepted

        NumberService->>NumberService: poll_operation() until complete

        alt Success
            NumberService-->>CLI: Success
            CLI->>CLI: Update progress bar, log success
        else Failure
            NumberService-->>CLI: Error
            CLI->>CLI: Log error, continue (--continue-on-error)
        end
    end

    CLI->>CLI: Write results to bulk-assign-results.csv
    CLI->>User: Completed: 48 success, 2 failed. See results file.
```

### 7.5 Tenant Switch Flow

```mermaid
sequenceDiagram
    participant User
    participant CLI
    participant TenantService
    participant ConfigManager
    participant AuthService
    participant CacheManager

    User->>CLI: tenants switch fabrikam
    CLI->>TenantService: switch_tenant("fabrikam")

    TenantService->>ConfigManager: get_tenant("fabrikam")
    ConfigManager-->>TenantService: TenantProfile

    TenantService->>AuthService: is_authenticated("fabrikam")
    AuthService->>CacheManager: get_token("fabrikam")

    alt Token cached and valid
        CacheManager-->>AuthService: CachedToken
        AuthService-->>TenantService: true
    else Token missing or expired
        AuthService-->>TenantService: false
        TenantService->>AuthService: login(fabrikam_profile)
        AuthService-->>TenantService: AuthToken
    end

    TenantService->>ConfigManager: set_default_tenant("fabrikam")
    TenantService-->>CLI: TenantProfile

    CLI->>User: Switched to Fabrikam Inc (fabrikam)
```

### 7.6 Error Handling Flow (API Throttling)

```mermaid
sequenceDiagram
    participant CLI
    participant GraphClient
    participant GraphAPI as Microsoft Graph API

    CLI->>GraphClient: get("/admin/teams/userConfigurations")
    GraphClient->>GraphAPI: GET request
    GraphAPI-->>GraphClient: 429 Too Many Requests (Retry-After: 5)

    GraphClient->>GraphClient: Log warning, wait 5 seconds
    GraphClient->>GraphAPI: GET request (retry 1)
    GraphAPI-->>GraphClient: 429 Too Many Requests (Retry-After: 10)

    GraphClient->>GraphClient: Log warning, wait 10 seconds
    GraphClient->>GraphAPI: GET request (retry 2)
    GraphAPI-->>GraphClient: 200 OK + data

    GraphClient-->>CLI: Response data
```

---

