# PRD: Auvik Network Device Integration

## Introduction/Overview

This feature adds Auvik as a third data source for configuration items, complementing existing Autotask (PSA) and Datto RMM integrations. Auvik specializes in network device monitoring and will provide detailed information about switches, routers, firewalls, and other network infrastructure. The integration will match Auvik devices against existing Autotask configuration items using serial numbers, hostnames, and MAC addresses, displaying the data in a new "Auvik" tab within the configuration item modal.

**Problem Statement:** Network administrators and MSP technicians currently lack visibility into network device details (firmware versions, network interfaces, uptime, etc.) when viewing configuration items. This requires switching between multiple tools to get a complete picture of network infrastructure.

**Goal:** Provide seamless access to Auvik network device data within the existing configuration items interface, enabling users to view comprehensive device information from PSA, RMM, and network monitoring systems in one place.

## Goals

1. **Primary Goal:** Integrate Auvik API to fetch and display network device data for configuration items
2. **Matching Goal:** Achieve high match rates (target: 90%+) for network devices using serial number, hostname, and MAC address matching
3. **UX Goal:** Provide a consistent, intuitive interface that follows the existing PSA/RMM tab pattern
4. **Performance Goal:** Fetch Auvik data on-demand without impacting page load times
5. **Reliability Goal:** Gracefully handle Auvik API failures without breaking existing functionality

## User Stories

1. **As a network administrator**, I want to see Auvik device details (firmware version, uptime, interfaces) when viewing a switch in the configuration items page, so that I don't have to switch to the Auvik dashboard.

2. **As an MSP technician**, I want to quickly identify which configuration items have matching Auvik devices, so that I can verify network monitoring coverage.

3. **As a system administrator**, I want the application to automatically match Auvik devices to configuration items using serial numbers and hostnames, so that I don't have to manually correlate devices across systems.

4. **As a user**, I want the configuration items page to continue working even if Auvik is unavailable, so that temporary API issues don't block my work.

5. **As a multi-tenant MSP**, I want Auvik devices to be correctly associated with the right customer/company, so that I see relevant data for each client.

## Functional Requirements

### FR1: Auvik API Client
1.1. Create an Auvik API client service (`/lib/services/auvik-client.ts`) that handles authentication and API requests  
1.2. Use credentials from environment variables: `AUVIK_API_URL`, `AUVIK_API_KEY`, `AUVIK_API_USER`  
1.3. Implement Basic Authentication using API user and key  
1.4. Support fetching device inventory with filtering by tenant  
1.5. Include proper error handling and logging for all API calls  
1.6. Implement rate limiting to respect Auvik API limits  

### FR2: Device Matching Logic
2.1. Match Auvik devices to Autotask configuration items using the following priority order:
   - First: Serial number (exact match, case-insensitive)
   - Second: Hostname (exact match, case-insensitive)
   - Third: MAC address (exact match, normalized format)  
2.2. Return only the first match found (no multiple matches per device)  
2.3. Log matching results for debugging purposes  
2.4. Handle cases where Auvik devices have multiple MAC addresses (match any)  

### FR3: Multi-Tenant Support
3.1. Fetch Auvik tenant list from API  
3.2. Map Auvik tenants to Autotask companies using tenant name matching  
3.3. Filter Auvik device queries by tenant when viewing a specific company's devices  
3.4. Handle cases where tenant mapping cannot be determined (show all devices)  

### FR4: API Endpoint
4.1. Create endpoint `/api/auvik/devices` that accepts query parameters:
   - `companyId`: Autotask company ID (optional)
   - `companyName`: Company name for tenant matching (optional)  
4.2. Return array of Auvik devices filtered by tenant if company info provided  
4.3. Include device details: name, serial number, IP addresses, MAC addresses, device type, firmware version, manufacturer, model, online status, last seen timestamp  
4.4. Return empty array (not error) if Auvik API is unavailable  
4.5. Log errors to console but return 200 status with empty data  

### FR5: Configuration Item Modal - Auvik Tab
5.1. Add "Auvik" tab to the configuration item modal (`/components/configuration-items/config-item-modal.tsx`)  
5.2. Create new component `/components/configuration-items/auvik-tab.tsx` following the pattern of `rmm-tab.tsx`  
5.3. Display Auvik device information in organized sections:
   - **Basic Information:** Device name, device type, serial number, manufacturer, model
   - **Network Information:** IP addresses, MAC addresses, subnet, VLAN
   - **Status Information:** Online/offline status, last seen, uptime
   - **Firmware Information:** Firmware version, last updated
   - **Network Interfaces:** List of interfaces with status and speed  
5.4. Show "No Auvik data available" message when no matching device is found  
5.5. Display Auvik online/offline status badge in tab header  

### FR6: Configuration Items Page - Auvik Indicator
6.1. Add "Auvik" column to the configuration items table (after RMM column)  
6.2. Display green checkmark icon when Auvik device is matched  
6.3. Display gray X icon when no Auvik match exists  
6.4. Update table column count and responsive layout accordingly  

### FR7: Configuration Item Detail API Enhancement
7.1. Modify `/api/configuration-items/[id]/route.ts` to fetch matching Auvik device  
7.2. Use the same matching logic as FR2 (serial number → hostname → MAC address)  
7.3. Include Auvik device data in API response: `{ autotaskDevice, rmmDevice, auvikDevice, companyName }`  
7.4. Handle Auvik API failures gracefully (return null for auvikDevice)  

### FR8: TypeScript Types
8.1. Create Auvik type definitions in `/lib/types/auvik.ts`:
   - `AuvikDevice` interface with all device properties
   - `AuvikTenant` interface for tenant information
   - `AuvikNetworkInterface` interface for network interface details  
8.2. Export types for use across the application  

### FR9: Error Handling & Logging
9.1. Log all Auvik API errors to console with descriptive messages  
9.2. Log successful device matches with match method (serial/hostname/MAC)  
9.3. Log tenant mapping results  
9.4. Never throw errors that would break the configuration items page  
9.5. Display user-friendly error messages in Auvik tab if data fetch fails  

### FR10: Real-Time Data Fetching
10.1. Fetch Auvik data on-demand when configuration items page loads  
10.2. Fetch Auvik device details when configuration item modal opens  
10.3. Do not cache Auvik data (always fetch fresh data)  
10.4. Implement loading states while fetching Auvik data  

## Non-Goals (Out of Scope)

1. **Database Sync:** Auvik data will NOT be synced to the PostgreSQL database (real-time only)
2. **Auvik Alerts:** Will not display Auvik alerts or notifications
3. **Auvik Configuration:** Will not allow modifying Auvik device settings from the application
4. **Network Topology:** Will not display Auvik network topology maps
5. **Historical Data:** Will not show historical performance metrics or trends
6. **Bulk Operations:** Will not support bulk actions on Auvik devices
7. **Auvik-Only View:** Will not create a dedicated page for viewing only Auvik devices
8. **Custom Field Mapping:** Will not support custom field mapping between Auvik and Autotask

## Design Considerations

### UI Components
- Follow existing design patterns from PSA and RMM tabs
- Use same Card, Badge, Label components from shadcn/ui
- Maintain consistent spacing, typography, and color scheme
- Use Lucide icons for network-related visuals (Network, Wifi, Router, etc.)

### Tab Layout
```
┌─────────────────────────────────────────────┐
│  PSA Data  │  RMM Data  │  Auvik Data      │
└─────────────────────────────────────────────┘
│                                             │
│  ┌─────────────────┐  ┌──────────────────┐ │
│  │ Basic Info      │  │ Network Info     │ │
│  │ - Name          │  │ - IP Addresses   │ │
│  │ - Type          │  │ - MAC Addresses  │ │
│  │ - Serial        │  │ - Interfaces     │ │
│  └─────────────────┘  └──────────────────┘ │
│                                             │
│  ┌─────────────────┐  ┌──────────────────┐ │
│  │ Status          │  │ Firmware         │ │
│  │ - Online        │  │ - Version        │ │
│  │ - Last Seen     │  │ - Last Updated   │ │
│  └─────────────────┘  └──────────────────┘ │
└─────────────────────────────────────────────┘
```

### Status Badges
- **Online:** Green badge with Wifi icon
- **Offline:** Gray badge with X icon
- **Unknown:** Yellow badge with AlertCircle icon

## Technical Considerations

### API Integration
- Auvik API uses Basic Authentication (username:password encoded in Base64)
- API endpoint: `https://auvikapi.us1.my.auvik.com/v1/` (or region-specific)
- Rate limits: Respect Auvik's rate limiting (typically 1000 requests/hour)
- Pagination: Auvik uses cursor-based pagination for large result sets

### Matching Algorithm
```typescript
function matchAuvikDevice(
  autotaskDevice: ConfigurationItem,
  auvikDevices: AuvikDevice[]
): AuvikDevice | null {
  // Priority 1: Serial number
  if (autotaskDevice.serialNumber) {
    const match = auvikDevices.find(d => 
      d.serialNumber?.toLowerCase() === autotaskDevice.serialNumber?.toLowerCase()
    );
    if (match) return match;
  }
  
  // Priority 2: Hostname
  if (autotaskDevice.rmmDeviceAuditHostname) {
    const match = auvikDevices.find(d => 
      d.deviceName?.toLowerCase() === autotaskDevice.rmmDeviceAuditHostname?.toLowerCase()
    );
    if (match) return match;
  }
  
  // Priority 3: MAC address
  if (autotaskDevice.rmmDeviceAuditMacAddress) {
    const normalizedMac = normalizeMacAddress(autotaskDevice.rmmDeviceAuditMacAddress);
    const match = auvikDevices.find(d => 
      d.macAddresses?.some(mac => normalizeMacAddress(mac) === normalizedMac)
    );
    if (match) return match;
  }
  
  return null;
}
```

### Dependencies
- No new npm packages required (use built-in fetch)
- Leverage existing service patterns (`autotask-client.ts`, `datto-rmm-client.ts`)
- Use existing UI components from shadcn/ui

### File Structure
```
/lib/services/auvik-client.ts          # Auvik API client
/lib/services/auvik-factory.ts         # Singleton factory for client
/lib/types/auvik.ts                    # TypeScript types
/app/api/auvik/devices/route.ts        # API endpoint for device list
/components/configuration-items/auvik-tab.tsx  # Auvik tab component
```

### Environment Variables
```bash
AUVIK_API_URL=https://auvikapi.us1.my.auvik.com/v1
AUVIK_API_USER=your-api-user
AUVIK_API_KEY=your-api-key
```

## Success Metrics

1. **Match Rate:** 90%+ of network devices (switches, routers, firewalls) with serial numbers are successfully matched to Auvik devices
2. **Performance:** Auvik data loads within 2 seconds for typical company (< 100 devices)
3. **Reliability:** Configuration items page remains functional even when Auvik API returns errors (100% uptime for core functionality)
4. **Adoption:** Network administrators use Auvik tab for at least 50% of network device views within first month
5. **Error Rate:** Less than 1% of Auvik API calls result in unhandled errors

## Open Questions

1. **Regional API Endpoints:** Should we support multiple Auvik regions (US1, US2, EU, AU) or assume single region?
   - *Recommendation:* Make `AUVIK_API_URL` configurable to support any region

2. **Tenant Name Matching:** What if Auvik tenant name doesn't exactly match Autotask company name?
   - *Recommendation:* Use fuzzy matching or allow manual tenant-to-company mapping in future iteration

3. **Device Type Filtering:** Should we only show Auvik data for network devices (switches, routers, firewalls) or all device types?
   - *Recommendation:* Show for all devices but prioritize network devices in matching

4. **API Key Rotation:** How should we handle API key expiration/rotation?
   - *Recommendation:* Log clear error messages when authentication fails, require manual .env update

5. **Multiple Auvik Instances:** Do we need to support multiple Auvik accounts (for MSPs with multiple Auvik instances)?
   - *Recommendation:* Out of scope for v1, single Auvik instance only

## Implementation Notes for Developers

### Getting Started
1. Review existing RMM integration (`datto-rmm-client.ts`, `rmm-tab.tsx`) as reference
2. Read Auvik API documentation: https://support.auvik.com/hc/en-us/articles/360031007111
3. Set up Auvik API credentials in `.env` file
4. Test API connectivity using Postman or curl before coding

### Testing Checklist
- [ ] Verify authentication works with provided credentials
- [ ] Test device matching with various scenarios (serial match, hostname match, MAC match, no match)
- [ ] Test with company that has no Auvik tenant
- [ ] Test with Auvik API unavailable (network error)
- [ ] Test with large device lists (100+ devices)
- [ ] Verify UI displays correctly on mobile/tablet/desktop
- [ ] Check that existing PSA/RMM functionality is not affected

### Code Review Focus Areas
- Error handling completeness
- TypeScript type safety
- Consistent code style with existing services
- Proper logging for debugging
- Performance (avoid N+1 queries)
