-- Migration: Row Level Security Policies -- Created: 2026-02-09 -- Issue: #14 -- Description: Enables RLS and creates security policies for all tables -- ====================== -- ENABLE RLS -- ====================== ALTER TABLE inventory_items ENABLE ROW LEVEL SECURITY; ALTER TABLE products ENABLE ROW LEVEL SECURITY; ALTER TABLE tags ENABLE ROW LEVEL SECURITY; ALTER TABLE item_tags ENABLE ROW LEVEL SECURITY; ALTER TABLE units ENABLE ROW LEVEL SECURITY; ALTER TABLE user_profiles ENABLE ROW LEVEL SECURITY; -- ====================== -- INVENTORY_ITEMS POLICIES -- ====================== -- Everyone can read (shared household inventory) CREATE POLICY "inventory_items_select_all" ON inventory_items FOR SELECT USING (true); -- Authenticated users can insert items CREATE POLICY "inventory_items_insert_auth" ON inventory_items FOR INSERT WITH CHECK (auth.uid() IS NOT NULL); -- Authenticated users can update any item CREATE POLICY "inventory_items_update_auth" ON inventory_items FOR UPDATE USING (auth.uid() IS NOT NULL); -- Authenticated users can delete any item CREATE POLICY "inventory_items_delete_auth" ON inventory_items FOR DELETE USING (auth.uid() IS NOT NULL); -- ====================== -- PRODUCTS POLICIES -- ====================== -- Everyone can read cached products CREATE POLICY "products_select_all" ON products FOR SELECT USING (true); -- Only service role can write (via Edge Functions) -- No user-level INSERT/UPDATE/DELETE policies -- ====================== -- TAGS POLICIES -- ====================== -- Everyone can read all tags CREATE POLICY "tags_select_all" ON tags FOR SELECT USING (true); -- Authenticated users can create tags CREATE POLICY "tags_insert_auth" ON tags FOR INSERT WITH CHECK (auth.uid() IS NOT NULL); -- Users can update their own tags OR system tags (created_by IS NULL) CREATE POLICY "tags_update_own" ON tags FOR UPDATE USING ( created_by = auth.uid() OR created_by IS NULL ); -- Users can only delete their own custom tags CREATE POLICY "tags_delete_own" ON tags FOR DELETE USING (created_by = auth.uid()); -- ====================== -- ITEM_TAGS POLICIES -- ====================== -- Everyone can read CREATE POLICY "item_tags_select_all" ON item_tags FOR SELECT USING (true); -- Authenticated users can add tags to items CREATE POLICY "item_tags_insert_auth" ON item_tags FOR INSERT WITH CHECK (auth.uid() IS NOT NULL); -- Authenticated users can remove tags from items CREATE POLICY "item_tags_delete_auth" ON item_tags FOR DELETE USING (auth.uid() IS NOT NULL); -- ====================== -- UNITS POLICIES -- ====================== -- Everyone can read all units CREATE POLICY "units_select_all" ON units FOR SELECT USING (true); -- Authenticated users can create custom units (not default ones) CREATE POLICY "units_insert_auth" ON units FOR INSERT WITH CHECK ( auth.uid() IS NOT NULL AND is_default = false ); -- Users can update their own custom units only CREATE POLICY "units_update_own" ON units FOR UPDATE USING ( created_by = auth.uid() AND is_default = false ); -- Users can delete their own custom units only CREATE POLICY "units_delete_own" ON units FOR DELETE USING ( created_by = auth.uid() AND is_default = false ); -- ====================== -- USER_PROFILES POLICIES -- ====================== -- Users can read all profiles (for display names, avatars) CREATE POLICY "user_profiles_select_all" ON user_profiles FOR SELECT USING (true); -- Users can insert their own profile CREATE POLICY "user_profiles_insert_own" ON user_profiles FOR INSERT WITH CHECK (auth.uid() = id); -- Users can update only their own profile CREATE POLICY "user_profiles_update_own" ON user_profiles FOR UPDATE USING (auth.uid() = id); -- Users can delete only their own profile CREATE POLICY "user_profiles_delete_own" ON user_profiles FOR DELETE USING (auth.uid() = id); -- ====================== -- COMMENTS -- ====================== COMMENT ON POLICY "inventory_items_select_all" ON inventory_items IS 'Allow all users to view shared household inventory'; COMMENT ON POLICY "inventory_items_insert_auth" ON inventory_items IS 'Authenticated users can add items'; COMMENT ON POLICY "inventory_items_update_auth" ON inventory_items IS 'Authenticated users can update any item (shared inventory)'; COMMENT ON POLICY "inventory_items_delete_auth" ON inventory_items IS 'Authenticated users can delete any item'; COMMENT ON POLICY "products_select_all" ON products IS 'Allow all users to view cached product data'; COMMENT ON POLICY "tags_select_all" ON tags IS 'Allow all users to view tags (system and custom)'; COMMENT ON POLICY "tags_insert_auth" ON tags IS 'Authenticated users can create custom tags'; COMMENT ON POLICY "tags_update_own" ON tags IS 'Users can update their own tags or system tags'; COMMENT ON POLICY "tags_delete_own" ON tags IS 'Users can only delete their own custom tags'; COMMENT ON POLICY "item_tags_select_all" ON item_tags IS 'Allow all users to view item tag associations'; COMMENT ON POLICY "item_tags_insert_auth" ON item_tags IS 'Authenticated users can tag items'; COMMENT ON POLICY "item_tags_delete_auth" ON item_tags IS 'Authenticated users can remove tags from items'; COMMENT ON POLICY "units_select_all" ON units IS 'Allow all users to view all units'; COMMENT ON POLICY "units_insert_auth" ON units IS 'Authenticated users can create custom units'; COMMENT ON POLICY "units_update_own" ON units IS 'Users can only update their own custom units'; COMMENT ON POLICY "units_delete_own" ON units IS 'Users can only delete their own custom units'; COMMENT ON POLICY "user_profiles_select_all" ON user_profiles IS 'Allow users to view all profiles for display purposes'; COMMENT ON POLICY "user_profiles_insert_own" ON user_profiles IS 'Users can create their own profile'; COMMENT ON POLICY "user_profiles_update_own" ON user_profiles IS 'Users can only update their own profile'; COMMENT ON POLICY "user_profiles_delete_own" ON user_profiles IS 'Users can only delete their own profile';