From 8279e5f9adb7ccd5704bb2a44e4aa86c96d27a2f Mon Sep 17 00:00:00 2001 From: Jexan Joel Date: Sat, 4 Apr 2026 12:01:39 +0530 Subject: [PATCH 1/3] docs: add database.sql and sync-rules.yaml to react-supabase-todolist demo --- demos/react-supabase-todolist/README.md | 32 ++++++---- demos/react-supabase-todolist/database.sql | 61 +++++++++++++++++++ demos/react-supabase-todolist/sync-rules.yaml | 7 +++ 3 files changed, 87 insertions(+), 13 deletions(-) create mode 100644 demos/react-supabase-todolist/database.sql create mode 100644 demos/react-supabase-todolist/sync-rules.yaml diff --git a/demos/react-supabase-todolist/README.md b/demos/react-supabase-todolist/README.md index 5518cd86b..864952b18 100644 --- a/demos/react-supabase-todolist/README.md +++ b/demos/react-supabase-todolist/README.md @@ -8,33 +8,41 @@ This demo uses [Sync Streams](https://docs.powersync.com/usage/sync-streams). Bo ## Run Demo -Prerequisites: -* To run this demo, you need to have properly configured Supabase and PowerSync projects. Follow the instructions in our Supabase<>PowerSync integration guide: - * [Configure Supabase](https://docs.powersync.com/integration-guides/supabase-+-powersync#configure-supabase) - * [Configure PowerSync](https://docs.powersync.com/integration-guides/supabase-+-powersync#configure-powersync) +### 1. Supabase Setup -Switch into the demo's directory: +Create a new Supabase project, then run the contents of [`database.sql`](./database.sql) in the [Supabase SQL editor](https://supabase.com/dashboard/project/_/sql). This will: +- Create the `lists` and `todos` tables +- Enable Row Level Security (RLS) so users can only access their own data +- Create a `powersync` publication for replication + +### 2. PowerSync Setup + +Create a new PowerSync instance connected to your Supabase project ([instructions here](https://docs.powersync.com/integration-guides/supabase-+-powersync#connect-powersync-to-your-supabase)). + +In the PowerSync dashboard, go to **Sync Rules** and paste the contents of [`sync-rules.yaml`](./sync-rules.yaml). + +### 3. Install Dependencies +Switch into the demo's directory: ```bash cd demos/react-supabase-todolist ``` Use [pnpm](https://pnpm.io/installation) to install dependencies: - ```bash pnpm install ``` -Set up the Environment variables: Copy the `.env.local.template` file: +### 4. Configure Environment Variables +Copy the `.env.local.template` file: ```bash cp .env.local.template .env.local ``` -And then edit `.env.local` to insert your credentials for Supabase. - -Run the development server: +Edit `.env.local` to insert your Supabase URL, anon key, and PowerSync URL. +### 5. Run the Development Server ```bash pnpm dev ``` @@ -46,13 +54,11 @@ Open [http://localhost:5173](http://localhost:5173) with your browser to see the This demo is PWA compatible, and works fully offline. PWA is not available in development (watch) mode. The manifest and service worker is built using [vite-plugin-pwa](https://vite-pwa-org.netlify.app/). Build the production codebase: - ```bash pnpm build ``` Run the production server: - ```bash pnpm preview ``` @@ -63,4 +69,4 @@ Open a browser on the served URL and install the PWA. Check out [the PowerSync Web SDK on GitHub](https://github.com/powersync-ja/powersync-js/tree/main/packages/web) - your feedback and contributions are welcome! -To learn more about PowerSync, see the [PowerSync docs](https://docs.powersync.com). +To learn more about PowerSync, see the [PowerSync docs](https://docs.powersync.com). \ No newline at end of file diff --git a/demos/react-supabase-todolist/database.sql b/demos/react-supabase-todolist/database.sql new file mode 100644 index 000000000..61636e9fd --- /dev/null +++ b/demos/react-supabase-todolist/database.sql @@ -0,0 +1,61 @@ +-- Create the lists table +CREATE TABLE IF NOT EXISTS public.lists ( + id uuid NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY, + created_at timestamp with time zone NOT NULL DEFAULT now(), + name text NOT NULL, + owner_id uuid NOT NULL REFERENCES auth.users (id) ON DELETE CASCADE +); + +-- Create the todos table +CREATE TABLE IF NOT EXISTS public.todos ( + id uuid NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY, + created_at timestamp with time zone NOT NULL DEFAULT now(), + completed_at timestamp with time zone, + description text NOT NULL, + completed boolean NOT NULL DEFAULT false, + list_id uuid NOT NULL REFERENCES public.lists (id) ON DELETE CASCADE, + created_by uuid REFERENCES auth.users (id), + completed_by uuid REFERENCES auth.users (id) +); + +-- Enable Row Level Security +ALTER TABLE public.lists ENABLE ROW LEVEL SECURITY; +ALTER TABLE public.todos ENABLE ROW LEVEL SECURITY; + +-- RLS policies for lists: users can only access their own lists +CREATE POLICY "Users can view their own lists" ON public.lists + FOR SELECT USING (auth.uid() = owner_id); + +CREATE POLICY "Users can insert their own lists" ON public.lists + FOR INSERT WITH CHECK (auth.uid() = owner_id); + +CREATE POLICY "Users can update their own lists" ON public.lists + FOR UPDATE USING (auth.uid() = owner_id); + +CREATE POLICY "Users can delete their own lists" ON public.lists + FOR DELETE USING (auth.uid() = owner_id); + +-- RLS policies for todos: users can only access todos in their own lists +CREATE POLICY "Users can view todos in their lists" ON public.todos + FOR SELECT USING ( + list_id IN (SELECT id FROM public.lists WHERE owner_id = auth.uid()) + ); + +CREATE POLICY "Users can insert todos in their lists" ON public.todos + FOR INSERT WITH CHECK ( + list_id IN (SELECT id FROM public.lists WHERE owner_id = auth.uid()) + ); + +CREATE POLICY "Users can update todos in their lists" ON public.todos + FOR UPDATE USING ( + list_id IN (SELECT id FROM public.lists WHERE owner_id = auth.uid()) + ); + +CREATE POLICY "Users can delete todos in their lists" ON public.todos + FOR DELETE USING ( + list_id IN (SELECT id FROM public.lists WHERE owner_id = auth.uid()) + ); + +-- Create PowerSync publication +-- Note: FOR ALL TABLES is simplest for dev. In production, specify tables explicitly. +CREATE PUBLICATION powersync FOR TABLE public.lists, public.todos; \ No newline at end of file diff --git a/demos/react-supabase-todolist/sync-rules.yaml b/demos/react-supabase-todolist/sync-rules.yaml new file mode 100644 index 000000000..c33c82e74 --- /dev/null +++ b/demos/react-supabase-todolist/sync-rules.yaml @@ -0,0 +1,7 @@ +bucket_definitions: + user_lists: + # Separate bucket per todo list, scoped to the authenticated user + parameters: select id as list_id from lists where owner_id = request.user_id() + data: + - select * from lists where id = bucket.list_id + - select * from todos where list_id = bucket.list_id \ No newline at end of file From df12eb4d6f7ffbea9a282139952cb007720e50cf Mon Sep 17 00:00:00 2001 From: Jexan Joel Date: Tue, 7 Apr 2026 15:01:24 +0530 Subject: [PATCH 2/3] address review: add powersync_role, rename to sync-streams.yaml, update README --- demos/react-supabase-todolist/README.md | 3 ++- demos/react-supabase-todolist/database.sql | 5 +++++ .../{sync-rules.yaml => sync-streams.yaml} | 6 +++--- 3 files changed, 10 insertions(+), 4 deletions(-) rename demos/react-supabase-todolist/{sync-rules.yaml => sync-streams.yaml} (68%) diff --git a/demos/react-supabase-todolist/README.md b/demos/react-supabase-todolist/README.md index 864952b18..6ae7ae535 100644 --- a/demos/react-supabase-todolist/README.md +++ b/demos/react-supabase-todolist/README.md @@ -11,6 +11,7 @@ This demo uses [Sync Streams](https://docs.powersync.com/usage/sync-streams). Bo ### 1. Supabase Setup Create a new Supabase project, then run the contents of [`database.sql`](./database.sql) in the [Supabase SQL editor](https://supabase.com/dashboard/project/_/sql). This will: + - Create the `lists` and `todos` tables - Enable Row Level Security (RLS) so users can only access their own data - Create a `powersync` publication for replication @@ -19,7 +20,7 @@ Create a new Supabase project, then run the contents of [`database.sql`](./datab Create a new PowerSync instance connected to your Supabase project ([instructions here](https://docs.powersync.com/integration-guides/supabase-+-powersync#connect-powersync-to-your-supabase)). -In the PowerSync dashboard, go to **Sync Rules** and paste the contents of [`sync-rules.yaml`](./sync-rules.yaml). +In the PowerSync dashboard, go to **Sync Streams** (shown as **Sync Rules** if using legacy Sync Rules) and paste the contents of [`sync-streams.yaml`](./sync-streams.yaml). ### 3. Install Dependencies diff --git a/demos/react-supabase-todolist/database.sql b/demos/react-supabase-todolist/database.sql index 61636e9fd..7a5870957 100644 --- a/demos/react-supabase-todolist/database.sql +++ b/demos/react-supabase-todolist/database.sql @@ -56,6 +56,11 @@ CREATE POLICY "Users can delete todos in their lists" ON public.todos list_id IN (SELECT id FROM public.lists WHERE owner_id = auth.uid()) ); +-- Create PowerSync role for replication access +CREATE ROLE powersync_role REPLICATION LOGIN; +GRANT SELECT ON public.lists TO powersync_role; +GRANT SELECT ON public.todos TO powersync_role; + -- Create PowerSync publication -- Note: FOR ALL TABLES is simplest for dev. In production, specify tables explicitly. CREATE PUBLICATION powersync FOR TABLE public.lists, public.todos; \ No newline at end of file diff --git a/demos/react-supabase-todolist/sync-rules.yaml b/demos/react-supabase-todolist/sync-streams.yaml similarity index 68% rename from demos/react-supabase-todolist/sync-rules.yaml rename to demos/react-supabase-todolist/sync-streams.yaml index c33c82e74..bcf61a1c8 100644 --- a/demos/react-supabase-todolist/sync-rules.yaml +++ b/demos/react-supabase-todolist/sync-streams.yaml @@ -1,6 +1,6 @@ -bucket_definitions: - user_lists: - # Separate bucket per todo list, scoped to the authenticated user +sync_streams: + - name: user_lists + # Separate stream per todo list, scoped to the authenticated user parameters: select id as list_id from lists where owner_id = request.user_id() data: - select * from lists where id = bucket.list_id From efdc7b2a948b6a58041a19db91d495f5f204d9ed Mon Sep 17 00:00:00 2001 From: Jexan Joel Date: Tue, 7 Apr 2026 15:42:01 +0530 Subject: [PATCH 3/3] address review: add powersync_role password note, update sync-streams.yaml format --- demos/react-supabase-todolist/database.sql | 2 ++ demos/react-supabase-todolist/sync-streams.yaml | 17 ++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/demos/react-supabase-todolist/database.sql b/demos/react-supabase-todolist/database.sql index 7a5870957..8321ccf6b 100644 --- a/demos/react-supabase-todolist/database.sql +++ b/demos/react-supabase-todolist/database.sql @@ -57,6 +57,8 @@ CREATE POLICY "Users can delete todos in their lists" ON public.todos ); -- Create PowerSync role for replication access +-- Note: After creating this role, set a secure password in the Supabase dashboard +-- or run: ALTER ROLE powersync_role WITH PASSWORD 'your-secure-password'; CREATE ROLE powersync_role REPLICATION LOGIN; GRANT SELECT ON public.lists TO powersync_role; GRANT SELECT ON public.todos TO powersync_role; diff --git a/demos/react-supabase-todolist/sync-streams.yaml b/demos/react-supabase-todolist/sync-streams.yaml index bcf61a1c8..788f30e46 100644 --- a/demos/react-supabase-todolist/sync-streams.yaml +++ b/demos/react-supabase-todolist/sync-streams.yaml @@ -1,7 +1,10 @@ -sync_streams: - - name: user_lists - # Separate stream per todo list, scoped to the authenticated user - parameters: select id as list_id from lists where owner_id = request.user_id() - data: - - select * from lists where id = bucket.list_id - - select * from todos where list_id = bucket.list_id \ No newline at end of file +config: + edition: 3 + +streams: + user_data: + auto_subscribe: true + queries: + # Scoped to the authenticated user + - SELECT * FROM lists WHERE owner_id = auth.user_id() + - SELECT todos.* FROM todos INNER JOIN lists ON todos.list_id = lists.id WHERE lists.owner_id = auth.user_id() \ No newline at end of file