resources/views/pages/frontend/docs/configuracion-sistema.md
Última modificación: 24 Oct, 2026

Configuración Dinámica Key-Value

Mañuti implementa un almacén global de configuraciones (System Configuration Store) que permite a los operadores del sistema alterar umbrales de seguridad, políticas operativas y branding en caliente sin reiniciar servicios ni modificar variables de entorno .env.


1. Esquema de Datos y Tipado Estricto

La tabla configuracion_sistema almacena los parámetros serializados junto con metadatos de categoría y tipado:

CREATE TABLE `configuracion_sistema` (
    `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `categoria` VARCHAR(255) DEFAULT 'General',
    `clave` VARCHAR(255) NOT NULL UNIQUE,
    `valor` TEXT NOT NULL,
    `descripcion` VARCHAR(255) NULL,
    `tipo_dato` VARCHAR(50) DEFAULT 'string',
    `created_at` TIMESTAMP NULL,
    `updated_at` TIMESTAMP NULL
);

Tipos de Datos Soportados

  • string: Texto plano o rutas (e.g., system_app_name, system_logo_url).
  • number: Enteros casteados en tiempo de ejecución (e.g., login_max_attempts, security_idle_timeout).
  • boolean: Banderas binarias (true/false) renderizadas como switches interactivos en la interfaz administrativa.
  • array: Listas JSON deserializadas a arreglos nativos de PHP (e.g., security_pii_fields).

2. Caché Persistente en Redis y Método Helper

Para evitar que una consulta SQL golpee MariaDB en cada petición HTTP, el modelo ConfiguracionSistema almacena cada parámetro en la RAM de Redis:

// app/Models/ConfiguracionSistema.php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;

class ConfiguracionSistema extends Model
{
    protected $table = 'configuracion_sistema';
    protected $fillable = ['categoria', 'clave', 'valor', 'descripcion', 'tipo_dato'];

    public static function getValor(string $clave, mixed $default = null): mixed
    {
        return Cache::remember("sys_config_{$clave}", 3600, function () use ($clave, $default) {
            $config = self::where('clave', $clave)->first();
            if (!$config) return $default;

            return match ($config->tipo_dato) {
                'boolean' => filter_var($config->valor, FILTER_VALIDATE_BOOLEAN),
                'number'  => (int) $config->valor,
                'array'   => json_decode($config->valor, true) ?? [],
                default   => $config->valor,
            };
        });
    }
}

3. Modo Mantenimiento Inteligente (CheckSystemMaintenance)

A diferencia del comando artisan down (que bloquea todo el tráfico a nivel de servidor web), Mañuti cuenta con un middleware dinámico gobernado por la clave system_maintenance_mode:

// app/Http/Middleware/CheckSystemMaintenance.php
public function handle(Request $request, Closure $next)
{
    $isMaintenance = ConfiguracionSistema::getValor('system_maintenance_mode', false);

    if ($isMaintenance) {
        // Excepción de bypass: El Super Admin puede ingresar y realizar pruebas
        if (Auth::check() && Auth::user()->hasRole('Super Admin')) {
            return $next($request);
        }

        // Permite acceso a rutas de autenticación para administradores
        if ($request->is('login') || $request->is('logout')) {
            return $next($request);
        }

        abort(503, 'Plataforma en mantenimiento programado. Intente más tarde.');
    }

    return $next($request);
}

4. Inyección Global en Vistas (View::share)

Para que el título, favicons y directivas SEO estén disponibles en todas las plantillas Blade sin consultarlas manualmente en los controladores, el AppServiceProvider precarga la colección:

// app/Providers/AppServiceProvider.php
if (Schema::hasTable('configuracion_sistema')) {
    $globalConfig = Cache::remember('global_site_config', 3600, function () {
        return ConfiguracionSistema::all()->pluck('valor', 'clave')->toArray();
    });
    View::share('config', $globalConfig);
}

Enlaces Relacionados

Edita este documento en >> configuracion-sistema.md
← Volver a la Landing Page