Seha Pharmacy Platform
Full-Stack Developer34 weeksLiveTeam of 4

Seha Pharmacy Platform

Full-stack pharmacy e-commerce migrated from microservices to a modular NestJS monolith

NNestJSTTypeORMMySQLMySQLNext.jsNext.jsTypeScriptTypeScriptASAWS S3JJWT
View LiveSource Code

Project Intelligence

Duration

34 weeks

Technologies

7

Status

Production

Key Challenge

Consolidating 7 microservice auth flows into a single modular NestJS auth module with account-type routing

Skills Demonstrated

System MigrationHealthcare APITypeORMAWS

TL;DR

Migrated a pharmacy backend from microservices to a modular NestJS monolith with MySQL, covering auth, products, orders, prescriptions, notifications, and a Next.js storefront.

Problem

Microservices architecture created auth duplication and deployment overhead for a small team

Solution

Modular monolith with shared guards, interceptors, and unified auth module

Result

Single deployable API with 10+ modules covering full pharmacy workflow

10+

Backend modules

3

Account types

Key Outcomes

10+

Backend modules

3

Account types

v1

API version

Curated Visuals

Order management
1 / 14

Order management

Results & Impact

Successfully migrated pharmacy platform to a maintainable modular monolith.

Reduced deployment complexity from 7 services to 1 while preserving all features.

10+

Modules consolidated

34

Weeks migration

Architecture

System architecture overview

Modular NestJS monolith with domain modules (auth, users, products, orders, prescriptions, pharmacy, location, upload, search, admin, notifications).

Shared common layer provides guards, interceptors, filters, pipes, and decorators. TypeORM entities map to MySQL with migrations.

Next.js frontend communicates via REST API with JWT + refresh token flow.

Infrastructure & Deployment

Backend on cloud VM or container with MySQL 8. AWS S3 for file uploads. Next.js frontend on AWS Amplify or Vercel.

Features

Core

Multi-Role Auth

Patient, pharmacy, and admin authentication with JWT refresh.

Core

Product Catalog

Searchable product listing with filters and categories.

Core

Order Management

Full order lifecycle from cart to fulfillment.

Core

Prescriptions

Upload and manage prescription documents.

Secondary

Pharmacy Discovery

Location-based search for nearby pharmacies.

Secondary

Admin Panel

Backend admin operations and analytics.

Challenges & Solutions

1

Microservice auth consolidation

The Problem

Each microservice had its own JWT validation and user lookup logic.

How I Solved It

Single auth module with account-type strategies and shared JwtAuthGuard.

@Post('auth/:accountType/signin')
signin(@Param('accountType') type: AccountType, @Body() dto: SignInDto) {
  return this.authService.signin(type, dto);
}
2

Prescription file handling

The Problem

Prescription uploads needed secure storage with access control.

How I Solved It

AWS S3 upload module with signed URLs and pharmacy-only access guards.

const url = await this.s3Service.upload(file, `prescriptions/${userId}/`);
return { url, expiresIn: 3600 };
3

Search across entities

The Problem

Users need to search products, pharmacies, and orders from one endpoint.

How I Solved It

Dedicated search module with typed query builders per entity type.

Lessons Learned

  1. 1

    Monolith wins for small teams

    Microservices overhead wasn't justified—modular monolith gave us boundaries without network complexity.

  2. 2

    Account-type routing in auth

    Patient, pharmacy, and admin signin paths share JWT infrastructure but differ in registration and profile schemas.

  3. 3

    Migration needs contract tests

    API contract tests against the old microservices caught breaking changes during consolidation.

What I'd Do Differently

Start with monolith architecture and add service extraction only when a module truly needs independent scaling.