@nextblock-cms/db 0.2.27 → 0.2.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/package.json +1 -1
  2. package/supabase/config.toml +1 -1
  3. package/supabase/migrations/00000000000013_seed_data.sql +6 -1
  4. package/supabase/migrations/00000000000014_seed_homepage_blocks.sql +21 -8
  5. package/supabase/migrations/{20251112141000_seed_homepage_blocks.sql → 00000000000016_sandbox_setup.sql} +834 -653
  6. package/supabase/migrations/20250513194738_setup_roles_and_profiles.sql +0 -41
  7. package/supabase/migrations/20250513194910_auto_create_profile_trigger.sql +0 -48
  8. package/supabase/migrations/20250513194916_rls_for_profiles.sql +0 -85
  9. package/supabase/migrations/20250514125634_fix_recursive_rls_policies.sql +0 -51
  10. package/supabase/migrations/20250514143016_setup_languages_table.sql +0 -66
  11. package/supabase/migrations/20250514171549_create_pages_table.sql +0 -73
  12. package/supabase/migrations/20250514171550_create_posts_table.sql +0 -61
  13. package/supabase/migrations/20250514171552_create_media_table.sql +0 -45
  14. package/supabase/migrations/20250514171553_create_blocks_table.sql +0 -54
  15. package/supabase/migrations/20250514171615_create_navigation_table.sql +0 -56
  16. package/supabase/migrations/20250514171627_rls_policies_for_content_tables.sql +0 -70
  17. package/supabase/migrations/20250515194800_add_translation_group_id.sql +0 -39
  18. package/supabase/migrations/20250520171900_add_translation_group_to_nav_items.sql +0 -21
  19. package/supabase/migrations/20250521143933_seed_homepage_and_nav.sql +0 -52
  20. package/supabase/migrations/20250523145833_add_feature_image_to_posts.sql +0 -8
  21. package/supabase/migrations/20250523151737_add_rls_to_media_table.sql +0 -18
  22. package/supabase/migrations/20250526110400_add_image_dimensions_to_media.sql +0 -14
  23. package/supabase/migrations/20250526153321_optimize_rls_policies.sql +0 -188
  24. package/supabase/migrations/20250526172513_resolve_select_policy_overlaps.sql +0 -96
  25. package/supabase/migrations/20250526172853_resolve_remaining_rls_v5.sql +0 -107
  26. package/supabase/migrations/20250526173538_finalize_rls_cleanup_v7.sql +0 -110
  27. package/supabase/migrations/20250526174710_separate_write_policies_v8.sql +0 -147
  28. package/supabase/migrations/20250526175359_fix_languages_select_rls_v9.sql +0 -81
  29. package/supabase/migrations/20250526182940_fix_nav_read_policy_v10.sql +0 -27
  30. package/supabase/migrations/20250526183239_fix_posts_read_rls_v11.sql +0 -59
  31. package/supabase/migrations/20250526183746_fix_media_select_rls_v12.sql +0 -39
  32. package/supabase/migrations/20250526184205_consolidate_content_read_rls_v13.sql +0 -61
  33. package/supabase/migrations/20250526185854_optimize_indexes.sql +0 -47
  34. package/supabase/migrations/20250526190900_debug_blocks_rls.sql +0 -56
  35. package/supabase/migrations/20250526191217_consolidate_blocks_select_rls.sql +0 -79
  36. package/supabase/migrations/20250526192822_fix_handle_languages_update_search_path.sql +0 -32
  37. package/supabase/migrations/20250527150500_fix_blocks_rls_policy.sql +0 -54
  38. package/supabase/migrations/20250602150602_add_blur_data_url_to_media.sql +0 -4
  39. package/supabase/migrations/20250602150959_add_variants_to_media.sql +0 -4
  40. package/supabase/migrations/20250618124000_create_get_my_claim_function.sql +0 -5
  41. package/supabase/migrations/20250618124100_create_logos_table.sql +0 -29
  42. package/supabase/migrations/20250618130000_fix_linter_warnings.sql +0 -58
  43. package/supabase/migrations/20250618151500_revert_storage_rls.sql +0 -6
  44. package/supabase/migrations/20250619084800_reinstate_storage_rls.sql +0 -13
  45. package/supabase/migrations/20250619092430_widen_logo_insert_policy.sql +0 -6
  46. package/supabase/migrations/20250619093122_fix_get_my_claim_volatility.sql +0 -5
  47. package/supabase/migrations/20250619104249_consolidated_logo_rls_fix.sql +0 -56
  48. package/supabase/migrations/20250619110700_fix_logo_rls_again.sql +0 -59
  49. package/supabase/migrations/20250619113200_add_file_path_to_media.sql +0 -4
  50. package/supabase/migrations/20250619124100_fix_rls_performance_warnings.sql +0 -74
  51. package/supabase/migrations/20250619195500_create_site_settings_table.sql +0 -28
  52. package/supabase/migrations/20250619201500_add_anon_read_to_site_settings.sql +0 -7
  53. package/supabase/migrations/20250619202000_add_is_active_to_languages.sql +0 -5
  54. package/supabase/migrations/20250620085700_fix_site_settings_write_rls.sql +0 -27
  55. package/supabase/migrations/20250620095500_fix_profiles_read_rls.sql +0 -11
  56. package/supabase/migrations/20250620100000_use_security_definer_for_rls.sql +0 -39
  57. package/supabase/migrations/20250620130000_add_public_read_to_logos.sql +0 -4
  58. package/supabase/migrations/20250708091700_create_translations_table.sql +0 -55
  59. package/supabase/migrations/20250708093403_seed_translations_table.sql +0 -20
  60. package/supabase/migrations/20250708110600_fix_translations_rls_policies.sql +0 -11
  61. package/supabase/migrations/20250708112300_add_new_translations.sql +0 -9
  62. package/supabase/migrations/20250709120000_create_revisions_tables.sql +0 -109
  63. package/supabase/migrations/20251001113000_add_folder_to_media.sql +0 -14
  64. package/supabase/migrations/20251112113736_fix_search_path_functions.sql +0 -74
  65. package/supabase/migrations/20251112124444_fix_rls_performance.sql +0 -63
  66. package/supabase/migrations/20251112125935_fix_combined_policies.sql +0 -194
  67. package/supabase/migrations/20251112132146_fix_foreign_key_indexes.sql +0 -21
  68. package/supabase/migrations/20251112132525_cleanup_unused_indexes.sql +0 -10
  69. package/supabase/migrations/20251112132822_fix_final_indexes.sql +0 -14
  70. package/supabase/migrations/20251112140000_scaffold_foundational_content.sql +0 -108
  71. package/supabase/migrations/20251112142000_seed_how_it_works_post_blocks.sql +0 -100
  72. package/supabase/migrations/20251112143000_seed_additional_translations.sql +0 -102
  73. package/supabase/migrations/20251112145000_grant_public_schema_usage.sql +0 -6
  74. package/supabase/migrations/20251112145500_grant_select_on_public_tables.sql +0 -19
  75. package/supabase/migrations/20251117093000_add_admin_created_flag.sql +0 -21
  76. package/supabase/migrations/20251117103000_relax_profile_username_constraint.sql +0 -6
  77. package/supabase/migrations/20251117110000_relax_profiles_site_settings_rls_for_signup.sql +0 -20
  78. package/supabase/migrations/20251117112000_fix_handle_new_user_role_enum.sql +0 -45
  79. package/supabase/migrations/20251117113000_cleanup_rls_duplicates.sql +0 -20
  80. package/supabase/migrations/20251117200000_media_service_role_insert.sql +0 -14
  81. package/supabase/migrations/20251117201500_media_service_role_select.sql +0 -11
  82. package/supabase/migrations/20251117203000_media_admin_writer_select.sql +0 -11
  83. package/supabase/migrations/20251117204500_fix_media_permissions.sql +0 -43
  84. package/supabase/migrations/20251126100000_seed_site_logo.sql +0 -33
  85. package/supabase/migrations/20251126133000_fix_blocks_rls.sql +0 -49
  86. package/supabase/migrations/20251127110000_fix_blocks_visibility_for_missing_profiles.sql +0 -23
  87. package/supabase/migrations/20251127120000_fix_duplicate_rls_policies.sql +0 -36
@@ -1,55 +0,0 @@
1
- -- Create the translations table
2
- CREATE TABLE translations (
3
- key TEXT PRIMARY KEY,
4
- translations JSONB NOT NULL,
5
- created_at TIMESTAMPTZ DEFAULT now() NOT NULL,
6
- updated_at TIMESTAMPTZ DEFAULT now() NOT NULL
7
- );
8
-
9
- -- Add comments on the columns
10
- COMMENT ON COLUMN translations.key IS 'A unique, slugified identifier (e.g., "sign_in_button_text").';
11
- COMMENT ON COLUMN translations.translations IS 'Stores translations as key-value pairs (e.g., {"en": "Sign In", "fr": "s''inscrire"}).';
12
-
13
- -- Enable Row Level Security
14
- ALTER TABLE translations ENABLE ROW LEVEL SECURITY;
15
-
16
- -- RLS Policies
17
- CREATE POLICY "Allow all access to ADMIN"
18
- ON public.translations
19
- FOR ALL
20
- TO authenticated
21
- USING (
22
- (auth.jwt() ->> 'user_role') = 'ADMIN'
23
- )
24
- WITH CHECK (
25
- (auth.jwt() ->> 'user_role') = 'ADMIN'
26
- );
27
-
28
- CREATE POLICY "Allow read access to all authenticated users"
29
- ON public.translations
30
- FOR SELECT
31
- TO authenticated
32
- USING (true);
33
-
34
- CREATE POLICY "Allow read access to all anonymous users"
35
- ON public.translations
36
- FOR SELECT
37
- TO anon
38
- USING (true);
39
-
40
- -- Trigger to update updated_at timestamp
41
- CREATE OR REPLACE FUNCTION public.set_current_timestamp_updated_at()
42
- RETURNS TRIGGER AS $$
43
- DECLARE
44
- _new record;
45
- BEGIN
46
- _new := NEW;
47
- _new."updated_at" = NOW();
48
- RETURN _new;
49
- END;
50
- $$ LANGUAGE plpgsql;
51
-
52
- CREATE TRIGGER set_updated_at
53
- BEFORE UPDATE ON public.translations
54
- FOR EACH ROW
55
- EXECUTE FUNCTION public.set_current_timestamp_updated_at();
@@ -1,20 +0,0 @@
1
- INSERT INTO public.translations (key, translations) VALUES
2
- ('sign_in', '{"en": "Sign in", "fr": "Connexion"}'),
3
- ('sign_up', '{"en": "Sign up", "fr": "Inscription"}'),
4
- ('sign_out', '{"en": "Sign out", "fr": "Déconnexion"}'),
5
- ('dont_have_account', '{"en": "Don''t have an account?", "fr": "Pas encore de compte ?"}'),
6
- ('email', '{"en": "Email", "fr": "Email"}'),
7
- ('you_at_example_com', '{"en": "you@example.com", "fr": "vous@example.com"}'),
8
- ('password', '{"en": "Password", "fr": "Mot de passe"}'),
9
- ('forgot_password', '{"en": "Forgot Password?", "fr": "Mot de passe oublié ?"}'),
10
- ('your_password', '{"en": "Your password", "fr": "Votre mot de passe"}'),
11
- ('signing_in_pending', '{"en": "Signing In...", "fr": "Connexion en cours..."}'),
12
- ('already_have_account', '{"en": "Already have an account?", "fr": "Déjà un compte ?"}'),
13
- ('signing_up_pending', '{"en": "Signing up...", "fr": "Inscription en cours..."}'),
14
- ('reset_password', '{"en": "Reset Password", "fr": "Réinitialiser le mot de passe"}');
15
-
16
- -- Route prefix for the blog section
17
- INSERT INTO public.translations (key, translations) VALUES
18
- ('blog_prefix', '{"en": "article", "fr": "article"}')
19
- ON CONFLICT (key) DO UPDATE
20
- SET translations = EXCLUDED.translations;
@@ -1,11 +0,0 @@
1
- -- Drop the existing restrictive policy for updates
2
- DROP POLICY IF EXISTS "Allow all access to ADMIN" ON public.translations;
3
-
4
- -- Create a more permissive policy that allows authenticated users to update translations
5
- -- This assumes that access to the CMS is already controlled at the application level
6
- CREATE POLICY "Allow authenticated users to manage translations"
7
- ON public.translations
8
- FOR ALL
9
- TO authenticated
10
- USING (true)
11
- WITH CHECK (true);
@@ -1,9 +0,0 @@
1
- INSERT INTO public.translations (key, translations) VALUES
2
- ('edit_page', '{"en": "Edit Page", "fr": "Éditer la page"}'),
3
- ('edit_post', '{"en": "Edit Post", "fr": "Éditer l''article"}'),
4
- ('open_main_menu', '{"en": "Open main menu", "fr": "Ouvrir le menu principal"}'),
5
- ('mobile_navigation_menu', '{"en": "Mobile navigation menu", "fr": "Menu de navigation mobile"}'),
6
- ('cms_dashboard', '{"en": "CMS Dashboard", "fr": "Tableau de bord CMS"}'),
7
- ('update_env_file_warning', '{"en": "Please update .env.local file with anon key and url", "fr": "Veuillez mettre à jour .env.local avec l''anon key et l''URL"}'),
8
- ('greeting', '{"en": "Hey, {username}!", "fr": "Salut, {username} !"}')
9
- ON CONFLICT (key) DO NOTHING;
@@ -1,109 +0,0 @@
1
- -- supabase/migrations/20250709120000_create_revisions_tables.sql
2
- -- Hybrid revision history for pages and posts
3
-
4
- begin;
5
-
6
- -- Create enum for revision type if not exists
7
- do $$
8
- begin
9
- if not exists (select 1 from pg_type where typname = 'revision_type') then
10
- create type public.revision_type as enum ('snapshot', 'diff');
11
- end if;
12
- end
13
- $$;
14
-
15
- -- Add version column to pages and posts if not exists
16
- do $$
17
- begin
18
- if not exists (
19
- select 1 from information_schema.columns
20
- where table_schema = 'public' and table_name = 'pages' and column_name = 'version'
21
- ) then
22
- alter table public.pages add column version integer not null default 1;
23
- comment on column public.pages.version is 'Monotonic version number for hybrid revisions.';
24
- end if;
25
- end
26
- $$;
27
-
28
- do $$
29
- begin
30
- if not exists (
31
- select 1 from information_schema.columns
32
- where table_schema = 'public' and table_name = 'posts' and column_name = 'version'
33
- ) then
34
- alter table public.posts add column version integer not null default 1;
35
- comment on column public.posts.version is 'Monotonic version number for hybrid revisions.';
36
- end if;
37
- end
38
- $$;
39
-
40
- -- Create page_revisions table
41
- create table if not exists public.page_revisions (
42
- id bigint generated by default as identity primary key,
43
- page_id bigint not null references public.pages(id) on delete cascade,
44
- author_id uuid references public.profiles(id) on delete set null,
45
- version integer not null,
46
- revision_type public.revision_type not null,
47
- content jsonb not null,
48
- created_at timestamp with time zone not null default now(),
49
- constraint page_revisions_page_version_key unique (page_id, version)
50
- );
51
-
52
- comment on table public.page_revisions is 'Hybrid (snapshot/diff) revisions for pages.';
53
- comment on column public.page_revisions.content is 'If snapshot: full content; if diff: JSON Patch array.';
54
-
55
- create index if not exists idx_page_revisions_page_id on public.page_revisions(page_id);
56
- create index if not exists idx_page_revisions_page_id_version on public.page_revisions(page_id, version);
57
-
58
- -- Create post_revisions table
59
- create table if not exists public.post_revisions (
60
- id bigint generated by default as identity primary key,
61
- post_id bigint not null references public.posts(id) on delete cascade,
62
- author_id uuid references public.profiles(id) on delete set null,
63
- version integer not null,
64
- revision_type public.revision_type not null,
65
- content jsonb not null,
66
- created_at timestamp with time zone not null default now(),
67
- constraint post_revisions_post_version_key unique (post_id, version)
68
- );
69
-
70
- comment on table public.post_revisions is 'Hybrid (snapshot/diff) revisions for posts.';
71
- comment on column public.post_revisions.content is 'If snapshot: full content; if diff: JSON Patch array.';
72
-
73
- create index if not exists idx_post_revisions_post_id on public.post_revisions(post_id);
74
- create index if not exists idx_post_revisions_post_id_version on public.post_revisions(post_id, version);
75
-
76
- -- Enable RLS and add policies (admins and writers manage; authenticated can read)
77
- alter table public.page_revisions enable row level security;
78
- alter table public.post_revisions enable row level security;
79
-
80
- -- Page revisions policies
81
- drop policy if exists "page_revisions_admin_writer_management" on public.page_revisions;
82
- create policy "page_revisions_admin_writer_management"
83
- on public.page_revisions for all
84
- to authenticated
85
- using (public.get_current_user_role() in ('ADMIN', 'WRITER'))
86
- with check (public.get_current_user_role() in ('ADMIN', 'WRITER'));
87
-
88
- drop policy if exists "page_revisions_authenticated_read" on public.page_revisions;
89
- create policy "page_revisions_authenticated_read"
90
- on public.page_revisions for select
91
- to authenticated
92
- using (true);
93
-
94
- -- Post revisions policies
95
- drop policy if exists "post_revisions_admin_writer_management" on public.post_revisions;
96
- create policy "post_revisions_admin_writer_management"
97
- on public.post_revisions for all
98
- to authenticated
99
- using (public.get_current_user_role() in ('ADMIN', 'WRITER'))
100
- with check (public.get_current_user_role() in ('ADMIN', 'WRITER'));
101
-
102
- drop policy if exists "post_revisions_authenticated_read" on public.post_revisions;
103
- create policy "post_revisions_authenticated_read"
104
- on public.post_revisions for select
105
- to authenticated
106
- using (true);
107
-
108
- commit;
109
-
@@ -1,14 +0,0 @@
1
- -- Add a folder column to organize media by path prefix
2
- ALTER TABLE public.media
3
- ADD COLUMN IF NOT EXISTS folder TEXT;
4
-
5
- COMMENT ON COLUMN public.media.folder IS 'Folder path prefix for the R2 object (e.g., images/summer/).';
6
-
7
- -- Backfill existing rows by deriving folder from object_key (everything up to last slash)
8
- UPDATE public.media
9
- SET folder = NULLIF(regexp_replace(object_key, '[^/]*$', ''), '')
10
- WHERE folder IS NULL;
11
-
12
- -- Index to speed up filtering by folder
13
- CREATE INDEX IF NOT EXISTS media_folder_idx ON public.media (folder);
14
-
@@ -1,74 +0,0 @@
1
- -- Ensure critical auth/public functions always use a safe search_path.
2
- BEGIN;
3
-
4
- CREATE OR REPLACE FUNCTION public.handle_languages_update()
5
- RETURNS TRIGGER
6
- LANGUAGE plpgsql
7
- SECURITY DEFINER
8
- SET search_path TO pg_temp, public
9
- AS $$
10
- BEGIN
11
- NEW.updated_at = now();
12
- RETURN NEW;
13
- END;
14
- $$;
15
-
16
- CREATE OR REPLACE FUNCTION public.get_my_claim(claim TEXT)
17
- RETURNS TEXT
18
- LANGUAGE plpgsql
19
- VOLATILE
20
- SET search_path TO pg_temp, public
21
- AS $$
22
- DECLARE
23
- claims jsonb;
24
- claim_value text;
25
- BEGIN
26
- -- Safely get claims, defaulting to NULL if not present or invalid JSON
27
- BEGIN
28
- claims := current_setting('request.jwt.claims', true)::jsonb;
29
- EXCEPTION
30
- WHEN invalid_text_representation THEN
31
- claims := NULL;
32
- END;
33
-
34
- -- If claims are NULL, return NULL
35
- IF claims IS NULL THEN
36
- RETURN NULL;
37
- END IF;
38
-
39
- -- Safely extract the claim value as text, removing quotes
40
- claim_value := claims ->> claim;
41
-
42
- RETURN claim_value;
43
- END;
44
- $$;
45
-
46
- CREATE OR REPLACE FUNCTION public.get_my_role()
47
- RETURNS TEXT
48
- LANGUAGE plpgsql
49
- SECURITY DEFINER
50
- SET search_path TO pg_temp, public
51
- AS $$
52
- DECLARE
53
- user_role TEXT;
54
- BEGIN
55
- SELECT role INTO user_role FROM public.profiles WHERE id = auth.uid();
56
- RETURN user_role;
57
- END;
58
- $$;
59
-
60
- CREATE OR REPLACE FUNCTION public.set_current_timestamp_updated_at()
61
- RETURNS TRIGGER
62
- LANGUAGE plpgsql
63
- SET search_path TO pg_temp, public
64
- AS $$
65
- DECLARE
66
- _new record;
67
- BEGIN
68
- _new := NEW;
69
- _new."updated_at" = now();
70
- RETURN _new;
71
- END;
72
- $$;
73
-
74
- COMMIT;
@@ -1,63 +0,0 @@
1
- BEGIN;
2
-
3
- -- Ensure profile read access uses a single policy and wraps auth.uid() safely.
4
- DROP POLICY IF EXISTS "Allow user to read their own profile" ON public.profiles;
5
- DROP POLICY IF EXISTS "authenticated_can_read_profiles" ON public.profiles;
6
-
7
- CREATE POLICY "authenticated_can_read_profiles" ON public.profiles
8
- FOR SELECT
9
- TO authenticated
10
- USING (
11
- (id = (SELECT auth.uid())) OR
12
- (public.get_current_user_role() = 'ADMIN')
13
- );
14
- COMMENT ON POLICY "authenticated_can_read_profiles" ON public.profiles IS 'Authenticated users can read their own profile; admins can read any profile.';
15
-
16
- -- Harden storage.objects ownership checks.
17
- DROP POLICY IF EXISTS "allow_authenticated_uploads" ON storage.objects;
18
- DROP POLICY IF EXISTS "allow_authenticated_updates" ON storage.objects;
19
- DROP POLICY IF EXISTS "allow_authenticated_deletes" ON storage.objects;
20
-
21
- CREATE POLICY "allow_authenticated_uploads" ON storage.objects
22
- FOR INSERT TO authenticated
23
- WITH CHECK (bucket_id = 'public' AND owner = (SELECT auth.uid()));
24
-
25
- CREATE POLICY "allow_authenticated_updates" ON storage.objects
26
- FOR UPDATE TO authenticated
27
- USING (bucket_id = 'public' AND owner = (SELECT auth.uid()));
28
-
29
- CREATE POLICY "allow_authenticated_deletes" ON storage.objects
30
- FOR DELETE TO authenticated
31
- USING (bucket_id = 'public' AND owner = (SELECT auth.uid()));
32
-
33
- -- Keep select policy as-is (bucket scoped) since it does not reference auth.uid().
34
-
35
- -- Update site_settings policies to avoid initplan warnings.
36
- DROP POLICY IF EXISTS "Allow ADMIN and WRITER to insert into site_settings" ON public.site_settings;
37
- DROP POLICY IF EXISTS "Allow ADMIN and WRITER to update site_settings" ON public.site_settings;
38
-
39
- CREATE POLICY "Allow ADMIN and WRITER to insert into site_settings" ON public.site_settings
40
- FOR INSERT TO authenticated
41
- WITH CHECK (
42
- EXISTS (
43
- SELECT 1 FROM public.profiles
44
- WHERE id = (SELECT auth.uid()) AND role IN ('ADMIN', 'WRITER')
45
- )
46
- );
47
-
48
- CREATE POLICY "Allow ADMIN and WRITER to update site_settings" ON public.site_settings
49
- FOR UPDATE TO authenticated
50
- USING (
51
- EXISTS (
52
- SELECT 1 FROM public.profiles
53
- WHERE id = (SELECT auth.uid()) AND role IN ('ADMIN', 'WRITER')
54
- )
55
- )
56
- WITH CHECK (
57
- EXISTS (
58
- SELECT 1 FROM public.profiles
59
- WHERE id = (SELECT auth.uid()) AND role IN ('ADMIN', 'WRITER')
60
- )
61
- );
62
-
63
- COMMIT;
@@ -1,194 +0,0 @@
1
- BEGIN;
2
-
3
- -- Consolidate logo read access into a single policy for the authenticated role.
4
- DROP POLICY IF EXISTS "Allow public read access to logos" ON public.logos;
5
- DROP POLICY IF EXISTS "Allow read access for authenticated users on logos" ON public.logos;
6
-
7
- CREATE POLICY "logos_authenticated_select_combined"
8
- ON public.logos
9
- FOR SELECT
10
- TO authenticated
11
- USING (true);
12
-
13
- -- Page revisions: remove overlapping SELECT coverage and keep a single policy per action.
14
- DROP POLICY IF EXISTS page_revisions_admin_writer_management ON public.page_revisions;
15
- DROP POLICY IF EXISTS page_revisions_authenticated_read ON public.page_revisions;
16
-
17
- CREATE POLICY "page_revisions_authenticated_select_combined"
18
- ON public.page_revisions
19
- FOR SELECT
20
- TO authenticated
21
- USING (true);
22
-
23
- CREATE POLICY "page_revisions_admin_writer_insert"
24
- ON public.page_revisions
25
- FOR INSERT
26
- TO authenticated
27
- WITH CHECK (
28
- EXISTS (
29
- SELECT 1 FROM public.profiles
30
- WHERE id = (SELECT auth.uid()) AND role IN ('ADMIN', 'WRITER')
31
- )
32
- );
33
-
34
- CREATE POLICY "page_revisions_admin_writer_update"
35
- ON public.page_revisions
36
- FOR UPDATE
37
- TO authenticated
38
- USING (
39
- EXISTS (
40
- SELECT 1 FROM public.profiles
41
- WHERE id = (SELECT auth.uid()) AND role IN ('ADMIN', 'WRITER')
42
- )
43
- )
44
- WITH CHECK (
45
- EXISTS (
46
- SELECT 1 FROM public.profiles
47
- WHERE id = (SELECT auth.uid()) AND role IN ('ADMIN', 'WRITER')
48
- )
49
- );
50
-
51
- CREATE POLICY "page_revisions_admin_writer_delete"
52
- ON public.page_revisions
53
- FOR DELETE
54
- TO authenticated
55
- USING (
56
- EXISTS (
57
- SELECT 1 FROM public.profiles
58
- WHERE id = (SELECT auth.uid()) AND role IN ('ADMIN', 'WRITER')
59
- )
60
- );
61
-
62
- -- Post revisions: same treatment as page revisions.
63
- DROP POLICY IF EXISTS post_revisions_admin_writer_management ON public.post_revisions;
64
- DROP POLICY IF EXISTS post_revisions_authenticated_read ON public.post_revisions;
65
-
66
- CREATE POLICY "post_revisions_authenticated_select_combined"
67
- ON public.post_revisions
68
- FOR SELECT
69
- TO authenticated
70
- USING (true);
71
-
72
- CREATE POLICY "post_revisions_admin_writer_insert"
73
- ON public.post_revisions
74
- FOR INSERT
75
- TO authenticated
76
- WITH CHECK (
77
- EXISTS (
78
- SELECT 1 FROM public.profiles
79
- WHERE id = (SELECT auth.uid()) AND role IN ('ADMIN', 'WRITER')
80
- )
81
- );
82
-
83
- CREATE POLICY "post_revisions_admin_writer_update"
84
- ON public.post_revisions
85
- FOR UPDATE
86
- TO authenticated
87
- USING (
88
- EXISTS (
89
- SELECT 1 FROM public.profiles
90
- WHERE id = (SELECT auth.uid()) AND role IN ('ADMIN', 'WRITER')
91
- )
92
- )
93
- WITH CHECK (
94
- EXISTS (
95
- SELECT 1 FROM public.profiles
96
- WHERE id = (SELECT auth.uid()) AND role IN ('ADMIN', 'WRITER')
97
- )
98
- );
99
-
100
- CREATE POLICY "post_revisions_admin_writer_delete"
101
- ON public.post_revisions
102
- FOR DELETE
103
- TO authenticated
104
- USING (
105
- EXISTS (
106
- SELECT 1 FROM public.profiles
107
- WHERE id = (SELECT auth.uid()) AND role IN ('ADMIN', 'WRITER')
108
- )
109
- );
110
-
111
- -- Site settings: collapse overlapping policies per action.
112
- DROP POLICY IF EXISTS "Allow ADMIN and WRITER to insert into site_settings" ON public.site_settings;
113
- DROP POLICY IF EXISTS "Allow admins full access on site_settings" ON public.site_settings;
114
- DROP POLICY IF EXISTS "Allow insert based on user role" ON public.site_settings;
115
- DROP POLICY IF EXISTS "Allow authenticated users to read site_settings" ON public.site_settings;
116
- DROP POLICY IF EXISTS "Allow update based on user role" ON public.site_settings;
117
- DROP POLICY IF EXISTS "Allow ADMIN and WRITER to update site_settings" ON public.site_settings;
118
- DROP POLICY IF EXISTS "Allow ADMIN and WRITER to modify site_settings" ON public.site_settings;
119
-
120
- CREATE POLICY "site_settings_authenticated_insert_combined"
121
- ON public.site_settings
122
- FOR INSERT
123
- TO authenticated
124
- WITH CHECK (
125
- EXISTS (
126
- SELECT 1 FROM public.profiles
127
- WHERE id = (SELECT auth.uid()) AND role IN ('ADMIN', 'WRITER')
128
- )
129
- );
130
-
131
- CREATE POLICY "site_settings_authenticated_select_combined"
132
- ON public.site_settings
133
- FOR SELECT
134
- TO authenticated
135
- USING (true);
136
-
137
- CREATE POLICY "site_settings_authenticated_update_combined"
138
- ON public.site_settings
139
- FOR UPDATE
140
- TO authenticated
141
- USING (
142
- EXISTS (
143
- SELECT 1 FROM public.profiles
144
- WHERE id = (SELECT auth.uid()) AND role IN ('ADMIN', 'WRITER')
145
- )
146
- )
147
- WITH CHECK (
148
- EXISTS (
149
- SELECT 1 FROM public.profiles
150
- WHERE id = (SELECT auth.uid()) AND role IN ('ADMIN', 'WRITER')
151
- )
152
- );
153
-
154
- CREATE POLICY "site_settings_authenticated_delete_combined"
155
- ON public.site_settings
156
- FOR DELETE
157
- TO authenticated
158
- USING (
159
- EXISTS (
160
- SELECT 1 FROM public.profiles
161
- WHERE id = (SELECT auth.uid()) AND role IN ('ADMIN', 'WRITER')
162
- )
163
- );
164
-
165
- -- Translations: split FOR ALL coverage into distinct policies.
166
- DROP POLICY IF EXISTS "Allow authenticated users to manage translations" ON public.translations;
167
- DROP POLICY IF EXISTS "Allow read access to all authenticated users" ON public.translations;
168
-
169
- CREATE POLICY "translations_authenticated_select_combined"
170
- ON public.translations
171
- FOR SELECT
172
- TO authenticated
173
- USING (true);
174
-
175
- CREATE POLICY "translations_authenticated_insert_combined"
176
- ON public.translations
177
- FOR INSERT
178
- TO authenticated
179
- WITH CHECK (true);
180
-
181
- CREATE POLICY "translations_authenticated_update_combined"
182
- ON public.translations
183
- FOR UPDATE
184
- TO authenticated
185
- USING (true)
186
- WITH CHECK (true);
187
-
188
- CREATE POLICY "translations_authenticated_delete_combined"
189
- ON public.translations
190
- FOR DELETE
191
- TO authenticated
192
- USING (true);
193
-
194
- COMMIT;
@@ -1,21 +0,0 @@
1
- BEGIN;
2
-
3
- -- Add missing coverage for frequently joined foreign keys.
4
- CREATE INDEX IF NOT EXISTS idx_logos_media_id
5
- ON public.logos (media_id);
6
-
7
- CREATE INDEX IF NOT EXISTS idx_page_revisions_author_id
8
- ON public.page_revisions (author_id);
9
-
10
- CREATE INDEX IF NOT EXISTS idx_post_revisions_author_id
11
- ON public.post_revisions (author_id);
12
-
13
- -- Drop unused or redundant indexes called out by Supabase insights.
14
- DROP INDEX IF EXISTS idx_page_revisions_page_id_version;
15
- DROP INDEX IF EXISTS idx_post_revisions_post_id_version;
16
- DROP INDEX IF EXISTS idx_post_revisions_post_id;
17
- DROP INDEX IF EXISTS idx_pages_translation_group_id;
18
- DROP INDEX IF EXISTS idx_posts_translation_group_id;
19
- DROP INDEX IF EXISTS idx_navigation_items_menu_lang_order;
20
-
21
- COMMIT;
@@ -1,10 +0,0 @@
1
- BEGIN;
2
-
3
- -- Drop redundant or legacy indexes highlighted by Supabase Advisor.
4
- DROP INDEX IF EXISTS media_folder_idx;
5
- DROP INDEX IF EXISTS idx_blocks_language_id;
6
- DROP INDEX IF EXISTS idx_blocks_post_id;
7
- DROP INDEX IF EXISTS idx_navigation_items_language_id;
8
- DROP INDEX IF EXISTS idx_page_revisions_page_id;
9
-
10
- COMMIT;
@@ -1,14 +0,0 @@
1
- BEGIN;
2
-
3
- CREATE INDEX IF NOT EXISTS idx_blocks_language_id
4
- ON public.blocks (language_id);
5
-
6
- CREATE INDEX IF NOT EXISTS idx_blocks_post_id
7
- ON public.blocks (post_id);
8
-
9
- CREATE INDEX IF NOT EXISTS idx_navigation_items_language_id
10
- ON public.navigation_items (language_id);
11
-
12
- ANALYZE VERBOSE;
13
-
14
- COMMIT;