Healthcare · B2B SaaS
Veterinary pharmaceutical reference SaaS
Legacy desktop app to cloud-native SaaS — zero data loss
Replaced a Microsoft Access / VB desktop product with a NestJS + PostgreSQL + Next.js SaaS. Built a B2B API distribution channel, Stripe billing, and clinical-grade governance.
Veterinary Pharmaceutical Reference Platform — Legacy to Cloud SaaS
Domain: Healthcare / Veterinary Pharmacy / B2B SaaS Engagement: Fixed Fee with T&M overage provision Duration: ~11 months (16 weeks active development + 7 months production support) Team Size: Architect, Project Manager, Senior & Junior Full-Stack Engineers Client Location: United States
The Problem
The client operates a long-standing pharmaceutical reference product used by veterinary medicine professionals to support safe and effective prescribing. The existing platform was a legacy Microsoft Access / Visual Basic desktop application with roughly 600 active clinical users. An earlier attempt at a cloud rebuild existed but had never gained traction with users — a common failure mode when domain knowledge lives implicitly in legacy code and doesn't survive translation.
The business needed to:
- Replace the aging desktop application with a modern, cloud-native SaaS platform — without asking 600 clinical users to take a leap of faith
- Preserve decades of accumulated pharmaceutical data (drug references, dosage formulas, interaction rules, client information sheets) with zero data loss
- Open up a B2B API distribution channel so partners (diagnostic platforms, practice management systems) could embed the reference data into their own products — a revenue line the legacy desktop simply couldn't support
- Introduce data governance and auditability suitable for a clinical decision support product, where every change has downstream clinical consequences
- Support a gradual transition: legacy desktop users and new cloud users had to operate on a single authoritative data set during the migration window, without the cloud platform forking the truth
The project was structured as a rebuild, but the real engineering problem was a migration of institutional knowledge — and the failed prior cloud attempt was a visible reminder of what happens when that's underestimated.
What We Built
A ground-up cloud platform on an enterprise-grade stack, migrating all critical data from the legacy Access database, with a B2B API layer, an administrative panel, a reference portal, and a self-service partner portal — plus a sync channel back to the legacy desktop client to support users who aren't ready to migrate.
Ground-up cloud platform
- NestJS API layer with modular architecture, guards, interceptors, and structured error handling
- PostgreSQL relational database with enforced referential integrity, replacing the flat Access table structure
- Next.js + Tailwind for admin panel, reference portal, and B2B partner portal
- JWT for internal users, API keys for B2B partners, with rate limiting and request quotas enforced at the API edge
Data migration from legacy desktop
- Field-level mapping of legacy Access tables into a fully normalized PostgreSQL schema
- Migration scripts for core drug data, embedded data (brand names, adverse effects, dosages, client info sheets), junction tables, and drug-to-drug interaction data
- Data integrity validation: source vs target record counts, foreign-key constraint verification, validation log per run
- Business logic preservation — dosage calculations and drug interaction rules reverse-engineered from legacy data and prior cloud attempts, then verified to produce identical outputs to the legacy system
B2B API platform
- RESTful APIs for drug reference, dosage calculator, interaction checker, and client information sheet generation
- Webhook system with event dispatch, partner registration, retry logic, and delivery logging
- Comprehensive OpenAPI / Swagger documentation with working examples
- Versioning and error-handling middleware designed for partner stability over time, not just at launch
Admin panel
- Full CRUD for drugs, interaction rules, dosage formulas, categories, and body systems
- Partner + API key management with usage statistics
- Webhook configuration with delivery status visibility
- Excel/CSV bulk import tool with validation for ongoing drug data updates
Reference & partner portals
- Reference portal — read-only drug lookup, dosage calculator, and interaction checker demos, used for sales enablement and partner evaluation
- B2B partner portal — self-service registration with email verification, onboarding wizard, API key self-service, webhook configuration, interactive API sandbox, and usage analytics dashboard
Subscription & billing
- Stripe-integrated subscription flow for individual UI users with plan/pricing model
- Admin-managed billing mode for API partners
- Usage metering and programmatic limit enforcement
- Partner billing dashboard and admin billing view
Data versioning & governance
- Temporal audit tables with triggers capturing every change to clinical data
- Draft → Approve workflow so no change reaches production users until reviewed
- Version history UI with diff viewer and rollback capability
- Audit log dashboard and bulk-operation versioning — essential for a clinical reference product where every change must be traceable
Cloud-to-legacy sync
To support users who are not yet ready to migrate off the desktop app, the cloud admin can export updated drug and clinical data in a format compatible with the legacy desktop application (.mdb / .csv). Legacy users receive the package via email or download link and import it into their desktop client. Cloud and legacy users operate on the same authoritative dataset throughout the transition — the cloud is the single source of truth even for users who haven't switched to it.
DevOps
- Dockerfiles and docker-compose for local parity with production
- GitHub Actions CI/CD with staging and pre-production pipelines
- AWS infrastructure (ECS/EC2, RDS PostgreSQL, S3, CloudFront, SES, Route 53, ACM, CloudWatch)
- Monitoring, structured logging, and automated backup / disaster-recovery configuration
Architecture Deep Dives
Business logic archaeology — and how we proved correctness
The hardest problem on this engagement wasn't building the APIs — it was ensuring that dosage calculations and drug interaction rules in the new system produced identical results to the ones clinicians had relied on for years. A near-miss would be worse than a total failure: silent output drift in a clinical reference product is exactly the kind of thing that erodes trust irreversibly.
The approach:
- Extract the logic from every available source — Access forms, VBA modules, prior cloud attempts, embedded data tables, and undocumented historical behavior preserved in the data itself
- Rebuild in TypeScript as pure, testable functions with explicit contracts, not scattered through controllers
- Build a parallel-run harness — run every dosage formula and interaction rule against a cohort of real historical inputs in both the legacy system and the new implementation, then diff outputs byte-for-byte
- Treat every diff as a ticket — either the legacy system has a bug the client wants corrected (document the deviation), or the new implementation is wrong (fix it). Nothing was ever "close enough"
- Lock in results with golden-file tests — the diff harness became a regression suite that any future refactor has to pass
This is slower than "just rewrite it" but it is the only approach that produces a system a clinician will trust.
Schema reconciliation — relational-first, intentionally
Access databases accumulate a particular kind of pathology: duplicated data across tables, implicit relationships that exist only in the UI code, columns whose meaning changed over time. Translating that into a clean relational PostgreSQL schema required deciding — for every table — what was essential relationship, what was denormalization for editing ergonomics, and what was accidental. Enforced foreign keys, check constraints, and properly-typed columns replaced a decade of "please enter a valid date" comments on a text field. The schema is the first place where the migration made the data better than it was, not just portable.
Draft → approve workflow + temporal audit
Clinical data changes don't just need an audit log — they need time-travel. Historical prescribing decisions that referenced a drug record need to be interpretable against the version of that record they saw, not whatever it looks like today. The governance model is:
- All clinical entities have a
currentversion and ahistoryvia temporal audit tables populated by triggers - Changes land in a
draftstate and are invisible to end users until explicitly approved by an authorized reviewer - The version history UI provides per-field diffs and a one-click rollback; rollbacks themselves are versioned events
- Bulk imports go through the same draft/approve gate — a spreadsheet paste cannot silently change clinical data
API versioning and partner stability
B2B partners ship products that embed this data. Breaking their integrations breaks their product — which breaks our trust with them. API versioning is explicit (URL-scoped), deprecation windows are communicated in both the response headers and the partner portal, and breaking changes are never shipped inside a minor version. The API's public contract is a first-class artifact — not whatever the code currently happens to do.
Webhook reliability
Webhook delivery to partners is a system that will fail — their endpoints will go down, their TLS certs will expire, their IPs will change. The delivery pipeline is built around that reality:
- Exponential-backoff retries with a bounded retry horizon
- Per-partner delivery status visible in the admin panel and the partner's own portal
- Signed payloads so partners can verify authenticity
- A dead-letter queue for terminal failures with explicit replay tooling
- Delivery logs retained long enough to support partner support conversations weeks after an incident
Cloud as system of record, legacy as subscriber
The two-way compatibility story is frequently done wrong — teams allow legacy clients to continue writing and then spend the project fighting sync conflicts. We designed from day one with the cloud as the single system of record; legacy is strictly a read-only subscriber consuming periodic data packages. There is one authoritative dataset, versioned and audited; legacy users get slightly older snapshots of it until they migrate.
Delivery Approach
The engagement runs as a fixed-fee project with a production-support tail:
- Phase 1–2 (Wk 1–5): Discovery, reverse-engineering of legacy data and business logic, architecture design, PostgreSQL schema design, API contract definition
- Phase 3–4 (Wk 3–8): NestJS API development (drug reference, dosage, interactions, client info sheets, webhooks), data migration, admin panel
- Phase 5–8 (Wk 5–11): Reference portal, B2B partner portal, Stripe subscription & billing, data versioning & governance
- Phase 9–10 (Wk 10–13): DevOps hardening, end-to-end testing, performance validation
- Phase 11–12 (Wk 12–14): Pre-production deployment, data cutover rehearsal, UAT with client stakeholders
- Phase 13 (Wk 13–16): Go-live, post-launch monitoring, stabilization, partner onboarding support
- Phase 14 (+6 months): Continued production support — bug fixes, performance tuning, security patches, partner onboarding
Tech Stack
| Layer | Technology |
|---|---|
| Backend / API | NestJS (Node.js), TypeScript |
| Database | PostgreSQL (relational, with temporal audit tables) |
| Frontend | Next.js, React, Tailwind CSS |
| Authentication | JWT (admin/UI), API keys (B2B partners) |
| Billing | Stripe (subscriptions + webhooks) |
| AWS SES | |
| Infrastructure | AWS (ECS/EC2, RDS, S3, CloudFront, Route 53, ACM, CloudWatch) |
| DevOps | Docker, GitHub Actions, staging + production environments |
| API Documentation | OpenAPI / Swagger |
| Validation | Parallel-run harness + golden-file regression suite against legacy outputs |
| Legacy Source | Microsoft Access / Visual Basic |
Outcome
- Replacement cloud SaaS platform delivered for a legacy desktop product with ~600 active clinical users
- All core drug, dosage, interaction, and client-info data migrated with zero data loss and validated record-for-record against the legacy source
- Dosage and interaction logic validated to produce identical outputs to the legacy system via a parallel-run diff harness — the single highest-stakes correctness requirement of the engagement
- Production-ready B2B API layer with documented endpoints, versioning discipline, rate limiting, signed webhooks, and self-service partner onboarding — a distribution channel the legacy product never had
- Clinical-grade data governance: every drug data change is drafted, reviewed, versioned, and reversible; historical states remain queryable
- Smooth transition path: legacy desktop users continue to receive authoritative data updates from the cloud admin in their native format, with the cloud as the single source of truth
Key Takeaway
Replacing a mature, domain-heavy legacy application is not a rewrite project — it is a migration of institutional knowledge, and the failure mode most rebuilds run into is underestimating that. The hardest parts of this engagement were not the APIs or Stripe integration; they were extracting dosage and interaction logic from a decades-old Access database and an abandoned cloud attempt, proving the new system produced byte-identical results to the one veterinarians already trusted, and designing governance that keeps clinical data auditable going forward. The combination of schema reconciliation, parallel-run validation, draft-approve governance, cloud-to-legacy sync, and a partner-ready API layer gave the client both a modern SaaS product and a new distribution channel — without asking 600 clinical users to take a leap of faith.
More recent work
Healthcare · Patient management
Multi-stakeholder healthcare platform
A six-app healthcare ecosystem — the product our client took to Shark Tank
Patient app, resident web, staff portal, admin dashboard, shared SDK, and an AI emergency dispatcher — all sharing a single backend with role-isolated access. Built for a healthcare startup that was later featured on Shark Tank with the product we delivered.
Read the case study
Transportation · Smart city
TransitPal
Multi-modal routing and cashless ticketing for public transit
Proprietary IP we built and productised — launched on the App Store and Play Store. 150+ APIs, dynamic fare engine, real-time vehicle tracking, ONDC-certified, and a voice AI for 250+ metro stations.
Read the case study
Have a project like this?
Tell us what you're trying to build. Discovery calls this week, scope within 3 business days.