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
| Herramienta | Mínimo | Por qué esta versión |
|---|---|---|
| PHP | 8.2+ | composer.json:12 requiere ^8.2. Laravel 12 no carga en 8.1. |
| Composer | 2.x (cualquiera reciente) | Composer 1 no es compatible con Laravel 12. |
| Node | 20.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+. |
| npm | 10.x+ (incluido con Node 20) | O pnpm/bun si lo prefieres; el equipo usa npm. |
| MySQL | 8.x | phpunit.xml espera MySQL. Existe el fallback a SQLite pero los tests han sido auditados como rotos sobre él. |
| Redis | opcional, 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:
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
# Homebrewbrew updatebrew install php@8.2 composer node@20 mysqlbrew services start mysql
# Confirmarphp -v # PHP 8.2.xcomposer -V # Composer 2.xnode -v # v20.xmysql -V # 8.x
# Enlazar PHP 8.2 si Homebrew eligió otro por defectobrew link --overwrite php@8.2Si 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)
# 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/phpsudo 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 antiguocurl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -sudo apt install -y nodejsWindows
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.nety 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
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 entornocp .env.example .env
# Llave de cifrado de la aplicaciónphp artisan key:generateSi 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
mysql -u root -pY 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=mysqlDB_HOST=127.0.0.1DB_PORT=3306DB_DATABASE=miplanteDB_USERNAME=miplanteDB_PASSWORD=localpasswordEjecutar migraciones
php artisan migrateDeberí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
php artisan db:seedLo 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 var | Propósito | Valor a asignar |
|---|---|---|
APP_KEY | Llave de cifrado | auto-generada por php artisan key:generate |
APP_ENV | Modo de entorno | local |
APP_DEBUG | Mostrar stack traces en el navegador | true |
APP_URL | Usada por Inertia + Ziggy | http://localhost:8000 |
DB_CONNECTION | Driver de base de datos | mysql |
DB_HOST | Host de MySQL | 127.0.0.1 |
DB_PORT | Puerto de MySQL | 3306 |
DB_DATABASE | Nombre de la BD local | miplante |
DB_USERNAME | Usuario de BD | miplante |
DB_PASSWORD | Contraseña de BD | localpassword (o la que hayas elegido) |
Fuertemente recomendadas
| Env var | Propósito | Valor |
|---|---|---|
APP_LOCALE | Forzar UI en español | es (nota: .env.example viene con en, lo cual es incorrecto; config/app.php realmente usa es por defecto) |
APP_FALLBACK_LOCALE | Igual | es |
APP_FAKER_LOCALE | Locale de datos de prueba de Faker | es_CO |
MAIL_MAILER | Driver de correo | log (escribe los correos a storage/logs/laravel.log en vez de enviarlos) |
QUEUE_CONNECTION | Driver de queue | database (por defecto — mantiene los queue jobs en MySQL, fácil de inspeccionar) |
CACHE_STORE | Driver de cache | database (por defecto) |
SESSION_DRIVER | Driver de sesión | database (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=0TASA_NOMINAL=0.01914SEGURO_VIDA=0.01MONTO_ESTUDIO_CREDITO=25000Integraciones 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:
composer devDetrás de escena (composer.json:63-66) esto corre cuatro procesos concurrentemente:
| Proceso | Qué hace | URL / salida |
|---|---|---|
php artisan serve | Servidor de desarrollo PHP | http://localhost:8000 |
php artisan queue:listen --tries=1 | Ejecuta queue jobs (esencial para ProcesarPagareDigital, GenerarCreditoDeVenta) | logs en terminal |
php artisan pail --timeout=0 | Tail en vivo del log de Laravel | logs en terminal |
npm run dev | Servidor de Vite con HMR | http://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ón | Comando / URL | Esperado |
|---|---|---|
| 1. Home carga | http://localhost:8000 | Renderiza la página de inicio de Mi Plante, sin errores de Vue en la consola del navegador |
| 2. Página de login del Aliado carga | http://localhost:8000/aliados/login | Formulario de login del portal de partners |
| 3. Rutas están registradas | php artisan route:list | Aproximadamente 139 rutas listadas (la auditoría dice 139 registradas / 135 funcionales) |
| 4. Tinker puede leer usuarios | php artisan tinker y luego App\Models\User::count() | Un entero ≥ 3 (los admins seedeados) |
| 5. Tinker puede leer líneas | App\Models\Linea::count() | ~50 (jerarquía multi-nivel del LineaSeeder) |
| 6. Tests pasan | composer test | Verde (asume que la BD miplante_testing existe y está migrada) |
| 7. Lint limpio | npm run lint | Sin errores (warnings están bien) |
| 8. Verificación de formato | npm run format:check | Sin desviaciones |
| 9. Log viewer carga | http://localhost:8000/aliados/log-viewer | Requiere 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:
php artisan test --filter=AprobarCupoEsto 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()→ siempreLegalCheckResult::success()IdentityValidationService::validarIdentidad()→ siempreIdentityValidationResult::success()IdentityValidationService::generarOTP()→ retorna OTP123456cacheadoDataCreditoService::obtenerHistorial()→ retorna un score fijo de 600EmcaliMembresiaService::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.
| Error | Causa probable | Solución |
|---|---|---|
Class "App\Http\Kernel" not found | Está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 refused | MySQL no está corriendo. | brew services start mysql (macOS) / sudo service mysql start (Linux). |
SQLSTATE[HY000] [1045] Access denied | Las 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.json | Corriste php artisan serve pero no npm run dev (ni npm run build). | Corre ambos, o simplemente usa composer dev. |
419 Page Expired | CSRF / 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 mismatched | Vite 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 cliente | Guard 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 CI | CI 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 devarranca sin errores -
http://localhost:8000muestra la página de inicio de Mi Plante -
http://localhost:5173(Vite) está sirviendo assets - Puedes iniciar sesión como
testadmin@example.com/Test1234.enhttp://localhost:8000/aliados/loginy ver el portal de partners -
composer testpasa -
npm run lintpasa -
npm run format:checkestá limpio - Puedes correr
php artisan tinkery consultarApp\Models\User::all() - Puedes navegar a
http://localhost:8000/aliados/log-viewery 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
| Herramienta | Qué te aporta | Cómo usarla |
|---|---|---|
| Laravel Pint | Linter / formateador de PHP (compatible PSR-12) | vendor/bin/pint para todo el repo; configurado en las dev deps de composer.json |
| Laravel Pail | Streaming de logs en tiempo real | ya corre como parte de composer dev; standalone: php artisan pail |
| Opcodes Log Viewer | Visor de logs en navegador | http://localhost:8000/aliados/log-viewer (requiere estar logueado como admin) |
| Tinker | REPL interactivo | php artisan tinker y luego App\Models\User::all(), etc. |
| Laravel IDE Helper | Genera .phpstorm.meta.php para intellisense del IDE | ya está en dev deps; corre php artisan ide-helper:generate después de cambios en modelos |
| Vue DevTools | Extensión de navegador para inspeccionar el árbol de componentes Vue | Instala en Chrome / Firefox; funciona automáticamente cuando APP_DEBUG=true |
| TablePlus / DBeaver | GUI de BD | conéctate a 127.0.0.1:3306 con las credenciales que asignaste |
php artisan route:list | Todas las rutas registradas | útil cuando buscas un 404 |
php artisan tinker | REPL de BD | verificaciones rápidas de modelos sin escribir migraciones |
php artisan db:seed --class=LineaSeeder | Re-ejecutar un seeder específico | si 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:generateafter 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:
- Abre
resources/js/pages/Welcome.vue(o cualquiera que sea la página de inicio — revisaroutes/web.phppara la llamada de render de Inertia de la rutahome). - Encuentra un string en la página de inicio.
- Cámbialo.
- Guarda el archivo.
- 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.