---
title: "RevOps engineering"
description: "A synthetic revenue-operations workbench: normalization, deduplication, enrichment, scoring, routing, simulated CRM writes, and failure handling. No live CRM and no real prospects."
canonical: "https://www.ayushrai.site/pow/revops-engineering/"
last-updated: "2026-10-19"
---

# RevOps engineering

Source: https://www.ayushrai.site/pow/revops-engineering/
Markdown: https://www.ayushrai.site/pow/revops-engineering.md

A synthetic revenue-operations workbench: normalization, deduplication, enrichment, scoring, routing, simulated CRM writes, and failure handling. No live CRM and no real prospects.

I engineer the systems behind predictable revenue operations.

From messy prospect data to actionable pipeline intelligence, I build the data pipelines, automations, controls, and analytics that help revenue teams operate more reliably.

REVFLOW is Revenue Operations Workbench. REVFLOW is a name for this portfolio demonstration. It is not a shipped product and it does not replace RevenueRoles or the Revenue Intelligence Engine.

The workbench uses fictional companies and `.example` addresses. It does not call an enrichment API, write to a CRM, or send email.

## Thesis

- Prospect records are duplicated, so two owners work the same person.
- CRM fields arrive under different names, so reports group the same fact apart.
- Enrichment data is stale and overwrites a newer value a person already checked.
- Routing rules match more than one owner, and the system hides which rule won.
- Sales activity is stored in a tool the CRM never hears about.
- A workflow trigger runs twice and creates two follow-up tasks.
- Pipeline stages are updated by different tools with different stage names.
- Attribution is missing, and a dashboard fills the gap with a silent default.
- A dashboard aggregate does not match the rows underneath it.
- An automation fails and the only trace is an empty queue.

The point of the engineering is a system that is observable and consistent. Better tools do not by themselves produce revenue.

## Architecture

### Ingestion (Asynchronous)

Accept a demo form, a CSV, an event file, a signup, or a referral without dropping a bad row.

Inputs: Source payloads and an idempotency key.

Outputs: A stored raw row and a receipt.

Failure: A repeated key must not create a second prospect.
### Canonical model (Synchronous)

Map source field names onto one prospect shape and keep provenance.

Inputs: Raw rows.

Outputs: Canonical prospects plus unmapped keys.

Failure: An unknown key is reported, not deleted.
### Validation (Synchronous)

Check required fields, enums, and email syntax. Syntax is not deliverability.

Inputs: Canonical prospects.

Outputs: Issues attached to the same rows.

Failure: A missing email stops routing. The row stays visible.
### Identity resolution (Synchronous)

Score contact duplicates and account links with explicit rules.

Inputs: Canonical prospects.

Outputs: Pairs, a heuristic score, and a merge decision.

Failure: A shared domain must not merge two people.
### Enrichment adapters (Asynchronous)

Propose values with a source, a time, and a freshness label. This demo uses a local fixture.

Inputs: A domain and the current field values.

Outputs: Proposals, conflicts, and provider errors.

Failure: A rate limit, a timeout, or a stale value must not be written as fact.
### Qualification (Synchronous)

Explain fit, intent, engagement, and confidence separately.

Inputs: A canonical prospect and the current weights.

Outputs: Four numbers and an illustrative band.

Failure: Missing fields lower confidence. They are not guessed.
### Routing (Synchronous)

Apply ordered rules and leave an explicit unassigned or review state.

Inputs: The prospect, the score, and the fictional roster.

Outputs: The matching rules and one owner, or none.

Failure: An unavailable owner is not silently replaced.
### Workflow orchestration (Asynchronous)

Move one prospect through validate, match, score, assign, preview, write, and verify.

Inputs: A prospect and a confirmation.

Outputs: A step list with completed, failed, skipped, or waiting states.

Failure: A failed step skips the follow-up instead of pretending the run finished.
### CRM adapter (Asynchronous)

Turn a canonical prospect into a create or update. This phase only stores the result in memory.

Inputs: A confirmed preview.

Outputs: A simulated response and a verification diff.

Failure: Partial writes, rate limits, and conflicts stay visible.
### Activity and tasks (Asynchronous)

Record the follow-up once.

Inputs: A successful CRM write.

Outputs: One task keyed by the prospect.

Failure: A retry must not create a second task.
### Analytics (Either)

Aggregate the same rows the workbench is showing, with the definition beside the number.

Inputs: Prospects, pairs, workflow runs, and CRM events.

Outputs: Rates and the row ids behind them.

Failure: A claimed total that disagrees with a recount is a discrepancy, not a new number.
### Observability (Asynchronous)

Keep the idempotency key, the rule trace, and the adapter response.

Inputs: Every state change.

Outputs: An audit a person can read.

Failure: A silent success with no event is treated as a bug.

## Decisions

### CRM-centric model or a canonical model

Source fields do not share names, and a CRM field list changes when the CRM does.

Demo: REVFLOW maps into a canonical prospect, then into a simulated CRM shape. The CRM is a destination, not the only schema.

Trade-off: A canonical model is extra surface area. It is useful when more than one source and more than one destination exist. A single form that only creates CRM leads does not need it.
### Real-time enrichment or batch enrichment

A person waiting on a form wants an answer now. A provider charges per call and limits the rate.

Demo: The workbench proposes fixture values when a row is inspected. It does not call a provider.

Trade-off: Real-time enrichment lowers the wait and raises cost and failure during the request. Batch enrichment is easier to retry and slower to show.
### Deterministic routing or AI-assisted routing

Ownership decides who is accountable for a person. An opaque suggestion is hard to audit.

Demo: Rules run in a fixed order. A model is not asked to pick an owner.

Trade-off: Rules are auditable and brittle when the business changes. A model can notice messy cases and can also assign the wrong person without a trace.
### Automatic merge or human review

Exact emails are usually the same person. Similar company names are often not.

Demo: An exact email may be merged after a click. A shared domain never merges two contacts by itself.

Trade-off: Automatic merges are fast and can combine two people. Review is slower and safer.
### Native CRM workflows or an external orchestrator

CRM automation is close to the record. It is also hard to test, version, and retry outside that CRM.

Demo: REVFLOW is the external orchestrator, and the CRM is a simulated adapter behind a preview.

Trade-off: An external service can be tested and can also drift from CRM permissions and field limits.
### Event-driven processing or a schedule

Events are timely and can arrive twice. A schedule is easier to replay and slower.

Demo: The queue is event-shaped, and the idempotency key is what makes a repeat safe. Nothing is deployed as a worker.

Trade-off: Events need keys, ordering, and a dead-letter path. Schedules need a watermark and can leave a person waiting.
### One dashboard or explicit metric definitions

Two charts can use the same words and different denominators.

Demo: Each rate names its numerator and denominator, and the rows behind it can be opened.

Trade-off: Definitions take space on the page. Without them, a duplicate rate can be argued forever.

## Revenue Intelligence Engine

The project addresses a GTM list that is researched by hand: fit, timing, a contact, and a reason to talk, with no shared trace of why an account was prioritized.

A run loads a synthetic company file, normalizes domain and name, drops later rows that share a domain or a normalized name, calls a mock enrichment provider, reads signals that are already on the fixture, scores the account with a fixed 100-point rubric, researches the top accounts, and waits for a person to approve an export.

The repository is a FastAPI service and a Next.js console. Scoring lives in app/scoring/icp.py. The weights are ICP fit 25, growth 20, hiring 20, technology fit 15, GTM need 10, and contactability 10. The numeric score is not produced by a model. Research uses an OpenAI-compatible client only when a key is set, and otherwise a deterministic fallback.

Companies, contacts, signals, and enrichment are synthetic. The default path described in the repository is 42 companies, 3 duplicates dropped, and the top 5 researched. I did not re-run that count for this page.

There is no Clay, Apollo, or CRM adapter. There is no outbound send. Without a database URL, the deployed store is SQLite in a temporary directory and does not survive a cold start; the report route seeds a run when the store is empty.

On 19 Oct 2026, revopy.vercel.app and cashmaker-two.vercel.app both returned a page titled Revenue Intelligence Engine with the same synthetic-data banner. The project record on this site stores the cashmaker URL. I did not treat either host as proof that a CRM is connected.

Repository: https://github.com/ayushrai-hub/REVENUE-INTELLIGENCE-ENGINE

Demo: https://revopy.vercel.app/

## Roadmap

- Phase 1: Frontend workbench and deterministic simulation — Implemented on this page
- Phase 2: Typed schemas and a reusable workflow engine — Proposed
- Phase 3: Persistent storage and audit records — Proposed
- Phase 4: CRM adapter against a vendor sandbox — Proposed
- Phase 5: Scheduled and event-driven ingestion — Proposed
- Phase 6: Production enrichment with provider controls — Proposed
- Phase 7: Analytics reconciliation and monitoring — Proposed
- Phase 8: Permission hardening, operational tests, and deployment — Proposed

Illustrative contracts on the HTML page are not a production API.

_Unverified award metrics are omitted. Wording matches the public site._
