Evaluar y adaptar

Cómo está estructurado Sushi SaaS

Entiende las capas obligatorias del starter, sus motivos y cómo añadir una función sin crear una segunda arquitectura.

Esta guía es para quien debe decidir dónde colocar su primera función de producto. Sushi SaaS utiliza una arquitectura horizontal para todos los dominios y la hace cumplir con tests.

El recorrido de una petición

src/app/**       rutas y páginas — entra y sale HTTP

src/services/**  reglas de negocio, coordinación e invariantes

src/models/**    persistencia tipada; única capa que llama a db()

src/db/**        esquema, migraciones y conexión

Una ruta interpreta y responde. Un servicio decide si se permite el trabajo y coordina efectos secundarios. Un modelo se ocupa de lecturas y escrituras. Las restricciones de la base son la última protección ante peticiones concurrentes.

El navegador sigue otra frontera:

Server Component  → servicio directamente
Client Component  → src/api/** → cliente API común → /api/**

Así se evita una llamada HTTP del servidor a sí mismo y los errores de cliente comparten un único contrato. Consulta Arquitectura y contratos de error para las reglas exactas.

Por qué Sushi eligió capas horizontales

Cobros, créditos, almacenamiento, reservas y tareas necesitan autenticación, alcance por tenant, errores y persistencia. Un conjunto de capas hace previsible cada responsabilidad y permite que los tests detecten atajos accidentales.

La contrapartida es que una función ocupa varios directorios. Las carpetas verticales por función pueden ser más cómodas en productos grandes, pero mezclar ambas estructuras es peor: la siguiente consulta o regla tendría dos ubicaciones posibles.

Tus opciones

  • Conservar la estructura cuando un equipo pequeño quiera convenciones fuertes e infraestructura compartida.
  • Migrar por completo a cortes verticales si ya es el estándar del equipo. Mueve dominios completos y actualiza tests/unit/architecture.test.ts; no añadas una isla src/features junto a las reglas actuales.
  • Simplificar para un prototipo temporal si aceptas una migración posterior. Si las rutas escriben en la base, cambia el test de forma explícita en vez de acumular excepciones.

El tenancy también es una elección arquitectónica

Cada usuario recibe una organización personal, por lo que clientes individuales y equipos usan los mismos cobros, créditos, archivos y límites con alcance de organización. Así no existen caminos paralelos de datos “del usuario” y “del equipo”.

Conserva el modelo si podría haber equipos. Si el producto siempre será individual, quitar organizaciones es válido, pero exige cambiar coordinadamente autorización, esquema, modelos, cobros, almacenamiento y tests; no es un interruptor de UI. Lee Organizaciones y equipos antes de decidir.

Por qué el admin está separado

apps/admin tiene páginas, APIs, acceso a datos, puerta MFA y roles de operador propios. Comparte esquema y autenticación, pero puede ejecutarse en otro origen. El coste es otra compilación y despliegue; el beneficio es una frontera operativa clara.

Puedes integrarlo en la aplicación de cliente si prefieres un único despliegue. Conserva autorización de admin en servidor y auditoría: ocultar navegación no es seguridad. Empieza por Configuración de la consola de administración.

Añade tu primer dominio

  1. Define vocabulario y límites en src/types y src/config.
  2. Añade esquema y una migración expand-safe en src/db.
  3. Coloca el CRUD tipado en src/models.
  4. Coloca autorización, idempotencia y efectos en src/services.
  5. Añade la ruta o Server Component en src/app; usa src/api para llamadas de cliente.
  6. Prueba la regla de servicio, la puerta de autenticación de la ruta y los reintentos para dinero o créditos.

Consulta capacidades en vez de comparar nombres de planes y actualiza el runbook cuando cambie el contrato. Esta guía refleja el commit 7580470 del starter.

Cómo está estructurado Sushi SaaS · Sushi SaaS