Files
MexusNuevo/docs/ARQUITECTURA.md
José Jiménez Salinas a1dde36ddc CRANEGOO v3.0 — Plataforma completa de gestión para grúas y elevadores
13 módulos, 6 roles, 5 idiomas, 4 temas visuales
Creador: José Jiménez Salinas — Consultoría Alcaraz Salazar
2026-03-25 03:36:07 +00:00

259 lines
9.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CRANEGOO — Documentación Técnica para Desarrollador
## Arquitectura General
La app es un **Single-File React Component** (`src/App.jsx`) con todo el estado en memoria. No hay backend, base de datos ni API. Esto es un prototipo funcional que debe migrarse a una arquitectura cliente-servidor.
---
## Mapa del Archivo (por líneas aproximadas)
```
Líneas 1-18 → Constantes de color (C), estilos base
Líneas 19-148 → ROLES, EQ_TYPES, SVC_TYPES, PRIORITY, EMP_ROLES, EXCLUSIVE_ROLES, etc.
Líneas 149-230 → INIT_EMPLOYEES, INIT_CLIENTS (vacíos en versión limpia)
Líneas 231-410 → INIT_SERVICES, INIT_MAINTENANCE, INIT_SUPPLIERS, INIT_PURCHASE_ORDERS, etc.
Líneas 410-535 → TRANSLATIONS (90 claves × 5 idiomas), THEMES (4), INIT_COMPANY
Líneas 535-600 → Hooks (useIsMobile), GSComp (global styles dinámicos por tema)
Líneas 600-640 → SignaturePad component (canvas touch+mouse)
Líneas 640-680 → Field, Modal, StatusBadge, SvcStatusBadge, PriorityBadge
Líneas 680-850 → Calendar component (con festivos 2026, domingos, modales)
Líneas 850-1500 → ServicesModule (OpsServicesView, EmpServicesView, VentasServicesView, ClientServicesView)
Líneas 1500-2100 → InventoryModule (EquipmentForm, PartForm)
Líneas 2100-2500 → MaintenanceModule (OpsMaintenanceView, ClientMaintenanceView, EmpMaintenanceView)
Líneas 2500-2950 → ComprasModule (OCs, proveedores, fotos)
Líneas 2950-3400 → CotizacionesModule (catálogo, PDF, cláusulas)
Líneas 3400-4600 → ContableModule (6 pestañas: resumen, facturas, edocuenta, tesorería, SAT/IMSS, nómina)
Líneas 4600-4850 → PersonalModule (CRUD empleados)
Líneas 4850-5200 → ClientesModule (CRUD clientes, proyectos, appUsers)
Líneas 5200-5400 → Sidebar, Header
Líneas 5400-5850 → Dashboard (KPIs, panel financiero, alertas)
Líneas 5850-6000 → GPSModule
Líneas 6000-6500 → ManualesModule
Líneas 6500-6900 → ReportesModule (checklists grúa/elevador, firmas, PDF)
Líneas 6900-7200 → ConfigModule (idiomas, temas, empresa, fiscal, acerca de)
Líneas 7200-7300 → Login (usuario + contraseña)
Líneas 7300-7450 → App (estado global, routing)
```
---
## Estado Global (en App component)
Todos estos `useState` viven en `App()` y se pasan como props:
| State | Tipo | Descripción |
|-------|------|-------------|
| `role` | string | Rol activo (admin, operaciones, ventas, contador, empleado, cliente) |
| `mod` | string | Módulo activo del sidebar |
| `equipment` | array | Equipos (grúas, elevadores) |
| `parts` | array | Refacciones |
| `services` | array | Servicios programados |
| `maintenance` | array | Mantenimientos |
| `employees` | array | Empleados con credenciales |
| `clients` | array | Clientes con proyectos y appUsers |
| `invoices` | array | Facturas (ingreso/egreso) |
| `quotations` | array | Cotizaciones |
| `purchaseOrders` | array | Órdenes de compra |
| `suppliers` | array | Proveedores |
| `messages` | array | Mensajes internos |
| `accounts` | array | Cuentas bancarias |
| `credits` | array | Créditos y tarjetas |
| `transactions` | array | Movimientos bancarios |
| `obligations` | array | Obligaciones SAT/IMSS |
| `nomina` | array | Registros de nómina semanal |
| `lang` | string | Idioma activo (es-MX, en, ru, fr, es-ES) |
| `theme` | string | Tema visual (dark, light, mexus, blue) |
| `company` | object | Datos de la empresa |
| `clientLangs` | object | Idioma por cliente/obra |
| `loggedUserId` | string | ID del usuario logueado |
| `loggedUserProject` | string | Proyecto del cliente logueado |
---
## Flujo de Autenticación
```
Login → usuario + contraseña
├─ Match ADMIN_CREDS? → onLogin("admin", null, null)
├─ Match employee.user + employee.pass? → onLogin(emp.systemRole, emp.id, null)
├─ Match client appUser.user + appUser.pass? → onLogin("cliente", cli.id, project)
└─ Fallback: Match employee.email + employee.pass? → onLogin(emp.systemRole, emp.id, null)
```
**Para migración:** Reemplazar con JWT + bcrypt. La estructura de roles ya está definida.
---
## Modelo de Datos Clave
### Employee
```javascript
{
id: "EMP-001",
name: "Carlos Mendoza",
role: "Operador de Grúa", // Puesto laboral
systemRole: "operaciones", // Rol en la app (empleado|operaciones|ventas|contador)
phone, email, curp, nss,
emergencyContact, startDate,
status: "activo"|"inactivo",
user: "carlos.mendoza", // Login
pass: "mexus2024", // Contraseña (migrar a hash)
comprasAccess: false // Acceso al módulo de compras
}
```
### Client
```javascript
{
id: "CLI-001",
company: "Hermosillo y Asociados",
contact, phone, email, rfc, address,
projects: ["WESTIN Tijuana"],
status: "activo",
projectDetails: {
"WESTIN Tijuana": {
equipmentIds: ["MX-GT-001"],
notifEmails: ["correo@empresa.mx"],
appUsers: [
{ name: "Fernando", email: "f@h.mx", user: "fhermosillo", pass: "westin2024" }
] // Máximo 2 por proyecto
}
}
}
```
### Service
```javascript
{
id: "SVC-001",
type: "elevacion_grua", // De SVC_TYPES
clientName, project, equipmentId,
date, endDate, timeSlot: "07:00-15:00",
priority: "alta"|"media"|"baja",
status: "pendiente"|"aprobado"|"en_proceso"|"en_sitio"|"completado"|"rechazado",
assignedTo: ["EMP-001", "EMP-005"],
tracking: {
inSite: false,
inSiteTime: null,
startTime: null, endTime: null,
photosStart: [], photosDuring: [], photosEnd: [],
employeeNotes: "",
checklist: null, // Se genera al iniciar (GRUA o ELEVADOR)
empSignature: null, // PNG data URL de firma
empSignName: "",
approverSignature: null,
approverSignName: "",
reportApproved: false,
reportApprovedAt: null,
opsNotes: ""
}
}
```
### Account (Tesorería)
```javascript
{
id: "CTA-001",
name: "BBVA Empresarial Pesos",
bank: "BBVA",
type: "pesos"|"dolares",
number: "**** 4521",
balance: 485000, // Se actualiza con transacciones
clabe: "012180001234567890"
}
```
### Obligation (SAT/IMSS)
```javascript
{
id: "OBL-001",
entity: "SAT"|"IMSS"|"Estatal",
type: "ISR Retenciones",
period: "Marzo 2026",
amount: 18500,
dueDate: "2026-04-17",
status: "pendiente"|"pagado",
receipt: null // { name, data } archivo subido
}
```
### Nomina
```javascript
{
id: "NOM-001",
week: "Semana 9 (24 Feb — 2 Mar)",
period: "2026-03-02",
totalBruto: 95000, totalNeto: 78500,
isr: 8500, imss: 4200, infonavit: 3800,
employees: 6,
timbrada: true, timbreXML: { name, date },
complemento: false, compXML: null,
receipt: null,
notes: ""
}
```
---
## Permisos — Tabla de Referencia
### canEdit / canOperate / canGrantAccess (ContableModule)
```javascript
const canEdit = isAdmin || isContador; // Editar/eliminar cuentas, créditos, obligaciones, nómina
const canOperate = isAdmin || isContador; // Crear, registrar transacciones, subir comprobantes
const canGrantAccess = isAdmin; // Activar visualización a otros roles
```
### Compras — Acciones de pago
```javascript
(role === "admin" || role === "contador") // Marcar pagado, subir comprobante
(role === "admin" || role === "operaciones") // Cancelar/eliminar OC
```
### Roles exclusivos en Scheduling
```javascript
const EXCLUSIVE_ROLES = ["Operador", "Maniobrista", "Operador de Grúa", ...];
// Si un operador tiene cualquier asignación en un día → bloqueado TODO el día
// Otros roles (Técnicos, Montadores): disponibles fuera de sus slots asignados
```
---
## Internacionalización
```javascript
const t = (key) => TRANSLATIONS[key]?.[activeLang] || TRANSLATIONS[key]?.["es-MX"] || key;
// activeLang se resuelve:
// 1. Si es cliente → clientLangs[clientId+"|"+project] || clientLangs[clientId] || lang
// 2. Todos los demás → lang (idioma global del sistema)
```
Claves traducidas: sidebar (13), login (6), common (20), roles (6), dashboard (8), services (6), contable (5), config (10), priority (3), reports (5).
---
## Generación de PDF
Se usa `window.open()` + `document.write()` para generar HTML imprimible. Los PDFs incluyen:
- Logo de la empresa (del cliente, no CRANEGOO)
- Checklist completo con OK/Defecto
- Firmas digitales (imágenes PNG incrustadas)
- Datos del equipo, cliente, inspector
**Para migración:** Reemplazar con librería como `jsPDF` o generación server-side.
---
## Notas para el Programador
1. **Todo el estado es en memoria** — al recargar se pierde. Prioridad #1: base de datos.
2. **Las contraseñas están en texto plano** — migrar a bcrypt + JWT inmediatamente.
3. **Las firmas son PNG data URLs** — almacenar en object storage (S3/Firebase Storage).
4. **Los archivos subidos (XML, fotos) son data URLs en memoria** — migrar a file storage.
5. **El CSS es inline** — considerar migrar a Tailwind CSS o CSS modules.
6. **No hay tests** — agregar tests unitarios y de integración.
7. **El routing es un switch/case interno** — migrar a React Router.
8. **No hay error boundaries** — agregar para producción.