-
Notifications
You must be signed in to change notification settings - Fork 44
Database‐Schema
Truxify implements a decoupled database design across Supabase (PostgreSQL), MongoDB, and Redis. Relational integrity, row authorizations, and atomic operations reside in Supabase, while event history is kept in MongoDB and in-memory caches in Redis.
Truxify tracks 27 distinct entities. Logical relationships (application-level joins) are utilized to link data together:
erDiagram
profiles {
uuid id PK
text firebase_uid UK
text role
text full_name
text phone
text email
text company_name
text avatar_url
text language
boolean dark_mode
boolean is_active
timestamptz created_at
timestamptz updated_at
}
driver_details {
uuid id PK
uuid user_id UK
uuid truck_id
numeric rating
int total_trips
numeric completion_rate
boolean is_online
int wallet_confirmed
int wallet_pending
int wallet_total
}
customer_stats {
uuid id PK
uuid user_id UK
int total_orders
int total_saved
numeric co2_reduced_kg
}
trucks {
uuid id PK
uuid driver_id
text name
text number_plate
numeric max_capacity_tons
int fuel_level_pct
int engine_health_pct
boolean tpms_connected
date insurance_expiry
date puc_expiry
date permit_expiry
}
orders {
uuid id PK
text order_display_id UK
uuid customer_id
uuid driver_id
uuid truck_id
text status
text pickup_address
float pickup_lat
float pickup_lng
text drop_address
float drop_lat
float drop_lng
date pickup_date
text goods_type
numeric weight_tonnes
int total_amount
text cancellation_reason
text driver_name
text eta
}
trips {
uuid id PK
text trip_display_id UK
uuid driver_id
text route_label
text status
date trip_date
int total_earnings
int net_earnings
text blockchain_hash
boolean verified_on_chain
}
documents {
uuid id PK
uuid user_id
text doc_type
text status
text file_url
text blockchain_hash
date valid_until
}
profiles ||--|| driver_details : "user_id"
profiles ||--|| customer_stats : "user_id"
profiles ||--o{ orders : "customer_id"
driver_details ||--o| trucks : "truck_id"
trucks ||--o{ orders : "truck_id"
orders ||--|| trips : "order_id"
profiles ||--o{ documents : "user_id"
Important
Truxify enforces no physical foreign keys in the database layer. All table associations are maintained logically at the application-layer (via REST query filters or RPC joins).
Why?
- Decoupled Scaling: Allows database partitions or separate micro-backends to scale independently (e.g., migrating trips to a separate database server in the future without breaking constraints).
- Flexible Deletions & Archive: Archiving or cleaning up old orders does not result in cascade errors or locks.
- Improved Performance: Eliminates parent-check write locks on heavy inserts.
-
profiles: The central user index. Stores names, emails, phones, and settings. Linked to Firebase Auth viafirebase_uid. -
driver_details: Extended stats for drivers, including ratings, trip counts, online toggles, and wallet ledger values. -
customer_stats: Aggregates customer booking frequencies, dynamic savings, and calculated CO₂ reductions.
-
trucks: Stores truck capacities, registration plates, fuel/engine telemetry, and document expiry flags. -
tyre_diagnostics: Real-time TPMS pressure values mapped per tyre position (front-left, rear-right, etc.). -
truck_maintenance_tickets: Tracks repair requests and scheduling histories for trucks.
-
orders: Stores pickup/drop coordinates, weight, cargo type, pricing details, status, and assigned driver. -
order_timeline: Milestones for active orders (e.g., "Assigned", "Picked Up", "In Transit", "Reached", "Delivered"). -
load_offers: Marketplace listings visible to nearby drivers. -
load_bids: Bids placed by drivers on active load offers.
-
trips: Active driver routing records tracking earnings and verification states. -
trip_stops: Sequential drop off points mapped to multi-delivery routes. -
route_map_points: GPS breadcrumbs indicating historical routes.
To prevent race conditions, double-allocations, or partial record failures during critical state changes, Truxify runs atomic SQL routines inside PostgreSQL.
When a customer accepts a driver's bid:
-- Logical sequence:
-- 1. Verify bid is 'pending' and order is 'pending'
-- 2. Lock order and driver records using SELECT FOR UPDATE
-- 3. Update order status to 'assigned', assign driver_id and truck_id
-- 4. Update load_offers status to 'assigned'
-- 5. Mark accepted bid as 'accepted' and all other bids for that load as 'rejected'
-- 6. Insert first milestone into order_timelineWhen a driver enters the correct customer OTP and confirms delivery:
-- Logical sequence:
-- 1. Lock orders, trips, and driver_details records
-- 2. Update order status to 'delivered' and trip status to 'completed'
-- 3. Transition order_timeline milestones to 'completed'
-- 4. Credit earnings to driver's balance in driver_details:
-- - Add trip net profit to wallet_confirmed
-- - Deduct from wallet_pending (if previously escrowed)
-- 5. Create a transaction audit log in wallet_historyWhen a driver requests a withdrawal from their in-app wallet to UPI:
-- Logical sequence:
-- 1. SELECT wallet_confirmed FROM driver_details FOR UPDATE
-- 2. Check if balance >= request_amount
-- 3. Deduct request_amount from wallet_confirmed and wallet_total
-- 4. Log transaction in wallet_history with status = 'processing'
-- (n8n or UPI broker handles execution; failures revert the balance)When a customer rates a driver after a trip:
-- Logical sequence:
-- 1. Insert review into ratings table
-- 2. Compute new average rating for user:
-- avg_rating = (SUM(stars) / COUNT(ratings))
-- 3. Update driver_details.rating
-- 4. Trigger on-chain event logger queue