@nextblock-cms/db 0.11.3 → 0.12.1
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/lib/supabase/server.d.ts +9 -0
- package/lib/supabase/types.d.ts +9 -0
- package/package.json +1 -1
- package/supabase/migrations/00000000000000_baseline_schema.sql +2454 -0
- package/supabase/migrations/00000000000001_baseline_constraints_and_indexes.sql +1071 -0
- package/supabase/migrations/00000000000002_baseline_security_and_grants.sql +1335 -0
- package/supabase/migrations/00000000000003_baseline_seed.sql +468 -0
- package/supabase/migrations/00000000000004_default_logo_email_safe.sql +24 -0
- package/supabase/migrations/00000000000005_add_custom_canonical.sql +13 -0
- package/supabase/migrations/00000000000006_home_live_demo_promo.sql +67 -0
- package/supabase/migrations/00000000000007_home_live_demo_promo_copy_fix.sql +49 -0
- package/supabase/templates/confirmation.html +1 -1
- package/supabase/templates/email_change.html +1 -1
- package/supabase/templates/invite.html +1 -1
- package/supabase/templates/magic_link.html +1 -1
- package/supabase/templates/reauthentication.html +1 -1
- package/supabase/templates/recovery.html +1 -1
- package/supabase/migrations/00000000000000_setup_foundation_and_enums.sql +0 -40
- package/supabase/migrations/00000000000001_setup_cms_core.sql +0 -124
- package/supabase/migrations/00000000000002_setup_content_tables.sql +0 -138
- package/supabase/migrations/00000000000003_setup_catalog_and_licensing.sql +0 -160
- package/supabase/migrations/00000000000004_setup_fulfillment_shipping_taxes_and_currencies.sql +0 -797
- package/supabase/migrations/00000000000005_setup_functions_and_triggers.sql +0 -767
- package/supabase/migrations/00000000000006_setup_rls_and_grants.sql +0 -872
- package/supabase/migrations/00000000000007_setup_indexes.sql +0 -158
- package/supabase/migrations/00000000000008_seed_platform_defaults.sql +0 -155
- package/supabase/migrations/00000000000009_seed_translations.sql +0 -801
- package/supabase/migrations/00000000000010_seed_content_scaffold.sql +0 -1088
- package/supabase/migrations/00000000000011_setup_cortex_ai_settings.sql +0 -81
- package/supabase/migrations/00000000000012_setup_commerce_coupons.sql +0 -275
- package/supabase/migrations/00000000000013_setup_cortex_ai_db_mutation_audit.sql +0 -47
- package/supabase/migrations/00000000000014_setup_content_drafts.sql +0 -119
- package/supabase/migrations/00000000000015_setup_product_drafts.sql +0 -97
- package/supabase/migrations/00000000000016_add_feature_image_to_pages.sql +0 -8
- package/supabase/migrations/00000000000017_add_product_blocks.sql +0 -118
- package/supabase/migrations/00000000000018_setup_bot_protection_settings.sql +0 -77
- package/supabase/migrations/00000000000019_add_product_categories.sql +0 -64
- package/supabase/migrations/00000000000020_add_category_translations.sql +0 -10
- package/supabase/migrations/00000000000021_migrate_hero_blocks_to_sections.sql +0 -29
- package/supabase/migrations/00000000000022_seed_cortex_ai_guide_post.sql +0 -184
- package/supabase/migrations/00000000000023_setup_custom_block_definitions.sql +0 -183
- package/supabase/migrations/00000000000024_setup_ucp_cart_sessions.sql +0 -72
- package/supabase/migrations/00000000000025_add_sale_schedule_columns.sql +0 -406
- package/supabase/migrations/00000000000026_seed_on_sale_translation.sql +0 -9
- package/supabase/migrations/00000000000027_setup_privacy_and_mfa.sql +0 -479
- package/supabase/migrations/00000000000028_clear_advisor_warnings.sql +0 -93
- package/supabase/migrations/00000000000029_refresh_setup_article.sql +0 -252
- package/supabase/migrations/00000000000030_setup_system_configuration.sql +0 -80
- package/supabase/migrations/00000000000031_seed_footer_navigation.sql +0 -85
- package/supabase/migrations/00000000000032_neutralize_seeded_contact_emails.sql +0 -34
- package/supabase/migrations/00000000000033_setup_config_settings.sql +0 -99
- package/supabase/migrations/00000000000034_enable_staff_2fa_reminder_default.sql +0 -15
- package/supabase/migrations/00000000000035_reassert_advisor_fixes.sql +0 -33
- package/supabase/migrations/00000000000036_setup_system_alerts.sql +0 -72
- package/supabase/migrations/00000000000037_refresh_setup_article_install_paths.sql +0 -317
- package/supabase/migrations/00000000000038_seed_consent_banner_translations.sql +0 -126
- package/supabase/migrations/00000000000039_setup_interactions.sql +0 -153
- package/supabase/migrations/00000000000040_add_profiles_fk_to_interactions.sql +0 -8
- package/supabase/migrations/00000000000041_seed_interactions_translations.sql +0 -145
- package/supabase/migrations/00000000000042_seed_deploy_to_vercel_ctas.sql +0 -72
- package/supabase/migrations/00000000000043_swap_home_hero_media_to_youtube.sql +0 -42
- package/supabase/migrations/00000000000044_swap_article_nx_graph_for_youtube.sql +0 -66
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
-- 00000000000011_setup_cortex_ai_settings.sql
|
|
2
|
-
-- NextBlock Cortex AI settings and sensitive BYOK policy hardening.
|
|
3
|
-
|
|
4
|
-
COMMENT ON TABLE public.site_settings IS 'Key-value store for global site settings. Sensitive keys such as Cortex AI BYOK are protected by row-level policies.';
|
|
5
|
-
|
|
6
|
-
DROP POLICY IF EXISTS site_settings_read_policy ON public.site_settings;
|
|
7
|
-
DROP POLICY IF EXISTS site_settings_insert_policy ON public.site_settings;
|
|
8
|
-
DROP POLICY IF EXISTS site_settings_update_policy ON public.site_settings;
|
|
9
|
-
DROP POLICY IF EXISTS site_settings_delete_policy ON public.site_settings;
|
|
10
|
-
DROP POLICY IF EXISTS site_settings_sensitive_read_policy ON public.site_settings;
|
|
11
|
-
DROP POLICY IF EXISTS site_settings_sensitive_insert_policy ON public.site_settings;
|
|
12
|
-
DROP POLICY IF EXISTS site_settings_sensitive_update_policy ON public.site_settings;
|
|
13
|
-
DROP POLICY IF EXISTS site_settings_sensitive_delete_policy ON public.site_settings;
|
|
14
|
-
|
|
15
|
-
CREATE POLICY site_settings_read_policy
|
|
16
|
-
ON public.site_settings
|
|
17
|
-
FOR SELECT
|
|
18
|
-
TO public
|
|
19
|
-
USING (
|
|
20
|
-
key <> 'cortex_ai_openrouter_api_key'
|
|
21
|
-
OR (
|
|
22
|
-
key = 'cortex_ai_openrouter_api_key'
|
|
23
|
-
AND (SELECT auth.role()) = 'authenticated'
|
|
24
|
-
AND (SELECT public.get_current_user_role()) = 'ADMIN'
|
|
25
|
-
)
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
CREATE POLICY site_settings_insert_policy
|
|
29
|
-
ON public.site_settings
|
|
30
|
-
FOR INSERT
|
|
31
|
-
TO authenticated
|
|
32
|
-
WITH CHECK (
|
|
33
|
-
(
|
|
34
|
-
key <> 'cortex_ai_openrouter_api_key'
|
|
35
|
-
AND (SELECT public.get_current_user_role()) IN ('ADMIN', 'WRITER')
|
|
36
|
-
)
|
|
37
|
-
OR (
|
|
38
|
-
key = 'cortex_ai_openrouter_api_key'
|
|
39
|
-
AND (SELECT public.get_current_user_role()) = 'ADMIN'
|
|
40
|
-
)
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
CREATE POLICY site_settings_update_policy
|
|
44
|
-
ON public.site_settings
|
|
45
|
-
FOR UPDATE
|
|
46
|
-
TO authenticated
|
|
47
|
-
USING (
|
|
48
|
-
(
|
|
49
|
-
key <> 'cortex_ai_openrouter_api_key'
|
|
50
|
-
AND (SELECT public.get_current_user_role()) IN ('ADMIN', 'WRITER')
|
|
51
|
-
)
|
|
52
|
-
OR (
|
|
53
|
-
key = 'cortex_ai_openrouter_api_key'
|
|
54
|
-
AND (SELECT public.get_current_user_role()) = 'ADMIN'
|
|
55
|
-
)
|
|
56
|
-
)
|
|
57
|
-
WITH CHECK (
|
|
58
|
-
(
|
|
59
|
-
key <> 'cortex_ai_openrouter_api_key'
|
|
60
|
-
AND (SELECT public.get_current_user_role()) IN ('ADMIN', 'WRITER')
|
|
61
|
-
)
|
|
62
|
-
OR (
|
|
63
|
-
key = 'cortex_ai_openrouter_api_key'
|
|
64
|
-
AND (SELECT public.get_current_user_role()) = 'ADMIN'
|
|
65
|
-
)
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
CREATE POLICY site_settings_delete_policy
|
|
69
|
-
ON public.site_settings
|
|
70
|
-
FOR DELETE
|
|
71
|
-
TO authenticated
|
|
72
|
-
USING (
|
|
73
|
-
(
|
|
74
|
-
key <> 'cortex_ai_openrouter_api_key'
|
|
75
|
-
AND (SELECT public.get_current_user_role()) IN ('ADMIN', 'WRITER')
|
|
76
|
-
)
|
|
77
|
-
OR (
|
|
78
|
-
key = 'cortex_ai_openrouter_api_key'
|
|
79
|
-
AND (SELECT public.get_current_user_role()) = 'ADMIN'
|
|
80
|
-
)
|
|
81
|
-
);
|
|
@@ -1,275 +0,0 @@
|
|
|
1
|
-
-- 00000000000012_setup_commerce_coupons.sql
|
|
2
|
-
-- Unified commerce coupons for Stripe and Freemius checkout.
|
|
3
|
-
|
|
4
|
-
CREATE TABLE public.coupons (
|
|
5
|
-
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
6
|
-
code text NOT NULL,
|
|
7
|
-
name text NOT NULL,
|
|
8
|
-
internal_note text,
|
|
9
|
-
provider_scope text NOT NULL DEFAULT 'all',
|
|
10
|
-
discount_type text NOT NULL,
|
|
11
|
-
discount_amount integer NOT NULL,
|
|
12
|
-
is_active boolean NOT NULL DEFAULT true,
|
|
13
|
-
starts_at timestamptz,
|
|
14
|
-
ends_at timestamptz,
|
|
15
|
-
redemption_limit integer,
|
|
16
|
-
redemptions_count integer NOT NULL DEFAULT 0,
|
|
17
|
-
freemius_sync_status text NOT NULL DEFAULT 'not_synced',
|
|
18
|
-
freemius_sync_error text,
|
|
19
|
-
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20
|
-
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
21
|
-
CONSTRAINT coupons_code_not_blank CHECK (char_length(btrim(code)) > 0),
|
|
22
|
-
CONSTRAINT coupons_name_not_blank CHECK (char_length(btrim(name)) > 0),
|
|
23
|
-
CONSTRAINT coupons_provider_scope_valid
|
|
24
|
-
CHECK (provider_scope IN ('all', 'stripe', 'freemius')),
|
|
25
|
-
CONSTRAINT coupons_discount_type_valid
|
|
26
|
-
CHECK (discount_type IN ('percent', 'fixed')),
|
|
27
|
-
CONSTRAINT coupons_discount_amount_positive
|
|
28
|
-
CHECK (discount_amount > 0),
|
|
29
|
-
CONSTRAINT coupons_percent_amount_valid
|
|
30
|
-
CHECK (discount_type <> 'percent' OR discount_amount <= 100),
|
|
31
|
-
CONSTRAINT coupons_redemption_limit_positive
|
|
32
|
-
CHECK (redemption_limit IS NULL OR redemption_limit > 0),
|
|
33
|
-
CONSTRAINT coupons_redemptions_count_nonnegative
|
|
34
|
-
CHECK (redemptions_count >= 0),
|
|
35
|
-
CONSTRAINT coupons_date_window_valid
|
|
36
|
-
CHECK (starts_at IS NULL OR ends_at IS NULL OR starts_at < ends_at),
|
|
37
|
-
CONSTRAINT coupons_freemius_sync_status_valid
|
|
38
|
-
CHECK (freemius_sync_status IN ('not_synced', 'pending', 'synced', 'failed', 'not_required'))
|
|
39
|
-
);
|
|
40
|
-
|
|
41
|
-
CREATE UNIQUE INDEX coupons_code_unique
|
|
42
|
-
ON public.coupons (upper(code));
|
|
43
|
-
|
|
44
|
-
COMMENT ON TABLE public.coupons IS
|
|
45
|
-
'Unified commerce coupons managed by NextBlock CMS and applied through provider-aware checkout.';
|
|
46
|
-
COMMENT ON COLUMN public.coupons.provider_scope IS
|
|
47
|
-
'Provider eligibility: all, stripe, or freemius.';
|
|
48
|
-
COMMENT ON COLUMN public.coupons.discount_amount IS
|
|
49
|
-
'Percent value for percent coupons, or fixed minor-unit amount for fixed coupons.';
|
|
50
|
-
COMMENT ON COLUMN public.coupons.freemius_sync_status IS
|
|
51
|
-
'Aggregate status for syncing this coupon to Freemius product coupon records.';
|
|
52
|
-
|
|
53
|
-
CREATE TABLE public.coupon_products (
|
|
54
|
-
coupon_id uuid NOT NULL REFERENCES public.coupons(id) ON DELETE CASCADE,
|
|
55
|
-
product_id uuid NOT NULL REFERENCES public.products(id) ON DELETE CASCADE,
|
|
56
|
-
created_at timestamptz NOT NULL DEFAULT now(),
|
|
57
|
-
PRIMARY KEY (coupon_id, product_id)
|
|
58
|
-
);
|
|
59
|
-
|
|
60
|
-
COMMENT ON TABLE public.coupon_products IS
|
|
61
|
-
'Optional product allow-list for coupons. No rows means all products in the provider scope are eligible.';
|
|
62
|
-
|
|
63
|
-
CREATE TABLE public.coupon_freemius_mappings (
|
|
64
|
-
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
65
|
-
coupon_id uuid NOT NULL REFERENCES public.coupons(id) ON DELETE CASCADE,
|
|
66
|
-
product_id uuid REFERENCES public.products(id) ON DELETE SET NULL,
|
|
67
|
-
freemius_product_id text NOT NULL,
|
|
68
|
-
freemius_coupon_id text,
|
|
69
|
-
freemius_coupon_code text NOT NULL,
|
|
70
|
-
sync_status text NOT NULL DEFAULT 'pending',
|
|
71
|
-
sync_error text,
|
|
72
|
-
remote_payload jsonb,
|
|
73
|
-
last_synced_at timestamptz,
|
|
74
|
-
created_at timestamptz NOT NULL DEFAULT now(),
|
|
75
|
-
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
76
|
-
CONSTRAINT coupon_freemius_mappings_product_not_blank
|
|
77
|
-
CHECK (char_length(btrim(freemius_product_id)) > 0),
|
|
78
|
-
CONSTRAINT coupon_freemius_mappings_code_not_blank
|
|
79
|
-
CHECK (char_length(btrim(freemius_coupon_code)) > 0),
|
|
80
|
-
CONSTRAINT coupon_freemius_mappings_sync_status_valid
|
|
81
|
-
CHECK (sync_status IN ('pending', 'synced', 'failed', 'deleted'))
|
|
82
|
-
);
|
|
83
|
-
|
|
84
|
-
CREATE UNIQUE INDEX coupon_freemius_mappings_coupon_product_unique
|
|
85
|
-
ON public.coupon_freemius_mappings (coupon_id, freemius_product_id);
|
|
86
|
-
|
|
87
|
-
CREATE TABLE public.coupon_redemptions (
|
|
88
|
-
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
89
|
-
coupon_id uuid REFERENCES public.coupons(id) ON DELETE SET NULL,
|
|
90
|
-
order_id uuid REFERENCES public.orders(id) ON DELETE CASCADE,
|
|
91
|
-
coupon_code text NOT NULL,
|
|
92
|
-
provider text NOT NULL CHECK (provider IN ('stripe', 'freemius')),
|
|
93
|
-
discount_total integer NOT NULL DEFAULT 0 CHECK (discount_total >= 0),
|
|
94
|
-
user_id uuid REFERENCES auth.users(id) ON DELETE SET NULL,
|
|
95
|
-
customer_email text,
|
|
96
|
-
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
97
|
-
redeemed_at timestamptz NOT NULL DEFAULT now(),
|
|
98
|
-
CONSTRAINT coupon_redemptions_code_not_blank CHECK (char_length(btrim(coupon_code)) > 0)
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
CREATE UNIQUE INDEX coupon_redemptions_order_unique
|
|
102
|
-
ON public.coupon_redemptions (order_id)
|
|
103
|
-
WHERE order_id IS NOT NULL;
|
|
104
|
-
|
|
105
|
-
ALTER TABLE public.orders
|
|
106
|
-
ADD COLUMN coupon_id uuid REFERENCES public.coupons(id) ON DELETE SET NULL,
|
|
107
|
-
ADD COLUMN coupon_code text,
|
|
108
|
-
ADD COLUMN discount_total integer NOT NULL DEFAULT 0 CHECK (discount_total >= 0),
|
|
109
|
-
ADD COLUMN discount_details jsonb;
|
|
110
|
-
|
|
111
|
-
COMMENT ON COLUMN public.orders.coupon_code IS
|
|
112
|
-
'Coupon code applied to the order at checkout time.';
|
|
113
|
-
COMMENT ON COLUMN public.orders.discount_total IS
|
|
114
|
-
'Total discount applied to this order in the smallest currency unit.';
|
|
115
|
-
COMMENT ON COLUMN public.orders.discount_details IS
|
|
116
|
-
'Provider-aware coupon quote details captured at checkout.';
|
|
117
|
-
|
|
118
|
-
CREATE OR REPLACE FUNCTION public.handle_coupons_write()
|
|
119
|
-
RETURNS trigger
|
|
120
|
-
LANGUAGE plpgsql
|
|
121
|
-
SET search_path = ''
|
|
122
|
-
AS $$
|
|
123
|
-
BEGIN
|
|
124
|
-
NEW.code := upper(regexp_replace(btrim(NEW.code), '\s+', '', 'g'));
|
|
125
|
-
NEW.name := btrim(NEW.name);
|
|
126
|
-
NEW.provider_scope := lower(btrim(NEW.provider_scope));
|
|
127
|
-
NEW.discount_type := lower(btrim(NEW.discount_type));
|
|
128
|
-
NEW.freemius_sync_status := lower(btrim(COALESCE(NEW.freemius_sync_status, 'not_synced')));
|
|
129
|
-
NEW.updated_at := now();
|
|
130
|
-
|
|
131
|
-
IF NEW.created_at IS NULL THEN
|
|
132
|
-
NEW.created_at := now();
|
|
133
|
-
END IF;
|
|
134
|
-
|
|
135
|
-
RETURN NEW;
|
|
136
|
-
END;
|
|
137
|
-
$$;
|
|
138
|
-
|
|
139
|
-
CREATE OR REPLACE FUNCTION public.handle_coupon_freemius_mappings_write()
|
|
140
|
-
RETURNS trigger
|
|
141
|
-
LANGUAGE plpgsql
|
|
142
|
-
SET search_path = ''
|
|
143
|
-
AS $$
|
|
144
|
-
BEGIN
|
|
145
|
-
NEW.freemius_product_id := btrim(NEW.freemius_product_id);
|
|
146
|
-
NEW.freemius_coupon_code := upper(regexp_replace(btrim(NEW.freemius_coupon_code), '\s+', '', 'g'));
|
|
147
|
-
NEW.sync_status := lower(btrim(COALESCE(NEW.sync_status, 'pending')));
|
|
148
|
-
NEW.updated_at := now();
|
|
149
|
-
|
|
150
|
-
IF NEW.created_at IS NULL THEN
|
|
151
|
-
NEW.created_at := now();
|
|
152
|
-
END IF;
|
|
153
|
-
|
|
154
|
-
RETURN NEW;
|
|
155
|
-
END;
|
|
156
|
-
$$;
|
|
157
|
-
|
|
158
|
-
DROP TRIGGER IF EXISTS on_coupons_write ON public.coupons;
|
|
159
|
-
CREATE TRIGGER on_coupons_write
|
|
160
|
-
BEFORE INSERT OR UPDATE ON public.coupons
|
|
161
|
-
FOR EACH ROW
|
|
162
|
-
EXECUTE FUNCTION public.handle_coupons_write();
|
|
163
|
-
|
|
164
|
-
DROP TRIGGER IF EXISTS on_coupon_freemius_mappings_write ON public.coupon_freemius_mappings;
|
|
165
|
-
CREATE TRIGGER on_coupon_freemius_mappings_write
|
|
166
|
-
BEFORE INSERT OR UPDATE ON public.coupon_freemius_mappings
|
|
167
|
-
FOR EACH ROW
|
|
168
|
-
EXECUTE FUNCTION public.handle_coupon_freemius_mappings_write();
|
|
169
|
-
|
|
170
|
-
CREATE INDEX idx_coupons_active_dates
|
|
171
|
-
ON public.coupons (is_active, starts_at, ends_at);
|
|
172
|
-
|
|
173
|
-
CREATE INDEX idx_coupon_products_product_id
|
|
174
|
-
ON public.coupon_products (product_id);
|
|
175
|
-
|
|
176
|
-
CREATE INDEX idx_coupon_freemius_mappings_product_id
|
|
177
|
-
ON public.coupon_freemius_mappings (product_id)
|
|
178
|
-
WHERE product_id IS NOT NULL;
|
|
179
|
-
|
|
180
|
-
CREATE INDEX idx_coupon_freemius_mappings_freemius_product_id
|
|
181
|
-
ON public.coupon_freemius_mappings (freemius_product_id);
|
|
182
|
-
|
|
183
|
-
CREATE INDEX idx_coupon_redemptions_coupon_id
|
|
184
|
-
ON public.coupon_redemptions (coupon_id);
|
|
185
|
-
|
|
186
|
-
CREATE INDEX idx_coupon_redemptions_user_id
|
|
187
|
-
ON public.coupon_redemptions (user_id)
|
|
188
|
-
WHERE user_id IS NOT NULL;
|
|
189
|
-
|
|
190
|
-
CREATE INDEX idx_orders_coupon_id
|
|
191
|
-
ON public.orders (coupon_id)
|
|
192
|
-
WHERE coupon_id IS NOT NULL;
|
|
193
|
-
|
|
194
|
-
ALTER TABLE public.coupons ENABLE ROW LEVEL SECURITY;
|
|
195
|
-
ALTER TABLE public.coupon_products ENABLE ROW LEVEL SECURITY;
|
|
196
|
-
ALTER TABLE public.coupon_freemius_mappings ENABLE ROW LEVEL SECURITY;
|
|
197
|
-
ALTER TABLE public.coupon_redemptions ENABLE ROW LEVEL SECURITY;
|
|
198
|
-
|
|
199
|
-
GRANT ALL ON public.coupons TO authenticated, service_role;
|
|
200
|
-
GRANT ALL ON public.coupon_products TO authenticated, service_role;
|
|
201
|
-
GRANT ALL ON public.coupon_freemius_mappings TO authenticated, service_role;
|
|
202
|
-
GRANT ALL ON public.coupon_redemptions TO authenticated, service_role;
|
|
203
|
-
|
|
204
|
-
CREATE POLICY coupons_admin_select_policy
|
|
205
|
-
ON public.coupons
|
|
206
|
-
FOR SELECT
|
|
207
|
-
TO authenticated
|
|
208
|
-
USING (((SELECT public.is_admin()) IS TRUE));
|
|
209
|
-
|
|
210
|
-
CREATE POLICY coupons_admin_insert_policy
|
|
211
|
-
ON public.coupons
|
|
212
|
-
FOR INSERT
|
|
213
|
-
TO authenticated
|
|
214
|
-
WITH CHECK (((SELECT public.is_admin()) IS TRUE));
|
|
215
|
-
|
|
216
|
-
CREATE POLICY coupons_admin_update_policy
|
|
217
|
-
ON public.coupons
|
|
218
|
-
FOR UPDATE
|
|
219
|
-
TO authenticated
|
|
220
|
-
USING (((SELECT public.is_admin()) IS TRUE))
|
|
221
|
-
WITH CHECK (((SELECT public.is_admin()) IS TRUE));
|
|
222
|
-
|
|
223
|
-
CREATE POLICY coupons_admin_delete_policy
|
|
224
|
-
ON public.coupons
|
|
225
|
-
FOR DELETE
|
|
226
|
-
TO authenticated
|
|
227
|
-
USING (((SELECT public.is_admin()) IS TRUE));
|
|
228
|
-
|
|
229
|
-
CREATE POLICY coupons_service_role_policy
|
|
230
|
-
ON public.coupons
|
|
231
|
-
FOR ALL
|
|
232
|
-
TO service_role
|
|
233
|
-
USING (true)
|
|
234
|
-
WITH CHECK (true);
|
|
235
|
-
|
|
236
|
-
CREATE POLICY coupon_products_admin_policy
|
|
237
|
-
ON public.coupon_products
|
|
238
|
-
FOR ALL
|
|
239
|
-
TO authenticated
|
|
240
|
-
USING (((SELECT public.is_admin()) IS TRUE))
|
|
241
|
-
WITH CHECK (((SELECT public.is_admin()) IS TRUE));
|
|
242
|
-
|
|
243
|
-
CREATE POLICY coupon_products_service_role_policy
|
|
244
|
-
ON public.coupon_products
|
|
245
|
-
FOR ALL
|
|
246
|
-
TO service_role
|
|
247
|
-
USING (true)
|
|
248
|
-
WITH CHECK (true);
|
|
249
|
-
|
|
250
|
-
CREATE POLICY coupon_freemius_mappings_admin_policy
|
|
251
|
-
ON public.coupon_freemius_mappings
|
|
252
|
-
FOR ALL
|
|
253
|
-
TO authenticated
|
|
254
|
-
USING (((SELECT public.is_admin()) IS TRUE))
|
|
255
|
-
WITH CHECK (((SELECT public.is_admin()) IS TRUE));
|
|
256
|
-
|
|
257
|
-
CREATE POLICY coupon_freemius_mappings_service_role_policy
|
|
258
|
-
ON public.coupon_freemius_mappings
|
|
259
|
-
FOR ALL
|
|
260
|
-
TO service_role
|
|
261
|
-
USING (true)
|
|
262
|
-
WITH CHECK (true);
|
|
263
|
-
|
|
264
|
-
CREATE POLICY coupon_redemptions_admin_select_policy
|
|
265
|
-
ON public.coupon_redemptions
|
|
266
|
-
FOR SELECT
|
|
267
|
-
TO authenticated
|
|
268
|
-
USING (((SELECT public.is_admin()) IS TRUE));
|
|
269
|
-
|
|
270
|
-
CREATE POLICY coupon_redemptions_service_role_policy
|
|
271
|
-
ON public.coupon_redemptions
|
|
272
|
-
FOR ALL
|
|
273
|
-
TO service_role
|
|
274
|
-
USING (true)
|
|
275
|
-
WITH CHECK (true);
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
-- 00000000000013_setup_cortex_ai_db_mutation_audit.sql
|
|
2
|
-
-- Durable audit trail for confirmed Cortex AI database mutations.
|
|
3
|
-
|
|
4
|
-
CREATE TABLE IF NOT EXISTS public.cortex_ai_db_mutation_audit (
|
|
5
|
-
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
6
|
-
actor_user_id uuid REFERENCES public.profiles(id) ON DELETE SET NULL,
|
|
7
|
-
tool_name text NOT NULL,
|
|
8
|
-
action_name text NOT NULL,
|
|
9
|
-
target_tables text[] NOT NULL DEFAULT '{}'::text[],
|
|
10
|
-
operation_summary text NOT NULL,
|
|
11
|
-
payload_hash text NOT NULL,
|
|
12
|
-
payload jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
13
|
-
preview jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
14
|
-
status text NOT NULL CHECK (status IN ('success', 'failure')),
|
|
15
|
-
error_message text,
|
|
16
|
-
created_at timestamptz NOT NULL DEFAULT now()
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
COMMENT ON TABLE public.cortex_ai_db_mutation_audit IS
|
|
20
|
-
'Audit trail for confirmed Cortex AI database mutation attempts.';
|
|
21
|
-
COMMENT ON COLUMN public.cortex_ai_db_mutation_audit.payload IS
|
|
22
|
-
'Redacted tool input payload for the confirmed mutation attempt.';
|
|
23
|
-
COMMENT ON COLUMN public.cortex_ai_db_mutation_audit.preview IS
|
|
24
|
-
'Redacted confirmation preview shown before the mutation was confirmed.';
|
|
25
|
-
|
|
26
|
-
ALTER TABLE public.cortex_ai_db_mutation_audit ENABLE ROW LEVEL SECURITY;
|
|
27
|
-
|
|
28
|
-
GRANT SELECT, INSERT ON public.cortex_ai_db_mutation_audit TO authenticated, service_role;
|
|
29
|
-
|
|
30
|
-
DROP POLICY IF EXISTS cortex_ai_db_mutation_audit_admin_read_policy
|
|
31
|
-
ON public.cortex_ai_db_mutation_audit;
|
|
32
|
-
|
|
33
|
-
CREATE POLICY cortex_ai_db_mutation_audit_admin_read_policy
|
|
34
|
-
ON public.cortex_ai_db_mutation_audit
|
|
35
|
-
FOR SELECT
|
|
36
|
-
TO authenticated
|
|
37
|
-
USING ((SELECT public.get_current_user_role()) = 'ADMIN');
|
|
38
|
-
|
|
39
|
-
DROP POLICY IF EXISTS cortex_ai_db_mutation_audit_service_role_policy
|
|
40
|
-
ON public.cortex_ai_db_mutation_audit;
|
|
41
|
-
|
|
42
|
-
CREATE POLICY cortex_ai_db_mutation_audit_service_role_policy
|
|
43
|
-
ON public.cortex_ai_db_mutation_audit
|
|
44
|
-
FOR ALL
|
|
45
|
-
TO service_role
|
|
46
|
-
USING (true)
|
|
47
|
-
WITH CHECK (true);
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
-- 00000000000014_setup_content_drafts.sql
|
|
2
|
-
-- Draft snapshots for front-end visual editing.
|
|
3
|
-
|
|
4
|
-
CREATE TABLE IF NOT EXISTS public.content_drafts (
|
|
5
|
-
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
6
|
-
parent_type text NOT NULL CHECK (parent_type IN ('page', 'post')),
|
|
7
|
-
parent_id bigint NOT NULL,
|
|
8
|
-
author_id uuid REFERENCES public.profiles(id) ON DELETE SET NULL,
|
|
9
|
-
base_version integer NOT NULL DEFAULT 1,
|
|
10
|
-
meta jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
11
|
-
blocks jsonb NOT NULL DEFAULT '[]'::jsonb,
|
|
12
|
-
created_at timestamptz NOT NULL DEFAULT now(),
|
|
13
|
-
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
14
|
-
CONSTRAINT content_drafts_parent_unique UNIQUE (parent_type, parent_id),
|
|
15
|
-
CONSTRAINT content_drafts_blocks_array CHECK (jsonb_typeof(blocks) = 'array'),
|
|
16
|
-
CONSTRAINT content_drafts_meta_object CHECK (jsonb_typeof(meta) = 'object')
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
ALTER TABLE public.content_drafts
|
|
20
|
-
ADD COLUMN IF NOT EXISTS parent_type text,
|
|
21
|
-
ADD COLUMN IF NOT EXISTS parent_id bigint,
|
|
22
|
-
ADD COLUMN IF NOT EXISTS author_id uuid REFERENCES public.profiles(id) ON DELETE SET NULL,
|
|
23
|
-
ADD COLUMN IF NOT EXISTS base_version integer NOT NULL DEFAULT 1,
|
|
24
|
-
ADD COLUMN IF NOT EXISTS meta jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
25
|
-
ADD COLUMN IF NOT EXISTS blocks jsonb NOT NULL DEFAULT '[]'::jsonb,
|
|
26
|
-
ADD COLUMN IF NOT EXISTS created_at timestamptz NOT NULL DEFAULT now(),
|
|
27
|
-
ADD COLUMN IF NOT EXISTS updated_at timestamptz NOT NULL DEFAULT now();
|
|
28
|
-
|
|
29
|
-
DO $$
|
|
30
|
-
BEGIN
|
|
31
|
-
IF NOT EXISTS (
|
|
32
|
-
SELECT 1 FROM pg_constraint
|
|
33
|
-
WHERE conname = 'content_drafts_parent_unique'
|
|
34
|
-
AND conrelid = 'public.content_drafts'::regclass
|
|
35
|
-
) THEN
|
|
36
|
-
ALTER TABLE public.content_drafts
|
|
37
|
-
ADD CONSTRAINT content_drafts_parent_unique UNIQUE (parent_type, parent_id);
|
|
38
|
-
END IF;
|
|
39
|
-
|
|
40
|
-
IF NOT EXISTS (
|
|
41
|
-
SELECT 1 FROM pg_constraint
|
|
42
|
-
WHERE conname = 'content_drafts_blocks_array'
|
|
43
|
-
AND conrelid = 'public.content_drafts'::regclass
|
|
44
|
-
) THEN
|
|
45
|
-
ALTER TABLE public.content_drafts
|
|
46
|
-
ADD CONSTRAINT content_drafts_blocks_array CHECK (jsonb_typeof(blocks) = 'array');
|
|
47
|
-
END IF;
|
|
48
|
-
|
|
49
|
-
IF NOT EXISTS (
|
|
50
|
-
SELECT 1 FROM pg_constraint
|
|
51
|
-
WHERE conname = 'content_drafts_meta_object'
|
|
52
|
-
AND conrelid = 'public.content_drafts'::regclass
|
|
53
|
-
) THEN
|
|
54
|
-
ALTER TABLE public.content_drafts
|
|
55
|
-
ADD CONSTRAINT content_drafts_meta_object CHECK (jsonb_typeof(meta) = 'object');
|
|
56
|
-
END IF;
|
|
57
|
-
END $$;
|
|
58
|
-
|
|
59
|
-
COMMENT ON TABLE public.content_drafts IS
|
|
60
|
-
'Draft snapshots used by Draft Mode and front-end visual editing before publishing to live page/post rows.';
|
|
61
|
-
COMMENT ON COLUMN public.content_drafts.parent_type IS
|
|
62
|
-
'The content table this draft belongs to: page or post.';
|
|
63
|
-
COMMENT ON COLUMN public.content_drafts.parent_id IS
|
|
64
|
-
'ID of the page or post being drafted.';
|
|
65
|
-
COMMENT ON COLUMN public.content_drafts.base_version IS
|
|
66
|
-
'Published page/post version the draft was created from.';
|
|
67
|
-
COMMENT ON COLUMN public.content_drafts.meta IS
|
|
68
|
-
'Draft page/post metadata snapshot.';
|
|
69
|
-
COMMENT ON COLUMN public.content_drafts.blocks IS
|
|
70
|
-
'Ordered draft block snapshot, including block ids, block types, content, language ids, and order values.';
|
|
71
|
-
|
|
72
|
-
CREATE INDEX IF NOT EXISTS content_drafts_author_id_idx ON public.content_drafts (author_id);
|
|
73
|
-
CREATE INDEX IF NOT EXISTS content_drafts_parent_idx ON public.content_drafts (parent_type, parent_id);
|
|
74
|
-
CREATE INDEX IF NOT EXISTS content_drafts_updated_at_idx ON public.content_drafts (updated_at DESC);
|
|
75
|
-
|
|
76
|
-
DROP TRIGGER IF EXISTS on_content_drafts_update ON public.content_drafts;
|
|
77
|
-
CREATE TRIGGER on_content_drafts_update
|
|
78
|
-
BEFORE UPDATE ON public.content_drafts
|
|
79
|
-
FOR EACH ROW
|
|
80
|
-
EXECUTE FUNCTION public.set_current_timestamp_updated_at();
|
|
81
|
-
|
|
82
|
-
ALTER TABLE public.content_drafts ENABLE ROW LEVEL SECURITY;
|
|
83
|
-
|
|
84
|
-
DROP POLICY IF EXISTS content_drafts_select_policy
|
|
85
|
-
ON public.content_drafts;
|
|
86
|
-
|
|
87
|
-
CREATE POLICY content_drafts_select_policy
|
|
88
|
-
ON public.content_drafts
|
|
89
|
-
FOR SELECT
|
|
90
|
-
TO authenticated
|
|
91
|
-
USING ((SELECT public.get_current_user_role()) IN ('ADMIN', 'WRITER'));
|
|
92
|
-
|
|
93
|
-
DROP POLICY IF EXISTS content_drafts_insert_policy
|
|
94
|
-
ON public.content_drafts;
|
|
95
|
-
|
|
96
|
-
CREATE POLICY content_drafts_insert_policy
|
|
97
|
-
ON public.content_drafts
|
|
98
|
-
FOR INSERT
|
|
99
|
-
TO authenticated
|
|
100
|
-
WITH CHECK ((SELECT public.get_current_user_role()) IN ('ADMIN', 'WRITER'));
|
|
101
|
-
|
|
102
|
-
DROP POLICY IF EXISTS content_drafts_update_policy
|
|
103
|
-
ON public.content_drafts;
|
|
104
|
-
|
|
105
|
-
CREATE POLICY content_drafts_update_policy
|
|
106
|
-
ON public.content_drafts
|
|
107
|
-
FOR UPDATE
|
|
108
|
-
TO authenticated
|
|
109
|
-
USING ((SELECT public.get_current_user_role()) IN ('ADMIN', 'WRITER'))
|
|
110
|
-
WITH CHECK ((SELECT public.get_current_user_role()) IN ('ADMIN', 'WRITER'));
|
|
111
|
-
|
|
112
|
-
DROP POLICY IF EXISTS content_drafts_delete_policy
|
|
113
|
-
ON public.content_drafts;
|
|
114
|
-
|
|
115
|
-
CREATE POLICY content_drafts_delete_policy
|
|
116
|
-
ON public.content_drafts
|
|
117
|
-
FOR DELETE
|
|
118
|
-
TO authenticated
|
|
119
|
-
USING ((SELECT public.get_current_user_role()) IN ('ADMIN', 'WRITER'));
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
-- 00000000000015_setup_product_drafts.sql
|
|
2
|
-
-- Product draft snapshots for front-end visual editing.
|
|
3
|
-
|
|
4
|
-
CREATE TABLE IF NOT EXISTS public.product_drafts (
|
|
5
|
-
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
6
|
-
product_id uuid NOT NULL REFERENCES public.products(id) ON DELETE CASCADE,
|
|
7
|
-
author_id uuid REFERENCES public.profiles(id) ON DELETE SET NULL,
|
|
8
|
-
meta jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
9
|
-
created_at timestamptz NOT NULL DEFAULT now(),
|
|
10
|
-
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
11
|
-
CONSTRAINT product_drafts_product_unique UNIQUE (product_id),
|
|
12
|
-
CONSTRAINT product_drafts_meta_object CHECK (jsonb_typeof(meta) = 'object')
|
|
13
|
-
);
|
|
14
|
-
|
|
15
|
-
ALTER TABLE public.product_drafts
|
|
16
|
-
ADD COLUMN IF NOT EXISTS product_id uuid REFERENCES public.products(id) ON DELETE CASCADE,
|
|
17
|
-
ADD COLUMN IF NOT EXISTS author_id uuid REFERENCES public.profiles(id) ON DELETE SET NULL,
|
|
18
|
-
ADD COLUMN IF NOT EXISTS meta jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
19
|
-
ADD COLUMN IF NOT EXISTS created_at timestamptz NOT NULL DEFAULT now(),
|
|
20
|
-
ADD COLUMN IF NOT EXISTS updated_at timestamptz NOT NULL DEFAULT now();
|
|
21
|
-
|
|
22
|
-
DO $$
|
|
23
|
-
BEGIN
|
|
24
|
-
IF NOT EXISTS (
|
|
25
|
-
SELECT 1 FROM pg_constraint
|
|
26
|
-
WHERE conname = 'product_drafts_product_unique'
|
|
27
|
-
AND conrelid = 'public.product_drafts'::regclass
|
|
28
|
-
) THEN
|
|
29
|
-
ALTER TABLE public.product_drafts
|
|
30
|
-
ADD CONSTRAINT product_drafts_product_unique UNIQUE (product_id);
|
|
31
|
-
END IF;
|
|
32
|
-
|
|
33
|
-
IF NOT EXISTS (
|
|
34
|
-
SELECT 1 FROM pg_constraint
|
|
35
|
-
WHERE conname = 'product_drafts_meta_object'
|
|
36
|
-
AND conrelid = 'public.product_drafts'::regclass
|
|
37
|
-
) THEN
|
|
38
|
-
ALTER TABLE public.product_drafts
|
|
39
|
-
ADD CONSTRAINT product_drafts_meta_object CHECK (jsonb_typeof(meta) = 'object');
|
|
40
|
-
END IF;
|
|
41
|
-
END $$;
|
|
42
|
-
|
|
43
|
-
COMMENT ON TABLE public.product_drafts IS
|
|
44
|
-
'Draft product metadata snapshots used by Draft Mode and front-end visual editing before publishing to live product rows.';
|
|
45
|
-
COMMENT ON COLUMN public.product_drafts.product_id IS
|
|
46
|
-
'ID of the product being drafted.';
|
|
47
|
-
COMMENT ON COLUMN public.product_drafts.meta IS
|
|
48
|
-
'Draft product metadata snapshot. Front-end visual editing currently mutates visible title, short_description, and description_json fields.';
|
|
49
|
-
|
|
50
|
-
CREATE INDEX IF NOT EXISTS product_drafts_author_id_idx ON public.product_drafts (author_id);
|
|
51
|
-
CREATE INDEX IF NOT EXISTS product_drafts_product_id_idx ON public.product_drafts (product_id);
|
|
52
|
-
CREATE INDEX IF NOT EXISTS product_drafts_updated_at_idx ON public.product_drafts (updated_at DESC);
|
|
53
|
-
|
|
54
|
-
DROP TRIGGER IF EXISTS on_product_drafts_update ON public.product_drafts;
|
|
55
|
-
CREATE TRIGGER on_product_drafts_update
|
|
56
|
-
BEFORE UPDATE ON public.product_drafts
|
|
57
|
-
FOR EACH ROW
|
|
58
|
-
EXECUTE FUNCTION public.set_current_timestamp_updated_at();
|
|
59
|
-
|
|
60
|
-
ALTER TABLE public.product_drafts ENABLE ROW LEVEL SECURITY;
|
|
61
|
-
|
|
62
|
-
DROP POLICY IF EXISTS product_drafts_select_policy
|
|
63
|
-
ON public.product_drafts;
|
|
64
|
-
|
|
65
|
-
CREATE POLICY product_drafts_select_policy
|
|
66
|
-
ON public.product_drafts
|
|
67
|
-
FOR SELECT
|
|
68
|
-
TO authenticated
|
|
69
|
-
USING ((SELECT public.get_current_user_role()) IN ('ADMIN', 'WRITER'));
|
|
70
|
-
|
|
71
|
-
DROP POLICY IF EXISTS product_drafts_insert_policy
|
|
72
|
-
ON public.product_drafts;
|
|
73
|
-
|
|
74
|
-
CREATE POLICY product_drafts_insert_policy
|
|
75
|
-
ON public.product_drafts
|
|
76
|
-
FOR INSERT
|
|
77
|
-
TO authenticated
|
|
78
|
-
WITH CHECK ((SELECT public.get_current_user_role()) IN ('ADMIN', 'WRITER'));
|
|
79
|
-
|
|
80
|
-
DROP POLICY IF EXISTS product_drafts_update_policy
|
|
81
|
-
ON public.product_drafts;
|
|
82
|
-
|
|
83
|
-
CREATE POLICY product_drafts_update_policy
|
|
84
|
-
ON public.product_drafts
|
|
85
|
-
FOR UPDATE
|
|
86
|
-
TO authenticated
|
|
87
|
-
USING ((SELECT public.get_current_user_role()) IN ('ADMIN', 'WRITER'))
|
|
88
|
-
WITH CHECK ((SELECT public.get_current_user_role()) IN ('ADMIN', 'WRITER'));
|
|
89
|
-
|
|
90
|
-
DROP POLICY IF EXISTS product_drafts_delete_policy
|
|
91
|
-
ON public.product_drafts;
|
|
92
|
-
|
|
93
|
-
CREATE POLICY product_drafts_delete_policy
|
|
94
|
-
ON public.product_drafts
|
|
95
|
-
FOR DELETE
|
|
96
|
-
TO authenticated
|
|
97
|
-
USING ((SELECT public.get_current_user_role()) IN ('ADMIN', 'WRITER'));
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
ALTER TABLE public.pages
|
|
2
|
-
ADD COLUMN IF NOT EXISTS feature_image_id uuid REFERENCES public.media(id) ON DELETE SET NULL;
|
|
3
|
-
|
|
4
|
-
COMMENT ON COLUMN public.pages.feature_image_id IS
|
|
5
|
-
'ID of the media item to be used as the page feature image.';
|
|
6
|
-
|
|
7
|
-
CREATE INDEX IF NOT EXISTS idx_pages_feature_image_id
|
|
8
|
-
ON public.pages (feature_image_id);
|