📚 Documentación Técnica

Especificaciones Técnicas Completas del Sistema AgenteLegal

🏗️Arquitectura del Sistema

AgenteLegal utiliza una arquitectura en capas moderna diseñada para escalabilidad, mantenibilidad y rendimiento óptimo en el cloud.

🎯 Diagrama de Arquitectura

🖥️ Capa de Presentación

Portal Firma Legal | Portal Cliente | Landing Page

React.js + Material-UI + Tailwind CSS

⚙️ Capa de Aplicación

API REST | Autenticación JWT | Sistema de Facturación

Node.js + Express + Middlewares de Seguridad

🗄️ Capa de Datos

PostgreSQL | Migraciones | Índices Optimizados

Relaciones complejas + Triggers + Funciones

☁️ Infraestructura Cloud

Google Cloud Run | Cloud SQL | Cloud Storage

Auto-scaling + Load Balancing + CDN

Características Arquitectónicas

  • Microservicios: Separación entre frontend, backend y servicios auxiliares
  • Stateless: Backend sin estado para mejor escalabilidad
  • Event-driven: Notificaciones y procesos asíncronos
  • Multi-tenant: Soporte para múltiples bufetes legales
  • Cloud-native: Diseñado específicamente para la nube

Stack Tecnológico

Tecnologías Principales

🖥️ Frontend

  • React 18 - Biblioteca principal de UI
  • Material-UI v5 - Componentes de diseño
  • Tailwind CSS - Utilidades de estilo
  • React Router - Navegación SPA
  • Axios - Cliente HTTP

⚙️ Backend

  • Node.js 18 LTS - Runtime de JavaScript
  • Express.js - Framework web
  • jsonwebtoken - Autenticación JWT
  • bcrypt - Hash de contraseñas
  • multer - Upload de archivos

🗄️ Base de Datos

  • PostgreSQL 15 - Base de datos principal
  • pg - Driver de Node.js
  • db-migrate - Migraciones
  • Triggers y Functions - Lógica de DB

☁️ Cloud & DevOps

  • Google Cloud Run - Hosting serverless
  • Google Cloud SQL - Base de datos managed
  • Google Cloud Storage - Almacenamiento de archivos
  • Docker - Containerización

💰 Pagos & Facturación

  • PayPal SDK - Procesamiento de pagos
  • Puppeteer - Generación de PDF
  • Handlebars - Templates de facturas
  • Transferencias Bancarias - Verificación manual

📧 Notificaciones

  • Nodemailer - Envío de emails
  • Gmail SMTP - Proveedor de email
  • Rich Text Editor - Templates personalizables
  • Cron Jobs - Notificaciones automáticas

Versiones y Compatibilidad

Tecnología Versión Actual Versión Mínima Estado
Node.js 18.17.0 LTS 16.x ✅ Estable
React 18.2.0 17.x ✅ Estable
PostgreSQL 15.3 13.x ✅ Estable
Express 4.18.2 4.17.x ✅ Estable

🗄️Esquema de Base de Datos

Diseño del Esquema

La base de datos utiliza un diseño relacional normalizado con énfasis en la integridad referencial y optimización de consultas.

Tablas Principales

SQL -- Usuarios del sistema CREATE TABLE users ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), email VARCHAR(255) UNIQUE NOT NULL, password_hash VARCHAR(255) NOT NULL, first_name VARCHAR(100) NOT NULL, last_name VARCHAR(100) NOT NULL, role VARCHAR(50) NOT NULL CHECK (role IN ('admin', 'lawyer', 'assistant', 'client')), is_active BOOLEAN DEFAULT true, plan_type VARCHAR(50) DEFAULT 'trial', max_sociedades INTEGER DEFAULT 10, current_sociedades_count INTEGER DEFAULT 0, trial_start_date TIMESTAMP, trial_end_date TIMESTAMP, subscription_status VARCHAR(50) DEFAULT 'trial', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- Clientes (sociedades) CREATE TABLE clients ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID REFERENCES users(id), name VARCHAR(255) NOT NULL, registration_number VARCHAR(100), entity_type VARCHAR(100), status VARCHAR(50) DEFAULT 'AL DÍA', incorporation_date DATE, -- RUC con formato panameño ruc VARCHAR(50), ruc_folio VARCHAR(20), ruc_periodo_fiscal INTEGER, ruc_ano_inscripcion INTEGER, ruc_completo VARCHAR(50) GENERATED ALWAYS AS ( CASE WHEN ruc_folio IS NOT NULL AND ruc_periodo_fiscal IS NOT NULL AND ruc_ano_inscripcion IS NOT NULL THEN ruc_folio || '-' || ruc_periodo_fiscal || '-' || ruc_ano_inscripcion ELSE ruc END ) STORED, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- Personas (directores, beneficiarios) CREATE TABLE persons ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), identification_number VARCHAR(50) NOT NULL, identification_type VARCHAR(50) NOT NULL, first_name VARCHAR(100) NOT NULL, last_name VARCHAR(100) NOT NULL, email VARCHAR(255), phone VARCHAR(50), nationality VARCHAR(100), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- Directores CREATE TABLE directors ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), client_id UUID REFERENCES clients(id) ON DELETE CASCADE, person_id UUID REFERENCES persons(id), appointment_date DATE, is_active BOOLEAN DEFAULT true, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- Beneficiarios finales CREATE TABLE beneficial_owners ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), client_id UUID REFERENCES clients(id) ON DELETE CASCADE, person_id UUID REFERENCES persons(id), ownership_percentage DECIMAL(5,2), is_active BOOLEAN DEFAULT true, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );

Sistema de Documentos

SQL -- Documentos CREATE TABLE entity_documents ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), client_id UUID REFERENCES clients(id) ON DELETE CASCADE, person_id UUID REFERENCES persons(id), document_type VARCHAR(100) NOT NULL, file_name VARCHAR(255) NOT NULL, file_path VARCHAR(500) NOT NULL, file_size INTEGER, upload_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP, status VARCHAR(50) DEFAULT 'pending', reviewed_by UUID REFERENCES users(id), review_date TIMESTAMP, review_comments TEXT );

Sistema de Facturación

SQL -- Facturas CREATE TABLE invoices ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID REFERENCES users(id), invoice_number VARCHAR(50) UNIQUE NOT NULL, amount DECIMAL(10,2) NOT NULL, currency VARCHAR(3) DEFAULT 'USD', status VARCHAR(50) DEFAULT 'pending', issue_date DATE DEFAULT CURRENT_DATE, due_date DATE DEFAULT (CURRENT_DATE + INTERVAL '15 days'), payment_date DATE, payment_method VARCHAR(50), payment_reference VARCHAR(100), pdf_path VARCHAR(500), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- Transacciones de balance de clientes CREATE TABLE balance_transactions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), client_id UUID REFERENCES clients(id) ON DELETE CASCADE, transaction_type VARCHAR(10) CHECK (transaction_type IN ('charge', 'payment')), amount DECIMAL(10,2) NOT NULL, description TEXT NOT NULL, due_date DATE, payment_date DATE, payment_method VARCHAR(50), payment_reference VARCHAR(100), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, created_by UUID REFERENCES users(id) );

Índices y Optimizaciones

SQL -- Índices para optimización de consultas CREATE INDEX idx_clients_user_id ON clients(user_id); CREATE INDEX idx_clients_ruc_completo ON clients(ruc_completo); CREATE INDEX idx_documents_client_id ON entity_documents(client_id); CREATE INDEX idx_documents_status ON entity_documents(status); CREATE INDEX idx_balance_client_id ON balance_transactions(client_id); CREATE INDEX idx_persons_identification ON persons(identification_number); -- Índice para búsquedas de texto CREATE INDEX idx_clients_name_trgm ON clients USING gin(name gin_trgm_ops); CREATE INDEX idx_persons_name_trgm ON persons USING gin((first_name || ' ' || last_name) gin_trgm_ops);

Funciones y Triggers

SQL -- Función para validar RUC panameño CREATE OR REPLACE FUNCTION validate_panama_ruc(ruc_text VARCHAR) RETURNS BOOLEAN AS $$ BEGIN RETURN ruc_text ~ '^[0-9]{6,10}-[1-9]-[0-9]{4,6}$'; END; $$ LANGUAGE plpgsql; -- Trigger para actualizar timestamps CREATE OR REPLACE FUNCTION update_timestamp() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = CURRENT_TIMESTAMP; RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER update_clients_timestamp BEFORE UPDATE ON clients FOR EACH ROW EXECUTE FUNCTION update_timestamp();

🔌API Endpoints

Estructura de la API

La API RESTful está organizada por recursos y sigue las convenciones estándar de HTTP.

Autenticación

POST /api/auth/login

Autenticación de usuario con email y contraseña

POST /api/auth/register

Registro de nuevo usuario

POST /api/auth/forgot-password

Solicitud de restablecimiento de contraseña

Gestión de Clientes

GET /api/clients

Obtener lista de clientes del usuario

POST /api/clients

Crear nuevo cliente

GET /api/clients/:id

Obtener detalles de cliente específico

PUT /api/clients/:id

Actualizar información de cliente

Gestión de Documentos

POST /api/documents/upload

Subir documento al sistema

GET /api/documents/pending-review

Obtener documentos pendientes de revisión

PUT /api/documents/:id/review

Aprobar o rechazar documento

Sistema de Facturación

GET /api/billing/invoices

Obtener facturas del usuario

POST /api/billing/create-subscription

Crear nueva suscripción

POST /api/billing/confirm-payment

Confirmar pago manual

Ejemplo de Respuesta API

JSON { "success": true, "data": { "id": "123e4567-e89b-12d3-a456-426614174000", "name": "Sociedad Ejemplo S.A.", "registration_number": "12345", "ruc_completo": "155767268-2-2025", "status": "AL DÍA", "directors": [ { "id": "dir_123", "person_id": "person_456", "full_name": "Juan Pérez", "appointment_date": "2025-01-01" } ], "balance": { "total_charges": 150.00, "total_payments": 100.00, "current_balance": 50.00 } }, "pagination": { "page": 1, "limit": 20, "total": 5, "pages": 1 } }

Códigos de Estado HTTP

Código Significado Uso
200 OK Operación exitosa
201 Created Recurso creado exitosamente
400 Bad Request Datos inválidos en la solicitud
401 Unauthorized No autenticado
403 Forbidden Sin permisos suficientes
404 Not Found Recurso no encontrado
500 Internal Server Error Error interno del servidor

🔐Sistema de Autenticación

Autenticación JWT

El sistema utiliza JSON Web Tokens (JWT) para autenticación stateless y segura.

Flujo de Autenticación

  1. Usuario envía credenciales (email/password)
  2. Servidor valida credenciales contra la base de datos
  3. Si son válidas, genera token JWT firmado
  4. Cliente almacena token en localStorage
  5. Token se envía en header Authorization en requests
  6. Servidor valida token en cada request protegido
JavaScript // Middleware de autenticación const authenticateToken = (req, res, next) => { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; if (!token) { return res.status(401).json({ error: 'Token de acceso requerido' }); } jwt.verify(token, process.env.JWT_SECRET, (err, user) => { if (err) { return res.status(403).json({ error: 'Token inválido' }); } req.user = user; next(); }); };

Estructura del Token

JSON { "header": { "alg": "HS256", "typ": "JWT" }, "payload": { "userId": "123e4567-e89b-12d3-a456-426614174000", "email": "user@example.com", "role": "lawyer", "iat": 1642780800, "exp": 1642867200 } }

Roles y Permisos

Rol Permisos Recursos Accesibles
admin Todos los permisos Todo el sistema
lawyer Gestión completa de clientes Clientes, documentos, balances
assistant Solo lectura y upload Clientes (lectura), documentos (upload)
client Solo sus propios datos Portal de cliente limitado

Seguridad de Contraseñas

JavaScript // Hash de contraseña con bcrypt const hashPassword = async (password) => { const saltRounds = 12; return await bcrypt.hash(password, saltRounds); }; // Verificación de contraseña const verifyPassword = async (password, hash) => { return await bcrypt.compare(password, hash); }; // Políticas de contraseña const passwordPolicy = { minLength: 8, requireUppercase: true, requireLowercase: true, requireNumbers: true, requireSpecialChars: true };

💰Sistema de Facturación (API)

Arquitectura del Sistema de Pagos

Sistema híbrido que combina PayPal y transferencias bancarias manuales, diseñado para el mercado panameño.

Servicios Principales

JavaScript // hybridSubscriptionService.js class HybridSubscriptionService { async createSubscription(userId, plan = 'basic') { // Crear suscripción con período de prueba de 14 días const trialEndDate = new Date(); trialEndDate.setDate(trialEndDate.getDate() + 14); await this.updateUserSubscription(userId, { plan_type: plan, max_sociedades: plan === 'trial' ? 10 : (plan === 'basic' ? 100 : 100), trial_start_date: new Date(), trial_end_date: trialEndDate, subscription_status: 'trial' }); return { status: 'trial_started', trial_end: trialEndDate }; } async createInvoice(userId) { const result = await pool.query( 'SELECT create_next_invoice($1) as invoice_id', [userId] ); return result.rows[0].invoice_id; } async confirmManualPayment(invoiceId, paymentData) { await pool.query(` UPDATE invoices SET status = 'paid', payment_date = CURRENT_DATE, payment_method = $2, payment_reference = $3 WHERE id = $1 `, [invoiceId, paymentData.method, paymentData.reference]); // Activar suscripción del usuario await this.activateUserSubscription(paymentData.userId); } }

Generación de Facturas PDF

JavaScript // invoiceService.js const generateInvoicePDF = async (invoiceId) => { const invoiceData = await getInvoiceData(invoiceId); const htmlTemplate = ` Factura {{invoice_number}}

FACTURA

{{invoice_number}} | {{issue_date}}

{{company_name}}

RUC: {{company_ruc}}

Instrucciones de Pago

Banco: {{bank_name}}

Cuenta: {{account_number}}

Referencia: {{invoice_number}}

`; const html = Handlebars.compile(htmlTemplate)(invoiceData); const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.setContent(html); const pdf = await page.pdf({ format: 'A4' }); await browser.close(); return pdf; };

Funciones de Base de Datos

SQL -- Función para crear la siguiente factura CREATE OR REPLACE FUNCTION create_next_invoice(user_uuid UUID) RETURNS UUID AS $$ DECLARE new_invoice_id UUID; invoice_num VARCHAR(50); user_plan VARCHAR(50); plan_amount DECIMAL(10,2); BEGIN -- Obtener plan del usuario SELECT plan_type INTO user_plan FROM users WHERE id = user_uuid; -- Determinar monto según plan plan_amount := CASE WHEN user_plan = 'trial' THEN 0.00 WHEN user_plan = 'basic' THEN 150.00 ELSE 150.00 -- Default to basic plan pricing END; -- Generar número de factura SELECT 'AL-' || EXTRACT(YEAR FROM CURRENT_DATE) || '-' || LPAD(COALESCE(MAX(CAST(SPLIT_PART(invoice_number, '-', 3) AS INTEGER)), 0) + 1, 4, '0') INTO invoice_num FROM invoices WHERE invoice_number LIKE 'AL-' || EXTRACT(YEAR FROM CURRENT_DATE) || '-%'; -- Crear factura INSERT INTO invoices (user_id, invoice_number, amount, status) VALUES (user_uuid, invoice_num, plan_amount, 'pending') RETURNING id INTO new_invoice_id; RETURN new_invoice_id; END; $$ LANGUAGE plpgsql;

Monitoreo de Suscripciones

JavaScript // Cron job para verificar trials expirados const checkExpiredTrials = async () => { const expiredUsers = await pool.query(` SELECT id, email, trial_end_date FROM users WHERE subscription_status = 'trial' AND trial_end_date < CURRENT_DATE `); for (const user of expiredUsers.rows) { // Suspender cuenta await pool.query(` UPDATE users SET subscription_status = 'suspended' WHERE id = $1 `, [user.id]); // Enviar notificación await sendTrialExpiredEmail(user.email); console.log(`Usuario ${user.email} suspendido por trial expirado`); } };

🚀Deployment y DevOps

Google Cloud Run Deployment

El sistema está desplegado en Google Cloud Run para auto-scaling y alta disponibilidad.

Servicios Desplegados

Servicio URL Memoria CPU
Backend API agente-legal-api-*.run.app 1Gi 1 vCPU
Portal Firma Legal agente-legal-law-firm-portal-*.run.app 512Mi 1 vCPU
Portal Cliente agente-legal-client-portal-*.run.app 512Mi 1 vCPU

Comandos de Deployment

bash # Deploy Backend API gcloud run deploy agente-legal-api \ --source ./backend \ --platform managed \ --region us-south1 \ --project agentelegal-469415 \ --allow-unauthenticated \ --port 8080 \ --memory 1Gi \ --cpu 1 \ --max-instances 10 \ --concurrency 80 \ --timeout 300 \ --service-account=agente-legal-api@agentelegal-469415.iam.gserviceaccount.com # Deploy Frontend Law Firm Portal gcloud run deploy agente-legal-law-firm-portal \ --source ./frontend \ --platform managed \ --region us-south1 \ --project agentelegal-469415 \ --allow-unauthenticated \ --port 8080 \ --memory 512Mi # Deploy Client Portal gcloud run deploy agente-legal-client-portal \ --source ./client-portal \ --platform managed \ --region us-south1 \ --project agentelegal-469415 \ --allow-unauthenticated \ --port 8080 \ --memory 512Mi

Dockerfile

dockerfile # Backend Dockerfile FROM node:18-alpine WORKDIR /app # Instalar dependencias COPY package*.json ./ RUN npm ci --only=production # Copiar código fuente COPY . . # Exponer puerto EXPOSE 8080 # Variables de entorno para producción ENV NODE_ENV=production ENV PORT=8080 # Comando de inicio CMD ["npm", "start"]

Variables de Entorno en Cloud Run

bash # Configurar variables de entorno gcloud run services update agente-legal-api \ --region us-south1 \ --set-env-vars NODE_ENV=production,GCS_PROJECT_ID=agentelegal-469415,GCS_BUCKET_NAME=agente-legal-documents \ --service-account=agente-legal-api@agentelegal-469415.iam.gserviceaccount.com

Monitoreo y Logs

Utilización de Google Cloud Logging y Monitoring para observabilidad:

  • Logs de aplicación: Disponibles en Cloud Logging
  • Métricas de rendimiento: CPU, memoria, latencia
  • Alertas: Configuradas para errores críticos
  • Dashboards: Cloud Monitoring para visualización
💡 Auto-scaling: Cloud Run escala automáticamente de 0 a 10 instancias basado en el tráfico.

🛡️Seguridad

Medidas de Seguridad Implementadas

Autenticación y Autorización

  • JWT con expiración: Tokens con tiempo de vida limitado
  • Roles basados en permisos: Control granular de acceso
  • Refresh tokens: Renovación segura de sesiones
  • Rate limiting: Protección contra ataques de fuerza bruta

Protección de Datos

  • Encriptación en tránsito: HTTPS/TLS en todas las comunicaciones
  • Encriptación en reposo: Datos sensibles encriptados en BD
  • Hash de contraseñas: bcrypt con salt rounds altos
  • Sanitización de inputs: Validación y limpieza de datos

Middleware de Seguridad

JavaScript // Configuración de seguridad express app.use(helmet()); // Headers de seguridad app.use(cors({ origin: process.env.ALLOWED_ORIGINS?.split(',') || 'http://localhost:3000', credentials: true })); // Rate limiting const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutos max: 100, // máximo 100 requests por IP message: 'Demasiadas solicitudes, intente más tarde' }); app.use('/api/', limiter); // Validación de entrada app.use(express.json({ limit: '10mb' })); app.use(mongoSanitize()); // Prevenir inyección NoSQL

Validación de Datos

JavaScript // Esquemas de validación con Joi const clientSchema = Joi.object({ name: Joi.string().min(2).max(255).required(), ruc: Joi.string().pattern(/^[0-9]{6,10}-[1-9]-[0-9]{4,6}$/), email: Joi.string().email(), phone: Joi.string().pattern(/^\+?[1-9]\d{1,14}$/) }); // Middleware de validación const validateClient = (req, res, next) => { const { error } = clientSchema.validate(req.body); if (error) { return res.status(400).json({ error: 'Datos inválidos', details: error.details[0].message }); } next(); };

Auditoría y Logs de Seguridad

  • Logs de acceso: Registro de todas las autenticaciones
  • Logs de cambios: Auditoría de modificaciones de datos
  • Detección de anomalías: Alertas por patrones sospechosos
  • Retention policies: Conservación de logs por compliance
🔒 Configuraciones Críticas de Seguridad:
  • Cambiar JWT_SECRET en producción
  • Configurar HTTPS con certificados válidos
  • Habilitar firewall de base de datos
  • Configurar backup encriptado
  • Implementar 2FA para administradores

🔧Guía de Desarrollo

Configuración del Entorno de Desarrollo

Prerequisitos

  • Node.js 18.x LTS
  • PostgreSQL 13+
  • Git
  • Docker (opcional)

Instalación Local

bash # Clonar repositorio git clone https://github.com/tu-organizacion/agentelegal.git cd agentelegal # Instalar dependencias del backend cd backend npm install # Instalar dependencias del frontend cd ../frontend npm install # Instalar dependencias del portal de clientes cd ../client-portal npm install # Configurar variables de entorno cp .env.example .env.development # Editar .env.development con tus configuraciones locales # Ejecutar migraciones de base de datos cd ../backend npm run migrate # Iniciar servicios en desarrollo npm run dev

Estructura del Proyecto

text agentelegal/ ├── backend/ # API Node.js/Express │ ├── src/ │ │ ├── routes/ # Rutas de la API │ │ ├── services/ # Lógica de negocio │ │ ├── middleware/ # Middlewares custom │ │ ├── config/ # Configuraciones │ │ ├── utils/ # Utilidades │ │ └── migrations/ # Migraciones de BD │ ├── uploads/ # Archivos subidos │ └── package.json ├── frontend/ # Portal de firma legal (React) │ ├── src/ │ │ ├── components/ # Componentes React │ │ ├── pages/ # Páginas principales │ │ ├── services/ # Llamadas API │ │ ├── utils/ # Utilidades frontend │ │ └── styles/ # Estilos CSS │ └── package.json ├── client-portal/ # Portal de clientes (React) │ ├── src/ │ └── package.json ├── LandingPage/ # Landing page y documentación │ ├── agentelegal.html │ ├── manual-firma-legal.html │ ├── manual-clientes.html │ └── assets/ └── docs/ # Documentación adicional

Scripts de Desarrollo

bash # Backend npm run dev # Servidor de desarrollo con nodemon npm run start # Servidor de producción npm run migrate # Ejecutar migraciones npm run test # Ejecutar tests npm run lint # Linter ESLint # Frontend npm start # Servidor de desarrollo React npm run build # Build de producción npm run test # Tests de componentes npm run lint # Linter para React # Utilidades npm run setup-bank # Configurar información bancaria npm run validate-config # Validar configuración npm run backup:create # Crear backup manual npm run deployment-check # Verificar antes de deploy

Estándares de Código

ESLint Configuration

json { "extends": [ "eslint:recommended", "@typescript-eslint/recommended", "react-app" ], "rules": { "indent": ["error", 2], "quotes": ["error", "single"], "semi": ["error", "always"], "no-console": "warn", "no-unused-vars": "error" } }

Convenciones de Naming

  • Variables: camelCase (userName, clientData)
  • Funciones: camelCase (getUserById, createInvoice)
  • Componentes React: PascalCase (ClientForm, DocumentList)
  • Archivos: kebab-case (client-service.js, user-profile.jsx)
  • Base de datos: snake_case (user_id, created_at)

Testing

JavaScript // Ejemplo de test unitario const request = require('supertest'); const app = require('../src/app'); describe('API de Clientes', () => { test('GET /api/clients debe retornar lista de clientes', async () => { const response = await request(app) .get('/api/clients') .set('Authorization', `Bearer ${validToken}`) .expect(200); expect(response.body.success).toBe(true); expect(Array.isArray(response.body.data)).toBe(true); }); test('POST /api/clients debe crear nuevo cliente', async () => { const clientData = { name: 'Sociedad Test S.A.', ruc: '155767268-2-2025', email: 'test@example.com' }; const response = await request(app) .post('/api/clients') .set('Authorization', `Bearer ${validToken}`) .send(clientData) .expect(201); expect(response.body.data.name).toBe(clientData.name); }); });
✅ Mejores Prácticas de Desarrollo:
  • Escribir tests para funcionalidades críticas
  • Usar TypeScript para type safety
  • Documentar APIs con comentarios JSDoc
  • Validar todos los inputs de usuario
  • Implementar manejo de errores robusto
  • Usar git flow para manejo de branches