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. The Flutter codebase runs to 72,753 lines of Dart across 183 files and 63 screens, against a separate backend at api.journita.ai.
02 The Challenge
A single app absorbing an assistant, a marketplace, a social feed and four booking flows has no natural seams, and almost none of the hard problems were in the Dart. The AI runs server-side and streams over Server-Sent Events, trip chat runs over Socket.IO, and eSIM, flights and payments each sit behind a different third-party provider reached through the backend. That meant most failures arrived as somebody else's contract breaking: a stream that returned HTTP 200 with an error inside it, a pagination parameter that was correct over the wire and wrong once it reached the database, a realtime socket that never upgraded, and a sign-in method that was implemented correctly in code and still refused to work.
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
