4.4 KiB
Guía 4 — Patrones Arquitectónicos Aprobados
Catálogo de patrones de desarrollo seguro y limpio para Next.js App Router
Propósito: Esta guía documenta los patrones de código oficiales del proyecto. Cualquier desvío de estos patrones debe estar debidamente motivado y registrado en Engram.
1. El Patrón Server-First (Server Components por defecto)
En Next.js App Router, todos los componentes de la carpeta app/ son React Server Components por defecto. Esto significa que se renderizan en el servidor, reduciendo el tamaño del bundle de JavaScript en el cliente y protegiendo accesos a base de datos o APIs downstream.
Reglas del Patrón:
- Fetching Directo: Las peticiones al backend Spring Boot se realizan directamente en la función asíncrona del componente, sin necesidad de usar
useEffecto estados de React en el cliente. - Seguridad Integrada: Se verifica la sesión del usuario al inicio del renderizado usando
serverRequireAuth().
// app/dashboard/page.tsx
import { serverRequireAuth } from '@/lib/auth/middleware';
import { fetchCuentasUsuario } from '@/standards/03-headers-contract';
export default async function DashboardPage() {
// 1. Validar sesión en servidor
const user = await serverRequireAuth();
// 2. Fetching asíncrono seguro
const cuentas = await fetchCuentasUsuario(user.sessionReference);
return (
<div>
<h1>Portal de Cuentas de {user.name}</h1>
<ul className="space-y-4">
{cuentas.map((cta) => (
<li key={cta.id} className="p-4 bg-base-100 rounded-box shadow">
Cuenta: {cta.numero} - Saldo: ${cta.saldo}
</li>
))}
</ul>
</div>
);
}
2. El Patrón de Hidratación de Componentes del Cliente
Cuando requerimos interactividad del usuario (clicks, formularios reactivos, modales dinámicos), declaramos un Client Component usando la directiva 'use client' al principio del archivo.
Reglas de Diseño:
- Área Limpia: Mantén el Client Component lo más atómico y libre de fetching posible. Pasa los datos iniciales obtenidos en el Server Component como Props.
- Estado Global: Si el componente altera el estado de la sesión, actualiza el store de Zustand.
// components/BotonTransferencia.tsx
'use client';
import { useState } from 'react';
import { logInfo } from '@/lib/logger/client-logger';
import { useAuthStore } from '@/lib/auth/client/useAuthStore';
interface BotonProps {
cuentaOrigenId: string;
}
export default function BotonTransferencia({ cuentaOrigenId }: BotonProps) {
const [loading, setLoading] = useState(false);
const { user } = useAuthStore();
const handleTransfer = async () => {
setLoading(true);
logInfo('Acción de transferencia disparada', { cuentaOrigenId, userId: user?.id });
// Simular llamada de API local
await new Promise((r) => setTimeout(r, 1000));
setLoading(false);
};
return (
<button
onClick={handleTransfer}
disabled={loading}
className="btn btn-primary"
>
{loading ? 'Procesando...' : 'Transferir Saldo'}
</button>
);
}
3. Gobernanza de Estado Cliente con Zustand
Evitamos el uso de React Context APIs redundantes o Redux pesado. El estado de la sesión cliente y configuraciones UI se centralizan en Zustand stores ubicados en lib/auth/client/useAuthStore.ts.
Reglas del Patrón:
- Reactividad Fina: Usa selectores en tus componentes para suscribirte solo a las propiedades requeridas (evita re-renders innecesarios).
- Acciones Claras: Toda lógica que muta el estado debe encapsularse en las acciones del store.
// lib/auth/client/useAuthStore.ts
import { create } from 'zustand';
interface User {
id: string;
name: string;
}
interface AuthState {
user: User | null;
isAuthenticated: boolean;
login: (user: User) => void;
logout: () => void;
}
export const useAuthStore = create<AuthState>((set) => ({
user: null,
isAuthenticated: false,
login: (user) => set({ user, isAuthenticated: true }),
logout: () => set({ user: null, isAuthenticated: false }),
}));
4. El Patrón de Logging Proxy para el Cliente
Como el cliente no tiene acceso al sistema de archivos local (logs/app.log), canalizamos todas las trazas de Client Components mediante el proxy seguro de Next.js /api/logs.
- Ver
standards/01-log-tracing.mdpara el flujo de llamadas y enrutamiento técnico de este patrón.