Saltar a contenido

Incidente: php artisan test vaciaba la base de desarrollo

Fecha: 2026-07-14 Estado: Causa raíz corregida; base dev restaurada desde backup del 2026-01-30.

Qué pasaba

Al correr php artisan test, los tests con RefreshDatabase ejecutaban migrate:fresh contra compulandia_integrador_dev (MySQL real), dropeando todas las tablas. Como las migraciones del proyecto viven en subdirectorios numerados (database/migrations/00..72), migrate:fresh además no recreaba nada: la base quedaba vacía. Era un problema conocido ("no se pueden correr tests acá").

Causa raíz

Existía bootstrap/cache/config.php (config cacheada, generada por root el 23/jun). Con config cacheada, Laravel ignora los <env> del phpunit.xml (DB_CONNECTION=sqlite, DB_DATABASE=:memory:) y usa la conexión cacheada: MySQL → compulandia_integrador_dev.

Factores agravantes:

  • Este host no tiene la extensión pdo_sqlite, así que aun sin config cacheada los tests sqlite nunca habrían funcionado (fallan con "could not find driver"), lo que ocultaba el problema de fondo.
  • .env.testing existe y apunta a sqlite :memory: (inutilizable por lo anterior).

Corrección aplicada (2026-07-14)

  1. Eliminado bootstrap/cache/config.php. Regla operativa: en este servidor no usar php artisan config:cache (o correr config:clear antes de cualquier test).
  2. Guard de seguridad en tests/CreatesApplication.php: al bootear la app de tests, si la conexión no es sqlite :memory: ni una base cuyo nombre termine en _test, se lanza excepción ANTES de que RefreshDatabase pueda tocar nada. Esto hace imposible repetir el incidente, incluso con config cacheada.
  3. phpunit.xml apunta a compulandia_integrador_test (base scratch dedicada, mismo servidor MySQL), ya que sqlite no está disponible.
  4. Los tests nuevos de productos compuestos (tests/*/CompositeProducts/) no usan RefreshDatabase: crean su propio esquema con drop+create por test (tests/Concerns/CreatesCompositeProductsSchema.php).

Nota: AppServiceProvider::shareDataGlobally() consulta suppliers/partners/ product_categories en el boot de la app, por lo que correr tests requiere que esas tablas existan en la base _test (pendiente si se retoman los tests).

Restauración

  • Backup usado: dump local de compulandia_integrador_dev del 2026-01-30 (402MB, dump de compulandia_integrador_dev del 2026-01-30, 66 tablas).
  • Restaurado el 2026-07-14 + migraciones pendientes aplicadas: 67 (parcial), 70, 71 y 72 (productos compuestos, RFC 004).
  • Verificado post-restore: 22.071 supplier_products, 14.197 product_items, 10 suppliers, 29 SKUs pcm-.
  • Gap de datos: lo que haya cambiado en dev entre el 30/ene y el incidente no está en el backup. Si hace falta algo más fresco, existen compulandia_integrador (840MB) y compulandia_integrador_staging (416MB) como fuentes alternativas de clonado.

Prevención a futuro

  • El guard de CreatesApplication es la barrera principal — no removerlo.
  • Programar un backup periódico de compulandia_integrador_dev (el único dump disponible tenía 5,5 meses).
  • Si se quiere volver a sqlite: instalar php8.3-sqlite3 en el host.