Saltar a contenido

Guía de Implementación: Control de Acceso Organizacional

Pasos para Implementar en Componentes Existentes

1. Preparación del Entorno

A. Verificar el Trait OrganizationAccessControl

# Verificar que el trait existe
ls -la app/Traits/OrganizationAccessControl.php

# Si no existe, crearlo con el contenido documentado

B. Identificar Componentes a Modificar

# Listar todos los componentes Setting
find app/Http/Livewire/Setting -name "*.php" -type f

2. Patrón de Modificación por Componente

A. Estructura Base de Modificación

Para cada componente en app/Http/Livewire/Setting/, seguir estos pasos:

// 1. Agregar el trait al inicio de la clase
use App\Traits\OrganizationAccessControl;

class ExistingComponent extends Component
{
    // 2. Incluir el trait junto a los existentes
    use SetLocale, ExistingTraits, OrganizationAccessControl;

    // 3. Agregar propiedad para organización si no existe
    public $organization_id;

    // 4. Modificar mount() para incluir verificación
    public function mount()
    {
        $this->setCurrentLocale(); // Mantener lógica existente

        // Agregar verificación de acceso
        $this->checkConfigurationAccess('configuration.key');

        // ... resto de lógica existente
    }

    // 5. Agregar método para selección de organización si no existe
    public function onSelectOrganization()
    {
        if (!empty($this->organization_id)) {
            if (!$this->canOrganizationAccessConfiguration($this->organization_id, 'configuration.key')) {
                $this->addError('organization_id', $this->getRestrictionMessage('configuration.key'));
                return;
            }

            // Lógica específica del componente para cargar datos de la organización
        }
    }

    // 6. Modificar update() para incluir verificación
    public function update()
    {
        // Verificar acceso antes de cualquier operación
        $this->checkConfigurationAccess('configuration.key');

        if (!$this->canOrganizationAccessConfiguration($this->organization_id, 'configuration.key')) {
            $this->addError('organization_id', $this->getRestrictionMessage('configuration.key'));
            return;
        }

        // ... resto de lógica existente de validación y actualización
    }

    // 7. Modificar render() para incluir variables de acceso
    public function render()
    {
        $organizationsWithAccess = $this->getOrganizationsWithAccess('configuration.key');
        $availableConfigurations = $this->getAvailableConfigurations();
        $settingsMenu = $this->getSettingsMenuConfiguration();

        return view('livewire.setting.existing-component', [
            'organizationsWithAccess' => $organizationsWithAccess,
            'availableConfigurations' => $availableConfigurations,
            'settingsMenu' => $settingsMenu,
            'title' => __('Component Title')
        ]);
        // Nota: Remover ->layout() si causa errores de compilación
    }
}

3. Mapeo de Claves de Configuración

A. Matriz de Componentes y Claves

Componente Archivo Clave de Configuración Planes Requeridos
Profile Profile.php profile basic, professional, premium, enterprise
Import Import.php import.general professional, premium, enterprise
Import SQL Server Import.php import.sqlserver professional, premium, enterprise
Import Magaya Import.php import.magaya premium, enterprise
Import Fikable Import.php import.fikable premium, enterprise
Invupos Invupos.php extraction.invupos professional, premium, enterprise
Lightspeed Lightspeed.php extraction.lightspeed premium, enterprise
LoginSecurity LoginSecurity.php security.login professional, premium, enterprise
Extraction Extraction.php extraction.general professional, premium, enterprise

B. Configuración de Acceso en el Trait

// En OrganizationAccessControl.php
private array $configurationAccess = [
    // Configuraciones básicas
    'profile' => ['basic', 'professional', 'premium', 'enterprise'],

    // Configuraciones profesionales
    'import.general' => ['professional', 'premium', 'enterprise'],
    'import.sqlserver' => ['professional', 'premium', 'enterprise'],
    'extraction.invupos' => ['professional', 'premium', 'enterprise'],
    'security.login' => ['professional', 'premium', 'enterprise'],
    'extraction.general' => ['professional', 'premium', 'enterprise'],

    // Configuraciones premium
    'import.magaya' => ['premium', 'enterprise'],
    'import.fikable' => ['premium', 'enterprise'],
    'extraction.lightspeed' => ['premium', 'enterprise'],
    'integration.quickbooks' => ['premium', 'enterprise'],

    // Configuraciones enterprise
    'integration.shopify' => ['enterprise'],
    'advanced.settings' => ['enterprise'],
];

4. Implementación Específica por Componente

A. Profile.php

# Comando para aplicar cambios
cp app/Http/Livewire/Setting/Profile.php app/Http/Livewire/Setting/Profile.backup.php

# Aplicar modificaciones según el patrón

Modificaciones específicas: - Clave: profile - Planes: Todos los planes - Sin verificación de organización específica (configuración global de usuario)

B. Import.php

# Backup del archivo original
cp app/Http/Livewire/Setting/Import.php app/Http/Livewire/Setting/Import.backup.php

Modificaciones específicas: - Clave base: import.general - Claves adicionales: import.sqlserver, import.magaya, import.fikable - Planes: Profesional en adelante - Verificación de organización específica requerida

C. Invupos.php

# Backup del archivo original
cp app/Http/Livewire/Setting/Invupos.php app/Http/Livewire/Setting/Invupos.backup.php

Modificaciones específicas: - Clave: extraction.invupos - Planes: Profesional en adelante - Verificación de organización específica requerida

5. Modificaciones en Vistas Blade

A. Agregar Selector de Organización Filtrado

{{-- En cada vista de configuración --}}
@if(isset($organizationsWithAccess) && $organizationsWithAccess->count() > 0)
<div class="form-group">
    <label for="organization_id">{{ __('Organization') }}</label>
    <select wire:model="organization_id" wire:change="onSelectOrganization" class="form-control">
        <option value="">{{ __('Select Organization') }}</option>
        @foreach($organizationsWithAccess as $org)
            <option value="{{ $org->id }}">{{ $org->name }} ({{ __(ucfirst($org->plan_type)) }})</option>
        @endforeach
    </select>
    @error('organization_id') <span class="text-danger">{{ $message }}</span> @enderror
</div>
@endif

B. Menú de Configuraciones Filtrado

{{-- Sidebar o menú de navegación --}}
@if(isset($settingsMenu))
<nav class="settings-navigation">
    @foreach($settingsMenu as $section => $configs)
        <div class="menu-section">
            <h4>{{ __(ucfirst($section)) }}</h4>
            @foreach($configs as $config)
                <a href="{{ route('setting.' . $config['route']) }}" 
                   class="nav-link {{ $config['active'] ? 'active' : '' }}">
                    <i class="{{ $config['icon'] ?? 'fas fa-cog' }}"></i>
                    {{ $config['name'] }}
                </a>
            @endforeach
        </div>
    @endforeach
</nav>
@endif

6. Testing de la Implementación

A. Test Manual por Componente

# Para cada componente modificado, probar:

# 1. Acceso con plan básico
# 2. Acceso con plan profesional
# 3. Acceso con plan premium
# 4. Acceso con plan enterprise
# 5. Cambio de organización
# 6. Mensaje de restricción cuando no tiene acceso

B. Script de Verificación

#!/bin/bash
# scripts/test-organization-access.sh

echo "Testing Organization Access Control"

# Test Profile access (should work for all plans)
echo "Testing Profile access..."
curl -s "http://localhost/setting/profile" | grep -q "Profile" && echo "✓ Profile accessible" || echo "✗ Profile not accessible"

# Test Import access (should work for professional+)
echo "Testing Import access..."
curl -s "http://localhost/setting/import" | grep -q "Import" && echo "✓ Import accessible" || echo "✗ Import not accessible"

# Add more tests for each component

7. Deployment y Rollback

A. Plan de Deployment

# 1. Backup de archivos originales
mkdir -p backups/setting-components/$(date +%Y%m%d_%H%M%S)
cp -r app/Http/Livewire/Setting/ backups/setting-components/$(date +%Y%m%d_%H%M%S)/

# 2. Aplicar trait
cp app/Traits/OrganizationAccessControl.php app/Traits/

# 3. Aplicar modificaciones componente por componente
# (Seguir el patrón documentado)

# 4. Verificar que no hay errores de compilación
php artisan route:clear
php artisan view:clear
php artisan config:clear

B. Plan de Rollback

# En caso de problemas, revertir cambios
BACKUP_DIR="backups/setting-components/YYYYMMDD_HHMMSS"
cp -r $BACKUP_DIR/* app/Http/Livewire/Setting/

# Remover trait si es necesario
rm app/Traits/OrganizationAccessControl.php

# Limpiar cache
php artisan route:clear
php artisan view:clear
php artisan config:clear

8. Monitoreo Post-Implementación

A. Logs a Monitorear

// En cada componente, agregar logging
Log::info('Organization access check', [
    'user_id' => auth()->id(),
    'organization_id' => $this->organization_id,
    'configuration' => 'configuration.key',
    'access_granted' => $hasAccess
]);

B. Métricas de Acceso

-- Query para monitorear uso por plan
SELECT 
    o.plan_type,
    COUNT(*) as access_attempts,
    COUNT(CASE WHEN access_granted = 1 THEN 1 END) as successful_access
FROM organization_access_logs oal
JOIN organizations o ON oal.organization_id = o.id
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)
GROUP BY o.plan_type;

9. Documentación para Usuarios

A. Guía de Restricciones por Plan

Plan Configuraciones Disponibles
Básico Profile
Profesional Profile, Import General, Import SQL Server, Extraction Invupos, Login Security
Premium Todo lo anterior + Import Magaya/Fikable, Extraction Lightspeed, QuickBooks
Enterprise Todas las configuraciones

B. Mensajes de Error Personalizados

// Mensajes en resources/lang/es/validation.php
'organization_access_denied' => 'Su plan :plan no incluye acceso a :configuration. Actualice a :required_plan o superior.',
'configuration_restricted' => 'Esta configuración está restringida a planes: :plans',
'upgrade_required' => 'Se requiere actualización de plan para acceder a esta funcionalidad.',

Esta guía proporciona un enfoque sistemático para implementar el control de acceso organizacional manteniendo la simetría del diseño y sin afectar la funcionalidad existente.