Operation at a glance: who's in line, who's available, who's busy and where are the drivers relative to the stop area?
From paper ledger to live operations system
2yaka was born from a very basic trust problem that recurs every day at the taxi rank: who gets in the queue first, who picks up passengers, who gets out of the queue, and when the manager intervenes is often kept track of on paper, WhatsApp or verbal memory. This not only creates inefficiency; It directly affects the driver's daily earnings and the sense of justice within the stop.
My product approach wasn't just to turn this problem into a digital list. I designed an operating model that calculates the queue from a single source, records changes, clearly shows the driver his position, and makes the manager's intervention visible. The promise at the heart of the product is therefore not technology: it is that each driver gets the turn he deserves and that the memory of the stop is not tied to a single person.
Development leadership: not one application, but four interconnected surfaces
I managed 2yaka's admin panel, stop panel and mobile application development processes end-to-end; I also developed the promotional site as part of the same product language and acquisition flow. This work did not only consist of producing screens. It was necessary to ensure that the layers, from the role model to database relationships, from the mobile location lifecycle to notification behavior, from web panel authorizations to publication and migration discipline, convey the same operational truth.
The driver sees his own stop, queue position and reservations in the mobile application. The stall manager manages the live queue, drivers, invitations, reservations, performance and geofence area. Super admin, on the other hand, provides system-wide control over stops, administrators, applications, notifications, feedback and platform settings. The Landing site explains this complex product to two separate users—the driver and the stall owner—with a clear value proposition.
The mobile home screen is not a decorative map; live operating surface for driver location, stall area, queue and operating status.
Driver app: location, queue and decision on the same screen
I developed the mobile application on Expo SDK 53, React Native 0.79, React 19 and Expo Router. The task of the main screen is as clear as possible: the driver sees at a glance which stop he is connected to, his free or busy status, his relationship to the stop area and his actual queue position. The user can manually enter and exit the queue as needed; geofence automation supports this flow by detecting entrance and exit to the physical area. Retaining manual control was a conscious product decision, as location permission, device manufacturer, battery optimization or poor connection should never be the sole decision point of the operation.
The application carries phone-based authentication, onboarding, profile and vehicle information, primary and secondary stop memberships, notification center, queue history, reservation offers and settings flows within the same navigation system. I separated local/remote state boundaries with Zustand and TanStack Query; I managed session information with Secure Store and necessary local preferences with AsyncStorage. I considered mobile behaviors such as haptic feedback, native date-time pickers, image picker, deep link and pull-to-refresh as natural parts of the product flow.
Multi-stop model: the driver can see the stops he is connected to, the live queue of each stop and his own position.
Sequence engine: rules behind visible position
The sequence is not a simple sequence number that the client writes on the screen. The active queue contract on the actual source PostgreSQL side. The driver's entry into the queue goes through the join-queue flow, and his exit goes through the leave-queue flow; The active list is read via get_active_queue RPC. Instead of storing the position as a fixed column, it is recalculated based on active records, priority and entry time. Thus, when two devices operate at the same time or the administrator intervenes in the queue, all clients can return to the same source.
Login methods such as manual login, geofence login and offline re-entry are separated in the system; The reason for leaving is also recorded. When a manager moves a driver to the front, sends him to the back, or removes him from the queue, this action leaves an audit trail. The daily queue session structure separates the operation days from each other. The driver_stations relationship for multi-stop membership allows the driver to attend other stops in a controlled manner while maintaining their primary stop. The main design goal here was for each user surface to show the same order truth and be able to explain what the system is in case of disagreement.
The booking surface brings the context of offer, pending job, time, number of passengers and location into the driver's work flow.
Reservations and notifications: also manage out-of-queue operations
As the product grew, just managing the queue was not enough. I developed a booking flow where the bus stop manager can create a passenger reservation, assign it directly to a driver, or publish it as an offer to available drivers. The driver sees the offer in the mobile application, accepts or rejects it; The system monitors statuses such as pending, offered, accepted, assigned, en-route, completed and cancelled. Closing offers that are not answered within the deadline and not disturbing the same driver repeatedly in short intervals are part of the backend rules.
I did not consider the notification system as a uniform push message. Joining the queue, queue approaching, queue coming, reservation offer, reservation reminder and general announcement have different importance and volume policies. Situations such as Android channel IDs, foreground behavior, persistent queue status and turn alert are managed with separate contracts. Notification actions do not directly change the risky operation while the application is in the background; It opens the relevant screen and receives confirmation from the user. Mobile transmission with Expo push, traceability with Supabase logs and announcements sent from the panel meet in the same life cycle.
The station manager defines the operation area on the map; center, radius, and polygon geometry fuel mobile location behavior.
Stall panel: work desk of daily operation
I developed the Durak panel on Next.js 15 as an operation tool that can display extensive data on the desktop but can also be managed from the phone when necessary. The panel includes live dashboard, queue management, driver list and details, invitation flow, reservations, notifications, performance, account and settings sections. Driver participation via QR and invitation code; Membership management via name, phone number and license plate; queue intervention and driver situations are kept in the same stop context.
The Geofence editor is one of the most critical technical surfaces of this panel. The manager can define the physical location of the stop, the operation center, the radius or polygonal area on the map. This data is not just a visual adjustment; It affects the mobile application's location evaluation, automatic login/logout behavior and field reports. I combined map layers with MapLibre, geographic data with PostGIS, and stop-based authority control. The panel can also be installed on the device home screen as a PWA; Thus, the computer, tablet or phone in a small stall office can become the same operating surface.
Mobile operation of the bus stop panel: map, geofence, active queue counters and management sections can also be accessed on the small screen.
Super admin: operating the platform, not a one-stop shop
The super admin panel is not an enlarged version of the stall manager's screen; a different decision surface. Here you can find platform-wide KPI and map view, stop list and details, creating new stops, drivers, managers, applications, reports, notifications, feedback and platform settings. Searching, filtering and sorting stops by status; appointing managers; reviewing memberships; Approving or rejecting applications and sending announcements are collected in this layer.
I deliberately preserved the border between the admin and the stall panel. While the station manager only sees the operation area for which he is authorized, the super admin works with cross-station data. Therefore, data access as well as UI differences are based on role and tenant context. When a stop record is soft-deleted, it is not enough to just keep the main line; Active admin connections, driver memberships, open queue records, sessions, and pending requests should also be closed consistently. I did not leave such life cycles just to the button on the screen, but secured them with database contracts and migrations.
Backend: multi-tenant system sharing the same reality
Backend uses PostgreSQL, Auth, Realtime, Storage and Edge Functions components on Supabase. The basic model is built around stations, profiles, drivers, vehicles, driver_stations, station_managers, queue_sessions, queue_entries, reservations, driver_locations, invitations, notifications and audit tables. The driver and the manager may have the same profile, but gain authority through different membership relationships; this distinction was especially important for real-world scenarios where a person may be at multiple stops or in multiple roles.
Join/leave, reservation actions, invitation processing, SMS/push transmission, location control and administrator queue interventions pass through Edge Function or secure RPC boundaries. RLS policies isolate data in the context of station_id and active membership. Decisions such as soft delete, audit log, phone and license plate normalization, atomic rate limiting, fail-closed CORS and input validation were added so that the product can work with real user and operation data, not just demo data. The most difficult part was not to increase the number of tables, but to ensure that each mutation was completed without interruptions between Auth, profile, tool, membership and row relationships.
Realtime architecture: consistency and load control as well as speed
The queue change should be reflected in the mobile application, stall panel and admin view without delay; However, opening separate queries and channels for each screen can rapidly increase the production load. In the realtime layer, I used station-based channels, TanStack Query invalidation and active queue RPC contract together. Combining WebSocket channels instead of duplicating them per surface, preventing duplicate subscriptions on mobile, and using broadcast when necessary reduced unnecessary reprocessing of the same event.
In this architecture, Realtime is not the sole source of accuracy; The transport layer that notifies the client of the change. When the connection is lost or the application returns to the foreground, the client recovers by re-reading the active queue. This distinction proved critical in actual device behavior. In particular, issues such as background restrictions of Android manufacturers, poor connection, old application versions and Supabase schema cache can produce different results from the happy flow on paper. While developing the product, I treated device, web, database and deployment verification as separate evidence layers.
Test, release and production operation
2yaka was not just a project where I developed features; It was a system in which I also managed the release and production operations. Monorepo keeps landing, admin, stop, mobile and partner packages under the same contract with Turborepo and pnpm workspaces. TypeScript checks, web production builds, mobile unit tests, API and security tests, Android device checks, migration drift checks and release preflight steps work separately from each other. A Git push, database migration, Realtime publication, Vercel deployment and store build are not the same thing; It is necessary to verify each one with its own output.
Android AAB and iOS release preparation on the mobile side; Vercel projects and private domains on the web side; On the backend side, Supabase migration and Edge Function publications are separate operation flows. I did not find the emulator output sufficient for device-dependent features such as location and notification, so I conducted long-term tests and notification behavior checks on real Android devices. Instead of waiting for a new mobile build for backend changes that could break old clients in production, I developed backwards compatible and targeted server-side fixes whenever possible.
Explaining the product was also part of the system design
I developed the demo site not as a generic SaaS showcase, but as a product surface that addresses real objections from two different user groups. Queue position, geofence, notification and history on the driver's side; Live operation, driver management, invitation and reporting are explained on the stop side. The home page unites these two sides under the same promise: a visible, fair and manageable stall layout instead of paper ledgers and uncertainty.
Live site; It includes product pages, download flow, stop application, contact, blog, privacy, terms of use and KVKK surfaces. Mobile application screens and stall panel visuals come directly from the product itself. In this way, the marketing layer shows the working interface instead of abstract promises. For me, 2yaka has become one of the most comprehensive product systems where product strategy, UX, mobile engineering, web applications, backend, field operation and release management intersect in a single project.
Today's situation and the most important thing I learned
2yaka.net is live today. While preparing this case study for the portfolio, I re-examined the main site, active repo structure, mobile screens, landing panel surfaces, backend functions and test directories. The scale of the study does not come from a single application file; It comes from product decisions that bring driver and administrator flows together in the same database reality.
This project taught me that field software is not just a nice and fast interface. Real product; It should also behave consistently when location permission is denied, the phone goes to sleep, the driver is connected to two stops, the administrator removes the wrong person, an old client connects to the new schema, or a deployment falls behind the source code. The development process I managed at 2yaka covered exactly all of these layers: defining the problem, designing the product, coding, releasing, monitoring it in production, and fixing it again based on real behavior.