# SLM Framework

Un framework moderno para aplicaciones web que utiliza Elasticsearch como almacén de datos principal. SLM Framework proporciona dos opciones de backend que pueden usarse de forma independiente o en conjunto:

- **🐘 Backend PHP** (`appweb/`): Aplicación web completa con sistema de módulos, autenticación, y templating `.slm`
- **🟢 Backend Node.js** (`api/`): API REST con Express.js, routing dinámico, y hot-reload automático

Puedes usar solo PHP, solo Node.js, o ambos en conjunto según las necesidades de tu proyecto.

## Características

### Backend PHP (`appweb/`)

- **Basado en Elasticsearch**: Utiliza Elasticsearch para todo el almacenamiento de datos (no requiere base de datos SQL)
- **Gestión de Sesiones**: Manejo de sesiones integrado con persistencia en Elasticsearch
- **Control de Acceso Avanzado**:
  - Sistema ACL (Lista de Control de Acceso) basado en perfiles
  - Permisos específicos de usuario (sobrescriben permisos del perfil)
  - Control de permisos granular (leer, crear, actualizar, eliminar)
- **Autenticación de Dos Factores**: Verificación con token de seguridad por email
- **Módulos de Configuración**: Gestión centralizada vía módulos `config.*`
  - `config.users`: Gestión de usuarios con permisos personalizados
  - `config.profile`: Gestión de perfiles y ACL
  - `config.modules`: Registro y configuración de módulos
- **Arquitectura Modular**: Estructura de módulos organizada con clara separación de responsabilidades
- **Integración con DataTables**: Procesamiento del lado del servidor para manejo eficiente de datos
- **Frontend Moderno**: Bootstrap 5, Select2, SweetAlert2 y Feather Icons

### Backend Node.js (`api/`)

- **Express.js + Node.js**: API REST moderna y performante
- **Routing Dinámico**: Sistema de carga de endpoints mediante JSON con path-to-regexp
- **Hot-Reload Automático**: Detecta cambios en endpoints y handlers sin reiniciar
- **Versionamiento de API**: Soporte para múltiples versiones (v1, v2, etc.)
- **Autenticación por API Key**: Middleware de seguridad integrado
- **Logging Estructurado**: Sistema de logs con archivos separados (JSON)
- **Constants & Utils**: Códigos HTTP y funciones auxiliares centralizadas
- **Moment.js**: Manejo avanzado de fechas y zonas horarias
- **CORS Configurable**: Cross-Origin Resource Sharing
- **Rate Limiting**: Control de peticiones (preparado para implementar)

## Requisitos

### Para Backend PHP (appweb/)
- PHP 8.3+
- Composer
- Elasticsearch 7.9+

### Para Backend Node.js (api/)
- Node.js 18+
- npm
- Elasticsearch 7.9+

### Desarrollo (recomendado)
- Docker & Docker Compose
- Git

## Inicio Rápido

### 1. Clonar el Repositorio

```bash
git clone <url-repositorio> slm-framework-skeleton
cd slm-framework-skeleton
```

### 2. Configurar Entorno

**Para Backend PHP:**
```bash
cp .env.example appweb/.env
```

Editar `appweb/.env` con tu configuración:

```env
APP_NAME="Mi Aplicación"
APP_DEBUG=true
ES_SERVER=http://elasticsearch:9200
DEV_ES_INDEX=mi-app-dev
```

**Para Backend Node.js:**

El archivo `api/.env` ya está configurado con valores por defecto. Ajustar si es necesario:

```env
NODE_ENV=development
API_PORT=3000
ES_SERVER=http://elasticsearch:9200
DEV_ES_INDEX=slm-app-dev
```

### 3. Instalar Dependencias

**Backend PHP:**
```bash
cd appweb/slm.framework/system
composer install
```

**Backend Node.js:**
```bash
cd api
npm install
```

### 4. Iniciar con Docker

**Opción A: Iniciar todo (PHP + Node.js + Elasticsearch + Kibana + MailHog):**
```bash
docker-compose up --build -d
```

**Opción B: Solo servicios específicos:**
```bash
# Solo PHP + Elasticsearch
docker-compose up app elasticsearch -d

# Solo Node.js API + Elasticsearch
docker-compose up api elasticsearch -d

# Personalizado
docker compose --project-name <appname> up --build -d
```

### 5. Inicializar Elasticsearch

Crear los índices requeridos (ver `docs/es_MX/07-elasticsearch.md` para detalles):

```bash
# Crear índice principal
curl -X PUT "http://localhost:9200/slm-app-dev" -H "Content-Type: application/json" -d @docs/es-mapping.json

# Crear índice de logs
curl -X PUT "http://localhost:9200/slm-app-dev-log" -H "Content-Type: application/json" -d @docs/es-mapping-log.json
```

### 6. Acceder a la Aplicación

**Servicios Principales:**
- **Aplicación PHP**: http://localhost (puerto 80)
- **API Node.js**: http://localhost:3000 (puerto 3000)

**Servicios de Infraestructura:**
- **Elasticsearch**: http://localhost:9200
- **Kibana**: http://localhost:5601 (visualización de ES)
- **MailHog**: http://localhost:8025 (pruebas de email)

### 7. Verificar que todo funciona

**Probar Backend PHP:**
```bash
curl http://localhost
```

**Probar Backend Node.js:**
```bash
# Sin autenticación
curl http://localhost:3000/health

# Con autenticación
curl -H "X-API-Key: dev-key-12345" \
  http://localhost:3000/v1/status
```

## Sistema API REST (Node.js)

El framework incluye un sistema completo de API REST construido con Node.js y Express.js, con routing dinámico, hot-reload automático y middlewares de seguridad.

### ¿Cuándo usar cada backend?

| Caso de Uso | Backend Recomendado |
|-------------|---------------------|
| Aplicación web tradicional con vistas | **PHP** (`appweb/`) |
| API REST para aplicaciones móviles/SPA | **Node.js** (`api/`) |
| Panel administrativo completo | **PHP** (`appweb/`) |
| Microservicios y webhooks | **Node.js** (`api/`) |
| Sistema híbrido (web + API) | **Ambos** |

### Endpoints Disponibles (Node.js API)

```bash
# Health check (público)
curl http://localhost:3000/health

# Status de la API (requiere API Key)
curl -H "X-API-Key: dev-key-12345" \
  http://localhost:3000/v1/status

# Login
curl -X POST \
  -H "X-API-Key: dev-key-12345" \
  -H "Content-Type: application/json" \
  -d '{"email":"admin@example.com","password":"admin123"}' \
  http://localhost:3000/v1/auth/login

# Listar usuarios (con paginación)
curl -H "X-API-Key: dev-key-12345" \
  "http://localhost:3000/v1/users?page=1&limit=10&search=john"

# Obtener usuario específico
curl -H "X-API-Key: dev-key-12345" \
  http://localhost:3000/v1/users/user-id-123
```

### Características API (Node.js)

- ✅ **Routing Dinámico**: Sistema de carga de endpoints mediante JSON con path-to-regexp
- ✅ **Hot-Reload Automático**: Detecta cambios en `endpoints.slm` sin reiniciar servidor
- ✅ **Versionamiento**: Soporte para múltiples versiones (v1, v2, etc.)
- ✅ **Autenticación**: API Key validation con middleware
- ✅ **Logging Estructurado**: Sistema de logs con archivos JSON separados
- ✅ **Constants & Utils**: Códigos HTTP y funciones auxiliares centralizadas
- ✅ **CORS**: Cross-Origin Resource Sharing configurable
- ✅ **Moment.js**: Manejo avanzado de fechas y zonas horarias
- ✅ **Rate Limiting**: Control de peticiones (preparado para implementar)
- ✅ **Caché inteligente**: Por entorno (desarrollo vs producción)

### Agregar Nuevos Endpoints

El sistema de hot-reload detecta cambios automáticamente:

**1. Editar `api/slm.framework/system/endpoints.slm`:**
```json
{
  "GET /v1/products/:id": {
    "handler": "./slm.framework/modules/v1/products/get.slm"
  }
}
```

**2. Crear el handler `api/slm.framework/modules/v1/products/get.slm`:**
```javascript
const constants = require('../../system/constants.slm');
const utils = require('../../system/utils.slm');

module.exports = async (req, res, next, slmapi) => {
    const { id } = req.params;
    // Tu lógica aquí...
};
```

**3. ¡Listo!** El endpoint está disponible inmediatamente (sin reiniciar).

📚 **Ver documentación completa:** [api/README.md](api/README.md)

## Configuración Inicial: Perfil SLM Super

> **IMPORTANTE:** El primer paso para configurar tu aplicación es crear el perfil **SLM Super** y el usuario administrador.

### ¿Qué es SLM Super?

**SLM Super** es el perfil administrativo que proporciona acceso completo a los módulos de configuración:

- ✅ **config.users**: Registrar y gestionar usuarios (incluyendo permisos personalizados)
- ✅ **config.profile**: Crear y gestionar perfiles de usuario con ACL
- ✅ **config.modules**: Registrar nuevos módulos y configurar la estructura del menú

### Script de Configuración Rápida

Usa el script proporcionado para crear el perfil SLM Super y el usuario administrador:

```bash
# Ejecutar el script de configuración
php scripts/setup-slm-super.php
```

Este script:
1. Crea el perfil SLM Super con acceso completo a configuración
2. Registra módulos de configuración core (users, profile, modules)
3. Crea la estructura de menú
4. Crea un usuario administrador con perfil SLM Super

### Configuración Manual

Alternativamente, sigue la guía completa de configuración:

```bash
# Ver instrucciones detalladas
docs/es_MX/03-profile-user-module-menu.md
```

### Primer Inicio de Sesión

Después de la configuración, accede a los módulos de configuración:

1. Iniciar sesión con tus credenciales de administrador
2. Navega a **Configuración → Usuarios** para gestionar usuarios
3. Navega a **Configuración → Perfiles** para crear nuevos perfiles
4. Navega a **Configuración → Módulos** para registrar nuevos módulos

## Estructura del Proyecto

```
slm-framework-skeleton/
├── README.md                           # Este archivo
├── ARCHITECTURE.md                     # Documentación de arquitectura
├── .env.example                        # Plantilla de entorno (PHP)
├── .gitignore                          # Reglas de Git ignore
├── docker-compose.yml                  # Servicios Docker (PHP + Node.js + ES)
├── Dockerfile                          # Contenedor PHP/Apache
│
├── api/                                # 🟢 Backend Node.js + Express.js
│   ├── server.js                       # Servidor principal
│   ├── package.json                    # Dependencias Node.js
│   ├── .env                            # Variables de entorno (Node.js)
│   ├── .env.example                    # Plantilla .env
│   ├── .gitignore                      # Exclusiones Git (API)
│   ├── README.md                       # Documentación completa API
│   ├── logs/                           # Logs estructurados (auto-creado)
│   ├── error/                          # Logs de errores (auto-creado)
│   └── slm.framework/
│       ├── system/                     # Sistema core API
│       │   ├── slmapi.slm              # Configuración centralizada
│       │   ├── endpoints.slm           # Registro de rutas (JSON)
│       │   ├── logger.slm              # Sistema de logging
│       │   ├── constants.slm           # Códigos HTTP y errores
│       │   └── utils.slm               # Funciones auxiliares
│       └── modules/                    # Módulos API versionados
│           └── v1/                     # API versión 1
│               ├── status.slm          # GET /v1/status
│               ├── auth/               # Autenticación
│               │   └── login.slm       # POST /v1/auth/login
│               ├── users/              # Usuarios
│               │   ├── list.slm        # GET /v1/users
│               │   └── get.slm         # GET /v1/users/:id
│               └── example/            # Ejemplos
│                   └── test.slm        # GET /v1/example/test
│
├── appweb/                             # 🐘 Backend PHP + Apache
│   ├── .env                            # Configuración de entorno (PHP)
│   ├── public/
│   │   └── index.slm                   # Punto de entrada
│   ├── assets/
│   │   ├── css/app.css                 # Estilos personalizados
│   │   ├── js/app.js                   # JavaScript personalizado
│   │   └── images/                     # Imágenes estáticas
│   ├── store/                          # Subida de archivos
│   └── slm.framework/
│       ├── system/                     # Core del framework
│       │   ├── _SLM.slm                # Gestión de sesiones
│       │   ├── config.slm              # Configuración
│       │   ├── helpers.slm             # Funciones auxiliares
│       │   ├── slm_api.slm             # API core
│       │   ├── slm_es_control.slm      # Operaciones Elasticsearch
│       │   ├── email.slm               # Manejo de email
│       │   ├── composer.json           # Dependencias PHP
│       │   └── lib/                    # Librerías
│       ├── security/
│       │   └── login.slm               # Autenticación
│       └── modules/
│           ├── _header.slm             # Cabecera de página
│           ├── _footer.slm             # Pie de página
│           ├── _menu.slm               # Navegación
│           ├── home/                   # Módulo dashboard
│           └── example/                # Ejemplo CRUD
│
├── scripts/                            # Scripts de configuración
│   ├── README.md                       # Documentación scripts
│   └── setup-slm-super.php             # Setup perfil SLM Super
│
└── docs/                               # Documentación completa
    ├── README.md                       # Índice de documentación
    └── es_MX/                          # Documentación en español
        ├── 01-getting-started.md
        ├── 02-slm-super-quick-start.md
        ├── 03-profile-user-module-menu.md
        ├── 04-modules.md
        ├── 05-modules-complete-guide.md
        ├── 06-user-specific-permissions.md
        ├── 07-elasticsearch.md
        ├── 08-security.md
        ├── 09-api-reference.md
        ├── 10-ARCHITECTURE.md
        └── 11-STANDARDS.md
```

## Estructura de Módulos

Cada módulo sigue este patrón:

```
modules/
└── mimodulo/
    ├── proc.action.slm    # Pre-procesamiento (opcional)
    ├── load.action.slm    # Carga de datos (opcional)
    ├── view.action.slm    # Vista HTML (requerido)
    ├── ajax.action.slm    # Manejadores AJAX (requerido para CRUD)
    ├── end.action.slm     # JavaScript (opcional)
    └── slm_api.slm        # Funciones específicas del módulo (opcional)
```

## Flujo de Peticiones

```
Petición HTTP → index.slm
      │
      ▼
  Config & Helpers
      │
      ▼
  Cargar Sesión (_SLM)
      │
      ▼
 ¿Autenticado? ──NO──→ login.slm
      │
     SÍ
      │
      ▼
 ¿Tiene Permisos? ──NO──→ Error 403
      │
     SÍ
      │
      ▼
?v=modulo.accion → Vista (proc → load → view → end)
?a=modulo.accion → Manejador AJAX
      │
      ▼
 Guardar Sesión → Respuesta
```

## Módulo CRUD de Ejemplo

El módulo `example/items` demuestra:

- Procesamiento del lado del servidor con DataTables
- Operaciones Crear, Leer, Actualizar, Eliminar
- Validación de formularios
- Diálogos modales
- Manejo de errores con try-catch-finally
- Registro de logs

## Sistema de Permisos

SLM Framework cuenta con un poderoso sistema de permisos de dos niveles:

### 1. Permisos Basados en Perfil (ACL)
Define permisos base a través de perfiles de usuario. Cada perfil contiene un ACL que especifica a qué módulos pueden acceder los usuarios y qué acciones pueden realizar.

### 2. Permisos Específicos de Usuario (NUEVO)
Sobrescribe permisos del perfil a nivel de usuario para casos especiales:
- **Override**: Los permisos de usuario reemplazan los permisos del perfil por módulo
- **Revocación**: Elimina el acceso a módulos específicos
- **Adicional**: Otorga acceso a módulos que no están en el perfil

**Casos de Uso de Ejemplo:**
- Consultor temporal con acceso limitado
- Usuario con responsabilidad adicional
- Acceso de soporte de emergencia

Ver [Guía de Permisos Específicos de Usuario](docs/es_MX/06-user-specific-permissions.md) para documentación completa.

## Documentación

#### Inicio Rápido
- 🚀 **[Guía de Perfil, Usuario, Módulo y Menú](docs/es_MX/03-profile-user-module-menu.md)** - Configuración completa de SLM Super
- 📘 [Guía Completa de Módulos](docs/es_MX/05-modules-complete-guide.md) - Módulos, menús y permisos
- 🔐 [Permisos Específicos de Usuario](docs/es_MX/06-user-specific-permissions.md) - Permisos a nivel de usuario
- 🎯 [SLM Super Quick Start](docs/es_MX/02-slm-super-quick-start.md) - Guía de inicio paso a paso

#### Documentación del Sistema
- [Arquitectura](docs/es_MX/10-ARCHITECTURE.md) - Arquitectura del sistema
- [Guía de Inicio](docs/es_MX/01-getting-started.md) - Configuración inicial
- [Desarrollo de Módulos](docs/es_MX/04-modules.md) - Creación de módulos
- [Guía de Elasticsearch](docs/es_MX/07-elasticsearch.md) - Trabajo con ES
- [Seguridad](docs/es_MX/08-security.md) - Autenticación y ACL
- [Referencia de API](docs/es_MX/09-api-reference.md) - Referencia de funciones
- [Estándares de Código](docs/es_MX/11-STANDARDS.md) - Convenciones de código

## Servicios Docker

| Servicio | Puerto | Descripción | Estado |
|----------|--------|-------------|--------|
| **app** | 80 | Aplicación PHP/Apache | Backend PHP |
| **api** | 3000 | API REST Node.js/Express | Backend Node.js |
| **elasticsearch** | 9200, 9300 | Servidor Elasticsearch | Base de datos |
| **kibana** | 5601 | Interfaz de Elasticsearch | Herramienta |
| **mailhog** | 1025, 8025 | Servidor y UI de email testing | Herramienta |

### Comandos útiles de Docker

```bash
# Ver logs de un servicio
docker-compose logs -f api
docker-compose logs -f app

# Reiniciar un servicio
docker-compose restart api
docker-compose restart app

# Detener todos los servicios
docker-compose down

# Detener y eliminar volúmenes
docker-compose down -v

# Reconstruir un servicio específico
docker-compose up --build api -d
```

## Arquitectura Dual: PHP + Node.js

SLM Framework ofrece flexibilidad para elegir el backend según tus necesidades:

### 🎯 Casos de Uso por Backend

#### Backend PHP (`appweb/`)
**Ideal para:**
- ✅ Aplicaciones web tradicionales con SSR (Server-Side Rendering)
- ✅ Paneles administrativos completos
- ✅ Sistemas con gestión de sesiones complejas
- ✅ Aplicaciones con control de acceso granular (ACL)
- ✅ Proyectos que requieren integración con librerías PHP existentes

**Ejemplo:** Panel administrativo corporativo, CMS, sistemas de gestión interna

#### Backend Node.js (`api/`)
**Ideal para:**
- ✅ API REST para aplicaciones móviles
- ✅ Backend para Single Page Applications (SPA)
- ✅ Microservicios
- ✅ Webhooks y integraciones
- ✅ APIs públicas con alta concurrencia
- ✅ Sistemas real-time (preparado para WebSockets)

**Ejemplo:** Backend para app móvil, API pública, microservicio de notificaciones

#### Arquitectura Híbrida (Ambos)
**Ideal para:**
- ✅ Aplicación web (PHP) + App móvil (Node.js API)
- ✅ Panel admin (PHP) + API pública (Node.js)
- ✅ Sistema legacy (PHP) + Nuevos servicios (Node.js)
- ✅ Migración gradual de PHP a Node.js

**Ejemplo:** E-commerce con panel admin en PHP y app móvil consumiendo API Node.js

### 📊 Comparación Técnica

| Aspecto | PHP (appweb/) | Node.js (api/) |
|---------|---------------|----------------|
| **Templating** | Sistema `.slm` integrado | JSON responses |
| **Sesiones** | Sí (Elasticsearch) | No (stateless) |
| **ACL** | Sí (permisos granulares) | API Key básico |
| **Hot-reload** | No (requiere restart Apache) | Sí (automático) |
| **Concurrencia** | Process-based (Apache) | Event-driven (Node.js) |
| **Ecosistema** | Composer/Packagist | npm |
| **Uso típico** | Full-stack web app | API REST |

### 🔄 Comunicación entre Backends

Ambos backends pueden coexistir y comunicarse:

```javascript
// Node.js API puede llamar a endpoints PHP
const response = await axios.get('http://app/api/internal/users');

// PHP puede consumir Node.js API
$response = file_get_contents('http://api:3000/v1/status');
```

**Elasticsearch como fuente única de verdad:**
- Ambos backends comparten el mismo índice de ES
- Los datos están sincronizados automáticamente
- Misma estructura de datos para users, profiles, modules, etc.

## Contribuir

1. Seguir los estándares de código en `docs/es_MX/11-STANDARDS.md`
2. Escribir pruebas para nuevas funcionalidades
3. Actualizar documentación según sea necesario
4. Enviar pull requests

## Licencia

Licencia MIT - ver archivo LICENSE para detalles.
