# 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.