> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devin.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrer 50 fichiers de REST à GraphQL

export const UseCaseHero = ({title, description, prompt, category, features, devinUrl, agent, intent, playbookId, type}) => {
  const encodedPrompt = encodeURIComponent(prompt || '');
  const tag = 'docs-use-case-gallery';
  const utm = 'utm_source=docs&utm_medium=use-case-gallery&utm_campaign=hero-cta';
  const agentParams = (agent ? '&agent=' + agent : '') + (intent ? '&intent=' + intent : '') + (playbookId ? '&playbookId=' + playbookId : '');
  const devinHref = type === 'schedule' ? 'https://app.devin.ai/settings/schedules/create?' + utm + agentParams + (prompt ? '&prompt=' + encodedPrompt : '') : type === 'review' ? 'https://app.devin.ai/review?' + utm : agent === 'ada' ? 'https://app.devin.ai/search?' + utm + '&noSubmit=true' + (prompt ? '&prompt=' + encodedPrompt : '') : devinUrl ? devinUrl.includes('?') ? devinUrl + '&' + utm + agentParams : devinUrl + '?' + utm + agentParams : prompt ? 'https://app.devin.ai/?tags=' + tag + '&' + utm + agentParams + '&prompt=' + encodedPrompt : 'https://app.devin.ai/?' + utm + agentParams;
  const buttonLabel = type === 'schedule' ? 'Schedule in Devin ↗' : type === 'review' ? 'Set Up Devin Review ↗' : agent === 'advanced' ? 'Try in Devin ↗' : agent === 'dana' ? 'Try in Dana ↗' : agent === 'ada' ? 'Try in Ask Devin ↗' : 'Try in Devin ↗';
  const featureList = features ? features.split(',').map(f => f.trim()) : [];
  return <div className="uc-hero">
      <div className="uc-hero-inner">
        <div className="uc-hero-left">
          <h1 className="uc-hero-title">{title}</h1>
          <p className="uc-hero-desc">{description}</p>
          <div>
            <a href={devinHref} target="_blank" rel="noopener noreferrer" className="try-in-devin-btn">
              {buttonLabel}
            </a>
          </div>
        </div>
        <div className="uc-hero-meta">
          <div className="uc-meta-item">
            <span className="uc-meta-label">Author</span>
            <span className="uc-meta-value">Cognition</span>
          </div>
          <div className="uc-meta-item">
            <span className="uc-meta-label">Category</span>
            <span className="uc-meta-value">{category}</span>
          </div>
          {featureList.length > 0 && <div className="uc-meta-item">
              <span className="uc-meta-label">Features</span>
              <span className="uc-meta-value">{featureList.join(', ')}</span>
            </div>}
        </div>
      </div>
    </div>;
};

export const PromptBlock = ({children, type, agent, intent, playbookId}) => {
  var utm = 'utm_source=docs&utm_medium=use-case-gallery&utm_campaign=prompt-block';
  var tag = 'docs-use-case-gallery';
  var agentParams = (agent ? '&agent=' + agent : '') + (intent ? '&intent=' + intent : '') + (playbookId ? '&playbookId=' + playbookId : '');
  var label = type === 'schedule' ? 'Schedule in Devin' : type === 'playbook' ? 'Create Playbook' : type === 'knowledge' ? 'Add to Knowledge' : agent === 'advanced' ? 'Try in Devin' : agent === 'dana' ? 'Try in Dana' : agent === 'ada' ? 'Try in Ask Devin' : 'Try in Devin';
  var buildUrl = function (text) {
    var encoded = encodeURIComponent(text);
    if (type === 'schedule') return 'https://app.devin.ai/settings/schedules/create?' + utm + agentParams + '&prompt=' + encoded;
    if (type === 'playbook') return 'https://app.devin.ai/settings/playbooks/create?' + utm + '&body=' + encoded;
    if (type === 'knowledge') return 'https://app.devin.ai/knowledge?' + utm + '&body=' + encoded;
    if (agent === 'ada') return 'https://app.devin.ai/search?' + utm + '&noSubmit=true&prompt=' + encoded;
    return 'https://app.devin.ai/?tags=' + tag + '&' + utm + agentParams + '&prompt=' + encoded;
  };
  const ref = React.useRef(null);
  const [href, setHref] = React.useState('#');
  React.useEffect(() => {
    if (!ref.current) return;
    var codeEl = ref.current.querySelector('pre code');
    if (codeEl) {
      var text = codeEl.textContent.trim();
      if (text) setHref(buildUrl(text));
    }
    var header = ref.current.querySelector('[data-component-part="code-block-header"]');
    if (header && !header.querySelector('.prompt-block-devin-link')) {
      var link = document.createElement('a');
      link.href = href;
      link.target = '_blank';
      link.rel = 'noopener noreferrer';
      link.className = 'prompt-block-devin-link';
      link.style.cssText = 'display:inline-flex;align-items:center;gap:6px;text-decoration:none;color:#fff;font-size:11px;font-weight:500;padding:4px 10px;border-radius:6px;white-space:nowrap;background:#317CFF;transition:background 0.2s;margin-left:8px;';
      link.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg> ' + label;
      link.onmouseenter = function () {
        link.style.background = '#2968D9';
      };
      link.onmouseleave = function () {
        link.style.background = '#317CFF';
      };
      header.appendChild(link);
    }
    var existingLink = ref.current.querySelector('.prompt-block-devin-link');
    if (existingLink && href !== '#') existingLink.href = href;
  });
  return <div className="prompt-block" ref={ref}>{children}</div>;
};

<UseCaseHero title="Migrer 50 fichiers de REST vers GraphQL" description="Délimitez le périmètre d'une migration REST-vers-GraphQL portant sur 50 fichiers, divisez-la en lots de travail sans conflits et exécutez-les tous en parallèle avec des Devin gérés." prompt="Analyse notre base de code pour identifier tous les fichiers qui utilisent l'ancien client REST. Regroupe-les en lots de travail indépendants qui ne se chevauchent pas, puis démarre une session Devin parallèle pour chaque lot afin de migrer vers le nouveau client GraphQL." category="Migrations" features="Avancé, Playbooks" agent="advanced" intent="batch" />

<div className="uc-detail-wrapper">
  <Tip>Vous ne souhaitez pas effectuer cette configuration manuellement ? Collez un lien vers cette page dans une session Devin et demandez-lui de tout configurer pour vous.</Tip>

  <Steps>
    <Step title="Définir le périmètre de la migration avec Ask Devin">
      Vous avez 50 fichiers qui importent depuis `src/lib/restClient.ts` et devez migrer vers le nouveau `graphqlClient`. Avant de répartir le travail en parallèle, vous devez comprendre comment ces fichiers sont reliés. Utilisez [Ask Devin](/fr/work-with-devin/ask-devin) pour cartographier le périmètre de la migration : quels fichiers importent l’ancien client, comment ils se regroupent par domaine et où se trouvent les couplages risqués. Devin utilise [DeepWiki](/fr/work-with-devin/deepwiki) et la recherche sémantique en arrière-plan, ce qui lui permet de répondre à ces questions en s’appuyant sur votre code existant.

      <Tip>Ask Devin nécessite que votre dépôt soit [indexé](/fr/onboard-devin/index-repo). Allez dans [**Settings > Repositories**](https://app.devin.ai/settings/repositories?utm_source=docs\&utm_medium=use-case-gallery) pour vérifier l’état d’indexation ou indexer un nouveau dépôt.</Tip>

      Ouvrez [Ask Devin](https://app.devin.ai/search?utm_source=docs\&utm_medium=use-case-gallery) et demandez :

      <PromptBlock agent="ada">
        ```txt Délimiter la migration de REST vers GraphQL theme={null}
        Combien de fichiers importent depuis src/lib/restClient.ts ? Regroupez-les
        par domaine (gestion des utilisateurs, facturation, analytics, notifications, auth,
        admin, recherche, onboarding, etc.) et signalez tous les fichiers qui partagent
        un état ou présentent un couplage fort entre domaines.
        Indiquez quels fichiers bénéficient déjà d’une couverture de tests.
        ```
      </PromptBlock>

      Ask Devin renvoie une analyse comme celle-ci :

      ```
      50 fichiers importent restClient dans 8 domaines :

        User Management  (7 fichiers) — isolé, couverture de tests complète
        Billing          (9 fichiers) — isolé, 6/9 testés
        Analytics        (5 fichiers) — isolé, 3/5 testés
        Auth             (6 fichiers) — middleware partagé, couverture de tests complète
        Notifications    (8 fichiers) — isolé, 5/8 testés
        Admin            (5 fichiers) — dépend du middleware Auth
        Search           (4 fichiers) — isolé, 2/4 testés
        Onboarding       (6 fichiers) — isolé, 4/6 testés

      Remarque sur le couplage : Admin importe requireAuth depuis Auth. Migrer
      Auth en premier, puis Admin. Tous les autres domaines sont indépendants.
      ```

      Cela vous indique si la parallélisation est pertinente. Si la plupart des fichiers sont fortement couplés entre domaines, une migration séquentielle est plus sûre. Ici, 6 domaines sur 8 sont totalement indépendants — vous pouvez les traiter en parallèle.
    </Step>

    <Step title="Créer un playbook de migration">
      Chaque session parallèle doit suivre le même modèle de migration afin que les PR soient cohérentes et faciles à examiner. Créez un [playbook](/fr/product-guides/creating-playbooks) qui définit exactement comment chaque fichier doit être migré.

      Allez dans [**Settings > Playbooks > Create Playbook**](https://app.devin.ai/settings/playbooks/create?utm_source=docs\&utm_medium=use-case-gallery) et définissez les étapes :

      <PromptBlock type="playbook">
        ```txt Migration REST vers GraphQL theme={null}
        Pour chaque fichier qui vous est attribué :

        1. Remplacez `import { restClient } from 'src/lib/restClient'`
           par `import { graphqlClient } from 'src/lib/graphqlClient'`
        2. Réécrivez chaque appel d'API pour utiliser la requête ou
           la mutation GraphQL correspondante définie dans
           src/graphql/operations/
        3. Mettez à jour la gestion des erreurs, en passant des
           codes de statut HTTP aux types d'erreurs GraphQL
           (voir src/lib/graphqlClient.ts pour la table de correspondance
           des erreurs)
        4. Mettez à jour le fichier de test correspondant :
           - Remplacez les mocks d'endpoints REST par des mocks GraphQL
             utilisant msw
           - Faites vos assertions sur le nom de l'opération GraphQL,
             et non sur l'URL
        5. Exécutez `npm run typecheck && npm test -- --related` pour vérifier
        6. Ouvrez une PR intitulée : "migrate: [domain] REST → GraphQL"
        ```
      </PromptBlock>

      Ou demandez à Devin de générer le playbook pour vous : décrivez votre modèle de migration et il produira un playbook complet :

      <PromptBlock agent="advanced">
        ```txt Générer un playbook de migration REST vers GraphQL theme={null}
        Créez un playbook pour migrer les fichiers de notre client REST
        (src/lib/restClient.ts) vers notre nouveau client GraphQL
        (src/lib/graphqlClient.ts). Consultez src/graphql/operations/ pour
        voir les requêtes et mutations disponibles. Incluez des étapes pour
        mettre à jour les imports, réécrire les appels d'API, convertir la
        gestion des erreurs des codes de statut HTTP vers les types d'erreurs
        GraphQL, mettre à jour les tests pour utiliser des mocks GraphQL msw,
        et exécuter le typecheck + les tests.
        ```
      </PromptBlock>

      Le fait de référencer ce playbook dans votre prompt d'orchestration garantit que toutes les sessions parallèles produisent des PR qui semblent provenir du même développeur.
    </Step>

    <Step title="Lancez des sessions parallèles avec Devin">
      Ouvrez une nouvelle session Devin depuis la [page d’accueil de Devin](https://app.devin.ai/?utm_source=docs\&utm_medium=use-case-gallery) et donnez-lui le prompt d’orchestration. Devin analyse le graphe de dépendances de votre base de code, crée des ensembles de travail indépendants et lance une session par ensemble — toutes s’exécutant en parallèle.

      <PromptBlock agent="advanced" intent="batch">
        ```txt Parallelize REST-to-GraphQL migration across 50 files theme={null}
        Analyze our codebase and find every file that imports from
        src/lib/restClient.ts. Map the dependency graph between these
        files to identify groups that can be migrated independently —
        no two groups should modify the same file or share mutable state.

        For each independent group, start a parallel Devin session using
        the "REST to GraphQL Migration" playbook. Each session should:
        - Migrate only its assigned files
        - Run typecheck and tests for its scope
        - Open a separate PR

        Before starting sessions, show me the proposed grouping so I can
        approve it. Include file counts and estimated complexity per group.
        ```
      </PromptBlock>

      Devin vous présente un regroupement pour validation avant de lancer quoi que ce soit :

      ```
      Packages de travail proposés (8 groupes, 50 fichiers au total) :

      Groupe 1 — User Management (7 fichiers, complexité : M)
        src/services/UserService.ts, src/pages/Profile.tsx,
        src/pages/Settings.tsx, src/hooks/useCurrentUser.ts,
        src/pages/UserDirectory.tsx, src/services/AvatarService.ts,
        src/components/UserCard.tsx

      Groupe 2 — Billing (9 fichiers, complexité : L)
        src/services/BillingService.ts, src/services/InvoiceService.ts,
        src/services/SubscriptionService.ts, src/pages/Checkout.tsx,
        src/pages/PlanSelector.tsx, src/pages/InvoiceHistory.tsx,
        src/components/PaymentForm.tsx, src/hooks/useSubscription.ts,
        src/components/PricingTable.tsx

      Groupe 3 — Analytics (5 fichiers, complexité : S)
        src/services/AnalyticsService.ts, src/pages/Dashboard.tsx,
        src/components/MetricsCard.tsx, src/hooks/useMetrics.ts,
        src/components/ChartPanel.tsx

      Groupe 4 — Auth (6 fichiers, complexité : L) ⚠ migrer en premier
        src/services/AuthService.ts, src/middleware/requireAuth.ts,
        src/middleware/refreshToken.ts, src/pages/Login.tsx,
        src/pages/Signup.tsx, src/services/SessionService.ts

      Groupe 5 — Notifications (8 fichiers, complexité : M)
        src/services/NotificationService.ts, src/services/EmailService.ts,
        src/services/PushService.ts, src/pages/NotificationPreferences.tsx,
        src/components/NotificationBell.tsx, src/hooks/useNotifications.ts,
        src/components/NotificationToast.tsx, src/services/WebhookService.ts

      Groupe 6 — Admin (5 fichiers, complexité : M) ⚠ dépend de Auth
        src/pages/AdminDashboard.tsx, src/pages/AdminUsers.tsx,
        src/services/AdminService.ts, src/components/AdminSidebar.tsx,
        src/middleware/requireAdmin.ts

      Groupe 7 — Search (4 fichiers, complexité : S)
        src/services/SearchService.ts, src/pages/SearchResults.tsx,
        src/components/SearchBar.tsx, src/hooks/useSearch.ts

      Groupe 8 — Onboarding (6 fichiers, complexité : M)
        src/services/OnboardingService.ts, src/pages/Welcome.tsx,
        src/pages/SetupWizard.tsx, src/components/ProgressTracker.tsx,
        src/hooks/useOnboardingState.ts, src/services/ChecklistService.ts

      Note de dépendance : le Groupe 6 (Admin) importe des middlewares du Groupe 4
      (Auth). Auth sera lancé en premier, puis Admin après la fusion de la PR d'Auth.
      Lancement des 6 groupes restants en parallèle immédiatement.

      Démarrer 6 sessions parallèles maintenant + 2 séquentielles ? (o/n)
      ```

      Approuvez le regroupement et lancez immédiatement les six sessions. Auth s’exécute en premier, puis Admin suit une fois Auth fusionné.
    </Step>

    <Step title="Examiner et fusionner les résultats">
      Chaque session ouvre sa propre PR. Étant donné que les packages sont indépendants, vous pouvez les examiner et les fusionner dans n'importe quel ordre — mais fusionnez Auth en premier, car Admin en dépend, et exécutez la CI complète après chaque fusion pour détecter toute interaction inattendue.

      Une fois les 8 PR de migration fusionnées, utilisez une session de suivi pour nettoyer le code mort :

      <PromptBlock>
        ```txt Nettoiement post-migration theme={null}
        Toutes les PR de migration REST vers GraphQL sont fusionnées. Analyse le code pour :
        1. Tout import restant de src/lib/restClient.ts
        2. Du code mort dans les utilitaires partagés que seul le client REST utilisait
        3. Des types ou interfaces spécifiques à REST qui peuvent être supprimés

        Nettoie-les et supprime complètement src/lib/restClient.ts si plus rien
        ne l’importe.
        ```
      </PromptBlock>
    </Step>
  </Steps>
</div>
