Guía técnica · v4.4

Estándares de desarrollo en Salesforce

El marco normativo que usa Vantegrate para construir soluciones sobre Salesforce desde 2009. Nomenclatura, modelo de datos, Flows, Apex, LWC, seguridad, PMD y release management — todo en un único documento técnico.

Diseñada para ser consumida por desarrolladores humanos y por asistentes de IA generativa (Agentforce, Cursor, Claude). Cada regla incluye ejemplos concretos, patrones canónicos y contra- ejemplos.

11
Secciones
16+
Convenciones
75%+
Cobertura mínima
v4.4
Versión

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

PrincipioSignificado
Explícito sobre implícitoCada regla incluye ejemplos concretos de uso correcto e incorrecto. No se asume conocimiento previo.
Optimizado para IALas convenciones emplean terminología consistente y estructuras predecibles que los modelos de lenguaje pueden interpretar.
Orientado a la prácticaTodos los ejemplos provienen de casos reales, en particular del ámbito de la facturación electrónica.
EvolutivoSe 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
AccountServiceServicioCuentas
isHighValueCustomeresClienteValioso
Invoice__cFactura__c
TotalAmount__cMontoTotal__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.
TipoLabel (Usuario)API Name (Código)
CampoPeríodo de facturaciónBillingPeriod__c
CampoCódigo de exenciónTaxExemptionCode__c
CampoEs principalIsPrimary__c
ObjetoLínea de facturaInvoiceLine__c
Record TypeFactura - BorradorInvoiceDraft

1.2 Desarrollo Guiado por Pruebas (TDD)

El ciclo TDD es obligatorio para todo desarrollo Apex:

FaseDescripción
🔴 REDEscribe un test que falle (define el comportamiento esperado).
🟢 GREENEscribe el código mínimo para que el test pase.
🔵 REFACTORMejora el código manteniendo los tests verdes.

Requisitos de cobertura

TipoCobertura requerida
Cobertura mínima global75%
Cobertura recomendada85%+
Clases críticas (Services, Handlers)90%+
AssertionsCada 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:

PrioridadTipo de soluciónEjemplos
1️⃣Soluciones de tercerosAppExchange o componentes de la comunidad (unofficialSF)
2️⃣Configuración declarativaValidation Rules, Formula Fields, Roll-up Summaries
3️⃣FlowsRecord-Triggered, Screen, Scheduled, Platform Event
4️⃣ApexCuando Flows no pueden resolver el requerimiento
5️⃣Integraciones externasSolo cuando no hay alternativa nativa
Antes de escribir código Apex, verificar si la funcionalidad puede resolverse mediante configuración declarativa o Flows. El código más fácil de mantener es el que no existe.

2Nomenclatura Universal

Esta sección define las convenciones de nomenclatura obligatorias para todos los componentes de desarrollo en Salesforce.

2.1 Estilos de Case

EstiloDescripciónEjemplo
PascalCasePrimera letra de cada palabra mayúscula, SIN guiones bajosInvoiceService
camelCasePrimera palabra minúscula, resto capitalizadoaccountList
UPPER_SNAKE_CASETodo mayúsculas separado por guion bajoMAX_RECORDS
kebab-caseTodo minúsculas separado por guionesinvoice-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__cSecondary_Contact__c
BillingPeriod__cBilling_Period__c
TaxExemptionCode__cTax_Exemption_Code__c
InvoiceLine__cInvoice_Line__c
PrimaryAccount__cPrimary_Account__c
Los guiones bajos internos dificultan la lectura, generan inconsistencias y pueden causar problemas en los paquetes de AppExchange.

2.1.2 Uso de PascalCase

Aplicar a nombres que representan entidades, tipos o estructuras principales.

ComponenteEjemplo
Custom Objects API NameInvoice__c, InvoiceLine__c
Custom Fields API NameServiceDate__c, TotalAmount__c
Apex ClassesAccountService, InvoiceController
Apex TriggersAccountTrigger, InvoiceTrigger
Test ClassesAccountServiceTest, InvoiceControllerTest
Flow API NamesInvoice_AfterInsert_SendToAfip
Permission SetsInvoicing_FullAccess, Billing_ReadOnly
Validation RulesInvoice_Amount_Required
Record Types (DeveloperName)InvoiceDraft, InvoicePosted

2.1.3 Uso de camelCase

Aplicar a variables, métodos, propiedades y elementos internos.

ComponenteEjemplo
Apex MethodscalculateTotal(), processInvoices()
Apex VariablesinvoiceList, isValid, totalAmount
LWC Component NamesinvoiceForm, customerOnboarding
LWC PropertiesisLoading, recordId, errorMessage
Flow VariablesvarB_IsValid, varT_CustomerName

2.1.4 Uso de UPPER_SNAKE_CASE

Aplicar a constantes y valores inmutables.

ComponenteEjemplo
Apex ConstantsMAX_RECORDS, DEFAULT_PAGE_SIZE
Apex Static Final VariablesAPI_VERSION, BATCH_SIZE
LWC ConstantsMAX_FILE_SIZE, SUPPORTED_FORMATS

2.1.5 Uso de kebab-case

Aplicar en referencias HTML y atributos web.

ComponenteEjemplo
LWC Component Tags en HTML<c-invoice-form>, <c-user-profile>
CSS Class Names.container-main, .button-primary
Data Attributesdata-record-id, data-field-name

2.2 Tabla resumen: Case style por componente

ComponenteCase styleEjemplo
Custom Object API NamePascalCaseInvoice__c
Custom Field API NamePascalCaseTotalAmount__c
Apex ClassPascalCaseInvoiceService
Apex MethodcamelCasecalculateTotal()
Apex VariablecamelCaseinvoiceList
Apex ConstantUPPER_SNAKE_CASEMAX_RECORDS
Apex TriggerPascalCaseInvoiceTrigger
Test ClassPascalCaseInvoiceServiceTest
Test MethodcamelCasetestCalculate_Valid_Success
LWC Component NamecamelCaseinvoiceForm
LWC en HTML Templatekebab-case<c-invoice-form>
Flow API NamePascalCaseInvoice_AfterInsert_Send
Flow VariablecamelCasevarB_IsValid
Permission SetPascalCaseInvoicing_FullAccess
Record TypePascalCaseInvoiceDraft
CSS Classkebab-case.btn-primary

2.3 Custom Objects

Case style: PascalCase. Formato API Name: [ObjectName]__c.

Tipo de objetoPrefijoEjemplo API NameEjemplo Label
Business ObjectInvoice__cInvoice
Junction ObjectAccountContact__cAccount Contact
Setting/ConfigInvoiceSettings__cInvoice Settings
Log/HistoryIntegrationLog__cIntegration Log
Managed Packagevtg__vtg__ProductCatalog__cProduct Catalog

Reglas obligatorias

  • USAR PascalCase para API Name.
  • USAR Singular (Invoice__c, NO Invoices__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.

TipoConvención✓ Correcto✗ Incorrecto
Lookup (único)Nombre del objetoAccount__cAccount_Lookup__c
Lookup (con rol)[Rol][Objeto]BillingAccount__cBilling_Account__c
External ID[System]ExternalIdComfiarExternalId__cComfiar_Ext_Id__c
CheckboxIs / Has / CanIsActive__cIs_Active__c
Date[Desc]DateInvoiceDate__cInvoice_Date__c
DateTime[Desc]DateTimeProcessedDateTime__cProcessed_Date_Time__c
CurrencyDescriptivoTotalAmount__cTotal_Amount__c
TextDescriptivoTaxExemptionCode__cTax_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:

Invoice__c
apex
1// Invoice__c tiene un lookup a Account
2Field API Name: Account__c
3Field Label: Cuenta

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

Invoice__c
apex
1// Invoice__c tiene dos lookups a Contact
2PrimaryContact__c → Label: Contacto Principal
3BillingContact__c → Label: Contacto de facturación
✓ Correcto✗ Incorrecto
PrimaryContact__cPrimary_Contact__c
SecondaryContact__cContact2__c
BillingAccount__cBilling_Account__c
ApproverUser__cApprover_User__c

2.5.3 Ejemplos comunes de campos con rol

EscenarioAPI NameLabel sugerido
Cuenta de facturaciónBillingAccount__cCuenta de facturación
Cuenta de envíoShippingAccount__cCuenta de envío
Contacto principalPrimaryContact__cContacto principal
Usuario aprobadorApproverUser__cAprobador
Proyecto padreParentProject__cProyecto padre
Factura originalOriginalInvoice__cFactura 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

Application__c
apex
1Object: Application__c
2Label: Solicitud | Plural Label: Solicitudes
3
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.

Elegir como primario el objeto de mayor importancia para el negocio o el que controlará el borrado en cascada.

2.7 Record Types

DeveloperName: PascalCase, sin sufijo __c.
Patrón: [Objeto][Segmento] o [Objeto][Proceso].

ObjetoDeveloperNameLabel
AccountAccountB2BCuenta - B2B
AccountAccountB2CCuenta - B2C
Invoice__cInvoiceDraftFactura - Borrador
Invoice__cInvoicePostedFactura - Contabilizada
CaseCaseSupportCaso - Soporte
CaseCaseBillingCaso - Facturación

2.8 Page Layouts

Patrón: [Objeto] Layout - [Variante].

✓ Correcto✗ Incorrecto
Invoice Layout - DraftInvoiceDraft
Invoice Layout - PostedLayout Factura Contabilizada
Account Layout - PartnerPartner Account Layout
Account Layout - StandardAccount Layout

2.9 Apex Classes

Case style: PascalCase con sufijo descriptivo según el rol.

TipoSufijoEjemploPropósito
ServiceServiceInvoiceServiceLógica de negocio
SelectorSelectorInvoiceSelectorQueries SOQL
Domain(plural)InvoicesComportamiento de objeto
Trigger HandlerTriggerHandlerInvoiceTriggerHandlerLógica de trigger
ControllerControllerInvoiceControllerLWC/Aura controller
BatchBatchInvoiceGenerationBatchProcesamiento batch
SchedulableSchedulerDailyInvoiceSchedulerJobs programados
QueueableQueueableInvoiceSendQueueableProcesamiento async
TestTestInvoiceServiceTestUnit tests
Test Data FactoryTestDataFactoryTestDataFactoryCreación datos test
UtilityUtilTaxCalculationUtilMétodos utilitarios
ExceptionExceptionValidationExceptionExcepciones custom
InvocableInvocableSendToAfipInvocableAcciones para Flow
WrapperWrapperInvoiceWrapperData transfer objects

2.10 Apex Methods y Variables

ElementoCase Style✓ Correcto✗ Incorrecto
MethodscamelCasecalculateTotal()CalculateTotal()
Variables localescamelCaseinvoiceListInvoiceList
ParámetroscamelCaseinvoiceIdInvoiceId
ConstantesUPPER_SNAKEMAX_RECORDSmaxRecords
Boolean varscamelCaseisValidIsValid
CollectionscamelCaseinvoicesInvoices

2.11 Triggers

Case style: PascalCase. Formato: [ObjectName]Trigger.

Regla crítica: un solo trigger por objeto. Toda la lógica debe delegarse al TriggerHandler.
✓ Correcto✗ Incorrecto
InvoiceTriggerinvoiceTrigger
InvoiceLineTriggerinvoice_line_trigger

2.12 Test Classes y Methods

Test Class: PascalCase → [ClassBeingTested]Test.
Test Method: camelCase → test[Method]_[Scenario]_[Result].

EjemploDescripción
InvoiceServiceTestTest class (PascalCase)
testCalculateTotal_ValidData_ReturnsSumTest method (camelCase)
testValidateInvoice_MissingCAE_ThrowsExceptionTest method (camelCase)

2.13 Validation Rules

Formato: [Object]_[Field/Condition]_[RuleType].

✓ Correcto✗ Incorrecto
Invoice_TotalAmount_Requiredinvoice_total_required
Invoice_CAE_ValidFormatinvoiceCAEValidation
InvoiceLine_Quantity_PositiveVR_001

2.14 Permission Sets

Permission Set: [Feature/Object]_[AccessLevel].
Permission Set Group: [Role]_Permissions.

TipoPatrónEjemplo
Full Access PS[Object]_FullAccessInvoicing_FullAccess
Read Only PS[Object]_ReadOnlyInvoicing_ReadOnly
Feature PS[Feature]_AccessReportBuilder_Access
Integration PS[System]_IntegrationComfiar_Integration
PS Group[Role]_PermissionsBillingManager_Permissions

2.15 Flows

API Name: PascalCase con underscores como separadores.
Variables: camelCase con prefijo de tipo.

Tipo de FlowPatrónEjemplo
Record-Triggered (Before)[Obj]_Before[Event]_[Action]Invoice_BeforeInsert_Validate
Record-Triggered (After)[Obj]_After[Event]_[Action]Invoice_AfterInsert_SendToAfip
Screen Flow[Process]_ScreenFlowInvoiceCreation_ScreenFlow
Autolaunched[Process]_AutolaunchedInvoiceGeneration_Autolaunched
SubFlowSubFlow_[Function]SubFlow_CalculateTaxes
Scheduled[Process]_Scheduled_[Freq]InvoiceRetry_Scheduled_Hourly
Platform Event[EventName]_HandlerInvoiceApproved_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 CAEInvoicesPendingCAE
Soporte – Casos Abiertos por PrioridadOpenCasesByPriority
RRHH – Onboarding Q4 2025HR_Onboarding_Report

2.16.2 Nomenclatura de Dashboards

Formato: [Área] – Dashboard [Propósito].

EjemploDescripción
Ventas – Dashboard EjecutivoVista ejecutiva de métricas de ventas
Facturación – Dashboard OperativoMétricas diarias de facturación
Soporte – Dashboard SLASeguimiento de niveles de servicio
Marketing – Dashboard Campañas Q4Performance de campañas

2.16.3 Nomenclatura de Carpetas

Formato: [Área/Departamento] – [Tema].

Ejemplo CarpetaContenido
Ventas – Reportes PipelineReportes de pipeline de ventas
Facturación – AFIPReportes de integración AFIP/COMFIAR
Finanzas – CobranzasReportes de cobranzas y aging
Ejecutivo – KPIsDashboards para dirección
Mantener la consistencia en los nombres de las carpetas, los reportes y los dashboards facilita la navegación. Usar el mismo prefijo de área agrupa el contenido lógicamente.

3Modelo de Datos

3.1 Campos de Integración Estándar

Para objetos que participan en integraciones con sistemas externos (como COMFIAR, ERPs, etc.):

CampoAPI NameTipoPropósito
Integration StatusIntegrationStatus__cPicklistEstado de sync
Last Sync DateTimeLastSyncDateTime__cDateTimeÚltima sync exitosa
Sync Error MessageSyncErrorMessage__cLong TextDetalle del error
Retry CountSyncRetryCount__cNumber(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.).

TipoPrefijoEjemploUso
BooleanvarB_varB_IsValidInvoiceFlags, decisiones
CurrencyvarC_varC_TotalAmountValores monetarios
DatevarD_varD_InvoiceDateFechas sin hora
DateTimevarDT_varDT_ProcessedAtTimestamps
NumbervarN_varN_LineCountContadores
TextvarT_varT_CAENumberStrings
RecordvarR_varR_CurrentInvoiceRegistro individual
CollectionvarCol_varCol_InvoiceLinesLista 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

PrefijoUsoEjemplo
SETAsignar un valorSET Invoice Status
CALCCalcular un valorCALC Total With Taxes
INITInicializar coleccionesINIT Lines Collection
ADDAgregar a colecciónADD to Update Collection
LOGPreparar datos de loggingLOG Error Details

Elementos de Datos

✓ Correcto✗ Incorrecto
Get Invoice RecordsDATA_RETRIEVAL
Create Invoice LinecreateLine
Update Invoice StatusUpdate1
Delete Draft Invoiceseliminar_borradores

4.3 Manejo de Errores

Obligatorio agregar Fault Path a todos los elementos críticos:
  • 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

InvoiceService.cls
apex
1/**
2 * @description Service class for Invoice-related business logic
3 * @author Vantegrate Development Team
4 * @date 2025-12-01
5 */
6public with sharing class InvoiceService { // PascalCase
7
8 // UPPER_SNAKE_CASE for constants
9 private static final Decimal IVA_RATE = 0.21;
10 private static final Integer MAX_RETRY_COUNT = 3;
11
12 // camelCase for methods
13 public static Decimal calculateTotalWithTax(List<InvoiceLine__c> lines) {
14 // camelCase for variables
15 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:

InvoiceTrigger.trigger
apex
1// Trigger — PascalCase: [Object]Trigger
2trigger InvoiceTrigger on Invoice__c (before insert, after insert) {
3 new InvoiceTriggerHandler().run();
4}
InvoiceTriggerHandler.cls
apex
1// Handler — PascalCase: [Object]TriggerHandler
2public 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}
Regla: un solo trigger por objeto. Toda la lógica de negocio debe estar en clases Service, no en el trigger ni en el handler.

6Lightning Web Components (LWC)

6.1 Nomenclatura de Componentes

ElementoCase StyleEjemplo JSEjemplo HTML
Component NamecamelCaseinvoiceForm<c-invoice-form>
JS PropertiescamelCaseisLoading
JS MethodscamelCasehandleSave()
ConstantsUPPER_SNAKEMAX_LINES
Event Nameslowercase'save'onsave
CSS Classeskebab-case.btn-primary
Data Attributeskebab-casedata-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

SIEMPRE verificar permisos antes de operaciones de datos.

En el siguiente ejemplo, con as user se aplican las verificaciones de forma automática y solo hay que interceptar la excepción:

Insert con 'as user'
apex
1Account myAcc = new Account(
2 Name = 'Vantegrate Upgrade',
3 AnnualRevenue = 500000 // Supongamos que este campo es de solo lectura
4);
5try {
6 // Valida automáticamente CRUD, FLS y Sharing Rules
7 insert as user myAcc;
8} catch (DmlException e) {
9 // Manejo robusto de errores de seguridad
10 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:

SOQL con WITH USER_MODE
apex
1try {
2 // La consulta fallará si el usuario no tiene acceso a 'Phone' o 'Industry'
3 List<Account> accs = [
4 SELECT Id, Name, Phone
5 FROM Account
6 WHERE Industry = 'Technology'
7 WITH USER_MODE
8 ];
9 System.debug('Registros recuperados respetando seguridad: ' + accs.size());
10} catch (QueryException e) {
11 // El mensaje indicará qué campo o permiso falta
12 System.debug('Error de permisos en SOQL: ' + e.getMessage());
13}

7.2 Sharing Model

Regla: SIEMPRE declarar sharing en clases Apex.
KeywordUso
with sharingDEFAULT — respeta sharing rules. Usar para lógica de negocio normal.
without sharingIgnora sharing rules. Solo para operaciones de sistema (batch, integrations).
inherited sharingHereda 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)

ReglaDescripción
ApexUnitTestClassShouldHaveAssertsTests DEBEN tener assertions.
AvoidLogicInTriggerTriggers DEBEN delegar a handlers.
AvoidDmlStatementsInLoopsNUNCA DML en loops.
AvoidSoqlInLoopsNUNCA SOQL en loops.
ApexCRUDViolationVerificar CRUD antes de DML.
ApexSharingViolationsDeclarar sharing en classes.
ApexSOQLInjectionPrevenir SOQL injection.
AvoidHardcodingIdNo IDs hardcodeados.

8.2 Reglas de Mejores Prácticas

ReglaDescripción
DebugsShouldUseLoggingLevelDebug con nivel: System.debug(LoggingLevel.INFO, msg).
ApexAssertionsShouldIncludeMessageAssertions con mensaje descriptivo.
MethodNamingConventionsMétodos en camelCase.
ClassNamingConventionsClases en PascalCase.
FieldNamingConventionsVariables en camelCase.
OneDeclarationPerLineUna declaración por línea.
AvoidGlobalModifierEvitar global (excepto webservices).

9Versionado y Release Management

9.1 Versionado Semántico

Formato: MAJOR.MINOR.PATCH.

ComponenteIncrementar cuandoEjemplo
MAJOR (X.0.0)Breaking changes, rediseño mayor2.0.0 → Nuevo data model
MINOR (x.Y.0)Nueva funcionalidad compatible2.1.0 → Nueva integración
PATCH (x.y.Z)Bug fixes, mejoras menores2.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

InvoiceService.cls
apex
1/**
2 * @description Service for invoice lifecycle management and AFIP integration
3 * @author Vantegrate Development Team
4 * @date 2025-12-01
5 * @version 2.0
6 */
7public with sharing class InvoiceService {
8
9 /**
10 * @description Sends invoices to COMFIAR for AFIP authorization
11 * @param invoices List of invoices to process
12 * @return ProcessingResult Results including CAE numbers
13 * @throws IntegrationException When COMFIAR is unavailable
14 * @example
15 * List<Invoice__c> invoices = [SELECT Id FROM Invoice__c];
16 * InvoiceService.sendToComfiar(invoices);
17 */
18 public static ProcessingResult sendToComfiar(List<Invoice__c> invoices) {
19 // Implementation
20 }
21}

10.2 Documentación de Flows

Cada Flow debe incluir en Description:

Flow — Description
apex
1FLOW NAME: Invoice Authorization Automation
2
3PURPOSE:
4Sends new invoices to COMFIAR for AFIP authorization
5and 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 Line
12
13ERROR HANDLING:
14- Validation errors: Set ProcessingStatus__c = 'Error'
15- COMFIAR errors: Log to IntegrationLog__c, alert admin
16
17VERSION: 2.0
18LAST MODIFIED: 2025-12-01
19AUTHOR: Vantegrate Development Team

11Checklists 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

ElementoCase StylePatrónEjemplo
Custom ObjectPascalCase[Name]__cInvoice__c
Custom FieldPascalCase[Name]__cTotalAmount__c
Apex ClassPascalCase[Name][Suffix]InvoiceService
Apex MethodcamelCase[verb][Object]calculateTotal
Apex VariablecamelCase[name]invoiceList
Apex ConstantUPPER_SNAKE[NAME]MAX_RECORDS
Test ClassPascalCase[Class]TestInvoiceServiceTest
Test MethodcamelCasetest[M]_[S]_[R]testCalc_Valid_Ok
TriggerPascalCase[Object]TriggerInvoiceTrigger
LWC ComponentcamelCase[descriptive]invoiceForm
LWC in HTMLkebab-case<c-[name]><c-invoice-form>
LWC PropertycamelCase[name]isLoading
LWC ConstantUPPER_SNAKE[NAME]MAX_FILE_SIZE
Flow API NamePascalCase[Obj]_[Action]Invoice_SendToAfip
Flow VariablecamelCasevar[T]_[Name]varB_IsValid
Flow DecisionSentence[Question]?Is Valid?
Permission SetPascalCase[Obj]_[Access]Invoicing_Admin
Validation RulePascalCase[O]_[F]_[Rule]Invoice_CAE_Required
Record TypePascalCase[Obj][Segment]InvoiceDraft
Page LayoutMixed[Obj] Layout - [V]Invoice Layout - Draft
CSS Classkebab-case.[name].btn-primary

Fin del documento

Guía de Estándares Vantegrate · Versión 4.4

Volver al inicio

Manifiesto

Por qué existe esta guía

Porque un trigger mal escrito puede frenar un deploy de 10.000 registros.

Porque un SOQL dentro de un loop puede voltear una transacción que tardó semanas en diseñarse.

Porque un campo sin Field Level Security puede exponer datos de un cliente que confió en vos.

Porque el código bueno es el que nadie nota: sigue funcionando mientras el negocio crece, la Org se expande y el equipo cambia.

Esta guía no existe para limitarte. Existe para que el código que escribís hoy siga haciendo feliz a alguien dentro de tres años — aunque esa persona nunca sepa que fue tu mano la que lo dejó así.

El juramento del desarrollador Vantegrate

Por la plataforma, por el equipo, por el cliente.

  • 01Prometo escribir código que otros puedan leer.
  • 02Prometo no duplicar un trigger donde ya existe uno.
  • 03Prometo respetar los límites de la plataforma antes que mi elegancia.
  • 04Prometo verificar los permisos antes de consultar los datos.
  • 05Prometo dejar el repo mejor de como lo encontré.
  • 06Prometo que mis tests dirán algo — no solo cubrirán líneas.
  • 07Prometo recordar que el código más fácil de mantener es el que no escribí.

Firmado por cada desarrollador Vantegrate

Guía v4.4

Equipo Vantegrate en evento Salesforce Buenos Aires

Nos integramos con las plataformas que ya usás

SalesforceOracleSAPSalesforce Marketing CloudMicrosoft Dynamics 365HubSpotWhatsApp BusinessSalesforceOracleSAPSalesforce Marketing CloudMicrosoft Dynamics 365HubSpotWhatsApp Business
Developers Salesforce

¿Sos developer Salesforce?

Trabajamos con profesionales certificados que construyen sobre estos estándares todos los días. Si compartís nuestra forma de pensar el código, queremos conocerte.

Sumate al equipo
Empresas

¿Tenés una Org que necesita IA?

Aplicamos estos estándares a cada implementación. Desde 2009 en el ecosistema Salesforce, con aplicaciones que pasaron el Security Review.

Hablemos sobre tu Org
Equipo Vantegrate en oficina al atardecer — empresa de agentes de IA
Equipo Vantegrate en pasillo de oficina — cultura de trabajo remoto
Desarrolladores Vantegrate trabajando con laptops — desarrollo de IA empresarial
Equipo Vantegrate trabajando junto al puerto — empresa de inteligencia artificial
Equipo Vantegrate en sala de reuniones — estrategia de automatización con IA
Equipo Vantegrate trabajando con vista al río — agentes de IA en Argentina