# Estándares de Código

Este documento define las convenciones de código y mejores prácticas para el desarrollo con SLM Framework.

## Convenciones de Nomenclatura

### Funciones y Métodos

Usa **camelCase** para todas las funciones y métodos:

```php
// Correcto
function getUserById($id) { }
function validateRequiredFields($fields) { }
function getSecurityAccess($module) { }

// Incorrecto
function get_user_by_id($id) { }
function GetUserById($id) { }
```

### Variables

Usa **camelCase** para variables:

```php
// Correcto
$userName = 'Juan';
$isActive = true;
$recordsTotal = 100;

// Incorrecto
$user_name = 'Juan';
$UserName = 'Juan';
```

### Constantes

Usa **UPPER_SNAKE_CASE** para constantes:

```php
// Correcto
define('APP_NAME', 'Mi App');
define('ES_SERVER', 'http://localhost:9200');
const MAX_LOGIN_ATTEMPTS = 3;

// Incorrecto
define('appName', 'Mi App');
define('app_name', 'Mi App');
```

### Archivos

- Archivos de módulo: `{tipo}.{accion}.slm` (ej., `view.list.slm`, `ajax.items.slm`)
- Archivos de sistema: nombres descriptivos en minúsculas (ej., `helpers.slm`, `config.slm`)

## Formato de Respuesta

Siempre usa el helper `_response()` para respuestas AJAX:

```php
// Respuesta de éxito
_response(false, 'Operación exitosa', ['id' => $newId]);

// Respuesta de error
_response(true, 'Mensaje de error');

// Respuesta con múltiples datos
_response(false, 'Creado', [
    'id' => $id,
    'closeModal' => true,
    'reloadTable' => true
]);
```

### Estructura de Respuesta

```php
[
    'error' => bool,      // true = error, false = éxito
    'message' => string,  // Mensaje amigable para el usuario
    'data' => array       // Datos adicionales opcionales
]
```

## Manejo de Errores

### Patrón Try-Catch-Finally

Siempre usa try-catch-finally con logging:

```php
function createItem(): void
{
    $response = _response(true);
    $logType = 'error';
    $logData = [];

    try {
        // Validación
        validateRequiredFields(['name']);

        // Lógica de negocio
        $data = [
            'name' => getPostString('name'),
            'slm' => [
                'type' => 'item',
                'timestamp' => getTimestamp()
            ]
        ];

        $result = setNewObject($data);

        if (isset($result['error'])) {
            throw new Exception('Error al crear elemento');
        }

        $response = _response(false, 'Elemento creado', ['id' => $result['_id']]);
        $logType = 'success';

    } catch (InvalidArgumentException $e) {
        $response['message'] = $e->getMessage();
    } catch (Exception $e) {
        $response['message'] = 'Ocurrió un error';
        $logData['exception'] = $e->getMessage();
    } finally {
        $logData['response'] = $response;
        addToLog($logType, 'items', __FUNCTION__, $logData);
    }

    exit(json_encode($response));
}
```

### Tipos de Excepción

- `InvalidArgumentException` - Errores de validación (mostrar mensaje al usuario)
- `RuntimeException` - Errores de lógica de negocio
- `Exception` - Errores generales (registrar detalles, mostrar mensaje genérico)

## Validación

### Campos Requeridos

```php
validateRequiredFields(['name', 'email', 'status']);
```

### Sanitización de Entrada

```php
$name = getPostString('name');           // String recortado
$page = getPostInt('page', 1);           // Entero con valor por defecto
$active = getPostBool('active', false);  // Booleano con valor por defecto
$email = validateEmail($_POST['email']); // Email validado
```

### Escape de Consultas Elasticsearch

```php
$searchTerm = escapeEsValue($_POST['search']);
```

## Estructura de Módulos

### Archivos Estándar

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

### Estructura de Handler AJAX

```php
<?php
/**
 * Nombre del Módulo - Handler AJAX
 */

// Despachador
if (isset($_POST['acc']) && function_exists($_POST['acc'])) {
    $_POST['acc']();
}

/**
 * Obtener lista de elementos.
 */
function getItems(): void
{
    // Implementación
}

/**
 * Crear nuevo elemento.
 */
function createItem(): void
{
    // Implementación
}
```

## Seguridad

### Verificación de Permisos

Siempre verifica permisos antes de las acciones:

```php
function deleteItem(): void
{
    $permissions = _SLM::getSecurityAccess('module.action');

    if (!in_array('delete', $permissions)) {
        exit(json_encode(_response(true, 'Permiso denegado')));
    }

    // Continuar con eliminación...
}
```

### Validación de Entrada

Nunca confíes en la entrada del usuario:

```php
// Siempre valida y sanitiza
$id = getPostString('id');
if (empty($id)) {
    throw new InvalidArgumentException('ID es requerido');
}

// Validar formato de email
$email = validateEmail($_POST['email']);

// Escapar para consultas ES
$search = escapeEsValue($_POST['search']);
```

### Escape de Salida

Previene XSS en las vistas:

```php
<?= htmlspecialchars($user['name'], ENT_QUOTES, 'UTF-8') ?>
```

## Documentación

### Documentación de Funciones

```php
/**
 * Obtener usuario por ID.
 *
 * @param string $id ID del usuario
 * @param bool $includeProfile Incluir datos del perfil
 * @return array|null Datos del usuario o null si no existe
 * @throws InvalidArgumentException Si el ID está vacío
 */
function getUserById(string $id, bool $includeProfile = false): ?array
{
    // Implementación
}
```

### Encabezados de Archivo

```php
<?php
/**
 * Nombre del Módulo - Descripción de la Acción
 *
 * Breve descripción de lo que hace este archivo.
 */
```

## Mejores Prácticas

1. **Responsabilidad Única**: Cada función debe hacer una sola cosa bien
2. **Retornos Tempranos**: Retorna temprano para reducir anidación
3. **Nombres Significativos**: Usa nombres descriptivos para variables y funciones
4. **Formato Consistente**: Usa indentación consistente (4 espacios)
5. **Sin Números Mágicos**: Usa constantes para valores repetidos
6. **Mensajes de Error**: Proporciona mensajes de error claros y accionables
7. **Logging**: Registra todas las operaciones importantes y errores
8. **Comentarios**: Comenta el "por qué", no el "qué"
