mashrur950's picture
Initial commit: FleetMind MCP with GitHub Actions auto-sync
d69447e
raw
history blame
7.48 kB
"""
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();
"""
# Additional schema components can be added here as needed
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
)