← All Work
Param Life
Healthcare & WellnessTech Extension

Param Life

Cross-platform mobile app with personalized programs, admin dashboards, and AI-ready backend.

The Challenge

Param Life brings together a holistic approach to wellbeing across practices such as positive psychology, yoga, Ayurveda and meditation. The challenge wasn't simply to build an app — it was to turn that methodology into a product system: personalized programs, habit formation, guided content and a growing media library, all manageable by the Param team without depending on us for every content change.

Our Approach

We treated Param as a product platform rather than a single app. That meant separating the consumer experience from content operations: a fast cross-platform Flutter client purely for consuming content, a dedicated React web admin portal where the Param team uploads and manages every type of content independently, and asynchronous infrastructure so heavy media processing never blocks the API.

Tech Stack

FlutterNode.js / FastifyReact (Admin)PostgreSQLPrismaBullMQValkey / RedisAWS S3AWS MediaConvertCloudFrontFirebase / FCMWebSockets

System Architecture

Client

Cross-platform consumer app for iOS and Android — a pure content consumption surface with no upload capability.

Flutter

API

Core product and content services, plus event-driven status push over WebSockets.

Node.jsFastifyWebSockets

Data

Structured, relational storage for users, programs, habits and content metadata.

PostgreSQLPrisma

Admin

Web portal where the Param team uploads and manages content of every type — video, audio, images and structured program data — independently of mobile releases.

React

Async infrastructure

Background job processing for media transcoding, notifications and status updates.

BullMQValkey / RedisAWS S3MediaConvertCloudFrontFirebase / FCM

Media Upload & Delivery Pipeline

Wellness content is video-heavy, so upload, transcoding and delivery are fully decoupled from the request/response cycle — each stage hands off asynchronously to the next.

1

Presigned upload

The React admin portal requests a short-lived presigned URL from the API and uploads the raw file — video, audio or image — straight to a private S3 bucket, whatever the content type. The Flutter app never uploads; it only consumes what's published.

React (Admin)AWS S3
2

Job queued

The completed upload emits an event that enqueues a transcoding job in BullMQ, backed by Valkey, fully decoupling the upload from processing.

BullMQValkey / Redis
3

Transcoding

AWS MediaConvert picks up the job and transforms the source video into multiple HLS renditions plus preview thumbnails, sized for different network conditions.

AWS MediaConvert
4

Status push

On completion, the backend pushes a real-time status update over WebSockets straight to the admin portal, so the team sees content go live the moment it's ready — no polling, no refreshing.

FastifyWebSockets
5

CDN delivery

Processed HLS streams and thumbnails are served through CloudFront, keeping playback fast for users regardless of location or device.

CloudFront

Technical Problem Solving

Problem 1

Large content uploads — video especially — would block API requests if handled synchronously, and transcoding time is unpredictable, so polling for status wastes requests and still feels slow.

Solution

We decoupled upload from processing entirely. The React admin portal gets a presigned URL and uploads directly to S3, bypassing our API completely. A finished-upload event enqueues a BullMQ job that drives AWS MediaConvert, generating HLS renditions and thumbnails. Completion is pushed back to the admin portal over a WebSocket instead of polled.

Impact: The API stays fast and available regardless of file size or transcoding load, and the content team sees an item go 'ready' the moment it actually is.

Problem 2

Every content update — a new program, a swapped meditation track, a reordered collection — would otherwise require a mobile release and app-store review cycle.

Solution

We built a dedicated React admin portal on top of the same Prisma-modeled PostgreSQL schema, with structured entities for programs, collections and content items rather than free-form blobs. The Param team edits and publishes directly; the mobile client just fetches current state.

Impact: Content velocity is fully decoupled from release cadence — new programs can ship the same day, with no engineering involvement.

Problem 3

The product needed to support personalization and AI-assisted recommendations down the line, without a future data-model rewrite.

Solution

Programs, habits, content and engagement are modeled as structured, queryable relations from day one — not opaque JSON blobs — with the events needed to drive recommendations already being captured.

Impact: Personalization becomes an additive layer on existing data rather than a migration, so the team can move directly into that work when ready.

Outcomes

Cross-platform consumer experience

A single Flutter codebase delivers the core mobile experience across iOS and Android.

Centralized content operations

A React admin portal handles content of every type — video, audio, images and program data — entirely separate from the consumer app, run independently by the Param team.

Asynchronous media processing

Video transcoding and related heavy lifting run as background workflows instead of blocking user-facing requests.

Built for personalization

The product foundation leaves room for deeper recommendation and AI-assisted experiences as the platform grows.

Building something similar?

Let's Talk