Design a system which levied taxes/penalties on drivers and riders with some constraints like completing 10 rides a month or getting lesser than average rating of that area consistently
Let's look into FR
FR
1.The system should support registration and management of two user types: drivers and riders.
2.Each user should have a unique profile containing their ride history, ratings, and location metadata.
3.The system should track each completed ride, associating it with both the driver and the rider.
4.Each ride record should include:
Timestamp
Location (pickup and drop)
Driver ID
Rider ID
Rating given by rider and driver
Duration and distance
5.The system should compute and store:
Number of rides per user (monthly basis)
Average rating per user over a sliding window (e.g., last 5 rides or monthly)
Area-wise average rating
6.The system should regularly update area-wise aggregate statistics (e.g., daily or hourly).
7.The system should define constraints/rules, such as:
Drivers completing fewer than 10 rides/month
Riders giving ratings significantly lower than the local average
Drivers consistently getting below-average ratings in an area
8.The system should evaluate these constraints periodically (e.g., daily, weekly, monthly).
9.Rules should be configurable so new policies can be added without redeploying the service.
10.When a rule is violated, the system should:
Automatically calculate the penalty amount
Associate it with the violating user
11.Users should be notified about:
Why they are penalized (rule violated, stats)
The amount and due date
NFR
1.System should be highly scalable to support scaling horizontally to handle increasing numbers of users, rides, and evaluations.
2.The system should maintain 99.9% uptime as it deals with critical billing and penalties that affect user trust and revenue.
3.Ride recording and rating submissions should happen with sub-second latency.
4.The system must ensure strong consistency for:
Ride counts per user per month
Average rating calculations
5.The system should be fault tolerant to individual service or node failures.
Estimates
Active cities = 100
Active drivers = 1 million
Active riders = 10 million
Daily rides = 5 million
Avg ride duration = 20 minutes
Ratings per ride = 2 (rider → driver & driver → rider)
Evaluation frequency = Daily batch
Evaluation window = 30 days
Ride data Storage
Per ride size:
- Ride metadata: ~500 bytes
- Ratings (2x): ~100 bytes
- Total per ride: ~600 bytes
Daily:
5M rides × 600B = 3 GB/day
Monthly (raw): 90 GB
With overhead (×2): ~180 GB/month
🧮 2. Rating Aggregation & Rule Evaluation
Users to evaluate: 1M drivers + 10M riders = 11M users
Rules per user: 3
Total rule evaluations/day:
11M × 3 = 33M evaluations
If system supports 10k eval/sec:
33M / 10k = ~3,300 sec ≈ 55 minutes (can be parallelized)
API’s
1. User & Ride APIs
GET /users/{userId}/summary
Description: Fetch ride count, average rating, and penalty summary for a user.
{ "userId": "user_123", "userType": "driver", "monthlyRideCount": 12, "averageRating": 4.2, "areaAverageRating": 4.5, "penalties": [ { "penaltyId": "pen_001", "amount": 100, "reason": "Low rating", "status": "UNPAID" } ] }
2.
POST /rides/complete
Description: Submit a completed ride record.
request { "rideId": "ride_789", "driverId": "user_123", "riderId": "user_456", "startTime": "2025-05-19T10:00:00Z", "endTime": "2025-05-19T10:20:00Z", "pickupLocation": "City Center", "dropLocation": "Airport" } response { "status": "success" }
3.POST /ratings/submit
Description: Submit a rating after a ride
request {
"rideId": "ride_789",
"fromUserId": "user_456",
"toUserId": "user_123",
"rating": 3.5
}
response { "status": "success" }
Rule Evaluation APIs
POST /rules/evaluate
Description: Trigger rule evaluation for a given user or batch.
request {
"userIds": ["user_123", "user_456"],
"evaluationDate": "2025-05-19"
}
response {
"evaluated": 2,
"penaltiesIssued": 1
}
GET /rules/violations?userId=user_123
Description: Get detailed rule violations for a user.
[ { "ruleId": "rule_001", "ruleName": "Low Monthly Ride Count", "violated": true, "details": { "monthlyRides": 6, "threshold": 10 } } ]
3. Penalty Management APIs
GET /penalties?userId=user_123
Description: List all penalties for a user.
[
{
"penaltyId": "pen_001",
"amount": 100,
"reason": "Low rating",
"status": "UNPAID",
"issuedAt": "2025-05-01T10:00:00Z"
}
]
POST /penalties/pay
Description: Mark a penalty as paid (or initiate payment).
Request:
{
"penaltyId": "pen_001",
"paymentMethod": "wallet"
}
response { "status": "paid" }
4. Admin APIs
POST /admin/rules
Description: Create or update a penalty rule.
Request:
request {
"ruleId": "rule_001",
"name": "Low Monthly Ride Count",
"description": "Penalty if less than 10 rides in a month",
"userType": "driver",
"threshold": 10,
"penaltyAmount": 100,
"active": true
}
POST /admin/penalties/waive
Description: Admin waives a penalty.
request {
"penaltyId": "pen_001",
"reason": "Verified dispute"
}
Databases
| Purpose | Database Type | Why? |
| ----------------------------- | ------------------------------------------------------- | --------------------------------------------------------------- |
| Core transactional data | **Relational DB (SQL)** like PostgreSQL or MySQL | Strong consistency, relational joins (users, rides, penalties) |
| Fast access to computed stats | **In-Memory Store** like Redis | Quick access to pre-aggregated metrics (monthly rides, ratings) |
| Rule evaluation & logs | **Document DB** like MongoDB or **NoSQL** like DynamoDB | Flexible schema, fast inserts, scalable |
| Analytics & reporting | **Data warehouse** like BigQuery, Redshift | Complex queries, aggregations, dashboards |
| Archival storage | **Object Store** like Amazon S3 | Cost-effective long-term data retention |
🗂️ Schema Design (Relational)
1. users
CREATE TABLE users (
user_id VARCHAR PRIMARY KEY,
name TEXT,
user_type ENUM('driver', 'rider'),
city TEXT,
created_at TIMESTAMP
);
2. rides
CREATE TABLE rides (
ride_id VARCHAR PRIMARY KEY,
driver_id VARCHAR REFERENCES users(user_id),
rider_id VARCHAR REFERENCES users(user_id),
start_time TIMESTAMP,
end_time TIMESTAMP,
pickup_location TEXT,
drop_location TEXT
);
3. ratings
CREATE TABLE ratings (
rating_id SERIAL PRIMARY KEY,
ride_id VARCHAR REFERENCES rides(ride_id),
from_user_id VARCHAR REFERENCES users(user_id),
to_user_id VARCHAR REFERENCES users(user_id),
rating FLOAT CHECK (rating >= 1.0 AND rating <= 5.0),
created_at TIMESTAMP
);
4. rules
CREATE TABLE rules (
rule_id VARCHAR PRIMARY KEY,
rule_name TEXT,
user_type ENUM('driver', 'rider'),
metric TEXT, -- e.g. "monthly_rides", "rating_vs_area"
threshold FLOAT,
penalty_amount INT,
description TEXT,
active BOOLEAN,
created_at TIMESTAMP
);
5. penalties
CREATE TABLE penalties (
penalty_id VARCHAR PRIMARY KEY,
user_id VARCHAR REFERENCES users(user_id),
rule_id VARCHAR REFERENCES rules(rule_id),
amount INT,
status ENUM('UNPAID', 'PAID', 'WAIVED'),
issued_at TIMESTAMP,
paid_at TIMESTAMP
);
6. area_metrics
(for fast comparison with area averages)
CREATE TABLE area_metrics (
city TEXT,
user_type ENUM('driver', 'rider'),
metric TEXT, -- e.g. "avg_rating"
value FLOAT,
computed_at TIMESTAMP,
PRIMARY KEY (city, user_type, metric)
);
7. rule_violations
(optional audit)
CREATE TABLE rule_violations (
violation_id SERIAL PRIMARY KEY,
user_id VARCHAR,
rule_id VARCHAR,
evaluated_at TIMESTAMP,
violated BOOLEAN,
details JSONB
);
Redis Caches (Examples)
monthly_rides:user:{user_id}
→ INT (rides in current month)avg_rating:user:{user_id}
→ FLOAT (recent rolling average)area_avg_rating:city:{city}
→ FLOAT (periodically refreshed)
🧠 Optimization Tips
Use materialized views or scheduled jobs to pre-aggregate monthly ride counts and ratings.
Shard large tables like
rides
,ratings
,penalties
by user ID for scalability.Partition
rides
andratings
by date for better performance.Use Kafka or CDC pipelines to sync transactional data to warehouse for analytics.
HLD
🧩 Microservices Overview
1. User Service
Manages user profiles (drivers/riders)
Exposes user metadata for penalties and evaluation
2. Ride Service
Stores ride history, ride metadata
Publishes ride completion events
3. Rating Service
Manages post-ride ratings
Publishes rating submission events
4. Penalty Evaluation Service
Evaluates rule violations for each user
Consumes events from Ride and Rating Services
Issues penalties via Penalty Service
5. Penalty Service
Stores, tracks, and manages penalty records
Sends notifications to users
Interfaces with Payment Service for penalty payments
6. Rule Engine Service
Hosts and applies configurable rules
Can evaluate complex conditions (e.g. average rating below city avg)
7. Notification Service
Sends SMS, push, or email alerts for penalties or warnings
8. Area Metrics Service
Calculates rolling metrics like average rating per area
Updates periodically via batch jobs or streaming aggregation
9. Admin Service
Allows admins to configure rules, waive penalties, or audit data
10. Payment Service
Handles penalty fee payments
Integrates with wallets/cards/etc
+------------------+ +-----------------+ +-------------------+
| Ride Service | ----> | Rating Service | ---> | Area Metrics Svc |
+------------------+ +-----------------+ +-------------------+
| | |
v v |
Publishes Ride Publishes Rating Computes City Avg
Completion Submission (Batch/Stream)
| | |
v v v
+--------------------------------------------+
| Penalty Evaluation Service |
+--------------------------------------------+
| | |
| | v
| | +--------------+
| +------> | Rule Engine | <------ Admin
| +--------------+
v
+----------------+ +------------------+
| Penalty Svc | <----------> | User Service |
+----------------+ +------------------+
|
v
+------------------+ +-------------------+
| Notification Svc | | Payment Service |
+------------------+ +-------------------+
🛰️ Asynchronous Communication
Used where event-driven flow is appropriate (via Kafka, SQS, etc.)
RideService →
ride.completed
→ PenaltyEvaluationRatingService →
rating.submitted
→ PenaltyEvaluationAreaMetrics →
area.rating.updated
→ RuleEngine
📬 Synchronous APIs (REST/gRPC)
Used for:
Admin operations
Fetching penalty details
Paying penalties
Querying user history
⚙️ Example Flow: Apply Penalty for Low Ratings
Rider submits a low rating for a driver.
RatingService
publishesrating.submitted
event.PenaltyEvaluationService
listens and fetches:Driver’s average rating (from RatingService or Cache)
City average rating (from AreaMetricsService)
RuleEngineService checks for violations:
e.g., “if average rating < city average for 5 consecutive days”
If violated,
PenaltyService
is called to issue a penalty.NotificationService
is triggered to inform the driver.Driver pays using
PaymentService
.