> ## 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 archivos de REST a 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 archivos de REST a GraphQL" description="Definir el alcance de la migración de 50 archivos de REST a GraphQL, dividirla en paquetes de trabajo sin conflictos y ejecutarlos todos simultáneamente mediante Devins gestionados." prompt="Analiza nuestro código base para encontrar todos los archivos que usan el cliente REST heredado. Agrúpalos en paquetes de trabajo independientes que no entren en conflicto y luego inicia una sesión paralela de Devin para cada paquete a fin de migrarlo al nuevo cliente GraphQL." category="Migraciones" features="Avanzado, Playbooks" agent="advanced" intent="batch" />

<div className="uc-detail-wrapper">
  <Tip>¿Prefieres no configurarlo manualmente? Pega un enlace a esta página en una sesión de Devin y pídele que lo configure todo por ti.</Tip>

  <Steps>
    <Step title="Delimita el alcance de la migración con Ask Devin">
      Tienes 50 archivos que importan desde `src/lib/restClient.ts` y necesitas migrarlos al nuevo `graphqlClient`. Antes de dividir nada en trabajo en paralelo, necesitas entender cómo están conectados esos archivos. Usa [Ask Devin](/es/work-with-devin/ask-devin) para mapear la superficie de migración: qué archivos importan el cliente heredado, cómo se agrupan por dominio y dónde existe acoplamiento riesgoso. Devin usa [DeepWiki](/es/work-with-devin/deepwiki) y búsqueda semántica bajo el capó, por lo que puede responder estas preguntas basándose en tu código real.

      <Tip>Ask Devin requiere que tu repositorio esté [indexado](/es/onboard-devin/index-repo). Ve a [**Settings > Repositories**](https://app.devin.ai/settings/repositories?utm_source=docs\&utm_medium=use-case-gallery) para comprobar el estado de indexación o indexar un nuevo repositorio.</Tip>

      Abre [Ask Devin](https://app.devin.ai/search?utm_source=docs\&utm_medium=use-case-gallery) y haz la siguiente consulta:

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

      Ask Devin devuelve un desglose como este:

      ```
      50 archivos importan restClient en 8 dominios:

        User Management  (7 archivos) — aislado, cobertura de pruebas completa
        Billing          (9 archivos) — aislado, 6/9 probados
        Analytics        (5 archivos) — aislado, 3/5 probados
        Auth             (6 archivos) — middleware compartido, cobertura de pruebas completa
        Notifications    (8 archivos) — aislado, 5/8 probados
        Admin            (5 archivos) — depende del middleware de Auth
        Search           (4 archivos) — aislado, 2/4 probados
        Onboarding       (6 archivos) — aislado, 4/6 probados

      Nota de acoplamiento: Admin importa requireAuth desde Auth. Migrar
      Auth primero, luego Admin. Todos los demás dominios son independientes.
      ```

      Esto te permite saber si la paralelización tiene sentido. Si la mayoría de los archivos están estrechamente acoplados entre distintos dominios, una migración secuencial es más segura. Aquí, 6 de 8 dominios son completamente independientes: puedes ejecutarlos en paralelo.
    </Step>

    <Step title="Crear un playbook de migración">
      Cada sesión en paralelo debe seguir el mismo patrón de migración para que las PR resultantes sean coherentes y fáciles de revisar. Crea un [playbook](/es/product-guides/creating-playbooks) que defina exactamente cómo se debe migrar cada archivo.

      Ve a [**Settings > Playbooks > Create Playbook**](https://app.devin.ai/settings/playbooks/create?utm_source=docs\&utm_medium=use-case-gallery) y define los pasos:

      <PromptBlock type="playbook">
        ```txt Migración de REST a GraphQL theme={null}
        Para cada archivo asignado a ti:

        1. Reemplaza `import { restClient } from 'src/lib/restClient'`
           por `import { graphqlClient } from 'src/lib/graphqlClient'`
        2. Reescribe cada llamada a la API para usar la consulta o
           mutación GraphQL correspondiente definida en src/graphql/operations/
        3. Actualiza el manejo de errores de códigos de estado HTTP
           a tipos de error de GraphQL (consulta el mapa de errores en
           src/lib/graphqlClient.ts)
        4. Actualiza el archivo de tests correspondiente:
           - Sustituye los mocks de endpoints REST por mocks GraphQL usando msw
           - Haz las aserciones sobre el nombre de la operación GraphQL, no la URL
        5. Ejecuta `npm run typecheck && npm test -- --related` para verificar
        6. Abre una PR titulada: "migrate: [domain] REST → GraphQL"
        ```
      </PromptBlock>

      O pídele a Devin que genere el playbook por ti: describe tu patrón de migración y generará un playbook completo:

      <PromptBlock agent="advanced">
        ```txt Generar un playbook de migración de REST a GraphQL theme={null}
        Crea un playbook para migrar archivos de nuestro cliente REST
        (src/lib/restClient.ts) a nuestro nuevo cliente GraphQL
        (src/lib/graphqlClient.ts). Revisa src/graphql/operations/ para
        ver las consultas y mutaciones disponibles. Incluye pasos para
        actualizar los imports, reescribir las llamadas a la API,
        convertir el manejo de errores de códigos de estado HTTP a tipos
        de error de GraphQL, actualizar los tests para usar mocks GraphQL
        con msw y ejecutar typecheck + tests.
        ```
      </PromptBlock>

      Incluir este playbook en tu prompt de orquestación garantiza que todas las sesiones en paralelo produzcan PR que parezcan hechas por el mismo desarrollador.
    </Step>

    <Step title="Inicia sesiones en paralelo con Devin">
      Abre una nueva sesión de Devin desde la [página de inicio de Devin](https://app.devin.ai/?utm_source=docs\&utm_medium=use-case-gallery) y dale la instrucción de orquestación. Devin analiza el grafo de dependencias de tu base de código, crea paquetes de trabajo independientes y lanza una sesión por paquete, todas ejecutándose simultáneamente.

      <PromptBlock agent="advanced" intent="batch">
        ```txt Paralelizar la migración de REST a GraphQL en 50 archivos theme={null}
        Analiza nuestra base de código y encuentra cada archivo que importe desde
        src/lib/restClient.ts. Mapea el grafo de dependencias entre estos
        archivos para identificar grupos que puedan migrarse de forma independiente:
        ningún par de grupos debe modificar el mismo archivo ni compartir estado mutable.

        Para cada grupo independiente, inicia una sesión paralela de Devin usando
        el playbook "REST to GraphQL Migration". Cada sesión debe:
        - Migrar solo los archivos que tenga asignados
        - Ejecutar typecheck y tests dentro de su propio alcance
        - Abrir un PR separado

        Antes de iniciar las sesiones, muéstrame la agrupación propuesta para que pueda
        aprobarla. Incluye el número de archivos y la complejidad estimada por grupo.
        ```
      </PromptBlock>

      Devin presenta una agrupación para tu aprobación antes de iniciar cualquier cosa:

      ```
      Paquetes de trabajo propuestos (8 grupos, 50 archivos en total):

      Grupo 1 — Gestión de usuarios (7 archivos, complejidad: 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 — Facturación (9 archivos, complejidad: 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 — Análisis (5 archivos, complejidad: 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 archivos, complejidad: L) ⚠ migrar primero
        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 — Notificaciones (8 archivos, complejidad: 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 archivos, complejidad: 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 — Búsqueda (4 archivos, complejidad: S)
        src/services/SearchService.ts, src/pages/SearchResults.tsx,
        src/components/SearchBar.tsx, src/hooks/useSearch.ts

      Grupo 8 — Onboarding (6 archivos, complejidad: 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 dependencia: el Grupo 6 (Admin) importa middleware del Grupo 4
      (Auth). Se lanzará Auth primero y luego Admin una vez que el PR de Auth se integre.
      Lanzar los 6 grupos restantes en paralelo de inmediato.

      ¿Iniciar 6 sesiones paralelas ahora + 2 secuenciales? (s/n)
      ```

      Aprueba la agrupación y lanza de una vez las seis sesiones. Auth se ejecuta primero y, una vez que se fusione, sigue Admin.
    </Step>

    <Step title="Revisa y fusiona los resultados">
      Cada sesión abre su propia solicitud de extracción (PR). Como los paquetes son independientes, puedes revisarlas y fusionarlas en cualquier orden, pero fusiona primero Auth, ya que Admin depende de él, y ejecuta la CI completa después de cada fusión para detectar cualquier interacción inesperada.

      Una vez que se hayan fusionado las 8 PR de migración, usa una sesión de seguimiento para limpiar el código muerto:

      <PromptBlock>
        ```txt Limpieza posterior a la migración theme={null}
        Todas las PR de migración de REST a GraphQL están fusionadas. Analiza la base de código en busca de:
        1. Cualquier importación restante de src/lib/restClient.ts
        2. Código muerto en utilidades compartidas que solo usaba el cliente REST
        3. Tipos o interfaces específicos de REST que puedan eliminarse

        Límpialos y elimina src/lib/restClient.ts por completo si ya nada lo
        importa.
        ```
      </PromptBlock>
    </Step>
  </Steps>
</div>
