feat: Implementación completa Fase 4 - Sistema de monitoreo con API REST y WebSocket

 Nuevas funcionalidades:
- API REST unificada en puerto 8080 (eliminado CORS)
- WebSocket para logs en tiempo real desde journalctl
- Integración completa con systemd para gestión de servicios
- Escaneo automático de procesos Node.js y Python
- Rate limiting (1 operación/segundo por app)
- Interface web moderna con Tailwind CSS (tema oscuro)
- Documentación API estilo Swagger completamente en español

🎨 Interface Web (todas las páginas en español):
- Dashboard con estadísticas en tiempo real
- Visor de escaneo de procesos con filtros
- Formulario de registro de aplicaciones con variables de entorno
- Visor de logs en tiempo real con WebSocket y sidebar
- Página de selección de apps detectadas
- Documentación completa de API REST

🏗️ Arquitectura:
- Módulo models: ServiceConfig, ManagedApp, AppStatus
- Módulo systemd: wrapper de systemctl, generador de .service, parser
- Módulo orchestrator: AppManager, LifecycleManager con validaciones
- Módulo api: handlers REST, WebSocket manager, DTOs
- Servidor unificado en puerto 8080 (Web + API + WS)

🔧 Mejoras técnicas:
- Eliminación de CORS mediante servidor unificado
- Separación clara frontend/backend con carga dinámica
- Thread-safe con Arc<DashMap> para estado compartido
- Reconciliación de estados: sysinfo vs systemd
- Validaciones de paths, usuarios y configuraciones
- Manejo robusto de errores con thiserror

📝 Documentación:
- README.md actualizado con arquitectura completa
- EJEMPLOS.md con casos de uso detallados
- ESTADO_PROYECTO.md con progreso de Fase 4
- API docs interactiva en /api-docs
- Script de despliegue mejorado con health checks

🚀 Producción:
- Deployment script con validaciones
- Health checks y rollback capability
- Configuración de sudoers para systemctl
- Hardening de seguridad en servicios systemd
This commit is contained in:
2026-01-13 08:24:13 -05:00
parent 3595e55a1e
commit b0489739cf
33 changed files with 6893 additions and 1261 deletions

817
README.md
View File

@@ -1,117 +1,134 @@
# SIAX Monitor
# SIAX Agent - Sistema de Monitoreo y Gestión de Procesos
Sistema de monitoreo en tiempo real para aplicaciones Node.js, desarrollado en Rust. Detecta automáticamente procesos Node.js, recolecta métricas de rendimiento (CPU, RAM, PID) y las envía a la nube SIAX.
Sistema completo de monitoreo y gestión de aplicaciones Node.js y Python con integración systemd, API REST y streaming de logs en tiempo real.
## Características
- **Monitoreo Automático**: Detecta y monitorea procesos Node.js basándose en su directorio de trabajo
- **Métricas en Tiempo Real**: CPU, memoria RAM, PID y estado del proceso
- **Interface Web**: Panel de control intuitivo en el puerto 8080
- **Sistema de Logs**: Registro completo con niveles (Info, Warning, Error, Critical)
- **Configuración Dinámica**: Gestión de aplicaciones mediante archivo JSON
- **Envío a la Nube**: Reportes automáticos cada 60 segundos a la API SIAX
### ✅ Monitoreo en Tiempo Real
- Detección automática de procesos Node.js y Python
- Métricas de CPU y RAM
- Reconciliación con systemd para detectar estados inconsistentes
- Reporte automático a API central cloud
## Arquitectura del Proyecto
### 🔧 Gestión de Servicios
- Registro dinámico de aplicaciones
- Generación automática de archivos `.service` para systemd
- Control de ciclo de vida: start, stop, restart
- Soporte para Node.js y Python/FastAPI
- Rate limiting para prevenir spam de operaciones
### 📊 Interface Web Local
- Dashboard de procesos en ejecución
- Escaneo y detección automática
- Visualizador de logs del sistema
- Control de aplicaciones (solo VPN)
### 🔌 API REST
- Endpoints para gestión completa de aplicaciones
- WebSocket para streaming de logs en tiempo real
- Documentación OpenAPI/Swagger ready
### 🔒 Seguridad
- Interface web solo accesible vía VPN
- Validaciones de permisos sudo
- Sistema de rate limiting
- Detección de discrepancias de estado
---
## Arquitectura
```
siax_monitor/
├── src/
├── main.rs # Punto de entrada principal
├── monitor.rs # Lógica de monitoreo de procesos
├── interface.rs # Servidor web Axum
│ ├── logger.rs # Sistema de logging
└── config.rs # Gestión de configuración
├── web/ # Templates HTML
├── index.html
│ ├── scan.html
├── select.html
├── success.html
└── logs.html
├── config/ # Configuración generada automáticamente
└── monitored_apps.json
├── logs/ # Logs del sistema
└── errors.log
└── Cargo.toml # Dependencias del proyecto
┌─────────────────────────────────────┐
│ API Central Cloud │
https://api.siax-system.net │
- Dashboard público analytics │
- Recibe reportes de agents │
└──────────────┬──────────────────────┘
│ POST /apps_servcs/apps
│ (reportes de estado)
┌──────────────▼──────────────────────┐
SIAX Agent (local en servidor) │
http://192.168.x.x:8080 (VPN only) │
│ Componentes: │
1. Monitor (background) │
│ 2. Interface Web (puerto 8080) │
3. API REST (puerto 8081) │
│ 4. WebSocket Logs (puerto 8081) │
└──────────────────────────────────────┘
```
## Requisitos Previos
### Sistema Operativo
- Linux (Ubuntu/Debian recomendado)
- macOS
- Windows (con limitaciones en detección de procesos)
### Herramientas Necesarias
#### 1. Rust (toolchain completo)
```bash
# Instalar Rust usando rustup
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Verificar instalación
rustc --version
cargo --version
```
#### 2. Librerías del Sistema (Linux)
**Ubuntu/Debian:**
```bash
sudo apt update
sudo apt install -y build-essential pkg-config libssl-dev
```
**Fedora/RHEL/CentOS:**
```bash
sudo dnf groupinstall "Development Tools"
sudo dnf install pkg-config openssl-devel
```
**Arch Linux:**
```bash
sudo pacman -S base-devel openssl pkg-config
```
**macOS:**
```bash
# Instalar Homebrew si no lo tienes
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Instalar dependencias
brew install openssl pkg-config
```
---
## Instalación
### Opción 1: Clonar y Compilar
### Requisitos Previos
- Linux con systemd
- Rust 1.70+ (instalación abajo)
- Acceso sudo para gestión de servicios
### Instalar Rust (si no está instalado)
```bash
# Clonar el repositorio (si aplica)
git clone <repository-url>
cd siax_monitor
# Compilar el proyecto
cargo build --release
# El binario estará en:
# ./target/release/siax_monitor
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env
```
### Opción 2: Compilación Directa
### Instalación Automática
```bash
# Si ya tienes el código fuente
# Clonar repositorio
git clone <repo-url>
cd siax_monitor
# Compilar en modo release (optimizado)
cargo build --release
# Ejecutar script de despliegue
sudo ./desplegar_agent.sh
```
El script automáticamente:
- ✅ Verifica dependencias
- ✅ Compila en modo release
- ✅ Crea usuario del sistema
- ✅ Instala binario en `/opt/siax-agent`
- ✅ Configura sudoers para systemctl
- ✅ Crea y habilita servicio systemd
- ✅ Inicia el agente
- ✅ Verifica instalación
### Instalación Manual
```bash
# Compilar
cargo build --release
# Copiar binario
sudo mkdir -p /opt/siax-agent
sudo cp target/release/siax_monitor /opt/siax-agent/siax-agent
# Crear usuario
sudo useradd --system --no-create-home siax-agent
# Configurar sudoers (ver sección Configuración)
# Crear servicio systemd (ver ejemplo abajo)
sudo nano /etc/systemd/system/siax-agent.service
# Habilitar e iniciar
sudo systemctl daemon-reload
sudo systemctl enable siax-agent
sudo systemctl start siax-agent
```
---
## Configuración
### 1. Archivo de Configuración
### Archivo de Configuración
El archivo `config/monitored_apps.json` se crea automáticamente con valores por defecto:
`/opt/siax-agent/config/monitored_apps.json`
```json
{
@@ -128,374 +145,348 @@ El archivo `config/monitored_apps.json` se crea automáticamente con valores por
}
```
**Edita este archivo para agregar/modificar las aplicaciones a monitorear.**
### Configuración de Sudoers
### 2. Configuración de Credenciales
`/etc/sudoers.d/siax-agent`
Actualmente las credenciales están en `src/main.rs`. Para producción, edita:
```bash
siax-agent ALL=(ALL) NOPASSWD: /bin/systemctl start *
siax-agent ALL=(ALL) NOPASSWD: /bin/systemctl stop *
siax-agent ALL=(ALL) NOPASSWD: /bin/systemctl restart *
siax-agent ALL=(ALL) NOPASSWD: /bin/systemctl status *
siax-agent ALL=(ALL) NOPASSWD: /bin/systemctl enable *
siax-agent ALL=(ALL) NOPASSWD: /bin/systemctl disable *
siax-agent ALL=(ALL) NOPASSWD: /bin/systemctl daemon-reload
siax-agent ALL=(ALL) NOPASSWD: /bin/journalctl *
```
### Variables de Entorno (main.rs)
```rust
let server_name = "tu-servidor".to_string();
let api_key = "tu-api-key".to_string();
let cloud_url = "https://api.siax-system.net/api/apps_servcs/apps".to_string();
let server_name = "siax-intel"; // Nombre del servidor
let api_key = "ak_xxx..."; // API key para cloud
let cloud_url = "https://api.siax-system.net/api/apps_servcs/apps";
```
## Despliegue
### Despliegue Manual
#### 1. Compilar el Proyecto
```bash
cd /ruta/a/siax_monitor
cargo build --release
```
#### 2. Ejecutar el Monitor
```bash
# Opción 1: Ejecutar directamente
./target/release/siax_monitor
# Opción 2: Ejecutar con Cargo
cargo run --release
```
#### 3. Verificar que Funciona
```bash
# El sistema mostrará:
# ✅ Sistema SIAX operativo. Monitor en segundo plano e Interface en puerto 8080.
# Acceder a la interface web:
# http://localhost:8080
```
### Despliegue Automático con Script Bash
Crea el archivo `desplegar_siax.sh`:
```bash
#!/bin/bash
# SIAX Monitor - Script de Despliegue Automático
# Autor: Sistema SIAX
# Descripción: Instala dependencias, compila y ejecuta el monitor
set -e # Detener en caso de error
echo "🚀 Iniciando despliegue de SIAX Monitor..."
# ========================================
# 1. Verificar Rust
# ========================================
echo ""
echo "📦 Verificando instalación de Rust..."
if ! command -v rustc &> /dev/null; then
echo "❌ Rust no está instalado."
echo "Instalando Rust..."
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source "$HOME/.cargo/env"
echo "✅ Rust instalado correctamente"
else
echo "✅ Rust ya está instalado ($(rustc --version))"
fi
# ========================================
# 2. Detectar sistema operativo e instalar dependencias
# ========================================
echo ""
echo "🔧 Instalando dependencias del sistema..."
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
# Detectar distribución Linux
if [ -f /etc/debian_version ]; then
echo "Detectado: Debian/Ubuntu"
sudo apt update
sudo apt install -y build-essential pkg-config libssl-dev
elif [ -f /etc/redhat-release ]; then
echo "Detectado: RHEL/Fedora/CentOS"
sudo dnf groupinstall "Development Tools" -y
sudo dnf install pkg-config openssl-devel -y
elif [ -f /etc/arch-release ]; then
echo "Detectado: Arch Linux"
sudo pacman -S --noconfirm base-devel openssl pkg-config
else
echo "⚠️ Distribución no reconocida. Instala manualmente: build-essential, pkg-config, libssl-dev"
fi
elif [[ "$OSTYPE" == "darwin"* ]]; then
echo "Detectado: macOS"
if ! command -v brew &> /dev/null; then
echo "Instalando Homebrew..."
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
fi
brew install openssl pkg-config
else
echo "⚠️ Sistema operativo no soportado automáticamente"
fi
echo "✅ Dependencias instaladas"
# ========================================
# 3. Compilar el proyecto
# ========================================
echo ""
echo "🔨 Compilando SIAX Monitor..."
cargo build --release
if [ $? -eq 0 ]; then
echo "✅ Compilación exitosa"
else
echo "❌ Error en la compilación"
exit 1
fi
# ========================================
# 4. Crear directorios necesarios
# ========================================
echo ""
echo "📁 Creando directorios..."
mkdir -p config
mkdir -p logs
echo "✅ Directorios creados"
# ========================================
# 5. Verificar configuración
# ========================================
echo ""
echo "⚙️ Verificando configuración..."
if [ ! -f "config/monitored_apps.json" ]; then
echo " Archivo de configuración no encontrado. Se creará automáticamente al iniciar."
fi
# ========================================
# 6. Ejecutar el monitor
# ========================================
echo ""
echo "🎯 Iniciando SIAX Monitor..."
echo ""
echo "=========================================="
echo " Interface Web: http://localhost:8080"
echo " Logs: logs/errors.log"
echo " Config: config/monitored_apps.json"
echo "=========================================="
echo ""
./target/release/siax_monitor
```
#### Usar el Script
```bash
# Dar permisos de ejecución
chmod +x desplegar_siax.sh
# Ejecutar
./desplegar_siax.sh
```
### Despliegue como Servicio Systemd (Linux)
Para ejecutar SIAX Monitor como servicio en segundo plano:
#### 1. Crear archivo de servicio
```bash
sudo nano /etc/systemd/system/siax-monitor.service
```
#### 2. Contenido del servicio
```ini
[Unit]
Description=SIAX Monitor - Sistema de Monitoreo Node.js
After=network.target
[Service]
Type=simple
User=tu_usuario
WorkingDirectory=/ruta/completa/a/siax_monitor
ExecStart=/ruta/completa/a/siax_monitor/target/release/siax_monitor
Restart=always
RestartSec=10
# Variables de entorno (opcional)
Environment="RUST_LOG=info"
# Logs
StandardOutput=append:/var/log/siax-monitor.log
StandardError=append:/var/log/siax-monitor-error.log
[Install]
WantedBy=multi-user.target
```
#### 3. Activar y gestionar el servicio
```bash
# Recargar systemd
sudo systemctl daemon-reload
# Habilitar inicio automático
sudo systemctl enable siax-monitor
# Iniciar el servicio
sudo systemctl start siax-monitor
# Ver estado
sudo systemctl status siax-monitor
# Ver logs
sudo journalctl -u siax-monitor -f
# Detener servicio
sudo systemctl stop siax-monitor
# Reiniciar servicio
sudo systemctl restart siax-monitor
```
---
## Uso
### Comandos del Sistema
```bash
# Ver estado del agente
sudo systemctl status siax-agent
# Ver logs en tiempo real
sudo journalctl -u siax-agent -f
# Reiniciar agente
sudo systemctl restart siax-agent
# Detener agente
sudo systemctl stop siax-agent
```
### Interface Web
Accede a `http://localhost:8080` para:
1. **Dashboard Principal** (`/`)
- Vista general del sistema
2. **Escanear Procesos** (`/scan`)
- Lista todos los procesos Node.js detectados
- Muestra PID, CPU, RAM y ruta
3. **Seleccionar Procesos** (`/select`)
- Interfaz para agregar procesos al monitoreo
- Auto-completa nombre basándose en la ruta
4. **Ver Logs** (`/logs`)
- Historial completo de logs
- Estadísticas por nivel
- Filtros por tipo
### Línea de Comandos
```bash
# Ver logs en tiempo real
tail -f logs/errors.log
# Editar configuración
nano config/monitored_apps.json
# Verificar procesos Node.js
ps aux | grep node
```
http://localhost:8080
```
## Dependencias de Rust
**Páginas disponibles:**
- `/` - Inicio
- `/scan` - Escanear procesos Node.js
- `/select` - Seleccionar y agregar procesos
- `/logs` - Ver logs del sistema
El proyecto utiliza las siguientes crates:
### API REST
- **tokio** `1.x` - Runtime asíncrono
- **axum** `0.7` - Framework web
- **reqwest** `0.11` - Cliente HTTP (con feature `json`)
- **serde** `1.0` - Serialización/deserialización (con feature `derive`)
- **serde_json** `1.0` - Manejo de JSON
- **sysinfo** `0.30` - Información del sistema
- **chrono** `0.4` - Manejo de fechas y timestamps
**Base URL:** `http://localhost:8081`
## Estructura de Datos
#### Listar Aplicaciones
```bash
GET /api/apps
### AppStatusUpdate (enviado a la nube)
```json
Response:
{
"app_name": "app_tareas",
"server": "siax-intel",
"status": "running",
"port": 3000,
"pid": 12345,
"memory_usage": "125.45MB",
"cpu_usage": "2.30%",
"last_check": "2025-01-11 14:30:00"
"success": true,
"data": {
"apps": ["app1", "app2"],
"total": 2
}
}
```
### MonitoredApp (configuración)
#### Registrar Nueva Aplicación
```bash
POST /api/apps
Content-Type: application/json
```json
{
"name": "nombre_app",
"port": 3000
"app_name": "mi-app",
"script_path": "/opt/apps/mi-app/index.js",
"working_directory": "/opt/apps/mi-app",
"user": "nodejs",
"environment": {
"PORT": "3000",
"NODE_ENV": "production"
},
"restart_policy": "always",
"app_type": "nodejs",
"description": "Mi aplicación"
}
```
## Solución de Problemas
### Error: "error: linker 'cc' not found"
#### Iniciar Aplicación
```bash
# Ubuntu/Debian
sudo apt install build-essential
# Fedora/RHEL
sudo dnf groupinstall "Development Tools"
POST /api/apps/:name/start
```
### Error: "failed to run custom build command for openssl-sys"
#### Detener Aplicación
```bash
# Ubuntu/Debian
sudo apt install pkg-config libssl-dev
# Fedora/RHEL
sudo dnf install pkg-config openssl-devel
# macOS
brew install openssl pkg-config
POST /api/apps/:name/stop
```
### El monitor no detecta mis procesos Node.js
#### Reiniciar Aplicación
```bash
POST /api/apps/:name/restart
```
1. Verifica que los procesos estén corriendo: `ps aux | grep node`
2. Comprueba que el nombre en `config/monitored_apps.json` coincida con el directorio de trabajo del proceso
3. El monitor busca coincidencias en el `cwd` (current working directory) del proceso
#### Obtener Estado
```bash
GET /api/apps/:name/status
### La interface web no carga
Response:
{
"success": true,
"data": {
"name": "mi-app",
"status": "running",
"pid": 12345,
"cpu_usage": 2.5,
"memory_usage": "128.50 MB",
"systemd_status": "active",
"last_updated": "2026-01-12 10:30:00"
}
}
```
1. Verifica que el puerto 8080 esté libre: `lsof -i :8080`
2. Comprueba los logs: `cat logs/errors.log`
3. Asegúrate de que las templates HTML existan en `web/`
#### Eliminar Aplicación
```bash
DELETE /api/apps/:name
```
## Seguridad
### WebSocket para Logs
⚠️ **IMPORTANTE**:
```javascript
// Conectar a logs en tiempo real
const ws = new WebSocket('ws://localhost:8081/ws/logs/mi-app');
- El API Key está hardcodeado en `src/main.rs`
- Para producción, usa variables de entorno
- No expongas el puerto 8080 a internet sin autenticación
- Considera usar HTTPS en producción
ws.onmessage = (event) => {
console.log('Log:', event.data);
};
## Contribuir
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
```
1. Fork el proyecto
2. Crea una rama para tu feature (`git checkout -b feature/nueva-funcionalidad`)
3. Commit tus cambios (`git commit -am 'Agrega nueva funcionalidad'`)
4. Push a la rama (`git push origin feature/nueva-funcionalidad`)
5. Crea un Pull Request
**Ejemplo con wscat:**
```bash
wscat -c ws://localhost:8081/ws/logs/mi-app
```
---
## Ejemplos de Uso
### Registrar una app Node.js
```bash
curl -X POST http://localhost:8081/api/apps \
-H "Content-Type: application/json" \
-d '{
"app_name": "api-backend",
"script_path": "/home/nodejs/api-backend/server.js",
"working_directory": "/home/nodejs/api-backend",
"user": "nodejs",
"environment": {
"PORT": "3000",
"NODE_ENV": "production"
},
"restart_policy": "always",
"app_type": "nodejs",
"description": "API Backend Principal"
}'
```
### Registrar una app Python (FastAPI)
```bash
curl -X POST http://localhost:8081/api/apps \
-H "Content-Type: application/json" \
-d '{
"app_name": "ml-service",
"script_path": "/home/python/ml-service/main.py",
"working_directory": "/home/python/ml-service",
"user": "python",
"environment": {
"PORT": "8000",
"WORKERS": "4"
},
"restart_policy": "on-failure",
"app_type": "python"
}'
```
### Reiniciar una aplicación
```bash
curl -X POST http://localhost:8081/api/apps/api-backend/restart
```
### Ver estado de todas las apps
```bash
curl http://localhost:8081/api/apps | jq
```
---
## Estructura del Proyecto
```
siax_monitor/
├── src/
│ ├── main.rs # Entry point
│ ├── lib.rs # Módulo raíz
│ ├── monitor.rs # Monitor de procesos + reconciliación systemd
│ ├── interface.rs # Interface web
│ ├── logger.rs # Sistema de logs
│ ├── config.rs # Gestión de configuración
│ ├── models/ # Modelos de datos
│ │ ├── mod.rs
│ │ ├── app.rs # ManagedApp, AppStatus, ServiceStatus
│ │ └── service_config.rs # ServiceConfig, AppType, RestartPolicy
│ ├── systemd/ # Integración con systemd
│ │ ├── mod.rs
│ │ ├── systemctl.rs # Wrapper de systemctl
│ │ ├── service_generator.rs # Generador de .service
│ │ └── parser.rs # Parser de salida systemd
│ ├── orchestrator/ # Lógica de ciclo de vida
│ │ ├── mod.rs
│ │ ├── app_manager.rs # CRUD de apps
│ │ └── lifecycle.rs # Start/Stop/Restart + rate limiting
│ └── api/ # API REST + WebSocket
│ ├── mod.rs
│ ├── handlers.rs # Handlers HTTP
│ ├── dto.rs # DTOs de request/response
│ └── websocket.rs # LogStreamer con journalctl
├── web/ # Templates HTML
├── config/ # Configuración
│ └── monitored_apps.json
├── logs/ # Logs del sistema
│ └── errors.log
├── Cargo.toml # Dependencias
├── desplegar_agent.sh # Script de deployment
├── tareas.txt # Plan de desarrollo
└── README.md # Esta documentación
```
---
## Estados de Aplicaciones
El sistema reconcilia estados entre detección de procesos y systemd:
| Proceso | Systemd | Estado Final | Descripción |
|---------|---------|--------------|-------------|
| ✅ | Active | `running` | Funcionamiento normal |
| ❌ | Active | `crashed` | ⚠️ Systemd dice activo pero proceso no existe |
| ❌ | Failed | `failed` | Servicio falló y systemd lo detectó |
| ✅ | Inactive | `zombie` | ⚠️ Proceso existe pero systemd dice inactivo |
| ❌ | Inactive | `stopped` | Aplicación detenida normalmente |
Las **discrepancias** (crashed/zombie) se reportan automáticamente en logs y a la API central.
---
## Troubleshooting
### El agente no inicia
```bash
# Ver logs detallados
sudo journalctl -u siax-agent -n 100 --no-pager
# Verificar permisos
ls -la /opt/siax-agent
```
### Error de permisos sudo
```bash
# Verificar configuración sudoers
sudo cat /etc/sudoers.d/siax-agent
# Probar manualmente
sudo -u siax-agent sudo systemctl status siax-agent
```
### No puede registrar apps
**Error:** `Permission denied writing to /etc/systemd/system`
**Solución:** Asegúrate de que el servicio tiene permisos de escritura o ajusta `ProtectSystem` en el servicio systemd.
### WebSocket no conecta
```bash
# Verificar que el puerto 8081 esté abierto
sudo netstat -tlnp | grep 8081
# Probar conexión
curl http://localhost:8081/api/apps
```
---
## Desarrollo
### Compilar en modo desarrollo
```bash
cargo build
cargo run
```
### Ejecutar tests
```bash
cargo test
```
### Linter
```bash
cargo clippy
```
### Formateo
```bash
cargo fmt
```
---
## Licencia
[Especificar licencia]
## Contacto
Sistema SIAX - [Información de contacto]
---
**Versión**: 0.1.0
**Última actualización**: 2025-01-11
## Contacto
[Información de contacto del proyecto]