metis-desk/.agents/skills/rdx-solid/referencias/arquitectura-frontend.md

7.1 KiB

Arquitectura frontend

Referencia especializada del skill rdx-solid. Consulta arquitectura.md y respeta las convenciones de SKILL.md y AGENTS.md.

1. Propósito

Organizar interfaces mantenibles, accesibles y verificables. Los ejemplos están orientados a React y TypeScript; adapta los criterios al framework utilizado. No reproduzcas automáticamente las capas del backend dentro del navegador.

2. Partir de la estructura del proyecto

Antes de modificar componentes, examina: enrutado, diseño visual, biblioteca de UI, convención de carpetas, gestión de estado, formularios, consumo de APIs, i18n y pruebas. Respeta los límites existentes y evita migraciones de arquitectura no solicitadas.

3. Organización por funcionalidades

Agrupa componentes, hooks, servicios y tipos de una funcionalidad cuando ello reduzca la dispersión. No crees todas las subcarpetas por defecto.

src/
  features/
    orders/
      components/
        order-list.tsx
        order-form-dialog.tsx
      hooks/
        use-orders.ts
      api/
        orders-client.ts
      index.ts
  shared/
    ui/
    hooks/
  • shared/ contiene elementos realmente reutilizables, no un cajón para código sin dueño.
  • Mantén públicas solo las APIs que otros módulos deban consumir; evita importar detalles internos entre funcionalidades.
  • No crees un componente por cada etiqueta HTML: la extracción debe representar una responsabilidad, reutilización o complejidad significativa.
  • No concentres numerosos componentes independientes en un solo archivo si dificulta comprenderlos o mantenerlos.
  • Modales y diálogos con lógica propia deben tender a componentes separados; un cuadro trivial puede permanecer local cuando resulte más claro.

4. Componentes y responsabilidades

  • Prefiere composición sobre jerarquías de herencia de componentes.
  • Mantén la lógica compleja de dominio fuera de la representación visual.
  • Utiliza props explícitas y contratos de componentes comprensibles.
  • Evita convertir cada componente en un conjunto de capas y controladores.
  • Extrae hooks cuando encapsulen lógica reactiva reutilizable o significativa; no para ocultar una única llamada simple.
  • No introduzcas renderizado derivado con estado duplicado cuando pueda calcularse a partir de props o estado existente.
interface OrderSummaryProps {
  order: OrderSummary;
  onSelect: (orderId: string) => void;
}

export function OrderSummaryCard({ order, onSelect }: OrderSummaryProps) {
  return (
    <article>
      <h3>{order.reference}</h3>
      <button type="button" onClick={() => onSelect(order.id)}>
        Ver pedido
      </button>
    </article>
  );
}

El ejemplo presupone un tipo de presentación OrderSummary y una interfaz accesible que puede requerir más detalles según el diseño.

5. Estado y datos remotos

Distingue:

  • Estado local: interacción de un componente o pequeño subárbol.
  • Estado compartido de UI: necesidades de varios componentes relacionados.
  • Estado remoto: datos obtenidos del servidor, con carga, error y actualización.
  • Estado derivado: valores calculables que normalmente no deben almacenarse por duplicado.

No introduzcas un gestor global de estado para resolver un formulario aislado. Para datos remotos, reutiliza las bibliotecas de consulta, caché e invalidación que ya utiliza el proyecto. Evita duplicar en estado global la caché del servidor sin motivo.

Controla carreras entre solicitudes, cancelación, refresco y estados vacíos cuando corresponda.

  • Conserva validaciones de experiencia de usuario en frontend y la validación autoritativa en backend.
  • Muestra errores comprensibles y asociados al campo o acción pertinente.
  • Considera guardado pendiente, reintentos, cambios sin guardar y envío duplicado.
  • Mantén los formularios complejos y modales con responsabilidad propia en componentes independientes.
  • Respeta foco, navegación por teclado, cierre, etiquetas y mensajes accesibles.
  • Reutiliza los componentes del sistema de diseño y no edites paquetes de terceros para implementar personalizaciones locales.

7. Acceso a APIs y contratos

  • Centraliza donde corresponda la adaptación de respuestas, autenticación y errores de transporte.
  • No expongas directamente modelos internos de la base de datos como modelos de UI.
  • Maneja explícitamente carga, vacío, éxito y error.
  • No confíes en tipos estáticos para garantizar la forma de datos remotos en ejecución.
  • Evita mezclar llamadas HTTP y transformación compleja dentro de componentes de presentación.
  • No asumas que frontend y backend se actualizan al mismo tiempo; mantén compatibilidad según sus contratos.

Consulta arquitectura-shared.md para DTO, tipos, esquemas y generación de clientes.

8. Accesibilidad, i18n y seguridad

  • Utiliza HTML semántico, etiquetas, navegación por teclado y gestión de foco.
  • Prueba estados accesibles de carga, error y modales.
  • No insertes textos literales en áreas gobernadas por i18n; conserva es y en cuando sean idiomas soportados.
  • Trata contenido no confiable de forma segura; evita inyección de HTML.
  • No almacenes secretos de servidor en código distribuido al navegador.
  • La ocultación de botones no sustituye la autorización del backend.

9. Rendimiento

Optimiza basándote en evidencia: identifica re-renderizados costosos, bundles grandes, rutas pesadas y solicitudes redundantes. No añadas memoización a todos los componentes por rutina. Utiliza división de código, virtualización o carga diferida cuando el volumen real lo requiera. Mantén claves estables en listas.

10. Pruebas

  • Prueba comportamientos percibidos por el usuario en lugar de detalles de implementación.
  • Comprueba formularios, validaciones, errores, roles y accesibilidad relevante.
  • Utiliza pruebas de componentes e integración para flujos locales; E2E para recorridos críticos.
  • No hagas que pruebas de UI dependan innecesariamente de detalles internos de hooks.
  • Verifica los contratos de API cuando cambien.

11. Señales de alerta

  • Componentes enormes con estado, transporte y reglas mezclados.
  • Estado remoto duplicado en varios almacenes.
  • Hooks extraídos sin responsabilidad concreta.
  • shared/ que contiene reglas exclusivas de una funcionalidad.
  • Múltiples diálogos complejos incrustados en un componente contenedor.
  • Uso de useEffect para derivar valores calculables directamente.
  • Lógica de autorización exclusivamente en frontend.
  • Optimizaciones preventivas que dificultan la lectura.

12. Lista de comprobación

  • ¿La modificación respeta las convenciones de React y del repositorio?
  • ¿Cada componente y hook mantiene una responsabilidad clara?
  • ¿El estado pertenece al ámbito apropiado?
  • ¿Los formularios y diálogos son accesibles y verificables?
  • ¿Se respetan i18n, seguridad y contratos de API?
  • ¿He evitado abstracciones o librerías nuevas sin necesidad?
  • ¿Las pruebas cubren el comportamiento modificado?

Principio final: el frontend debe expresar flujos de usuario claros sin convertir la interfaz en un conjunto de abstracciones innecesarias.