Portal
Portal del cliente de ixiclinic — Next.js 16. Dos flujos de auth (paciente y empresa), resolución de tenant por subdominio o slug.
El portal (apps/portal) es la app de cara al cliente final del laboratorio: el paciente
consulta sus resultados, citas y facturas; la empresa gestiona sus empleados y órdenes. Cada
laboratorio (tenant) tiene su propio portal, resuelto por subdominio.
| Stack | Next.js 16 (App Router), Tailwind 4 |
| Puerto local | 3002 |
| Producción | portal.ixiclinic.com (Vercel) |
| Paquete | @ixiclinic/portal |
Resolución de tenant
El portal es multi-tenant resuelto por el host. La lógica está en
apps/portal/src/middleware.ts y apps/portal/src/lib/tenant.ts:
- Producción:
<slug>.portal.ixiclinic.com(forma preferida; un wildcard*.portal.ixiclinic.comcubre todos los labs). También se acepta el legado<slug>.ixiclinic.com. El host literalportalno lleva tenant. - Desarrollo:
localhost:3002con?tenant=<slug>; el middleware guarda el slug en la cookieclient-tenant.
El middleware corre sobre casi todas las rutas (matcher excluye _next y favicon) y fija la
cookie del tenant. getTenantSlug() lo lee del host o de la cookie, y getTenantBranding()
trae el nombre y logo del laboratorio desde /api/portal/<slug>/branding.
Dos flujos de autenticación
El portal soporta dos tipos de usuario, seleccionables con pestañas en la pantalla de login
(apps/portal/src/app/(auth)/login/login-client.tsx):
- Paciente — inicia sesión con cédula.
- Empresa — inicia sesión con correo electrónico.
El registro y la activación tienen variantes por tipo (register/patient, register/company).
Route groups (apps/portal/src/app/)
| Grupo | Contenido |
|---|---|
(auth)/ | login, register (paciente/empresa), activate. |
(portal)/ | Workspace del cliente autenticado (ver abajo). |
[slug]/ | Variante por-ruta del portal ([slug]/(auth) y [slug]/(portal)) para acceder con portal.ixiclinic.com/<slug>/login cuando no hay subdominio. |
api/ | Ruta API de Next: results/[orderId]/pdf (PDF de resultados con @react-pdf/renderer). |
Secciones del (portal): dashboard, appointments, billing, orders, results,
reports, prescriptions, encounters, profile, y employees (gestión de empleados para el
flujo de empresa).
Comunicación con el API
Mismo patrón server-side que el admin, vía apps/portal/src/lib/api-client.ts
(apiGet, apiPost, apiPatch, apiDelete). Usa cookies con prefijo client-
(client-accessToken, client-refreshToken) y refresca el token contra
/api/client/auth/refresh. Consume endpoints scoped al portal (/api/portal/<slug>/...,
públicos) y endpoints del cliente autenticado (/api/client/...).
Nota: No confundir el portal con el lab-site. El lab-site es el sitio público del laboratorio (catálogo, carrito) sin login; el portal exige autenticación de paciente o empresa.
UI stack
Next.js 16 con Tailwind 4, framer-motion para las transiciones y sonner para
notificaciones. La generación de PDF de resultados usa @react-pdf/renderer
(apps/portal/src/lib/result-pdf.tsx).
Build y despliegue
Despliega automáticamente en Vercel al hacer push a main. Ver Operaciones.
Console
Panel SaaS interno de ixiclinic — mismo stack que el admin pero para gestionar clientes, planes, demos y organizaciones. Cookies saas- y endpoints /api/saas/*.
Landing
Sitio público de marketing de ixiclinic (ixiclinic.com) — Next.js 16 con SSG multipágina, páginas de módulo data-driven y formulario de demo.