agmission/Development/server/docs/archived/PARTNER_AUTH_REFACTORING_VISUAL.md

18 KiB

Partner Authentication Refactoring - Visual Guide

Before vs After Architecture

Before Refactoring

┌──────────────────────────────────────────────────────────┐
│         testPartnerAuth_post() Controller                │
│         (Testing authentication)                         │
└────────────────────┬─────────────────────────────────────┘
                     │
                     ▼
┌──────────────────────────────────────────────────────────┐
│      authenticateAndCache()                              │
│      ┌────────────────────────────────────────────┐     │
│      │ 1. Make API call to SatLoc                 │     │
│      │ 2. Validate response                       │     │
│      │ 3. Build auth data                         │     │
│      │ 4. Cache in Redis ← ⚠️ SIDE EFFECT         │     │
│      │ 5. Return auth data                        │     │
│      └────────────────────────────────────────────┘     │
└──────────────────────────────────────────────────────────┘
         │
         ▼
┌────────────────┐
│  Redis Cache   │ ← ⚠️ Polluted during testing
└────────────────┘

⚠️ Problems:
- Testing pollutes cache
- Tight coupling of concerns
- Side effects in test endpoints

After Refactoring

┌──────────────────────────────────────────────────────────┐
│         testPartnerAuth_post() Controller                │
│         (Testing authentication)                         │
└────────────────────┬─────────────────────────────────────┘
                     │
                     ▼
┌──────────────────────────────────────────────────────────┐
│      authenticate()                                      │
│      ┌────────────────────────────────────────────┐     │
│      │ 1. Make API call to SatLoc                 │     │
│      │ 2. Validate response                       │     │
│      │ 3. Build auth data                         │     │
│      │ 4. Return auth data                        │     │
│      │                                            │     │
│      │ ✅ NO CACHING - Pure function              │     │
│      └────────────────────────────────────────────┘     │
└──────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────┐
│      Production Flow                                     │
└────────────────────┬─────────────────────────────────────┘
                     │
                     ▼
┌──────────────────────────────────────────────────────────┐
│      authenticateAndCache()                              │
│      ┌────────────────────────────────────────────┐     │
│      │ 1. Call authenticate() ← REUSES            │     │
│      │ 2. Cache result in Redis                   │     │
│      │ 3. Return auth data                        │     │
│      └────────────────────────────────────────────┘     │
└──────────────────────┬───────────────────────────────────┘
                       │
                       ▼
              ┌────────────────┐
              │  Redis Cache   │ ← ✅ Only cached in production
              └────────────────┘

✅ Benefits:
- Separation of concerns
- No cache pollution during testing
- Code reusability
- Single source of truth

Method Comparison

authenticate() - Pure Authentication

┌─────────────────────────────────────────────┐
│         authenticate(credentials)           │
├─────────────────────────────────────────────┤
│                                             │
│  INPUT:                                     │
│  • credentials { username, password }       │
│  • customerId (for logging)                 │
│                                             │
│  PROCESS:                                   │
│  1. Call SatLoc API /AuthenticateAPIUser    │
│  2. Parse response                          │
│  3. Build auth data structure               │
│  4. Return auth data                        │
│                                             │
│  OUTPUT:                                    │
│  {                                          │
│    userId: "...",                           │
│    companyId: "...",                        │
│    expiresAt: 1234567890,                   │
│    lastHealthCheck: 1234567890,             │
│    originalResponse: {...}                  │
│  }                                          │
│                                             │
│  SIDE EFFECTS: None ✅                      │
│                                             │
└─────────────────────────────────────────────┘

authenticateAndCache() - With Caching

┌─────────────────────────────────────────────┐
│    authenticateAndCache(credentials)        │
├─────────────────────────────────────────────┤
│                                             │
│  INPUT:                                     │
│  • credentials { username, password }       │
│  • customerId (for caching key)             │
│                                             │
│  PROCESS:                                   │
│  1. Call authenticate() ← REUSES            │
│     └─ Returns auth data                    │
│  2. Calculate TTL from expiresAt            │
│  3. Store in Redis with TTL                 │
│  4. Return auth data                        │
│                                             │
│  OUTPUT:                                    │
│  {                                          │
│    userId: "...",                           │
│    companyId: "...",                        │
│    expiresAt: 1234567890,                   │
│    lastHealthCheck: 1234567890,             │
│    originalResponse: {...}                  │
│  }                                          │
│                                             │
│  SIDE EFFECTS:                              │
│  • Stores auth data in Redis ✅             │
│  • Sets TTL on cache entry ✅               │
│                                             │
└─────────────────────────────────────────────┘

Usage Decision Tree

                Need to authenticate?
                        │
                        ▼
            ┌───────────────────────┐
            │ What's the use case?  │
            └───────────┬───────────┘
                        │
        ┌───────────────┼───────────────┐
        │                               │
        ▼                               ▼
┌───────────────┐               ┌───────────────┐
│   Testing?    │               │  Production?  │
│   Validation? │               │  Normal flow? │
└───────┬───────┘               └───────┬───────┘
        │                               │
        ▼                               ▼
┌────────────────────┐         ┌────────────────────┐
│  authenticate()    │         │authenticateAndCache│
│                    │         │                    │
│ ✅ No caching      │         │ ✅ With caching    │
│ ✅ Pure function   │         │ ✅ Reuses auth()   │
│ ✅ For testing     │         │ ✅ For production  │
└────────────────────┘         └────────────────────┘

Code Examples

Example 1: Testing Endpoint

// controllers/partner.js

async function testPartnerAuth_post(req, res) {
  const { customerId, partnerId, username, password } = req.body;
  
  // Validate partner system user
  const partnerSystemUser = await findAndValidatePartnerSystemUser(
    customerId, partnerId, { requireActive: true, username, password }
  );
  
  // Get partner service
  const partnerService = partnerServiceFactory.getService(partnerCode);
  const credentials = partnerConfig.getApiCredentials(partnerSystemUser, partnerCode);
  
  // ✅ Use authenticate() - no caching for testing
  const authResult = await partnerService.authenticate(credentials, customerId);
  
  res.json({
    authSuccess: true,
    userId: authResult.userId,
    companyId: authResult.companyId
  });
}

Example 2: Production Flow

// services/partner_sync_service.js

async function syncPartnerData(customerId, partnerId) {
  const partnerService = partnerServiceFactory.getService('SATLOC');
  const credentials = getCredentials(customerId);
  
  // ✅ Use authenticateAndCache() - with caching for production
  const authData = await partnerService.authenticateAndCache(credentials, customerId);
  
  // Use authData for API calls
  const aircraftList = await partnerService.getAircraftList(authData);
  
  return aircraftList;
}

Example 3: Getting Cached or Fresh Auth

// services/satloc_service.js

async getApiCredentials(credentials, customerId) {
  // Check cache first
  const cached = await this.cache.getAuth(this.partnerCode, customerId);
  
  if (cached && cached.expiresAt > Date.now()) {
    // ✅ Return cached auth
    return cached;
  }
  
  // Cache miss - authenticate and cache
  // ✅ Uses authenticateAndCache() internally
  const authData = await this.authenticateAndCache(credentials, customerId);
  
  return authData;
}

Sequence Diagrams

Testing Flow (No Caching)

┌──────────┐   ┌────────────┐   ┌─────────┐   ┌───────────┐
│  Client  │   │ Controller │   │ Service │   │ SatLoc API│
└────┬─────┘   └─────┬──────┘   └────┬────┘   └─────┬─────┘
     │               │               │              │
     │ POST testAuth │               │              │
     │──────────────>│               │              │
     │               │               │              │
     │               │ authenticate()│              │
     │               │──────────────>│              │
     │               │               │              │
     │               │               │ GET /Auth... │
     │               │               │─────────────>│
     │               │               │              │
     │               │               │ Success      │
     │               │               │<─────────────│
     │               │               │              │
     │               │ authData      │              │
     │               │<──────────────│              │
     │               │               │              │
     │ 200 OK        │               │              │
     │<──────────────│               │              │
     │               │               │              │
     
✅ NO CACHE OPERATIONS - Clean test

Production Flow (With Caching)

┌──────────┐   ┌─────────┐   ┌─────────┐   ┌───────────┐   ┌───────┐
│ Sync Job │   │ Service │   │ Service │   │ SatLoc API│   │ Redis │
└────┬─────┘   └────┬────┘   └────┬────┘   └─────┬─────┘   └───┬───┘
     │              │              │              │             │
     │ sync data    │              │              │             │
     │─────────────>│              │              │             │
     │              │              │              │             │
     │              │authenticateAn│              │             │
     │              │dCache()      │              │             │
     │              │─────────────>│              │             │
     │              │              │              │             │
     │              │              │authenticate()│             │
     │              │              │─────────────>│             │
     │              │              │              │             │
     │              │              │ GET /Auth... │             │
     │              │              │─────────────>│             │
     │              │              │              │             │
     │              │              │ Success      │             │
     │              │              │<─────────────│             │
     │              │              │              │             │
     │              │              │ authData     │             │
     │              │              │<─────────────│             │
     │              │              │              │             │
     │              │              │ setAuth()    │             │
     │              │              │──────────────────────────>│
     │              │              │              │             │
     │              │              │ OK           │             │
     │              │              │<──────────────────────────│
     │              │              │              │             │
     │              │ authData     │              │             │
     │              │<─────────────│              │             │
     │              │              │              │             │
     │ data synced  │              │              │             │
     │<─────────────│              │              │             │
     │              │              │              │             │

✅ CACHED FOR REUSE - Efficient production flow

Benefits Summary

Aspect Before After
Test Isolation Tests pollute cache Tests are isolated
Code Reuse Duplicated logic Shared authenticate()
Maintainability Coupled concerns Separated concerns
Debugging Cache interference Clear flow
Performance Unnecessary caching Cache only when needed
Testing Complex mocking Simple unit tests

This refactoring provides a cleaner, more maintainable architecture while maintaining full backward compatibility!