Introducción
¿Qué es este documento?
Esta Guía de Estándares de Desarrollo de Salesforce es el marco normativo oficial de Vantegrate para la construcción de soluciones en la plataforma Salesforce. Define las convenciones, patrones y mejores prácticas que garantizan un código consistente, mantenible y de alta calidad en todos los proyectos.
El documento establece reglas claras para la nomenclatura, la estructura del código, el modelo de datos, las automatizaciones, la seguridad y la documentación. Cada estándar está respaldado por ejemplos concretos, utilizando un caso real de implementación de facturación electrónica en Salesforce, para facilitar su comprensión y aplicación inmediata.
¿Para quién está diseñado?
Desarrolladores Salesforce: tanto nuevos integrantes del equipo de Vantegrate como desarrolladores experimentados encontrarán aquí las convenciones obligatorias para escribir código que se integre perfectamente con el resto del ecosistema de Vantegrate.
Arquitectos y Tech Leads: proporciona un marco de referencia para revisiones de código, decisiones de diseño y la evaluación de la calidad técnica.
Herramientas de IA Generativa: este documento está optimizado para ser consumido por asistentes de inteligencia artificial como Agentforce, Cursor, Claude y otras herramientas de generación de código.
¿Cómo usar este documento?
Para desarrolladores humanos
- Leer las secciones 1 y 2 completas antes de escribir cualquier código.
- Consultar la sección específica según el tipo de componente a desarrollar.
- Usar los checklists de la sección 11 antes de cada commit y deploy.
- Referirse al Apéndice A como guía rápida de nomenclatura.
Para herramientas de IA
- Incluir este documento (o secciones relevantes) en el contexto del prompt.
- Referenciar explícitamente las convenciones de nomenclatura de la sección 2.
- Solicitar que el código generado siga los patrones de las secciones 3-6.
- Validar el output contra las reglas PMD de la sección 8.
Principios de diseño del documento
| Principio | Significado |
|---|---|
| Explícito sobre implícito | Cada regla incluye ejemplos concretos de uso correcto e incorrecto. No se asume conocimiento previo. |
| Optimizado para IA | Las convenciones emplean terminología consistente y estructuras predecibles que los modelos de lenguaje pueden interpretar. |
| Orientado a la práctica | Todos los ejemplos provienen de casos reales, en particular del ámbito de la facturación electrónica. |
| Evolutivo | Se actualiza conforme surgen nuevas capacidades de Salesforce y mejores prácticas de la industria. |
1Principios Fundamentales
1.1 Regla Fundamental: Sólo Inglés
Principio: todo el código, los comentarios, los nombres de variables, métodos, clases, objetos, campos y la documentación técnica deben estar en inglés.
Razón: el inglés es el estándar de la industria, facilita la colaboración global, mejora la documentación y permite la integración con herramientas de análisis.
| ✓ Correcto | ✗ Incorrecto |
|---|---|
| AccountService | ServicioCuentas |
| isHighValueCustomer | esClienteValioso |
| Invoice__c | Factura__c |
| TotalAmount__c | MontoTotal__c |
| // Calculate total revenue | // Calcular ingresos |
1.1.1 Distinción entre Label y API Name
Es importante distinguir entre Label (etiqueta visible al usuario) y API Name (nombre técnico en código):
- API Name: SIEMPRE en inglés, usando PascalCase. Es el identificador técnico utilizado en el código, las fórmulas, las integraciones y las automatizaciones.
- Label: PUEDE estar en español o en el idioma del usuario final. Es lo que el usuario ve en la interfaz de Salesforce.
| Tipo | Label (Usuario) | API Name (Código) |
|---|---|---|
| Campo | Período de facturación | BillingPeriod__c |
| Campo | Código de exención | TaxExemptionCode__c |
| Campo | Es principal | IsPrimary__c |
| Objeto | Línea de factura | InvoiceLine__c |
| Record Type | Factura - Borrador | InvoiceDraft |
1.2 Desarrollo Guiado por Pruebas (TDD)
El ciclo TDD es obligatorio para todo desarrollo Apex:
| Fase | Descripción |
|---|---|
| 🔴 RED | Escribe un test que falle (define el comportamiento esperado). |
| 🟢 GREEN | Escribe el código mínimo para que el test pase. |
| 🔵 REFACTOR | Mejora el código manteniendo los tests verdes. |
Requisitos de cobertura
| Tipo | Cobertura requerida |
|---|---|
| Cobertura mínima global | 75% |
| Cobertura recomendada | 85%+ |
| Clases críticas (Services, Handlers) | 90%+ |
| Assertions | Cada test DEBE tener assertions significativas. |
1.3 Calidad y Performance
Reglas de oro (obligatorias):
- 🚫 NUNCA ejecutar SOQL dentro de loops.
- 🚫 NUNCA ejecutar DML dentro de loops.
- ✓ SIEMPRE usar bulk processing (diseñar para 200+ registros).
- ✓ SIEMPRE verificar Field Level Security (FLS).
- ✓ SIEMPRE verificar CRUD permissions antes de operaciones DML.
- ✓ SIEMPRE declarar sharing model (
with sharing/without sharing). - 📋 Cumplimiento obligatorio de reglas PMD críticas.
1.4 Principio de Solución Nativa
Priorizar siempre soluciones nativas de Salesforce en este orden:
| Prioridad | Tipo de solución | Ejemplos |
|---|---|---|
| 1️⃣ | Soluciones de terceros | AppExchange o componentes de la comunidad (unofficialSF) |
| 2️⃣ | Configuración declarativa | Validation Rules, Formula Fields, Roll-up Summaries |
| 3️⃣ | Flows | Record-Triggered, Screen, Scheduled, Platform Event |
| 4️⃣ | Apex | Cuando Flows no pueden resolver el requerimiento |
| 5️⃣ | Integraciones externas | Solo cuando no hay alternativa nativa |
2Nomenclatura Universal
Esta sección define las convenciones de nomenclatura obligatorias para todos los componentes de desarrollo en Salesforce.
2.1 Estilos de Case
| Estilo | Descripción | Ejemplo |
|---|---|---|
| PascalCase | Primera letra de cada palabra mayúscula, SIN guiones bajos | InvoiceService |
| camelCase | Primera palabra minúscula, resto capitalizado | accountList |
| UPPER_SNAKE_CASE | Todo mayúsculas separado por guion bajo | MAX_RECORDS |
| kebab-case | Todo minúsculas separado por guiones | invoice-form |
2.1.1 Regla Crítica: PascalCase SIN guiones bajos internos
La convención Vantegrate exige PascalCase sin guiones bajos internos para los nombres de API de objetos y campos.
| ✓ Correcto | ✗ Incorrecto |
|---|---|
| SecondaryContact__c | Secondary_Contact__c |
| BillingPeriod__c | Billing_Period__c |
| TaxExemptionCode__c | Tax_Exemption_Code__c |
| InvoiceLine__c | Invoice_Line__c |
| PrimaryAccount__c | Primary_Account__c |
2.1.2 Uso de PascalCase
Aplicar a nombres que representan entidades, tipos o estructuras principales.
| Componente | Ejemplo |
|---|---|
| Custom Objects API Name | Invoice__c, InvoiceLine__c |
| Custom Fields API Name | ServiceDate__c, TotalAmount__c |
| Apex Classes | AccountService, InvoiceController |
| Apex Triggers | AccountTrigger, InvoiceTrigger |
| Test Classes | AccountServiceTest, InvoiceControllerTest |
| Flow API Names | Invoice_AfterInsert_SendToAfip |
| Permission Sets | Invoicing_FullAccess, Billing_ReadOnly |
| Validation Rules | Invoice_Amount_Required |
| Record Types (DeveloperName) | InvoiceDraft, InvoicePosted |
2.1.3 Uso de camelCase
Aplicar a variables, métodos, propiedades y elementos internos.
| Componente | Ejemplo |
|---|---|
| Apex Methods | calculateTotal(), processInvoices() |
| Apex Variables | invoiceList, isValid, totalAmount |
| LWC Component Names | invoiceForm, customerOnboarding |
| LWC Properties | isLoading, recordId, errorMessage |
| Flow Variables | varB_IsValid, varT_CustomerName |
2.1.4 Uso de UPPER_SNAKE_CASE
Aplicar a constantes y valores inmutables.
| Componente | Ejemplo |
|---|---|
| Apex Constants | MAX_RECORDS, DEFAULT_PAGE_SIZE |
| Apex Static Final Variables | API_VERSION, BATCH_SIZE |
| LWC Constants | MAX_FILE_SIZE, SUPPORTED_FORMATS |
2.1.5 Uso de kebab-case
Aplicar en referencias HTML y atributos web.
| Componente | Ejemplo |
|---|---|
| LWC Component Tags en HTML | <c-invoice-form>, <c-user-profile> |
| CSS Class Names | .container-main, .button-primary |
| Data Attributes | data-record-id, data-field-name |
2.2 Tabla resumen: Case style por componente
| Componente | Case style | Ejemplo |
|---|---|---|
| Custom Object API Name | PascalCase | Invoice__c |
| Custom Field API Name | PascalCase | TotalAmount__c |
| Apex Class | PascalCase | InvoiceService |
| Apex Method | camelCase | calculateTotal() |
| Apex Variable | camelCase | invoiceList |
| Apex Constant | UPPER_SNAKE_CASE | MAX_RECORDS |
| Apex Trigger | PascalCase | InvoiceTrigger |
| Test Class | PascalCase | InvoiceServiceTest |
| Test Method | camelCase | testCalculate_Valid_Success |
| LWC Component Name | camelCase | invoiceForm |
| LWC en HTML Template | kebab-case | <c-invoice-form> |
| Flow API Name | PascalCase | Invoice_AfterInsert_Send |
| Flow Variable | camelCase | varB_IsValid |
| Permission Set | PascalCase | Invoicing_FullAccess |
| Record Type | PascalCase | InvoiceDraft |
| CSS Class | kebab-case | .btn-primary |
2.3 Custom Objects
Case style: PascalCase. Formato API Name: [ObjectName]__c.
| Tipo de objeto | Prefijo | Ejemplo API Name | Ejemplo Label |
|---|---|---|---|
| Business Object | — | Invoice__c | Invoice |
| Junction Object | — | AccountContact__c | Account Contact |
| Setting/Config | — | InvoiceSettings__c | Invoice Settings |
| Log/History | — | IntegrationLog__c | Integration Log |
| Managed Package | vtg__ | vtg__ProductCatalog__c | Product Catalog |
Reglas obligatorias
- USAR PascalCase para API Name.
- USAR Singular (
Invoice__c, NOInvoices__c). - USAR nombres descriptivos en inglés.
- Junction Objects: concatenar nombres en orden alfabético.
- NO usar abreviaturas excepto estándares (Id, URL, API).
2.4 Custom Fields
Case style: PascalCase sin guiones bajos internos. Formato API Name: [FieldName]__c.
| Tipo | Convención | ✓ Correcto | ✗ Incorrecto |
|---|---|---|---|
| Lookup (único) | Nombre del objeto | Account__c | Account_Lookup__c |
| Lookup (con rol) | [Rol][Objeto] | BillingAccount__c | Billing_Account__c |
| External ID | [System]ExternalId | ComfiarExternalId__c | Comfiar_Ext_Id__c |
| Checkbox | Is / Has / Can | IsActive__c | Is_Active__c |
| Date | [Desc]Date | InvoiceDate__c | Invoice_Date__c |
| DateTime | [Desc]DateTime | ProcessedDateTime__c | Processed_Date_Time__c |
| Currency | Descriptivo | TotalAmount__c | Total_Amount__c |
| Text | Descriptivo | TaxExemptionCode__c | Tax_Exemption_Code__c |
2.5 Campos de Relación (Lookup y Master-Detail)
Los campos de relación requieren atención especial porque definen cómo los usuarios "leen" el modelo de datos.
2.5.1 Relación única hacia un objeto
Cuando un objeto tiene UNA sola relación hacia otro objeto, el API Name es simplemente el nombre del objeto destino:
1// Invoice__c tiene un lookup a Account2Field API Name: Account__c3Field Label: Cuenta2.5.2 Múltiples relaciones hacia el mismo objeto
Cuando un objeto tiene MÚLTIPLES relaciones hacia el mismo objeto, usar el patrón: [Rol][NombreDelObjeto]__c.
1// Invoice__c tiene dos lookups a Contact2PrimaryContact__c → Label: Contacto Principal3BillingContact__c → Label: Contacto de facturación| ✓ Correcto | ✗ Incorrecto |
|---|---|
| PrimaryContact__c | Primary_Contact__c |
| SecondaryContact__c | Contact2__c |
| BillingAccount__c | Billing_Account__c |
| ApproverUser__c | Approver_User__c |
2.5.3 Ejemplos comunes de campos con rol
| Escenario | API Name | Label sugerido |
|---|---|---|
| Cuenta de facturación | BillingAccount__c | Cuenta de facturación |
| Cuenta de envío | ShippingAccount__c | Cuenta de envío |
| Contacto principal | PrimaryContact__c | Contacto principal |
| Usuario aprobador | ApproverUser__c | Aprobador |
| Proyecto padre | ParentProject__c | Proyecto padre |
| Factura original | OriginalInvoice__c | Factura original |
2.6 Junction Objects (Objetos de Unión)
Un Junction Object implementa una relación muchos-a-muchos entre dos objetos.
2.6.1 Nomenclatura
Regla fundamental: usar un nombre de negocio, NO un nombre técnico.
| ✓ Correcto | ✗ Incorrecto |
|---|---|
| Application__c (Solicitud) | CandidateJobJunction__c |
| Enrollment__c (Inscripción) | StudentCourseJunction__c |
| Subscription__c (Suscripción) | UserServiceJunction__c |
| Assignment__c (Asignación) | EmployeeProjectJunction__c |
| Membership__c (Membresía) | ContactGroupJunction__c |
2.6.2 Estructura de un Junction Object
1Object: Application__c2Label: Solicitud | Plural Label: Solicitudes3
4Master-Detail fields:5 - Candidate__c (MD → Candidate__c)6 - JobPosition__c (MD → JobPosition__c)7
8Additional fields:9 - ApplicationDate__c (Date)10 - Status__c (Picklist: Pending, Approved, Rejected)2.6.3 Relación Master-Detail primaria
El primer campo Master-Detail creado se convierte en la relación primaria. Esto determina la herencia de la propiedad, el borrado en cascada y la disponibilidad de Roll-up Summary.
2.7 Record Types
DeveloperName: PascalCase, sin sufijo __c.
Patrón: [Objeto][Segmento] o [Objeto][Proceso].
| Objeto | DeveloperName | Label |
|---|---|---|
| Account | AccountB2B | Cuenta - B2B |
| Account | AccountB2C | Cuenta - B2C |
| Invoice__c | InvoiceDraft | Factura - Borrador |
| Invoice__c | InvoicePosted | Factura - Contabilizada |
| Case | CaseSupport | Caso - Soporte |
| Case | CaseBilling | Caso - Facturación |
2.8 Page Layouts
Patrón: [Objeto] Layout - [Variante].
| ✓ Correcto | ✗ Incorrecto |
|---|---|
| Invoice Layout - Draft | InvoiceDraft |
| Invoice Layout - Posted | Layout Factura Contabilizada |
| Account Layout - Partner | Partner Account Layout |
| Account Layout - Standard | Account Layout |
2.9 Apex Classes
Case style: PascalCase con sufijo descriptivo según el rol.
| Tipo | Sufijo | Ejemplo | Propósito |
|---|---|---|---|
| Service | Service | InvoiceService | Lógica de negocio |
| Selector | Selector | InvoiceSelector | Queries SOQL |
| Domain | (plural) | Invoices | Comportamiento de objeto |
| Trigger Handler | TriggerHandler | InvoiceTriggerHandler | Lógica de trigger |
| Controller | Controller | InvoiceController | LWC/Aura controller |
| Batch | Batch | InvoiceGenerationBatch | Procesamiento batch |
| Schedulable | Scheduler | DailyInvoiceScheduler | Jobs programados |
| Queueable | Queueable | InvoiceSendQueueable | Procesamiento async |
| Test | Test | InvoiceServiceTest | Unit tests |
| Test Data Factory | TestDataFactory | TestDataFactory | Creación datos test |
| Utility | Util | TaxCalculationUtil | Métodos utilitarios |
| Exception | Exception | ValidationException | Excepciones custom |
| Invocable | Invocable | SendToAfipInvocable | Acciones para Flow |
| Wrapper | Wrapper | InvoiceWrapper | Data transfer objects |
2.10 Apex Methods y Variables
| Elemento | Case Style | ✓ Correcto | ✗ Incorrecto |
|---|---|---|---|
| Methods | camelCase | calculateTotal() | CalculateTotal() |
| Variables locales | camelCase | invoiceList | InvoiceList |
| Parámetros | camelCase | invoiceId | InvoiceId |
| Constantes | UPPER_SNAKE | MAX_RECORDS | maxRecords |
| Boolean vars | camelCase | isValid | IsValid |
| Collections | camelCase | invoices | Invoices |
2.11 Triggers
Case style: PascalCase. Formato: [ObjectName]Trigger.
| ✓ Correcto | ✗ Incorrecto |
|---|---|
| InvoiceTrigger | invoiceTrigger |
| InvoiceLineTrigger | invoice_line_trigger |
2.12 Test Classes y Methods
Test Class: PascalCase → [ClassBeingTested]Test.
Test Method: camelCase → test[Method]_[Scenario]_[Result].
| Ejemplo | Descripción |
|---|---|
InvoiceServiceTest | Test class (PascalCase) |
testCalculateTotal_ValidData_ReturnsSum | Test method (camelCase) |
testValidateInvoice_MissingCAE_ThrowsException | Test method (camelCase) |
2.13 Validation Rules
Formato: [Object]_[Field/Condition]_[RuleType].
| ✓ Correcto | ✗ Incorrecto |
|---|---|
| Invoice_TotalAmount_Required | invoice_total_required |
| Invoice_CAE_ValidFormat | invoiceCAEValidation |
| InvoiceLine_Quantity_Positive | VR_001 |
2.14 Permission Sets
Permission Set: [Feature/Object]_[AccessLevel].
Permission Set Group: [Role]_Permissions.
| Tipo | Patrón | Ejemplo |
|---|---|---|
| Full Access PS | [Object]_FullAccess | Invoicing_FullAccess |
| Read Only PS | [Object]_ReadOnly | Invoicing_ReadOnly |
| Feature PS | [Feature]_Access | ReportBuilder_Access |
| Integration PS | [System]_Integration | Comfiar_Integration |
| PS Group | [Role]_Permissions | BillingManager_Permissions |
2.15 Flows
API Name: PascalCase con underscores como separadores.
Variables: camelCase con prefijo de tipo.
| Tipo de Flow | Patrón | Ejemplo |
|---|---|---|
| Record-Triggered (Before) | [Obj]_Before[Event]_[Action] | Invoice_BeforeInsert_Validate |
| Record-Triggered (After) | [Obj]_After[Event]_[Action] | Invoice_AfterInsert_SendToAfip |
| Screen Flow | [Process]_ScreenFlow | InvoiceCreation_ScreenFlow |
| Autolaunched | [Process]_Autolaunched | InvoiceGeneration_Autolaunched |
| SubFlow | SubFlow_[Function] | SubFlow_CalculateTaxes |
| Scheduled | [Process]_Scheduled_[Freq] | InvoiceRetry_Scheduled_Hourly |
| Platform Event | [EventName]_Handler | InvoiceApproved_Handler |
2.16 Reports y Dashboards
Los nombres de Reportes y Dashboards son visibles para usuarios finales, por lo que priman la claridad y la organización.
2.16.1 Nomenclatura de Reports
Case style: Title Case con espacios (legible para usuarios).
Formato: [Área] – [Nombre Descriptivo] ([Período]).
| ✓ Correcto | ✗ Incorrecto |
|---|---|
| Ventas – Pipeline por Etapa (Mensual) | SalesPipelineMonthly |
| Facturación – Facturas Pendientes de CAE | InvoicesPendingCAE |
| Soporte – Casos Abiertos por Prioridad | OpenCasesByPriority |
| RRHH – Onboarding Q4 2025 | HR_Onboarding_Report |
2.16.2 Nomenclatura de Dashboards
Formato: [Área] – Dashboard [Propósito].
| Ejemplo | Descripción |
|---|---|
| Ventas – Dashboard Ejecutivo | Vista ejecutiva de métricas de ventas |
| Facturación – Dashboard Operativo | Métricas diarias de facturación |
| Soporte – Dashboard SLA | Seguimiento de niveles de servicio |
| Marketing – Dashboard Campañas Q4 | Performance de campañas |
2.16.3 Nomenclatura de Carpetas
Formato: [Área/Departamento] – [Tema].
| Ejemplo Carpeta | Contenido |
|---|---|
| Ventas – Reportes Pipeline | Reportes de pipeline de ventas |
| Facturación – AFIP | Reportes de integración AFIP/COMFIAR |
| Finanzas – Cobranzas | Reportes de cobranzas y aging |
| Ejecutivo – KPIs | Dashboards para dirección |
3Modelo de Datos
3.1 Campos de Integración Estándar
Para objetos que participan en integraciones con sistemas externos (como COMFIAR, ERPs, etc.):
| Campo | API Name | Tipo | Propósito |
|---|---|---|---|
| Integration Status | IntegrationStatus__c | Picklist | Estado de sync |
| Last Sync DateTime | LastSyncDateTime__c | DateTime | Última sync exitosa |
| Sync Error Message | SyncErrorMessage__c | Long Text | Detalle del error |
| Retry Count | SyncRetryCount__c | Number(3,0) | Intentos de sync |
4Estándares de Flow
Los Flows representan aproximadamente el 60% del desarrollo de automatización en Salesforce.
4.1 Variables de Flow
Case style: camelCase con prefijo de tipo (varB_, varT_, etc.).
| Tipo | Prefijo | Ejemplo | Uso |
|---|---|---|---|
| Boolean | varB_ | varB_IsValidInvoice | Flags, decisiones |
| Currency | varC_ | varC_TotalAmount | Valores monetarios |
| Date | varD_ | varD_InvoiceDate | Fechas sin hora |
| DateTime | varDT_ | varDT_ProcessedAt | Timestamps |
| Number | varN_ | varN_LineCount | Contadores |
| Text | varT_ | varT_CAENumber | Strings |
| Record | varR_ | varR_CurrentInvoice | Registro individual |
| Collection | varCol_ | varCol_InvoiceLines | Lista de registros |
4.2 Elementos de Flow
Decisiones
Case style: Sentence case (pregunta en inglés).
| ✓ Correcto | ✗ Incorrecto |
|---|---|
| Is Valid Invoice? | Invoice_Check |
| Has Valid CAE? | CAE_VALIDATION |
| Exceeds Credit Limit? | verificarLimite |
Asignaciones
| Prefijo | Uso | Ejemplo |
|---|---|---|
SET | Asignar un valor | SET Invoice Status |
CALC | Calcular un valor | CALC Total With Taxes |
INIT | Inicializar colecciones | INIT Lines Collection |
ADD | Agregar a colección | ADD to Update Collection |
LOG | Preparar datos de logging | LOG Error Details |
Elementos de Datos
| ✓ Correcto | ✗ Incorrecto |
|---|---|
| Get Invoice Records | DATA_RETRIEVAL |
| Create Invoice Line | createLine |
| Update Invoice Status | Update1 |
| Delete Draft Invoices | eliminar_borradores |
4.3 Manejo de Errores
- Todos los elementos Get/Create/Update/Delete Records.
- HTTP Callouts / External Services.
- Llamadas a SubFlows.
- Invocable Actions.
4.4 Performance en Flows
Checklist de performance:
- Usar filtros específicos en elementos Get Records.
- Limitar registros retornados (usar LIMIT).
- Seleccionar solo campos necesarios.
- UN solo Get Records por objeto (consolidar).
- NUNCA DML dentro de loops — usar colecciones.
- SubFlows para lógica reutilizable.
- Máximo 50 elementos por Flow.
- Fault paths en elementos críticos.
5Desarrollo Apex y TDD
5.1 Estructura de Clases Apex
1/**2 * @description Service class for Invoice-related business logic3 * @author Vantegrate Development Team4 * @date 2025-12-015 */6public with sharing class InvoiceService { // PascalCase7
8 // UPPER_SNAKE_CASE for constants9 private static final Decimal IVA_RATE = 0.21;10 private static final Integer MAX_RETRY_COUNT = 3;11
12 // camelCase for methods13 public static Decimal calculateTotalWithTax(List<InvoiceLine__c> lines) {14 // camelCase for variables15 Decimal subtotal = 0;16 Decimal taxAmount = 0;17
18 for (InvoiceLine__c line : lines) {19 subtotal += line.Amount__c;20 }21
22 taxAmount = subtotal * IVA_RATE;23 return subtotal + taxAmount;24 }25}5.2 Patrón Trigger Handler
El trigger debe ser mínimo y delegar toda la lógica al handler:
1// Trigger — PascalCase: [Object]Trigger2trigger InvoiceTrigger on Invoice__c (before insert, after insert) {3 new InvoiceTriggerHandler().run();4}1// Handler — PascalCase: [Object]TriggerHandler2public class InvoiceTriggerHandler extends TriggerHandler {3
4 public override void beforeInsert() {5 InvoiceService.validateInvoices((List<Invoice__c>) Trigger.new);6 }7
8 public override void afterInsert() {9 InvoiceService.sendToComfiar((List<Invoice__c>) Trigger.new);10 }11}6Lightning Web Components (LWC)
6.1 Nomenclatura de Componentes
| Elemento | Case Style | Ejemplo JS | Ejemplo HTML |
|---|---|---|---|
| Component Name | camelCase | invoiceForm | <c-invoice-form> |
| JS Properties | camelCase | isLoading | — |
| JS Methods | camelCase | handleSave() | — |
| Constants | UPPER_SNAKE | MAX_LINES | — |
| Event Names | lowercase | 'save' | onsave |
| CSS Classes | kebab-case | — | .btn-primary |
| Data Attributes | kebab-case | — | data-line-id |
6.2 Mejores Prácticas LWC
- Usar @api para propiedades públicas expuestas a padres.
- Usar @track solo cuando sea necesario (objetos/arrays reactivos).
- Preferir getter methods sobre @track para valores computados.
- Manejar errores en wire methods.
- Usar ShowToastEvent para feedback al usuario.
- Evitar querySelector — usar data-id y template refs.
- Implementar loading states para operaciones async.
- Usar constantes UPPER_SNAKE_CASE para valores mágicos.
7Seguridad y Permisos
7.1 CRUD y FLS
En el siguiente ejemplo, con as user se aplican las verificaciones de forma automática y solo hay que interceptar la excepción:
1Account myAcc = new Account(2 Name = 'Vantegrate Upgrade',3 AnnualRevenue = 500000 // Supongamos que este campo es de solo lectura4);5try {6 // Valida automáticamente CRUD, FLS y Sharing Rules7 insert as user myAcc;8} catch (DmlException e) {9 // Manejo robusto de errores de seguridad10 for (Integer i = 0; i < e.getNumDml(); i++) {11 if (e.getDmlType(i) == StatusCode.INSUFFICIENT_ACCESS_OR_READONLY) {12 System.debug('Error: El usuario no tiene permisos');13 } else {14 System.debug('Otro error de DML: ' + e.getDmlMessage(i));15 }16 }17}En el siguiente ejemplo, usando WITH USER_MODE al final de la query SOQL las verificaciones se hacen de forma automática y solo hay que interceptar la excepción:
1try {2 // La consulta fallará si el usuario no tiene acceso a 'Phone' o 'Industry'3 List<Account> accs = [4 SELECT Id, Name, Phone5 FROM Account6 WHERE Industry = 'Technology'7 WITH USER_MODE8 ];9 System.debug('Registros recuperados respetando seguridad: ' + accs.size());10} catch (QueryException e) {11 // El mensaje indicará qué campo o permiso falta12 System.debug('Error de permisos en SOQL: ' + e.getMessage());13}7.2 Sharing Model
| Keyword | Uso |
|---|---|
with sharing | DEFAULT — respeta sharing rules. Usar para lógica de negocio normal. |
without sharing | Ignora sharing rules. Solo para operaciones de sistema (batch, integrations). |
inherited sharing | Hereda del caller. Usar para utility classes reutilizables. |
7.3 Checklist de Seguridad
- Declarar sharing model en todas las clases.
- Verificar CRUD antes de DML operations.
- Verificar FLS antes de acceder a campos sensibles.
- Usar WITH USER_MODE en queries.
- No hardcodear IDs.
- Sanitizar inputs de usuarios.
- Usar variable binding en SOQL (prevenir injection).
- Evitar información sensible en debug logs.
8Reglas PMD
8.1 Reglas Críticas (Bloquean Deploy)
| Regla | Descripción |
|---|---|
ApexUnitTestClassShouldHaveAsserts | Tests DEBEN tener assertions. |
AvoidLogicInTrigger | Triggers DEBEN delegar a handlers. |
AvoidDmlStatementsInLoops | NUNCA DML en loops. |
AvoidSoqlInLoops | NUNCA SOQL en loops. |
ApexCRUDViolation | Verificar CRUD antes de DML. |
ApexSharingViolations | Declarar sharing en classes. |
ApexSOQLInjection | Prevenir SOQL injection. |
AvoidHardcodingId | No IDs hardcodeados. |
8.2 Reglas de Mejores Prácticas
| Regla | Descripción |
|---|---|
DebugsShouldUseLoggingLevel | Debug con nivel: System.debug(LoggingLevel.INFO, msg). |
ApexAssertionsShouldIncludeMessage | Assertions con mensaje descriptivo. |
MethodNamingConventions | Métodos en camelCase. |
ClassNamingConventions | Clases en PascalCase. |
FieldNamingConventions | Variables en camelCase. |
OneDeclarationPerLine | Una declaración por línea. |
AvoidGlobalModifier | Evitar global (excepto webservices). |
9Versionado y Release Management
9.1 Versionado Semántico
Formato: MAJOR.MINOR.PATCH.
| Componente | Incrementar cuando | Ejemplo |
|---|---|---|
| MAJOR (X.0.0) | Breaking changes, rediseño mayor | 2.0.0 → Nuevo data model |
| MINOR (x.Y.0) | Nueva funcionalidad compatible | 2.1.0 → Nueva integración |
| PATCH (x.y.Z) | Bug fixes, mejoras menores | 2.1.1 → Fix validation rule |
9.2 Release Notes
Cada release debe documentar:
- Número de versión y fecha.
- Nuevas funcionalidades.
- Cambios en funcionalidad existente.
- Bug fixes.
- Breaking changes (si aplica).
- Pasos de migración (si aplica).
- Dependencias actualizadas.
10Documentación
10.1 ApexDoc para Clases
1/**2 * @description Service for invoice lifecycle management and AFIP integration3 * @author Vantegrate Development Team4 * @date 2025-12-015 * @version 2.06 */7public with sharing class InvoiceService {8
9 /**10 * @description Sends invoices to COMFIAR for AFIP authorization11 * @param invoices List of invoices to process12 * @return ProcessingResult Results including CAE numbers13 * @throws IntegrationException When COMFIAR is unavailable14 * @example15 * List<Invoice__c> invoices = [SELECT Id FROM Invoice__c];16 * InvoiceService.sendToComfiar(invoices);17 */18 public static ProcessingResult sendToComfiar(List<Invoice__c> invoices) {19 // Implementation20 }21}10.2 Documentación de Flows
Cada Flow debe incluir en Description:
1FLOW NAME: Invoice Authorization Automation2
3PURPOSE:4Sends new invoices to COMFIAR for AFIP authorization5and updates CAE information upon response.6
7TRIGGER:8Record-Triggered Flow on Invoice__c (After Insert)9
10INPUT REQUIREMENTS:11- Invoice with Customer, InvoiceDate, and at least one Line12
13ERROR HANDLING:14- Validation errors: Set ProcessingStatus__c = 'Error'15- COMFIAR errors: Log to IntegrationLog__c, alert admin16
17VERSION: 2.018LAST MODIFIED: 2025-12-0119AUTHOR: Vantegrate Development Team11Checklists y Templates
11.1 Checklist Pre-Deployment
- Todas las clases tienen cobertura ≥ 75%.
- Todos los tests tienen assertions significativas.
- PMD no reporta violaciones críticas.
- ApexDoc completo en clases públicas.
- Flows tienen fault paths en elementos críticos.
- No hay SOQL/DML en loops.
- Bulk testing completado (200+ records).
- Nombres siguen convenciones del estándar.
- Security Review: CRUD/FLS verificado.
- Release notes documentadas.
11.2 Checklist Code Review
- Código en inglés (variables, métodos, comentarios).
- Nomenclatura correcta según estándar.
- Triggers delegan a Handlers.
- Classes declaran sharing model.
- No hay IDs hardcodeados.
- Error handling implementado.
- Logging apropiado con LoggingLevel.
- Tests cubren escenarios positivos y negativos.
- Bulk processing implementado.
11.3 Checklist Nuevo Custom Object
- API Name en PascalCase y singular.
- Label y Plural Label definidos.
- Description completada.
- Campo ExternalId__c creado.
- Campo IsActive__c creado.
- Campo SourceSystem__c creado.
- Campo LastProcessedDateTime__c creado.
- Campo ProcessingStatus__c creado.
- Sharing model configurado.
- Permission Sets actualizados.
- Page Layouts configurados.
AApéndice A: Tabla de Referencia Rápida de Nomenclatura
| Elemento | Case Style | Patrón | Ejemplo |
|---|---|---|---|
| Custom Object | PascalCase | [Name]__c | Invoice__c |
| Custom Field | PascalCase | [Name]__c | TotalAmount__c |
| Apex Class | PascalCase | [Name][Suffix] | InvoiceService |
| Apex Method | camelCase | [verb][Object] | calculateTotal |
| Apex Variable | camelCase | [name] | invoiceList |
| Apex Constant | UPPER_SNAKE | [NAME] | MAX_RECORDS |
| Test Class | PascalCase | [Class]Test | InvoiceServiceTest |
| Test Method | camelCase | test[M]_[S]_[R] | testCalc_Valid_Ok |
| Trigger | PascalCase | [Object]Trigger | InvoiceTrigger |
| LWC Component | camelCase | [descriptive] | invoiceForm |
| LWC in HTML | kebab-case | <c-[name]> | <c-invoice-form> |
| LWC Property | camelCase | [name] | isLoading |
| LWC Constant | UPPER_SNAKE | [NAME] | MAX_FILE_SIZE |
| Flow API Name | PascalCase | [Obj]_[Action] | Invoice_SendToAfip |
| Flow Variable | camelCase | var[T]_[Name] | varB_IsValid |
| Flow Decision | Sentence | [Question]? | Is Valid? |
| Permission Set | PascalCase | [Obj]_[Access] | Invoicing_Admin |
| Validation Rule | PascalCase | [O]_[F]_[Rule] | Invoice_CAE_Required |
| Record Type | PascalCase | [Obj][Segment] | InvoiceDraft |
| Page Layout | Mixed | [Obj] Layout - [V] | Invoice Layout - Draft |
| CSS Class | kebab-case | .[name] | .btn-primary |
Fin del documento
Guía de Estándares Vantegrate · Versión 4.4

















