33800 Docs

← Retour

Backlog : Évolution connectors-api → Connectors Hub

Date ajout : 24/01/2026 Priorité : HAUTE Catégorie : DEV / INFRA Statut : À FAIRE Effort estimé : M (1-2 semaines) Bloque : qwik-interface-generator


Contexte

Marre de configurer l'auth pour chaque projet. On a besoin d'un service centralisé qui gère :


État Actuel

connectors-api (port 5400)

/api/linkedin/auth      → OAuth LinkedIn
/api/linkedin/callback  → Callback OAuth
/api/linkedin/profile   → Get profile
/api/linkedin/post      → Créer post

browser-connector (port 5401)

/api/linkedin/*  → Scraping Playwright
/api/gmail/*     → Scraping Playwright

Architecture Cible

┌─────────────────────────────────────────────────────────────────────┐
│                      CONNECTORS HUB                                  │
│                      (connectors-api v2)                             │
│                                                                      │
│  ┌────────────────────────────────────────────────────────────────┐ │
│  │  REGISTRY                                                      │ │
│  │  GET  /api/connectors              → Liste tous les connecteurs│ │
│  │  GET  /api/connectors/:id          → Détails + status          │ │
│  │  POST /api/connectors              → Ajouter connecteur custom │ │
│  │  DEL  /api/connectors/:id          → Supprimer                 │ │
│  └────────────────────────────────────────────────────────────────┘ │
│                                                                      │
│  ┌────────────────────────────────────────────────────────────────┐ │
│  │  AUTH                                                          │ │
│  │  GET  /api/connectors/:id/auth     → URL OAuth ou instructions │ │
│  │  GET  /api/connectors/:id/callback → Callback OAuth            │ │
│  │  POST /api/connectors/:id/token    → Set API Key / Bearer      │ │
│  │  DEL  /api/connectors/:id/auth     → Révoquer auth             │ │
│  └────────────────────────────────────────────────────────────────┘ │
│                                                                      │
│  ┌────────────────────────────────────────────────────────────────┐ │
│  │  PROXY FETCH (le cœur du système)                              │ │
│  │  POST /api/fetch                                               │ │
│  │  {                                                              │ │
│  │    "connector": "stripe",      // ou "my-custom-api"           │ │
│  │    "method": "GET",                                            │ │
│  │    "path": "/v1/customers",                                    │ │
│  │    "params": { "limit": 10 },                                  │ │
│  │    "body": { ... }             // pour POST/PUT                │ │
│  │  }                                                              │ │
│  │  → Injecte auth automatiquement                                │ │
│  │  → Fait la requête                                             │ │
│  │  → Retourne la réponse                                         │ │
│  └────────────────────────────────────────────────────────────────┘ │
│                                                                      │
│  ┌────────────────────────────────────────────────────────────────┐ │
│  │  SWAGGER IMPORT                                                │ │
│  │  POST /api/connectors/import/swagger                           │ │
│  │  → Upload swagger.json                                         │ │
│  │  → Crée connecteur auto-configuré (base_url, endpoints)        │ │
│  │  → Retourne config pour auth manuelle                          │ │
│  └────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘

Modèle de Données (Supabase)

Table: connectors_config

CREATE TABLE connectors.config (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  name TEXT NOT NULL UNIQUE,           -- "stripe", "github", "my-api"
  display_name TEXT,                   -- "Stripe Payments"
  base_url TEXT NOT NULL,              -- "https://api.stripe.com"

  -- Auth config
  auth_type TEXT NOT NULL,             -- "oauth2", "api_key", "bearer", "basic"
  auth_config JSONB DEFAULT '{}',      -- OAuth: client_id, scopes, etc.

  -- Swagger/OpenAPI (optionnel)
  swagger_url TEXT,                    -- URL du swagger
  swagger_spec JSONB,                  -- Spec cachée

  -- Metadata
  icon_url TEXT,
  description TEXT,
  is_builtin BOOLEAN DEFAULT false,    -- true pour LinkedIn, Stripe, etc.

  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

Table: connectors_tokens

CREATE TABLE connectors.tokens (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  connector_id UUID REFERENCES connectors.config(id) ON DELETE CASCADE,
  user_id UUID,                        -- Pour multi-tenant (null = global)

  -- Tokens
  access_token TEXT,
  refresh_token TEXT,
  api_key TEXT,                        -- Pour auth_type = api_key

  -- Metadata
  expires_at TIMESTAMPTZ,
  scopes TEXT[],
  token_metadata JSONB DEFAULT '{}',   -- Infos supplémentaires

  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW(),

  UNIQUE(connector_id, user_id)
);

Types d'Auth Supportés

Type Config Injection Header
api_key { header: "X-API-Key" } X-API-Key: {token}
bearer - Authorization: Bearer {token}
basic - Authorization: Basic {base64}
oauth2 { client_id, client_secret, scopes, auth_url, token_url } Authorization: Bearer {token}
custom { header, prefix } {header}: {prefix} {token}

Connecteurs Built-in

Connecteur Auth Type Base URL Priorité Notes
linkedin oauth2 api.linkedin.com ✅ Legacy Garder le code existant, migrer vers nouveau système
github oauth2 api.github.com P1 GitLab API similaire
o2switch api_key/basic ? P1 Hébergement, besoin réel
mailjet api_key api.mailjet.com P1 Emails transactionnels
supabase api_key {project}.supabase.co P1 BDD + Auth
stripe api_key api.stripe.com P2 Paiements (plus tard)
openai bearer api.openai.com P3 Fallback IA (Ollama prioritaire)

Phases de Dev

Phase 1 : Refacto base

□ Créer schema Supabase (connectors.config, connectors.tokens)
□ Interface TypeScript Connector
□ Migrer LinkedIn vers nouveau système
□ Endpoint GET /api/connectors (liste)
□ Endpoint GET /api/connectors/:id/status
□ Persistance tokens en DB

Phase 2 : Proxy Fetch

□ Endpoint POST /api/fetch
□ Résolution connector → config
□ Injection auth automatique
□ Gestion erreurs (401 → refresh token)
□ Logging des requêtes

Phase 3 : Connecteurs prioritaires

□ GitHub (oauth2) - accès repos, issues, API
□ O2switch (api_key/basic) - gestion hébergement
□ Mailjet (api_key) - envoi emails
□ Supabase (api_key) - BDD directe
□ Generic REST (configurable) - pour tout le reste
□ Generic OAuth2 (configurable)

Phase 4 : Connecteurs secondaires

□ Stripe (api_key) - paiements
□ OpenAI (bearer) - fallback IA

Phase 5 : Import Swagger

□ Endpoint POST /api/connectors/import/swagger
□ Parser swagger → base_url, endpoints
□ Auto-detect auth type depuis swagger security
□ Génération config connecteur

Exemple d'Usage Final

// Avant (dans chaque projet)
const stripe = new Stripe(process.env.STRIPE_KEY);
const res = await stripe.customers.list({ limit: 10 });

// Après (via Connectors Hub)
const res = await fetch('http://connectors:5400/api/fetch', {
  method: 'POST',
  body: JSON.stringify({
    connector: 'stripe',
    method: 'GET',
    path: '/v1/customers',
    params: { limit: 10 }
  })
});
// Auth injectée automatiquement, token géré par le hub
// Connecteur custom depuis Swagger
await fetch('http://connectors:5400/api/connectors/import/swagger', {
  method: 'POST',
  body: JSON.stringify({
    name: 'petstore',
    swagger_url: 'https://petstore.swagger.io/v2/swagger.json'
  })
});

// Puis utilisation immédiate
await fetch('http://connectors:5400/api/fetch', {
  method: 'POST',
  body: JSON.stringify({
    connector: 'petstore',
    method: 'GET',
    path: '/pet/findByStatus',
    params: { status: 'available' }
  })
});

Questions Ouvertes

  1. Multi-tenant : Un token par user ou tokens globaux ?
  2. Rate limiting : Gérer côté hub ou laisser les APIs répondre 429 ?
  3. Cache : Cacher les réponses GET ? TTL configurable ?
  4. Webhooks : Le hub reçoit les webhooks et les redistribue ?

GitLab