KNKuba Nowacki
← Work

Undesk

A mobile app for desk workers with neck, back and wrist pain. Claude builds an adaptive four-week plan from daily check-ins, and Pro access is enforced server-side through RevenueCat.

Status
App Store
Platforms
iOS · Android
Started
2026
Stack
Expo, React Native, NestJS, Claude
  • Undesk screenshot 1
  • Undesk screenshot 2
  • Undesk screenshot 3
  • Undesk screenshot 4
  • Undesk screenshot 5
  • Undesk screenshot 6

Undesk is a mobile app for desk workers with neck, back and wrist pain. Each day you check in, and it gives you a short stretch routine that fits what hurts. It is on TestFlight now.

An adaptive plan, not a fixed programme

Every user gets a four-week plan generated by Claude from their daily check-ins: where it hurts, how much, how long they sat. The plan changes as the check-ins change, so week three can look nothing like week one.

Generation has to be safe to repeat. A user can tap twice, the app can retry on a bad connection, and a job can run twice. I made plan generation idempotent, so the same request always lands on the same plan instead of creating a second one.

Long-running AI jobs

A full plan takes longer than a request should stay open. The API accepts the request, queues the work on BullMQ and returns right away. The app shows progress and picks up the finished plan when the worker is done. A failed job retries without the user doing anything.

Pro access is decided on the server

Undesk has a subscription through RevenueCat. The app never decides on its own whether someone is Pro. The backend keeps the entitlement, and a RevenueCat webhook updates it. I hardened that webhook: it verifies the signature, ignores events it has already processed, and handles events that arrive out of order.

The result is that a modified client cannot unlock Pro, and a renewal or refund shows up in the app without a release.

Production-readiness audit

Before sending the app to TestFlight reviewers I audited the whole stack for production readiness: auth, rate limits, webhook handling, error reporting and data deletion. The audit produced a list of fixes, and I worked through it before shipping.

What I would keep

Queuing the AI work and keeping entitlements on the server cost more time up front than calling the model from the app. Both paid off the first time a job failed or a webhook arrived twice, and nothing visible went wrong for the user.

Where it stands

Undesk runs on iOS and Android and is out on the App Store.