RLS Policies
All tables have Row-Level Security enabled. Policies enforce access based on the authenticated user's role (customer, seller, admin).
Policy Pattern
-- Enable RLS
ALTER TABLE table_name ENABLE ROW LEVEL SECURITY;
-- Admin: full access
CREATE POLICY "Admin full access" ON table_name
FOR ALL USING (
auth.uid() IN (SELECT id FROM profiles WHERE role = 'admin')
);
-- Owner: own data only
CREATE POLICY "Owner access" ON table_name
FOR ALL USING (
auth.uid() = user_id -- or owner_id column
);
-- Public: read only
CREATE POLICY "Public read" ON table_name
FOR SELECT USING (true);
Profiles
| Policy |
Operation |
Scope |
| Admin full access |
ALL |
role = 'admin' |
| Owner read |
SELECT |
auth.uid() = id |
| Owner update |
UPDATE |
auth.uid() = id |
| Insert (trigger) |
INSERT |
From auth signup hook |
Sellers
| Policy |
Operation |
Scope |
| Admin full access |
ALL |
role = 'admin' |
| Owner read |
SELECT |
auth.uid() = user_id |
| Owner update |
UPDATE |
auth.uid() = user_id |
| Public read approved |
SELECT |
approval_status = 'approved' |
Products
| Policy |
Operation |
Scope |
| Admin full access |
ALL |
role = 'admin' |
| Seller write |
INSERT/UPDATE/DELETE |
auth.uid() owns the seller record |
| Public read published |
SELECT |
is_published = true AND approval_status = 'approved' |
Orders
| Policy |
Operation |
Scope |
| Admin full access |
ALL |
role = 'admin' |
| Customer own |
ALL |
auth.uid() = user_id |
| Seller involved |
SELECT |
auth.uid() is seller for any item in order |
Notifications
| Policy |
Operation |
Scope |
| Owner access |
ALL |
auth.uid() = user_id |
| Admin create |
INSERT |
Admin role (for createNotificationForAllCustomers) |
Chats & Messages
| Policy |
Operation |
Scope |
| Participant read |
SELECT |
auth.uid() is participant |
| Participant write |
INSERT |
auth.uid() is participant |
| Owner messages |
ALL |
auth.uid() = sender_id |
| Policy |
Operation |
Scope |
| Admin full access |
ALL |
role = 'admin' |
| Public read active |
SELECT |
status = 'active' |
| Seller read |
SELECT |
Authenticated users |
| Seller create offers |
INSERT |
auth.uid() owns the seller |
| Seller update own offers |
UPDATE |
Owner of offer |
Featured Product Payments
| Policy |
Operation |
Scope |
| Admin full access |
ALL |
role = 'admin' |
| Seller own |
ALL |
auth.uid() owns the pharmacy |
| Public read active |
SELECT |
status = 'active' |
Pharmacy Subscriptions
| Policy |
Operation |
Scope |
| Admin full access |
ALL |
role = 'admin' |
| Seller own |
ALL |
auth.uid() owns the pharmacy |