Skip to content

Ambiente: Development

Status: ✅ Stack completo levantable con ./start-dev.sh Última actualización: 2026-07-25

Qué corre hoy en Dev (todo vía Docker Compose)

ServicioImagen/BuildPuertoRol
frontendfrontend/Dockerfile.dev (Vue 3 + Vite)5173UI de la web app
backendbackend/Dockerfile.dev (Laravel 13 + PHP 8.5)3000 → 8000API propia
backend-queuemismo build que backendphp artisan queue:work (jobs encolados)
backend-schedulermismo build que backendphp artisan schedule:work (cron de SendRequest cada 30 min)
postgrespostgres:17-alpine5432Base de datos (en staging/prod: Aurora PostgreSQL — ver ADR-003)
redisredis:7-alpine6379Cache + colas
firebase-emulatorinfra/firebase-emulator/Dockerfile9099 (auth) / 4000 (UI)Firebase Auth sin tocar el proyecto real
admineradminer:latest8081Administración visual de Postgres
docsnginx:alpine (sirve doc/site/public/)— (detrás de traefik)Portal de documentación de API (ReDoc + login vía emulador)
traefiktraefik:v3.380Reverse proxy — expone docs-vitepress y docs en sus dominios .localhost
docs-vitepressdoc/Dockerfile.dev (VitePress)— (detrás de traefik)Sitio de documentación del proyecto (Análisis Funcional, ADRs, planes, QA)

Todavía no conectado: integración real con Soterex (sandbox) y el proyecto Laravel existente de Soterex que el cliente va a compartir (ver ADR-002).

Cómo levantar el ambiente Dev

bash
git clone git@github.com:raxardev/soterex.git
cd soterex
./start-dev.sh

El script:

  1. Verifica que Docker/Docker Compose v2 estén instalados.
  2. Genera backend/.env y frontend/.env.local desde sus .env.example la primera vez (nunca pisa un .env que ya exista).
  3. Levanta todo el stack con docker compose up --build.

URLs una vez levantado:

Datos iniciales y usuarios de desarrollo (seed)

bash
docker compose exec backend php artisan migrate --seed

Idempotente: se puede correr las veces que haga falta. Crea el catálogo base (roles + matriz de permisos del funcional §2.1, países) y, solo en local, los mocks: 4 PDVs de Guatemala, 24 transacciones (ACCEPTED/PAID/CANCELLED), 3 asientos de prefondeo y logs de auditoría de ejemplo.

También crea los usuarios de desarrollo en el emulador y en la base (DevUserSeeder):

EmailPasswordRolAlcance
admin@cislatam.testAdmin123!AdminGuatemala, todos los PDVs
supervisor@cislatam.testSuper123!SupervisorGT-CAP-001 + GT-QUE-002
backoffice@cislatam.testBackoffice123!BackofficeGT-CAP-001

El emulador pierde los usuarios en cada restart del contenedor (base en memoria): volver a correr php artisan db:seed los recrea sin duplicar nada.

Crear un usuario de prueba adicional en el Firebase Auth Emulator

Los usuarios estándar de desarrollo los crea el seed (ver sección anterior). Para un usuario ad-hoc extra:

bash
curl -X POST 'http://localhost:9099/identitytoolkit.googleapis.com/v1/accounts:signUp?key=fake-api-key' \
  -H 'Content-Type: application/json' \
  -d '{"email":"otro@cislatam.test","password":"secreto123","returnSecureToken":true}'

O manual: abrir http://localhost:4000 → pestaña Authentication → agregar usuario con email/password. Ojo: un usuario creado así existe solo en el emulador — no tiene fila en users ni rol asignado en la base.

Variables de entorno (Dev)

Ver backend/.env.example y frontend/.env.example — se copian automáticamente a .env / .env.local la primera vez que se corre start-dev.sh, que además genera el APP_KEY y una service account fake en backend/storage/firebase/dev-service-account.json (el SDK de Firebase exige una credencial con forma válida aunque hable con el emulador; nunca se commitea).

Validación end-to-end (2026-07-25)

Primera corrida real de composer install + ./start-dev.sh en un entorno con acceso a Packagist. Todo el stack levanta y quedó validado end-to-end:

  • composer install OK (Laravel 13.22, PHP 8.5.8) — hubo que corregir constraints inventados del scaffold: laravel/sanctum ^5.0 → ^4.0 (v5 no existe), laravel/tinker ^2.10 → ^3.0 y kreait/laravel-firebase ^6.1 → ^7.0 (las versiones anteriores no soportan Laravel 13). composer.lock commiteado a partir de acá.
  • Las 11 migraciones corren limpias contra Postgres 17.
  • Auth end-to-end: usuario creado en el Auth Emulator → GET /api/transacciones con Authorization: Bearer <idToken> → 200; sin token → 401.
  • Health check: GET http://localhost:3000/up → 200. Queue worker y scheduler corriendo.

Arreglos de scaffold que hicieron falta (ya aplicados): .firebaserc faltante en infra/firebase-emulator/, start-dev.sh sin permiso de ejecución, bootstrap/cache/ y storage/framework/* faltantes (con sus .gitignore), backend/.gitignore faltante, y el @import de Google Fonts después de Tailwind en frontend/src/style.css (el browser lo ignoraba y las fuentes no cargaban).

Segunda ronda (frontend, validado con browser real headless — login + API):

  • frontend/.env.example venía con VITE_FIREBASE_API_KEY vacía → getAuth() tiraba auth/invalid-api-key y la app no montaba. En dev contra el emulador alcanza cualquier string no vacío (fake-api-key) + VITE_FIREBASE_PROJECT_ID=demo-soterex — ya vienen cargados en el example.
  • El router guard trataba loading=true como "dejar pasar" → cualquier ruta privada renderizaba sin sesión en el primer load. Ahora el guard espera (untilReady()) a que Firebase resuelva el estado inicial.
  • Carrera intermitente al loguear: signIn() resolvía antes de que onAuthStateChanged poblara el store y el guard rebotaba al login. El store ahora setea el user directo del credential.
  • VITE_API_PROXY_TARGET del example apuntaba a backend:3000 (puerto/host inválido en todos los escenarios) → localhost:3000 (docker-compose lo pisa con backend:8000).

E2E de browser verificado (3 corridas): deep-link sin sesión → redirect a /login?redirect=… → login contra el emulador → vuelve a la ruta pedida → api.get('/transacciones') con el Bearer token real → 200 con el email del usuario. Cero errores de consola.

Tests de backend (phpunit)

bash
docker compose exec backend php artisan test

Antes de correr la suite completa la primera vez en una sesión nueva, correr el test canario de aislamiento — no toca ninguna tabla, solo confirma que la conexión activa es soterex_test:

bash
docker compose exec backend ./vendor/bin/phpunit --filter=DatabaseIsolationTest

Si ese test falla, no correr nada más — ver el incidente documentado en doc/plans/2026-07-25-plan-desarrollo-modulos.md (aislamiento de base de datos en tests): la suite completa usa RefreshDatabase, que si pierde el aislamiento vacía la base de dev por completo (recuperable con php artisan db:seed, pero mejor evitarlo).

Próximos pasos para completar Dev

  1. En un clone nuevo, migrar la base la primera vez: docker compose exec backend php artisan migrate.
  2. Conectar el SoterexClient a credenciales reales de sandbox de Soterex.
  3. Cuando el cliente comparta el proyecto Laravel existente de Soterex, evaluar reuso de su cliente de integración (ver ADR-002).

Documentación viva — se actualiza junto con el código, no es un anexo aparte.