Guía de setup

Requisitos, variables de entorno y primer arranque, con comandos listos para copiar y pegar.

Esta guía te deja el template corriendo en local, con la base de datos migrada y una cuenta con la que entrar. Todo se ejecuta con pnpm, que es el gestor fijado en packageManager dentro de package.json.

pnpm install instala también los hooks de git: en cada commit corre ESLint sobre lo que esté en stage (segundos) y en cada push la suite completa de Playwright. Para saltar la suite de forma deliberada existe SKIP_E2E=1 git push.

Requisitos

HerramientaVersiónPara qué
Node.js>= 22.12El runtime fijado en package.json → engines
pnpm10.xGestor de paquetes; actívalo con corepack enable
PostgreSQL15 o superiorBase de datos. Sirve una gratuita de Neon o una local

1. Instala las dependencias

pnpm install

2. Configura el entorno

Crea un .env en la raíz del proyecto. Estas son las variables que necesitas para arrancar:

# Base de datos PostgreSQL (usa la connection string completa)
NUXT_DATABASE_URL="postgresql://usuario:password@host:5432/base?sslmode=require"

# Better Auth: cadena larga y aleatoria, distinta en cada entorno
BETTER_AUTH_SECRET="pega-aqui-un-secreto-largo"

# URL pública de la app (Better Auth la usa como baseURL)
NUXT_APP_URL="http://localhost:3000"

# Email del administrador de la instancia: con la tabla `user` vacía, `/setup`
# solo acepta esta dirección para crear la primera cuenta (paso 4).
NUXT_ADMIN_EMAIL="admin@example.com"
# Opcional: solo la usa la tarea no interactiva `db:seed_admin`. La contraseña
# normal se elige en `/setup`, no en el entorno.
NUXT_ADMIN_PASSWORD="una-password-larga"

El archivo .env.example de la raíz es la plantilla comentada: cópialo a .env y completa los valores. server/utils/runtimeConfig.ts es la fuente de verdad de los nombres.

Obligatorias

VariablePara quéDónde se lee
NUXT_DATABASE_URLConnection string de PostgreSQLserver/utils/db.ts, server/utils/pgboss.ts, server/database/drizzle.config.ts
BETTER_AUTH_SECRETFirma de sesiones, magic links y tokensBetter Auth la toma del entorno (fallback del SDK); alternativa NUXT_BETTER_AUTH_SECRET → runtimeConfig.betterAuthSecret (server/utils/auth.ts, secret)
NUXT_APP_URLOrigen público: baseURL y trustedOrigins de Better Auth, enlaces de invitación y exportaciones, baseUrl de i18nnuxt.config.ts, server/utils/auth.ts, server/utils/invitations.ts
NUXT_ADMIN_EMAILEmail del administrador: es la única dirección que /setup acepta para crear la primera cuentaserver/api/setup/*
NUXT_ADMIN_PASSWORDOpcional — solo la tarea no interactiva db:seed_adminserver/tasks/db/seed_admin.ts

Opcionales

VariablePara qué y sin ellaDónde se lee
NUXT_NITRO_PRESETPreset de Nitro; con node-server (el del repo) el pool de Drizzle se cachea por procesoserver/utils/db.ts
NUXT_DB_POOL_MAX · _IDLE_TIMEOUT · _CONNECT_TIMEOUT · _MAX_LIFETIMEAjuste del pool de postgres-js (segundos); sin ellas, 10 conexiones y timeouts 20/10/1800 sserver/utils/db.ts
NUXT_REDIS_URLRedis como almacenamiento secundario de Better Auth; sin ella (o si Redis cae) todo va contra la base de datosserver/utils/secondary-storage.ts, server/api/admin/system/health.get.ts
NUXT_RESEND_API_KEYCorreos transaccionales; sin clave se registran pero no se envíanserver/utils/mails-templates.ts, server/api/admin/system/health.get.ts
NUXT_APP_NAMENombre visible en correos y comunicaciones (el de la interfaz sale de i18n)server/utils/mails-templates.ts, server/emails/communication.ts
NUXT_APP_NOTIFY_EMAILRemitente From de los correosserver/utils/mails-templates.ts
NUXT_APP_S3_ENDPOINT · _REGION · _ACCESS_KEY · _SECRET_KEY · _BUCKET_NAMEDocumentos, fotos y adjuntos; sin ellas las subidas quedan apagadas (región por defecto us-east-1)server/utils/create-s3-client.ts, server/utils/get-presigned.ts, server/api/upload/*, server/api/admin/system/health.get.ts
NUXT_APP_S3_BACKUP_BUCKET_NAMEBucket dedicado a los backups de base de datos del dashboard admin; sin él los backups quedan apagados (requiere la sección S3 de arriba)server/utils/database-backup.ts, server/api/admin/backups/*, server/api/admin/system/health.get.ts
NUXT_BACKUP_DATABASE_URL · NUXT_BACKUP_PG_DUMP_PATHBackups: conexión directa para pg_dump (si la principal es pooled) y ruta del binario; sin ellas se usa NUXT_DATABASE_URL quitándole -pooler y el pg_dump del PATHserver/utils/database-backup.ts
NUXT_APP_GOOGLE_CLIENT_ID · NUXT_APP_GOOGLE_CLIENT_SECRETLogin con Google; sin claves el proveedor solo emite un warning al arrancarserver/utils/auth.ts
NUXT_GOOGLE_MAPS_SERVER_KEYGeocodificación en el servidor (autocomplete, place details, timezone)server/api/google/*.get.ts
NUXT_PUBLIC_GOOGLE_MAPS_CLIENT_KEYKey pública del selector de ubicación (restringida por referrer)app/components/plan/LocationPicker.vue
Los backups de base de datos (/app/admin/dashboard) necesitan además el binario pg_dump (versión ≥ a la del servidor PostgreSQL) en la máquina que corre la app: en local brew install postgresql@17 o apt install postgresql-client-17; en el deploy lo instala el Dockerfile.
runtimeConfig lee algunas variables que hoy no tienen consumidores, así que no hacen falta para arrancar: BETTER_AUTH_URL (el baseURL sale de NUXT_APP_URL), NUXT_RESEND_WEBHOOK_SECRET, NUXT_ADMIN_USER_IDS, NUXT_APP_CONTACT_EMAIL, NODE_ENV (public.appEnv) y NUXT_PUBLIC_SITE_URL.
El BETTER_AUTH_SECRET local, el de dev y el de producción deben ser distintos. Ese secreto firma sesiones y enlaces mágicos: si se filtra, hay que rotarlo y todos los enlaces pendientes dejan de valer.

3. Migra la base de datos

pnpm db:migrate    # aplica las migraciones pendientes
pnpm db:generate   # genera una migración después de cambiar el schema
pnpm studio        # abre Drizzle Studio para inspeccionar datos

4. Crea la cuenta admin

El template no tiene registro público. La primera cuenta se crea desde la pantalla de setup de primer arranque: arranca el servidor y abre http://localhost:3000/setup (con la app en marcha, cualquier visita a una ruta privada te lleva ahí mientras no exista ningún usuario).

La pantalla pide el email y la contraseña. El email tiene que coincidir con NUXT_ADMIN_EMAIL — el servidor rechaza cualquier otro, así que funciona como el secreto de la instalación — y la contraseña la eliges tú en ese momento. La cuenta que se crea es platform admin, queda verificada y se inicia sesión automáticamente.

La pantalla deja de existir en cuanto hay un usuario: /setup redirige al login.

Alternativa no interactiva. Para un deploy automatizado, db:seed_admin crea la cuenta a partir de NUXT_ADMIN_EMAIL y NUXT_ADMIN_PASSWORD del entorno. Con el servidor corriendo:

curl -X POST http://localhost:3000/_nitro/tasks/db:seed_admin

La tarea es idempotente: si el usuario ya existe, no hace nada. La lista completa de tareas está en GET /_nitro/tasks.

Esa cuenta es también la que usa la suite de Playwright (E2E_EMAIL / E2E_PASSWORD, con las credenciales del seed como fallback).

5. Arranca

pnpm dev              # http://localhost:3000
pnpm test:e2e:smoke   # smoke de Playwright sobre las páginas principales
pnpm lint             # ESLint (es el único formatter del repo)

Siguientes pasos