Shuttle and Crew Scheduling
An in-house bilingual mobile app for small service operators, built as the second client of the same backend that runs our website.
- Shared API endpoints reused
- 4
- Platforms, one codebase
- 2
- UI locales from day one
- 2
Client
In-house product — in development
Services
Mobile app · UI/UX · Backend · i18n
Technology
React Native · Expo · TypeScript · FastAPI · PostgreSQL
The challenge
Small service operators — cleaning crews, shuttle vans, courier routes — run tomorrow's schedule out of a WeChat group and a printed sheet. A shift changes, the dispatcher posts a message, and whoever scrolls far enough finds out. Nobody has a record of who accepted what, and at the end of the week hours get reconstructed from memory.
These crews are bilingual and often Chinese-dominant. The scheduling tools sold into this market are English-first and assume a desk with steady wifi. A driver in a parking garage or a cleaner in a basement service corridor has no signal at the exact moment the schedule matters most. The gap is not features. It is language and connectivity.
What we built
This is Porcelain Tech Studio's own product, in active development. No client commissioned it and nothing has shipped. We are building it because the shared-backend architecture behind our website needed a second, genuinely different client to prove it — one that is mobile, offline-tolerant, and nothing like a browser.
React Native on Expo, one codebase for iOS and Android. It talks to the same FastAPI service and the same PostgreSQL database that serve the website: the same session auth, the same health check, the same deploy path. No second backend and no duplicated user model.
- Job lists render from local storage first and reconcile with the server when signal returns. Opening today's work never waits on the network.
- Shift swaps are one tap to offer and one tap to accept, and the accept writes a row. A handoff stops being a chat message somebody might have missed.
- A manager view shows today, tomorrow, and every unfilled slot.
- English and Chinese ship in the same build, from the first screen. Language is a field on the record, not a translation pass added at the end.
Outcome
Development is ongoing, so the numbers here are the targets governing the build rather than results we are claiming.
Four endpoints carry over from the website API unchanged. Two platforms come off one codebase. The job list opens with zero network requests, which is a constraint that shapes the local data layer rather than a feature added later.
The useful result is architectural. Building a mobile client against the same contract forced that contract to stop assuming a browser. Whatever app work we take on next starts from an API that has already served two very different consumers.
Want something like this?
Most projects start with a short description and a rough budget. We take it from there.