Saltar al contenido principal

Stack tecnológico

CapaTecnología
FrontendNext.js 16 (App Router, Turbopack), React 19, Tailwind CSS v4
Componentes UIshadcn/ui v4 (estilo base-nova)
APIFastify 5, TypeScript
Base de datosNeon serverless Postgres, Drizzle ORM
AutenticaciónClerk (organizaciones habilitadas)
FacturaciónStripe
ValidaciónZod
IAOpenAI GPT-4

Estructura del monorepo

PoolPuma usa un monorepo con pnpm workspaces + Turborepo:
  • apps/web: Frontend Next.js con App Router
  • apps/api: API REST con Fastify
  • apps/docs: Este sitio de documentación (Mintlify)
  • packages/db: Esquema Drizzle ORM compartido y utilidades de base de datos

Multi-inquilino

PoolPuma es multi-inquilino usando organizaciones de Clerk. Cada organización representa una empresa de servicio de piscinas y puede tener múltiples sucursales (regiones de servicio).
Los datos de la organización y los miembros de Clerk se sincronizan con la base de datos en el primer acceso mediante la utilidad ensureOrgSynced(). Esto evita depender únicamente de webhooks y maneja casos límite como entregas de webhooks fallidas.

Esquema de base de datos

La base de datos tiene 18 tablas organizadas en estos dominios:
  • Inquilinos: organizations, stores, memberships, store_access
  • CRM: customers, properties, pool_profiles
  • Operaciones: routes, route_stops, technician_assignments, service_visits, service_reports
  • Facturación: plans, subscriptions, invoices
  • Inventario: inventory_items, equipment_assets
  • Sistema: audit_events

Flujo de autenticación

  1. El usuario inicia sesión mediante Clerk
  2. El middleware de Clerk protege todas las rutas /dashboard
  3. En el primer acceso al dashboard, ensureOrgSynced() sincroniza la organización y sus miembros con la base de datos
  4. Todas las consultas posteriores están limitadas a la organización del usuario