# 4. Data Models

### 4.1 UserConfiguration

**Purpose:** Represents a Teams user's voice configuration, including phone number, license status, and policy assignments.

| Attribute | Type | Description |
|-----------|------|-------------|
| `id` | UUID | User's Entra object ID |
| `user_principal_name` | str | User's UPN (email format) |
| `display_name` | str | User's display name |
| `account_type` | Enum | `user`, `resourceAccount`, `guest`, `sfbOnPremUser`, `unknown` |
| `is_enterprise_voice_enabled` | bool | Whether voice is enabled |
| `feature_types` | list[str] | Features like `Teams`, `CallingPlan`, `DirectRouting` |
| `telephone_numbers` | list[TelephoneNumber] | Assigned phone numbers |
| `effective_policy_assignments` | list[PolicyAssignment] | All effective policies with source |

**Relationships:**
- Has many `TelephoneNumber` (typically 0-1 primary)
- Has many `PolicyAssignment` (one per policy type)

### 4.2 NumberAssignment

**Purpose:** Represents a phone number in the tenant's inventory with its assignment status and capabilities.

| Attribute | Type | Description |
|-----------|------|-------------|
| `id` | str | Graph API resource ID |
| `telephone_number` | str | E.164 format (+12065551234) |
| `number_type` | Enum | `callingPlan`, `directRouting`, `operatorConnect` |
| `assignment_status` | Enum | `unassigned`, `userAssigned`, `conferenceAssigned`, `voiceApplicationAssigned` |
| `activation_state` | Enum | `activated`, `assignmentPending`, `assignmentFailed`, `updatePending`, `updateFailed` |
| `capabilities` | list[str] | `userAssignment`, `conferenceAssignment`, `voiceApplicationAssignment` |
| `assignment_target_id` | UUID | Assigned user's object ID (if assigned) |
| `assignment_category` | Enum | `primary`, `private`, `alternate` (if assigned) |
| `location_id` | UUID | Emergency location ID |
| `civic_address_id` | UUID | Parent civic address ID |
| `city` | str | City where number is provisioned |
| `iso_country_code` | str | Country code (e.g., "US") |

**Relationships:**
- Belongs to one `UserConfiguration` (when assigned)
- References one `EmergencyLocation` (via location_id)

### 4.3 PolicyAssignment

**Purpose:** Represents a policy assigned to a user, including the assignment source (direct, group, or global).

| Attribute | Type | Description |
|-----------|------|-------------|
| `policy_type` | str | Policy type (e.g., `TeamsCallingPolicy`, `TenantDialPlan`) |
| `policy_id` | str | Policy identifier |
| `display_name` | str | Human-readable policy name |
| `assignment_type` | Enum | `direct`, `group`, `global` |
| `group_id` | UUID | Group ID if assigned via group |

**Relationships:**
- Belongs to one `UserConfiguration`
- References one `Policy` (from CSV cache)

### 4.4 EmergencyLocation

**Purpose:** Represents an emergency location for E911 compliance (from PowerShell CSV export).

| Attribute | Type | Description |
|-----------|------|-------------|
| `location_id` | UUID | Unique location identifier (used in number assignment) |
| `civic_address_id` | UUID | Parent civic address ID |
| `description` | str | Location name (e.g., "Main Office - Floor 3") |
| `company_name` | str | Organization name |
| `address` | str | Full street address |
| `city` | str | City name |
| `state_or_province` | str | State/province code |
| `postal_code` | str | ZIP/postal code |
| `country_or_region` | str | Country code (e.g., "US") |
| `is_default` | bool | Whether this is the default location for the civic address |

**Relationships:**
- Referenced by `NumberAssignment` (via location_id)

### 4.5 TenantProfile

**Purpose:** Represents a configured tenant for multi-tenant CLI operations (stored in config.toml).

| Attribute | Type | Description |
|-----------|------|-------------|
| `name` | str | Profile name (e.g., "contoso") |
| `tenant_id` | UUID | Microsoft Entra tenant ID |
| `client_id` | UUID | App registration client ID |
| `display_name` | str | Human-readable tenant name |
| `auth_method` | Enum | `certificate`, `client-secret` |
| `cert_path` | str | Path to certificate file (if certificate auth) |
| `default_location` | str | Default emergency location name for this tenant |

**Relationships:**
- Has cached authentication tokens
- Has associated CSV cache files

### 4.6 AsyncOperation

**Purpose:** Represents a long-running Graph API operation (assign/unassign number).

| Attribute | Type | Description |
|-----------|------|-------------|
| `id` | str | Operation ID (base64 encoded) |
| `status` | Enum | `notStarted`, `running`, `succeeded`, `failed`, `skipped` |
| `created_datetime` | datetime | When operation was created |
| `numbers` | list[OperationNumber] | Status per phone number in operation |

**Relationships:**
- Created by `NumberService.assign()` and `NumberService.unassign()`

### 4.7 Policy (Reference Data)

**Purpose:** Represents a policy definition from CSV cache (for validation and display).

| Attribute | Type | Description |
|-----------|------|-------------|
| `policy_type` | str | Policy type identifier |
| `policy_name` | str | Policy name (Identity) |
| `policy_id` | str | Policy ID for API calls |
| `description` | str | Policy description |
| `is_global` | bool | Whether this is the global/default policy |

**Relationships:**
- Referenced by `PolicyAssignment`

---

