offdataai
Sales & CRM · data model template

Sales Pipeline Analytics data model

Vendor-neutral Kimball pipeline mart focused on forecasting, velocity, and rep activity: an accumulating-snapshot opportunity fact with milestone date keys, a daily opportunity stage snapshot for pipeline waterfalls, and a transaction-grain sales-activity fact over conformed account/contact/sales-rep/product/stage/campaign dimensions. For Salesforce-specific objects — lead conversion, OpportunityLineItem, record types, field history — use the Salesforce Sales Cloud Analytics template.

Source-agnostic sales-pipeline analytics that works across any CRM (HubSpot, Pipedrive, Microsoft Dynamics, Salesforce): the opportunity lifecycle, daily pipeline stage snapshots, and sales-rep activity over a conformed SCD2 account dimension with contact, sales-rep, product, stage, and campaign dimensions for forecasting, velocity, win/loss, and rep-productivity analytics. It is a Kimball dimensional model: fact tables at a declared grain surrounded by conformed dimensions, ready for BI tools and a semantic layer.

KimballSales & CRMGDPRSOX
10
tables
108
columns
13
relationships
6
PII columns

Opening the template creates a project with the ERD, platform-native DDL, a dbt project and documentation already generated (recommended platform: Snowflake). Edit it in plain English or on the canvas, then ship it to any supported warehouse.

Subject areas

pipelineactivityconformed_dimensions

Design decisions

  • Accumulating snapshot for opportunities

    A deal moves through created → qualified → proposal → closed with well-defined milestones; an accumulating snapshot yields stage lag and cycle-time metrics from a single row per opportunity.

  • Daily stage snapshot alongside the accumulating fact

    Pipeline waterfall, snapshot-over-snapshot movement, and velocity require the value and stage of every open deal captured daily, which the accumulating fact (which overwrites) cannot provide.

  • Transaction fact for sales activity

    Rep productivity and engagement are measured at call/email/meeting grain, independent of whether an opportunity exists yet.

  • SCD2 on account, contact, and sales rep

    Territory realignments, account tier changes, and contact role moves must be analysed as-of, so descriptive history is versioned.

Tables in the Sales Pipeline Analytics model

Every table with its grain, columns, types and keys. PK marks a primary key, BK a business key and PII a column classified as personal data, which gets a masking strategy by default.

Fact tables (3)

fct_opportunity

Grain: one row per sales opportunity (accumulating snapshot across the deal lifecycle)

Accumulating-snapshot fact — one row per opportunity; milestone date keys and stage update as the deal progresses.

ColumnTypeKeys
opportunity_keybigintPK
account_keybigint
contact_keybigint
sales_rep_keybigint
campaign_keybigint
current_stage_keybigint
created_date_keybigint
qualified_date_keybigint
proposal_date_keybigint
expected_close_date_keybigint
closed_date_keybigint
opportunity_idvarchar
opportunity_namevarchar
opportunity_typevarchar
amountdecimal
weighted_amountdecimal
annual_recurring_revenuedecimal
win_probabilitydecimal
is_wonboolean
is_closedboolean
sales_cycle_dayssmallint
forecast_categoryvarchar

fct_opportunity_stage_snapshot

Grain: one row per open opportunity per day (periodic snapshot)

Daily pipeline snapshot — captures stage and value of every open deal for waterfall/velocity analysis.

ColumnTypeKeys
date_keybigint
account_keybigint
sales_rep_keybigint
stage_keybigint
opportunity_idvarchar
amountdecimal
weighted_amountdecimal
win_probabilitydecimal
days_in_current_stagesmallint
days_opensmallint
is_stalledboolean

fct_sales_activity

Grain: one row per sales activity (call, email, meeting)

Transaction-grain sales-activity fact for rep productivity and engagement analytics.

ColumnTypeKeys
sales_activity_keybigintPK
date_keybigint
account_keybigint
contact_keybigint
sales_rep_keybigint
activity_idvarchar
activity_typevarchar
activity_directionvarchar
duration_minutessmallint
activity_countsmallint
is_connectedboolean
is_meeting_bookedboolean

Dimension tables (6)

dim_date

Grain: one row per calendar day

ColumnTypeKeys
date_keybigintPK
full_datedateBK
month_numbersmallint
quartersmallint
yearsmallint
fiscal_quartervarchar
fiscal_yearsmallint
is_quarter_endboolean
is_business_dayboolean

dim_account

Grain: one row per account per SCD2 version

SCD type 2

ColumnTypeKeys
account_keybigintPK
account_idvarcharBK
account_namevarchar
industryvarchar
account_typevarchar
account_tiervarchar
annual_revenue_bandvarchar
employee_bandvarchar
billing_countryvarchar
billing_statevarchar
owner_regionvarchar
is_target_accountboolean
is_active_customerboolean

dim_contact

Grain: one row per contact per SCD2 version

SCD type 2

ColumnTypeKeys
contact_keybigintPK
contact_idvarcharBK
first_namevarcharPII
last_namevarcharPII
emailvarcharPII
phonevarcharPII
job_titlevarchar
seniorityvarchar
buyer_rolevarchar
is_primary_contactboolean

dim_sales_rep

Grain: one row per sales rep per SCD2 version

SCD type 2

ColumnTypeKeys
sales_rep_keybigintPK
sales_rep_idvarcharBK
rep_namevarcharPII
rep_emailvarcharPII
sales_teamvarchar
sales_rolevarchar
territoryvarchar
regionvarchar
segmentvarchar
quota_bandvarchar

dim_product

Grain: one row per product/SKU

ColumnTypeKeys
product_keybigintPK
product_idvarcharBK
product_namevarchar
product_familyvarchar
product_linevarchar
pricing_modelvarchar
list_pricedecimal

dim_campaign

Grain: one row per marketing campaign

ColumnTypeKeys
campaign_keybigintPK
campaign_idvarcharBK
campaign_namevarchar
campaign_typevarchar
channelvarchar
start_datedate
end_datedate

Lookup tables (1)

dim_stage

Grain: one row per opportunity sales stage

ColumnTypeKeys
stage_keybigintPK
stage_codevarcharBK
stage_namevarchar
stage_ordersmallint
default_win_probabilitydecimal
is_closedboolean
is_wonboolean

Relationships

Each relationship is a foreign key on the first table referencing the second.

  • fct_opportunity.account_key → dim_account (many-to-one)
  • fct_opportunity.contact_key → dim_contact (many-to-one)
  • fct_opportunity.sales_rep_key → dim_sales_rep (many-to-one)
  • fct_opportunity.campaign_key → dim_campaign (many-to-one)
  • fct_opportunity.current_stage_key → dim_stage (many-to-one)
  • fct_opportunity_stage_snapshot.date_key → dim_date (many-to-one)
  • fct_opportunity_stage_snapshot.account_key → dim_account (many-to-one)
  • fct_opportunity_stage_snapshot.sales_rep_key → dim_sales_rep (many-to-one)
  • fct_opportunity_stage_snapshot.stage_key → dim_stage (many-to-one)
  • fct_sales_activity.date_key → dim_date (many-to-one)
  • fct_sales_activity.account_key → dim_account (many-to-one)
  • fct_sales_activity.contact_key → dim_contact (many-to-one)
  • fct_sales_activity.sales_rep_key → dim_sales_rep (many-to-one)

Related templates

All templates →
Start for $1

From requirements to AI-ready context, in one platform.

Describe your business in a conversation, start from a template or connect your own database. Your first model is ready in minutes.

Get startedBook a demo

Plans from $1/month · cancel any time