⚠️ Run this ONCE in your Supabase project → SQL Editor → New Query. This is required for realtime sync to work.
-- MillPro ERP - Supabase Full Setup SQL (v25)
-- Run this ONCE in: Supabase Dashboard → SQL Editor → New Query → Run
-- Safe to run again at any time - will not delete existing invoice/customer data.
-- ================================================
-- STEP 0: Recreate tables that may have wrong schema (dispatch_requests fix)
-- This drops and recreates ONLY the tables the app uses for dispatch.
-- Your invoices, customers, products, payments are NOT affected.
DROP TABLE IF EXISTS dispatch_requests CASCADE;
DROP TABLE IF EXISTS dispatches CASCADE;
DROP TABLE IF EXISTS arrival_logs CASCADE;
DROP TABLE IF EXISTS reset_logs CASCADE;
DROP TABLE IF EXISTS staff CASCADE;
-- 1. Enable REPLICA IDENTITY FULL (required for UPDATE/DELETE to send full row data)
ALTER TABLE products REPLICA IDENTITY FULL;
ALTER TABLE warehouse_stock REPLICA IDENTITY FULL;
ALTER TABLE customers REPLICA IDENTITY FULL;
ALTER TABLE invoices REPLICA IDENTITY FULL;
ALTER TABLE dispatches REPLICA IDENTITY FULL;
ALTER TABLE dispatch_requests REPLICA IDENTITY FULL;
ALTER TABLE cheques REPLICA IDENTITY FULL;
ALTER TABLE returns REPLICA IDENTITY FULL;
ALTER TABLE payments REPLICA IDENTITY FULL;
ALTER TABLE app_users REPLICA IDENTITY FULL;
ALTER TABLE app_passwords REPLICA IDENTITY FULL;
ALTER TABLE app_settings REPLICA IDENTITY FULL;
-- NEW v14 tables
ALTER TABLE staff REPLICA IDENTITY FULL;
ALTER TABLE reset_logs REPLICA IDENTITY FULL;
-- 2. Add tables to the supabase_realtime publication
ALTER PUBLICATION supabase_realtime ADD TABLE products;
ALTER PUBLICATION supabase_realtime ADD TABLE warehouse_stock;
ALTER PUBLICATION supabase_realtime ADD TABLE customers;
ALTER PUBLICATION supabase_realtime ADD TABLE invoices;
ALTER PUBLICATION supabase_realtime ADD TABLE dispatches;
ALTER PUBLICATION supabase_realtime ADD TABLE dispatch_requests;
ALTER PUBLICATION supabase_realtime ADD TABLE cheques;
ALTER PUBLICATION supabase_realtime ADD TABLE returns;
ALTER PUBLICATION supabase_realtime ADD TABLE payments;
ALTER PUBLICATION supabase_realtime ADD TABLE app_users;
ALTER PUBLICATION supabase_realtime ADD TABLE app_settings;
-- NEW v14 tables
ALTER PUBLICATION supabase_realtime ADD TABLE staff;
ALTER PUBLICATION supabase_realtime ADD TABLE reset_logs;
-- 3. Enable Row Level Security
ALTER TABLE products ENABLE ROW LEVEL SECURITY;
ALTER TABLE warehouse_stock ENABLE ROW LEVEL SECURITY;
ALTER TABLE customers ENABLE ROW LEVEL SECURITY;
ALTER TABLE invoices ENABLE ROW LEVEL SECURITY;
ALTER TABLE dispatches ENABLE ROW LEVEL SECURITY;
ALTER TABLE dispatch_requests ENABLE ROW LEVEL SECURITY;
ALTER TABLE cheques ENABLE ROW LEVEL SECURITY;
ALTER TABLE returns ENABLE ROW LEVEL SECURITY;
ALTER TABLE payments ENABLE ROW LEVEL SECURITY;
ALTER TABLE app_users ENABLE ROW LEVEL SECURITY;
ALTER TABLE app_passwords ENABLE ROW LEVEL SECURITY;
ALTER TABLE app_settings ENABLE ROW LEVEL SECURITY;
-- NEW v14 tables
ALTER TABLE staff ENABLE ROW LEVEL SECURITY;
ALTER TABLE reset_logs ENABLE ROW LEVEL SECURITY;
-- 4. Create permissive policies (anon key can read/write all rows)
-- Products
DROP POLICY IF EXISTS "millpro_products_all" ON products;
CREATE POLICY "millpro_products_all" ON products FOR ALL TO anon USING (true) WITH CHECK (true);
-- Warehouse Stock
DROP POLICY IF EXISTS "millpro_wh_stock_all" ON warehouse_stock;
CREATE POLICY "millpro_wh_stock_all" ON warehouse_stock FOR ALL TO anon USING (true) WITH CHECK (true);
-- Customers
DROP POLICY IF EXISTS "millpro_customers_all" ON customers;
CREATE POLICY "millpro_customers_all" ON customers FOR ALL TO anon USING (true) WITH CHECK (true);
-- Invoices
DROP POLICY IF EXISTS "millpro_invoices_all" ON invoices;
CREATE POLICY "millpro_invoices_all" ON invoices FOR ALL TO anon USING (true) WITH CHECK (true);
-- Dispatches
DROP POLICY IF EXISTS "millpro_dispatches_all" ON dispatches;
CREATE POLICY "millpro_dispatches_all" ON dispatches FOR ALL TO anon USING (true) WITH CHECK (true);
-- STEP 1: Create ALL tables with correct schema
-- (tables dropped in step 0 are recreated; others use IF NOT EXISTS)
CREATE TABLE IF NOT EXISTS products (id TEXT PRIMARY KEY, data JSONB NOT NULL DEFAULT '{}');
CREATE TABLE IF NOT EXISTS warehouse_stock (id TEXT PRIMARY KEY, data JSONB NOT NULL DEFAULT '{}');
CREATE TABLE IF NOT EXISTS customers (id TEXT PRIMARY KEY, data JSONB NOT NULL DEFAULT '{}');
CREATE TABLE IF NOT EXISTS invoices (id TEXT PRIMARY KEY, data JSONB NOT NULL DEFAULT '{}');
CREATE TABLE IF NOT EXISTS cheques (id TEXT PRIMARY KEY, data JSONB NOT NULL DEFAULT '{}');
CREATE TABLE IF NOT EXISTS returns (id TEXT PRIMARY KEY, data JSONB NOT NULL DEFAULT '{}');
CREATE TABLE IF NOT EXISTS payments (id TEXT PRIMARY KEY, data JSONB NOT NULL DEFAULT '{}');
CREATE TABLE IF NOT EXISTS app_users (id TEXT PRIMARY KEY, data JSONB NOT NULL DEFAULT '{}');
CREATE TABLE IF NOT EXISTS app_passwords (email TEXT PRIMARY KEY, password TEXT NOT NULL DEFAULT '1234');
CREATE TABLE IF NOT EXISTS app_settings (key TEXT PRIMARY KEY, value TEXT);
-- These were dropped above and are now recreated fresh with correct schema:
CREATE TABLE dispatches (id TEXT PRIMARY KEY, data JSONB NOT NULL DEFAULT '{}');
CREATE TABLE dispatch_requests (id TEXT PRIMARY KEY, data JSONB NOT NULL DEFAULT '{}');
CREATE TABLE arrival_logs (id TEXT PRIMARY KEY, data JSONB NOT NULL DEFAULT '{}');
CREATE TABLE reset_logs (id TEXT PRIMARY KEY, data JSONB NOT NULL DEFAULT '{}');
CREATE TABLE staff (id TEXT PRIMARY KEY, data JSONB NOT NULL DEFAULT '{}');
DROP POLICY IF EXISTS "millpro_dispatch_requests_all" ON dispatch_requests;
CREATE POLICY "millpro_dispatch_requests_all" ON dispatch_requests FOR ALL TO anon USING (true) WITH CHECK (true);
-- Cheques
DROP POLICY IF EXISTS "millpro_cheques_all" ON cheques;
CREATE POLICY "millpro_cheques_all" ON cheques FOR ALL TO anon USING (true) WITH CHECK (true);
-- Returns
DROP POLICY IF EXISTS "millpro_returns_all" ON returns;
CREATE POLICY "millpro_returns_all" ON returns FOR ALL TO anon USING (true) WITH CHECK (true);
-- Payments
DROP POLICY IF EXISTS "millpro_payments_all" ON payments;
CREATE POLICY "millpro_payments_all" ON payments FOR ALL TO anon USING (true) WITH CHECK (true);
-- App Users
DROP POLICY IF EXISTS "millpro_app_users_all" ON app_users;
CREATE POLICY "millpro_app_users_all" ON app_users FOR ALL TO anon USING (true) WITH CHECK (true);
-- App Passwords
DROP POLICY IF EXISTS "millpro_app_passwords_all" ON app_passwords;
CREATE POLICY "millpro_app_passwords_all" ON app_passwords FOR ALL TO anon USING (true) WITH CHECK (true);
-- App Settings
DROP POLICY IF EXISTS "millpro_app_settings_all" ON app_settings;
CREATE POLICY "millpro_app_settings_all" ON app_settings FOR ALL TO anon USING (true) WITH CHECK (true);
-- Arrival Logs (NEW v17)
CREATE TABLE IF NOT EXISTS arrival_logs (id TEXT PRIMARY KEY, data JSONB NOT NULL DEFAULT '{}');
DROP POLICY IF EXISTS "millpro_arrival_logs_all" ON arrival_logs;
CREATE POLICY "millpro_arrival_logs_all" ON arrival_logs FOR ALL TO anon USING (true) WITH CHECK (true);
-- Staff (NEW v14)
CREATE TABLE IF NOT EXISTS staff (id TEXT PRIMARY KEY, data JSONB NOT NULL DEFAULT '{}');
DROP POLICY IF EXISTS "millpro_staff_all" ON staff;
CREATE POLICY "millpro_staff_all" ON staff FOR ALL TO anon USING (true) WITH CHECK (true);
-- Reset Logs (NEW v14)
CREATE TABLE IF NOT EXISTS reset_logs (id TEXT PRIMARY KEY, data JSONB NOT NULL DEFAULT '{}');
DROP POLICY IF EXISTS "millpro_reset_logs_all" ON reset_logs;
CREATE POLICY "millpro_reset_logs_all" ON reset_logs FOR ALL TO anon USING (true) WITH CHECK (true);
-- 5. Grant realtime access to anon role
GRANT SELECT ON ALL TABLES IN SCHEMA public TO anon;
GRANT INSERT, UPDATE, DELETE ON products, warehouse_stock, customers, invoices,
dispatches, dispatch_requests, cheques, returns, payments,
app_users, app_passwords, app_settings, staff, reset_logs TO anon;
-- 6. Verify the publication includes all tables
SELECT tablename FROM pg_publication_tables WHERE pubname='supabase_realtime';
-- You should see all 10+ tables listed above in the result.
After running: reload the app. Realtime events will fire across all accounts instantly.