Medivent / MedicartPharmacy E-commerce Backend
A NestJS and PostgreSQL backend for a pharmacy e-commerce platform: catalogue, customer and order APIs, Redis-supported caching and Zoho CRM integration.
- NestJS
- TypeScript
- PostgreSQL
- TypeORM
- Redis
- Zoho CRM
- REST APIs
Project snapshot
- Project type
- Pharmacy E-commerce Backend
- My role
- Backend Developer
- Contribution
- Backend Development
- Project context
- Professional Project
Project Overview
Medivent / Medicart is a pharmacy e-commerce platform. The backend behind it holds the product catalogue, the customer and order records, and the rules that decide what a request is allowed to do, and it serves all of that to the client applications through a REST API.
The business problem it answers is the ordinary but unforgiving one of online retail: product data has to be consistent across every client that reads it, orders have to be recorded correctly the first time, and the sales side of the business needs the same customer and order information without anyone retyping it into a separate system.
I contributed to this project as a Backend Developer, as part of my employment. My work was on the backend — API design, data modelling, business logic, authentication and third-party integration — rather than on the complete product, which was built by a team.
What stands out
- Catalogue, customer and order REST APIs with DTO-defined contracts
- Authentication and authorisation ahead of business logic
- Redis-supported caching and Zoho CRM integration
My Role
Backend Developer — Professional Contribution
I worked on the server side of the platform: NestJS modules and REST endpoints, the PostgreSQL data model through TypeORM, request validation, authentication and authorisation on protected routes, Redis-supported caching for read-heavy data, and the Zoho CRM integration.
This is a team-delivered product owned by my employer. The client applications and the wider product decisions were not mine; what this case study documents is the backend work I was responsible for within it.
What I was responsible for
- NestJS modules and REST endpoints for catalogue, customer and order domains
- PostgreSQL schema and TypeORM entities, relations and migrations
- Request validation and error handling at the API boundary
- Authentication and authorisation on protected endpoints
- Backend business logic for catalogue and order operations
- Redis-supported caching for repeatedly requested data
- Zoho CRM integration over its API
Services Delivered
The work actually performed on this project, and nothing beyond it.
Backend Development
Server-side application structure, modules and business logic in NestJS and TypeScript.
API Development
REST endpoints for catalogue, customer and order operations, with consistent request and response contracts.
Database Design
A PostgreSQL model for products, customers and orders, expressed as TypeORM entities and relations.
Authentication & Authorisation
Sign-in handling plus authorisation checks that decide which endpoints a caller may reach.
Third-Party API Integration
Zoho CRM integration, so platform records reach the CRM without manual re-entry.
Performance Optimisation
Redis-supported caching for read-heavy routes, keeping repeated reads off the database.
Business Workflow Development
The backend rules behind catalogue and order operations, applied in services rather than in clients.
Data Management
Validation, consistency and lifecycle of the platform's product, customer and order data.
Functionality
How the system works in practice, workflow by workflow.
Product and catalogue management
Product data is created and maintained through backend endpoints and served to the storefront through catalogue routes. Because every client reads the catalogue from the same API, there is one version of what a product is.
Customer and order processing
Customer records and orders are created and updated through the API, with the backend deciding what a valid order looks like before anything is persisted.
API communication
The client applications talk to the platform only through its REST endpoints. Request and response shapes are defined as DTOs, so the contract a client codes against is explicit rather than implied by whatever a handler happened to return.
Authentication and authorisation
Callers authenticate before reaching protected routes, and authorisation checks run before the business logic, so administrative operations and customer operations can share one API surface safely.
CRM synchronisation
Relevant customer and order information is sent to Zoho CRM through its API, so the sales and support side of the business works from platform data instead of a separately maintained copy.
Backend business logic
Catalogue and order rules live in NestJS services, which keeps them in one place and applied identically no matter which client made the call.
Data processing and validation
Incoming payloads are validated at the boundary and rejected with clear errors rather than being written and cleaned up later, which is what keeps the stored data trustworthy.
Redis-supported functionality
Data that is read far more often than it changes — catalogue reads in particular — is served from Redis, so repeated traffic does not turn into repeated database work.
Key Features
What the system does, and what each capability is worth to the business running it.
Pharmacy e-commerce backend
The server-side platform behind an online pharmacy: catalogue, customers, orders and the rules around them.
Catalogue APIs
Endpoints that serve product and category data to the storefront and administrative clients from a single source.
Customer and order APIs
Endpoints for customer records and order creation and retrieval, validated before anything is persisted.
Authentication and authorisation
Protected routes with authorisation applied before business logic, so administrative and customer operations coexist on one API.
PostgreSQL data model
Products, customers and orders modelled relationally with TypeORM entities, relations and migrations.
Redis caching
Read-heavy responses cached in Redis and invalidated on write, so cached data does not outlive its accuracy.
Zoho CRM integration
Platform records sent to Zoho CRM over its API, isolated in its own module so external calls stay contained.
Request validation
DTO-level validation at the API boundary, turning malformed requests into explicit errors instead of bad rows.
Modular REST architecture
One NestJS module per domain, so catalogue, customer, order and integration concerns stay separable as the API grows.
Challenges & Approach
The engineering problems this project actually presented, why each was difficult, how it was approached and what changed as a result.
A REST API several clients can depend on
- The problem
- More than one client application reads and writes through the same endpoints. When the contract is loose, every backend change becomes a client-side breakage, and the API turns into something nobody can safely modify.
- Why it was difficult
- Consistency has to be structural rather than a convention people remember. Payload shapes, validation and error responses all need to behave the same way across domains that were built at different times.
- Approach
- The API is organised as a NestJS module per domain, with DTOs defining request and response shapes and validation applied at the boundary. Business rules sit in services, so controllers stay thin and the contract stays visible.
- Outcome
- Clients code against explicit payloads, and a change inside one domain stays inside that domain instead of rippling across the API.
Modelling catalogue and order relationships
- The problem
- E-commerce data fans out quickly: a product appears in many orders, an order references a customer and its own line items, and catalogue data is read constantly while order data is written constantly.
- Why it was difficult
- A shallow schema pushes that complexity into application code, where joins become loops and consistency becomes something each query has to remember. Getting the relations right early is the difference between simple reads and hand-assembled ones.
- Approach
- The PostgreSQL model was designed relationally and expressed as TypeORM entities with explicit relations, with migrations carrying schema changes so the database and the code move together.
- Outcome
- Common reads are answerable in a query rather than reconstructed in application code, and referential integrity is enforced by the database instead of by convention.
Integrating Zoho CRM without coupling the platform to it
- The problem
- The CRM is a third-party system with its own authentication, its own limits and its own downtime. If core order handling calls it inline and trusts it, a problem there becomes a problem in the platform.
- Why it was difficult
- External integrations fail in ways local code does not — expired credentials, throttling, changed payloads — and each of those has to be handled without letting it look like a platform-side failure.
- Approach
- The integration was kept in its own module behind a service interface, so CRM concerns — credentials, payload mapping, error handling — stay in one place instead of being scattered through order logic.
- Outcome
- CRM problems surface as integration errors in a bounded part of the codebase, and the code that records orders does not need to know how Zoho is reached.
Serving read-heavy catalogue traffic
- The problem
- Catalogue endpoints are requested far more often than product data actually changes, and every one of those requests hitting the database is repeated work with no new information in it.
- Why it was difficult
- The hard part of caching is not storing values, it is deciding what may be cached and when it must be dropped. In a pharmacy catalogue, serving a stale product or price is worse than serving it a little slower.
- Approach
- Redis fronts the read-heavy routes, with cache entries invalidated when the underlying records are written, so freshness is tied to writes rather than to a timer alone.
- Outcome
- Repeated catalogue reads are served from cache and kept off the database, without the API returning product data that has already been superseded.
Keeping authorisation ahead of business logic
- The problem
- Administrative operations and customer operations live on the same API. If permission checks are scattered through handlers, a new endpoint can quietly ship without one.
- Why it was difficult
- Authorisation has to be applied consistently across modules, and it has to run before any logic that could read or change data — not somewhere in the middle of it.
- Approach
- Authentication and authorisation were handled at the framework level in front of the route handlers, so protection is part of how an endpoint is declared rather than something remembered inside it.
- Outcome
- Protected routes are protected by construction, and adding an endpoint means declaring its access requirements rather than reimplementing them.
Technologies Used
The stack this project runs on, grouped by the job each part does.
Backend
- NestJS
- TypeScript
- REST APIs
Data
- PostgreSQL
- TypeORM
- Redis
Integrations
- Zoho CRM API
Cross-cutting
- Authentication & authorisation
- DTO validation
Technical Highlights
- NestJS backend architecture with one module per domain
- Relational PostgreSQL modelling through TypeORM entities and migrations
- Redis-supported caching for read-heavy routes, invalidated on write
- Zoho CRM integration isolated behind its own service module
- REST API development with DTO-defined contracts
- Authentication and authorisation applied ahead of business logic
- Backend business rules held in services rather than in clients
Results & Impact
What changed in practice. No figures are quoted here, because none are published for this project.
A dependable API layer for the client applications
Clients read and write through explicit contracts, so front-end work does not depend on guessing what an endpoint returns.
Repeated reads kept off the database
Catalogue traffic is served from Redis where it is safe to do so, and invalidated on write rather than left to go stale.
Better integration between systems
Zoho CRM reflects platform customer and order activity through the integration, instead of being maintained as a separate copy by hand.
Better data management
Validation at the boundary and relations enforced in PostgreSQL mean the stored data stays usable rather than needing periodic cleanup.
A codebase that stays separable
Domain modules and an isolated integration layer keep catalogue, order and third-party concerns from growing into each other.