Elderly SOS pendants used to call the family. That is the whole product for most competitors. The problem: family members are at work, on flights, or asleep. The pendant beeps, nobody picks up, the emergency escalates.
Sensu Ángela's founder wanted to change the shape entirely. Every pendant press should ping a live 24/7 call center AND every family member simultaneously. Whichever human responds first takes the case. Nobody is left alone with a button they hope somebody hears.
The moving parts#
- Eview GPS pendants — cellular-connected, panic button, fall detection, GPS location.
- MQTT ingest — pendants speak MQTT to our broker.
- FastAPI worker — subscribes to MQTT, writes to Postgres, fans out events.
- Postgres — canonical state (users, devices, alerts, subscriptions, family relationships).
- Next.js PWA — customer web app, admin panel, operator panel, family panel.
- Capacitor iOS wrapper — App Store presence.
- Android TWA via Bubblewrap — Google Play presence.
- Stripe subscriptions with MSI — Mexican-specific installment plans without interest.
- Twilio Programmable Voice — outbound calls to the family when a pendant fires.
The pendant → alert → response flow#
- Elder presses the pendant (or a fall is detected).
- Pendant sends an MQTT message with location, battery, and a signature.
- FastAPI worker validates the signature, writes the alert to Postgres, publishes a fan-out event.
- Three things happen in parallel:
- The 24/7 call center operator panel gets a new red card with the elder's profile, location on a map, and next-of-kin contacts. - Every family member's app gets a push notification. - Twilio calls every family phone number in a rotation.
- Whoever acknowledges first (operator or family) claims the alert. Everyone else's phone stops ringing.
- The operator's ack triggers a case file (voice notes, photos, resolution). The family's ack triggers a call transcript record for the operator to review.
Median end-to-end latency from pendant press to first human seeing the alert: 3.4 seconds.
Why PWA-wrapped, not native#
Native iOS + native Android + a web admin panel = three codebases. For an early-stage company that is a maintenance disaster.
The Sensu app is a Next.js 15 PWA. On iOS, Capacitor wraps it into a native App Store submission. On Android, Bubblewrap packages it as a Trusted Web Activity for Google Play. The web admin panel is the same PWA at a different route.
One codebase, three distribution channels. Ship a feature once, it lands everywhere within a day.
Push notifications through the wrapper#
The tricky part with PWA wrapping is push. iOS Safari has strict PWA push rules; Capacitor bypasses them by exposing native APNs to the PWA layer. Android TWA uses FCM natively.
The PWA code has one sendPush(userId, message) call. A thin adapter routes to APNs on iOS Capacitor and FCM on Android TWA (and to Web Push on the desktop PWA). The app code never knows the difference.
Stripe MSI — meses sin intereses#
Mexico's retail installment culture is different from the US. Customers expect "3 meses sin intereses" or "6 MSI" as a standard option. Stripe supports this natively for Mexican cards issued by participating banks.
The subscription page shows the plans in three columns: monthly, 3 MSI, 6 MSI. Selecting MSI charges the full amount to the customer's card as a single transaction, but the bank splits it into equal monthly charges without adding interest — the bank absorbs the finance cost, the merchant gets paid up front.
The Stripe integration is 60 lines of code and the customer conversion lift was measurable.
Publishing to the App Store on first submission#
Apple rejects PWA-wrapped apps that "feel like a website". The mitigation:
- Every screen has native-feeling transitions (Capacitor's native page transitions plugin).
- Bottom tab bar uses native styling (not web).
- The onboarding flow uses native permission prompts (location, camera, notifications).
- Metadata screenshots are taken inside the wrapped app, not the browser.
Sensu Ángela passed Apple review on first submission. That is the only success metric that matters for the initial launch — every rejection round adds a week.
What is live now#
- iOS App Store — Sensu Ángela, live under the client's Apple Developer account.
- Google Play — Sensu Ángela, live under the client's Play Console.
- app.sensu.com.mx — the same PWA in the browser for admins.
- 24/7 call center — 8 operators rotating shifts.
- N pendants in service (public number pending business milestone).
The client owns the Next.js codebase, the FastAPI worker, the iOS Xcode project, the Android Bubblewrap config, and the deployment scripts.

