Contact Us
Get in touch Get in touch
One Platform, Five Surfaces

Custom Learning Platform We Built for vCare Project Management

vCare prepares professionals for the project-management world's most demanding PMI certifications. We built them a custom learning platform they fully own — a single TypeScript backend that runs the marketing website, the learner portal, the admin console, and the Android and iOS apps. Video lessons, timed mock exams, subscriptions, and certificates all run on infrastructure that's theirs.

vCare Project Management learning app on mobile, a unified e-learning platform for PMI exam prep and career growth
vCare Project Management dashboard on laptop and mobile showing courses, progress tracking and learner analytics
vCare online project management course website on tablet, a modern learning experience for PMP and career development
vCare learning portal on laptop with course modules, lessons and mock tests for project management exam preparation
About

About vCare Project Management

vCare helps working professionals earn the industry's most respected project-management credentials — PMP, PgMP, PfMP, PMI-RMP, PMI-PMOCP, and CPMAI. Students learn through video lessons, large question banks, full-length mock exams, flashcards, and exam-strategy content, and they study across both web and mobile, often switching between the two in a single day.

about

Built Beyond the Storefront: A Fully Owned Platform

Running a business like that takes more than a storefront. It needs to stream protected video, run timed exams that behave like the real thing, share one subscription across web and phone, issue certificates on demand, and let the team manage all of it without calling a developer. vCare wanted a platform built for exactly that — and one they would fully own.

The Challenge

A Learning Business Needs More Than a Storefront

A generic online store is good at selling a single product page. It was never built to run a learning business — and vCare's product is entirely learning. Five things pushed well past what an off-the-shelf store can do:

01

Protected content.

Stream hours of protected video and documents without the files leaking the moment a link is shared.

02

Real exams

Run timed mock exams with several question types that survive a refresh, a phone call, or a dropped connection — with zero lost answers.

03

One subscription, three stores

Sell one subscription that works the same whether it's bought on the web, an iPhone, or an Android phone.

04

Certificates

Issue PDU certificates on demand, in seconds, from templates the team controls.

The answer was a custom platform built around the learning product itself, with one backend behind every screen.

  • Industry

    EdTech — Professional Certification Training
  • Core Stack

    MERN — MongoDB
    Express
    React
    Node.js — in TypeScript
  • Services

    Full-Stack Web Development
    Mobile App Development
    Backend & API Engineering
    Cloud & DevOps
    UI/UX
  • Client

    vCare Project Management (PMI certification training)
BUILT FOR LEARNING

What We Built

Five surfaces, one backend. Each piece does one job well, and they all share the same source of truth.

PieceWhat It DoesStack
Marketing WebsiteCourse pages, exam simulators, practice exams, SEO landing pages.React 18, TypeScript, Vite, Tailwind, Radix UI
Learner PortalLessons, question banks, mock exams, flashcards, certificates.React 18, TypeScript, Vite, Firebase web push
Admin ConsoleContent, users, plans, roles, reports, notifications.React 18, TypeScript, TanStack Table, TinyMCE
Core APIOne backend for web, Android and iOS.Node.js, Express 5, TypeScript, MongoDB (Mongoose), Redis
Media & DeliveryVideo, documents, certificates.AWS S3, CloudFront signed URLs, FFmpeg
PaymentsWeb checkout plus in-app purchases.Stripe, Apple App Store, Google Play Billing
OUR APPROACH

How We Built It

Four decisions early on shaped a platform the business could actually run and grow on its own.

Every course is real data

Each course is a record with its own modules, lessons, question banks, mock exams, flashcards, and exam-strategy content. Plans and prices are records too — so the business edits them in the admin console without touching code or waiting on a developer.

Clean URLs and real SEO

Each certification gets its own indexable pages, with clean URLs such as /pmp/exam-prep and /pmi-rmp/flash-cards, so search traffic lands on the right page instead of a single generic route.

A smooth handoff into the portal

Every “Start” or “Subscribe” button sends the visitor to the portal login with a return path — for example /subscriptions?course=PMP — so after signing in they land exactly where they meant to go.

Bulk content loading

Admins import lessons and questions from CSV templates the console provides — one each for multiple-choice, fill-in-the-blank, and drag-and-drop — so hundreds of questions go in at once instead of being typed one by one.

The Architecture

Five Clients, One API, Eight Services

Every client — the marketing site, the learner portal, the admin console, and both mobile apps — talks to the same API. Business rules, payments, and access checks all live in one place, so a change ships to web and mobile at the same time, and the three platforms can never drift apart.

The simple version

The app and web clients show and remember things; the backend checks and decides things; the database and cloud storage hold things.

architecture

One source of truth

A learner can start a mock exam on a laptop, pause it, and finish it on a phone — because there is no separate mobile backend to fall out of sync.

The Web Frontend

Three Apps, One Design System

We built three React applications — the marketing site, the learner portal, and the admin console — on one shared design system. Each deploys on its own, but all three look and behave like a single product.

01

One design system.

All three apps use React 18, TypeScript, Vite, Tailwind, and accessible Radix UI primitives. Buttons, dialogs, tables and forms behave the same everywhere, and a fix in one app carries over to the others.

02

A real exam simulator

The mock-exam engine supports multiple-choice, fill-in-the-blank, and drag-and-drop ordering (built on dnd-kit). A drift-resistant timer checks the clock twice a second and auto-submits at zero; refresh and back-navigation are guarded; and learners can pause and resume on web or phone.

03

Access that matches the plan

The portal reads one access map per course and shows, locks, or upsells each feature accordingly — and the server enforces the very same rules again.

04

An admin console that runs the business

Admins manage courses, questions, plans, users, tickets, ratings, announcements, and certificate templates — with drag-and-drop ordering, rich content via TinyMCE, and CSV report exports.

05

SEO that works

A route-aware SEO layer sets the title, meta description, Open Graph tags, and canonical URL on every navigation — so a single-page app still ranks page by page.

The Backend

One TypeScript Service Behind Everything

The backend is a TypeScript service on Express 5, MongoDB, and Redis, split into three guarded route groups — public, learner, and admin. Here's what makes it trustworthy.

Authentication built for many devices

  • Secure by design. Short-lived JWT access tokens paired with rotating refresh tokens — and refresh tokens are stored only as SHA-256 hashes, so a database leak exposes no live session.
  • One session per account. Every token is tied to a server-side session, so signing in on a new device ends the old one — which quietly stops paid accounts from being shared.
  • Flexible and self-cleaning. Sign-in with Apple and Google, plus email with OTP; expired sessions are cleared automatically by MongoDB TTL indexes, with a 30-day window to restore a deleted account.

Protection against abuse — that fails gracefully

  • Abuse control. Redis counts failed logins per email and per IP and triggers a timed lockout, telling the client exactly how long to wait; public forms are rate-limited.
  • Resilience. If Redis is ever down, the API keeps serving and skips only those protections — a cache outage never becomes a sign-in outage.

Protected media and on-demand certificates

  • Paid content stays paid. Lesson videos live in private S3 storage; learners get CloudFront signed URLs that expire within minutes, so a copied link stops working almost immediately. Uploads are re-encoded with FFmpeg to H.264 with fast-start for instant playback.
  • Certificates on demand. Admins design certificate templates; the server draws each one with node-canvas, wraps it in a PDF with PDFKit, emails the learner, and keeps a copy — so PDU certificates are issued in seconds.

Runs itself in the background

  • Automation. Scheduled jobs expire ended subscriptions, send renewal reminders, deliver timed announcements, and clean up old notifications — each with a guard so a slow run never overlaps the next.
  • Email and analytics. Fourteen transactional emails are written as typed React Email components and sent through Resend; daily active users are counted once each via a Redis set and surfaced on the admin dashboard.
One Backend

For Web and Mobile

The Android and iOS apps call the exact same API as the website — there is no separate mobile backend to maintain or fall out of sync.

01

Device-aware sessions

Every login records the device type. On the web the refresh token sits in a cookie; native apps send the same token in a header. The rotation and security rules are identical.

02

One subscription, three ways to pay

The same plan can be bought through Stripe, the App Store, or Google Play. Each plan stores all three product IDs, and whichever store reports the purchase, the backend grants the same access. Free trials are one per course per learner, on any device.

03

Reach every device

Firebase Cloud Messaging reaches Android, iOS, and web from one call, in batches, with dead tokens pruned automatically; universal links open emails and web links straight into the installed iOS app.

04

Same rules everywhere

Content access, exam rules, progress, bookmarks, and certificates are all enforced by the API — so a feature built once on the server works on all three platforms.

BEHIND THE BUILD

Challenges and How We Solved Them

The Challenge

One subscription, three stores

Why it was hard

Stripe, Apple and Google each report purchases in a different format and on a different schedule

How we solved it

Each plan maps to all three store product IDs; every purchase becomes one internal record granting the same access

The Challenge

Trusting payment events

Why it was hard

Webhooks can be forged, repeated, or arrive late

How we solved it

Signature checks on Stripe, cryptographic verification on Apple, server-to-server confirmation with Google, and de-duplication by transaction ID

The Challenge

Keeping paid video private

Why it was hard

A video link can be shared in seconds

How we solved it

Private S3 storage behind CloudFront URLs that expire within minutes, plus one active session per account

The Challenge

Account sharing

Why it was hard

Exam-prep accounts are often shared between colleagues

How we solved it

Every token is tied to a server-side session; a new login ends the previous one

The Challenge

A fair, real-feeling exam

Why it was hard

Timers drift, tabs get refreshed, and people lose connection

How we solved it

A clock-based timer, auto-submit at zero, guarded navigation, and pause-and-resume stored on the server

The Challenge

SEO on a React single-page app

Why it was hard

Every route shared one title and description

How we solved it

A route-aware SEO layer sets title, meta, Open Graph and canonical tags for each page

The Challenge

Large video uploads

Why it was hard

Raw recordings are heavy and slow to start playing

How we solved it

FFmpeg re-encodes to H.264 with fast-start; multipart upload sends large files to S3 in chunks

The Challenge

Staying up when a dependency fails

Why it was hard

Redis or a third-party API can go down

How we solved it

Redis-based protections fail open, MongoDB reconnects with retries, and scheduled jobs never overlap

Tech Stack

Why We Built It This Way

01

Frontend (3 apps)

React 18, TypeScript, Vite, Tailwind CSS, Radix UI (shadcn pattern), TanStack Table, TinyMCE, Recharts, dnd-kit

02

Backend

Node.js, Express 5, TypeScript

03

Database & cache

MongoDB (Mongoose) — 33 collections; Redis

04

Media

AWS S3, CloudFront (signed URLs), FFmpeg, node-canvas, PDFKit

05

Authentication

JWT access + rotating refresh tokens; Apple & Google sign-in; email OTP

06

Payments

Stripe, Apple App Store, Google Play Billing

07

Messaging & email

Firebase Cloud Messaging; React Email + Resend

08

Delivery

Docker image; stateless API containers

Visual Proof

The Screens We Built

The Result

A Platform vCare Fully Owns

vCare now owns its entire learning platform, from the first website visit to the issued certificate — nothing is locked inside someone else's storefront.

01

One build, everywhere

  • One codebase serves five surfaces: the marketing site, the learner portal, the admin console, Android, and iOS.
02

Unified revenue

  • Revenue from every channel lands in one place — web, App Store, and Google Play purchases all show up in one admin report, with CSV export.
03

Self-service

  • The business runs day to day on its own: courses, prices, plans, announcements, and certificate templates are all edited in the admin console without a developer.
04

Easy to extend

  • Six certifications are live, and adding a new one is a content task, not an engineering project.
05

Ready to grow

  • Stateless API containers, a CDN for media, and batched push messaging mean it scales out without a redesign.
Execution Strategy
WHAT SETS US APART

Why Auspicious Soft

01

Business first

We start from the business — keep revenue flowing, protect the paid content, and let the client run things without us — then choose the technology that fits

02

Built to stay in sync

One backend for five surfaces means web and mobile never drift apart, and every new feature is built once.

03

Security and resilience by default

Hashed refresh tokens, signed media URLs, verified payment events, and graceful failure under load are standard, not extras.

04

Ownership

A platform the client owns outright — no storefront lock-in, no per-feature fees, no waiting on a third party to grow.

Outgrown an off-the-shelf store or no-code tool?

We plan the same kind of move — to a platform you fully own.

Talk to our team Talk to our team

Frequently Asked Questions

What exactly did Auspicious Soft build for vCare?

A complete, custom learning platform: a marketing website, a learner portal, an admin console, and native Android and iOS apps — all powered by a single backend. It handles video lessons, question banks, timed mock exams, flashcards, subscriptions, and certificates, with the business managing all the content itself.

What's the tech stack?

A MERN stack in TypeScript. The three web apps are built with React 18, Vite, Tailwind, and Radix UI. The backend is Node.js and Express 5 with MongoDB (around 33 collections) and Redis, shipped as a Docker image. Media runs on AWS S3 and CloudFront, payments on Stripe plus Apple and Google billing, and messaging on Firebase Cloud Messaging and Resend.

How does one subscription work across web, iPhone, and Android?

Each plan stores its Stripe, Apple, and Google product IDs. Whichever store a learner buys through, the backend verifies the purchase with that store and maps it to the same internal plan — granting identical access everywhere. Renewals, cancellations, and expiries update access automatically, and free trials are limited to one per course per learner across all devices.

How do you keep paid video and exams secure?

Videos live in private storage and are served only through links that expire within minutes, so a shared link stops working almost immediately. Every login is tied to a server-side session, so a new sign-in ends the previous one — which stops account sharing. Exams run on a server-backed timer and save progress continuously, so no answers are lost if the connection drops.

Why build a custom platform instead of using an off-the-shelf store?

A standard store is built to sell a product page, not to run a learning business — streaming protected video, running real timed exams, sharing one subscription across web and mobile, and issuing certificates on demand. A custom platform does all of that, and leaves vCare owning the whole thing, free to change courses, prices, and plans without a developer or a third-party's feature limits.

Can the platform grow as vCare adds courses and students?

Yes. Adding a certification is a content task, not an engineering one. The API runs as stateless containers that scale out, media is delivered through a CDN, and push notifications are batched — so the platform handles more courses and more learners without a redesign.

(function () { "use strict"; var authors = { "/author/anil-kumar/": { name: "Anil Kumar", url: "https://auspicioussoft.com/author/anil-kumar/" }, "/author/anil-thakur/": { name: "Anil Thakur", url: "https://auspicioussoft.com/author/anil-thakur/" }, "/author/richa-sharma/": { name: "Richa Sharma", url: "https://auspicioussoft.com/author/richa-sharma/" } }; var path = window.location.pathname.replace(/\/+$/, "") + "/"; var author = authors[path]; // Run only on the three specified author pages. if (!author) { return; } // Prevent duplicate schema insertion. if (document.getElementById("auspicious-author-schema")) { return; } var organizationId = "https://auspicioussoft.com/#organization"; var websiteId = "https://auspicioussoft.com/#website"; var personId = author.url + "#person"; var schema = { "@context": "https://schema.org", "@graph": [ { "@type": "ProfilePage", "@id": author.url + "#profilepage", "url": author.url, "name": author.name + " | Author Profile", "isPartOf": { "@id": websiteId }, "mainEntity": { "@id": personId } }, { "@type": "Person", "@id": personId, "name": author.name, "url": author.url, "worksFor": { "@id": organizationId } } ] }; var script = document.createElement("script"); script.type = "application/ld+json"; script.id = "auspicious-author-schema"; script.textContent = JSON.stringify(schema); document.head.appendChild(script); })();