Mobile App · Case Study
Journita AI
Journita AI is a travel app built around a conversational assistant. A traveller can ask for somewhere to eat, plan a trip with friends in a shared group chat, buy an eSIM before landing, book a flight or a ride, and pay from an in-app wallet. Live on the App Store and Google Play.
01 Overview
Journita AI positions itself as an AI travel companion, and the onboarding states the promise plainly: ask, explore, and book through conversational AI that understands your preferences. In practice the app is broader than a chat assistant. It ships fifteen feature areas behind a five-tab shell of Chat, Explore, Trips, Feed and Account, covering an AI assistant, a map-based explore surface, group trip planning, a social feed, eSIM purchase and top-up, flight booking, food ordering, ride booking and a wallet. It is one Flutter codebase for iOS and Android, 63 screens in all, against a separate backend at api.journita.ai.
02 The Challenge
One conversation carries a traveller from a question to a booking that is paid for. That single promise set the engineering constraints. The assistant answers over a stream, so the screen has to be useful while a reply is still arriving rather than after it lands. Trips are planned by groups, so several people edit the same trip at once and each expects to see the others as they type. eSIM, flights, rides and food are four separate purchases with money at the end, so each one needs its own success and failure states rather than a shared one. And people use this in the places they have travelled to, on roaming or hotel wifi, so the app has to hold a session together across a connection that comes and goes.
03 The Solution
- 01Built the app in Flutter against a single Dart codebase for iOS and Android, with Provider for state and nine scoped change notifiers composed at the root rather than one global store.
- 02Consumed the assistant over Server-Sent Events, parsing the chunk-then-complete frame contract directly. The parser treats an error frame as a failure even though the response status is 200, because the stream can carry a server error inside a successful response and a naive client renders that as an empty message bubble.
- 03Diagnosed a backend pagination fault that only reproduced from the app and not from Postman: HTTP query parameters are always strings, and the string was reaching a MongoDB aggregation stage that requires a number. The fix belonged server-side, so the report named the cause, the affected endpoints and the one-line coercion, and stated plainly that no frontend workaround existed.
- 04Traced Apple Sign In failing with authorization error 1000 to a missing platform capability rather than a code defect, then authored the entitlements file and linked it through code signing so the working implementation could actually run.
- 05Ran trip group chat over Socket.IO with a heartbeat and bounded reconnection, and identified a 502 on the realtime endpoint as a reverse proxy that was not configured to upgrade the connection.
- 06Wired three sign-in paths, email and password, Google and Apple, all exchanged for a token against the project's own API, with JWT expiry checks and a single global handler that forces logout and redirects rather than leaving screens holding a dead session.
- 07Integrated eSIM, flights, rides and payments through the backend rather than embedding provider SDKs, and put a feature flag in front of the eSIM endpoints so the app could keep serving the legacy contract while a replacement API was still being built.
- 08Handled cold-start deep links by reading the launch link before the widget tree is built, with a retry ladder for trip navigation, plus a verified App Links and associated-domains setup alongside the custom scheme.
04 Key Features
- Conversational AI assistant streamed over Server-Sent Events
- Map-based explore for restaurants, hotels and activities by location
- Group trip planning with realtime chat over Socket.IO
- eSIM purchase and top-up with QR delivery
- Flight search, passenger details and booking
- In-app wallet with hosted card payment
- Social feed with posts, saves and following
- Push notifications and deep links into a trip or post
