Selected Work - Engineering

SentiKits - a guided emotional-wellness companion

A mobile emotional-wellness app: curated reflection "kits", a journaling system, a real-time community, an in-app shop, and a server-verified subscription layer - built as one React Native codebase for iOS and Android on a fully serverless Firebase backend.

Role

Founding Engineer

Stack

React Native · Firebase · Cloud Functions

Links

TestFlight (iOS beta) · GitHub

01Overview

SentiKits helps people work through emotional moments from their phone, moving through curated reflection kits, journaling their progress, connecting in community groups, and shopping physical and digital products. As founding engineer I own the React Native client and the Firebase backend, including the Firestore data model, the Cloud Functions layer, security rules, and the subscription system. The app spans about 45 routes, 30 Cloud Functions, and 20+ Firestore collections, shipping to iOS and Android from one codebase and currently in beta.

02What I built

  • Kits & reflection engine - curated kits made of reflection cards, "new normal" reframes, journal prompts, and workbook chapters, with per-card and per-kit progress tracking - each kit opening with a kit-specific breathing-intro meditation overlay (Reanimated + SVG).

  • Journaling - kit-linked and standalone entries with create/edit/filter, free-tier limits, and unlimited entries for subscribers.

  • Community - groups with posts (text + images), threaded comments, a weekly song feed with voting, direct messaging, user search, and an "Inner Circle" of accepted connections.

  • Shop - an in-app storefront backed by the Shopify Storefront GraphQL API, with a Firestore-cached catalog and a persisted cart.

  • Subscription & redeem-code layer - a 5-state entitlement model (free / trial / redeemer / paid / expired) with server-side Apple App Store receipt verification, plus physical-kit redeem codes generated and validated by admin Cloud Functions.

  • Notifications - an FCM push pipeline and an in-app inbox written only by server-side Firestore triggers (post/comment/like/message/connection events + scheduled broadcasts).

  • Guided onboarding - a 7-step spotlight tour over the core surfaces, reset on sign-out.

  • SAM (designed, coming soon) - a planned AI companion ("Self-Awareness Mediator") with a warm, non-clinical persona and a tiered safety-escalation framework - shipping as a waitlist today, conversational backend not yet live.

03Architecture

Mobile App

React Native 0.80 · TypeScript · iOS + Android

Firebase

serverless · no servers to manage

Auth

email · Google · Apple · phone

Firestore

20+ collections

Cloud Functions

TypeScript · Node 20 · 30 fns

Cloud Storage

user media · FCM push

External

Apple IAP · Shopify · OpenAI

A single React Native client talks to Firebase over its SDK, so there are no servers to manage. Firebase provides auth, Cloud Firestore for app data, Cloud Functions on Node 20 for trusted logic, FCM for push, and Cloud Storage for media. Two external services sit behind the Functions, the Apple App Store Server API for receipt verification and the Shopify Storefront API for the shop.

04Technical challenges

Server-verified subscription billing

Problem
Entitlements reported by the client can be spoofed, which would hand out paid features for free.
Approach
I moved entitlement state server-side and verify iOS receipts in a Cloud Function with Apple's app-store-server-library, decoding and signature-checking transactions across production and sandbox before persisting them. Clients only read their entitlement.
Result
Entitlements are provable from server state, with one subscription per account rather than a value the client asserts.

Entitlement state machine

Problem
Access depends on trials, paid subscriptions, and physical-kit redeem codes, each on its own clock, and it has to stay correct as they start and lapse.
Approach
I modeled access as five states (free, 30-day trial, 12-month redeemer, paid, expired) checked through one useEntitlementGate hook, with a daily scheduled function that expires lapsed trials and codes and re-checks renewals.
Result
Gating is consistent across the app and the entitlement state corrects itself every day.

Real-time community, no servers

Problem
Posts, comments, likes, and messages need to feel live, notifications cannot be forgeable by clients, and I did not want to run realtime infrastructure.
Approach
I used Firestore onSnapshot listeners with careful unsubscribe cleanup in the MobX stores and did notification fan-out entirely in Firestore triggers, so the notifications collection is only writable by server functions.
Result
Live updates and trustworthy notifications with no realtime infrastructure to operate.

Tamper-proof moderation

Problem
A social surface needs block, report, and admin moderation to stay store-compliant and resistant to abuse.
Approach
I had block and report write to server-only collections, used admin-gated Cloud Functions to resolve reports and delete content with its nested comments, and made maintenance scripts take a backup before any destructive delete.
Result
A moderation loop the client cannot tamper with, with a backup before anything is removed.
Reflection cards
Journal
Community feed

05Stack & why

React Native for one mobile codebase, Firebase for a complete backend with no servers to run.

React NativeTypeScriptMobXReact QueryNativeWindReanimatedFirebaseCloud FirestoreCloud FunctionsFCMApple IAPShopifyOpenAI (planned)Fastlane

06Outcomes

In beta

iOS via TestFlight · Android from the same React Native codebase

34 / ~45

Screen modules / named routes

30

Cloud Functions · callable · triggers · scheduled

20+

Firestore collections

5

Entitlement states · free · trial · redeemer · paid · expired

Server-verified

Apple IAP receipts (App Store Server API)