Wiki / Documentación interna / Arquitectura

Visión general y stack

Next.js 16 + Supabase, multi-tenant real (aislamiento en base de datos, no en código de aplicación), pensado para servir a 20 sociedades distintas sin tocar código.

Stack

Framework Next.js 16 (App Router, Server Components, Server Actions), TypeScript estricto
UI Tailwind CSS v4, shadcn/ui, lucide-react, sonner
Formularios react-hook-form + zod
Tablas TanStack Table v8 (paginación/orden/filtro en servidor)
BBDD / Auth / Storage Supabase (PostgreSQL, región Frankfurt/UE)
Migraciones Supabase CLI, todo versionado en supabase/migrations/*.sql
Hosting Vercel
Email SMTP propio o Resend, configurable en caliente (ver Envío de email)
PDF @react-pdf/renderer
Excel exceljs (nunca SheetJS, por licencia)
Jobs / colas Vercel Cron + tabla job_queue (patrón outbox), sin Redis

El núcleo: aislamiento por sociedad

Base de datos única, esquema único. Toda tabla de negocio lleva society_id y Row Level Security con ENABLE + FORCE. El aislamiento no se implementa con un WHERE society_id = ... en el código de la aplicación — eso es una optimización, no la barrera de seguridad. La barrera real vive en las políticas RLS de Postgres. Detalle completo en Seguridad, cifrado y RLS y Roles, RLS y superadmin.

La aplicación nunca usa la service_role key en código que atienda peticiones de usuario — solo en src/lib/server/admin/, con un comentario justificando cada uso, reforzado por una regla de ESLint (no-restricted-syntax/no-restricted-imports) que impide usarla fuera de esas rutas.

Routing

  • /(app)/[societySlug]/... — área de gestión y de socio de una sociedad concreta.
  • /admin/... — área de superadmin, sin slug de sociedad.
  • /login vs /admin/login — dos puertas separadas, nunca cruzadas (ver Roles, RLS y superadmin).

Sistema de módulos

Buena parte de lo construido más allá del núcleo (certificados, 2FA, correos personalizados, importación, login de marca, SSO WordPress, formularios de alta, tickets) es un módulo activable, con interruptor global y por sociedad. Detalle en Sistema de módulos activables.

Entornos

Hoy no hay separación real de entornos Supabase (local Docker / staging / producción) — supabase/config.toml es la configuración compartida de todos los proyectos vinculados, con site_url apuntando a localhost a propósito (el código siempre pasa un redirectTo explícito) y la URL de producción añadida a la lista de redirecciones permitidas.

Esta configuración de Auth ([auth] en config.toml) no se sincroniza sola con el proyecto en la nube — hace falta supabase config push explícitamente. Ver Incidencias resueltas, fue la causa real de un bug de producción el 19/09/2026.