Back to Projects
DJI Logo

The DJI Bangalore
Engineering Transformation

The original DJI Bangalore platform was a static React SPA lacking a secure backend. I architected a unified Turborepo monorepo, migrating the system to Next.js React Server Components, Payload CMS, and a React Native Expo application.

Visit Live Store
DJI Bangalore Hero

Architecture Evolution

Migrating from a legacy SPA to a modern, type-safe monorepo.

Legacy Platform

  • Architecture: Single-page React application (Create React App).
  • Rendering: 100% Client-Side Rendering (CSR), causing slow initial loads.
  • Backend: None. Completely decoupled, relying on manual data entry.
  • Security: No server-side validation; vulnerable to client manipulation.
  • Payments: Manual coordination for B2B quotes.

Modern Platform

  • Architecture: Turborepo Monorepo sharing interfaces across Web and Mobile.
  • Rendering: Next.js React Server Components (RSC) for immediate TTFB.
  • Backend: Payload CMS seamlessly integrated with PostgreSQL.
  • Security: Zod runtime validation, Edge Rate-Limiting via Upstash Redis.
  • Lead Generation: Structured order intake acts as an automated lead generation funnel, with orders and price negotiations processed via the custom Expo Admin App.

Production Implementation

Features explicitly implemented and active in the codebase.

MonorepoTurborepoShared packages across apps.
FrontendNext.jsApp Router & Server Components.
MobileExpoCross-platform React Native.
BackendPayloadHeadless CMS tied to Next.js.
DatabasePostgreSQLRelational data modeling.
Lead GenAutomatedFeeds directly into Expo admin.
SecurityTurnstileCloudflare anti-bot widget.
Caching & EdgeRedisUpstash rate-limiting.
Type SafetyTypeScriptEnd-to-end interface sharing.

Architecture Data Flow

End-to-end type safety enforced by auto-generating TypeScript interfaces from the Postgres database up to the Next.js and React Native clients.

Next.js Web

Consumer Client

Expo Mobile

B2B Admin App (Order Processing)

Payload CMS

Headless Admin Core

PostgreSQL

Primary Database

Cloudflare R2

Technology Decisions (ADRs)

Architectural decisions made during the rewrite.

Payload CMS inside Next.js

Problem: Need a robust relational backend and Admin UI without maintaining separate node servers.
Why Chosen: Payload natively integrates into Next.js App Router, sharing the same deployment context and auto-generating TypeScript interfaces.
Trade-offs: Couples the CMS scaling tightly to the Next.js frontend scaling.
Alternatives: Supabase (too much vendor lock-in for this client), custom Express (high maintenance).

Upstash Redis Middleware

Problem: API routes in a serverless environment are vulnerable to DDoS, exhausting the Postgres connection pool.
Why Chosen: Edge rate-limiting guarantees requests are dropped globally before spinning up expensive serverless compute.
Trade-offs: Introduces a third-party dependency and slight network latency to Upstash.
Benefits: Absolute protection of the core Postgres database from malicious bot traffic.

Turborepo & Expo

Problem: Building a web app and a mobile app usually requires duplicating UI logic and validation schemas.
Why Chosen: Turborepo allows the Next.js app and Expo app to import the exact same Zod validation rules and TypeScript interfaces from a shared package.
Alternatives: Separate repositories (high drift risk), standard Yarn Workspaces (slow builds).
Benefits: Changing a database column immediately throws a type error in the mobile app during compilation, preventing runtime crashes.

My Responsibilities

Designed

The monorepo architecture, 24 relational database schemas, and the B2B checkout workflow.

Built

32 custom Next.js API routes, 54 React 19 UI components, and 25 cross-platform Expo screens.

Integrated

Payload CMS into the Next.js runtime, automated checkout flows, and Playwright for E2E testing.

Configured

Cloudflare R2 for S3-compatible media storage and Turnstile for client-side bot protection.

Maintained

Production monitoring via Sentry, database migrations, and connection pooling tuning.

Engineering Challenges

  • Serverless Connection Pooling: Deploying to a serverless edge runtime meant concurrent requests could exhaust Postgres connections. Solved by tuning pool limits.
  • Business Adaptation: The Stripe payment gateway was fully integrated, but due to pending corporate GST registration, the client required an immediate fallback. I adapted the checkout flow into an automated B2B lead generation tool, engineering the Expo Admin App to allow the internal team to process leads, confirm orders, and handle real-time price negotiations. The Stripe integration remains fully tested and secured behind a configuration toggle, ready for instant activation once the client completes KYC.
  • Shared Logic: Structuring the Turborepo so Zod schemas could be securely shared between the backend and mobile without exposing server secrets to the client.

Lessons Learned

  • Monorepo Overhead: While sharing code is powerful, configuring Turborepo caching and TS paths requires significant upfront investment to prevent build-time bottlenecks.
  • Server Components Paradigm: Shifting from CSR to RSC requires a fundamental rethinking of state management, relying more on URL parameters and cookies than React Context.
  • API Security: Never trust client-side validation alone. Robust backend Zod validation and Edge rate-limiting are mandatory for public-facing e-commerce.

Expected Business Benefits

Projected ROI resulting from the underlying architectural rewrite.

Sales PipelineAdmin DrivenReplaced manual quotes with an automated lead gen funnel managed inside the Expo app.
ScalabilityHighReady to handle significantly higher traffic spikes.
MaintainabilityUnifiedSingle codebase prevents technical debt accumulation.

Production Tech Stack

Next.js
Payload CMS
PostgreSQL
React Native
Upstash Redis
Cloudflare
Available for Hire

Looking for a Software Engineer?

I'm currently open to full-time roles. Whether you need a full-stack expert, a front-end specialist, or someone to build React Native apps from scratch, my inbox is open.

View GitHub