Servidor y cliente
Los archivos src/app/**/page.tsx son wrappers de servidor mínimos: resuelven
la sesión y/o cargan datos, y renderizan un componente de src/views/
marcado "use client". La lógica de presentación e interacción vive en el
componente cliente; el page.tsx solo hace de puente hacia el servidor.
Guards
Los guards de acceso no viven en cada page.tsx, sino en el layout.tsx de
cada sección. Ese layout.tsx es el que:
- redirige a
/login si no hay sesión,
- redirige a
/dashboard si la sesión no tiene rol ADMIN,
- y envuelve el contenido en
DashboardShell.
Las rutas admin son /usuarios, /servicios y /camellos.
Componentes
src/components/ agrupa los componentes por feature: admin/, explore/,
home/, provider-profile/, entre otros. src/components/ui/ son los
primitivos de shadcn/ui y están excluidos del umbral de cobertura de tests.
Split server-only / -shared
Los módulos de datos en src/lib/ que solo debe poder correr en servidor
empiezan con import "server-only". Eso rompe la build si un componente
cliente los importa.
Lo que ese módulo expone y que también necesita el cliente (tipos, DTOs,
funciones puras) vive en un gemelo sin esa marca, con el sufijo -shared. El
módulo de servidor reexporta lo que el gemelo -shared ya define. El
ejemplo real de este patrón es camellos.ts ↔ camellos-shared.ts: los DTOs,
parseTrades y buildCamelloWhatsAppUrl viven en camellos-shared.ts, y
camellos.ts los reexporta junto con la lógica que sí toca la base de datos.
No importes un módulo server-only desde un componente cliente. Si un
componente cliente necesita algo de ahí, ese algo debe vivir (o moverse) al
gemelo -shared.