Files
horux-strategy-platform/docs/10-administracion.md
Torch2196 4c3dc94ff2 Initial commit: Horux Strategy Platform
- Laravel 11 backend with API REST
- React 18 + TypeScript + Vite frontend
- Multi-parser architecture for accounting systems (CONTPAQi, Aspel, SAP)
- 27+ financial metrics calculation
- PDF report generation with Browsershot
- Complete documentation (10 documents)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 22:24:00 -06:00

393 lines
9.7 KiB
Markdown

# 10. Panel de Administración
## Descripción
El panel de administración permite a usuarios con rol **admin** gestionar la configuración global del sistema.
---
## Acceso
- **URL**: `/admin`
- **Rol requerido**: `admin`
- **Middleware**: `auth:sanctum`, `role:admin`
---
## Secciones
### 1. Gestión de Usuarios
**Ruta**: `/admin/usuarios`
Permite crear, editar y eliminar usuarios del sistema.
| Campo | Descripción |
|-------|-------------|
| nombre | Nombre completo |
| email | Email único |
| password | Contraseña (mínimo 8 caracteres) |
| role | admin, analista, cliente, empleado |
| cliente_id | Cliente asignado (requerido para cliente/empleado) |
| activo | Estado del usuario |
#### API Endpoints
```
GET /api/admin/usuarios - Listar usuarios
POST /api/admin/usuarios - Crear usuario
GET /api/admin/usuarios/{id} - Ver usuario
PUT /api/admin/usuarios/{id} - Actualizar usuario
DELETE /api/admin/usuarios/{id} - Eliminar usuario
```
#### Ejemplo de creación
```bash
curl -X POST /api/admin/usuarios \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"nombre": "Juan Pérez",
"email": "juan@empresa.com",
"password": "password123",
"role": "analista"
}'
```
---
### 2. Gestión de Giros
**Ruta**: `/admin/giros`
Catálogo de giros de negocio (industrias).
| Campo | Descripción |
|-------|-------------|
| nombre | Nombre del giro |
| activo | Estado |
#### Giros predeterminados
1. Agricultura
2. Alimentación y Bebidas
3. Automotriz
4. Comercio Mayorista
5. Comercio Minorista
6. Construcción
7. Consultoría
8. Educación
9. Energía
10. Farmacéutico
11. Financiero
12. Hotelería
13. Inmobiliario
14. Logística
15. Manufactura
16. Minería
17. Publicidad
18. Salud
19. Seguros
20. Software
21. Telecomunicaciones
22. Textil
23. Transporte
24. Turismo
#### API Endpoints
```
GET /api/admin/giros - Listar giros
POST /api/admin/giros - Crear giro
PUT /api/admin/giros/{id} - Actualizar giro
DELETE /api/admin/giros/{id} - Eliminar giro
```
---
### 3. Gestión de Umbrales
**Ruta**: `/admin/umbrales`
Configuración de umbrales para el sistema de semáforos.
| Campo | Descripción |
|-------|-------------|
| metrica | Nombre de la métrica |
| muy_positivo | Umbral verde oscuro |
| positivo | Umbral verde claro |
| neutral | Umbral amarillo |
| negativo | Umbral naranja |
| muy_negativo | Umbral rojo |
| giro_id | Giro específico (null = general) |
#### Umbrales por defecto
| Métrica | Muy Positivo | Positivo | Neutral | Negativo |
|---------|--------------|----------|---------|----------|
| margen_bruto | ≥40% | ≥30% | ≥20% | ≥10% |
| margen_ebitda | ≥25% | ≥15% | ≥10% | ≥5% |
| margen_operativo | ≥20% | ≥12% | ≥8% | ≥4% |
| margen_neto | ≥15% | ≥10% | ≥5% | ≥2% |
| roic | ≥20% | ≥15% | ≥10% | ≥5% |
| roe | ≥20% | ≥15% | ≥10% | ≥5% |
| roa | ≥12% | ≥8% | ≥5% | ≥2% |
| current_ratio | ≥2.0 | ≥1.5 | ≥1.2 | ≥1.0 |
| quick_ratio | ≥1.5 | ≥1.0 | ≥0.8 | ≥0.5 |
| net_debt_ebitda | ≤1.0 | ≤2.0 | ≤3.0 | ≤4.0 |
| interest_coverage | ≥8.0 | ≥5.0 | ≥3.0 | ≥1.5 |
#### API Endpoints
```
GET /api/admin/umbrales - Listar umbrales
POST /api/admin/umbrales - Crear umbral
PUT /api/admin/umbrales/{id} - Actualizar umbral
DELETE /api/admin/umbrales/{id} - Eliminar umbral
```
#### Ejemplo: Umbral específico por giro
```bash
# Crear umbral de margen bruto específico para Hotelería
curl -X POST /api/admin/umbrales \
-H "Authorization: Bearer {token}" \
-d '{
"metrica": "margen_bruto",
"muy_positivo": 0.50,
"positivo": 0.40,
"neutral": 0.30,
"negativo": 0.20,
"giro_id": 12
}'
```
---
### 4. Reglas de Mapeo
**Ruta**: `/admin/reglas-mapeo`
Reglas para clasificar cuentas automáticamente según el sistema contable.
| Campo | Descripción |
|-------|-------------|
| sistema_origen | contpaqi, aspel, sap, etc. |
| cuenta_padre_codigo | Código de cuenta padre |
| rango_inicio | Inicio del rango de códigos |
| rango_fin | Fin del rango |
| patron_regex | Patrón regex alternativo |
| reporte_contable_id | Balance General o Estado de Resultados |
| categoria_contable_id | Categoría destino |
| prioridad | Mayor número = mayor prioridad |
| activo | Estado de la regla |
#### Reglas CONTPAQi predeterminadas
| Cuenta Padre | Rango | Categoría |
|--------------|-------|-----------|
| 001-100-000 | 101-000-000 a 154-999-999 | Activos Circulantes |
| 001-200-000 | 155-000-000 a 199-999-999 | Activos No Circulantes |
| 002-100-000 | 200-000-000 a 209-999-999 | Pasivo Circulante |
| 002-200-000 | 210-000-000 a 220-999-999 | Pasivo No Circulante |
| - | 30X-XXX-XXX | Capital Social |
| - | 310-XXX-XXX | Pérdidas Anteriores |
| - | 311-XXX-XXX | Utilidades Anteriores |
| - | 40X-XXX-XXX | Ingresos |
| - | 5XX-XXX-XXX | Gastos Operativos |
| - | 6XX-XXX-XXX | Otros Gastos |
| - | 7XX-XXX-XXX | Gastos Financieros |
#### API Endpoints
```
GET /api/admin/reglas-mapeo - Listar reglas
POST /api/admin/reglas-mapeo - Crear regla
PUT /api/admin/reglas-mapeo/{id} - Actualizar regla
DELETE /api/admin/reglas-mapeo/{id} - Eliminar regla
```
#### Ejemplo: Agregar regla para Aspel
```bash
curl -X POST /api/admin/reglas-mapeo \
-H "Authorization: Bearer {token}" \
-d '{
"sistema_origen": "aspel",
"patron_regex": "^1[0-4]\\d{2}",
"reporte_contable_id": 1,
"categoria_contable_id": 1,
"prioridad": 10,
"activo": true
}'
```
---
## Interfaz de Usuario
### Layout Admin
```tsx
// src/pages/Admin/Layout.tsx
export default function AdminLayout({ children }) {
const menuItems = [
{ path: '/admin/usuarios', label: 'Usuarios', icon: UsersIcon },
{ path: '/admin/giros', label: 'Giros', icon: BuildingIcon },
{ path: '/admin/umbrales', label: 'Umbrales', icon: ChartIcon },
{ path: '/admin/reglas-mapeo', label: 'Reglas Mapeo', icon: MapIcon },
];
return (
<div className="flex">
<aside className="w-64 bg-horux-dark min-h-screen p-4">
<h2 className="text-white text-xl font-bold mb-6">Administración</h2>
<nav>
{menuItems.map((item) => (
<NavLink
key={item.path}
to={item.path}
className={({ isActive }) =>
`flex items-center px-4 py-2 rounded ${
isActive ? 'bg-horux-primary text-white' : 'text-gray-300 hover:bg-gray-700'
}`
}
>
<item.icon className="w-5 h-5 mr-3" />
{item.label}
</NavLink>
))}
</nav>
</aside>
<main className="flex-1 p-8">{children}</main>
</div>
);
}
```
### Tabla CRUD genérica
```tsx
// src/components/admin/CrudTable.tsx
interface CrudTableProps<T> {
data: T[];
columns: Column<T>[];
onEdit: (item: T) => void;
onDelete: (item: T) => void;
onCreate: () => void;
title: string;
}
export default function CrudTable<T extends { id: number }>({
data,
columns,
onEdit,
onDelete,
onCreate,
title,
}: CrudTableProps<T>) {
return (
<div>
<div className="flex justify-between items-center mb-6">
<h1 className="text-2xl font-bold">{title}</h1>
<button
onClick={onCreate}
className="bg-horux-primary text-white px-4 py-2 rounded hover:bg-horux-secondary"
>
+ Nuevo
</button>
</div>
<table className="w-full border-collapse">
<thead>
<tr className="bg-gray-100">
{columns.map((col) => (
<th key={col.key} className="p-3 text-left">{col.label}</th>
))}
<th className="p-3 text-right">Acciones</th>
</tr>
</thead>
<tbody>
{data.map((item) => (
<tr key={item.id} className="border-b hover:bg-gray-50">
{columns.map((col) => (
<td key={col.key} className="p-3">
{col.render ? col.render(item) : item[col.key]}
</td>
))}
<td className="p-3 text-right">
<button
onClick={() => onEdit(item)}
className="text-blue-600 hover:text-blue-800 mr-3"
>
Editar
</button>
<button
onClick={() => onDelete(item)}
className="text-red-600 hover:text-red-800"
>
Eliminar
</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
```
---
## Auditoría
Todas las acciones administrativas se registran en el log:
```php
// Ejemplo en AdminController
Log::channel('admin')->info('Usuario creado', [
'admin_id' => auth()->id(),
'user_id' => $user->id,
'email' => $user->email,
'ip' => request()->ip(),
]);
```
### Configuración de logging
```php
// config/logging.php
'channels' => [
'admin' => [
'driver' => 'daily',
'path' => storage_path('logs/admin.log'),
'level' => 'info',
'days' => 90,
],
],
```
---
## Permisos por Rol
| Acción | Admin | Analista | Cliente | Empleado |
|--------|-------|----------|---------|----------|
| Gestionar usuarios | ✓ | ✗ | ✗ | ✗ |
| Gestionar giros | ✓ | ✗ | ✗ | ✗ |
| Gestionar umbrales | ✓ | ✗ | ✗ | ✗ |
| Gestionar reglas mapeo | ✓ | ✗ | ✗ | ✗ |
| Ver todos los clientes | ✓ | ✓ | ✗ | ✗ |
| Crear clientes | ✓ | ✓ | ✗ | ✗ |
| Subir balanzas | ✓ | ✓ | ✗ | ✗ |
| Generar reportes | ✓ | ✓ | ✗ | ✗ |
| Ver dashboard propio | ✓ | ✓ | ✓ | * |
| Descargar PDF | ✓ | ✓ | ✓ | * |
\* Según permisos configurados