Designing a Ride Hailing Service in .NET - Part 1 - Defining the domain models

When I think of designing a ride-hailing service, below are the core functionalities I would like to have in it initially. Let us consider these as our initial requirements:

  1. A person can register on the platform as a customer or a partner (driver).

  2. A customer can request a ride by entering a pickup location and a drop location.

  3. The customer is shown the price estimate and asked to confirm. If customer confirms, the price is locked and a booking request is initiated.

  4. In case user has not yet entered payment details, they are asked to enter payment details.

  5. Once user confirms a ride, all drivers are sent a notification. We will modify this later to notify only nearby drivers.

  6. A driver can accept a ride by clicking on the Accept button.

  7. At this point, the customer is sent a notification showing the ride details, such as driver and the vehicle details, as well as provided with a PIN for verification.

  8. Once the driver reaches the pickup point, the customer provides the PIN to the driver to start the ride. The driver clicks on a button to start, and the journey begins.

  9. Upon reaching the destination, the customer makes payment online and the driver clicks on the End trip button.

  10. Users should be able to see the history of past trips.

Step 1: Define the Model Classes

Based on the above description of requirements, here are some of the key models you might consider when designing the architecture for a ride-sharing service:

1. User

  • Represents information about users, both riders and drivers.

  • Includes fields such as user ID, name, email, phone number, and authentication tokens.

  • May include user profile details and preferences.

public class User
{
    public int UserId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string PhoneNumber { get; set; }

    // Other common user-related properties and methods

    // Navigation property to link to the Driver model
    public virtual Driver Driver { get; set; } //in case this user has a driver profile
}

2. Driver

  • Represents driver profiles and information.

  • Contains fields like driver ID, name, contact information, vehicle details (make, model, license plate), and driver status (e.g., available, on a ride).

public class Driver
{
    public int DriverId { get; set; }
    public string LicensePlate { get; set; } // Vehicle license plate
    public double DriverRating { get; set; }
    public bool IsAvailable { get; set; }

    // Other driver-specific properties and methods

    // Navigation property to link to the User model
    public int UserId { get; set; }
    public virtual User User { get; set; }

    // Navigation property to link to the Vehicle model
    public int VehicleId { get; set; }
    public virtual Vehicle Vehicle { get; set; }
}

3. Vehicle

  • Represents information about the vehicles available for rides.

  • Includes details like vehicle ID, vehicle type (e.g., sedan, SUV), capacity, and vehicle status (e.g., available, in maintenance).

public class Vehicle
{
    public int VehicleId { get; set; }
    public string Make { get; set; } // Vehicle make (e.g., Toyota, Honda)
    public string Model { get; set; } // Vehicle model (e.g., Corolla, Civic)
    public string LicensePlate { get; set; }
    public int Year { get; set; } // Vehicle manufacturing year
    public string Color { get; set; }
    public int Capacity { get; set; } // Maximum passenger capacity
    public bool IsAvailable { get; set; } // Vehicle availability status

    // Other vehicle-related properties and methods

    // Navigation property
    public int DriverId { get; set; } // Foreign key to link to the associated driver
    public virtual Driver Driver { get; set; } // Driver associated with the vehicle
}

4. Ride

  • Represents an individual ride request or ride booking.

  • Contains information such as ride ID, rider details, driver details, pickup location, destination, and ride status (e.g., requested, accepted, completed).

  • Includes timestamps for ride creation, acceptance, and completion.

public class Ride
{
    public int RideId { get; set; }
    public int RiderId { get; set; }           //foreign key to associated user (passenger)
    public int DriverId { get; set; }          //foreign key to associated driver
    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; }
    public decimal Amount { get; set; }
    public string RideStatus { get; set; }

    // Navigation properties
    public virtual User Rider { get; set; }       //passenger details
    public virtual Driver Driver { get; set; }    //driver details
    public virtual Payment Payment { get; set; }  //payment details

    // Navigation properties for pickup and dropoff locations
    public virtual Location PickupLocation { get; set; }
    public virtual Location DropoffLocation { get; set; }
}

5. Location

  • Represents geographical locations, including pickup and drop-off locations.

  • Contains latitude and longitude coordinates, address details, and possibly location-based metadata.

public class Location
{
    public int LocationId { get; set; }
    public string Name { get; set; }
    public double Latitude { get; set; }
    public double Longitude { get; set; }

    // Other location-related properties and methods
}

6. Payment

  • Represents payment information for rides.

  • Includes details such as payment ID, payment method (credit card, digital wallet), transaction history, and fare details.

public class Payment
{
    public int PaymentId { get; set; }
    public int RideId { get; set; } // Foreign key to link to the Ride associated with the payment
    public string PaymentMethod { get; set; }
    public double Amount { get; set; }
    public DateTime PaymentDate { get; set; }

    // Other payment-related properties and methods

    // Navigation property
    public virtual Ride Ride { get; set; } // Ride associated with the payment
}

7. Notification

  • Represents notifications sent to users.

  • Contains fields like notification ID, recipient ID, message content, notification type, and timestamps.

  • May have RideId and DriverId as optional parameters for later once a ride is confirmed.

  • At a later stage, we may prefer to have different notification model classes for different types of notifications, rather than clubbing all the notifications into a single model/table. If the number of fields needed for different notifications keeps on increasing, then it may be a better idea to have a separate class for each notification type.

public class Notification
{
    public int NotificationId { get; set; }
    public int UserId { get; set; } // Foreign key to link to the user receiving the notification
    public string Message { get; set; }
    public DateTime NotificationDate { get; set; }
    public bool IsRead { get; set; }
    public NotificationType Type { get; set; } // Enum or string to indicate the type of notification

    // Additional properties for context and differentiation
    public int? RideId { get; set; } // Reference to the associated ride (null for initial notifications)
    public int? DriverId { get; set; } // Reference to the associated driver (null for initial notifications)

    //Email related
    public string EmailAddress { get; set; }
    public string Subject { get; set; }

    //SMS related
    public string PhoneNumber { get; set; }

}

public enum NotificationType
{
    User,
    Driver,
    System,
    Email,
    SMS
}

8. RideHistory

  • Represents historical ride data.

  • Includes ride details, timestamps, payment information, and other relevant ride-related data.

public class RideHistory
{
    public int RideId { get; set; } // Foreign key to link to the corresponding ride
    public int UserId { get; set; } // Foreign key to link to the user who took the ride
    public int DriverId { get; set; } // Foreign key to link to the driver for the ride
    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; }
    public decimal Amount { get; set; }
    public Location PickupLocation { get; set; }
    public Location DropoffLocation { get; set; }

    // Other ride-related properties and methods

    // Navigation properties
    public virtual Ride Ride { get; set; } // Reference to the corresponding ride
    public virtual User User { get; set; }
    public virtual Driver Driver { get; set; }
    public virtual Payment Payment { get; set; }
}

9. Event

  • The "Event" model is primarily used for logging and tracking various activities or interactions that occur within the application.

  • These activities can be diverse and cover a wide range of events, including user interactions, system notifications, ride-related events, and more.

public class Event
{
    public int EventId { get; set; } // Primary key
    public EventType Type { get; set; } // Enum or string indicating the type of event (e.g., user interaction, system notification)
    public int UserId { get; set; } // Foreign key to link to the user associated with the event
    public int RideId { get; set; } // Foreign key to link to the ride associated with the event (if applicable)
    public string Description { get; set; } // A brief description or message about the event
    public DateTime EventDate { get; set; } // Timestamp for when the event occurred

    // Other event-related properties and methods

    // Navigation properties
    public virtual User User { get; set; } // Reference to the user associated with the event
    public virtual Ride Ride { get; set; } // Reference to the ride associated with the event (if applicable)
}

In Part 2, we will discuss about how to define the services for this app. Stay tuned!