> ## 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.

# Migrar 50 arquivos de REST para 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="Migrar 50 arquivos de REST para GraphQL" description="Defina o escopo de uma migração de 50 arquivos de REST para GraphQL, divida-a em pacotes de trabalho sem conflitos entre si e execute todos de uma vez com Devins gerenciados." prompt="Analise nossa codebase para encontrar todos os arquivos que usam o cliente REST legado. Agrupe-os em pacotes de trabalho independentes que não entrem em conflito e, em seguida, inicie uma sessão paralela do Devin para cada pacote para migrar para o novo cliente GraphQL." category="Migrações" features="Avançado, Playbooks" agent="advanced" intent="batch" />

<div className="uc-detail-wrapper">
  <Tip>Não quer configurar isso manualmente? Cole um link para esta página em uma sessão do Devin e peça para ele configurar tudo para você.</Tip>

  <Steps>
    <Step title="Use o Ask Devin para definir o escopo da migração">
      Você tem 50 arquivos que importam de `src/lib/restClient.ts` e precisa migrá-los para o novo `graphqlClient`. Antes de dividir esse trabalho em paralelo, você precisa saber como esses arquivos estão conectados. Use o [Ask Devin](/pt-BR/work-with-devin/ask-devin) para mapear o escopo da migração — quais arquivos importam o cliente legado, como eles se agrupam por domínio e onde estão os acoplamentos mais arriscados. O Devin usa [DeepWiki](/pt-BR/work-with-devin/deepwiki) e busca semântica nos bastidores, então consegue responder a essas perguntas com base no seu código real.

      <Tip>O Ask Devin exige que o seu repositório esteja [indexado](/pt-BR/onboard-devin/index-repo). Vá em [**Settings > Repositories**](https://app.devin.ai/settings/repositories?utm_source=docs\&utm_medium=use-case-gallery) para verificar o status de indexação ou indexar um novo repositório.</Tip>

      Abra o [Ask Devin](https://app.devin.ai/search?utm_source=docs\&utm_medium=use-case-gallery) e peça:

      <PromptBlock agent="ada">
        ```txt Scope the REST-to-GraphQL migration theme={null}
        How many files import from src/lib/restClient.ts? Group them by
        domain (user management, billing, analytics, notifications, auth,
        admin, search, onboarding, etc.) and flag any files that share
        state or have tight coupling across domains.
        Note which files have existing test coverage.
        ```
      </PromptBlock>

      O Ask Devin retorna um detalhamento como este:

      ```
      50 arquivos importam restClient em 8 domínios:

        User Management  (7 arquivos) — isolado, cobertura de testes completa
        Billing          (9 arquivos) — isolado, 6/9 testados
        Analytics        (5 arquivos) — isolado, 3/5 testados
        Auth             (6 arquivos) — middleware compartilhado, cobertura de testes completa
        Notifications    (8 arquivos) — isolado, 5/8 testados
        Admin            (5 arquivos) — depende do middleware Auth
        Search           (4 arquivos) — isolado, 2/4 testados
        Onboarding       (6 arquivos) — isolado, 4/6 testados

      Nota de acoplamento: Admin importa requireAuth de Auth. Migre
      Auth primeiro, depois Admin. Todos os outros domínios são independentes.
      ```

      Isso indica se a paralelização faz sentido. Se a maioria dos arquivos estiver fortemente acoplada entre domínios, uma migração sequencial é mais segura. Aqui, 6 de 8 domínios são totalmente independentes — você pode executá-los em paralelo.
    </Step>

    <Step title="Criar um playbook de migração">
      Cada sessão paralela deve seguir o mesmo padrão de migração para que as PRs resultantes sejam consistentes e fáceis de revisar. Crie um [playbook](/pt-BR/product-guides/creating-playbooks) que defina exatamente como cada arquivo deve ser migrado.

      Acesse [**Settings > Playbooks > Create Playbook**](https://app.devin.ai/settings/playbooks/create?utm_source=docs\&utm_medium=use-case-gallery) e defina as etapas:

      <PromptBlock type="playbook">
        ```txt Migração de REST para GraphQL theme={null}
        Para cada arquivo atribuído a você:

        1. Substitua `import { restClient } from 'src/lib/restClient'`
           por `import { graphqlClient } from 'src/lib/graphqlClient'`
        2. Reescreva cada chamada de API para usar a respectiva query
           ou mutation GraphQL definida em src/graphql/operations/
        3. Atualize o tratamento de erros de códigos de status HTTP
           para tipos de erro GraphQL (consulte src/lib/graphqlClient.ts para o mapa de erros)
        4. Atualize o arquivo de teste correspondente:
           - Substitua os mocks de endpoint REST por mocks GraphQL usando msw
           - Faça asserções com base no nome da operação GraphQL, não na URL
        5. Execute `npm run typecheck && npm test -- --related` para validar
        6. Abra uma PR com o título: "migrate: [domain] REST → GraphQL"
        ```
      </PromptBlock>

      Ou peça ao Devin para gerar o playbook para você — descreva seu padrão de migração e ele produzirá um playbook completo:

      <PromptBlock agent="advanced">
        ```txt Gerar um playbook de migração de REST para GraphQL theme={null}
        Crie um playbook para migrar arquivos do nosso cliente REST
        (src/lib/restClient.ts) para o nosso novo cliente GraphQL
        (src/lib/graphqlClient.ts). Veja src/graphql/operations/ para
        as consultas e mutations disponíveis. Inclua etapas para atualizar
        imports, reescrever chamadas de API, converter o tratamento de erros
        de códigos de status HTTP para tipos de erro GraphQL, atualizar testes
        para usar mocks GraphQL com msw e executar typecheck + testes.
        ```
      </PromptBlock>

      Referenciar esse playbook no seu prompt de orquestração garante que todas as sessões paralelas produzam PRs que pareçam ter vindo do mesmo desenvolvedor.
    </Step>

    <Step title="Inicie sessões paralelas com Devin">
      Abra uma nova sessão do Devin na [home page do Devin](https://app.devin.ai/?utm_source=docs\&utm_medium=use-case-gallery) e forneça a ela o prompt de orquestração. Devin analisa o grafo de dependências da sua base de código, cria pacotes de trabalho independentes e inicia uma sessão por pacote — todas sendo executadas simultaneamente.

      <PromptBlock agent="advanced" intent="batch">
        ```txt Paralelizar a migração de REST para GraphQL em 50 arquivos theme={null}
        Analise nossa base de código e encontre todos os arquivos que importam de
        src/lib/restClient.ts. Mapeie o grafo de dependências entre esses
        arquivos para identificar grupos que possam ser migrados de forma independente —
        dois grupos diferentes não devem modificar o mesmo arquivo nem compartilhar estado mutável.

        Para cada grupo independente, inicie uma sessão do Devin em paralelo usando
        o playbook "REST to GraphQL Migration". Cada sessão deve:
        - Migrar apenas os arquivos atribuídos a ela
        - Executar verificação de tipos (typecheck) e testes para seu escopo
        - Abrir um PR separado

        Antes de iniciar as sessões, mostre-me o agrupamento proposto para que eu possa
        aprová-lo. Inclua a contagem de arquivos e a complexidade estimada por grupo.
        ```
      </PromptBlock>

      Devin apresenta um agrupamento para sua aprovação antes de iniciar qualquer coisa:

      ```
      Pacotes de trabalho propostos (8 grupos, 50 arquivos no total):

      Grupo 1 — Gerenciamento de Usuários (7 arquivos, complexidade: 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

      Grupo 2 — Faturamento (9 arquivos, complexidade: 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

      Grupo 3 — Analytics (5 arquivos, complexidade: S)
        src/services/AnalyticsService.ts, src/pages/Dashboard.tsx,
        src/components/MetricsCard.tsx, src/hooks/useMetrics.ts,
        src/components/ChartPanel.tsx

      Grupo 4 — Auth (6 arquivos, complexidade: L) ⚠ migrar primeiro
        src/services/AuthService.ts, src/middleware/requireAuth.ts,
        src/middleware/refreshToken.ts, src/pages/Login.tsx,
        src/pages/Signup.tsx, src/services/SessionService.ts

      Grupo 5 — Notificações (8 arquivos, complexidade: 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

      Grupo 6 — Admin (5 arquivos, complexidade: M) ⚠ depende de Auth
        src/pages/AdminDashboard.tsx, src/pages/AdminUsers.tsx,
        src/services/AdminService.ts, src/components/AdminSidebar.tsx,
        src/middleware/requireAdmin.ts

      Grupo 7 — Busca (4 arquivos, complexidade: S)
        src/services/SearchService.ts, src/pages/SearchResults.tsx,
        src/components/SearchBar.tsx, src/hooks/useSearch.ts

      Grupo 8 — Onboarding (6 arquivos, complexidade: 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

      Nota de dependência: o Grupo 6 (Admin) importa middleware do Grupo 4
      (Auth). Auth será iniciado primeiro; Admin será iniciado após o PR de Auth ser mesclado.
      Iniciar os 6 grupos restantes em paralelo imediatamente.

      Iniciar 6 sessões paralelas agora + 2 sequenciais? (s/n)
      ```

      Aprove o agrupamento e o lançamento simultâneo das seis sessões. Auth é executado primeiro e, depois que o merge de Auth for concluído, Admin é executado em seguida.
    </Step>

    <Step title="Revise e faça o merge dos resultados">
      Cada sessão abre seu próprio PR. Como os pacotes são independentes, você pode revisá-los e mesclá-los em qualquer ordem — mas faça o merge de Auth primeiro, já que Admin depende dele, e execute o CI completo após cada merge para detectar eventuais interações inesperadas.

      Depois que todos os 8 PRs de migração forem mesclados, use uma sessão de acompanhamento para limpar código morto:

      <PromptBlock>
        ```txt Limpeza pós-migração theme={null}
        Todos os PRs de migração de REST para GraphQL foram mesclados. Analise a codebase em busca de:
        1. Quaisquer importações restantes de src/lib/restClient.ts
        2. Código morto em utilitários compartilhados que apenas o cliente REST usava
        3. Tipos ou interfaces específicos de REST que possam ser removidos

        Limpe tudo isso e exclua src/lib/restClient.ts completamente se nada
        mais fizer import dele.
        ```
      </PromptBlock>
    </Step>
  </Steps>
</div>
