@nextblock-cms/db 0.2.10 → 0.2.13
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.
- package/package.json +13 -3
- package/supabase/config.toml +319 -0
- package/supabase/migrations/20250513194738_setup_roles_and_profiles.sql +41 -0
- package/supabase/migrations/20250513194910_auto_create_profile_trigger.sql +48 -0
- package/supabase/migrations/20250513194916_rls_for_profiles.sql +85 -0
- package/supabase/migrations/20250514125634_fix_recursive_rls_policies.sql +51 -0
- package/supabase/migrations/20250514143016_setup_languages_table.sql +66 -0
- package/supabase/migrations/20250514171549_create_pages_table.sql +73 -0
- package/supabase/migrations/20250514171550_create_posts_table.sql +61 -0
- package/supabase/migrations/20250514171552_create_media_table.sql +45 -0
- package/supabase/migrations/20250514171553_create_blocks_table.sql +54 -0
- package/supabase/migrations/20250514171615_create_navigation_table.sql +56 -0
- package/supabase/migrations/20250514171627_rls_policies_for_content_tables.sql +70 -0
- package/supabase/migrations/20250515194800_add_translation_group_id.sql +39 -0
- package/supabase/migrations/20250520171900_add_translation_group_to_nav_items.sql +21 -0
- package/supabase/migrations/20250521143933_seed_homepage_and_nav.sql +64 -0
- package/supabase/migrations/20250523145833_add_feature_image_to_posts.sql +8 -0
- package/supabase/migrations/20250523151737_add_rls_to_media_table.sql +18 -0
- package/supabase/migrations/20250526110400_add_image_dimensions_to_media.sql +14 -0
- package/supabase/migrations/20250526153321_optimize_rls_policies.sql +188 -0
- package/supabase/migrations/20250526172513_resolve_select_policy_overlaps.sql +96 -0
- package/supabase/migrations/20250526172853_resolve_remaining_rls_v5.sql +107 -0
- package/supabase/migrations/20250526173538_finalize_rls_cleanup_v7.sql +110 -0
- package/supabase/migrations/20250526174710_separate_write_policies_v8.sql +147 -0
- package/supabase/migrations/20250526175359_fix_languages_select_rls_v9.sql +81 -0
- package/supabase/migrations/20250526182940_fix_nav_read_policy_v10.sql +27 -0
- package/supabase/migrations/20250526183239_fix_posts_read_rls_v11.sql +59 -0
- package/supabase/migrations/20250526183746_fix_media_select_rls_v12.sql +39 -0
- package/supabase/migrations/20250526184205_consolidate_content_read_rls_v13.sql +61 -0
- package/supabase/migrations/20250526185854_optimize_indexes.sql +47 -0
- package/supabase/migrations/20250526190900_debug_blocks_rls.sql +56 -0
- package/supabase/migrations/20250526191217_consolidate_blocks_select_rls.sql +79 -0
- package/supabase/migrations/20250526192822_fix_handle_languages_update_search_path.sql +32 -0
- package/supabase/migrations/20250527150500_fix_blocks_rls_policy.sql +54 -0
- package/supabase/migrations/20250602150602_add_blur_data_url_to_media.sql +4 -0
- package/supabase/migrations/20250602150959_add_variants_to_media.sql +4 -0
- package/supabase/migrations/20250618124000_create_get_my_claim_function.sql +5 -0
- package/supabase/migrations/20250618124100_create_logos_table.sql +29 -0
- package/supabase/migrations/20250618130000_fix_linter_warnings.sql +58 -0
- package/supabase/migrations/20250618151500_revert_storage_rls.sql +6 -0
- package/supabase/migrations/20250619084800_reinstate_storage_rls.sql +13 -0
- package/supabase/migrations/20250619092430_widen_logo_insert_policy.sql +6 -0
- package/supabase/migrations/20250619093122_fix_get_my_claim_volatility.sql +5 -0
- package/supabase/migrations/20250619104249_consolidated_logo_rls_fix.sql +56 -0
- package/supabase/migrations/20250619110700_fix_logo_rls_again.sql +59 -0
- package/supabase/migrations/20250619113200_add_file_path_to_media.sql +4 -0
- package/supabase/migrations/20250619124100_fix_rls_performance_warnings.sql +74 -0
- package/supabase/migrations/20250619195500_create_site_settings_table.sql +28 -0
- package/supabase/migrations/20250619201500_add_anon_read_to_site_settings.sql +7 -0
- package/supabase/migrations/20250619202000_add_is_active_to_languages.sql +5 -0
- package/supabase/migrations/20250620085700_fix_site_settings_write_rls.sql +27 -0
- package/supabase/migrations/20250620095500_fix_profiles_read_rls.sql +11 -0
- package/supabase/migrations/20250620100000_use_security_definer_for_rls.sql +39 -0
- package/supabase/migrations/20250620130000_add_public_read_to_logos.sql +4 -0
- package/supabase/migrations/20250708091700_create_translations_table.sql +55 -0
- package/supabase/migrations/20250708093403_seed_translations_table.sql +20 -0
- package/supabase/migrations/20250708110600_fix_translations_rls_policies.sql +11 -0
- package/supabase/migrations/20250708112300_add_new_translations.sql +9 -0
- package/supabase/migrations/20250709120000_create_revisions_tables.sql +109 -0
- package/supabase/migrations/20251001113000_add_folder_to_media.sql +14 -0
- package/supabase/migrations/20251112113736_fix_search_path_functions.sql +74 -0
- package/supabase/migrations/20251112124444_fix_rls_performance.sql +63 -0
- package/supabase/migrations/20251112125935_fix_combined_policies.sql +194 -0
- package/supabase/migrations/20251112132146_fix_foreign_key_indexes.sql +21 -0
- package/supabase/migrations/20251112132525_cleanup_unused_indexes.sql +10 -0
- package/supabase/migrations/20251112132822_fix_final_indexes.sql +14 -0
- package/supabase/migrations/20251112140000_scaffold_foundational_content.sql +95 -0
- package/supabase/migrations/20251112141000_seed_homepage_blocks.sql +656 -0
- package/supabase/migrations/20251112142000_seed_how_it_works_post_blocks.sql +100 -0
- package/supabase/migrations/20251112143000_seed_additional_translations.sql +102 -0
- package/supabase/migrations/20251112145000_grant_public_schema_usage.sql +6 -0
- package/supabase/migrations/20251112145500_grant_select_on_public_tables.sql +19 -0
- package/supabase/migrations/20251117093000_add_admin_created_flag.sql +21 -0
- package/supabase/migrations/20251117103000_relax_profile_username_constraint.sql +6 -0
- package/supabase/migrations/20251117110000_relax_profiles_site_settings_rls_for_signup.sql +20 -0
- package/supabase/migrations/20251117112000_fix_handle_new_user_role_enum.sql +45 -0
- package/supabase/migrations/20251117113000_cleanup_rls_duplicates.sql +20 -0
- package/supabase/migrations/20251117200000_media_service_role_insert.sql +14 -0
- package/supabase/migrations/20251117201500_media_service_role_select.sql +11 -0
- package/supabase/migrations/20251117203000_media_admin_writer_select.sql +11 -0
- package/supabase/migrations/20251117204500_fix_media_permissions.sql +43 -0
- package/lib/supabase/client.d.ts +0 -9
- package/lib/supabase/middleware.d.ts +0 -2
- package/lib/supabase/server.d.ts +0 -7
- package/lib/supabase/ssg-client.d.ts +0 -2
- package/lib/supabase/types.d.ts +0 -635
|
@@ -0,0 +1,74 @@
|
|
|
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;
|
|
@@ -0,0 +1,63 @@
|
|
|
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;
|
|
@@ -0,0 +1,194 @@
|
|
|
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;
|
|
@@ -0,0 +1,21 @@
|
|
|
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;
|
|
@@ -0,0 +1,10 @@
|
|
|
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;
|
|
@@ -0,0 +1,14 @@
|
|
|
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;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
-- supabase/migrations/20251112140000_scaffold_foundational_content.sql
|
|
2
|
+
-- seeds additional languages plus the foundational Home/Articles pages and flagship post translations
|
|
3
|
+
|
|
4
|
+
do $migration$
|
|
5
|
+
declare
|
|
6
|
+
v_home_page_group_id uuid := gen_random_uuid();
|
|
7
|
+
v_blog_page_group_id uuid := gen_random_uuid();
|
|
8
|
+
v_how_it_works_post_group_id uuid := gen_random_uuid();
|
|
9
|
+
v_en_lang_id bigint;
|
|
10
|
+
v_fr_lang_id bigint;
|
|
11
|
+
v_feature_media_id uuid;
|
|
12
|
+
begin
|
|
13
|
+
-- only english and french
|
|
14
|
+
insert into public.languages (id, name, code, is_default, is_active)
|
|
15
|
+
values
|
|
16
|
+
(1, 'English', 'en', true, true),
|
|
17
|
+
(2, 'Français', 'fr', false, true)
|
|
18
|
+
on conflict (id) do update
|
|
19
|
+
set name = excluded.name,
|
|
20
|
+
code = excluded.code,
|
|
21
|
+
is_default = excluded.is_default,
|
|
22
|
+
is_active = excluded.is_active;
|
|
23
|
+
|
|
24
|
+
select id into v_en_lang_id from public.languages where code = 'en' limit 1;
|
|
25
|
+
select id into v_fr_lang_id from public.languages where code = 'fr' limit 1;
|
|
26
|
+
|
|
27
|
+
if v_en_lang_id is null or v_fr_lang_id is null then
|
|
28
|
+
raise exception 'Required languages (en, fr) not found. Please seed languages first.';
|
|
29
|
+
end if;
|
|
30
|
+
|
|
31
|
+
-- reset defaults/actives
|
|
32
|
+
update public.languages
|
|
33
|
+
set is_active = true,
|
|
34
|
+
is_default = case when code = 'en' then true else false end
|
|
35
|
+
where code in ('en', 'fr');
|
|
36
|
+
|
|
37
|
+
-- scaffold the Home and Articles parent pages (EN + FR)
|
|
38
|
+
insert into public.pages (language_id, title, slug, status, translation_group_id)
|
|
39
|
+
values (v_en_lang_id, 'Home', 'home', 'published', v_home_page_group_id)
|
|
40
|
+
on conflict (language_id, slug) do update
|
|
41
|
+
set title = excluded.title,
|
|
42
|
+
status = excluded.status,
|
|
43
|
+
translation_group_id = excluded.translation_group_id;
|
|
44
|
+
|
|
45
|
+
insert into public.pages (language_id, title, slug, status, translation_group_id)
|
|
46
|
+
values (v_fr_lang_id, 'Accueil', 'accueil', 'published', v_home_page_group_id)
|
|
47
|
+
on conflict (language_id, slug) do update
|
|
48
|
+
set title = excluded.title,
|
|
49
|
+
status = excluded.status,
|
|
50
|
+
translation_group_id = excluded.translation_group_id;
|
|
51
|
+
|
|
52
|
+
insert into public.pages (language_id, title, slug, status, translation_group_id)
|
|
53
|
+
values (v_en_lang_id, 'Articles', 'articles', 'published', v_blog_page_group_id)
|
|
54
|
+
on conflict (language_id, slug) do update
|
|
55
|
+
set title = excluded.title,
|
|
56
|
+
status = excluded.status,
|
|
57
|
+
translation_group_id = excluded.translation_group_id;
|
|
58
|
+
|
|
59
|
+
insert into public.pages (language_id, title, slug, status, translation_group_id)
|
|
60
|
+
values (v_fr_lang_id, 'Articles', 'articles', 'published', v_blog_page_group_id)
|
|
61
|
+
on conflict (language_id, slug) do update
|
|
62
|
+
set title = excluded.title,
|
|
63
|
+
status = excluded.status,
|
|
64
|
+
translation_group_id = excluded.translation_group_id;
|
|
65
|
+
|
|
66
|
+
-- seed the flagship How It Works blog post in EN + FR
|
|
67
|
+
insert into public.posts (language_id, title, slug, status, translation_group_id)
|
|
68
|
+
values (v_en_lang_id, 'How NextBlock Works: A Look Under the Hood', 'how-nextblock-works', 'published', v_how_it_works_post_group_id)
|
|
69
|
+
on conflict (language_id, slug) do update
|
|
70
|
+
set title = excluded.title,
|
|
71
|
+
status = excluded.status,
|
|
72
|
+
translation_group_id = excluded.translation_group_id;
|
|
73
|
+
|
|
74
|
+
insert into public.posts (language_id, title, slug, status, translation_group_id)
|
|
75
|
+
values (v_fr_lang_id, 'Comment NextBlock Fonctionne : Regard Sous le Capot', 'comment-nextblock-fonctionne', 'published', v_how_it_works_post_group_id)
|
|
76
|
+
on conflict (language_id, slug) do update
|
|
77
|
+
set title = excluded.title,
|
|
78
|
+
status = excluded.status,
|
|
79
|
+
translation_group_id = excluded.translation_group_id;
|
|
80
|
+
|
|
81
|
+
-- Feature image for the flagship post can be set later via CMS; no seed insert for static asset.
|
|
82
|
+
end;
|
|
83
|
+
$migration$;
|
|
84
|
+
|
|
85
|
+
select id as home_page_id
|
|
86
|
+
from public.pages
|
|
87
|
+
where slug = 'home' and language_id = (select id from public.languages where code = 'en' limit 1)
|
|
88
|
+
order by created_at desc
|
|
89
|
+
limit 1;
|
|
90
|
+
|
|
91
|
+
select id as post_id
|
|
92
|
+
from public.posts
|
|
93
|
+
where slug = 'how-nextblock-works' and language_id = (select id from public.languages where code = 'en' limit 1)
|
|
94
|
+
order by created_at desc
|
|
95
|
+
limit 1;
|