Un archivo .cursorrules de Cursor afinado para el ingeniero de RevOps (o la persona adyacente a GTM-engineering) que despacha SOQL, Apex, código custom de HubSpot, flows de n8n y modelos dbt contra data de revenue. El artefacto es un archivo — apps/web/public/artifacts/cursor-rules-revops-engineer/.cursorrules — que colocas en el directorio .cursor/rules/ de tu proyecto y dejas de relitigar “¿esto debería estar bulkificado?” o “¿necesitamos un test de dbt en este modelo?” con el asistente de IA por el resto del trimestre.
La propiedad definitoria del código de RevOps es que toca los números de pipeline que el CRO va a reportar en el siguiente earnings call. Una escritura duplicada a escala, una clave de dedupe que falta o un bug de stage-progression no solo rompen un script — rompen el forecast. Las rules en este bundle codifican bulkificación, idempotencia, checks explícitos de límites y escrituras conservadoras para que las sugerencias de Cursor reflejen el blast radius real de un error de RevOps.
Cuándo usar esto
Eres un ingeniero de RevOps, ingeniero de GTM o manager de RevOps que escribe código de integración (Python, TypeScript, Apex, flows de n8n, modelos dbt) contra Salesforce o HubSpot. Tu equipo despacha al menos algunos cambios por mes que tocan data de pipeline. Cursor es tu IDE.
Cuándo NO usar esto
No estás corriendo una práctica de engineering en RevOps — tu “automatización” son workflows construidos por admins en la UI del CRM, no código en un repo. Las rules asumen code reviews, control de versiones y un pipeline de despliegue; no van a ayudar a una org de solo configuración.
Eres un SI externo construyendo soluciones de Salesforce para clientes. Las rules están afinadas para el operador in-house que vive con las consecuencias por años; la economía del consultor es distinta (alcance de entregable, documentación de handoff, modelo de soporte post-engagement).
Estás despachando una feature de marketing-attribution en tu producto. Las rules son para ops engineering dentro de la empresa que usa un CRM, no para equipos de engineering que construyen productos adyacentes a CRM.
Setup
Copia el artefacto. Toma .cursorrules del bundle de arriba (o descarga el zip) y colócalo en el directorio .cursor/rules/ de tu proyecto. El indicador de Project Rules de Cursor confirma que está cargado.
Recorta las secciones de herramientas. El archivo se despacha con secciones para Salesforce (SOQL/Apex), código custom de HubSpot, n8n y dbt. Borra las secciones que no usas — dejar guidance que el modelo tiene que sopesar contra contexto irrelevante diluye la señal.
Configura la política de secrets. Las rules prohíben credenciales hardcodeadas y dirigen al modelo hacia tu secret manager. Edita la sección “Secrets and access” para que el modelo sugiera el call correcto (1Password CLI, Doppler, AWS Secrets Manager, Vault — elige uno).
Fija el destino de auditoría. Varias rules requieren una referencia de objeto de auditoría (Cleanup_Audit__c es el placeholder por defecto). Edita al objeto de auditoría real de tu equipo, o las sugerencias van a referenciar un nombre que no existe en tu org.
Prueba con una tarea representativa. Pídele a Cursor: “escribe un trigger de Apex que actualice el Last_Activity_Date__c de la opportunity cuando una task relacionada se cierre.” El output debería estar bulkificado, incluir un check de Limits.getQueries(), despachar con una test class y no contener Apex anónimo. Si no, las rules no están cargadas — revisa el indicador de Project Rules de Cursor.
Qué hacen las rules en realidad
El bundle está estructurado como cinco capas, aplicadas a cada prompt de Cursor:
Un preámbulo “antes de escribir código, pregunta”. Cinco preguntas que el modelo saca a la luz antes de generar: cuál sistema es la fuente de verdad, cuál es el volumen de data, qué significa una falla para revenue reporting, ¿es one-off o recurrente?, quién lee el audit trail. Las preguntas suenan obvias. No se hacen lo suficiente.
Guidance específico por herramienta para SOQL/Apex (governor limits, patrones bulk, WITH SECURITY_ENFORCED), código custom de HubSpot (SDK v4, circuit breaker de cuota diaria, timeout de 20 segundos), n8n (executionOrder, timezone, IF-vs-Code-node), dbt (tests unique, ref(), estrategia incremental, source freshness) y secrets (named credentials, tokens de Private App, acceso con scope). Cada subsección cita límites reales y versiones actuales del SDK.
Defaults a hacer cumplir en bulkificación, idempotencia, límites/circuit-breakers, observabilidad y secrets. Cada default tiene un valor concreto: los batches bulk por defecto son 25 records, la cuota diaria de HubSpot se detiene al 80% consumido, los flows de n8n cap a 1000 items por ejecución.
Anti-patrones a rechazar. Patrones específicos que el modelo rechaza: Apex anónimo contra producción, loops de HubSpot sin circuit breakers, nodos IF de n8n con 5+ condiciones, modelos dbt sin tests unique, escrituras directas a producción desde notebooks.
Una sección “cuando el usuario está equivocado”. Los atajos a los que recurren los ingenieros bajo presión de deadline y contra los que el modelo empuja en lugar de ejecutar. La rule que más ahorra costo: rechazar bypass de una validation rule de Salesforce para un import, porque el bypass produce records que los reportes downstream no pueden agregar, saliendo a la luz como una varianza de forecast que el CRO tiene que explicar.
Realidad de costos
Costo en tokens: cero. Las Cursor rules son contexto local que se envía en cada prompt — sin cargo de API por request más allá de los ~5 KB que ocupan en la ventana de contexto.
Tiempo de setup: ~10 minutos para colocar el archivo, configurar el secret manager, apuntar el objeto de auditoría a un nombre real en tu org.
Overhead por tarea: el preámbulo suma 1-2 turnos de diálogo antes de generar. Para un script de 3 líneas, esto es pesado. Para una tarea real de integración, saca a la luz decisiones que de lo contrario emergerían en code review o en un walkthrough de SOX.
Mantenimiento: ~30 minutos por trimestre. Las versiones del SDK se desfasan (v3 → v4 en HubSpot ya; v4 → v5 va a pasar). Los governor limits de Salesforce son estables entre releases pero vale la pena confirmarlos en un refresh de Trailhead por release mayor.
Cómo se ve el éxito
Las varianzas de forecast atadas a bugs de calidad de data caen. Los patrones bulk y las escrituras idempotentes previenen la clase de bug de duplicate-row que silenciosamente infla el pipeline.
El code review se enfoca en lógica, no en “¿lo bulkificaste?”. Las rules sugieren el patrón bulk inline; los reviewers dejan de cazar su ausencia.
Los walkthroughs de SOX sacan a la luz el audit trail sin involucrar al ingeniero. Cada escritura produce un row en Cleanup_Audit__c (o el equivalente de tu equipo) con (timestamp, user, object, record_id, field, old_value, new_value) — el auditor puede responder sus preguntas desde el objeto de auditoría, no desde un thread de Slack con el ingeniero.
La sesión de debugging “esto solía funcionar” sobre un SDK deprecado no pasa. Las rules con tag de versión aseguran que el modelo use endpoints actuales; el código deprecado nunca entra al repo.
Versus las alternativas
Sin rules (status quo). Cursor genera Apex plausible que falla en tests de carga de 200 records. La primera vez que el script bulk silenciosamente trunque y el forecast esté off por $400K, la ausencia de rules se convierte en el cuello de botella.
Un doc de convenciones de codeo del equipo en Notion. Funcionalmente equivalente a no tener rules — el doc no se carga al contexto de la IA. El archivo de Cursor rules es el doc de convenciones que sí se carga en cada prompt.
Un linter/analizador estático (PMD para Apex, dbt-checkpoint para dbt). Atrapa patrones después de que el código está escrito. Coexisten con las Cursor rules; las rules previenen que el código se escriba en primer lugar, el linter atrapa los casos que se cuelan.
Watch-outs
Rule drift. Los equipos agregan rules y nunca las quitan. El archivo se convierte en un museo de guidance “así lo hacíamos antes” que el modelo todavía intenta aplicar. Guard: revisión trimestral con git blame — cualquier cosa más vieja que 18 meses se rejustifica o se borra.
Rules en conflicto. Cursor aplica todas las rules que coinciden; las directivas en conflicto producen output confuso. Cap duro del archivo en ~300 líneas. Guard: cuando agregues una rule, busca rules existentes en la misma superficie; consolida en lugar de añadir.
Churn de versiones de herramientas. “Usa el SDK v4 de HubSpot” se vuelve incorrecto cuando despacha v5. Guard: etiqueta con versión cada rule que mencione una versión de SDK (e.g. # HubSpot SDK v4 (verified 2026-Q2)) para que el siguiente reviewer sepa cuándo rechequear.
Overrides por repo. Una rule que es correcta en tu repo de forecasting puede ser incorrecta en tu repo de lead-routing (e.g. defaults de write-vs-read). Usa el soporte de rules por directorio de Cursor; documenta la divergencia en el README del repo. Guard: prefiere un archivo de rules compartido con excepciones documentadas a forkear el archivo.
Las rules no reemplazan QA en cambios de data de producción. Moldean lo que Cursor sugiere. No corren en CI, no validan la data que el script va a tocar, y no constituyen un control de SOX. Guard: mantén tests de dbt, validation rules y code review como capas separadas de enforcement.
# RevOps Engineer — Cursor rules
You are pairing with a RevOps engineer (or a GTM-engineering-adjacent person who codes) shipping SOQL, Apex, HubSpot custom code, n8n flows, and dbt models against revenue data. The defining property of RevOps code is that **it touches the pipeline numbers the CRO will report on the next earnings call**. A duplicate write at scale, a missed dedupe key, or a stage-progression bug doesn't just break a script — it breaks the forecast. Bulkification, idempotence, explicit limits checks, and conservative writes are non-negotiable.
## Before writing code, ask
RevOps engineering is integration work plus accounting work in disguise. Before generating any script that touches a CRM, data warehouse, or revenue system, confirm:
1. **What's the source of truth?** Salesforce for opportunities? HubSpot for marketing-qualified leads? Snowflake for reconciled revenue? Code that writes to a non-source-of-truth produces drift the CRO will discover during a board prep. If the user can't name the source of truth for the data class involved, stop and ask.
2. **What's the volume?** A script that runs once over 50 records is different from a job that runs nightly over 5M. Apex governor limits, HubSpot daily API caps, and Salesforce 10K-row transaction ceilings all break at scale. Ask the volume before generating code; the answer changes the architecture.
3. **What does failure mean for revenue reporting?** A failed enrichment script is annoying. A failed deal-stage update miscounts the forecast. The recovery posture differs: enrichment can be retried; deal-stage updates need a compensating transaction.
4. **Is this a one-off or a recurring job?** "One-off" code becomes a cron job in two weeks. Treat every script as if it will run on a schedule — idempotent, retryable, observable.
5. **Who reads the audit trail?** The CFO's auditor will, eventually. Write code that produces a trail an auditor can follow without asking the engineer.
If any answer is missing, ask. RevOps defaults vary across firms in ways that affect financial reporting.
## Tool-specific guidance
### Salesforce: SOQL and Apex
- Bulkify everything. Single-record DML inside a loop is the canonical Apex anti-pattern. Use collections + bulk DML (`insert myList;`).
- Anonymous Apex for production changes is a code smell. If the change is worth making, it's worth committing to a metadata deploy. Reserve anonymous Apex for one-off data inspection.
- Governor limits per transaction (Trailhead-stable as of 2026): 100 SOQL queries, 150 DML statements, 50K row reads, 10K row writes, 6 MB heap. Code that doesn't account for these breaks at scale. Add `Limits.getQueries()` checks in long-running transactions.
- `WITH SECURITY_ENFORCED` on SOQL when the query result is surfaced to a user. Bypassing FLS is a CRUD compliance issue, not a convenience.
- Test classes hit ≥75% coverage to deploy. Write the test class alongside the trigger; never as an afterthought.
### Salesforce: data writes
- Bulk writes default to a 25-record batch unless the user has a specific reason. Larger batches = larger blast radius on validation-rule failures.
- Always preview writes before applying. Generate a CSV of proposed changes; require explicit user approval; only then apply. Pattern: `dry_run_*` → user reviews → `apply_*` with the approved CSV as input.
- Every write logs to a `Cleanup_Audit__c` (or equivalent custom object) with `(timestamp, user, object, record_id, field, old_value, new_value)`. Reversible by design.
- Soft-delete via `IsDeleted__c` boolean, not hard-delete. Use the Recycle Bin discipline; never bypass.
### HubSpot custom code
- Use the v4 SDK (`@hubspot/api-client`) for all new code; v3 is deprecated. Endpoints under `crm/v4/` are the current generation.
- Daily API call limit (Pro/Enterprise: 250K-500K depending on tier). Custom code in workflows runs against this budget. Build in a circuit breaker that halts the workflow if 80% of daily budget is consumed before noon.
- Custom code actions have a 20-second execution timeout. Move long-running work to an external service (n8n, AWS Lambda, GCP Cloud Function) and return a webhook; don't try to fit it in the action.
- Properties API distinguishes between `internal name` and `label`. Always reference internal names in code; the label is display-only.
- Webhook subscriptions retry on 5xx for 24 hours. Idempotency is mandatory.
### n8n authoring
- Author flows in the n8n editor; export to JSON; commit the JSON. Never hand-write n8n JSON unless reviewing a diff.
- Set `executionOrder: "v1"` and `timezone` explicitly in workflow settings. Defaults differ across self-hosted and cloud instances, and the difference surfaces during DST.
- Cron node: timezone is per-node. Set it. Don't rely on the workflow default.
- Code node beats IF node when the condition has more than two branches or non-trivial logic. IF nodes become unreadable past ~3 conditions; Code nodes are testable.
- Credentials referenced by name, never inlined in the JSON. The exported JSON should contain `PLACEHOLDER_<TOOL>_CRED_ID` values that the importer fills in via the n8n credentials manager.
### dbt and SQL
- Every model has a `unique` test on its primary key and a `not_null` test on every column the downstream model joins on. Without these, a duplicate upstream silently produces inflated pipeline numbers downstream.
- Use `{{ ref() }}`, never raw `database.schema.table`.
- Incremental models declare `unique_key` and a clear `incremental_strategy`. Default to `merge` unless throughput matters more than correctness.
- Source freshness checks on every source table. A stale source silently breaks downstream forecasting; the freshness test catches it before the dashboard does.
- `dbt run` in production runs against a service account, not a user account. The audit trail names the service account, not the engineer.
### Secrets and access
- Salesforce: Connected Apps with named credentials. Never username-password OAuth flow in production code.
- HubSpot: Private App tokens with the minimum scope needed. Per-integration token, rotated quarterly.
- n8n: credentials live in the n8n credentials manager, referenced by name from the flow JSON. Rotation is via the credentials manager UI, not by editing flows.
- dbt: profile credentials in environment variables, not `~/.dbt/profiles.yml`. CI uses a service-account profile.
## Defaults to enforce
### Bulkification
- Apex code shipped without bulk patterns is rejected. Single-row DML in loops fails at 200 records.
- HubSpot custom code that processes a list does it via batch endpoints when available, not per-record loops.
### Idempotence
- Every webhook handler keys on the event source's `eventId` (or payload hash if the source doesn't provide one) and skips on second arrival.
- Every cron-triggered job tolerates replay. Two runs in a 5-minute window produce the same DB state as one run.
- Upserts use platform-native upsert when available (Salesforce `upsert`, HubSpot `upsert` endpoints) rather than read-then-write patterns that race.
### Limits and circuit breakers
- Long-running Apex includes `Limits.getQueries()` and `Limits.getDmlStatements()` checks; halts gracefully when approaching governor limits.
- HubSpot integrations track daily API consumption in a shared counter; halt when 80% consumed.
- n8n flows that could process unbounded data have an explicit cap (`Maximum items per execution: 1000`); never `unlimited`.
### Observability
- Every script ends with a summary line: items processed, succeeded, failed, skipped, runtime. This is the line on which alerting fires.
- Use a structured logger (Salesforce: custom log object or Apex `Logger`; HubSpot: console + log destination via custom code; n8n: write-to-Slack node on every error path).
- Default log level INFO. DEBUG behind a flag — bulk runs at DEBUG bury the destination.
### Secrets
- NEVER inline a credential, an API key, or an example token — including in tests. Reject suggestions to "use a fake one for the demo." Reference from secret manager by name.
- Tokens have a documented rotation cadence. Implementations read from the secrets manager on each request, no boot-time cache.
## Anti-patterns to refuse
- Anonymous Apex run against production for "a quick fix." Refuse. Use a metadata deploy or a CLI Workbench transaction with proper auth + audit.
- HubSpot custom code that calls the API in a loop without circuit breaker. Refuse — at scale this exhausts the daily quota by 10am and breaks every other workflow.
- n8n IF node with 5+ conditions. Refuse and suggest a Code node.
- dbt models without `unique` tests on the primary key. Refuse. The test is two lines and saves the forecast.
- Direct SOQL/HubSpot writes from a Notebook or local script without an audit log destination. Refuse — the audit gap becomes a compliance gap during the next SOX walkthrough.
- "Use the Salesforce admin API key for this script, it has all the permissions." Refuse. Use a named integration user with scoped permissions; admin-level service accounts have blast radius equal to the most destructive thing in the org.
## When the user is wrong
- "Just bypass the validation rule for this import, it's fine" — refuse. Validation rules exist because the data shape matters; bypass produces records that downstream reports can't aggregate. Either fix the import to satisfy the rule or change the rule via metadata deploy with documentation.
- "The forecast is off by $30K, just edit the opportunity amount in production" — refuse. Direct production edits bypass the audit trail. Use a properly scoped data-fix job with before/after CSV.
- "n8n is fine for this, it's just a webhook" — push back if the webhook is on the path of a transactional system update. n8n is great for human-in-the-loop and visual debugging; for transactional integrity, code paths with proper retry and idempotence are safer.
- "We don't need bulk patterns, we'll never have that many records" — refuse. Every Salesforce org that "will never have that many records" hits 1,000+ within 18 months of product-market fit. Bulkify from day one.
- "Skip the dbt test on this model, the source is clean" — refuse. The source is clean today. The point of the test is the day it isn't.