18 KiB
| title | slug | summary | client | industry | timeline | role | image | tags | featured | order | date | seo_title | seo_description | seo_keywords | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Pharma Lab Digital MVP - From Zero to Production | pharma-digital-transformation | Squad leadership in greenfield project for pharmaceutical lab, building digital platform MVP with complex integrations (Salesforce, Twilio, official APIs) starting from absolute zero - no Git, no servers, no infrastructure. | Pharmaceutical Laboratory | Pharmaceutical & Healthcare | 4 months (2-month planned delay) | Tech Lead & Solution Architect |
|
true | 3 | 2023-03-01 | Pharma Digital MVP - Digital Transformation from Scratch | Case study of building digital MVP for pharmaceutical lab from scratch: no Git, no infrastructure, with complex integrations and successful delivery. | MVP, digital transformation, pharma, .NET, React, Next.js, Salesforce, greenfield project, tech lead |
Overview
Pharmaceutical laboratory at the beginning of digital transformation hires consulting firm to build discount platform for prescribing physicians, starting from WordPress prototype.
Unique challenge: Start greenfield project in company without basic development infrastructure - no Git, no provisioned servers, no defined processes.
Context: Project executed in multi-squad environment. Successful production delivery despite initial infrastructure challenges, with controlled 2-month delay.
Challenge
Digital Transformation... Starting from Absolute Zero
Company initial state (2023):
No Git/versioning
- Code only on local machines
- Non-existent history
- Impossible collaboration
No provisioned servers
- Non-existent development environment
- Staging not configured
- Production not prepared
No development processes
- No CI/CD
- No code review
- No structured task management
No experienced internal technical team
- Team unfamiliar with modern stacks
- First contact with React, REST APIs
- Inexperience with complex integrations
Technical starting point:
- Functional prototype in WordPress
- Content and texts already approved
- UX/UI defined
- Business rules documented (partially)
Required Complex Integrations
The MVP needed to integrate with multiple external systems:
- Salesforce - Discount order registration
- Twilio - SMS for login validation (2FA)
- Official physician API - CRM validation + professional data
- Interplayers - Discount record sending by CPF
- WordPress - Content reading (headless CMS)
- SQL Server - Data persistence
Additional complexity:
- Different credentials/environments per integration
- Varying SLAs (Twilio critical, WordPress tolerant)
- Provider-specific error handling
- LGPD compliance (sensitive physician data)
Solution Architecture
Strategy: Start Small, Build Solid
Initial decision: Explain to the team the process we would follow, establishing foundations before coding.
Phase 1: Basic Infrastructure Setup (Weeks 1-2)
Even without provisioned servers, I started essential setup:
Git & Versioning:
# Structured repository from day 1
git init
git flow init # Defined branch strategy
# Monorepo structure
/
├── frontend/ # Next.js + React
├── backend/ # .NET APIs
├── cms-adapter/ # WordPress integration
└── docs/ # Architecture and ADRs
Process explained to team:
- Everything in Git (atomic commits, descriptive messages)
- Feature branches (never commit directly to main)
- Mandatory code review (2 approvals)
- CI/CD prepared (for when servers are ready)
Local environments first:
- Docker Compose for local development
- External API mocks (until credentials arrive)
- Local SQL Server with data seeds
Phase 2: Modern & Decoupled Architecture
┌─────────────────────────────────────────────────────┐
│ FRONTEND (Next.js + React) │
│ - SSR for SEO │
│ - Client-side for interactivity │
│ - API consumption │
└────────────┬────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ BACKEND APIs (.NET 7) │
│ - REST APIs │
│ - Authentication/Authorization │
│ - Business logic │
│ - Orchestration layer │
└────┬────┬────┬────┬────┬─────────────────────────┬──┘
│ │ │ │ │ │
▼ ▼ ▼ ▼ ▼ ▼
┌────────┐ ┌──────┐ ┌──────┐ ┌────────┐ ┌────────┐ ┌──────────┐
│Salesf. │ │Twilio│ │CRM │ │Interpl.│ │WordPr. │ │SQL Server│
│ │ │ │ │API │ │ │ │(CMS) │ │ │
└────────┘ └──────┘ └──────┘ └────────┘ └────────┘ └──────────┘
Chosen stack:
Frontend:
Next.js 13- SSR, routing, optimizationsReact 18- Components, hooks, contextTypeScript- Type safetyTailwind CSS- Modern styling
Backend:
.NET 7- REST APIsEntity Framework Core- ORMSQL Server 2019- DatabasePolly- Resilience patterns (retry, circuit breaker)
Why Next.js instead of keeping WordPress?
- Performance (SSR vs monolithic PHP)
- Optimized SEO (critical for pharma)
- Modern experience (SPA when needed)
- Scalability
- WordPress kept only as CMS (headless)
Phase 3: Integrations (Project Core)
1. Salesforce - Campaigns and Order Registration
Implemented solution:
Salesforce was configured to manage two main functionalities:
a) Discount campaigns:
- Marketing configures campaigns in Salesforce (medication X, discount Y%, period)
- Backend queries active campaigns via API
- Frontend (Next.js) displays available discount percentage based on: medication + active campaign
b) Order registration:
- User informs: physician CRM, state, patient CPF, medication
- System validates data (real CRM via official API, valid CPF)
- Percentage calculated automatically (Salesforce campaigns + CMS rules)
- Order registered in Salesforce with all data (LGPD compliance)
Overcome technical challenges:
- OAuth2 authentication with automatic refresh token
- Rate limiting (Salesforce has API/day limits)
- Retry logic for transient failures (Polly)
- CPF masking for logs (LGPD)
2. Twilio - SMS Authentication (2FA)
Implemented solution:
Two-factor authentication system to ensure security:
Login flow:
- User enters phone number
- Backend generates 6-digit code (valid for 5 minutes)
- SMS sent via Twilio ("Your code: 123456")
- User enters code in frontend
- Backend validates code + expiration timestamp
- JWT token issued after successful validation
Compliance and audit:
- Phone numbers masked in logs (LGPD)
- Complete audit (who, when, which SMS)
- Delivery rate: 99.8%
3. Official Physician API (Regional Medical Council)
Implemented solution:
Automatic physician validation via official medical council API:
Performed validations:
- CRM exists and is active in council
- Physician name matches informed CRM
- Specialty is allowed (lab business rule)
- State corresponds to registration state
Optimizations:
- 24-hour cache to reduce official API calls
- Fallback if API is down (notifies admin)
- Automatic retry for transient failures
Why this matters: Ensures only real and active physicians can prescribe discounts, avoiding fraud.
4. WordPress as Headless CMS
Implemented solution:
Marketing continues managing content in WordPress (familiar), but frontend is modern Next.js.
Architecture:
- WordPress: Manages texts, images, campaign rules
- WordPress REST API: Exposes content via JSON
- Next.js: Consumes API and renders with SSR (SEO optimized)
Benefits:
- Marketing doesn't need to learn new tool
- Modern frontend (performance, UX)
- Optimized SEO (Server-Side Rendering)
- Clear separation of responsibilities (content vs code)
Phase 4: Resilience & Error Handling
With multiple external integrations, failures are inevitable. The solution was to implement resilience patterns using Polly library (.NET):
Implemented patterns:
1. Retry
- If Salesforce/Twilio/CRM API fail, system automatically retries 2-3x
- Wait grows exponentially (1s, 2s, 4s) to avoid overload
- Only transient errors (timeout, 503) are retried
2. Circuit Breaker
- If service fails 5x in a row, "opens circuit" for 30s
- During 30s, doesn't try anymore (avoids wasting resources)
- After 30s, tries again (may have recovered)
3. Timeout
- Each integration has maximum response time
- Avoids indefinitely stuck requests
4. Fallback (Plan B)
- Salesforce down: Order goes to queue, processes later
- Twilio down: Alert administrator via email
- CRM API down: Uses cache (24h old data)
- WordPress down: Displays pre-loaded static content
Strategies per integration:
| Integration | Retry | Circuit Breaker | Timeout | Plan B |
|---|---|---|---|---|
| Salesforce | 3x (exponential) | 5 failures/30s | 10s | Retry queue |
| Twilio | 2x (linear) | 3 failures/60s | 5s | Admin alert |
| CRM API | 3x (exponential) | No | 15s | Cache |
| WordPress | No | No | 3s | Static content |
Production result:
- Salesforce had maintenance (1h) → System continued working (queue processed later)
- Twilio had instability → Automatic retry resolved 95% of cases
- Zero downtime perceived by users
Overcoming Infrastructure Challenges
Problem: Servers Not Provisioned
Temporary solution:
- 100% local development (Docker Compose)
- External service mocks (when credentials delayed)
- CI/CD prepared but not active (awaiting infra)
When servers arrived (week 6):
- Deploy in 2 hours (already prepared)
- Zero surprises (everything tested locally)
- Smooth rollout
Problem: Delayed Integration Credentials
Impact: Twilio and Salesforce took 3 weeks to be provisioned.
Solution: Create "mock" (simulated) versions of each integration:
- Twilio mock: Logs instead of sending real SMS
- Salesforce mock: Saves order to local JSON file
- CRM API mock: Returns fictional physician data
How it works:
- Development environment: Uses mocks (no credentials needed)
- Production environment: Uses real integrations (when credentials arrive)
- Automatic switch based on configuration
Result: Team stayed 100% productive for 3 weeks, testing complete flows without depending on credentials.
Problem: Team Inexperienced with Modern Stack
Context: Team had no experience with React, TypeScript, modern .NET Core, REST APIs.
Enablement approach:
1. Pair Programming (1h/day per developer)
- Tech lead works alongside dev
- Screen sharing + real-time explanation
- Dev writes code, tech lead guides
2. Educational Code Review
- Not just "approve" or "reject"
- Comments explain the why of each suggestion
- Example: "Always handle request errors! If API crashes, user needs to know what happened."
3. Living Documentation
- ADRs (Architecture Decision Records): Why did we choose X and not Y?
- READMEs: How to run, test, deploy
- Onboarding guide: From zero to first feature
4. Weekly Live Coding (2h)
- Tech lead solves real problem live
- Team observes thinking process
- Q&A at end
Result:
- After 4 weeks, team was autonomous
- Code quality consistently increased
- Devs started doing code review among themselves (peer review)
Results & Impact
Successful Delivery Despite Challenges
Context: Program with multiple squads working in parallel.
Achieved result:
- MVP delivered to production successfully
- Controlled 2-month delay (significantly less than other program initiatives)
- All integrations working as planned
- Zero critical bugs in production (first week)
Why was delivery successful?
- Anticipated setup - Git, processes, local Docker from day 1
- Strategic mocks - Team wasn't blocked waiting for infra
- Solid architecture - Resilience from the start
- Continuous upskilling - Team learned by doing
- Proactive communication - Risks reported early
MVP Metrics
Performance:
- Loading time: <2s (95th percentile)
- Lighthouse score: 95+ (mobile)
- SSL A+ rating
Integrations:
- Salesforce: 100% orders synchronized
- Twilio: 99.8% delivery rate
- CRM API: 10k validations/day (average)
- SQL Server: 50k records/month
Adoption:
- 2,000+ registered physicians (first 3 months)
- 15,000+ processed discount orders
- 4.8/5 satisfaction (internal survey)
Client Impact
Digital transformation initiated:
- Git implemented and adopted
- Established development processes
- Internal team enabled in modern stacks
- Cloud infrastructure configured (Azure)
- Evolution roadmap defined
Foundation for future projects:
- Architecture served as reference for other initiatives
- Documented code patterns (coding standards)
- Reused CI/CD pipelines
Tech Stack
.NET 7 C# Entity Framework Core SQL Server React 18 Next.js 13 TypeScript Tailwind CSS Salesforce API Twilio WordPress REST API Docker Polly OAuth2 JWT LGPD Compliance
Key Decisions & Trade-offs
Why Next.js instead of pure React?
Requirements:
- Critical SEO (pharma needs to rank)
- Performance (physicians use mobile)
- Dynamic content (WordPress)
Next.js offers:
- SSR out-of-the-box
- API routes (BFF pattern)
- Automatic optimizations (image, fonts)
- Simplified deploy (Vercel, Azure)
Why keep WordPress?
Alternatives considered:
- Migrate content to database + custom CMS (time)
- Strapi/Contentful (costs + learning curve)
- WordPress headless (best trade-off)
Advantages:
- Marketing team already knows how to use
- Approved content was already there
- WordPress REST API is solid
- Zero cost (already running)
Why .NET 7 instead of Node.js?
Context: Client had preference for Microsoft stack.
Additional benefits:
- Superior performance (vs Node in APIs)
- Native type safety (C#)
- Entity Framework (mature ORM)
- Easy Azure integration (future deploy)
- Client team had familiarity
Lessons Learned
1. Infrastructure Delayed? Prepare Alternatives
Don't wait for servers/credentials to start:
- Local Docker is your friend
- Mocks allow progress
- CI/CD can be prepared before having where to deploy
Lesson: Control what you can control.
2. Processes > Tools
Even without corporate Git, I established:
- Branching strategy
- Code review
- Commit conventions
- Documentation standards
Result: When tools arrived, team already knew how to use them.
3. Upskilling is Investment, Not Cost
Pair programming and code reviews took time, but:
- Team became autonomous faster
- Code quality increased
- Natural knowledge sharing
- Simplified onboarding of new devs
4. Resilience from the Start
Implementing Polly (retry, circuit breaker) at the start saved in production:
- Twilio had instability (resolved automatically)
- Salesforce had maintenance (queue worked)
- CRM API had slowness (cache mitigated)
Lesson: Don't leave resilience for "later". Failures will happen.
5. Clear Risk Communication
I reported weekly:
- Blockers (infrastructure, credentials)
- Risks (deadlines, dependencies)
- Alternative solutions (mocks, workarounds)
Result: Stakeholders knew exact status and had no surprises.
Challenges & How They Were Overcome
| Challenge | Impact | Solution | Result |
|---|---|---|---|
| No Git | Total blocker | Local setup + GitLab Cloud | Team productive day 1 |
| No servers | No dev environment | Local Docker Compose | Complete local dev/test |
| Delayed credentials | Integration blocked | Mock services | Progress without blocker |
| Inexperienced team | Low quality code | Pair prog + Code review | Ramp-up in 4 weeks |
| Multiple integrations | High complexity | Polly + patterns | Zero prod downtime |
Next Steps (Post-MVP)
Roadmap suggested to client:
-
Phase 2: Feature expansion
- Dashboard for physicians (order history)
- Push notifications (Firebase)
- E-commerce integration (direct purchase)
-
Phase 3: Optimizations
- Distributed cache (Redis)
- CDN for static assets
- Advanced analytics (Amplitude)
-
Phase 4: Scale
- Kubernetes (AKS)
- Microservices (break monolith)
- Event-driven architecture (Azure Service Bus)
Result: MVP delivered to production despite starting literally from zero, establishing solid foundations for client's digital transformation.
Need to build an MVP in a challenging scenario? Get in touch