Skip to content
Dr4culePublic

About

Casual transport pooling app

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

OnTheWay (Work in progress)

A casual, real-time ride-sharing marketplace — grab a ride from someone already heading your way.

Not a taxi app, not ride-hailing. Everyone can both post and join rides. You're already going there — someone can simply come along and split the fuel cost.

Flutter · Supabase · PostGIS · OpenStreetMap · UPI


What it is

OnTheWay connects people who are already travelling with others going the same way. Open the app, see nearby rides on a map, book a seat, coordinate a safe meet point, travel, and settle a small fuel contribution over UPI or cash after the ride. It is not ride-hailing: drivers are not taxis; they are people already on the route.

✨ Features

Discovery

  • Rides around you — location-scoped discovery fetches only nearby rides using the rides_nearby PostGIS RPC, with a user-adjustable 5-60 km radius. The feed refreshes on pull-to-refresh, radius changes, and meaningful location/provider updates rather than a timer that resets the review session.
  • Live OpenStreetMap map with theme-aware dark/light tiles, route polylines, vehicle-aware markers, and cancellable tile requests for web performance.
  • Filters for leaving soon, cheapest, women-only, verified, plus live ride count and distance-aware sorting.
  • First-run onboarding explains the product model: not a taxi app, trust first, and one-tap commutes.

Post a ride

  • Pick a vehicle you own (or add one on the spot: type, model, plate, mileage).
  • Origin & destination via address autocomplete (OpenRouteService geocoding), drop a pin on the map, or explicitly use current location. The Create Ride page does not auto-request browser location on open, so web preview remains responsive.
  • Save regular commutes and reuse them for one-tap route setup; saved commutes sync through Supabase when using the real backend.
  • Real routed distance/ETA and an intelligent fare (distance x mileage x fuel price x traffic) with an enforced allowed range — drivers can't over-charge.
  • Seats, departure window, luggage, gender preference, and a note for riders.

Book & coordinate

  • First-come-first-serve seat reservation; rides close automatically when full or after departure.
  • Smart meet-point suggestions (metro, bus stop, petrol pump, mall…).
  • Participant-only chat for accepted/completed bookings, backed by chat_messages RLS.
  • UPI or cash after the ride — the app records payment status (pending / paid) but never processes money.

Trust & profile

  • Post-ride ratings feed a trust score recalculated server-side from real ratings.
  • Trust badges show tier, rating, completed rides, and verification signals on ride cards, booking, and profile.
  • Editable profile — change your name, UPI, phone, emergency contact, college/company, and upload a profile photo (Supabase Storage). Email is locked to your login.
  • Verification document submission for ID, licence, college, and company proof. Documents are stored privately in Supabase Storage and recorded as review requests.
  • Money saved / earned and CO2 saved stats.

Brand & platform

  • Custom OnTheWay logo mark and generated Android, iOS, web, and PWA icons.
  • Realtime-ready rides, bookings, chat, notifications, and a mock backend mode for offline UI work.
  • Dark-mode-first Material 3 UI with Riverpod state management.

🧱 Stack

Layer Choice
App Flutter (Material 3), Riverpod DI/state, feature-first + clean architecture
Backend Supabase — Auth, Postgres + PostGIS, RLS, Realtime, Storage, Edge Functions
Maps OpenStreetMap via flutter_map, OpenRouteService for routing/ETA/geocoding
Location geolocator
Payments UPI deep links (+ cash) — status tracked, no gateway

Route matching uses real polyline/PostGIS overlap (search_matched_rides), not straight-line distance. The map layer sits behind a MapService abstraction so a different provider can be swapped in without touching business logic.

📁 Project structure

lib/
  main.dart                 # bootstrap: load .env, init Supabase, run app
  app.dart                  # MaterialApp + theme + AuthGate
  core/
    brand/                  # custom OnTheWay logo widgets
    config/app_config.dart  # typed env access
    theme/                  # colors, spacing, typography, dark/light themes
    errors/
  data/
    models/                 # UserProfile, Ride, Booking, Vehicle, TrustScore, ChatMessage, SavedCommute, …
    repositories/           # RideRepository (abstract) + Mock + Supabase impls
    services/               # map_service, open_route_service, location_service
  features/
    auth/                   # auth gate + email/password screen
    onboarding/             # first-run product onboarding
    home/                   # bottom-nav shell + ride feed + map
    create_ride/            # saved commutes, vehicle picker, autocomplete, map pin, fare preview
    profile/                # editable profile, avatar upload, verification submission
    rides/
      application/          # Riverpod providers
      domain/               # pricing_engine, route_matcher
      presentation/         # booking sheet, chat screen, ratings, trust badges
supabase/
  migrations/               # full schema, RLS, RPCs, views, storage buckets
  functions/                # Edge Functions (matching, pricing, notify, trust…)
  seed.sql, *.sql           # demo data + repair helpers

🚀 Getting started

Prerequisites: Flutter (stable, 3.44+), a Supabase project, and a free OpenRouteService API key (optional — the app falls back to offline estimates without it).

# 1. Configure environment (public values only — never commit real keys)
cp .env.example .env
#    then edit .env with your SUPABASE_URL, SUPABASE_ANON_KEY and ORS_API_KEY

# 2. Install packages
flutter pub get

# 3. Run
flutter run

.env is intentionally git-ignored and is bundled as a Flutter asset, so you must create it before building. Set USE_MOCK_BACKEND=true to run entirely on in-memory data (great for UI work, demos, and tests — no Supabase or network needed). For Flutter web preview, if the debugger says the main isolate is paused, press Resume in DevTools; that is a debugger state, not an app crash.

Environment variables

Key Purpose
SUPABASE_URL Your Supabase project URL
SUPABASE_ANON_KEY Publishable/anon key (safe for the client)
ORS_API_KEY OpenRouteService key for routing & geocoding (optional)
USE_MOCK_BACKEND true = in-memory backend, false = Supabase

The service-role key never goes in the client .env — it lives only in supabase/.env.local (git-ignored) for migrations/function deploys.

🗄️ Supabase setup

supabase login
supabase link --project-ref <your-project-ref>

# Schema, RLS, RPCs, views, storage buckets
supabase db push --linked

# Optional: seed demo users/profiles/vehicles/rides
supabase db push --linked --include-seed --yes

# Edge Functions
supabase functions deploy match-rides
supabase functions deploy recommend-price
supabase functions deploy generate-recurring-rides
supabase functions deploy calculate-trust-score
supabase functions deploy notify

For rapid local testing, supabase/config.toml disables email confirmations (enable_confirmations = false) so signup isn't blocked by the hosted email quota. Enable confirmations + custom SMTP before production.

Demo ride times are relative; if the feed goes quiet after a long session, refresh them:

supabase db query --linked --file supabase/refresh_demo_rides.sql

Scaling: location-scoped discovery

The feed never downloads every ride in the country. The client sends its location + a radius (default 15 km, user-adjustable 5–60 km) to the rides_nearby(lng, lat, radius_m, limit) RPC, which uses PostGIS ST_DWithin against the GiST index on rides.origin and returns only nearby, open, non-expired rides ordered by distance and hard-capped. The query re-runs as the user moves (a location stream that emits every ~300 m), when the radius changes, and on pull-to-refresh — without global realtime fan-out or timer-based UI resets. This keeps payloads and DB work bounded no matter how many rides exist nationwide.

Backend shape

The migrations create profiles, vehicles, rides, meet points, bookings, ride locations, chat, notifications, ratings, saved commutes, verification requests, recurring templates, payment events, reports, and cache tables; enums for every status; RLS protecting participant-only data; PostGIS indexes; RPCs for matching/booking/cancellation/payment/trust; storage buckets (avatars, vehicle-photos, verification-docs); and a realtime publication.

Demo accounts (if seeded)

riya@example.com / password123      (driver)
arjun@example.com / password123      (driver)
meera@example.com / password123      (rider — browse & book the seeded Delhi ride)

✅ Verify

flutter analyze     # static analysis — should report no issues
flutter test        # unit + widget tests

Ride lifecycle rules enforced server-side:

  • Passengers pick UPI-after-ride or cash-after-ride at booking; payment is only recorded, never collected.
  • No two overlapping requested/accepted bookings per passenger.
  • Passengers can cancel upcoming bookings (seats auto-restore); drivers can cancel their rides (bookings auto-cancel); cancelled bookings can't be marked paid.
  • Chat messages are readable/writable only by ride participants through RLS.
  • Saved commutes and verification requests are scoped to the signed-in user.

🗺️ Roadmap

Admin review for verification requests · live trip tracking · richer realtime chat notifications · recurring ride generation UI · shareable ride groups · campus/company mode gating · gamified eco dashboard.

📄 License

Released under the MIT License.


Built with Flutter & Supabase. Contributions welcome.

About

Casual transport pooling app

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages