- 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>
9.7 KiB
9.7 KiB
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 ú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
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
- Agricultura
- Alimentación y Bebidas
- Automotriz
- Comercio Mayorista
- Comercio Minorista
- Construcción
- Consultoría
- Educación
- Energía
- Farmacéutico
- Financiero
- Hotelería
- Inmobiliario
- Logística
- Manufactura
- Minería
- Publicidad
- Salud
- Seguros
- Software
- Telecomunicaciones
- Textil
- Transporte
- 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
# 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
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
// 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
// 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:
// 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
// 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