# Let's create an integrated, complete RBAC (Role-Based Access Control) authentication system
# Roles to implement:
# 1. Platform Super Admin (Master analytics, Store approvals, Global commission config, Central Escrow)
# 2. Merchant / Supermarket Owner (Store ERP, Local Staff, Purchase/GRN, Local POS Counter, Stock Sync)
# 3. Vendor / Supplier (Wholesale Catalog, Bulk Supply POs, Delivery Invoices, Receivable Ledgers)
# 4. End Customer (Hyperlocal Multi-store Ordering, Live GPS Track, Cart, Order History)
#
# The file will manage session-based authentication, user registration, role isolation, and dedicated switchable dashboards.
auth_erp_code = """setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
} catch (Exception $e) {
die("DB Init Error: " . $e->getMessage());
}
if ($isFirstRun) {
// 1. Users Table with Role-Based Separation
$pdo->exec("
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL,
phone TEXT UNIQUE NOT NULL,
password TEXT NOT NULL,
role TEXT NOT NULL, -- SUPER_ADMIN, MERCHANT_OWNER, VENDOR_SUPPLIER, CUSTOMER
entity_id INTEGER DEFAULT 0, -- Maps to store_id or supplier_id
status TEXT DEFAULT 'ACTIVE',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- 2. Stores Table
CREATE TABLE IF NOT EXISTS stores (
id INTEGER PRIMARY KEY AUTOINCREMENT,
owner_id INTEGER NOT NULL,
store_name TEXT NOT NULL,
gstin TEXT NOT NULL,
pincode TEXT NOT NULL,
address TEXT NOT NULL,
commission_rate REAL DEFAULT 3.50,
status TEXT DEFAULT 'APPROVED',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- 3. Vendors / Suppliers Table
CREATE TABLE IF NOT EXISTS suppliers (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
company_name TEXT NOT NULL,
contact_person TEXT NOT NULL,
phone TEXT NOT NULL,
gstin TEXT NOT NULL,
address TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- 4. Products Master
CREATE TABLE IF NOT EXISTS products (
id INTEGER PRIMARY KEY AUTOINCREMENT,
store_id INTEGER NOT NULL,
barcode TEXT NOT NULL,
product_name TEXT NOT NULL,
category TEXT NOT NULL,
purchase_cost REAL NOT NULL,
pos_mrp REAL NOT NULL,
online_price REAL NOT NULL,
stock_qty INTEGER NOT NULL DEFAULT 0,
image_url TEXT DEFAULT '',
is_published_online INTEGER DEFAULT 1,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- 5. Orders Master
CREATE TABLE IF NOT EXISTS orders (
id INTEGER PRIMARY KEY AUTOINCREMENT,
order_number TEXT UNIQUE NOT NULL,
store_id INTEGER NOT NULL,
customer_id INTEGER NOT NULL,
channel TEXT NOT NULL, -- POS, ECOM
total_amount REAL NOT NULL,
platform_commission REAL NOT NULL,
vendor_net_amount REAL NOT NULL,
order_status TEXT NOT NULL,
delivery_otp TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- 6. Settlement & Payout Ledger
CREATE TABLE IF NOT EXISTS settlement_ledger (
id INTEGER PRIMARY KEY AUTOINCREMENT,
transaction_ref TEXT UNIQUE NOT NULL,
order_id INTEGER NOT NULL,
store_id INTEGER NOT NULL,
gross_amount REAL NOT NULL,
platform_fee REAL NOT NULL,
net_vendor_payout REAL NOT NULL,
settlement_status TEXT DEFAULT 'ESCROW_HELD',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
");
// Seed Initial Role Accounts (Default Pass: admin123 / owner123 / vendor123 / user123)
$stmtUser = $pdo->prepare("INSERT INTO users (name, email, phone, password, role, entity_id) VALUES (?, ?, ?, ?, ?, ?)");
// 1. Super Admin
$stmtUser->execute(['Platform Super Admin', 'admin@nizon.com', '9999900000', password_hash('admin123', PASSWORD_DEFAULT), 'SUPER_ADMIN', 0]);
// 2. Merchant Owner (Store #1)
$stmtUser->execute(['Karthik Raja (Amman Store)', 'merchant@amman.com', '9842100001', password_hash('owner123', PASSWORD_DEFAULT), 'MERCHANT_OWNER', 1]);
$pdo->exec("INSERT INTO stores (owner_id, store_name, gstin, pincode, address) VALUES (2, 'Sri Amman Supermarket', '33AAAAA0000A1Z5', '622001', 'Main Bazaar, Pudukkottai')");
// 3. Vendor / Wholesale Supplier
$stmtUser->execute(['Ramesh (HUL Wholesale)', 'vendor@hulsupply.com', '9842111111', password_hash('vendor123', PASSWORD_DEFAULT), 'VENDOR_SUPPLIER', 1]);
$pdo->exec("INSERT INTO suppliers (user_id, company_name, contact_person, phone, gstin, address) VALUES (3, 'Hindustan Unilever Distributor Agency', 'Ramesh Sundaram', '9842111111', '33HULAA1234F1Z1', 'Trichy Road, Pudukkottai')");
// 4. End Customer
$stmtUser->execute(['Anbarasan S', 'customer@gmail.com', '9442019876', password_hash('user123', PASSWORD_DEFAULT), 'CUSTOMER', 0]);
// Seed Sample Products
$pdo->exec("
INSERT INTO products (store_id, barcode, product_name, category, purchase_cost, pos_mrp, online_price, stock_qty, is_published_online) VALUES
(1, '8901030383848', 'Fortune Sunlite Refined Sunflower Oil 1L', 'Groceries', 110.00, 135.00, 135.00, 30, 1),
(1, '8901491101832', 'Aashirvaad Superior MP Atta 5kg', 'Groceries', 230.00, 275.00, 275.00, 20, 1),
(1, '8901725181222', 'Amul Pasteurised Butter 500g', 'Dairy & Fresh', 240.00, 275.00, 275.00, 15, 1),
(1, '8901058852331', 'Tata Tea Gold Premium 500g', 'Beverages', 260.00, 310.00, 310.00, 18, 1);
");
}
// ==========================================
// 2. AUTHENTICATION & REST API CONTROLLERS
// ==========================================
if (isset($_GET['action'])) {
header('Content-Type: application/json');
$action = $_GET['action'];
// API: Authenticate / Login
if ($action === 'login' && $_SERVER['REQUEST_METHOD'] === 'POST') {
$data = json_decode(file_get_contents('php://input'), true);
$email = trim($data['email']);
$password = trim($data['password']);
$selectedRole = $data['role'] ?? '';
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?");
$stmt->execute([$email]);
$user = $stmt->fetch();
if ($user && password_verify($password, $user['password'])) {
if ($selectedRole && $user['role'] !== $selectedRole) {
echo json_encode(['status' => 'error', 'message' => "Unauthorized for this portal. You are registered as {$user['role']}."]);
exit;
}
$_SESSION['user'] = $user;
echo json_encode(['status' => 'success', 'user' => $user]);
} else {
echo json_encode(['status' => 'error', 'message' => 'Invalid email or password.']);
}
exit;
}
// API: Register User
if ($action === 'register' && $_SERVER['REQUEST_METHOD'] === 'POST') {
$data = json_decode(file_get_contents('php://input'), true);
$name = trim($data['name']);
$email = trim($data['email']);
$phone = trim($data['phone']);
$password = password_hash($data['password'], PASSWORD_DEFAULT);
$role = $data['role']; // MERCHANT_OWNER, VENDOR_SUPPLIER, CUSTOMER
try {
$stmt = $pdo->prepare("INSERT INTO users (name, email, phone, password, role) VALUES (?, ?, ?, ?, ?)");
$stmt->execute([$name, $email, $phone, $password, $role]);
$userId = $pdo->lastInsertId();
if ($role === 'MERCHANT_OWNER') {
$storeName = $data['store_name'] ?? ($name . ' Store');
$gstin = $data['gstin'] ?? 'TEMP33GST';
$pincode = $data['pincode'] ?? '622001';
$address = $data['address'] ?? 'Tamil Nadu';
$pdo->prepare("INSERT INTO stores (owner_id, store_name, gstin, pincode, address) VALUES (?, ?, ?, ?, ?)")->execute([$userId, $storeName, $gstin, $pincode, $address]);
$storeId = $pdo->lastInsertId();
$pdo->prepare("UPDATE users SET entity_id = ? WHERE id = ?")->execute([$storeId, $userId]);
} elseif ($role === 'VENDOR_SUPPLIER') {
$company = $data['company_name'] ?? ($name . ' Wholesale');
$gstin = $data['gstin'] ?? 'TEMP33SUPP';
$pdo->prepare("INSERT INTO suppliers (user_id, company_name, contact_person, phone, gstin, address) VALUES (?, ?, ?, ?, ?, ?)")->execute([$userId, $company, $name, $phone, $gstin, 'Distributor Hub']);
$suppId = $pdo->lastInsertId();
$pdo->prepare("UPDATE users SET entity_id = ? WHERE id = ?")->execute([$suppId, $userId]);
}
echo json_encode(['status' => 'success', 'message' => 'Registration successful! You can now log in.']);
} catch (Exception $e) {
echo json_encode(['status' => 'error', 'message' => 'Registration failed: Email or Phone already exists.']);
}
exit;
}
// API: Logout
if ($action === 'logout') {
session_destroy();
echo json_encode(['status' => 'success']);
exit;
}
// API: Current Session Info
if ($action === 'get_current_user') {
echo json_encode(['status' => 'success', 'user' => $_SESSION['user'] ?? null]);
exit;
}
// API: Super Admin Platform Master Data
if ($action === 'get_admin_data') {
$stores = $pdo->query("SELECT s.*, u.name as owner_name, u.phone as owner_phone FROM stores s JOIN users u ON s.owner_id = u.id")->fetchAll();
$vendors = $pdo->query("SELECT * FROM suppliers")->fetchAll();
$orders = $pdo->query("SELECT o.*, s.store_name, u.name as customer_name FROM orders o JOIN stores s ON o.store_id = s.id JOIN users u ON o.customer_id = u.id ORDER BY o.id DESC LIMIT 20")->fetchAll();
$stats = $pdo->query("SELECT COUNT(DISTINCT id) as total_orders, COALESCE(SUM(total_amount),0) as gmv, COALESCE(SUM(platform_commission),0) as platform_revenue FROM orders")->fetch();
echo json_encode(['status' => 'success', 'stores' => $stores, 'vendors' => $vendors, 'orders' => $orders, 'stats' => $stats]);
exit;
}
// API: Merchant Store ERP Master Data
if ($action === 'get_merchant_data') {
$storeId = (int)($_GET['store_id'] ?? 1);
$products = $pdo->prepare("SELECT * FROM products WHERE store_id = ? ORDER BY id DESC");
$products->execute([$storeId]);
$orders = $pdo->prepare("SELECT * FROM orders WHERE store_id = ? ORDER BY id DESC LIMIT 15");
$orders->execute([$storeId]);
$store = $pdo->prepare("SELECT * FROM stores WHERE id = ?");
$store->execute([$storeId]);
echo json_encode(['status' => 'success', 'store' => $store->fetch(), 'products' => $products->fetchAll(), 'orders' => $orders->fetchAll()]);
exit;
}
// API: Vendor Wholesale Master Data
if ($action === 'get_vendor_data') {
$stores = $pdo->query("SELECT id, store_name, pincode, phone FROM stores")->fetchAll();
echo json_encode(['status' => 'success', 'retail_stores' => $stores]);
exit;
}
// API: Customer E-Com Catalog
if ($action === 'get_customer_catalog') {
$products = $pdo->query("SELECT p.*, s.store_name, s.pincode as store_pin FROM products p JOIN stores s ON p.store_id = s.id WHERE p.is_published_online = 1 AND p.stock_qty > 0")->fetchAll();
echo json_encode(['status' => 'success', 'catalog' => $products]);
exit;
}
}
?>
OmniRetail OS | Multi-Role Authentication & Access Portals
4-Tier Decoupled RBAC Architecture
Platform Super Administration
Central Platform Oversight & Escrow Clearing
Default Demo Credentials: admin@nizon.com / admin123
Platform Executive Overview
NIZON Multi-Vendor Network Control Center
Total Outlets Onboarded
0 Outlets
Gross Merchandise Value (GMV)
₹ 0.00
Net Platform Commission (3.5%)
₹ 0.00
Approved Supermarket & Merchant Outlets
| Store Name |
Owner Name |
Phone |
Pincode |
Commission % |
Status |
Merchant Retail ERP Portal
Supermarket Owners, POS Billing & Procurement
Demo: merchant@amman.com / owner123
Independent Store ERP Console
Sri Amman Supermarket
Live POS Connected
Store Shelf Inventory (Barcode Catalog)
| Barcode |
Product Name |
Cost Price |
POS MRP |
Online Price |
Shelf Stock |
E-Com Sync |
Vendor & Wholesale Supplier Portal
Distributors, Bulk Supply Inwarding & Receivables
Demo: vendor@hulsupply.com / vendor123
Wholesale Distributor Network
Connected Supermarkets & Purchase Demand
Customer Instant Shopping
Order from Neighborhood Supermarkets
Demo: customer@gmail.com / user123
⚡ 30-Minute Guaranteed Hyperlocal
Neighborhood Live Supermarket Catalog
Delivery Location
Pudukkottai (622001)
"""
with open("index.php", "w", encoding="utf-8") as f:
f.write(auth_erp_code)
print("OmniRetail OS v5.0 RBAC Package (index.php) generated successfully!")