commit 8e84f1b11ac3875b1103acca4336a367ab638207 Author: MWorld Deployer Date: Mon Sep 28 22:18:32 2026 +0530 chore: initial database schema diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5de5f73 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +node_modules +dist +.wrangler +.env +.next diff --git a/database/01_init.sql b/database/01_init.sql new file mode 100644 index 0000000..7031ecc --- /dev/null +++ b/database/01_init.sql @@ -0,0 +1,115 @@ +CREATE TABLE IF NOT EXISTS users ( + email TEXT PRIMARY KEY, + username TEXT UNIQUE, + full_name TEXT NOT NULL, + phone TEXT, + citizen_id TEXT, + mauth_token TEXT, + role TEXT DEFAULT 'visitor' CHECK(role IN ('customer', 'restaurant', 'delivery_agent', 'visitor')), + is_banned INTEGER DEFAULT 0, + created_at TEXT DEFAULT CURRENT_TIMESTAMP, + updated_at TEXT DEFAULT CURRENT_TIMESTAMP +); +CREATE TABLE IF NOT EXISTS restaurants ( + id TEXT PRIMARY KEY, + owner_email TEXT NOT NULL, + name TEXT NOT NULL, + description TEXT, + address TEXT NOT NULL, + latitude REAL NOT NULL, + longitude REAL NOT NULL, + image_url TEXT, + status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('active', 'closed')), + created_at TEXT DEFAULT CURRENT_TIMESTAMP, + updated_at TEXT DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (owner_email) REFERENCES users(email) ON DELETE CASCADE +); +CREATE TABLE IF NOT EXISTS delivery_agents ( + user_email TEXT PRIMARY KEY, + vehicle_type TEXT, + is_available INTEGER NOT NULL DEFAULT 1, + current_latitude REAL, + current_longitude REAL, + updated_at TEXT DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (user_email) REFERENCES users(email) ON DELETE CASCADE +); +CREATE TABLE IF NOT EXISTS menu_items ( + id TEXT PRIMARY KEY, + restaurant_id TEXT NOT NULL, + name TEXT NOT NULL, + description TEXT, + category TEXT, + ingredients TEXT, + recipe TEXT, + price REAL NOT NULL, + image_url TEXT, + is_available INTEGER NOT NULL DEFAULT 1, + created_at TEXT DEFAULT CURRENT_TIMESTAMP, + updated_at TEXT DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (restaurant_id) REFERENCES restaurants(id) ON DELETE CASCADE +); +CREATE TABLE IF NOT EXISTS orders ( + id TEXT PRIMARY KEY, + customer_email TEXT NOT NULL, + restaurant_id TEXT NOT NULL, + delivery_agent_email TEXT, + delivery_address TEXT NOT NULL, + delivery_latitude REAL NOT NULL, + delivery_longitude REAL NOT NULL, + subtotal REAL NOT NULL, + delivery_fee REAL NOT NULL, + total_amount REAL NOT NULL, + status TEXT NOT NULL DEFAULT 'placed' CHECK(status IN ('placed', 'accepted', 'preparing', 'ready_for_pickup', 'assigned', 'picked_up', 'delivered', 'cancelled')), + created_at TEXT DEFAULT CURRENT_TIMESTAMP, + updated_at TEXT DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (customer_email) REFERENCES users(email), + FOREIGN KEY (restaurant_id) REFERENCES restaurants(id), + FOREIGN KEY (delivery_agent_email) REFERENCES users(email) +); +CREATE TABLE IF NOT EXISTS order_items ( + id TEXT PRIMARY KEY, + order_id TEXT NOT NULL, + menu_item_id TEXT NOT NULL, + item_name TEXT NOT NULL, + quantity INTEGER NOT NULL, + unit_price REAL NOT NULL, + special_instructions TEXT, + FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE, + FOREIGN KEY (menu_item_id) REFERENCES menu_items(id) +); +CREATE TABLE IF NOT EXISTS ratings ( + id TEXT PRIMARY KEY, + order_id TEXT NOT NULL, + customer_email TEXT NOT NULL, + restaurant_rating INTEGER NOT NULL CHECK(restaurant_rating BETWEEN 1 AND 5), + driver_rating INTEGER CHECK(driver_rating BETWEEN 1 AND 5), + comment TEXT, + created_at TEXT DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (order_id) REFERENCES orders(id), + FOREIGN KEY (customer_email) REFERENCES users(email) +); +CREATE TABLE IF NOT EXISTS notifications ( + id TEXT PRIMARY KEY, + recipient_email TEXT NOT NULL, + type TEXT NOT NULL DEFAULT 'info' CHECK(type IN ('info', 'success', 'warning', 'mention', 'system')), + title TEXT NOT NULL, + body TEXT, + link TEXT, + actor_email TEXT, + is_read INTEGER NOT NULL DEFAULT 0, + created_at TEXT DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (recipient_email) REFERENCES users(email) ON DELETE CASCADE, + FOREIGN KEY (actor_email) REFERENCES users(email) +); +CREATE INDEX IF NOT EXISTS idx_users_username ON users(username); +CREATE INDEX IF NOT EXISTS idx_restaurants_owner ON restaurants(owner_email); +CREATE INDEX IF NOT EXISTS idx_menu_items_restaurant ON menu_items(restaurant_id); +CREATE INDEX IF NOT EXISTS idx_orders_customer ON orders(customer_email); +CREATE INDEX IF NOT EXISTS idx_orders_restaurant ON orders(restaurant_id); +CREATE INDEX IF NOT EXISTS idx_orders_delivery_agent ON orders(delivery_agent_email); +CREATE INDEX IF NOT EXISTS idx_order_items_order ON order_items(order_id); +CREATE INDEX IF NOT EXISTS idx_order_items_menu_item ON order_items(menu_item_id); +CREATE INDEX IF NOT EXISTS idx_ratings_order ON ratings(order_id); +CREATE INDEX IF NOT EXISTS idx_ratings_customer ON ratings(customer_email); +CREATE INDEX IF NOT EXISTS idx_notifications_recipient ON notifications(recipient_email, is_read, created_at); +CREATE UNIQUE INDEX IF NOT EXISTS idx_users_email ON users(email);