@nextblock-cms/db 0.2.32 → 0.8.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/cache-Bb4TkKGq.js +38 -0
- package/cache-D0Q6YeSV.mjs +10150 -0
- package/index.cjs.js +1 -1
- package/index.es.js +66 -61
- package/package.json +1 -1
- package/server.cjs.js +1 -1
- package/server.es.js +48 -43
- package/supabase/config.toml +330 -319
- package/supabase/functions/import_map.json +6 -0
- package/supabase/functions/nextblock-migration-ingest/index.d.ts +1 -0
- package/supabase/functions/nextblock-migration-ingest/index.js +519 -0
- package/supabase/functions/nextblock-migration-ingest/index.js.map +7 -0
- package/supabase/functions/nextblock-migration-ingest/index.ts +646 -0
- package/supabase/migrations/00000000000000_setup_foundation_and_enums.sql +40 -0
- package/supabase/migrations/00000000000001_setup_cms_core.sql +124 -0
- package/supabase/migrations/00000000000002_setup_content_tables.sql +138 -0
- package/supabase/migrations/00000000000003_setup_catalog_and_licensing.sql +160 -0
- package/supabase/migrations/00000000000004_setup_fulfillment_shipping_taxes_and_currencies.sql +797 -0
- package/supabase/migrations/00000000000005_setup_functions_and_triggers.sql +767 -0
- package/supabase/migrations/00000000000006_setup_rls_and_grants.sql +872 -0
- package/supabase/migrations/00000000000007_setup_indexes.sql +158 -0
- package/supabase/migrations/00000000000008_seed_platform_defaults.sql +155 -0
- package/supabase/migrations/00000000000009_seed_translations.sql +801 -0
- package/supabase/migrations/00000000000010_seed_content_scaffold.sql +1088 -0
- package/supabase/migrations/00000000000011_setup_cortex_ai_settings.sql +81 -0
- package/supabase/migrations/00000000000012_setup_commerce_coupons.sql +275 -0
- package/supabase/migrations/00000000000013_setup_cortex_ai_db_mutation_audit.sql +47 -0
- package/supabase/migrations/00000000000014_setup_content_drafts.sql +119 -0
- package/supabase/migrations/00000000000015_setup_product_drafts.sql +97 -0
- package/supabase/migrations/00000000000016_add_feature_image_to_pages.sql +8 -0
- package/supabase/migrations/00000000000017_add_product_blocks.sql +118 -0
- package/supabase/migrations/00000000000018_setup_bot_protection_settings.sql +77 -0
- package/supabase/migrations/00000000000019_add_product_categories.sql +64 -0
- package/supabase/migrations/00000000000020_add_category_translations.sql +10 -0
- package/supabase/migrations/00000000000021_migrate_hero_blocks_to_sections.sql +29 -0
- package/supabase/migrations/00000000000022_seed_cortex_ai_guide_post.sql +184 -0
- package/supabase/migrations/00000000000023_setup_custom_block_definitions.sql +183 -0
- package/supabase/migrations/00000000000024_setup_ucp_cart_sessions.sql +72 -0
- package/supabase/migrations/00000000000025_add_sale_schedule_columns.sql +406 -0
- package/supabase/migrations/00000000000026_seed_on_sale_translation.sql +9 -0
- package/supabase/migrations/00000000000027_setup_privacy_and_mfa.sql +479 -0
- package/supabase/migrations/00000000000028_clear_advisor_warnings.sql +93 -0
- package/supabase/migrations/00000000000029_refresh_setup_article.sql +252 -0
- package/supabase/templates/confirmation.html +54 -0
- package/supabase/templates/email_change.html +53 -0
- package/supabase/templates/invite.html +53 -0
- package/supabase/templates/magic_link.html +53 -0
- package/supabase/templates/reauthentication.html +45 -0
- package/supabase/templates/recovery.html +54 -0
- package/index.d.ts +0 -4
- 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
- package/server.d.ts +0 -2
- package/ssg-client-CiaENGEv.js +0 -1
- package/ssg-client-DgUYZgPq.mjs +0 -8
- package/supabase/migrations/00000000000000_setup_extensions_and_roles.sql +0 -54
- package/supabase/migrations/00000000000001_setup_site_settings.sql +0 -19
- package/supabase/migrations/00000000000002_setup_profiles.sql +0 -87
- package/supabase/migrations/00000000000003_setup_languages.sql +0 -43
- package/supabase/migrations/00000000000004_setup_media.sql +0 -54
- package/supabase/migrations/00000000000005_setup_posts.sql +0 -56
- package/supabase/migrations/00000000000006_setup_pages.sql +0 -51
- package/supabase/migrations/00000000000007_setup_blocks.sql +0 -47
- package/supabase/migrations/00000000000008_setup_navigation.sql +0 -51
- package/supabase/migrations/00000000000009_setup_logos.sql +0 -13
- package/supabase/migrations/00000000000010_setup_translations.sql +0 -29
- package/supabase/migrations/00000000000011_setup_revisions.sql +0 -38
- package/supabase/migrations/00000000000012_setup_rls_policies.sql +0 -239
- package/supabase/migrations/00000000000013_seed_data.sql +0 -149
- package/supabase/migrations/00000000000014_seed_homepage_blocks.sql +0 -661
- package/supabase/migrations/00000000000015_seed_how_it_works.sql +0 -89
- package/supabase/migrations/00000000000016_sandbox_setup.sql +0 -834
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
-- 00000000000001_setup_cms_core.sql
|
|
2
|
+
-- Consolidated migration preserving original statement order within grouped sections.
|
|
3
|
+
|
|
4
|
+
-- 00000000000003_setup_site_settings_and_profiles.sql
|
|
5
|
+
-- Global settings, user profiles, and saved addresses.
|
|
6
|
+
|
|
7
|
+
CREATE TABLE public.site_settings (
|
|
8
|
+
key text PRIMARY KEY,
|
|
9
|
+
value jsonb
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
COMMENT ON TABLE public.site_settings IS 'Key-value store for global site settings.';
|
|
13
|
+
|
|
14
|
+
CREATE TABLE public.profiles (
|
|
15
|
+
id uuid PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
16
|
+
updated_at timestamptz,
|
|
17
|
+
full_name text,
|
|
18
|
+
avatar_url text,
|
|
19
|
+
website text,
|
|
20
|
+
github_username text,
|
|
21
|
+
phone text,
|
|
22
|
+
role public.user_role NOT NULL DEFAULT 'USER'
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
COMMENT ON TABLE public.profiles IS 'Profile information for each user, extending auth.users.';
|
|
26
|
+
COMMENT ON COLUMN public.profiles.id IS 'References auth.users.id';
|
|
27
|
+
COMMENT ON COLUMN public.profiles.role IS 'User role for RBAC.';
|
|
28
|
+
|
|
29
|
+
CREATE TABLE public.user_addresses (
|
|
30
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
31
|
+
user_id uuid NOT NULL REFERENCES public.profiles(id) ON DELETE CASCADE,
|
|
32
|
+
address_type text NOT NULL CHECK (address_type IN ('billing', 'shipping')),
|
|
33
|
+
is_default boolean NOT NULL DEFAULT false,
|
|
34
|
+
recipient_name text,
|
|
35
|
+
company_name text,
|
|
36
|
+
line1 text,
|
|
37
|
+
line2 text,
|
|
38
|
+
city text,
|
|
39
|
+
state text,
|
|
40
|
+
postal_code text,
|
|
41
|
+
country_code text,
|
|
42
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
43
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
COMMENT ON COLUMN public.user_addresses.company_name IS
|
|
47
|
+
'Optional company or organization name for the address.';
|
|
48
|
+
|
|
49
|
+
CREATE UNIQUE INDEX idx_user_addresses_one_default_per_type
|
|
50
|
+
ON public.user_addresses (user_id, address_type)
|
|
51
|
+
WHERE is_default = true;
|
|
52
|
+
|
|
53
|
+
-- 00000000000004_setup_languages_and_media.sql
|
|
54
|
+
-- Core locale and media tables.
|
|
55
|
+
|
|
56
|
+
CREATE TABLE public.languages (
|
|
57
|
+
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
58
|
+
code text NOT NULL UNIQUE,
|
|
59
|
+
name text NOT NULL,
|
|
60
|
+
is_default boolean NOT NULL DEFAULT false,
|
|
61
|
+
is_active boolean DEFAULT true,
|
|
62
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
63
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
COMMENT ON TABLE public.languages IS 'Stores supported languages for the CMS.';
|
|
67
|
+
COMMENT ON COLUMN public.languages.code IS 'BCP 47 language code.';
|
|
68
|
+
|
|
69
|
+
CREATE UNIQUE INDEX ensure_single_default_language_idx
|
|
70
|
+
ON public.languages (is_default)
|
|
71
|
+
WHERE is_default = true;
|
|
72
|
+
|
|
73
|
+
CREATE TABLE public.media (
|
|
74
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
75
|
+
uploader_id uuid REFERENCES public.profiles(id) ON DELETE SET NULL,
|
|
76
|
+
file_name text NOT NULL,
|
|
77
|
+
object_key text NOT NULL UNIQUE,
|
|
78
|
+
file_type text,
|
|
79
|
+
size_bytes bigint,
|
|
80
|
+
description text,
|
|
81
|
+
width integer,
|
|
82
|
+
height integer,
|
|
83
|
+
blur_data_url text,
|
|
84
|
+
variants jsonb,
|
|
85
|
+
file_path text,
|
|
86
|
+
folder text,
|
|
87
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
88
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
COMMENT ON TABLE public.media IS 'Stores information about uploaded media assets.';
|
|
92
|
+
COMMENT ON COLUMN public.media.object_key IS 'Unique key (path) in Cloudflare R2.';
|
|
93
|
+
COMMENT ON COLUMN public.media.width IS 'Width of the image in pixels.';
|
|
94
|
+
COMMENT ON COLUMN public.media.height IS 'Height of the image in pixels.';
|
|
95
|
+
COMMENT ON COLUMN public.media.blur_data_url IS 'Base64 encoded string for image blur placeholders.';
|
|
96
|
+
COMMENT ON COLUMN public.media.variants IS 'Array of image variant objects.';
|
|
97
|
+
COMMENT ON COLUMN public.media.file_path IS 'Full path to the file in the storage bucket.';
|
|
98
|
+
COMMENT ON COLUMN public.media.folder IS 'Folder path prefix for the R2 object.';
|
|
99
|
+
|
|
100
|
+
-- 00000000000005_setup_translations_and_branding.sql
|
|
101
|
+
-- Shared translation storage and logo metadata.
|
|
102
|
+
|
|
103
|
+
CREATE TABLE public.translations (
|
|
104
|
+
key text PRIMARY KEY,
|
|
105
|
+
translations jsonb NOT NULL,
|
|
106
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
107
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
COMMENT ON COLUMN public.translations.key IS
|
|
111
|
+
'A unique, slugified identifier (e.g., "sign_in_button_text").';
|
|
112
|
+
COMMENT ON COLUMN public.translations.translations IS
|
|
113
|
+
'Stores translations as key-value pairs (e.g., {"en": "Sign In", "fr": "S''inscrire"}).';
|
|
114
|
+
|
|
115
|
+
CREATE TABLE public.logos (
|
|
116
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
117
|
+
name text NOT NULL,
|
|
118
|
+
media_id uuid REFERENCES public.media(id) ON DELETE SET NULL,
|
|
119
|
+
created_at timestamptz NOT NULL DEFAULT now()
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
COMMENT ON TABLE public.logos IS 'Stores company and brand logos.';
|
|
123
|
+
COMMENT ON COLUMN public.logos.name IS 'The name of the brand or company for the logo.';
|
|
124
|
+
COMMENT ON COLUMN public.logos.media_id IS 'Foreign key to the media table for the logo image.';
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
-- 00000000000002_setup_content_tables.sql
|
|
2
|
+
-- Consolidated migration preserving original statement order within grouped sections.
|
|
3
|
+
|
|
4
|
+
-- 00000000000006_setup_pages_and_posts.sql
|
|
5
|
+
-- Page and post records.
|
|
6
|
+
|
|
7
|
+
CREATE TABLE public.posts (
|
|
8
|
+
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
9
|
+
language_id bigint NOT NULL REFERENCES public.languages(id) ON DELETE CASCADE,
|
|
10
|
+
author_id uuid REFERENCES public.profiles(id) ON DELETE SET NULL,
|
|
11
|
+
title text NOT NULL,
|
|
12
|
+
slug text NOT NULL,
|
|
13
|
+
label text,
|
|
14
|
+
excerpt text,
|
|
15
|
+
subtitle text,
|
|
16
|
+
status public.page_status NOT NULL DEFAULT 'draft',
|
|
17
|
+
published_at timestamptz,
|
|
18
|
+
meta_title text,
|
|
19
|
+
meta_description text,
|
|
20
|
+
feature_image_id uuid REFERENCES public.media(id) ON DELETE SET NULL,
|
|
21
|
+
version integer NOT NULL DEFAULT 1,
|
|
22
|
+
translation_group_id uuid NOT NULL DEFAULT gen_random_uuid(),
|
|
23
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
24
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
25
|
+
CONSTRAINT posts_language_id_slug_key UNIQUE (language_id, slug)
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
COMMENT ON TABLE public.posts IS 'Stores blog posts or news articles.';
|
|
29
|
+
COMMENT ON COLUMN public.posts.slug IS 'URL-friendly identifier, unique per language.';
|
|
30
|
+
COMMENT ON COLUMN public.posts.label IS
|
|
31
|
+
'Short editorial label rendered as a pill on post hero and article cards.';
|
|
32
|
+
COMMENT ON COLUMN public.posts.excerpt IS
|
|
33
|
+
'Short editorial summary used in post metadata rows and post cards.';
|
|
34
|
+
COMMENT ON COLUMN public.posts.subtitle IS
|
|
35
|
+
'Longer deck shown under the post title.';
|
|
36
|
+
COMMENT ON COLUMN public.posts.feature_image_id IS
|
|
37
|
+
'ID of the media item to be used as the feature image.';
|
|
38
|
+
COMMENT ON COLUMN public.posts.version IS 'Monotonic version number for hybrid revisions.';
|
|
39
|
+
COMMENT ON COLUMN public.posts.translation_group_id IS
|
|
40
|
+
'Groups different language versions of the same conceptual post.';
|
|
41
|
+
|
|
42
|
+
CREATE TABLE public.pages (
|
|
43
|
+
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
44
|
+
language_id bigint NOT NULL REFERENCES public.languages(id) ON DELETE CASCADE,
|
|
45
|
+
author_id uuid REFERENCES public.profiles(id) ON DELETE SET NULL,
|
|
46
|
+
title text NOT NULL,
|
|
47
|
+
slug text NOT NULL,
|
|
48
|
+
status public.page_status NOT NULL DEFAULT 'draft',
|
|
49
|
+
meta_title text,
|
|
50
|
+
meta_description text,
|
|
51
|
+
version integer NOT NULL DEFAULT 1,
|
|
52
|
+
translation_group_id uuid NOT NULL DEFAULT gen_random_uuid(),
|
|
53
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
54
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
55
|
+
CONSTRAINT pages_language_id_slug_key UNIQUE (language_id, slug)
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
COMMENT ON TABLE public.pages IS 'Stores static pages for the website.';
|
|
59
|
+
COMMENT ON COLUMN public.pages.slug IS 'URL-friendly identifier, unique per language.';
|
|
60
|
+
COMMENT ON COLUMN public.pages.version IS 'Monotonic version number for hybrid revisions.';
|
|
61
|
+
COMMENT ON COLUMN public.pages.translation_group_id IS
|
|
62
|
+
'Groups different language versions of the same conceptual page.';
|
|
63
|
+
|
|
64
|
+
-- 00000000000007_setup_blocks_and_navigation.sql
|
|
65
|
+
-- Content blocks and navigation trees.
|
|
66
|
+
|
|
67
|
+
CREATE TABLE public.blocks (
|
|
68
|
+
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
69
|
+
page_id bigint REFERENCES public.pages(id) ON DELETE CASCADE,
|
|
70
|
+
post_id bigint REFERENCES public.posts(id) ON DELETE CASCADE,
|
|
71
|
+
language_id bigint NOT NULL REFERENCES public.languages(id) ON DELETE CASCADE,
|
|
72
|
+
block_type text NOT NULL,
|
|
73
|
+
content jsonb,
|
|
74
|
+
"order" integer NOT NULL DEFAULT 0,
|
|
75
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
76
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
77
|
+
CONSTRAINT check_exactly_one_parent CHECK (
|
|
78
|
+
(page_id IS NOT NULL AND post_id IS NULL)
|
|
79
|
+
OR (post_id IS NOT NULL AND page_id IS NULL)
|
|
80
|
+
)
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
COMMENT ON TABLE public.blocks IS 'Stores content blocks for pages and posts.';
|
|
84
|
+
COMMENT ON COLUMN public.blocks.block_type IS
|
|
85
|
+
'Type of the block, e.g., "text", "image".';
|
|
86
|
+
COMMENT ON COLUMN public.blocks.content IS 'JSONB content specific to the block_type.';
|
|
87
|
+
COMMENT ON COLUMN public.blocks.order IS 'Sort order of the block.';
|
|
88
|
+
|
|
89
|
+
CREATE TABLE public.navigation_items (
|
|
90
|
+
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
91
|
+
language_id bigint NOT NULL REFERENCES public.languages(id) ON DELETE CASCADE,
|
|
92
|
+
menu_key public.menu_location NOT NULL,
|
|
93
|
+
label text NOT NULL,
|
|
94
|
+
url text NOT NULL,
|
|
95
|
+
parent_id bigint REFERENCES public.navigation_items(id) ON DELETE CASCADE,
|
|
96
|
+
"order" integer NOT NULL DEFAULT 0,
|
|
97
|
+
page_id bigint REFERENCES public.pages(id) ON DELETE SET NULL,
|
|
98
|
+
translation_group_id uuid NOT NULL DEFAULT gen_random_uuid(),
|
|
99
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
100
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
COMMENT ON TABLE public.navigation_items IS 'Stores navigation menu items.';
|
|
104
|
+
COMMENT ON COLUMN public.navigation_items.menu_key IS
|
|
105
|
+
'Identifies the menu this item belongs to.';
|
|
106
|
+
|
|
107
|
+
-- 00000000000008_setup_revisions.sql
|
|
108
|
+
-- Page and post revision history.
|
|
109
|
+
|
|
110
|
+
CREATE TABLE public.page_revisions (
|
|
111
|
+
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
112
|
+
page_id bigint NOT NULL REFERENCES public.pages(id) ON DELETE CASCADE,
|
|
113
|
+
author_id uuid REFERENCES public.profiles(id) ON DELETE SET NULL,
|
|
114
|
+
version integer NOT NULL,
|
|
115
|
+
revision_type public.revision_type NOT NULL,
|
|
116
|
+
content jsonb NOT NULL,
|
|
117
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
118
|
+
CONSTRAINT page_revisions_page_version_key UNIQUE (page_id, version)
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
COMMENT ON TABLE public.page_revisions IS 'Hybrid (snapshot/diff) revisions for pages.';
|
|
122
|
+
COMMENT ON COLUMN public.page_revisions.content IS
|
|
123
|
+
'If snapshot: full content; if diff: JSON Patch array.';
|
|
124
|
+
|
|
125
|
+
CREATE TABLE public.post_revisions (
|
|
126
|
+
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
127
|
+
post_id bigint NOT NULL REFERENCES public.posts(id) ON DELETE CASCADE,
|
|
128
|
+
author_id uuid REFERENCES public.profiles(id) ON DELETE SET NULL,
|
|
129
|
+
version integer NOT NULL,
|
|
130
|
+
revision_type public.revision_type NOT NULL,
|
|
131
|
+
content jsonb NOT NULL,
|
|
132
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
133
|
+
CONSTRAINT post_revisions_post_version_key UNIQUE (post_id, version)
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
COMMENT ON TABLE public.post_revisions IS 'Hybrid (snapshot/diff) revisions for posts.';
|
|
137
|
+
COMMENT ON COLUMN public.post_revisions.content IS
|
|
138
|
+
'If snapshot: full content; if diff: JSON Patch array.';
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
-- 00000000000003_setup_catalog_and_licensing.sql
|
|
2
|
+
-- Consolidated migration preserving original statement order within grouped sections.
|
|
3
|
+
|
|
4
|
+
-- 00000000000009_setup_products_and_media.sql
|
|
5
|
+
-- Core product catalog tables.
|
|
6
|
+
|
|
7
|
+
CREATE TABLE public.products (
|
|
8
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
9
|
+
language_id bigint NOT NULL REFERENCES public.languages(id) ON DELETE CASCADE,
|
|
10
|
+
translation_group_id uuid NOT NULL DEFAULT gen_random_uuid(),
|
|
11
|
+
sku text NOT NULL,
|
|
12
|
+
title text NOT NULL,
|
|
13
|
+
slug text NOT NULL,
|
|
14
|
+
product_type text NOT NULL CHECK (product_type IN ('physical', 'digital')),
|
|
15
|
+
payment_provider text NOT NULL CHECK (payment_provider IN ('stripe', 'freemius')),
|
|
16
|
+
price integer NOT NULL,
|
|
17
|
+
prices jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
18
|
+
sale_price integer,
|
|
19
|
+
sale_prices jsonb,
|
|
20
|
+
stock integer DEFAULT 0,
|
|
21
|
+
status text NOT NULL CHECK (status IN ('draft', 'active', 'archived')) DEFAULT 'draft',
|
|
22
|
+
meta_title text,
|
|
23
|
+
meta_description text,
|
|
24
|
+
short_description text,
|
|
25
|
+
description_json jsonb,
|
|
26
|
+
metadata jsonb,
|
|
27
|
+
freemius_plan_id text,
|
|
28
|
+
freemius_product_id text,
|
|
29
|
+
trial_period_days integer NOT NULL DEFAULT 0 CHECK (trial_period_days >= 0),
|
|
30
|
+
trial_requires_payment_method boolean NOT NULL DEFAULT false,
|
|
31
|
+
upc text,
|
|
32
|
+
is_taxable boolean NOT NULL DEFAULT true,
|
|
33
|
+
created_at timestamptz DEFAULT now(),
|
|
34
|
+
updated_at timestamptz DEFAULT now(),
|
|
35
|
+
CONSTRAINT products_type_provider_consistency_check CHECK (
|
|
36
|
+
(product_type = 'physical' AND payment_provider = 'stripe')
|
|
37
|
+
OR (product_type = 'digital' AND payment_provider = 'freemius')
|
|
38
|
+
),
|
|
39
|
+
CONSTRAINT products_language_id_slug_key UNIQUE (language_id, slug),
|
|
40
|
+
CONSTRAINT products_language_id_sku_key UNIQUE (language_id, sku)
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
COMMENT ON COLUMN public.products.is_taxable IS
|
|
44
|
+
'When true, this product participates in Stripe tax calculation.';
|
|
45
|
+
COMMENT ON COLUMN public.products.prices IS
|
|
46
|
+
'Regular prices by ISO 4217 code in the smallest currency unit.';
|
|
47
|
+
COMMENT ON COLUMN public.products.sale_prices IS
|
|
48
|
+
'Sale prices by ISO 4217 code in the smallest currency unit.';
|
|
49
|
+
|
|
50
|
+
CREATE TABLE public.product_media (
|
|
51
|
+
product_id uuid NOT NULL REFERENCES public.products(id) ON DELETE CASCADE,
|
|
52
|
+
media_id uuid NOT NULL REFERENCES public.media(id) ON DELETE CASCADE,
|
|
53
|
+
sort_order integer DEFAULT 0,
|
|
54
|
+
PRIMARY KEY (product_id, media_id)
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
-- 00000000000010_setup_product_variants_and_attributes.sql
|
|
58
|
+
-- Variant attributes, terms, and sellable variants.
|
|
59
|
+
|
|
60
|
+
CREATE TABLE public.product_attributes (
|
|
61
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
62
|
+
name text NOT NULL,
|
|
63
|
+
slug text NOT NULL UNIQUE,
|
|
64
|
+
name_translations jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
65
|
+
created_at timestamptz DEFAULT now(),
|
|
66
|
+
updated_at timestamptz DEFAULT now()
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
CREATE TABLE public.product_attribute_terms (
|
|
70
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
71
|
+
attribute_id uuid NOT NULL REFERENCES public.product_attributes(id) ON DELETE CASCADE,
|
|
72
|
+
value text NOT NULL,
|
|
73
|
+
slug text NOT NULL,
|
|
74
|
+
sort_order integer NOT NULL DEFAULT 0,
|
|
75
|
+
value_translations jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
76
|
+
created_at timestamptz DEFAULT now(),
|
|
77
|
+
updated_at timestamptz DEFAULT now(),
|
|
78
|
+
CONSTRAINT product_attribute_terms_attribute_id_slug_key UNIQUE (attribute_id, slug)
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
CREATE TABLE public.product_variants (
|
|
82
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
83
|
+
product_id uuid NOT NULL REFERENCES public.products(id) ON DELETE CASCADE,
|
|
84
|
+
sku text NOT NULL,
|
|
85
|
+
price_adjustment integer NOT NULL DEFAULT 0,
|
|
86
|
+
price integer NOT NULL DEFAULT 0,
|
|
87
|
+
prices jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
88
|
+
sale_price integer,
|
|
89
|
+
sale_prices jsonb,
|
|
90
|
+
stock_quantity integer NOT NULL DEFAULT 0,
|
|
91
|
+
upc text,
|
|
92
|
+
main_media_id uuid REFERENCES public.media(id) ON DELETE SET NULL,
|
|
93
|
+
created_at timestamptz DEFAULT now(),
|
|
94
|
+
updated_at timestamptz DEFAULT now(),
|
|
95
|
+
CONSTRAINT product_variants_product_id_sku_key UNIQUE (product_id, sku)
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
COMMENT ON COLUMN public.product_variants.prices IS
|
|
99
|
+
'Variant regular prices by ISO 4217 code in the smallest currency unit.';
|
|
100
|
+
COMMENT ON COLUMN public.product_variants.sale_prices IS
|
|
101
|
+
'Variant sale prices by ISO 4217 code in the smallest currency unit.';
|
|
102
|
+
|
|
103
|
+
CREATE TABLE public.inventory_items (
|
|
104
|
+
sku text PRIMARY KEY,
|
|
105
|
+
quantity integer NOT NULL DEFAULT 0 CHECK (quantity >= 0),
|
|
106
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
107
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
COMMENT ON TABLE public.inventory_items IS
|
|
111
|
+
'Source-of-truth inventory records keyed by sellable SKU.';
|
|
112
|
+
COMMENT ON COLUMN public.inventory_items.sku IS
|
|
113
|
+
'Global sellable SKU. Matching products or variants share inventory.';
|
|
114
|
+
COMMENT ON COLUMN public.inventory_items.quantity IS
|
|
115
|
+
'Available quantity for this SKU.';
|
|
116
|
+
|
|
117
|
+
CREATE TABLE public.variant_attribute_mapping (
|
|
118
|
+
variant_id uuid NOT NULL REFERENCES public.product_variants(id) ON DELETE CASCADE,
|
|
119
|
+
attribute_term_id uuid NOT NULL REFERENCES public.product_attribute_terms(id) ON DELETE CASCADE,
|
|
120
|
+
PRIMARY KEY (variant_id, attribute_term_id)
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
-- 00000000000011_setup_licensing_and_freemius.sql
|
|
124
|
+
-- Package activations and Freemius plan metadata.
|
|
125
|
+
|
|
126
|
+
CREATE TABLE public.package_activations (
|
|
127
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
128
|
+
license_key text NOT NULL,
|
|
129
|
+
instance_name text NOT NULL,
|
|
130
|
+
package_id text NOT NULL,
|
|
131
|
+
status text NOT NULL DEFAULT 'active',
|
|
132
|
+
meta jsonb DEFAULT '{}'::jsonb,
|
|
133
|
+
last_validated_at timestamptz DEFAULT now(),
|
|
134
|
+
created_at timestamptz DEFAULT now(),
|
|
135
|
+
UNIQUE (license_key, package_id)
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
CREATE TABLE public.freemius_plans (
|
|
139
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
140
|
+
product_id uuid NOT NULL REFERENCES public.products(id) ON DELETE CASCADE,
|
|
141
|
+
name text NOT NULL,
|
|
142
|
+
title text,
|
|
143
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
144
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
CREATE TABLE public.freemius_pricing (
|
|
148
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
149
|
+
plan_id uuid NOT NULL REFERENCES public.freemius_plans(id) ON DELETE CASCADE,
|
|
150
|
+
api_monthly_price numeric,
|
|
151
|
+
api_annual_price numeric,
|
|
152
|
+
api_lifetime_price numeric,
|
|
153
|
+
override_monthly_price numeric,
|
|
154
|
+
override_annual_price numeric,
|
|
155
|
+
override_lifetime_price numeric,
|
|
156
|
+
license_quota integer,
|
|
157
|
+
is_active boolean NOT NULL DEFAULT true,
|
|
158
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
159
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
160
|
+
);
|