| """ |
| Database schema definitions for FleetMind |
| Contains PostgreSQL schema for all database tables |
| """ |
|
|
| SCHEMA_SQL = """ |
| -- ============================================ |
| -- ORDERS TABLE |
| -- ============================================ |
| |
| CREATE TABLE IF NOT EXISTS orders ( |
| order_id VARCHAR(50) PRIMARY KEY, |
| customer_name VARCHAR(255) NOT NULL, |
| customer_phone VARCHAR(20), |
| customer_email VARCHAR(255), |
| pickup_address TEXT, |
| pickup_lat DECIMAL(10, 8), |
| pickup_lng DECIMAL(11, 8), |
| delivery_address TEXT NOT NULL, |
| delivery_lat DECIMAL(10, 8), |
| delivery_lng DECIMAL(11, 8), |
| time_window_start TIMESTAMP, |
| time_window_end TIMESTAMP, |
| priority VARCHAR(20) CHECK(priority IN ('standard', 'express', 'urgent')) DEFAULT 'standard', |
| weight_kg DECIMAL(10, 2), |
| volume_m3 DECIMAL(10, 3), |
| special_instructions TEXT, |
| status VARCHAR(20) CHECK(status IN ('pending', 'assigned', 'in_transit', 'delivered', 'failed', 'cancelled')) DEFAULT 'pending', |
| assigned_driver_id VARCHAR(50), |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
| updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
| delivered_at TIMESTAMP, |
| |
| -- Additional fields for order management |
| order_value DECIMAL(10, 2), |
| payment_status VARCHAR(20) CHECK(payment_status IN ('pending', 'paid', 'cod')) DEFAULT 'pending', |
| requires_signature BOOLEAN DEFAULT FALSE, |
| is_fragile BOOLEAN DEFAULT FALSE, |
| requires_cold_storage BOOLEAN DEFAULT FALSE |
| ); |
| |
| -- ============================================ |
| -- INDEXES FOR ORDERS TABLE |
| -- ============================================ |
| |
| CREATE INDEX IF NOT EXISTS idx_orders_status ON orders(status); |
| CREATE INDEX IF NOT EXISTS idx_orders_priority ON orders(priority); |
| CREATE INDEX IF NOT EXISTS idx_orders_assigned_driver ON orders(assigned_driver_id); |
| CREATE INDEX IF NOT EXISTS idx_orders_created_at ON orders(created_at); |
| CREATE INDEX IF NOT EXISTS idx_orders_time_window ON orders(time_window_start, time_window_end); |
| |
| -- ============================================ |
| -- TRIGGER TO UPDATE updated_at TIMESTAMP |
| -- ============================================ |
| |
| CREATE OR REPLACE FUNCTION update_updated_at_column() |
| RETURNS TRIGGER AS $$ |
| BEGIN |
| NEW.updated_at = CURRENT_TIMESTAMP; |
| RETURN NEW; |
| END; |
| $$ language 'plpgsql'; |
| |
| DROP TRIGGER IF EXISTS update_orders_timestamp ON orders; |
| CREATE TRIGGER update_orders_timestamp |
| BEFORE UPDATE ON orders |
| FOR EACH ROW |
| EXECUTE FUNCTION update_updated_at_column(); |
| """ |
|
|
| |
| DRIVERS_SCHEMA = """ |
| -- ============================================ |
| -- DRIVERS TABLE |
| -- ============================================ |
| |
| CREATE TABLE IF NOT EXISTS drivers ( |
| driver_id VARCHAR(50) PRIMARY KEY, |
| name VARCHAR(255) NOT NULL, |
| phone VARCHAR(20), |
| email VARCHAR(255), |
| current_lat DECIMAL(10, 8), |
| current_lng DECIMAL(11, 8), |
| last_location_update TIMESTAMP, |
| status VARCHAR(20) CHECK(status IN ('active', 'busy', 'offline', 'unavailable')) DEFAULT 'active', |
| vehicle_type VARCHAR(50), |
| vehicle_plate VARCHAR(20), |
| capacity_kg DECIMAL(10, 2), |
| capacity_m3 DECIMAL(10, 3), |
| skills JSONB, -- JSON array: ["medical_certified", "refrigerated"] |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
| updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
| ); |
| |
| CREATE INDEX IF NOT EXISTS idx_drivers_status ON drivers(status); |
| |
| DROP TRIGGER IF EXISTS update_drivers_timestamp ON drivers; |
| CREATE TRIGGER update_drivers_timestamp |
| BEFORE UPDATE ON drivers |
| FOR EACH ROW |
| EXECUTE FUNCTION update_updated_at_column(); |
| """ |
|
|
| ASSIGNMENTS_SCHEMA = """ |
| -- ============================================ |
| -- ASSIGNMENTS TABLE |
| -- ============================================ |
| |
| CREATE TABLE IF NOT EXISTS assignments ( |
| assignment_id VARCHAR(50) PRIMARY KEY, |
| order_id VARCHAR(50) NOT NULL, |
| driver_id VARCHAR(50) NOT NULL, |
| assigned_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
| sequence_number INTEGER, -- Order in driver's route |
| estimated_arrival TIMESTAMP, |
| actual_arrival TIMESTAMP, |
| estimated_distance_km DECIMAL(10, 2), |
| actual_distance_km DECIMAL(10, 2), |
| status VARCHAR(20) CHECK(status IN ('assigned', 'in_progress', 'completed', 'failed')) DEFAULT 'assigned', |
| notes TEXT, |
| FOREIGN KEY (order_id) REFERENCES orders(order_id) ON DELETE CASCADE, |
| FOREIGN KEY (driver_id) REFERENCES drivers(driver_id) ON DELETE CASCADE |
| ); |
| |
| CREATE INDEX IF NOT EXISTS idx_assignments_driver ON assignments(driver_id); |
| CREATE INDEX IF NOT EXISTS idx_assignments_order ON assignments(order_id); |
| CREATE INDEX IF NOT EXISTS idx_assignments_status ON assignments(status); |
| """ |
|
|
| EXCEPTIONS_SCHEMA = """ |
| -- ============================================ |
| -- EXCEPTIONS TABLE |
| -- ============================================ |
| |
| CREATE TABLE IF NOT EXISTS exceptions ( |
| exception_id VARCHAR(50) PRIMARY KEY, |
| exception_type VARCHAR(50) CHECK(exception_type IN ('driver_breakdown', 'traffic_delay', 'weather', 'customer_unavailable', 'other')), |
| severity VARCHAR(20) CHECK(severity IN ('low', 'medium', 'high', 'critical')), |
| description TEXT, |
| affected_orders JSONB, -- JSON array of order IDs |
| affected_drivers JSONB, -- JSON array of driver IDs |
| detected_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
| resolved_at TIMESTAMP, |
| resolution_method JSONB, -- JSON: {agent: "...", actions: [...]} |
| coordinator_override BOOLEAN DEFAULT FALSE, |
| resolution_time_seconds INTEGER |
| ); |
| |
| CREATE INDEX IF NOT EXISTS idx_exceptions_type ON exceptions(exception_type); |
| CREATE INDEX IF NOT EXISTS idx_exceptions_severity ON exceptions(severity); |
| CREATE INDEX IF NOT EXISTS idx_exceptions_detected_at ON exceptions(detected_at); |
| """ |
|
|
| AGENT_DECISIONS_SCHEMA = """ |
| -- ============================================ |
| -- AGENT DECISIONS TABLE (For Agent Learning) |
| -- ============================================ |
| |
| CREATE TABLE IF NOT EXISTS agent_decisions ( |
| decision_id VARCHAR(50) PRIMARY KEY, |
| session_id VARCHAR(50), |
| task_type VARCHAR(50), |
| situation_context JSONB, -- JSON |
| options_generated JSONB, -- JSON array |
| selected_option JSONB, -- JSON |
| reasoning TEXT, |
| approval_status VARCHAR(20) CHECK(approval_status IN ('approved', 'rejected', 'modified')), |
| coordinator_feedback TEXT, |
| outcome_success BOOLEAN, |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
| ); |
| |
| CREATE INDEX IF NOT EXISTS idx_decisions_session ON agent_decisions(session_id); |
| CREATE INDEX IF NOT EXISTS idx_decisions_task_type ON agent_decisions(task_type); |
| """ |
|
|
| METRICS_SCHEMA = """ |
| -- ============================================ |
| -- PERFORMANCE METRICS TABLE |
| -- ============================================ |
| |
| CREATE TABLE IF NOT EXISTS metrics ( |
| metric_id VARCHAR(50) PRIMARY KEY, |
| date DATE, |
| total_orders INTEGER, |
| on_time_deliveries INTEGER, |
| failed_deliveries INTEGER, |
| exceptions_count INTEGER, |
| avg_resolution_time_seconds DECIMAL(10, 2), |
| coordinator_time_saved_minutes INTEGER, |
| fuel_cost_savings DECIMAL(10, 2) |
| ); |
| |
| CREATE INDEX IF NOT EXISTS idx_metrics_date ON metrics(date); |
| """ |
|
|
|
|
| def get_full_schema() -> str: |
| """ |
| Get the complete database schema including all tables. |
| |
| Returns: |
| str: Complete SQL schema |
| """ |
| return ( |
| SCHEMA_SQL + "\n" + |
| DRIVERS_SCHEMA + "\n" + |
| ASSIGNMENTS_SCHEMA + "\n" + |
| EXCEPTIONS_SCHEMA + "\n" + |
| AGENT_DECISIONS_SCHEMA + "\n" + |
| METRICS_SCHEMA |
| ) |
|
|