@company-manager/docs
Integrations

Systèmes Externes

Guide d'intégration avec les systèmes externes.

Intégration Systèmes Externes

Guide complet pour l'intégration de Company Manager avec des systèmes externes.

Architecture

Adaptateur Générique

// lib/external/adapter.ts
interface ExternalSystemAdapter {
  connect(): Promise<void>;
  disconnect(): Promise<void>;
  sync<T>(entity: T, type: string): Promise<T>;
  query<T>(params: QueryParams): Promise<T[]>;
}

class BaseAdapter implements ExternalSystemAdapter {
  protected config: SystemConfig;
  protected client: any;

  constructor(config: SystemConfig) {
    this.config = config;
  }

  async connect() {
    // Implémentation de la connexion
  }

  async disconnect() {
    // Nettoyage des ressources
  }

  async sync<T>(entity: T, type: string): Promise<T> {
    // Logique de synchronisation
    return entity;
  }

  async query<T>(params: QueryParams): Promise<T[]> {
    // Logique de requête
    return [];
  }
}

Synchronisation

Service de Synchronisation

// services/SyncService.ts
class SyncService {
  private adapter: ExternalSystemAdapter;
  private queue: Queue;

  constructor(adapter: ExternalSystemAdapter) {
    this.adapter = adapter;
    this.queue = new Queue();
  }

  async syncEntity<T>(entity: T, type: string) {
    try {
      await this.queue.add(async () => {
        await this.adapter.sync(entity, type);
      });
    } catch (error) {
      await this.handleSyncError(error, entity);
    }
  }

  private async handleSyncError(error: Error, entity: any) {
    await prisma.syncError.create({
      data: {
        entityId: entity.id,
        error: error.message,
        timestamp: new Date(),
      },
    });
  }
}

Gestion des Entités

// lib/sync/entities.ts
interface SyncableEntity {
  id: string;
  updatedAt: Date;
  syncedAt?: Date;
}

class EntitySync<T extends SyncableEntity> {
  async syncAll(entities: T[]) {
    const updates = entities.filter(this.needsSync);
    
    for (const entity of updates) {
      await this.syncOne(entity);
    }
  }

  private needsSync(entity: T): boolean {
    return !entity.syncedAt || 
           entity.updatedAt > entity.syncedAt;
  }
}

Cache

Configuration LRU

// lib/cache/lru.ts
import LRU from 'lru-cache';

export const cache = new LRU({
  max: 500,
  ttl: 1000 * 60 * 5, // 5 minutes
});

export const withCache = async <T>(
  key: string,
  fn: () => Promise<T>
): Promise<T> => {
  const cached = cache.get<T>(key);
  if (cached) return cached;

  const result = await fn();
  cache.set(key, result);
  return result;
};

Authentification

Gestionnaire de Session

// lib/auth/session.ts
class SessionManager {
  private token: string | null = null;
  private expiresAt: Date | null = null;

  async getToken(): Promise<string> {
    if (this.isTokenValid()) {
      return this.token!;
    }

    return this.refreshToken();
  }

  private isTokenValid(): boolean {
    return (
      this.token != null &&
      this.expiresAt != null &&
      this.expiresAt > new Date()
    );
  }
}

Webhooks

Gestionnaire de Webhooks

// lib/webhooks/handler.ts
class WebhookHandler {
  async handleEvent(event: WebhookEvent) {
    switch (event.type) {
      case 'entity.updated':
        await this.handleEntityUpdate(event.data);
        break;
      case 'entity.deleted':
        await this.handleEntityDelete(event.data);
        break;
      default:
        throw new Error(`Unknown event type: ${event.type}`);
    }
  }

  private async handleEntityUpdate(data: any) {
    await prisma.$transaction(async (tx) => {
      // Mise à jour de l'entité
    });
  }
}

Monitoring

Métriques

// lib/monitoring/metrics.ts
class SyncMetrics {
  private metrics: Map<string, number> = new Map();

  recordSync(entityType: string, duration: number) {
    const current = this.metrics.get(entityType) || 0;
    this.metrics.set(entityType, current + 1);
  }

  async reportMetrics() {
    await prisma.syncMetrics.createMany({
      data: Array.from(this.metrics.entries()).map(
        ([type, count]) => ({
          type,
          count,
          timestamp: new Date(),
        })
      ),
    });
  }
}

Gestion des Erreurs

Retry Logic

// lib/retry/backoff.ts
const retry = async <T>(
  fn: () => Promise<T>,
  options: RetryOptions
): Promise<T> => {
  let lastError: Error;
  
  for (let i = 0; i < options.maxAttempts; i++) {
    try {
      return await fn();
    } catch (error) {
      lastError = error;
      await sleep(options.backoff(i));
    }
  }
  
  throw lastError;
};

Bonnes Pratiques

  1. Résilience

    • Gestion des erreurs robuste
    • Retry avec backoff exponentiel
    • Circuit breaker pour les appels externes
  2. Performance

    • Cache efficace
    • Traitement par lots
    • Connexions réutilisées
  3. Sécurité

    • Authentification sécurisée
    • Validation des données
    • Audit des opérations