Veeva CRM is the best-behaved feed you have. It comes from your own system, it arrives daily, and the data sources reference calls it generally well structured. That is exactly why its failures get missed. They are never in the call record. They are in what the call record joins to.
At one rare-disease biotech, Veeva CRM carried field activity, territory alignment, and sales goals, Veeva Network held the HCP master, and Veeva Vault held medical communications. Field activity, the weekly report reps live in, joins prescriber reference, alignment, targeting, and activity data to show calls and samples against plan. Every one of those joins is a place for a row to vanish.
Six checks that sit at the joins
| Check | Failure it catches | Test |
|---|---|---|
| Every call’s account exists in the account master | Calls disappear from the roll-up | Reference Match, CRM activity to account master |
| Every prescriber key resolves to exactly one master record | A transposed NPI drops a prescriber; a duplicate splits credit | Valid NPI, then Unique Values on the master key |
| Activity and performance read the same alignment version | The two field reports never reconcile | Reference Match on the alignment version before the join |
| Territory totals still tie to the national total after an alignment load | A realignment moves a rep’s numbers with every value valid | Aggregate Balance against the prior delivery |
| Every target on the call plan still exists in the current master | Reps are sent to prescribers who are gone | Reference Match, target list to prescriber master |
| Every sample row resolves to a master prescriber and a product in the product dimension | Sample drops credited to nobody, or to a product the dimension lacks | Reference Match, sample fact to prescriber master and product dimension |
Failure modes from the data sources reference; tests from the commercial pharma testing post; the sample row follows how the platform models samples as a fact table.
Column checks see none of these. The account ID in the call is well formed. It just isn’t in the master. The testing post names this exact case, an account with sales activity that never made it into the account master, as the kind of failure only a test comparing two tables can see.
Prescriber keys are where Veeva meets everything else
Your call data is clean. The trouble starts when it meets a prescriber from another source. A transposed NPI in a specialty pharmacy feed no longer matches the NPI in Veeva, and the join drops that prescriber with the pattern test green. Two prescriber files that disagree put a ghost on the targeting list, and alignment double-counts.
Veeva Network is one input to the master, not the whole answer. It tells you what it could match. An analytic master that links NPI, ME, DEA, and vendor provider IDs keeps the prescribers Network never mastered in view. The HCP duplicates answer has the full method.
Alignment changes on a schedule, so test on that schedule
Alignment is the part of CRM data that moves. The quarterly Veeva alignment load is one of the manual jobs hourly offshore teams spend their time on, next to chasing late vendor files and HCP master stewardship. After it lands, a rep’s numbers can drop 40 percent overnight while the underlying data stays correct.
Run the alignment checks on the load itself. If the national total holds and territories move, the mapping did it. If activity and performance disagree, check which alignment version each one read. The alignment and incentive comp answer covers the payout side.
Turn the field’s rules into tests
Sales operations already knows rules no profiler can infer. When sales ops says a rep cannot hold two territories in the same week, that becomes a test. When the incentive comp analyst says samples do not count toward quota, that becomes a test too. Each is a Custom Condition, one row-level rule in your repository rather than a line in a spec.
Profiling covers the rest. Freshness and volume checks on the daily CRM extract catch a missed or partial delivery, and DataOps TestGen generates them from what it observes.
Samples are a fact table, so test them like one
In DataKitchen’s pharma platform, samples are time-series data. Each row is a date, a prescriber, a product, and a quantity, and it lands in a fact table in one of the interlinked star schemas that share physician, product, time, and territory dimensions. So a sample is a join problem like the rest of CRM.
It gets the tests any fact keyed to an HCP and a product gets. Every row resolves to a master prescriber by NPI. Every product key resolves to a valid product and NDC in the product dimension. No orphan keys on either side. Volume and distribution checks run over time, so a week with half the usual drops, or one product’s share jumping, gets flagged before the field activity report shows it. And the loaded rows reconcile against the source extract.