Traducción de
docs/en/onboarding/getting-started.md, que es el original. Si discrepan, manda el inglés.
Una instalación limpia es un comando. Todo lo que viene después es ese comando desarmado, para cuando haya que correr un paso por separado.
#Requisitos
| Requisito | Versión confirmada o restricción |
|---|---|
| Git | Cualquiera actual |
| Node.js | >=22.17.0 |
| npm | El lockfile es de npm; usa npm ci |
| Docker Engine + Compose | Opcional. Sin él, un PostgreSQL instalado en la máquina |
La integración continua usa Node 24. Node 22 es el mínimo que declaran los manifiestos de la raíz y de la API.
#Instalar
git clone <url-del-repositorio>
cd payment-emulator-lab
npm run setup
npm run setup hace la instalación entera, en orden: comprueba Node, crea .env
desde .env.example si falta, instala desde el lockfile con npm ci, compila los
tres espacios de trabajo, levanta la base de datos, aplica las migraciones y crea
la administradora con la que vas a entrar. Te pregunta su correo y su contraseña,
y nada más.
Usa Docker cuando su motor responde y un PostgreSQL instalado cuando no. Dilo
explícitamente con --docker o --local.
| Opción | Efecto |
|---|---|
--docker / --local |
Elegir el modo en vez de detectarlo |
--seed |
Cargar además los datos de demostración |
--reset |
Destruir antes lo que haya. Pide confirmación |
--no-admin |
Parar tras las migraciones, con la base vacía |
--yes |
No preguntar nada. Para integración continua |
--admin-email --admin-password --admin-name |
Dar la administradora en vez de que te la pregunte |
npm run setup -- --local --seed
npm run setup -- --reset
npm run setup -- --yes --admin-email admin@example.test --admin-password "..." --admin-name Admin
En modo Docker la pila queda en marcha:
- Consola: http://localhost:3000
- Checkout: http://localhost:3001
- API: http://localhost:8080
En modo local no se arranca nada; la base queda lista y los cuatro procesos son cosa tuya (ver Modo desarrollo).
En Windows, run.bat setup llega a este mismo script. Sin Docker hay antes un
paso que ningún script portable puede dar: configure-local.bat —el mismo
asistente que run-local.bat setup— pregunta por tu PostgreSQL, crea el rol
payment y la base payment_emulator si faltan, elige puertos, modo y
transporte de webhooks, genera los secretos que falten y lo escribe en
.env.local antes de llamar a este instalador.
#La administradora
No hay cuenta por defecto ni contraseña de consola. Hay personas, con roles, y la
primera se crea con el token de operador — ADMIN_TOKEN, que actúa como
administrador pero no es nadie. Ver
Identidad, roles y alcance.
npm run setup crea esa primera persona. Para crear una en cualquier otro
momento, contra una API viva:
npm run admin:create
Pregunta correo, nombre visible y contraseña, sin mostrar la contraseña. Sin preguntas:
npm run admin:create -- --email admin@example.test --password "..." --name Admin
Es idempotente por correo: una dirección que ya existe se deja exactamente como está, contraseña incluida. Después de crear la cuenta inicia sesión con ella y la cierra, para que un arranque que respondió bien pero dejó una cuenta inutilizable falle aquí y no en el formulario de la consola.
Lee ADMIN_TOKEN y API_URL del entorno, y después de .env y .env.local. Por
debajo es una sola llamada, POST /auth/bootstrap, que también puedes hacer a
mano:
curl -X POST http://localhost:8080/auth/bootstrap \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"email":"admin@example.test","displayName":"Admin local","role":"admin","password":"cambia-esta-contrasena"}'
En PowerShell, curl es un alias de Invoke-WebRequest y ahí no sobreviven ni
-X ni el JSON entre comillas simples. Usa npm run admin:create, o:
Invoke-RestMethod -Method Post http://localhost:8080/auth/bootstrap `
-Headers @{ Authorization = "Bearer $env:ADMIN_TOKEN" } -ContentType 'application/json' `
-Body '{"email":"admin@example.test","displayName":"Admin local","role":"admin","password":"cambia-esta-contrasena"}'
Con una administradora ya creada, entra por la consola o con POST /auth/login.
Las llamadas normales al plano de control deben usar la sesión de esa persona, no
fingir que el token de operador es alguien.
#Datos de demostración
La semilla está separada de la instalación a propósito: una instalación en la que vas a trabajar no debería empezar con los pagos de otra persona dentro.
npm run seed
npm run seed -- --keep # añadir a lo que ya haya
Llama a las superficies HTTP reales — nada dentro de ella pasa por detrás de la API — y crea personas, aplicaciones, pagos en todos los estados canónicos, cuentas, liquidaciones, un retiro, un contracargo y un escenario escrito a mano. Crea también su propia administradora:
operadora@example.test / emulator-demo-password
Son credenciales de demostración, visibles a propósito. Antes de exponer la pila
a otra máquina, cambia ADMIN_TOKEN, SESSION_PASSWORD y
CHECKOUT_SESSION_PASSWORD en .env, y no reutilices esos valores fuera de este
emulador. Si cambias ADMIN_TOKEN, pon esa misma variable en la terminal que
corre la semilla.
#Migraciones
npm run migrate # aplicar lo pendiente
npm run migrate -- --down # deshacer la última
npm run migrate -- --fresh # deshacerlo todo y volver a aplicarlo
El envoltorio lee .env y .env.local, compila la API si no está dist/ y
espera a que PostgreSQL acepte conexiones, así que se puede lanzar contra una base
que todavía está arrancando. Con Compose casi nunca hace falta: el propio comando
del servicio api migra antes de servir.
--fresh es la base vacía portable. Borrar y recrear necesita un superusuario y
un cliente que este proyecto no exige, así que deshace todas las migraciones y las
vuelve a aplicar — lo que además ejercita la mitad down en vez de darla por
buena.
Las migraciones y el worker corren desde dist/, nunca con tsx: las entidades
llevan los tipos de sus propiedades en emitDecoratorMetadata, y esbuild — que es
sobre lo que corre tsx — no lo emite. Dentro del espacio de trabajo de la API los
tres comandos son npm run migrate, migrate:down y migrate:fresh.
#Comprobar que funciona
La humareda de pila entera usa la consola y el checkout por sus rutas de Nitro, llama a las APIs de proveedor como lo haría una integración, y comprueba que las tres pasarelas y el libro mayor se comportan de forma coherente:
npm run smoke:stack
La humareda pequeña no necesita servidor ni base de datos. Valida los viajes de ida y vuelta del dinero, el emparejado de escenarios y la conformidad estática de cada plugin:
npm run smoke
#Levantar la pila a mano
El camino por Compose corre las mismas seis piezas que ejercita la integración continua: PostgreSQL, Redis, API, worker, consola y checkout.
docker compose up --build --wait
curl http://localhost:8080/health
Respuesta esperada:
{"status":"ok","service":"payment-emulator-lab"}
En Windows, run.bat envuelve Compose con los comandos que si no llevan varias
opciones:
run.bat :: la pila entera en Docker
run.bat dev :: Postgres y Redis en contenedores, los cuatro procesos locales
run.bat infra :: sólo Postgres y Redis
run.bat setup :: la instalación limpia de arriba
run.bat admin :: crear una administradora
run.bat migrate :: aplicar las migraciones pendientes
run.bat seed :: datos de demostración
run.bat smoke :: humareda contra la pila en marcha
run.bat logs [svc] :: seguir los logs de un servicio
run.bat status :: qué hay corriendo
run.bat down :: parar los contenedores, conservar los datos
run.bat reset :: parar y borrar los volúmenes
run.bat env :: crear .env desde .env.example
#Modo desarrollo
Usa Compose sólo para las dependencias:
docker compose up -d postgres redis
npm run migrate
Después, cuatro procesos largos en terminales separadas:
npm run dev:api
npm run start:worker --workspace @payment-emulator/api
npm run dev:console
npm run dev:checkout
Antes de arrancar cada uno, dale su entorno como describe
Configuración. La distinción que importa en
desarrollo directo es que las dos aplicaciones Nuxt leen
NUXT_SESSION_PASSWORD, y tienen que recibir valores distintos en sus procesos
separados.
El .env de la raíz no se lee aquí. Es el fichero que creó npm run setup, y
lo leen Compose y los scripts de Node, pero una API arrancada directamente lee el
.env de su propio directorio de trabajo —apps/api/.env con estos comandos—,
así que un .env de raíz completo sigue terminando en ADMIN_TOKEN is required.
Exporta las variables en cada terminal, como abajo, o escríbelas en
apps/api/.env. Las dos aplicaciones Nuxt se comportan igual con
apps/console/.env y apps/checkout/.env, con una trampa propia: nuxt dev lee
esos ficheros y el servidor compilado no, así que un valor que funcionó durante
todo el desarrollo desaparece en cuanto se compila.
En PowerShell, una terminal mínima para la API:
$env:ADMIN_TOKEN = 'cambia-esto-por-al-menos-16-caracteres'
$env:DATABASE_URL = 'postgresql://payment:payment@localhost:54329/payment_emulator'
npm run dev:api
La API se niega a arrancar si ADMIN_TOKEN falta o tiene menos de 16 caracteres.
El worker necesita la URL de la base y, salvo que use el transporte postgres
por defecto, aquello a lo que apunte WEBHOOK_QUEUE_DRIVER; pon
RUNTIME_OUTBOUND_ENABLED=true sólo cuando los webhooks deban salir de verdad.
El script start:worker:dev usa tsx y no puede aportar los metadatos de
decoradores que necesitan las entidades; compila la API y usa start:worker.
#Arrancar en Windows sin Docker
run-local.bat corre los mismos cuatro procesos contra un PostgreSQL que ya
tengas instalado. Existe porque un PostgreSQL local rara vez está en el puerto que
publica Compose, y porque el transporte de webhooks es una elección.
configure-local.bat :: pregunta la configuracion, prepara la instalacion y arranca los cuatro procesos
run-local.bat setup :: el mismo asistente
run-local.bat doctor :: informa de configuracion, servicios y puertos, sin tocar nada
run-local.bat :: arranca API, worker, consola y checkout, cada uno en su ventana
run-local.bat admin :: crear una administradora
run-local.bat stop :: lista las ventanas de este proyecto y ofrece cerrarlas
El asistente escribe sus respuestas en .env.local, que es el fichero de ajustes
de esta máquina y el lanzador lo vuelve a leer en cada arranque: la conexión, los
tres puertos, el modo, WEBHOOK_QUEUE_DRIVER y los secretos van ahí. Está en
.gitignore, y el asistente sólo sustituye su propio bloque —lo que hayas
escrito a mano se queda—. Todo lo que viene después de configurar es el
instalador portable, así que lo que pasa aquí y lo que pasa en macOS es el mismo
código.
El worker sólo arranca si su transporte responde, y doctor dice cuál es:
Transporte de webhooks
driver postgres
necesita nada mas: entrega desde el outbox
Con el transporte postgres por defecto no hace falta nada más en marcha, que es
justo su razón de ser en una máquina donde Redis significaría WSL. Ver
Configuración y
Webhooks.
#Empezar de cero
npm run setup -- --reset
Con Docker eso borra los volúmenes de PostgreSQL y Redis; en local deshace todas
las migraciones y las vuelve a aplicar. En ambos casos pregunta antes, y --yes
es como una tubería dice que iba en serio.
Para parar sin perder nada:
docker compose down
Eso conserva los volúmenes con nombre. docker compose down --volumes borra
además sus datos locales.
#Cambiar una contraseña por correo
Para una cuenta existente, necesitas la API y PostgreSQL en marcha, las
migraciones aplicadas y el ADMIN_TOKEN con el que arrancó la API. La consola,
el checkout y el worker no son necesarios. Los comandos siguientes se ejecutan
desde la raíz del repositorio, después de preparar la instalación.
#1. Compilar el servidor NestJS
npm run build --workspace @payment-emulator/api
Compila primero los escenarios y después la API. La salida queda en apps/api/dist.
#2. Arrancar la API y dejar esa terminal abierta
Para cargar explícitamente la configuración de la raíz, incluido .env.local
cuando exista:
node --env-file=.env --env-file-if-exists=.env.local apps/api/dist/main.js
Configura DATABASE_URL y ADMIN_TOKEN en esos archivos antes de arrancar.
ADMIN_TOKEN debe tener al menos 16 caracteres y coincidir con el del CLI.
PostgreSQL debe responder en la dirección configurada en DATABASE_URL.
También puedes usar npm run start --workspace @payment-emulator/api si ya
configuraste las variables en la terminal o en apps/api/.env. Ese script no
carga automáticamente el .env de la raíz. Si muestra
ADMIN_TOKEN is required and must be at least 16 characters, comprueba que el
token esté configurado y usa el arranque explícito de arriba. Si ya tienes un
token válido, no necesitas generar otro ni recompilar para cargarlo.
Como alternativa, en PowerShell puedes configurar la terminal de la API:
$env:ADMIN_TOKEN = 'el-mismo-token-configurado-en-tu-env'
$env:DATABASE_URL = 'postgresql://payment:payment@localhost:54329/payment_emulator'
npm run start --workspace @payment-emulator/api
Sustituye el token por el de tu instalación y ajusta usuario, contraseña, puerto
y base de PostgreSQL. El CLI sí lee .env y .env.local de la raíz; el valor
efectivo de ADMIN_TOKEN debe coincidir en ambos procesos. Las variables que
exportes en una terminal no se propagan a otra ya abierta.
#3. Cambiar la contraseña desde otra terminal
Con la API ejecutándose, abre otra terminal en la raíz del repositorio:
npm run password:reset -- --email usuario@example.test
Sustituye el correo por el de tu cuenta. Si la API ya estaba arrancada, puedes
ir directamente a este paso. Para que también pregunte el correo, ejecuta
npm run password:reset sin argumentos.
Pregunta la contraseña en modo oculto y pide repetirla. En automatización usa
USER_PASSWORD o --password; --api permite elegir la API. Lee ADMIN_TOKEN
de .env y .env.local, igual que admin:create. --help muestra las opciones.
Busca el correo exacto, normalizado, recorriendo todas las páginas necesarias;
actualiza mediante PATCH /users/:id. La API valida 8–200 caracteres, calcula
el hash y revoca las sesiones anteriores. El CLI verifica el login y cierra la
sesión usada para comprobarlo. Una cuenta desactivada cambia de contraseña sin
activarse. No imprime ni guarda la contraseña. No existe una contraseña universal
de administración: usa la elegida al crear la cuenta o establece una nueva aquí.