Principios del Plan
Reglas que rigen cada decisión de migración
01
Testing primero, siempre
Ningún cambio llega a producción sin validación completa en el entorno de testing.
02
Rollback en < 5 min
Cada despliegue tiene un punto de retorno claro: tag git o cambio de IP en VPN.
03
Deploys nocturnos
Se definen ventanas de bajo tráfico para cada despliegue a producción.
04
Una dependencia a la vez
No se migran dos librerías simultáneamente para aislar y diagnosticar problemas.
05
Funcionalidad primero
El sistema debe funcionar igual o mejor tras cada fase. El refactor visual viene después.
Tabla de Reemplazos Recomendados
Librerías obsoletas y sus sustitutos modernos
Librería actualEstadoReemplazo recomendadoRazón
CentOS 7 EOL jun 2024 Rocky Linux 9 Sucesor natural, compatible con RHEL 9, soporte hasta 2032
PHPExcel 1.8.0 Abandonado PhpSpreadsheet 2.x Sucesor oficial del mismo autor, API muy similar
Bootstrap DatetimePicker Abandonado Flatpickr 4.x Sin dependencias, 16KB, activo, fácil integración
Morris.js + Raphael.js Abandonado 2014 Chart.js 4.x Estándar de la industria, sin dependencias, documentación excelente
SweetAlert 1.x Abandonado SweetAlert2 11.x Sucesor directo, API base compatible, activo
Moment.js 2.9.0 Mantenimiento Day.js 1.x API casi idéntica, 2 KB, activo y recomendado por Moment
AngularJS 1.5.9 + UI-Bootstrap EOL dic 2021 Alpine.js 3.x Sin build step, convive con jQuery, directivas similares a AngularJS
Bootstrap 3.4.1 + Material Design fork Sin soporte Bootstrap 5.3.x Estándar actual, sin jQuery, activo
Font Awesome 4.5.0 Sin actualizaciones Font Awesome 6 Free Mismo sistema de iconos, ~1400 iconos nuevos, shim de compatibilidad
FullCalendar 2.5.0 API obsoleta FullCalendar 6.x Misma librería, API moderna, sin Moment ni jQuery
Socket.IO 1.4.5 Sin uso (huérfano) Eliminar No hay referencias en ningún archivo del proyecto
CodeIgniter 3.0.3 EOL CodeIgniter 4.x (Fase 7) Reescritura completa; se aborda al final para no bloquear fases anteriores

¿Por qué Alpine.js y no Vue.js o React?

Análisis técnico comparativo considerando el stack actual del proyecto (PHP · CodeIgniter · jQuery · Apache)

CriterioAlpine.js 3.x ✓Vue.js 3React 18
Build step requerido No — solo un <script> Sí (Vite + npm) Sí (Vite/Webpack + npm)
Tamaño (min + gzip) 15 KB 33 KB 45 KB
Integración con PHP/Apache Directa — idéntica a jQuery Requiere configuración Requiere configuración
Convive con jQuery Sí, sin conflicto Parcialmente Conflictos frecuentes
Directivas declarativas en HTML Sí (como AngularJS) No (requiere JSX)
Curva de aprendizaje Muy baja (1–2 días) Media (2–4 semanas) Alta (1–2 meses)
Migración módulo a módulo Sí — coexiste con AngularJS Complejo Requiere reescritura total
Adopción en ecosistema PHP Enorme (Laravel, Livewire) Media Baja

Razones técnicas en detalle

1. Sin sistema de build
Vue.js 3 y React requieren instalar Node.js, npm y una herramienta de compilación (Vite o Webpack) que transforma el código antes de que el navegador pueda leerlo. Esto agrega una capa de infraestructura completamente nueva al proyecto. Alpine.js se incluye igual que jQuery: un solo <script> en el HTML y listo.
2. Migración sin big-bang
Alpine.js y AngularJS pueden convivir en la misma página sin conflicto. Esto permite migrar módulo por módulo: se agrega Alpine.js al layout global, se reescribe un módulo, se valida en testing, y se hace deploy. El resto del sistema sigue funcionando con AngularJS sin tocar. Vue y React no pueden coexistir así con código AngularJS existente.
3. Sintaxis familiar para el equipo
Alpine.js usa directivas declarativas en el HTML, el mismo patrón mental que AngularJS. El comportamiento se define en el marcado HTML con atributos (x-model, @click, x-show), no en archivos de componentes separados. El equipo actual que conoce AngularJS adoptará Alpine.js en días, no en semanas.
4. Estado simple sin complejidad adicional
Vue.js típicamente necesita Pinia o Vuex para estado compartido. React necesita Redux o Zustand. Alpine.js maneja el estado con objetos JavaScript simples definidos localmente en el HTML. Para un sistema de gestión empresarial con formularios y tablas, esto es exactamente lo que se necesita, sin sobre-ingeniería.

¿Quién usa Alpine.js en el mundo real?

Alpine.js es el estándar de facto para interactividad JavaScript en el ecosistema PHP/Laravel. No es una herramienta experimental.

Laravel Livewire
El framework de componentes PHP más popular del mundo usa Alpine.js como su capa JavaScript oficial. Millones de aplicaciones PHP en producción globalmente.
Filament PHP
El panel de administración más usado en Laravel (más de 200,000 desarrolladores activos). Toda su interfaz interactiva está construida sobre Alpine.js.
Tailwind UI
La librería de componentes oficial de los creadores de Tailwind CSS. Todos sus ejemplos interactivos (menús, modales, dropdowns) están escritos con Alpine.js.
Statamic CMS
CMS profesional basado en PHP/Laravel, usado por miles de empresas. Todo su panel de administración usa Alpine.js como única capa de JavaScript reactivo.
Sentry (parcial)
La plataforma de monitoreo de errores más usada del mundo ha adoptado Alpine.js en secciones de su panel donde necesitan interactividad ligera sin overhead.
Más de 300,000 repos
Alpine.js tiene más de 28,000 estrellas en GitHub y aparece en más de 300,000 repositorios públicos. Es una tecnología madura y activamente mantenida.

Conclusión: Alpine.js no es una apuesta experimental. Es la herramienta que el ecosistema PHP ha adoptado masivamente para exactamente este caso de uso: modernizar interactividad en aplicaciones server-side sin reescribir ni agregar complejidad de build. Para Mas Me Dan, reduce el riesgo de migración, acelera los tiempos, y mantiene el stack familiar para el equipo.

Cronograma General
Estimado por fase · Dedicación completa al 100%
FASE 0
Preparación
1 – 2 semanas
FASE 1A
CentOS → Rocky Linux 9
2 – 3 semanas
FASE 1B
PHP 8.2 — código
2 – 3 semanas
FASE 2
Deps PHP críticas
2 – 3 semanas
FASE 3
JS Utilities
2 semanas
FASE 4
Bootstrap 5 + Font Awesome 6 — una vista a la vez
8 – 10 semanas
FASE 5
Fechas, Calendar, Charts
3 – 4 semanas
FASE 6
AngularJS → Alpine.js (módulo a módulo)
6 – 8 semanas
FASE 7
CodeIgniter 4 — opcional / largo plazo
4 – 6 meses
~3.5 meses
Total estimado · Fases 0 a 6 · Dedicación completa al 100%
Nota: Las Fases 1A y 1B son secuenciales — el servidor nuevo debe estar operativo antes de corregir compatibilidad PHP en el código. Las Fases 2 y 3 pueden correr en paralelo una vez completada la 1B. La Fase 4 es la más larga por el volumen de vistas HTML a revisar.
Fase 0

Preparación y Baseline

Establecer el entorno de trabajo seguro antes de modificar cualquier dependencia
Duración 1 – 2 semanas
Prioridad Punto de entrada

0.1 — Entorno de Testing

  • Confirmar que testing tiene la misma versión de PHP, MySQL y configuración de Apache que producción.
  • Configurar sincronización documentada de BD (dump de producción → testing) con datos anónimos si es posible.
  • Bloquear testing por IP o autenticación básica HTTP para que ninguna sucursal lo vea.

0.2 — Git y Proceso de Deploys

  • Verificar que el repositorio Git tiene una rama master limpia y al día.
  • Crear ramas de trabajo por fase: migration/fase-1a-servidor, migration/fase-1b-php8, etc.
  • Documentar proceso de deploy a producción (script / rsync / FTP).
  • Política de backups antes de cada deploy: dump SQL + zip de application/ y res/ con timestamp.

0.3 — Limpieza de Archivos Huérfanos

  • Eliminar res/js/socket.io-1.4.5.js — no está referenciado en ningún archivo del proyecto.
  • Eliminar res/js/jquery-1.10.2.min.js y jquery-2.1.4.min.js — versiones obsoletas sin uso activo.
  • Eliminar res/js/ui-bootstrap-tpls-2.1.2.min.js — versión intermedia sin uso activo.
  • Documentar qué módulos usan ui-bootstrap-tpls-0.12.1 vs 2.5.0.

0.4 — Inventario de Módulos con AngularJS

  • Listar todas las vistas que usan directivas AngularJS (ng-*) para conocer el alcance de la Fase 6.
Fase 1A

Servidor: CentOS 7 → Rocky Linux 9

Migración del sistema operativo del servidor de producción
Duración 2 – 3 semanas
Prioridad 🔴 CRÍTICA — base de todo
CentOS 7 EOL 30 junio 2024

¿Por qué Rocky Linux 9?

  • Sucesor natural de CentOS, binariamente compatible con RHEL 9.
  • Mismos comandos (dnf/yum), misma estructura de directorios — curva de aprendizaje mínima.
  • Soporte garantizado hasta mayo de 2032.
  • PHP 8.2/8.3, MariaDB 10.11, Apache 2.4 disponibles desde repositorios oficiales.

Argumento de seguridad para el comité

"La VPN protege el canal de comunicación, no el servidor. Si un dispositivo infectado se conecta a la red — un equipo de sucursal, un portátil de empleado — el atacante ya está adentro. En ese escenario, CentOS 7 sin parches de seguridad + PHP 5.6 es una superficie de ataque completamente expuesta. La VPN es la puerta blindada; CentOS 7 es la casa de cartón detrás de ella."

Estrategia: Servidor Paralelo (Blue-Green Deployment)

No se migra el servidor existente en caliente. Se levanta un servidor nuevo con Rocky Linux 9 en paralelo, se prueba completamente, y el cutover es un simple cambio de IP en la VPN.

[CentOS 7 — producción actual] ← sucursales apuntan aquí
[Rocky Linux 9 — nuevo] ← preparación y pruebas
 
CUTOVER: cambiar IP en VPN → sucursales apuntan a Rocky Linux 9
[CentOS 7] → standby 72h por si hay rollback → luego se apaga

Tiempo de downtime real: 15–30 minutos (solo el cambio de IP en la VPN). Rollback disponible en menos de 5 minutos.

Paso A — Inventario de configuración de CentOS 7

  • Documentar versiones: php -v, httpd -v, mysql --version.
  • Exportar extensiones PHP activas: php -m > extensiones_php.txt.
  • Exportar configuración de Apache: /etc/httpd/conf/httpd.conf y todos los vhosts en conf.d/.
  • Listar crontabs: crontab -l y /etc/cron.d/.
  • Documentar reglas de firewall: firewall-cmd --list-all.
  • Exportar BD completa: mysqldump --all-databases > backup_completo.sql.
  • Guardar todo en el repo bajo infra/centos7-config/.

Paso B — Instalación de Rocky Linux 9

# Apache
dnf install httpd -y
systemctl enable --now httpd

# PHP 8.2 via repositorio Remi
dnf install https://rpms.remirepo.net/enterprise/remi-release-9.rpm -y
dnf module reset php && dnf module enable php:remi-8.2
dnf install php php-mysqlnd php-mbstring php-gd php-curl php-zip php-xml php-intl php-json php-opcache php-fpm -y

# MariaDB 10.11
dnf install mariadb-server -y
systemctl enable --now mariadb && mysql_secure_installation

# Restaurar base de datos
mysql -u root -p < backup_completo.sql
  • Copiar el código del proyecto al nuevo servidor (mismo path que en CentOS 7).
  • Replicar vhosts, crontabs y variables de entorno desde el inventario del Paso A.
  • Ajustar permisos (chown, chmod) y configurar SELinux si está activo.

Paso C — Pruebas en Rocky Linux 9

  • Acceder al nuevo servidor por IP directa desde el equipo de desarrollo.
  • QA funcional completo: todos los módulos, PDFs, Excel, consultas a BD.
  • Verificar logs: tail -f /var/log/httpd/error_log.
  • Probar acceso desde al menos 2 sucursales piloto apuntando temporalmente al nuevo servidor.

Paso D — Cutover a Producción

  • Programar ventana nocturna (15–30 min). Comunicar a supervisores con 48h de anticipación.
  • Hacer dump final de la BD de CentOS 7 justo antes del cutover (datos del mismo día).
  • Importar dump final en Rocky Linux 9.
  • Cambiar IP en la configuración VPN → sucursales apuntan al servidor nuevo.
  • Verificar acceso desde 3–5 sucursales piloto distribuidas.
  • Mantener CentOS 7 en standby 72 horas — no apagar hasta confirmar estabilidad total.
  • Monitorear logs durante 48 horas post-cutover. Apagar CentOS 7 al confirmar estabilidad.
Criterio de éxito: El sistema funciona en Rocky Linux 9 con PHP 8.2 durante 5 días hábiles consecutivos sin incidentes. CentOS 7 apagado definitivamente.
Fase 1B

Correcciones de Compatibilidad PHP 8.2

Adaptar el código de la aplicación para que funcione sin errores en PHP 8.2
Duración2 – 3 semanas
RequiereFase 1A completada

Errores comunes PHP 5.6 → PHP 8.2

Función / PatrónEn PHP 5.6En PHP 8.2Solución
ereg(), ereg_replace()FuncionabaEliminadaReemplazar con preg_match(), preg_replace()
split()FuncionabaEliminadaUsar explode() o preg_split()
each()FuncionabaEliminadaReemplazar con foreach
create_function()FuncionabaEliminadaUsar closures anónimas function() {}
mysql_* functionsDeprecadaEliminadaCI3 ya usa mysqli — verificar código legado
strpos() con nullSilenciosoWarningVerificar valores antes de llamar a la función

Parches específicos de CodeIgniter 3 para PHP 8

  • system/core/Security.php — ajuste en csrf_verify() por cambio en manejo de null.
  • system/database/drivers/mysqli/mysqli_driver.php — ajuste en inicialización de conexión.
  • system/core/Input.php — ajuste en _fetch_from_array() por tipos estrictos.
  • system/core/Utf8.php — ajuste en detección de encoding.

Proceso de corrección

  • Activar reporte completo en testing: error_reporting(E_ALL) en index.php.
  • Navegar todos los módulos y registrar cada error/warning en el log de PHP.
  • Corregir errores fatales primero → deprecaciones → warnings.
  • Commits atómicos por archivo corregido en migration/fase-1b-php8.
  • QA funcional completo tras cada lote de correcciones.
  • Desactivar reporte de errores ampliado antes del deploy a producción.
Criterio de éxito: La aplicación corre sin errores ni warnings en PHP 8.2. Los logs de PHP en producción están limpios durante 5 días hábiles.
Fase 2

Dependencias PHP Críticas

Actualizar librerías PHP incompatibles con PHP 8
Duración2 – 3 semanas
RequiereFases 1A y 1B completadas

2.1 — PHPExcel → PhpSpreadsheet 2.x

PHPExcel no funciona con PHP 8. PhpSpreadsheet es su sucesor oficial del mismo autor.

PHPExcel (actual)PhpSpreadsheet (nuevo)
new PHPExcel()new \PhpOffice\PhpSpreadsheet\Spreadsheet()
PHPExcel_IOFactory::load($file)\PhpOffice\PhpSpreadsheet\IOFactory::load($file)
PHPExcel_IOFactory::createWriter($obj, 'Excel2007')IOFactory::createWriter($obj, 'Xlsx')
$sheet->setCellValue('A1', $val)Idéntico — sin cambio
  • Identificar todos los archivos PHP que instancian PHPExcel o usan PHPExcel_IOFactory.
  • Instalar PhpSpreadsheet via Composer o manualmente.
  • Probar cada reporte Excel en testing. Deploy a producción.

2.2 — AWS SDK 3.340+

  • Actualizar application/libraries/aws/ a la versión 3.340+ (requiere PHP 8.1+, ya cumplido).
  • Verificar que application/libraries/Aws.php (wrapper interno) sigue siendo compatible.
  • Probar todas las operaciones S3/AWS del sistema.

2.3 — TCPDF 6.7.x

  • Actualizar application/libraries/tcpdf/ a la versión 6.7.x.
  • Probar generación de todos los PDFs existentes (contratos, recibos, etc.) en testing.
Criterio de éxito: Todos los reportes Excel y PDFs se generan correctamente en producción con las nuevas librerías.
Fase 3

Actualizaciones JS Menores

Actualizaciones de bajo riesgo sin cambios de interfaz visual
Duración2 semanas
Puede correrEn paralelo con Fase 2

jQuery 3.4.1 → 3.7.x · SweetAlert → SweetAlert2 · Select2 → 4.1.x

  • jQuery: Reemplazar jquery-3.4.1.min.js con 3.7.x. API compatible, incluye fixes de seguridad.
  • SweetAlert2: Reemplazar archivos. Agregar shim temporal: window.swal = (t,m,i) => Swal.fire({title:t, text:m, icon:i}) para mantener llamadas existentes sin romper nada.
  • Select2 4.1.x: Reemplazar archivos. API compatible hacia atrás.
  • Underscore.js 1.13.x: Reemplazar archivo. API compatible hacia atrás.
Criterio de éxito: Ningún error en consola del navegador en los flujos principales del sistema.
Fase 4

Bootstrap 5 + Font Awesome 6

La fase de mayor impacto visual — se hace módulo por módulo
Duración8 – 10 semanas
EstrategiaMódulo a módulo, menor → mayor tráfico

Cambios principales Bootstrap 3 → Bootstrap 5

Bootstrap 3Bootstrap 5Nota
col-xs-*col-*Breakpoint xs eliminado
hidden-xs, visible-mdd-none d-md-blockNuevo sistema de visibilidad
panel, panel-bodycard, card-bodyComponente renombrado
btn-defaultbtn-secondary
pull-left / pull-rightfloat-start / float-end
data-toggle, data-dismiss, data-targetdata-bs-toggle, data-bs-dismiss, data-bs-targetTodos los atributos data- cambian
GlyphiconsEliminados → Font Awesome 6

Orden de migración de módulos (menor → mayor riesgo)

1
Login / Inicio — alta visibilidad, pocas vistas
2
Configuración / Administración
3
Reportes
4
Registro (clientes, prendas)
5
Inventario
6
Movimientos / Caja Menuda
7
Ventas
8
Prorrogas / Adendas
9
Negociación (empeños) — último, el más crítico del negocio

Font Awesome 6 — estrategia con shim

Se despliega FA6 con el shim de compatibilidad que convierte automáticamente clases fa fa-* al nuevo formato. Esto permite desplegar FA6 sin cambiar ningún ícono de inmediato.

<!-- FA6 con shim para clases de FA4 -->
<link rel="stylesheet" href="res/css/font-awesome-6/css/all.min.css">
<link rel="stylesheet" href="res/css/font-awesome-6/css/v4-shims.min.css">
Criterio de éxito: Todos los módulos renderizan correctamente en Bootstrap 5 sin regresiones visuales en producción.
Fase 5

Fechas, Calendario y Gráficos

Reemplazar componentes de manejo de fechas, calendario y visualización de datos
Duración3 – 4 semanas
RequiereFase 4 completada

Bootstrap DatetimePicker → Flatpickr 4.x

Flatpickr no depende de Bootstrap ni de Moment.js — funciona de forma completamente independiente.

// Antes (Bootstrap DatetimePicker)
$('#fecha').datetimepicker({ format: 'DD/MM/YYYY', locale: 'es' });

// Después (Flatpickr)
flatpickr('#fecha', { dateFormat: 'd/m/Y', locale: 'es' });

Moment.js → Day.js — API casi idéntica

// Antes (Moment.js)
moment().format('DD/MM/YYYY')
moment('2026-01-15').add(30, 'days').format('DD/MM/YYYY')

// Después (Day.js) — mismo código, diferente nombre
dayjs().format('DD/MM/YYYY')
dayjs('2026-01-15').add(30, 'days').format('DD/MM/YYYY')

Morris.js + Raphael.js → Chart.js 4.x

// Antes (Morris.js)
Morris.Bar({ element: 'chart', data: [...], xkey: 'mes', ykeys: ['valor'] });

// Después (Chart.js 4)
new Chart(document.getElementById('chart'), {
  type: 'bar',
  data: { labels: data.map(d => d.mes), datasets: [{ data: data.map(d => d.valor) }] }
});
Criterio de éxito: Todos los selectores de fecha, el calendario y los gráficos funcionan en producción. Moment.js, Morris.js y Raphael.js eliminados del proyecto.
Fase 6

AngularJS → Alpine.js

La fase más compleja — sustitución gradual módulo por módulo
Duración6 – 8 semanas
EstrategiaStrangler Fig — módulo a módulo

Equivalencias de directivas clave

AngularJS (actual)Alpine.js (nuevo)
ng-app="miApp"x-data="miComponente()"
ng-model="variable"x-model="variable"
ng-click="funcion()"@click="funcion()"
ng-show="cond"x-show="cond"
ng-if="cond"x-if="cond"
ng-repeat="item in lista"template x-for="item in lista"
ng-class="{'clase': cond}":class="{'clase': cond}"
{{ variable }}<span x-text="variable">
$http.get(url)fetch(url).then(r => r.json())

Orden de migración de módulos (menor → mayor complejidad AngularJS)

1
Módulos con solo ng-show/ng-hide simples
2
Módulos con formularios y ng-model
3
Módulos con listados y ng-repeat
4
Módulos con llamadas AJAX ($http)
5
Negociación (empeños) — último, el más crítico
Criterio de éxito: AngularJS eliminado completamente del proyecto. Todos los módulos funcionan con Alpine.js.
Fase 7

CodeIgniter 3 → CodeIgniter 4

Opcional — largo plazo — requiere fases 0–6 completadas
Duración4 – 6 meses
TipoOpcional / Largo plazo

CI4 es una reescritura completa (namespaces PHP, PSR-4, sin compatibilidad directa con CI3). Se aborda al final porque las fases anteriores tienen mayor impacto inmediato en seguridad.

Estrategia recomendada: Strangler Fig a nivel de framework. Instalar CI4 como proyecto separado, migrar un módulo a la vez, y usar un proxy en Apache para enrutar las rutas del módulo migrado a CI4 mientras el resto sigue en CI3. Al final, CI3 queda sin rutas activas y se elimina.

Checklist de Deploys a Producción
Usar antes de cada deploy en cualquier fase
Para cambios de código — Fases 1B a 6
  • Backup de BD completo en S3/local.
  • Backup de archivos application/ y res/ con timestamp.
  • Comunicado a supervisores de sucursales si la ventana afecta el horario de apertura.
  • Deploy en ventana nocturna.
  • Monitorear logs las primeras 2 horas post-deploy.
  • QA express: login, crear empeño, PDF, Excel, acceso desde 2 sucursales piloto.
  • Plan de rollback: revertir commit → deploy versión anterior.
Para el cutover de servidor — Fase 1A (único evento)
  • Rocky Linux 9 probado al menos 3 días en testing.
  • Dump final de BD de CentOS 7 importado en Rocky Linux 9 (datos del día).
  • Ventana nocturna comunicada con 48h de anticipación.
  • Cambiar IP en configuración VPN.
  • Verificar acceso desde 3–5 sucursales piloto distribuidas.
  • CentOS 7 en standby 72 horas antes de apagar.
  • Rollback: revertir IP en VPN → sucursales vuelven a CentOS 7 en < 5 min.
Resumen Visual — Flujo de Migración
De dónde viene y a dónde va cada dependencia
Infraestructura del Servidor
FASE 1A
CentOS 7 (EOL jun 2024) + PHP 5.6 instalado
Rocky Linux 9 (soporte 2032) + PHP 8.2 instalado
Código de la Aplicación — Backend
FASE 1B
Código con funciones PHP 5.6 obsoletas
Código compatible con PHP 8.2
FASE 2
PHPExcel · AWS SDK 3.198 · TCPDF 6.2.13
PhpSpreadsheet 2.x · AWS SDK 3.340+ · TCPDF 6.7.x
Frontend — Utilidades
FASE 3
jQuery 3.4.1 · SweetAlert 1.x · Select2 4.0.8
jQuery 3.7.x · SweetAlert2 11.x · Select2 4.1.x
Frontend — UI y Estilos
FASE 4
Bootstrap 3.4.1 + Material Design fork + Font Awesome 4
Bootstrap 5.3 + CSS custom + Font Awesome 6
Frontend — Componentes de Datos
FASE 5
BS DatetimePicker · Moment.js · FullCalendar 2 · Morris + Raphael
Flatpickr · Day.js · FullCalendar 6 · Chart.js 4
Frontend — Framework JS
FASE 6
AngularJS 1.5.9 (EOL 2021) + UI-Bootstrap (abandonado)
Alpine.js 3.x + Bootstrap 5 nativo
Framework PHP — Largo Plazo
FASE 7
CodeIgniter 3.0.3 (EOL)
CodeIgniter 4.x (opcional, después de estabilizar fases 0–6)

Punto de entrada recomendado: Fase 0 (preparación) → Fase 1A (servidor).
Sin un servidor moderno con PHP 8.2, ninguna otra fase puede avanzar de forma sostenida.
La Fase 1A y 1B son el desbloqueante de todo el plan.