@nextblock-cms/db 0.22.0 → 0.22.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/README.md +47 -47
- package/lib/supabase/server.d.ts +151 -2
- package/lib/supabase/types.d.ts +160 -2
- package/package.json +1 -1
- package/supabase/functions/nextblock-migration-ingest/index.ts +64 -1
- package/supabase/migrations/02000_catchup_gen1.sql +5880 -5880
- package/supabase/migrations/02001_baseline_schema.sql +2734 -2734
- package/supabase/migrations/02002_baseline_constraints_and_indexes.sql +1262 -1262
- package/supabase/migrations/02003_baseline_security_and_grants.sql +1577 -1577
- package/supabase/migrations/02004_baseline_seed.sql +565 -565
- package/supabase/migrations/02005_home_live_demo_promo_cadence_15min.sql +53 -53
- package/supabase/migrations/02006_home_marketing_contrast.sql +56 -56
- package/supabase/migrations/02007_home_pillar_caption_contrast.sql +44 -44
- package/supabase/migrations/02008_home_fr_parity.sql +89 -89
- package/supabase/migrations/02009_fr_cortex_posts.sql +67 -67
- package/supabase/migrations/02010_shop_hero_redesign.sql +72 -72
- package/supabase/migrations/02011_drop_backdrop_blur_on_pages.sql +26 -26
- package/supabase/migrations/02012_drop_variant_backdrop_blur.sql +17 -17
- package/supabase/migrations/02013_advisor_rls_and_trigger_grants.sql +102 -102
- package/supabase/migrations/02014_package_activations_staff_read.sql +18 -18
- package/supabase/migrations/02018_install_paths_and_seed_copy_accuracy.sql +1820 -1820
- package/supabase/migrations/02019_open_handed_licensing_and_mcp_clients.sql +448 -448
- package/supabase/migrations/02020_commerce_product_accuracy.sql +93 -93
- package/supabase/migrations/02021_profiles_staff_read_and_role_guard.sql +362 -362
- package/supabase/migrations/02022_security_hardening_writer_boundary_and_aal.sql +504 -0
- package/supabase/migrations/02023_aal2_for_orders_profiles_site_settings.sql +171 -0
|
@@ -1,93 +1,93 @@
|
|
|
1
|
-
-- 02020: Commerce Pro license product copy, EN + FR (vendor-only rows: nextblock.dev has them,
|
|
2
|
-
-- fresh installs do not, so this is a no-op everywhere else). Copy only; no schema.
|
|
3
|
-
--
|
|
4
|
-
-- The page claimed things the code does not do:
|
|
5
|
-
-- * "real-time exchange rates" -- rates are ECB reference rates from api.frankfurter.dev, refreshed
|
|
6
|
-
-- at most once a day from the CMS layout via after() (apps/nextblock/lib/commerce/currency-rates-refresh.ts),
|
|
7
|
-
-- with a "Sync Live Rates" button and the optional /api/cron/sync-currencies route. The Vercel cron
|
|
8
|
-
-- that used to run this was dropped because vercel.json ships to every 1-click install.
|
|
9
|
-
-- * "< 50ms Cart API Response" -- there is no cart API route at all.
|
|
10
|
-
-- * "135+ Currencies Supported" / "40+ Tax Jurisdictions" -- currencies are rows an operator creates,
|
|
11
|
-
-- and tax coverage is Stripe's, not ours.
|
|
12
|
-
-- * "Every API path is edge-cached" -- public pages come from the 5-minute content cache that clears
|
|
13
|
-
-- on publish; HTML is served must-revalidate.
|
|
14
|
-
-- * "optimistic locking" -- stock is deducted under SELECT ... FOR UPDATE (libs/ecommerce order-inventory.ts).
|
|
15
|
-
-- * "email notifications" -- no order email exists; orders produce printable invoices.
|
|
16
|
-
-- * "shares inventory and pricing" -- stock is shared through the SKU, prices are per language row.
|
|
17
|
-
-- The page also never mentioned the 30-day free trial, the French buttons pointed at the English
|
|
18
|
-
-- product, the cards skipped from h3 to h5, and neither language had SEO meta (45/100 in the audit;
|
|
19
|
-
-- the new copy scores 85). Same copy as apps/nextblock/app/api/cron/reset-sandbox/commerce-product-copy.ts,
|
|
20
|
-
-- which re-seeds the sandbox after every reset.
|
|
21
|
-
--
|
|
22
|
-
-- Guarded: each product is replaced only while it still carries the shipped signature, so a product
|
|
23
|
-
-- the vendor rewrote by hand is left alone (a NOTICE names it). Idempotent: the new signature stops
|
|
24
|
-
-- a second run.
|
|
25
|
-
--
|
|
26
|
-
-- NOTE: keep the word "sandbox" OUT of this filename -- generate-sandbox-reset.ts excludes any
|
|
27
|
-
-- migration whose filename contains "sandbox" from the reset bundle.
|
|
28
|
-
|
|
29
|
-
DO $nb_02020_products$
|
|
30
|
-
DECLARE
|
|
31
|
-
v_id uuid;
|
|
32
|
-
v_lang bigint;
|
|
33
|
-
BEGIN
|
|
34
|
-
|
|
35
|
-
-- English
|
|
36
|
-
v_id := NULL;
|
|
37
|
-
SELECT p.id, p.language_id INTO v_id, v_lang
|
|
38
|
-
FROM public.products AS p JOIN public.languages AS l ON l.id = p.language_id
|
|
39
|
-
WHERE p.slug = 'nextblock-commerce-pro-commerce-license' AND l.code = 'en'
|
|
40
|
-
ORDER BY p.id LIMIT 1;
|
|
41
|
-
IF v_id IS NOT NULL THEN
|
|
42
|
-
IF EXISTS (SELECT 1 FROM public.blocks WHERE product_id = v_id AND content::text LIKE $t$%Enterprise E-Commerce Engine%$t$)
|
|
43
|
-
AND NOT EXISTS (SELECT 1 FROM public.blocks WHERE product_id = v_id AND content::text LIKE $t$%Days free, no card%$t$) THEN
|
|
44
|
-
DELETE FROM public.blocks WHERE product_id = v_id;
|
|
45
|
-
INSERT INTO public.blocks (product_id, language_id, block_type, content, "order") VALUES
|
|
46
|
-
(v_id, v_lang, 'section', $nbcm0en${"padding":{"top":"xl","bottom":"xl"},"background":{"type":"gradient","gradient":{"type":"linear","stops":[{"color":"#022c22","position":0},{"color":"#064e3b","position":40},{"color":"#0f172a","position":100}],"direction":"135deg"}},"column_gap":"xl","column_blocks":[[{"content":{"html_content":"<p class=\"text-xs uppercase tracking-[0.3em] text-emerald-400 font-semibold mb-4\">Enterprise E-Commerce Engine</p>\n<h2 class=\"text-3xl md:text-5xl font-extrabold text-white leading-tight mb-5\">Turn Next.js Into a<br/>Global Storefront.</h2>\n<p class=\"text-base md:text-lg text-slate-200 leading-relaxed mb-6\">Commerce Pro is a composable, developer-first engine that powers physical product catalogs, digital licensing, and subscription commerce — all from your existing Next.js stack. Try it free for 30 days, no credit card.</p>"},"block_type":"text"},{"content":{"url":"https://nextblock.dev/product/nextblock-commerce-pro-commerce-license","size":"lg","text":"Get Commerce Pro →","variant":"default","position":"left"},"block_type":"button"}],[{"content":{"html_content":"<div class=\"rounded-2xl border border-emerald-700 bg-slate-950 p-6 shadow-xl sm:p-8\">\n<h3 class=\"text-lg font-bold text-white mb-5\">Why Teams Choose Commerce Pro</h3>\n<ul class=\"space-y-4 text-sm leading-relaxed text-slate-300\">\n <li class=\"flex items-start gap-3\">\n <span class=\"flex-shrink-0 w-6 h-6 rounded-full bg-emerald-950 flex items-center justify-center text-emerald-300 text-xs font-bold\">✓</span>\n <span><strong class=\"text-white\">Multi-Currency Pricing</strong> — daily exchange-rate sync, charm pricing rules, and a currency suggested by the visitor's locale.</span>\n </li>\n <li class=\"flex items-start gap-3\">\n <span class=\"flex-shrink-0 w-6 h-6 rounded-full bg-emerald-950 flex items-center justify-center text-emerald-300 text-xs font-bold\">✓</span>\n <span><strong class=\"text-white\">Tax Automation</strong> — switch on Stripe Tax and checkout calculates and collects tax for you, with the tax lines stored on every order.</span>\n </li>\n <li class=\"flex items-start gap-3\">\n <span class=\"flex-shrink-0 w-6 h-6 rounded-full bg-emerald-950 flex items-center justify-center text-emerald-300 text-xs font-bold\">✓</span>\n <span><strong class=\"text-white\">Resilient Stock Tracking</strong> — inventory locks at checkout to prevent over-selling, with per-variant control.</span>\n </li>\n <li class=\"flex items-start gap-3\">\n <span class=\"flex-shrink-0 w-6 h-6 rounded-full bg-emerald-950 flex items-center justify-center text-emerald-300 text-xs font-bold\">✓</span>\n <span><strong class=\"text-white\">Flexible Shipping Zones</strong> — rate tables, free-shipping thresholds, and per-country rules out of the box.</span>\n </li>\n</ul>\n</div>"},"block_type":"text"}]],"container_type":"container","responsive_columns":{"mobile":1,"tablet":1,"desktop":2},"vertical_alignment":"center"}$nbcm0en$::jsonb, 0),
|
|
47
|
-
(v_id, v_lang, 'section', $nbcm1en${"padding":{"top":"lg","bottom":"lg"},"background":{"type":"theme","theme":"muted"},"column_gap":"lg","column_blocks":[[{"content":{"html_content":"<p class=\"text-center\"><span class=\"block text-2xl font-extrabold text-foreground\">30</span><span class=\"text-xs text-muted-foreground uppercase tracking-wider\">Days free, no card</span></p>"},"block_type":"text"}],[{"content":{"html_content":"<p class=\"text-center\"><span class=\"block text-2xl font-extrabold text-foreground\">2</span><span class=\"text-xs text-muted-foreground uppercase tracking-wider\">Checkout providers</span></p>"},"block_type":"text"}],[{"content":{"html_content":"<p class=\"text-center\"><span class=\"block text-2xl font-extrabold text-foreground\">Daily</span><span class=\"text-xs text-muted-foreground uppercase tracking-wider\">Exchange-rate sync</span></p>"},"block_type":"text"}],[{"content":{"html_content":"<p class=\"text-center\"><span class=\"block text-2xl font-extrabold text-foreground\">EN + FR</span><span class=\"text-xs text-muted-foreground uppercase tracking-wider\">Linked storefronts</span></p>"},"block_type":"text"}]],"container_type":"container","responsive_columns":{"mobile":1,"tablet":2,"desktop":4},"vertical_alignment":"center"}$nbcm1en$::jsonb, 1),
|
|
48
|
-
(v_id, v_lang, 'section', $nbcm2en${"padding":{"top":"xl","bottom":"xl"},"background":{"type":"none"},"column_gap":"lg","column_blocks":[[{"content":{"html_content":"<div class=\"h-full rounded-2xl border border-slate-200 bg-white p-6 shadow-sm transition-colors hover:border-emerald-300 hover:bg-slate-50 dark:border-white/10 dark:bg-slate-950 dark:hover:border-emerald-500 sm:p-7\">\n<div class=\"mb-4 inline-flex h-10 w-10 items-center justify-center rounded-xl bg-emerald-50 text-emerald-700 dark:bg-emerald-950 dark:text-emerald-300\"><svg class=\"h-5 w-5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\"></rect><path d=\"M3 10h18M7 15h3\"></path></svg></div>\n<h4 class=\"text-base font-bold text-slate-900 dark:text-white mb-2\">Headless Stripe Checkout</h4>\n<p class=\"text-sm text-slate-600 dark:text-slate-300 leading-relaxed\">Integrated checkout session creation for single or multiple items. Auto-fulfillment fires via webhook events, with built-in idempotency guards.</p>\n</div>"},"block_type":"text"}],[{"content":{"html_content":"<div class=\"h-full rounded-2xl border border-slate-200 bg-white p-6 shadow-sm transition-colors hover:border-emerald-300 hover:bg-slate-50 dark:border-white/10 dark:bg-slate-950 dark:hover:border-emerald-500 sm:p-7\">\n<div class=\"mb-4 inline-flex h-10 w-10 items-center justify-center rounded-xl bg-emerald-50 text-emerald-700 dark:bg-emerald-950 dark:text-emerald-300\"><svg class=\"h-5 w-5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M15 7a4 4 0 1 1-2.83 6.83L7 19H4v-3h3l2.17-2.17A4 4 0 0 1 15 7Z\"></path><path d=\"M17.5 8.5h.01\"></path></svg></div>\n<h4 class=\"text-base font-bold text-slate-900 dark:text-white mb-2\">Freemius Digital Licensing</h4>\n<p class=\"text-sm text-slate-600 dark:text-slate-300 leading-relaxed\">Distribute software downloads, validate license keys, and manage SaaS trial periods natively — no third-party integration layer required.</p>\n</div>"},"block_type":"text"}],[{"content":{"html_content":"<div class=\"h-full rounded-2xl border border-slate-200 bg-white p-6 shadow-sm transition-colors hover:border-emerald-300 hover:bg-slate-50 dark:border-white/10 dark:bg-slate-950 dark:hover:border-emerald-500 sm:p-7\">\n<div class=\"mb-4 inline-flex h-10 w-10 items-center justify-center rounded-xl bg-emerald-50 text-emerald-700 dark:bg-emerald-950 dark:text-emerald-300\"><svg class=\"h-5 w-5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><rect x=\"4\" y=\"5\" width=\"16\" height=\"14\" rx=\"2\"></rect><path d=\"m4 15 4-4 4 4 3-3 5 5\"></path><circle cx=\"15\" cy=\"9\" r=\"1\"></circle></svg></div>\n<h4 class=\"text-base font-bold text-slate-900 dark:text-white mb-2\">Visual Merchandising</h4>\n<p class=\"text-sm text-slate-600 dark:text-slate-300 leading-relaxed\">Content creators can add product details pages, highlight promotions, and build full landing pages — all inside the block editor, no code needed.</p>\n</div>"},"block_type":"text"}]],"container_type":"container","responsive_columns":{"mobile":1,"tablet":2,"desktop":3},"vertical_alignment":"stretch"}$nbcm2en$::jsonb, 2),
|
|
49
|
-
(v_id, v_lang, 'section', $nbcm3en${"padding":{"top":"xl","bottom":"xl"},"background":{"type":"gradient","gradient":{"type":"linear","stops":[{"color":"#020617","position":0},{"color":"#0f172a","position":100}],"direction":"180deg"}},"column_gap":"xl","column_blocks":[[{"content":{"html_content":"<p class=\"text-xs uppercase tracking-[0.3em] text-emerald-400 font-semibold mb-4\">Under The Hood</p>\n<h3 class=\"text-2xl md:text-3xl font-extrabold text-white mb-4\">Built for Production Scale</h3>\n<p class=\"text-slate-300 leading-relaxed mb-5\">Commerce Pro was designed from day one for high-traffic stores. Store pages come from a public content cache that clears the moment you publish, every database query is indexed, and every webhook handler is idempotent.</p>\n<ul class=\"space-y-3 text-sm text-slate-400\">\n <li class=\"flex items-start gap-2.5\">\n <span class=\"text-emerald-400\">→</span>\n <span>Variant-level inventory with row-locked stock deduction</span>\n </li>\n <li class=\"flex items-start gap-2.5\">\n <span class=\"text-emerald-400\">→</span>\n <span>Automatic shipping zone calculation and rate tables</span>\n </li>\n <li class=\"flex items-start gap-2.5\">\n <span class=\"text-emerald-400\">→</span>\n <span>Real-time order status with Stripe webhook sync</span>\n </li>\n <li class=\"flex items-start gap-2.5\">\n <span class=\"text-emerald-400\">→</span>\n <span>Product attributes and filterable facets system</span>\n </li>\n</ul>"},"block_type":"text"}],[{"content":{"html_content":"<div class=\"space-y-4\">\n<div class=\"p-5 rounded-xl border border-slate-700 bg-slate-900\">\n <h4 class=\"text-sm font-bold text-white mb-1\">Order Management</h4>\n <p class=\"text-xs text-slate-400 leading-relaxed\">Full order lifecycle from cart to fulfillment. Automatic status transitions, printable invoices, and refund handling baked in.</p>\n</div>\n<div class=\"p-5 rounded-xl border border-slate-700 bg-slate-900\">\n <h4 class=\"text-sm font-bold text-white mb-1\">Product Categories</h4>\n <p class=\"text-xs text-slate-400 leading-relaxed\">Hierarchical taxonomy with slugs, media attachments, and full i18n support. Categories are managed directly in the CMS dashboard.</p>\n</div>\n<div class=\"p-5 rounded-xl border border-slate-700 bg-slate-900\">\n <h4 class=\"text-sm font-bold text-white mb-1\">Multi-Language Storefronts</h4>\n <p class=\"text-xs text-slate-400 leading-relaxed\">Products, categories, and checkout flows are fully translatable. Each language variant keeps its own prices and SEO metadata, and shares stock with its twins through the product SKU.</p>\n</div>\n</div>"},"block_type":"text"}]],"container_type":"container","responsive_columns":{"mobile":1,"tablet":1,"desktop":2},"vertical_alignment":"center"}$nbcm3en$::jsonb, 3),
|
|
50
|
-
(v_id, v_lang, 'section', $nbcm4en${"padding":{"top":"xl","bottom":"xl"},"background":{"type":"gradient","gradient":{"type":"linear","stops":[{"color":"#064e3b","position":0},{"color":"#022c22","position":100}],"direction":"135deg"}},"column_gap":"none","column_blocks":[[{"content":{"level":2,"textAlign":"center","textColor":"background","text_content":"Ready to launch your storefront?"},"block_type":"heading"},{"content":{"html_content":"<p class=\"text-center text-emerald-100 max-w-xl mx-auto mt-2 mb-6\">Start selling today with Commerce Pro. Multi-currency pricing, automatic tax, and shipping zones are ready out of the box, and the first 30 days are free.</p>"},"block_type":"text"},{"content":{"url":"https://nextblock.dev/product/nextblock-commerce-pro-commerce-license","size":"lg","text":"Start the 30-Day Free Trial","variant":"secondary","position":"center"},"block_type":"button"}]],"container_type":"container","responsive_columns":{"mobile":1,"tablet":1,"desktop":1},"vertical_alignment":"center"}$nbcm4en$::jsonb, 4);
|
|
51
|
-
UPDATE public.products
|
|
52
|
-
SET title = $t$NextBlock™ Commerce Pro - Commerce License$t$,
|
|
53
|
-
short_description = $t$NextBlock™ Commerce Pro turns your CMS into a storefront: products and variants, multi-currency pricing with daily rate sync, automatic tax through Stripe Tax, shipping zones, and checkout with Stripe or Freemius. Free for 30 days, no credit card.$t$,
|
|
54
|
-
meta_title = $t$NextBlock™ Commerce Pro | Next.js Storefront License$t$,
|
|
55
|
-
meta_description = $t$Sell products, licences and subscriptions from your Next.js site: multi-currency pricing, Stripe Tax, shipping zones, Stripe or Freemius checkout.$t$,
|
|
56
|
-
updated_at = now()
|
|
57
|
-
WHERE id = v_id;
|
|
58
|
-
ELSIF NOT EXISTS (SELECT 1 FROM public.blocks WHERE product_id = v_id AND content::text LIKE $t$%Days free, no card%$t$) THEN
|
|
59
|
-
RAISE NOTICE '02020: product nextblock-commerce-pro-commerce-license (en) differs from the shipped copy; left unchanged.';
|
|
60
|
-
END IF;
|
|
61
|
-
END IF;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
-- French
|
|
65
|
-
v_id := NULL;
|
|
66
|
-
SELECT p.id, p.language_id INTO v_id, v_lang
|
|
67
|
-
FROM public.products AS p JOIN public.languages AS l ON l.id = p.language_id
|
|
68
|
-
WHERE p.slug = 'nextblock-commerce-pro-commerce-license-fr' AND l.code = 'fr'
|
|
69
|
-
ORDER BY p.id LIMIT 1;
|
|
70
|
-
IF v_id IS NOT NULL THEN
|
|
71
|
-
IF EXISTS (SELECT 1 FROM public.blocks WHERE product_id = v_id AND content::text LIKE $t$%Moteur E-Commerce d'Entreprise%$t$)
|
|
72
|
-
AND NOT EXISTS (SELECT 1 FROM public.blocks WHERE product_id = v_id AND content::text LIKE $t$%Jours gratuits, sans carte%$t$) THEN
|
|
73
|
-
DELETE FROM public.blocks WHERE product_id = v_id;
|
|
74
|
-
INSERT INTO public.blocks (product_id, language_id, block_type, content, "order") VALUES
|
|
75
|
-
(v_id, v_lang, 'section', $nbcm0fr${"padding":{"top":"xl","bottom":"xl"},"background":{"type":"gradient","gradient":{"type":"linear","stops":[{"color":"#022c22","position":0},{"color":"#064e3b","position":40},{"color":"#0f172a","position":100}],"direction":"135deg"}},"column_gap":"xl","column_blocks":[[{"content":{"html_content":"<p class=\"text-xs uppercase tracking-[0.3em] text-emerald-400 font-semibold mb-4\">Moteur E-Commerce d'Entreprise</p>\n<h2 class=\"text-3xl md:text-5xl font-extrabold text-white leading-tight mb-5\">Faites de Next.js une<br/>Boutique Mondiale.</h2>\n<p class=\"text-base md:text-lg text-slate-200 leading-relaxed mb-6\">Commerce Pro est un moteur composable pensé pour les développeurs : catalogues physiques, licences numériques et abonnements — le tout depuis votre stack Next.js existant. Essayez-le gratuitement pendant 30 jours, sans carte de crédit.</p>"},"block_type":"text"},{"content":{"url":"https://nextblock.dev/product/nextblock-commerce-pro-commerce-license-fr","size":"lg","text":"Obtenir Commerce Pro →","variant":"default","position":"left"},"block_type":"button"}],[{"content":{"html_content":"<div class=\"rounded-2xl border border-emerald-700 bg-slate-950 p-6 shadow-xl sm:p-8\">\n<h3 class=\"text-lg font-bold text-white mb-5\">Pourquoi choisir Commerce Pro</h3>\n<ul class=\"space-y-4 text-sm leading-relaxed text-slate-300\">\n <li class=\"flex items-start gap-3\">\n <span class=\"flex-shrink-0 w-6 h-6 rounded-full bg-emerald-950 flex items-center justify-center text-emerald-300 text-xs font-bold\">✓</span>\n <span><strong class=\"text-white\">Multi-Devises</strong> — synchronisation quotidienne des taux de change, arrondis personnalisés et devise suggérée selon la langue du visiteur.</span>\n </li>\n <li class=\"flex items-start gap-3\">\n <span class=\"flex-shrink-0 w-6 h-6 rounded-full bg-emerald-950 flex items-center justify-center text-emerald-300 text-xs font-bold\">✓</span>\n <span><strong class=\"text-white\">Taxes automatisées</strong> — activez Stripe Tax et le paiement calcule et collecte la taxe pour vous, avec le détail conservé sur chaque commande.</span>\n </li>\n <li class=\"flex items-start gap-3\">\n <span class=\"flex-shrink-0 w-6 h-6 rounded-full bg-emerald-950 flex items-center justify-center text-emerald-300 text-xs font-bold\">✓</span>\n <span><strong class=\"text-white\">Gestion des Stocks</strong> — verrouillage de l'inventaire au checkout pour éviter les surventes, avec contrôle par variante.</span>\n </li>\n <li class=\"flex items-start gap-3\">\n <span class=\"flex-shrink-0 w-6 h-6 rounded-full bg-emerald-950 flex items-center justify-center text-emerald-300 text-xs font-bold\">✓</span>\n <span><strong class=\"text-white\">Zones d'expédition flexibles</strong> — tables de tarifs, seuils de livraison gratuite et règles par pays inclus.</span>\n </li>\n</ul>\n</div>"},"block_type":"text"}]],"container_type":"container","responsive_columns":{"mobile":1,"tablet":1,"desktop":2},"vertical_alignment":"center"}$nbcm0fr$::jsonb, 0),
|
|
76
|
-
(v_id, v_lang, 'section', $nbcm1fr${"padding":{"top":"lg","bottom":"lg"},"background":{"type":"theme","theme":"muted"},"column_gap":"lg","column_blocks":[[{"content":{"html_content":"<p class=\"text-center\"><span class=\"block text-2xl font-extrabold text-foreground\">30</span><span class=\"text-xs text-muted-foreground uppercase tracking-wider\">Jours gratuits, sans carte</span></p>"},"block_type":"text"}],[{"content":{"html_content":"<p class=\"text-center\"><span class=\"block text-2xl font-extrabold text-foreground\">2</span><span class=\"text-xs text-muted-foreground uppercase tracking-wider\">Fournisseurs de paiement</span></p>"},"block_type":"text"}],[{"content":{"html_content":"<p class=\"text-center\"><span class=\"block text-2xl font-extrabold text-foreground\">Quotidienne</span><span class=\"text-xs text-muted-foreground uppercase tracking-wider\">Synchro des taux</span></p>"},"block_type":"text"}],[{"content":{"html_content":"<p class=\"text-center\"><span class=\"block text-2xl font-extrabold text-foreground\">EN + FR</span><span class=\"text-xs text-muted-foreground uppercase tracking-wider\">Boutiques liées</span></p>"},"block_type":"text"}]],"container_type":"container","responsive_columns":{"mobile":1,"tablet":2,"desktop":4},"vertical_alignment":"center"}$nbcm1fr$::jsonb, 1),
|
|
77
|
-
(v_id, v_lang, 'section', $nbcm2fr${"padding":{"top":"xl","bottom":"xl"},"background":{"type":"none"},"column_gap":"lg","column_blocks":[[{"content":{"html_content":"<div class=\"h-full rounded-2xl border border-slate-200 bg-white p-6 shadow-sm transition-colors hover:border-emerald-300 hover:bg-slate-50 dark:border-white/10 dark:bg-slate-950 dark:hover:border-emerald-500 sm:p-7\">\n<div class=\"mb-4 inline-flex h-10 w-10 items-center justify-center rounded-xl bg-emerald-50 text-emerald-700 dark:bg-emerald-950 dark:text-emerald-300\"><svg class=\"h-5 w-5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\"></rect><path d=\"M3 10h18M7 15h3\"></path></svg></div>\n<h4 class=\"text-base font-bold text-slate-900 dark:text-white mb-2\">Checkout Stripe Headless</h4>\n<p class=\"text-sm text-slate-600 dark:text-slate-300 leading-relaxed\">Création de sessions Stripe Checkout pour un ou plusieurs articles. Traitement automatique des commandes par webhooks avec protection d'idempotence.</p>\n</div>"},"block_type":"text"}],[{"content":{"html_content":"<div class=\"h-full rounded-2xl border border-slate-200 bg-white p-6 shadow-sm transition-colors hover:border-emerald-300 hover:bg-slate-50 dark:border-white/10 dark:bg-slate-950 dark:hover:border-emerald-500 sm:p-7\">\n<div class=\"mb-4 inline-flex h-10 w-10 items-center justify-center rounded-xl bg-emerald-50 text-emerald-700 dark:bg-emerald-950 dark:text-emerald-300\"><svg class=\"h-5 w-5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M15 7a4 4 0 1 1-2.83 6.83L7 19H4v-3h3l2.17-2.17A4 4 0 0 1 15 7Z\"></path><path d=\"M17.5 8.5h.01\"></path></svg></div>\n<h4 class=\"text-base font-bold text-slate-900 dark:text-white mb-2\">Licences Numériques Freemius</h4>\n<p class=\"text-sm text-slate-600 dark:text-slate-300 leading-relaxed\">Distribuez vos logiciels, validez les clés de licence et gérez les périodes d'essai SaaS — aucune intégration tierce requise.</p>\n</div>"},"block_type":"text"}],[{"content":{"html_content":"<div class=\"h-full rounded-2xl border border-slate-200 bg-white p-6 shadow-sm transition-colors hover:border-emerald-300 hover:bg-slate-50 dark:border-white/10 dark:bg-slate-950 dark:hover:border-emerald-500 sm:p-7\">\n<div class=\"mb-4 inline-flex h-10 w-10 items-center justify-center rounded-xl bg-emerald-50 text-emerald-700 dark:bg-emerald-950 dark:text-emerald-300\"><svg class=\"h-5 w-5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><rect x=\"4\" y=\"5\" width=\"16\" height=\"14\" rx=\"2\"></rect><path d=\"m4 15 4-4 4 4 3-3 5 5\"></path><circle cx=\"15\" cy=\"9\" r=\"1\"></circle></svg></div>\n<h4 class=\"text-base font-bold text-slate-900 dark:text-white mb-2\">Merchandising Visuel</h4>\n<p class=\"text-sm text-slate-600 dark:text-slate-300 leading-relaxed\">Vos équipes éditoriales enrichissent les fiches produits de landing pages, promotions et galeries — directement dans l'éditeur de blocs.</p>\n</div>"},"block_type":"text"}]],"container_type":"container","responsive_columns":{"mobile":1,"tablet":2,"desktop":3},"vertical_alignment":"stretch"}$nbcm2fr$::jsonb, 2),
|
|
78
|
-
(v_id, v_lang, 'section', $nbcm3fr${"padding":{"top":"xl","bottom":"xl"},"background":{"type":"gradient","gradient":{"type":"linear","stops":[{"color":"#020617","position":0},{"color":"#0f172a","position":100}],"direction":"180deg"}},"column_gap":"xl","column_blocks":[[{"content":{"html_content":"<p class=\"text-xs uppercase tracking-[0.3em] text-emerald-400 font-semibold mb-4\">Sous le capot</p>\n<h3 class=\"text-2xl md:text-3xl font-extrabold text-white mb-4\">Conçu pour la production à grande échelle</h3>\n<p class=\"text-slate-300 leading-relaxed mb-5\">Commerce Pro a été conçu dès le départ pour les boutiques à fort trafic. Les pages de la boutique proviennent d'un cache de contenu public vidé dès la publication, chaque requête est indexée, et chaque gestionnaire de webhook est idempotent.</p>\n<ul class=\"space-y-3 text-sm text-slate-400\">\n <li class=\"flex items-start gap-2.5\">\n <span class=\"text-emerald-400\">→</span>\n <span>Inventaire par variante avec déduction du stock sous verrou de ligne</span>\n </li>\n <li class=\"flex items-start gap-2.5\">\n <span class=\"text-emerald-400\">→</span>\n <span>Calcul automatique des zones d'expédition et tables de tarifs</span>\n </li>\n <li class=\"flex items-start gap-2.5\">\n <span class=\"text-emerald-400\">→</span>\n <span>Statut des commandes en temps réel via synchronisation Stripe webhook</span>\n </li>\n <li class=\"flex items-start gap-2.5\">\n <span class=\"text-emerald-400\">→</span>\n <span>Système d'attributs produits et de facettes filtrables</span>\n </li>\n</ul>"},"block_type":"text"}],[{"content":{"html_content":"<div class=\"space-y-4\">\n<div class=\"p-5 rounded-xl border border-slate-700 bg-slate-900\">\n <h4 class=\"text-sm font-bold text-white mb-1\">Gestion des commandes</h4>\n <p class=\"text-xs text-slate-400 leading-relaxed\">Cycle de vie complet : du panier à la livraison. Transitions automatiques, factures imprimables et gestion des remboursements intégrées.</p>\n</div>\n<div class=\"p-5 rounded-xl border border-slate-700 bg-slate-900\">\n <h4 class=\"text-sm font-bold text-white mb-1\">Catégories de produits</h4>\n <p class=\"text-xs text-slate-400 leading-relaxed\">Taxonomie hiérarchique avec slugs, médias associés et support i18n complet. Les catégories sont gérées directement dans le tableau de bord du CMS.</p>\n</div>\n<div class=\"p-5 rounded-xl border border-slate-700 bg-slate-900\">\n <h4 class=\"text-sm font-bold text-white mb-1\">Boutiques multilingues</h4>\n <p class=\"text-xs text-slate-400 leading-relaxed\">Produits, catégories et flux de paiement entièrement traduisibles. Chaque variante linguistique garde ses propres prix et métadonnées SEO, et partage le stock avec ses jumelles grâce au SKU du produit.</p>\n</div>\n</div>"},"block_type":"text"}]],"container_type":"container","responsive_columns":{"mobile":1,"tablet":1,"desktop":2},"vertical_alignment":"center"}$nbcm3fr$::jsonb, 3),
|
|
79
|
-
(v_id, v_lang, 'section', $nbcm4fr${"padding":{"top":"xl","bottom":"xl"},"background":{"type":"gradient","gradient":{"type":"linear","stops":[{"color":"#064e3b","position":0},{"color":"#022c22","position":100}],"direction":"135deg"}},"column_gap":"none","column_blocks":[[{"content":{"level":2,"textAlign":"center","textColor":"background","text_content":"Prêt à lancer votre boutique ?"},"block_type":"heading"},{"content":{"html_content":"<p class=\"text-center text-emerald-100 max-w-xl mx-auto mt-2 mb-6\">Commencez à vendre dès aujourd'hui avec Commerce Pro. Prix multi-devises, taxes automatiques et zones de livraison sont prêts dès l'installation, et les 30 premiers jours sont gratuits.</p>"},"block_type":"text"},{"content":{"url":"https://nextblock.dev/product/nextblock-commerce-pro-commerce-license-fr","size":"lg","text":"Commencer l'essai gratuit de 30 jours","variant":"secondary","position":"center"},"block_type":"button"}]],"container_type":"container","responsive_columns":{"mobile":1,"tablet":1,"desktop":1},"vertical_alignment":"center"}$nbcm4fr$::jsonb, 4);
|
|
80
|
-
UPDATE public.products
|
|
81
|
-
SET title = $t$Licence NextBlock™ Commerce Pro$t$,
|
|
82
|
-
short_description = $t$NextBlock™ Commerce Pro transforme votre CMS en boutique : produits et variantes, prix multi-devises avec synchronisation quotidienne des taux, taxes automatiques via Stripe Tax, zones de livraison et paiement Stripe ou Freemius. Gratuit pendant 30 jours, sans carte de crédit.$t$,
|
|
83
|
-
meta_title = $t$NextBlock™ Commerce Pro | Licence boutique Next.js$t$,
|
|
84
|
-
meta_description = $t$Vendez produits, licences et abonnements depuis votre site Next.js : prix multi-devises, Stripe Tax, zones de livraison, paiement Stripe ou Freemius.$t$,
|
|
85
|
-
updated_at = now()
|
|
86
|
-
WHERE id = v_id;
|
|
87
|
-
ELSIF NOT EXISTS (SELECT 1 FROM public.blocks WHERE product_id = v_id AND content::text LIKE $t$%Jours gratuits, sans carte%$t$) THEN
|
|
88
|
-
RAISE NOTICE '02020: product nextblock-commerce-pro-commerce-license-fr (fr) differs from the shipped copy; left unchanged.';
|
|
89
|
-
END IF;
|
|
90
|
-
END IF;
|
|
91
|
-
|
|
92
|
-
END
|
|
93
|
-
$nb_02020_products$;
|
|
1
|
+
-- 02020: Commerce Pro license product copy, EN + FR (vendor-only rows: nextblock.dev has them,
|
|
2
|
+
-- fresh installs do not, so this is a no-op everywhere else). Copy only; no schema.
|
|
3
|
+
--
|
|
4
|
+
-- The page claimed things the code does not do:
|
|
5
|
+
-- * "real-time exchange rates" -- rates are ECB reference rates from api.frankfurter.dev, refreshed
|
|
6
|
+
-- at most once a day from the CMS layout via after() (apps/nextblock/lib/commerce/currency-rates-refresh.ts),
|
|
7
|
+
-- with a "Sync Live Rates" button and the optional /api/cron/sync-currencies route. The Vercel cron
|
|
8
|
+
-- that used to run this was dropped because vercel.json ships to every 1-click install.
|
|
9
|
+
-- * "< 50ms Cart API Response" -- there is no cart API route at all.
|
|
10
|
+
-- * "135+ Currencies Supported" / "40+ Tax Jurisdictions" -- currencies are rows an operator creates,
|
|
11
|
+
-- and tax coverage is Stripe's, not ours.
|
|
12
|
+
-- * "Every API path is edge-cached" -- public pages come from the 5-minute content cache that clears
|
|
13
|
+
-- on publish; HTML is served must-revalidate.
|
|
14
|
+
-- * "optimistic locking" -- stock is deducted under SELECT ... FOR UPDATE (libs/ecommerce order-inventory.ts).
|
|
15
|
+
-- * "email notifications" -- no order email exists; orders produce printable invoices.
|
|
16
|
+
-- * "shares inventory and pricing" -- stock is shared through the SKU, prices are per language row.
|
|
17
|
+
-- The page also never mentioned the 30-day free trial, the French buttons pointed at the English
|
|
18
|
+
-- product, the cards skipped from h3 to h5, and neither language had SEO meta (45/100 in the audit;
|
|
19
|
+
-- the new copy scores 85). Same copy as apps/nextblock/app/api/cron/reset-sandbox/commerce-product-copy.ts,
|
|
20
|
+
-- which re-seeds the sandbox after every reset.
|
|
21
|
+
--
|
|
22
|
+
-- Guarded: each product is replaced only while it still carries the shipped signature, so a product
|
|
23
|
+
-- the vendor rewrote by hand is left alone (a NOTICE names it). Idempotent: the new signature stops
|
|
24
|
+
-- a second run.
|
|
25
|
+
--
|
|
26
|
+
-- NOTE: keep the word "sandbox" OUT of this filename -- generate-sandbox-reset.ts excludes any
|
|
27
|
+
-- migration whose filename contains "sandbox" from the reset bundle.
|
|
28
|
+
|
|
29
|
+
DO $nb_02020_products$
|
|
30
|
+
DECLARE
|
|
31
|
+
v_id uuid;
|
|
32
|
+
v_lang bigint;
|
|
33
|
+
BEGIN
|
|
34
|
+
|
|
35
|
+
-- English
|
|
36
|
+
v_id := NULL;
|
|
37
|
+
SELECT p.id, p.language_id INTO v_id, v_lang
|
|
38
|
+
FROM public.products AS p JOIN public.languages AS l ON l.id = p.language_id
|
|
39
|
+
WHERE p.slug = 'nextblock-commerce-pro-commerce-license' AND l.code = 'en'
|
|
40
|
+
ORDER BY p.id LIMIT 1;
|
|
41
|
+
IF v_id IS NOT NULL THEN
|
|
42
|
+
IF EXISTS (SELECT 1 FROM public.blocks WHERE product_id = v_id AND content::text LIKE $t$%Enterprise E-Commerce Engine%$t$)
|
|
43
|
+
AND NOT EXISTS (SELECT 1 FROM public.blocks WHERE product_id = v_id AND content::text LIKE $t$%Days free, no card%$t$) THEN
|
|
44
|
+
DELETE FROM public.blocks WHERE product_id = v_id;
|
|
45
|
+
INSERT INTO public.blocks (product_id, language_id, block_type, content, "order") VALUES
|
|
46
|
+
(v_id, v_lang, 'section', $nbcm0en${"padding":{"top":"xl","bottom":"xl"},"background":{"type":"gradient","gradient":{"type":"linear","stops":[{"color":"#022c22","position":0},{"color":"#064e3b","position":40},{"color":"#0f172a","position":100}],"direction":"135deg"}},"column_gap":"xl","column_blocks":[[{"content":{"html_content":"<p class=\"text-xs uppercase tracking-[0.3em] text-emerald-400 font-semibold mb-4\">Enterprise E-Commerce Engine</p>\n<h2 class=\"text-3xl md:text-5xl font-extrabold text-white leading-tight mb-5\">Turn Next.js Into a<br/>Global Storefront.</h2>\n<p class=\"text-base md:text-lg text-slate-200 leading-relaxed mb-6\">Commerce Pro is a composable, developer-first engine that powers physical product catalogs, digital licensing, and subscription commerce — all from your existing Next.js stack. Try it free for 30 days, no credit card.</p>"},"block_type":"text"},{"content":{"url":"https://nextblock.dev/product/nextblock-commerce-pro-commerce-license","size":"lg","text":"Get Commerce Pro →","variant":"default","position":"left"},"block_type":"button"}],[{"content":{"html_content":"<div class=\"rounded-2xl border border-emerald-700 bg-slate-950 p-6 shadow-xl sm:p-8\">\n<h3 class=\"text-lg font-bold text-white mb-5\">Why Teams Choose Commerce Pro</h3>\n<ul class=\"space-y-4 text-sm leading-relaxed text-slate-300\">\n <li class=\"flex items-start gap-3\">\n <span class=\"flex-shrink-0 w-6 h-6 rounded-full bg-emerald-950 flex items-center justify-center text-emerald-300 text-xs font-bold\">✓</span>\n <span><strong class=\"text-white\">Multi-Currency Pricing</strong> — daily exchange-rate sync, charm pricing rules, and a currency suggested by the visitor's locale.</span>\n </li>\n <li class=\"flex items-start gap-3\">\n <span class=\"flex-shrink-0 w-6 h-6 rounded-full bg-emerald-950 flex items-center justify-center text-emerald-300 text-xs font-bold\">✓</span>\n <span><strong class=\"text-white\">Tax Automation</strong> — switch on Stripe Tax and checkout calculates and collects tax for you, with the tax lines stored on every order.</span>\n </li>\n <li class=\"flex items-start gap-3\">\n <span class=\"flex-shrink-0 w-6 h-6 rounded-full bg-emerald-950 flex items-center justify-center text-emerald-300 text-xs font-bold\">✓</span>\n <span><strong class=\"text-white\">Resilient Stock Tracking</strong> — inventory locks at checkout to prevent over-selling, with per-variant control.</span>\n </li>\n <li class=\"flex items-start gap-3\">\n <span class=\"flex-shrink-0 w-6 h-6 rounded-full bg-emerald-950 flex items-center justify-center text-emerald-300 text-xs font-bold\">✓</span>\n <span><strong class=\"text-white\">Flexible Shipping Zones</strong> — rate tables, free-shipping thresholds, and per-country rules out of the box.</span>\n </li>\n</ul>\n</div>"},"block_type":"text"}]],"container_type":"container","responsive_columns":{"mobile":1,"tablet":1,"desktop":2},"vertical_alignment":"center"}$nbcm0en$::jsonb, 0),
|
|
47
|
+
(v_id, v_lang, 'section', $nbcm1en${"padding":{"top":"lg","bottom":"lg"},"background":{"type":"theme","theme":"muted"},"column_gap":"lg","column_blocks":[[{"content":{"html_content":"<p class=\"text-center\"><span class=\"block text-2xl font-extrabold text-foreground\">30</span><span class=\"text-xs text-muted-foreground uppercase tracking-wider\">Days free, no card</span></p>"},"block_type":"text"}],[{"content":{"html_content":"<p class=\"text-center\"><span class=\"block text-2xl font-extrabold text-foreground\">2</span><span class=\"text-xs text-muted-foreground uppercase tracking-wider\">Checkout providers</span></p>"},"block_type":"text"}],[{"content":{"html_content":"<p class=\"text-center\"><span class=\"block text-2xl font-extrabold text-foreground\">Daily</span><span class=\"text-xs text-muted-foreground uppercase tracking-wider\">Exchange-rate sync</span></p>"},"block_type":"text"}],[{"content":{"html_content":"<p class=\"text-center\"><span class=\"block text-2xl font-extrabold text-foreground\">EN + FR</span><span class=\"text-xs text-muted-foreground uppercase tracking-wider\">Linked storefronts</span></p>"},"block_type":"text"}]],"container_type":"container","responsive_columns":{"mobile":1,"tablet":2,"desktop":4},"vertical_alignment":"center"}$nbcm1en$::jsonb, 1),
|
|
48
|
+
(v_id, v_lang, 'section', $nbcm2en${"padding":{"top":"xl","bottom":"xl"},"background":{"type":"none"},"column_gap":"lg","column_blocks":[[{"content":{"html_content":"<div class=\"h-full rounded-2xl border border-slate-200 bg-white p-6 shadow-sm transition-colors hover:border-emerald-300 hover:bg-slate-50 dark:border-white/10 dark:bg-slate-950 dark:hover:border-emerald-500 sm:p-7\">\n<div class=\"mb-4 inline-flex h-10 w-10 items-center justify-center rounded-xl bg-emerald-50 text-emerald-700 dark:bg-emerald-950 dark:text-emerald-300\"><svg class=\"h-5 w-5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\"></rect><path d=\"M3 10h18M7 15h3\"></path></svg></div>\n<h4 class=\"text-base font-bold text-slate-900 dark:text-white mb-2\">Headless Stripe Checkout</h4>\n<p class=\"text-sm text-slate-600 dark:text-slate-300 leading-relaxed\">Integrated checkout session creation for single or multiple items. Auto-fulfillment fires via webhook events, with built-in idempotency guards.</p>\n</div>"},"block_type":"text"}],[{"content":{"html_content":"<div class=\"h-full rounded-2xl border border-slate-200 bg-white p-6 shadow-sm transition-colors hover:border-emerald-300 hover:bg-slate-50 dark:border-white/10 dark:bg-slate-950 dark:hover:border-emerald-500 sm:p-7\">\n<div class=\"mb-4 inline-flex h-10 w-10 items-center justify-center rounded-xl bg-emerald-50 text-emerald-700 dark:bg-emerald-950 dark:text-emerald-300\"><svg class=\"h-5 w-5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M15 7a4 4 0 1 1-2.83 6.83L7 19H4v-3h3l2.17-2.17A4 4 0 0 1 15 7Z\"></path><path d=\"M17.5 8.5h.01\"></path></svg></div>\n<h4 class=\"text-base font-bold text-slate-900 dark:text-white mb-2\">Freemius Digital Licensing</h4>\n<p class=\"text-sm text-slate-600 dark:text-slate-300 leading-relaxed\">Distribute software downloads, validate license keys, and manage SaaS trial periods natively — no third-party integration layer required.</p>\n</div>"},"block_type":"text"}],[{"content":{"html_content":"<div class=\"h-full rounded-2xl border border-slate-200 bg-white p-6 shadow-sm transition-colors hover:border-emerald-300 hover:bg-slate-50 dark:border-white/10 dark:bg-slate-950 dark:hover:border-emerald-500 sm:p-7\">\n<div class=\"mb-4 inline-flex h-10 w-10 items-center justify-center rounded-xl bg-emerald-50 text-emerald-700 dark:bg-emerald-950 dark:text-emerald-300\"><svg class=\"h-5 w-5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><rect x=\"4\" y=\"5\" width=\"16\" height=\"14\" rx=\"2\"></rect><path d=\"m4 15 4-4 4 4 3-3 5 5\"></path><circle cx=\"15\" cy=\"9\" r=\"1\"></circle></svg></div>\n<h4 class=\"text-base font-bold text-slate-900 dark:text-white mb-2\">Visual Merchandising</h4>\n<p class=\"text-sm text-slate-600 dark:text-slate-300 leading-relaxed\">Content creators can add product details pages, highlight promotions, and build full landing pages — all inside the block editor, no code needed.</p>\n</div>"},"block_type":"text"}]],"container_type":"container","responsive_columns":{"mobile":1,"tablet":2,"desktop":3},"vertical_alignment":"stretch"}$nbcm2en$::jsonb, 2),
|
|
49
|
+
(v_id, v_lang, 'section', $nbcm3en${"padding":{"top":"xl","bottom":"xl"},"background":{"type":"gradient","gradient":{"type":"linear","stops":[{"color":"#020617","position":0},{"color":"#0f172a","position":100}],"direction":"180deg"}},"column_gap":"xl","column_blocks":[[{"content":{"html_content":"<p class=\"text-xs uppercase tracking-[0.3em] text-emerald-400 font-semibold mb-4\">Under The Hood</p>\n<h3 class=\"text-2xl md:text-3xl font-extrabold text-white mb-4\">Built for Production Scale</h3>\n<p class=\"text-slate-300 leading-relaxed mb-5\">Commerce Pro was designed from day one for high-traffic stores. Store pages come from a public content cache that clears the moment you publish, every database query is indexed, and every webhook handler is idempotent.</p>\n<ul class=\"space-y-3 text-sm text-slate-400\">\n <li class=\"flex items-start gap-2.5\">\n <span class=\"text-emerald-400\">→</span>\n <span>Variant-level inventory with row-locked stock deduction</span>\n </li>\n <li class=\"flex items-start gap-2.5\">\n <span class=\"text-emerald-400\">→</span>\n <span>Automatic shipping zone calculation and rate tables</span>\n </li>\n <li class=\"flex items-start gap-2.5\">\n <span class=\"text-emerald-400\">→</span>\n <span>Real-time order status with Stripe webhook sync</span>\n </li>\n <li class=\"flex items-start gap-2.5\">\n <span class=\"text-emerald-400\">→</span>\n <span>Product attributes and filterable facets system</span>\n </li>\n</ul>"},"block_type":"text"}],[{"content":{"html_content":"<div class=\"space-y-4\">\n<div class=\"p-5 rounded-xl border border-slate-700 bg-slate-900\">\n <h4 class=\"text-sm font-bold text-white mb-1\">Order Management</h4>\n <p class=\"text-xs text-slate-400 leading-relaxed\">Full order lifecycle from cart to fulfillment. Automatic status transitions, printable invoices, and refund handling baked in.</p>\n</div>\n<div class=\"p-5 rounded-xl border border-slate-700 bg-slate-900\">\n <h4 class=\"text-sm font-bold text-white mb-1\">Product Categories</h4>\n <p class=\"text-xs text-slate-400 leading-relaxed\">Hierarchical taxonomy with slugs, media attachments, and full i18n support. Categories are managed directly in the CMS dashboard.</p>\n</div>\n<div class=\"p-5 rounded-xl border border-slate-700 bg-slate-900\">\n <h4 class=\"text-sm font-bold text-white mb-1\">Multi-Language Storefronts</h4>\n <p class=\"text-xs text-slate-400 leading-relaxed\">Products, categories, and checkout flows are fully translatable. Each language variant keeps its own prices and SEO metadata, and shares stock with its twins through the product SKU.</p>\n</div>\n</div>"},"block_type":"text"}]],"container_type":"container","responsive_columns":{"mobile":1,"tablet":1,"desktop":2},"vertical_alignment":"center"}$nbcm3en$::jsonb, 3),
|
|
50
|
+
(v_id, v_lang, 'section', $nbcm4en${"padding":{"top":"xl","bottom":"xl"},"background":{"type":"gradient","gradient":{"type":"linear","stops":[{"color":"#064e3b","position":0},{"color":"#022c22","position":100}],"direction":"135deg"}},"column_gap":"none","column_blocks":[[{"content":{"level":2,"textAlign":"center","textColor":"background","text_content":"Ready to launch your storefront?"},"block_type":"heading"},{"content":{"html_content":"<p class=\"text-center text-emerald-100 max-w-xl mx-auto mt-2 mb-6\">Start selling today with Commerce Pro. Multi-currency pricing, automatic tax, and shipping zones are ready out of the box, and the first 30 days are free.</p>"},"block_type":"text"},{"content":{"url":"https://nextblock.dev/product/nextblock-commerce-pro-commerce-license","size":"lg","text":"Start the 30-Day Free Trial","variant":"secondary","position":"center"},"block_type":"button"}]],"container_type":"container","responsive_columns":{"mobile":1,"tablet":1,"desktop":1},"vertical_alignment":"center"}$nbcm4en$::jsonb, 4);
|
|
51
|
+
UPDATE public.products
|
|
52
|
+
SET title = $t$NextBlock™ Commerce Pro - Commerce License$t$,
|
|
53
|
+
short_description = $t$NextBlock™ Commerce Pro turns your CMS into a storefront: products and variants, multi-currency pricing with daily rate sync, automatic tax through Stripe Tax, shipping zones, and checkout with Stripe or Freemius. Free for 30 days, no credit card.$t$,
|
|
54
|
+
meta_title = $t$NextBlock™ Commerce Pro | Next.js Storefront License$t$,
|
|
55
|
+
meta_description = $t$Sell products, licences and subscriptions from your Next.js site: multi-currency pricing, Stripe Tax, shipping zones, Stripe or Freemius checkout.$t$,
|
|
56
|
+
updated_at = now()
|
|
57
|
+
WHERE id = v_id;
|
|
58
|
+
ELSIF NOT EXISTS (SELECT 1 FROM public.blocks WHERE product_id = v_id AND content::text LIKE $t$%Days free, no card%$t$) THEN
|
|
59
|
+
RAISE NOTICE '02020: product nextblock-commerce-pro-commerce-license (en) differs from the shipped copy; left unchanged.';
|
|
60
|
+
END IF;
|
|
61
|
+
END IF;
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
-- French
|
|
65
|
+
v_id := NULL;
|
|
66
|
+
SELECT p.id, p.language_id INTO v_id, v_lang
|
|
67
|
+
FROM public.products AS p JOIN public.languages AS l ON l.id = p.language_id
|
|
68
|
+
WHERE p.slug = 'nextblock-commerce-pro-commerce-license-fr' AND l.code = 'fr'
|
|
69
|
+
ORDER BY p.id LIMIT 1;
|
|
70
|
+
IF v_id IS NOT NULL THEN
|
|
71
|
+
IF EXISTS (SELECT 1 FROM public.blocks WHERE product_id = v_id AND content::text LIKE $t$%Moteur E-Commerce d'Entreprise%$t$)
|
|
72
|
+
AND NOT EXISTS (SELECT 1 FROM public.blocks WHERE product_id = v_id AND content::text LIKE $t$%Jours gratuits, sans carte%$t$) THEN
|
|
73
|
+
DELETE FROM public.blocks WHERE product_id = v_id;
|
|
74
|
+
INSERT INTO public.blocks (product_id, language_id, block_type, content, "order") VALUES
|
|
75
|
+
(v_id, v_lang, 'section', $nbcm0fr${"padding":{"top":"xl","bottom":"xl"},"background":{"type":"gradient","gradient":{"type":"linear","stops":[{"color":"#022c22","position":0},{"color":"#064e3b","position":40},{"color":"#0f172a","position":100}],"direction":"135deg"}},"column_gap":"xl","column_blocks":[[{"content":{"html_content":"<p class=\"text-xs uppercase tracking-[0.3em] text-emerald-400 font-semibold mb-4\">Moteur E-Commerce d'Entreprise</p>\n<h2 class=\"text-3xl md:text-5xl font-extrabold text-white leading-tight mb-5\">Faites de Next.js une<br/>Boutique Mondiale.</h2>\n<p class=\"text-base md:text-lg text-slate-200 leading-relaxed mb-6\">Commerce Pro est un moteur composable pensé pour les développeurs : catalogues physiques, licences numériques et abonnements — le tout depuis votre stack Next.js existant. Essayez-le gratuitement pendant 30 jours, sans carte de crédit.</p>"},"block_type":"text"},{"content":{"url":"https://nextblock.dev/product/nextblock-commerce-pro-commerce-license-fr","size":"lg","text":"Obtenir Commerce Pro →","variant":"default","position":"left"},"block_type":"button"}],[{"content":{"html_content":"<div class=\"rounded-2xl border border-emerald-700 bg-slate-950 p-6 shadow-xl sm:p-8\">\n<h3 class=\"text-lg font-bold text-white mb-5\">Pourquoi choisir Commerce Pro</h3>\n<ul class=\"space-y-4 text-sm leading-relaxed text-slate-300\">\n <li class=\"flex items-start gap-3\">\n <span class=\"flex-shrink-0 w-6 h-6 rounded-full bg-emerald-950 flex items-center justify-center text-emerald-300 text-xs font-bold\">✓</span>\n <span><strong class=\"text-white\">Multi-Devises</strong> — synchronisation quotidienne des taux de change, arrondis personnalisés et devise suggérée selon la langue du visiteur.</span>\n </li>\n <li class=\"flex items-start gap-3\">\n <span class=\"flex-shrink-0 w-6 h-6 rounded-full bg-emerald-950 flex items-center justify-center text-emerald-300 text-xs font-bold\">✓</span>\n <span><strong class=\"text-white\">Taxes automatisées</strong> — activez Stripe Tax et le paiement calcule et collecte la taxe pour vous, avec le détail conservé sur chaque commande.</span>\n </li>\n <li class=\"flex items-start gap-3\">\n <span class=\"flex-shrink-0 w-6 h-6 rounded-full bg-emerald-950 flex items-center justify-center text-emerald-300 text-xs font-bold\">✓</span>\n <span><strong class=\"text-white\">Gestion des Stocks</strong> — verrouillage de l'inventaire au checkout pour éviter les surventes, avec contrôle par variante.</span>\n </li>\n <li class=\"flex items-start gap-3\">\n <span class=\"flex-shrink-0 w-6 h-6 rounded-full bg-emerald-950 flex items-center justify-center text-emerald-300 text-xs font-bold\">✓</span>\n <span><strong class=\"text-white\">Zones d'expédition flexibles</strong> — tables de tarifs, seuils de livraison gratuite et règles par pays inclus.</span>\n </li>\n</ul>\n</div>"},"block_type":"text"}]],"container_type":"container","responsive_columns":{"mobile":1,"tablet":1,"desktop":2},"vertical_alignment":"center"}$nbcm0fr$::jsonb, 0),
|
|
76
|
+
(v_id, v_lang, 'section', $nbcm1fr${"padding":{"top":"lg","bottom":"lg"},"background":{"type":"theme","theme":"muted"},"column_gap":"lg","column_blocks":[[{"content":{"html_content":"<p class=\"text-center\"><span class=\"block text-2xl font-extrabold text-foreground\">30</span><span class=\"text-xs text-muted-foreground uppercase tracking-wider\">Jours gratuits, sans carte</span></p>"},"block_type":"text"}],[{"content":{"html_content":"<p class=\"text-center\"><span class=\"block text-2xl font-extrabold text-foreground\">2</span><span class=\"text-xs text-muted-foreground uppercase tracking-wider\">Fournisseurs de paiement</span></p>"},"block_type":"text"}],[{"content":{"html_content":"<p class=\"text-center\"><span class=\"block text-2xl font-extrabold text-foreground\">Quotidienne</span><span class=\"text-xs text-muted-foreground uppercase tracking-wider\">Synchro des taux</span></p>"},"block_type":"text"}],[{"content":{"html_content":"<p class=\"text-center\"><span class=\"block text-2xl font-extrabold text-foreground\">EN + FR</span><span class=\"text-xs text-muted-foreground uppercase tracking-wider\">Boutiques liées</span></p>"},"block_type":"text"}]],"container_type":"container","responsive_columns":{"mobile":1,"tablet":2,"desktop":4},"vertical_alignment":"center"}$nbcm1fr$::jsonb, 1),
|
|
77
|
+
(v_id, v_lang, 'section', $nbcm2fr${"padding":{"top":"xl","bottom":"xl"},"background":{"type":"none"},"column_gap":"lg","column_blocks":[[{"content":{"html_content":"<div class=\"h-full rounded-2xl border border-slate-200 bg-white p-6 shadow-sm transition-colors hover:border-emerald-300 hover:bg-slate-50 dark:border-white/10 dark:bg-slate-950 dark:hover:border-emerald-500 sm:p-7\">\n<div class=\"mb-4 inline-flex h-10 w-10 items-center justify-center rounded-xl bg-emerald-50 text-emerald-700 dark:bg-emerald-950 dark:text-emerald-300\"><svg class=\"h-5 w-5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\"></rect><path d=\"M3 10h18M7 15h3\"></path></svg></div>\n<h4 class=\"text-base font-bold text-slate-900 dark:text-white mb-2\">Checkout Stripe Headless</h4>\n<p class=\"text-sm text-slate-600 dark:text-slate-300 leading-relaxed\">Création de sessions Stripe Checkout pour un ou plusieurs articles. Traitement automatique des commandes par webhooks avec protection d'idempotence.</p>\n</div>"},"block_type":"text"}],[{"content":{"html_content":"<div class=\"h-full rounded-2xl border border-slate-200 bg-white p-6 shadow-sm transition-colors hover:border-emerald-300 hover:bg-slate-50 dark:border-white/10 dark:bg-slate-950 dark:hover:border-emerald-500 sm:p-7\">\n<div class=\"mb-4 inline-flex h-10 w-10 items-center justify-center rounded-xl bg-emerald-50 text-emerald-700 dark:bg-emerald-950 dark:text-emerald-300\"><svg class=\"h-5 w-5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M15 7a4 4 0 1 1-2.83 6.83L7 19H4v-3h3l2.17-2.17A4 4 0 0 1 15 7Z\"></path><path d=\"M17.5 8.5h.01\"></path></svg></div>\n<h4 class=\"text-base font-bold text-slate-900 dark:text-white mb-2\">Licences Numériques Freemius</h4>\n<p class=\"text-sm text-slate-600 dark:text-slate-300 leading-relaxed\">Distribuez vos logiciels, validez les clés de licence et gérez les périodes d'essai SaaS — aucune intégration tierce requise.</p>\n</div>"},"block_type":"text"}],[{"content":{"html_content":"<div class=\"h-full rounded-2xl border border-slate-200 bg-white p-6 shadow-sm transition-colors hover:border-emerald-300 hover:bg-slate-50 dark:border-white/10 dark:bg-slate-950 dark:hover:border-emerald-500 sm:p-7\">\n<div class=\"mb-4 inline-flex h-10 w-10 items-center justify-center rounded-xl bg-emerald-50 text-emerald-700 dark:bg-emerald-950 dark:text-emerald-300\"><svg class=\"h-5 w-5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><rect x=\"4\" y=\"5\" width=\"16\" height=\"14\" rx=\"2\"></rect><path d=\"m4 15 4-4 4 4 3-3 5 5\"></path><circle cx=\"15\" cy=\"9\" r=\"1\"></circle></svg></div>\n<h4 class=\"text-base font-bold text-slate-900 dark:text-white mb-2\">Merchandising Visuel</h4>\n<p class=\"text-sm text-slate-600 dark:text-slate-300 leading-relaxed\">Vos équipes éditoriales enrichissent les fiches produits de landing pages, promotions et galeries — directement dans l'éditeur de blocs.</p>\n</div>"},"block_type":"text"}]],"container_type":"container","responsive_columns":{"mobile":1,"tablet":2,"desktop":3},"vertical_alignment":"stretch"}$nbcm2fr$::jsonb, 2),
|
|
78
|
+
(v_id, v_lang, 'section', $nbcm3fr${"padding":{"top":"xl","bottom":"xl"},"background":{"type":"gradient","gradient":{"type":"linear","stops":[{"color":"#020617","position":0},{"color":"#0f172a","position":100}],"direction":"180deg"}},"column_gap":"xl","column_blocks":[[{"content":{"html_content":"<p class=\"text-xs uppercase tracking-[0.3em] text-emerald-400 font-semibold mb-4\">Sous le capot</p>\n<h3 class=\"text-2xl md:text-3xl font-extrabold text-white mb-4\">Conçu pour la production à grande échelle</h3>\n<p class=\"text-slate-300 leading-relaxed mb-5\">Commerce Pro a été conçu dès le départ pour les boutiques à fort trafic. Les pages de la boutique proviennent d'un cache de contenu public vidé dès la publication, chaque requête est indexée, et chaque gestionnaire de webhook est idempotent.</p>\n<ul class=\"space-y-3 text-sm text-slate-400\">\n <li class=\"flex items-start gap-2.5\">\n <span class=\"text-emerald-400\">→</span>\n <span>Inventaire par variante avec déduction du stock sous verrou de ligne</span>\n </li>\n <li class=\"flex items-start gap-2.5\">\n <span class=\"text-emerald-400\">→</span>\n <span>Calcul automatique des zones d'expédition et tables de tarifs</span>\n </li>\n <li class=\"flex items-start gap-2.5\">\n <span class=\"text-emerald-400\">→</span>\n <span>Statut des commandes en temps réel via synchronisation Stripe webhook</span>\n </li>\n <li class=\"flex items-start gap-2.5\">\n <span class=\"text-emerald-400\">→</span>\n <span>Système d'attributs produits et de facettes filtrables</span>\n </li>\n</ul>"},"block_type":"text"}],[{"content":{"html_content":"<div class=\"space-y-4\">\n<div class=\"p-5 rounded-xl border border-slate-700 bg-slate-900\">\n <h4 class=\"text-sm font-bold text-white mb-1\">Gestion des commandes</h4>\n <p class=\"text-xs text-slate-400 leading-relaxed\">Cycle de vie complet : du panier à la livraison. Transitions automatiques, factures imprimables et gestion des remboursements intégrées.</p>\n</div>\n<div class=\"p-5 rounded-xl border border-slate-700 bg-slate-900\">\n <h4 class=\"text-sm font-bold text-white mb-1\">Catégories de produits</h4>\n <p class=\"text-xs text-slate-400 leading-relaxed\">Taxonomie hiérarchique avec slugs, médias associés et support i18n complet. Les catégories sont gérées directement dans le tableau de bord du CMS.</p>\n</div>\n<div class=\"p-5 rounded-xl border border-slate-700 bg-slate-900\">\n <h4 class=\"text-sm font-bold text-white mb-1\">Boutiques multilingues</h4>\n <p class=\"text-xs text-slate-400 leading-relaxed\">Produits, catégories et flux de paiement entièrement traduisibles. Chaque variante linguistique garde ses propres prix et métadonnées SEO, et partage le stock avec ses jumelles grâce au SKU du produit.</p>\n</div>\n</div>"},"block_type":"text"}]],"container_type":"container","responsive_columns":{"mobile":1,"tablet":1,"desktop":2},"vertical_alignment":"center"}$nbcm3fr$::jsonb, 3),
|
|
79
|
+
(v_id, v_lang, 'section', $nbcm4fr${"padding":{"top":"xl","bottom":"xl"},"background":{"type":"gradient","gradient":{"type":"linear","stops":[{"color":"#064e3b","position":0},{"color":"#022c22","position":100}],"direction":"135deg"}},"column_gap":"none","column_blocks":[[{"content":{"level":2,"textAlign":"center","textColor":"background","text_content":"Prêt à lancer votre boutique ?"},"block_type":"heading"},{"content":{"html_content":"<p class=\"text-center text-emerald-100 max-w-xl mx-auto mt-2 mb-6\">Commencez à vendre dès aujourd'hui avec Commerce Pro. Prix multi-devises, taxes automatiques et zones de livraison sont prêts dès l'installation, et les 30 premiers jours sont gratuits.</p>"},"block_type":"text"},{"content":{"url":"https://nextblock.dev/product/nextblock-commerce-pro-commerce-license-fr","size":"lg","text":"Commencer l'essai gratuit de 30 jours","variant":"secondary","position":"center"},"block_type":"button"}]],"container_type":"container","responsive_columns":{"mobile":1,"tablet":1,"desktop":1},"vertical_alignment":"center"}$nbcm4fr$::jsonb, 4);
|
|
80
|
+
UPDATE public.products
|
|
81
|
+
SET title = $t$Licence NextBlock™ Commerce Pro$t$,
|
|
82
|
+
short_description = $t$NextBlock™ Commerce Pro transforme votre CMS en boutique : produits et variantes, prix multi-devises avec synchronisation quotidienne des taux, taxes automatiques via Stripe Tax, zones de livraison et paiement Stripe ou Freemius. Gratuit pendant 30 jours, sans carte de crédit.$t$,
|
|
83
|
+
meta_title = $t$NextBlock™ Commerce Pro | Licence boutique Next.js$t$,
|
|
84
|
+
meta_description = $t$Vendez produits, licences et abonnements depuis votre site Next.js : prix multi-devises, Stripe Tax, zones de livraison, paiement Stripe ou Freemius.$t$,
|
|
85
|
+
updated_at = now()
|
|
86
|
+
WHERE id = v_id;
|
|
87
|
+
ELSIF NOT EXISTS (SELECT 1 FROM public.blocks WHERE product_id = v_id AND content::text LIKE $t$%Jours gratuits, sans carte%$t$) THEN
|
|
88
|
+
RAISE NOTICE '02020: product nextblock-commerce-pro-commerce-license-fr (fr) differs from the shipped copy; left unchanged.';
|
|
89
|
+
END IF;
|
|
90
|
+
END IF;
|
|
91
|
+
|
|
92
|
+
END
|
|
93
|
+
$nb_02020_products$;
|