Saltearse al contenido

Entorno Local

Objetivo: desde un laptop nuevo hasta localhost:8000 mostrando la página de inicio de Mi Plante en menos de una hora.

Si ya has trabajado antes con Laravel e Inertia, espera de 20 a 30 minutos. Si es tu primera vez con el stack, espera de 45 a 60. Si te topas con algo inesperado, ve a 03-common-gotchas.md antes de escribir en el chat del equipo.


1. Prerrequisitos

Versiones exactas

HerramientaMínimoPor qué esta versión
PHP8.2+composer.json:12 requiere ^8.2. Laravel 12 no carga en 8.1.
Composer2.x (cualquiera reciente)Composer 1 no es compatible con Laravel 12.
Node20.x LTS (o 22.x)Vite 6 requiere Node moderno. package.json no fija un mínimo pero la documentación de Vite 6 indica Node 18+.
npm10.x+ (incluido con Node 20)O pnpm/bun si lo prefieres; el equipo usa npm.
MySQL8.xphpunit.xml espera MySQL. Existe el fallback a SQLite pero los tests han sido auditados como rotos sobre él.
Redisopcional, no se usa realmente en runtime.env.example referencia Redis pero el código usa MySQL para cache/queue/session. Puedes ignorar Redis en local.

Extensiones PHP requeridas

La lista completa de Laravel 12 — la mayoría de distribuciones las incluyen por defecto con los paquetes php:

bcmath, ctype, fileinfo, gd, intl, mbstring, openssl, pdo_mysql, tokenizer, xml, zip, curl

Para verificar lo que tienes:

Ventana de terminal
php -m | sort | grep -E 'bcmath|ctype|fileinfo|gd|intl|mbstring|openssl|pdo_mysql|tokenizer|xml|zip|curl'

Si falta alguna, instala el paquete correspondiente (php8.2-intl, php8.2-gd, etc. en Debian/Ubuntu; brew install php@8.2 las cubre todas en macOS).

Opcionales pero recomendadas

  • TablePlus / DBeaver / Sequel Ace — GUI de BD para inspeccionar MySQL durante el desarrollo. El modelo de datos está en español; una GUI ayuda.
  • Laravel Tinker (ya incluido) — REPL para interactuar con los modelos.
  • php artisan pail (incluido vía dev deps) — visor de logs en tiempo real.
  • Opcodes Log Viewer en /aliados/log-viewer (ya integrado) — inspección de logs desde el navegador.
  • VS Code con las extensiones PHP Intelephense, Vue Language Tools, ESLint, Prettier. PhpStorm o Cursor funcionan igual de bien.

2. Notas específicas por SO

macOS

Ventana de terminal
# Homebrew
brew update
brew install php@8.2 composer node@20 mysql
brew services start mysql
# Confirmar
php -v # PHP 8.2.x
composer -V # Composer 2.x
node -v # v20.x
mysql -V # 8.x
# Enlazar PHP 8.2 si Homebrew eligió otro por defecto
brew link --overwrite php@8.2

Si MySQL se rehúsa a arrancar con mysql_secure_installation, elimina el requisito de contraseña de root o asigna una explícitamente — las credenciales de la BD de dev local irán a .env.

Linux (Debian/Ubuntu)

Ventana de terminal
# Añadir el PPA de Ondrej PHP para PHP 8.2 si no estás en Ubuntu 24.04+
sudo add-apt-repository ppa:ondrej/php
sudo apt update
sudo apt install -y php8.2 php8.2-cli php8.2-fpm php8.2-mysql php8.2-mbstring \
php8.2-xml php8.2-curl php8.2-zip php8.2-bcmath php8.2-gd php8.2-intl \
composer mysql-server nodejs npm
# Node 20 desde NodeSource si el npm de tu distro es más antiguo
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs

Windows

Usa WSL2 (Windows Subsystem for Linux) y sigue las instrucciones de Linux dentro de Ubuntu 22.04 o 24.04. PHP nativo en Windows funciona en teoría pero genera fricción con Composer, Vite y los file watchers. No pelees esa batalla el día 1.

Si debes usar Windows nativo:

  • Instala PHP 8.2 desde windows.php.net y agrégalo al PATH.
  • Instala Composer para Windows.
  • Instala Node 20 LTS desde nodejs.org.
  • Instala MySQL Community Server.
  • Espera problemas con la sensibilidad a mayúsculas/minúsculas del sistema de archivos y con scripts vendor/bin/* que asumen bash.

3. Clonar el repo e instalar dependencias

Ventana de terminal
git clone <repo-url>
cd ext-miplante
# Dependencias PHP (alrededor de 150 MB)
composer install
# Dependencias Node (alrededor de 400-500 MB)
npm install
# Archivo de entorno
cp .env.example .env
# Llave de cifrado de la aplicación
php artisan key:generate

Si composer install se queja por extensiones, instala lo que pida y reintenta.

Si npm install se queja por lightningcss-linux-x64-gnu o @tailwindcss/oxide-linux-x64-gnu en macOS o Windows — esos son binarios opcionales exclusivos de Linux. El bloque optionalDependencies en package.json es intencional. Puedes ignorar el warning.


4. Configuración de base de datos

El .env.example del repo trae por defecto DB_CONNECTION=sqlite, pero se recomienda fuertemente MySQL para el desarrollo local porque:

  • La BD de producción es MySQL — mantener local en MySQL detecta temprano bugs específicos de MySQL.
  • La base de datos de tests de PHPUnit (phpunit.xml) está configurada para MySQL.
  • Algunas migraciones pueden comportarse distinto en SQLite (especialmente las que hacen ALTER de tablas).

Crear las bases de datos locales

Ventana de terminal
mysql -u root -p

Y luego en el prompt de MySQL:

CREATE DATABASE miplante CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE miplante_testing CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'miplante'@'localhost' IDENTIFIED BY 'localpassword';
GRANT ALL PRIVILEGES ON miplante.* TO 'miplante'@'localhost';
GRANT ALL PRIVILEGES ON miplante_testing.* TO 'miplante'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Editar .env para MySQL

Cambia estas líneas en .env:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=miplante
DB_USERNAME=miplante
DB_PASSWORD=localpassword

Ejecutar migraciones

Ventana de terminal
php artisan migrate

Deberías ver correr alrededor de 54 archivos de migración. Si ves errores de “Table already exists”, la base de datos no se eliminó limpiamente — ejecuta php artisan migrate:fresh para borrarla y recrearla.

Ejecutar seeders

Ventana de terminal
php artisan db:seed

Lo que esto te da está documentado en detalle en 02-seed-data-walkthrough.md. Versión corta: Líneas, Marcas y una Empresa MASTER con tres usuarios admin (testadmin@example.com, testadmincomercial@example.com, testfinanciero@example.com, contraseña Test1234. para los tres).

Nota: el ClienteAdministradorSeeder existe pero no se llama desde DatabaseSeeder::run(). No hay un Cliente seedeado ni datos de productos del marketplace seedeados por defecto. Tendrás que crearlos manualmente o extender los seeders (una excelente primera contribución).


5. Variables de entorno que debes configurar en local

Para un entorno básico de dev local (sin llamadas a APIs externas), solo necesitas configurar el bloque principal. Para un entorno local completo que pueda intentar el flujo de aprobación de crédito, necesitarías todas las credenciales de APIs externas — que no tienes, así que no te molestes.

Requeridas para cualquier dev local

Env varPropósitoValor a asignar
APP_KEYLlave de cifradoauto-generada por php artisan key:generate
APP_ENVModo de entornolocal
APP_DEBUGMostrar stack traces en el navegadortrue
APP_URLUsada por Inertia + Ziggyhttp://localhost:8000
DB_CONNECTIONDriver de base de datosmysql
DB_HOSTHost de MySQL127.0.0.1
DB_PORTPuerto de MySQL3306
DB_DATABASENombre de la BD localmiplante
DB_USERNAMEUsuario de BDmiplante
DB_PASSWORDContraseña de BDlocalpassword (o la que hayas elegido)

Fuertemente recomendadas

Env varPropósitoValor
APP_LOCALEForzar UI en españoles (nota: .env.example viene con en, lo cual es incorrecto; config/app.php realmente usa es por defecto)
APP_FALLBACK_LOCALEIguales
APP_FAKER_LOCALELocale de datos de prueba de Fakeres_CO
MAIL_MAILERDriver de correolog (escribe los correos a storage/logs/laravel.log en vez de enviarlos)
QUEUE_CONNECTIONDriver de queuedatabase (por defecto — mantiene los queue jobs en MySQL, fácil de inspeccionar)
CACHE_STOREDriver de cachedatabase (por defecto)
SESSION_DRIVERDriver de sesióndatabase (por defecto)

Valores por defecto del marketplace (ya configurados en .env.example)

Vienen pre-cargados; no necesitas cambiarlos a menos que quieras experimentar con tasas distintas:

DIAS_DESFASE=0
TASA_NOMINAL=0.01914
SEGURO_VIDA=0.01
MONTO_ESTUDIO_CREDITO=25000

Integraciones externas — déjalas vacías en local

No llenes EXPIRIAN_*, TRANSUNION_*, DATACREDITO_*, CERTICAMARA_*, CORE_CREDITO_*, EMCALI_*. No tienes esas credenciales. El flujo de aprobación de crédito fallará en la primera llamada externa, lo cual se espera para dev local.

Implicación: puedes navegar el marketplace, registrarte, iniciar sesión, ver tu perfil, gestionar carrito y wishlist. No puedes completar el pipeline de aprobación de crédito localmente sin mocks.

Este es el dolor de cabeza más grande en dev local y está marcado como un candidato Tier-1 de primera contribución: construir un LocalIntegrationMockProvider (o similar) que retorne respuestas enlatadas cuando APP_ENV=local. Ver la sección 8 más abajo.


6. El comando composer dev

La forma más rápida de levantar el stack completo localmente es:

Ventana de terminal
composer dev

Detrás de escena (composer.json:63-66) esto corre cuatro procesos concurrentemente:

ProcesoQué haceURL / salida
php artisan serveServidor de desarrollo PHPhttp://localhost:8000
php artisan queue:listen --tries=1Ejecuta queue jobs (esencial para ProcesarPagareDigital, GenerarCreditoDeVenta)logs en terminal
php artisan pail --timeout=0Tail en vivo del log de Laravellogs en terminal
npm run devServidor de Vite con HMRhttp://localhost:5173 (proxyeado automáticamente a través de Laravel)

La salida está codificada por color:

  • Azul: server
  • Morado: queue
  • Rojo: logs
  • Naranja: vite

Presiona Ctrl+C una vez y los cuatro procesos se detienen (vía --kill-others).

Si no quieres usar composer dev: puedes correr cada comando por separado en cuatro pestañas de terminal. El subconjunto mínimo más común es php artisan serve + npm run dev si estás trabajando solo en cambios de UI.


7. Checklist de verificación de primera ejecución

Después de que composer dev esté arriba:

VerificaciónComando / URLEsperado
1. Home cargahttp://localhost:8000Renderiza la página de inicio de Mi Plante, sin errores de Vue en la consola del navegador
2. Página de login del Aliado cargahttp://localhost:8000/aliados/loginFormulario de login del portal de partners
3. Rutas están registradasphp artisan route:listAproximadamente 139 rutas listadas (la auditoría dice 139 registradas / 135 funcionales)
4. Tinker puede leer usuariosphp artisan tinker y luego App\Models\User::count()Un entero ≥ 3 (los admins seedeados)
5. Tinker puede leer líneasApp\Models\Linea::count()~50 (jerarquía multi-nivel del LineaSeeder)
6. Tests pasancomposer testVerde (asume que la BD miplante_testing existe y está migrada)
7. Lint limpionpm run lintSin errores (warnings están bien)
8. Verificación de formatonpm run format:checkSin desviaciones
9. Log viewer cargahttp://localhost:8000/aliados/log-viewerRequiere login como admin; debería mostrar la UI del Opcodes log viewer

Si 1-3 funcionan pero 4 falla, tu seed de BD no se ejecutó. Vuelve a correr php artisan db:seed.

Si 1 funciona pero 6 falla porque los tests quieren una BD miplante_testing, repite la configuración de MySQL para la BD de testing.


8. Mocking de integraciones externas para dev local

Eventualmente vas a querer ejercitar el flujo de aprobación de crédito localmente. Dos enfoques:

Enfoque A — Solo-tests (funciona hoy)

La suite de tests usa Http::fake() de Laravel para cortocircuitar las llamadas externas. Patrón de ejemplo (de tests/Feature/AprobarCliente/):

Http::fake([
'*/cs/credit-history/*' => Http::response([
'ReportHDCplus' => ['productResult' => ['responseCode' => 13]]
], 200),
// ... más fakes
]);

Corre un feature test específico para verlo en acción:

Ventana de terminal
php artisan test --filter=AprobarCupo

Esto funciona para la suite de tests pero no para php artisan serve — cuando navegas por la UI, las llamadas HTTP reales se disparan y fallan.

Enfoque B — Mocking en runtime de dev (no existe aún)

Contribución nueva recomendada: construir un service provider LocalIntegrationMockProvider que se registre bajo APP_ENV=local y retorne respuestas enlatadas para las llamadas a APIs externas. Esquema:

// app/Providers/LocalIntegrationMockProvider.php (BORRADOR — no existe)
class LocalIntegrationMockProvider extends ServiceProvider
{
public function register(): void
{
if (!app()->environment('local')) return;
// Bindear un CerticamaraService falso que retorne UUIDs falsos
$this->app->bind(CerticamaraService::class, FakeCerticamaraService::class);
// Lo mismo para DataCreditoService, IdentityValidationService, etc.
}
}

Luego en bootstrap/providers.php, regístralo. Los servicios falsos retornan datos enlatados realistas:

  • LegalCheckService::manejar() → siempre LegalCheckResult::success()
  • IdentityValidationService::validarIdentidad() → siempre IdentityValidationResult::success()
  • IdentityValidationService::generarOTP() → retorna OTP 123456 cacheado
  • DataCreditoService::obtenerHistorial() → retorna un score fijo de 600
  • EmcaliMembresiaService::consultarMembresia() → retorna membresía válida para cualquier dirección

Esto desbloquea el pipeline completo localmente y es una de las tareas de onboarding con mayor apalancamiento. Márquenla como Tier-1.


9. Problemas comunes de setup

Referencia rápida. El catálogo completo de landmines está en 03-common-gotchas.md.

ErrorCausa probableSolución
Class "App\Http\Kernel" not foundEstás siguiendo un tutorial viejo de Laravel 9-10. Laravel 12 usa bootstrap/app.php, sin Kernel.php.Revisa bootstrap/app.php para el registro de middleware/rutas.
SQLSTATE[HY000] [2002] Connection refusedMySQL no está corriendo.brew services start mysql (macOS) / sudo service mysql start (Linux).
SQLSTATE[HY000] [1045] Access deniedLas credenciales de BD en .env no coinciden con lo que GRANTeaste en MySQL.Verifica dos veces DB_USERNAME / DB_PASSWORD.
Vite manifest not found at: public/build/manifest.jsonCorriste php artisan serve pero no npm run dev (ni npm run build).Corre ambos, o simplemente usa composer dev.
419 Page ExpiredCSRF / sesión expirada.Limpia las cookies del navegador para localhost, o reinicia npm run dev si el reinicio de Vite borró la cookie de sesión.
Inertia: The Inertia X-Inertia-Version header is mismatchedVite reinició con un nuevo hash de build.Hard-refresh del navegador (Cmd+Shift+R / Ctrl+Shift+F5).
419 en /aliados/* pero no en rutas de clienteGuard distinto con posiblemente distinta ruta de cookie de sesión.Revisa los alias de middleware en bootstrap/app.php.
Class "App\Services\Modelo" not found (o similar)¿Corriste composer install? El autoload puede no estar preparado.composer dump-autoload.
Migraciones fallan con “Specified key was too long”MySQL viejo sin soporte de longitud de índice utf8mb4 por defecto.Asegura MySQL 8.x. Si estás en 5.7, agrega Schema::defaultStringLength(191) en un service provider, pero realmente, solo usa MySQL 8.
Tests fallan con “no MySQL test connection”La BD miplante_testing no existe o no está migrada.Recréala como en la sección 4.
Tests pasan localmente pero fallan en CICI usa el fallback de SQLite (auditado como roto — L-25). No confíes solo en CI verde hoy.Corre localmente como fuente de verdad.

10. Cuando finalmente puedes empezar a codear

Estás listo para escribir tu primer PR cuando todos estos son verdaderos:

  • composer dev arranca sin errores
  • http://localhost:8000 muestra la página de inicio de Mi Plante
  • http://localhost:5173 (Vite) está sirviendo assets
  • Puedes iniciar sesión como testadmin@example.com / Test1234. en http://localhost:8000/aliados/login y ver el portal de partners
  • composer test pasa
  • npm run lint pasa
  • npm run format:check está limpio
  • Puedes correr php artisan tinker y consultar App\Models\User::all()
  • Puedes navegar a http://localhost:8000/aliados/log-viewer y ver logs

Si algo está en rojo, arréglalo antes de escribir código. No desarrolles sobre un local roto — vas a perder horas.


11. Herramientas de dev recomendadas

HerramientaQué te aportaCómo usarla
Laravel PintLinter / formateador de PHP (compatible PSR-12)vendor/bin/pint para todo el repo; configurado en las dev deps de composer.json
Laravel PailStreaming de logs en tiempo realya corre como parte de composer dev; standalone: php artisan pail
Opcodes Log ViewerVisor de logs en navegadorhttp://localhost:8000/aliados/log-viewer (requiere estar logueado como admin)
TinkerREPL interactivophp artisan tinker y luego App\Models\User::all(), etc.
Laravel IDE HelperGenera .phpstorm.meta.php para intellisense del IDEya está en dev deps; corre php artisan ide-helper:generate después de cambios en modelos
Vue DevToolsExtensión de navegador para inspeccionar el árbol de componentes VueInstala en Chrome / Firefox; funciona automáticamente cuando APP_DEBUG=true
TablePlus / DBeaverGUI de BDconéctate a 127.0.0.1:3306 con las credenciales que asignaste
php artisan route:listTodas las rutas registradasútil cuando buscas un 404
php artisan tinkerREPL de BDverificaciones rápidas de modelos sin escribir migraciones
php artisan db:seed --class=LineaSeederRe-ejecutar un seeder específicosi borraste datos y solo quieres reseedear una sección

12. Configuración del editor / IDE

Sea cual sea el que uses, instala estas extensiones / plugins:

VS Code

  • PHP Intelephense
  • Vue Language Tools (Volar)
  • ESLint
  • Prettier
  • Tailwind CSS IntelliSense
  • Laravel Blade Snippets
  • Inertia.js
  • GitLens

Configuración para agregar al .vscode/settings.json de tu workspace (sugerida):

{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit" },
"[php]": { "editor.defaultFormatter": "junstyle.php-cs-fixer" },
"[vue]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
"[typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }
}

PhpStorm / Cursor

PhpStorm autodetecta la mayoría de cosas. Asegúrate de:

  • Tener habilitado el plugin de Laravel (file → settings → plugins)
  • Tener habilitado “Run php artisan ide-helper:generate after changes”

13. La primera cosa que deberías cambiar

Ahora que la app corre, no escribas código de producción todavía. Prueba este calentamiento seguro:

  1. Abre resources/js/pages/Welcome.vue (o cualquiera que sea la página de inicio — revisa routes/web.php para la llamada de render de Inertia de la ruta home).
  2. Encuentra un string en la página de inicio.
  3. Cámbialo.
  4. Guarda el archivo.
  5. Observa el hot-reload del navegador.

Si ves tu cambio, el loop funciona. No hagas commit. Revierte el cambio. Ya estás listo.


14. Orden de lectura a partir de aquí

Siguiente:

  • docs/onboarding/03-development-setup/02-seed-data-walkthrough.md — qué hay en la BD, con qué usuarios puedes loguearte, qué falta.
  • docs/onboarding/03-development-setup/03-common-gotchas.md — las 15-20 cosas no obvias que te van a hacer tropezar en la semana 1. Léelo antes de toparte con ellas.
  • docs/onboarding/02-codebase-tour/ — el recorrido estructural del codebase. Los docs de la auditoría son la fuente canónica; el codebase tour es el resumen amigable para nuevos devs.

Deberías estar corriendo localmente en menos de una hora. Si te tomó más, deja una nota en el canal del equipo sobre qué paso te mordió — esa es nuestra deuda por pagar.