If you're building software for pharmaceutical supply chains, you need to understand something: your users will implement workarounds on Day One.
Not because your software is bad. Because the system you're trying to model is fundamentally unmodelable.
Let me show you what I mean.
The System Requirements Look Straightforward
Product Owner: "We need real-time inventory visibility across all distribution centers."
You: "Sure, we'll implement event-driven architecture with WebSocket updates."
Product Owner: "Perfect. Also track expiration dates, batch numbers, and temperature compliance."
You: "Easy. We'll add those fields to the data model."
Product Owner: "Great! When can we see a demo?"
You ship it in three months. It works beautifully.
Nobody uses it.
The Hidden Requirements
Here's what wasn't in the spec:
Requirement 1: "Available" Has Six Different Meanings
When your system shows 500 units available, it might mean:
- Available AND released by QC
- Available BUT pending quality review
- Available BUT reserved for ongoing clinical trial
- Available BUT at a location we can't ship from today
- Available BUT only if the pending deviation gets approved
- Available BUT we're not actually sure because the last audit found inventory discrepancies
Your boolean is_available flag doesn't capture this. And the complexity of modeling all these states exceeds the value of the feature.
So users add a spreadsheet where they track "real availability."
Requirement 2: Lead Time Isn't a Number
Your system asks: "What's the lead time from Belgium to New York?"
The user wants to answer: "7 days if nothing goes wrong, but it goes wrong 40% of the time, and when it does, we can't predict how long it takes."
You implement lead_time_days: integer.
The user mentally adds three days every time they look at it.
Requirement 3: The Calendar Lies
You built a beautiful production scheduling system.
It shows Manufacturing finishing Batch 427 on March 15th.
What it can't show:
Quality testing takes 45-90 days depending on what they find
If stability samples show unexpected results, add another 30 days
If there was any deviation during production, add an investigation period
If the deviation requires regulatory notification, add another 45 days
Manufacturing finishes on March 15th.
Quality releases it on June 2nd.
Your "expected delivery" calculation was wrong by 79 days, but your code was perfect.
Why This Keeps Happening
Most supply chain software fails in pharma because engineers build for the idealized process while users operate in regulatory reality.
Here's the gap:
What Engineers See:
Manufacturing → Quality Control → Release → Ship
(5 days) (45 days) (instant) (7 days)
Total: 57 days
What Actually Happens:
Manufacturing → Quality finds issue → Investigation →
(5 days) (day 30 of 45) (15 days)
→ Stability retest → Additional documentation →
(30 days) (10 days)
→ QC approval → Regulatory notification → Release
(5 days) (45 days) (instant)
Total: 145 days (and we still shipped on time somehow)
The software models the first flow. Reality runs on the second.
The Three Pharma-Specific System Constraints
If you're building for this industry, bake these in from the start:
1. Compliance Creates Unpredictable Latency
Every decision point has a "...unless compliance says no" clause.
Your shipping optimization algorithm finds the fastest route. Compliance blocks it because that carrier isn't validated for this product temperature range.
Your inventory system suggests transferring stock between locations. Regulatory says no because the receiving facility isn't approved for that batch's manufacturing site.
You can't model this with business rules because the compliance team's decision-making process includes:
- Interpretation of regulations
- Risk tolerance that varies by product
- Historical relationships with regulators
- Informal guidance that isn't written down
Build for compliance gates that reject 5-15% of algorithmic recommendations and you'll be closer to reality.
2. State Changes Happen Outside Your System
A batch status changes from "in production" to "on hold" because:
- A piece of equipment failed validation
- A raw material supplier had an FDA warning letter
- A deviation was discovered during an audit
- Someone in Quality noticed something that "doesn't look right"
None of these events flow through your API.
Your system shows the batch as on-schedule until someone manually updates it three days later.
By then, the shortage is already happening.
Design for latency in state updates. Assume your system is always 24-72 hours behind reality for anything involving quality or compliance.
3. Optimization Is Often Illegal
Your algorithm suggests consolidating two shipments to save costs.
Compliance says no because:
- Combining the shipments exceeds the validated load configuration
- The products have different temperature requirements
- Regulatory requires separate chain of custody documentation
- The packaging qualification doesn't cover mixed loads
In pharma, the optimal solution is frequently non-compliant.
Which means your optimization engine is building recommendations that will never be implemented.
What To Build Instead
Stop trying to automate decisions. Start building systems that surface the right context for human judgment.
Build for Skepticism
_// Don't show this:
{ inventory: 500, status: "available" }
// Show this:
{
inventory: 500,
status: "available",
confidence: "medium",
caveats: [
"120 units pending quality review",
"Last 3 batches from this site had documentation delays",
"Current site utilization: 94% (delays likely)"
],
historical_accuracy: "72% of 'available' became actually shippable"
}_
Build for Uncertainty
_# Don't calculate this:
def calculate_ship_date(production_end_date):
return production_end_date + timedelta(days=52)
Calculate this:
def estimate_ship_date_range(batch_id, confidence_level=0.8):
base_timeline = 52
historical_variance = get_batch_variance(batch_id.product, batch_id.site)
compliance_risk = assess_compliance_risk(batch_id)
return {
"earliest": base_timeline + 0,
"likely": base_timeline + historical_variance.median,
"latest": base_timeline + historical_variance.p80,
"confidence": confidence_level,
"assumptions": [...],
"risk_factors": [...]
}_
Build for Workarounds
_Accept that users will:
- Export to Excel
- Keep offline trackers
- Override your calculations
- Ignore your recommendations 40% of the time
Make it EASY:
- One-click export of any view
- Bulk override capabilities
- "Why did you override?" capture (to improve your model)
- Make workarounds visible, not hidden_
The Real Success Metric
Your system succeeds when users say:
"The software is wrong about 30% of the time, but it surfaces the right questions so we catch problems early."
Not:
"The software is accurate and we trust it completely."
Because in pharmaceutical supply chains, trust comes from acknowledging uncertainty, not hiding it.
Further Reading
This is based on patterns observed across 15 major pharmaceutical companies dealing with 347 active drug shortages in January 2026.
[Read full article: "Pharma Supply Chain Challenges in 2026"]
What patterns have you seen building healthcare/supply chain systems? Drop them in the comments.
Top comments (0)