Skip to main content

Overview

The Transport Logistics system uses PostgreSQL (via Supabase) with a relational schema optimized for fleet management, shipment tracking, and user management. All tables implement Row Level Security (RLS) for fine-grained access control.
The database schema is automatically synced to TypeScript types in src/integrations/supabase/types.ts, providing full type safety throughout the application.

Core Tables

vehicles

Stores information about transport vehicles in the fleet.
CREATE TABLE vehicles (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  vehicle_number VARCHAR UNIQUE NOT NULL,
  vehicle_type VARCHAR NOT NULL,
  capacity NUMERIC NOT NULL,
  status VARCHAR DEFAULT 'available',
  active BOOLEAN DEFAULT true,
  last_maintenance TIMESTAMP,
  transporter_id UUID NOT NULL REFERENCES transporters(id),
  created_at TIMESTAMP DEFAULT now(),
  updated_at TIMESTAMP DEFAULT now()
);
Columns:
ColumnTypeDescription
idUUIDPrimary key
vehicle_numberVARCHARUnique vehicle registration number
vehicle_typeVARCHARType of vehicle (truck, trailer, etc.)
capacityNUMERICMaximum load capacity in tons
statusVARCHARCurrent status (available, in-transit, maintenance)
activeBOOLEANWhether the vehicle is active
last_maintenanceTIMESTAMPLast maintenance date
transporter_idUUIDForeign key to transporters table
created_atTIMESTAMPRecord creation timestamp
updated_atTIMESTAMPLast update timestamp
Relationships:
  • transporter_idtransporters.id (many-to-one)
  • Referenced by shipments.vehicle_id
Constraints:
  • vehicles_vehicle_number_unique - Ensures vehicle numbers are unique

shipments

Tracks individual shipment records with route, material, and vehicle information.
CREATE TABLE shipments (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  source VARCHAR NOT NULL,
  destination VARCHAR NOT NULL,
  departure_time TIMESTAMP NOT NULL,
  arrival_time TIMESTAMP,
  quantity_tons NUMERIC NOT NULL,
  gross_weight NUMERIC,
  tare_weight NUMERIC,
  status VARCHAR DEFAULT 'pending',
  active BOOLEAN DEFAULT true,
  remarks TEXT,
  vehicle_id UUID NOT NULL REFERENCES vehicles(id),
  transporter_id UUID NOT NULL REFERENCES transporters(id),
  material_id UUID REFERENCES materials(id),
  route_id UUID REFERENCES routes(id),
  package_id UUID REFERENCES packages(id),
  created_at TIMESTAMP DEFAULT now(),
  updated_at TIMESTAMP DEFAULT now()
);
Columns:
ColumnTypeDescription
idUUIDPrimary key
sourceVARCHAROrigin location
destinationVARCHARDestination location
departure_timeTIMESTAMPScheduled/actual departure time
arrival_timeTIMESTAMPActual arrival time (nullable)
quantity_tonsNUMERICShipment quantity in tons
gross_weightNUMERICTotal weight including vehicle
tare_weightNUMERICEmpty vehicle weight
statusVARCHARShipment status (pending, in-transit, delivered, cancelled)
activeBOOLEANWhether the shipment is active
remarksTEXTAdditional notes
vehicle_idUUIDForeign key to vehicles table
transporter_idUUIDForeign key to transporters table
material_idUUIDForeign key to materials table
route_idUUIDForeign key to routes table
package_idUUIDForeign key to packages table
created_atTIMESTAMPRecord creation timestamp
updated_atTIMESTAMPLast update timestamp
Relationships:
  • vehicle_idvehicles.id (many-to-one)
  • transporter_idtransporters.id (many-to-one)
  • material_idmaterials.id (many-to-one, optional)
  • route_idroutes.id (many-to-one, optional)
  • package_idpackages.id (many-to-one, optional)

packages

Organizes shipments into logical packages for tracking and assignment.
CREATE TABLE packages (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  name VARCHAR NOT NULL,
  status VARCHAR DEFAULT 'active',
  active BOOLEAN DEFAULT true,
  created_by_id UUID NOT NULL,
  shipment_id UUID REFERENCES shipments(id),
  created_at TIMESTAMP DEFAULT now(),
  updated_at TIMESTAMP DEFAULT now()
);
Columns:
ColumnTypeDescription
idUUIDPrimary key
nameVARCHARPackage name/identifier
statusVARCHARPackage status
activeBOOLEANWhether the package is active
created_by_idUUIDUser who created the package
shipment_idUUIDAssociated shipment (optional)
created_atTIMESTAMPRecord creation timestamp
updated_atTIMESTAMPLast update timestamp
Relationships:
  • shipment_idshipments.id (many-to-one, optional)
  • Referenced by routes.assigned_package_id
  • Referenced by shipments.package_id
  • Referenced by profiles.assigned_packages (array)

materials

Defines the types of materials that can be transported.
CREATE TABLE materials (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  name VARCHAR NOT NULL,
  description TEXT,
  unit VARCHAR NOT NULL,
  status VARCHAR DEFAULT 'active',
  created_at TIMESTAMP DEFAULT now(),
  updated_at TIMESTAMP DEFAULT now()
);
Columns:
ColumnTypeDescription
idUUIDPrimary key
nameVARCHARMaterial name
descriptionTEXTMaterial description
unitVARCHARUnit of measurement (tons, kg, etc.)
statusVARCHARMaterial status
created_atTIMESTAMPRecord creation timestamp
updated_atTIMESTAMPLast update timestamp
Relationships:
  • Referenced by shipments.material_id

routes

Defines transportation routes with distance and pricing information.
CREATE TABLE routes (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  source VARCHAR NOT NULL,
  destination VARCHAR NOT NULL,
  distance_km NUMERIC NOT NULL,
  estimated_time NUMERIC DEFAULT 0,
  billing_rate_per_ton NUMERIC NOT NULL,
  vendor_rate_per_ton NUMERIC NOT NULL,
  assigned_package_id UUID REFERENCES packages(id),
  created_at TIMESTAMP DEFAULT now(),
  updated_at TIMESTAMP DEFAULT now()
);
Columns:
ColumnTypeDescription
idUUIDPrimary key
sourceVARCHARRoute origin
destinationVARCHARRoute destination
distance_kmNUMERICDistance in kilometers
estimated_timeNUMERICEstimated transit time in hours
billing_rate_per_tonNUMERICCustomer billing rate per ton
vendor_rate_per_tonNUMERICVendor payment rate per ton
assigned_package_idUUIDAssigned package (optional)
created_atTIMESTAMPRecord creation timestamp
updated_atTIMESTAMPLast update timestamp
Relationships:
  • assigned_package_idpackages.id (many-to-one, optional)
  • Referenced by shipments.route_id

transporters

Stores information about transport companies and vendors.
CREATE TABLE transporters (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  name VARCHAR NOT NULL,
  contact_person VARCHAR NOT NULL,
  contact_number VARCHAR NOT NULL,
  address VARCHAR NOT NULL,
  gstn VARCHAR NOT NULL,
  active BOOLEAN DEFAULT true,
  created_at TIMESTAMP DEFAULT now(),
  updated_at TIMESTAMP DEFAULT now()
);
Columns:
ColumnTypeDescription
idUUIDPrimary key
nameVARCHARTransporter company name
contact_personVARCHARPrimary contact name
contact_numberVARCHARContact phone number
addressVARCHARCompany address
gstnVARCHARGST Number (tax identifier)
activeBOOLEANWhether the transporter is active
created_atTIMESTAMPRecord creation timestamp
updated_atTIMESTAMPLast update timestamp
Relationships:
  • Referenced by vehicles.transporter_id
  • Referenced by shipments.transporter_id

profiles

User profile information linked to Supabase authentication.
CREATE TABLE profiles (
  id UUID PRIMARY KEY REFERENCES auth.users(id),
  username VARCHAR NOT NULL,
  full_name VARCHAR,
  phone_number VARCHAR,
  role VARCHAR DEFAULT 'user',
  active BOOLEAN DEFAULT true,
  assigned_packages UUID[],
  created_at TIMESTAMP DEFAULT now(),
  updated_at TIMESTAMP DEFAULT now()
);
Columns:
ColumnTypeDescription
idUUIDPrimary key, references auth.users
usernameVARCHARUser’s username
full_nameVARCHARUser’s full name
phone_numberVARCHARContact phone number
roleVARCHARUser role (admin, user, manager)
activeBOOLEANWhether the user account is active
assigned_packagesUUID[]Array of assigned package IDs
created_atTIMESTAMPRecord creation timestamp
updated_atTIMESTAMPLast update timestamp
Relationships:
  • idauth.users.id (one-to-one with Supabase Auth)

user_settings

User-specific notification and preference settings.
CREATE TABLE user_settings (
  user_id UUID PRIMARY KEY,
  email_notifications BOOLEAN DEFAULT true,
  sms_notifications BOOLEAN DEFAULT false,
  shipment_updates BOOLEAN DEFAULT true,
  system_announcements BOOLEAN DEFAULT true,
  created_at TIMESTAMP DEFAULT now(),
  updated_at TIMESTAMP DEFAULT now()
);
Columns:
ColumnTypeDescription
user_idUUIDPrimary key, user identifier
email_notificationsBOOLEANEnable email notifications
sms_notificationsBOOLEANEnable SMS notifications
shipment_updatesBOOLEANReceive shipment status updates
system_announcementsBOOLEANReceive system announcements
created_atTIMESTAMPRecord creation timestamp
updated_atTIMESTAMPLast update timestamp

Database Views

user_roles_view

Simplified view for querying user roles.
CREATE VIEW user_roles_view AS
  SELECT id, role FROM profiles;

Database Functions

The schema includes several PostgreSQL functions for common operations:

get_current_user_role()

Returns the role of the currently authenticated user.
CREATE FUNCTION get_current_user_role()
RETURNS TEXT AS $$
  SELECT role FROM public.profiles WHERE id = auth.uid();
$$ LANGUAGE SQL SECURITY DEFINER STABLE;

assign_user_role(user_id, user_role)

Assigns or updates a user’s role.
CREATE FUNCTION assign_user_role(
  user_id UUID,
  user_role TEXT
) RETURNS VOID;

assign_packages_to_user(user_id, package_ids)

Assigns multiple packages to a user.
CREATE FUNCTION assign_packages_to_user(
  user_id UUID,
  package_ids UUID[]
) RETURNS VOID;

toggle_user_access(user_id, is_active)

Activates or deactivates a user account.
CREATE FUNCTION toggle_user_access(
  user_id UUID,
  is_active BOOLEAN
) RETURNS VOID;

delete_user(user_id)

Deletes a user and their associated data.
CREATE FUNCTION delete_user(
  user_id UUID
) RETURNS VOID;

get_user_email(user_id)

Retrieves a user’s email address from the auth schema.
CREATE FUNCTION get_user_email(
  user_id UUID
) RETURNS TABLE(email TEXT);

Row Level Security (RLS)

All tables have Row Level Security enabled to ensure data access is properly controlled based on user roles and ownership.
RLS policies are enforced at the database level, providing security even if the application layer is compromised.

Security Policies

-- All authenticated users can view vehicles
CREATE POLICY "Authenticated users can view vehicles"
  ON vehicles FOR SELECT
  TO authenticated
  USING (true);

-- Only admins can manage vehicles
CREATE POLICY "Admin users can manage vehicles"
  ON vehicles FOR ALL
  TO authenticated
  USING (get_current_user_role() = 'admin')
  WITH CHECK (get_current_user_role() = 'admin');

Entity Relationship Diagram

TypeScript Integration

The database schema is automatically reflected in TypeScript types:
// src/integrations/supabase/types.ts
export type Tables<T extends keyof Database['public']['Tables']> = 
  Database['public']['Tables'][T]['Row'];

// Usage in code
import { Tables } from '@/integrations/supabase/types';

type Vehicle = Tables<'vehicles'>;
type Shipment = Tables<'shipments'>;
type Package = Tables<'packages'>;

Migration Files

Database changes are managed through SQL migration files:
  • 20250626084408-40640dda-5b51-48b2-b2ac-0a64dc5022c0.sql - Initial RLS setup
  • 20250710103823-11aa3e41-d45b-4c07-877d-ef8adc04984c.sql - Vehicle number unique constraint

Best Practices

Data Integrity

  • All tables use UUID primary keys
  • Foreign key constraints ensure referential integrity
  • Unique constraints prevent duplicate data
  • Timestamps track all changes

Security

  • Row Level Security enabled on all tables
  • Role-based access control via RLS policies
  • Security definer functions for privilege escalation
  • Authenticated-only access

Performance

  • Indexed foreign keys for join performance
  • Selective column queries to reduce data transfer
  • Proper use of nullable fields
  • Query optimization with TanStack Query caching

Next Steps

Tech Stack

Learn about the technologies used in the project

Project Structure

Explore how the codebase is organized

Build docs developers (and LLMs) love