@nextblock-cms/db 0.15.10 → 0.16.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/lib/supabase/server.d.ts +31 -1
  2. package/lib/supabase/types.d.ts +41 -11
  3. package/package.json +1 -1
  4. package/supabase/migrations/00000000000003_baseline_seed.sql +468 -468
  5. package/supabase/migrations/00000000000006_home_live_demo_promo.sql +67 -67
  6. package/supabase/migrations/00000000000007_home_live_demo_promo_copy_fix.sql +49 -49
  7. package/supabase/migrations/00000000000009_home_live_demo_promo_contrast.sql +52 -52
  8. package/supabase/migrations/00000000000014_site_themes.sql +254 -254
  9. package/supabase/migrations/00000000000015_scheduled_publishing.sql +43 -43
  10. package/supabase/migrations/00000000000016_product_revisions_and_revision_baseline.sql +310 -310
  11. package/supabase/migrations/00000000000017_cortex_ai_mcp_server.sql +91 -91
  12. package/supabase/migrations/00000000000018_site_scripts.sql +96 -96
  13. package/supabase/migrations/00000000000019_site_script_revisions.sql +85 -85
  14. package/supabase/migrations/00000000000020_updating_article.sql +162 -162
  15. package/supabase/migrations/00000000000021_updating_article_git_merge.sql +91 -91
  16. package/supabase/migrations/00000000000022_updating_article_accuracy.sql +94 -94
  17. package/supabase/migrations/00000000000023_updating_article_layout_not_host.sql +87 -87
  18. package/supabase/migrations/00000000000024_updating_article_newline_fix.sql +70 -70
  19. package/supabase/migrations/00000000000025_rebrand_nextblock_dev.sql +53 -53
  20. package/supabase/migrations/00000000000026_product_inquiries.sql +118 -118
  21. package/supabase/migrations/00000000000027_message_threads.sql +391 -391
  22. package/supabase/migrations/00000000000028_interaction_replies.sql +86 -86
  23. package/supabase/migrations/00000000000029_form_endpoints_default_empty.sql +52 -52
  24. package/supabase/migrations/00000000000030_seo_redirects_and_robots.sql +149 -0
  25. package/supabase/migrations/00000000000031_seo_robots_settings_admin_only.sql +35 -0
@@ -1,91 +1,91 @@
1
- -- 00000000000021_updating_article_git_merge.sql
2
- -- Corrects the "How Updating NextBlock Works" article seeded in 00000000000020.
3
- --
4
- -- That version described the standalone update as "replace the files and keep a backup
5
- -- under .nextblock-backup/". The updater now performs a real git 3-way merge instead:
6
- -- both template versions are committed into the project's own object database under
7
- -- refs/nextblock/{base,head}, and the diff between them is applied with `git apply --3way`.
8
- -- A developer's edits to framework files are preserved and only genuine overlaps conflict.
9
- -- The copy-and-back-up path survives only as the fallback for a project with no git repo,
10
- -- no commits, or a dirty tree.
11
- --
12
- -- 020 is already applied everywhere and never replays, so the copy is corrected here as
13
- -- targeted, idempotent string replacements rather than a full re-write of the body: each
14
- -- replace() is a no-op once the old sentence is gone, so re-running changes nothing.
15
- -- Data-only; no schema change.
16
-
17
- DO $body$
18
- DECLARE
19
- v_en_post integer;
20
- v_fr_post integer;
21
- BEGIN
22
- SELECT id INTO v_en_post
23
- FROM public.posts WHERE language_id = 1 AND slug = 'how-updating-works'
24
- ORDER BY id LIMIT 1;
25
-
26
- SELECT id INTO v_fr_post
27
- FROM public.posts WHERE language_id = 2 AND slug = 'comment-fonctionnent-les-mises-a-jour'
28
- ORDER BY id LIMIT 1;
29
-
30
- ---------------------------------------------------------------------------
31
- -- English
32
- ---------------------------------------------------------------------------
33
- IF v_en_post IS NOT NULL THEN
34
- UPDATE public.blocks
35
- SET content = jsonb_set(
36
- content,
37
- '{html_content}',
38
- to_jsonb(
39
- replace(
40
- replace(
41
- replace(
42
- content->>'html_content',
43
- -- 1. the "if something goes wrong" bullet
44
- '<li><strong>Standalone projects:</strong> every framework file the update replaces is copied first into a timestamped folder under <code>.nextblock-backup/</code> in your project. Nothing is deleted, so files you added yourself are never removed.</li>',
45
- '<li><strong>Standalone projects:</strong> the update is applied as a <strong>git 3-way merge</strong> into your working tree &mdash; nothing is committed for you. Review it with <code>git diff</code>, and undo the whole thing with <code>git reset --hard HEAD</code>. Nothing is ever deleted, so files you added yourself are never removed.</li>'
46
- ),
47
- -- 2. the "you customised a framework file" paragraph
48
- '<p>If you have customised a file that NextBlock owns &mdash; something under <code>app/</code>, <code>components/</code> or <code>lib/</code> &mdash; the update will replace it and back up your version. Diff the backup afterwards to bring your change forward. Customisations that live in your own new files, in the CMS, or in <code>.env</code> are never affected.</p>',
49
- '<p>If you have customised a file that NextBlock owns &mdash; something under <code>app/</code>, <code>components/</code> or <code>lib/</code> &mdash; <strong>your edit is kept</strong>. The update merges the upstream change into your version, and only a change that genuinely overlaps yours conflicts, with ordinary <code>&lt;&lt;&lt;&lt;&lt;&lt;&lt; ours</code> / <code>&gt;&gt;&gt;&gt;&gt;&gt;&gt; theirs</code> markers. List them with <code>git diff --name-only --diff-filter=U</code> and resolve with <code>git checkout --theirs</code> or <code>--ours</code>. Customisations in your own files, in the CMS, or in <code>.env</code> are never touched at all.</p>'
50
- ),
51
- -- 3. the managed-cloud section
52
- '<p>Your project is a standalone Next.js app, so new framework code is fetched from the published <code>create-nextblock</code> package on npm &mdash; the exact artifact your project was scaffolded from, versioned in lockstep with the release. NextBlock refreshes the files it owns, merges the new dependency versions into your <code>package.json</code>, runs <code>npm install</code>, and then applies migrations.</p>',
53
- '<p>Your project is a standalone Next.js app with no upstream to pull from, so new framework code comes from the published <code>create-nextblock</code> package on npm &mdash; the exact artifact your project was scaffolded from, versioned in lockstep with the release. NextBlock fetches both your current version and the new one, and applies the difference between them as a <strong>git 3-way merge</strong>, so the update behaves exactly like a <code>git pull</code>: files you never touched update silently, files you customised keep your changes. It then merges the new dependency versions into your <code>package.json</code>, runs <code>npm install</code>, and applies migrations.</p><p>This needs a git repository with at least one commit and a clean working tree &mdash; commit your work before updating. Without that there is nothing to merge against, so the files are copied instead and anything replaced is kept under <code>.nextblock-backup/</code>.</p>'
54
- )
55
- )
56
- ),
57
- updated_at = now()
58
- WHERE post_id = v_en_post
59
- AND block_type = 'text';
60
- END IF;
61
-
62
- ---------------------------------------------------------------------------
63
- -- French
64
- ---------------------------------------------------------------------------
65
- IF v_fr_post IS NOT NULL THEN
66
- UPDATE public.blocks
67
- SET content = jsonb_set(
68
- content,
69
- '{html_content}',
70
- to_jsonb(
71
- replace(
72
- replace(
73
- replace(
74
- content->>'html_content',
75
- '<li><strong>Projets autonomes :</strong> chaque fichier remplac&eacute; est d''abord copi&eacute; dans un dossier horodat&eacute; sous <code>.nextblock-backup/</code> dans votre projet. Rien n''est supprim&eacute; : les fichiers que vous avez ajout&eacute;s ne disparaissent jamais.</li>',
76
- '<li><strong>Projets autonomes :</strong> la mise &agrave; jour est appliqu&eacute;e comme une <strong>fusion git &agrave; trois voies</strong> dans votre copie de travail &mdash; rien n''est valid&eacute; &agrave; votre place. Examinez-la avec <code>git diff</code>, et annulez tout avec <code>git reset --hard HEAD</code>. Rien n''est jamais supprim&eacute; : les fichiers que vous avez ajout&eacute;s ne disparaissent jamais.</li>'
77
- ),
78
- '<p>Si vous avez personnalis&eacute; un fichier appartenant &agrave; NextBlock &mdash; sous <code>app/</code>, <code>components/</code> ou <code>lib/</code> &mdash; la mise &agrave; jour le remplacera en sauvegardant votre version. Comparez ensuite la sauvegarde pour reporter votre modification. Les personnalisations qui vivent dans vos propres fichiers, dans le CMS ou dans <code>.env</code> ne sont jamais affect&eacute;es.</p>',
79
- '<p>Si vous avez personnalis&eacute; un fichier appartenant &agrave; NextBlock &mdash; sous <code>app/</code>, <code>components/</code> ou <code>lib/</code> &mdash; <strong>votre modification est conserv&eacute;e</strong>. La mise &agrave; jour fusionne le changement amont dans votre version, et seul un changement qui chevauche r&eacute;ellement le v&ocirc;tre entre en conflit, avec les marqueurs habituels <code>&lt;&lt;&lt;&lt;&lt;&lt;&lt; ours</code> / <code>&gt;&gt;&gt;&gt;&gt;&gt;&gt; theirs</code>. Listez-les avec <code>git diff --name-only --diff-filter=U</code> et r&eacute;solvez avec <code>git checkout --theirs</code> ou <code>--ours</code>. Les personnalisations dans vos propres fichiers, dans le CMS ou dans <code>.env</code> ne sont jamais touch&eacute;es.</p>'
80
- ),
81
- '<p>Votre projet est une application Next.js autonome : le nouveau code provient donc du paquet <code>create-nextblock</code> publi&eacute; sur npm &mdash; exactement l''artefact &agrave; partir duquel votre projet a &eacute;t&eacute; g&eacute;n&eacute;r&eacute;, versionn&eacute; en phase avec la release. NextBlock rafra&icirc;chit les fichiers qui lui appartiennent, fusionne les nouvelles versions de d&eacute;pendances dans votre <code>package.json</code>, lance <code>npm install</code>, puis applique les migrations.</p>',
82
- '<p>Votre projet est une application Next.js autonome sans d&eacute;p&ocirc;t amont &agrave; tirer : le nouveau code provient donc du paquet <code>create-nextblock</code> publi&eacute; sur npm &mdash; exactement l''artefact &agrave; partir duquel votre projet a &eacute;t&eacute; g&eacute;n&eacute;r&eacute;, versionn&eacute; en phase avec la release. NextBlock r&eacute;cup&egrave;re votre version actuelle et la nouvelle, puis applique la diff&eacute;rence entre les deux comme une <strong>fusion git &agrave; trois voies</strong> : la mise &agrave; jour se comporte donc exactement comme un <code>git pull</code> &mdash; les fichiers que vous n''avez jamais touch&eacute;s se mettent &agrave; jour silencieusement, ceux que vous avez personnalis&eacute;s conservent vos changements. Elle fusionne ensuite les nouvelles versions de d&eacute;pendances dans votre <code>package.json</code>, lance <code>npm install</code> et applique les migrations.</p><p>Cela n&eacute;cessite un d&eacute;p&ocirc;t git avec au moins un commit et une copie de travail propre &mdash; validez votre travail avant de mettre &agrave; jour. Sans cela il n''y a rien contre quoi fusionner : les fichiers sont alors copi&eacute;s et tout ce qui est remplac&eacute; est conserv&eacute; sous <code>.nextblock-backup/</code>.</p>'
83
- )
84
- )
85
- ),
86
- updated_at = now()
87
- WHERE post_id = v_fr_post
88
- AND block_type = 'text';
89
- END IF;
90
- END
91
- $body$;
1
+ -- 00000000000021_updating_article_git_merge.sql
2
+ -- Corrects the "How Updating NextBlock Works" article seeded in 00000000000020.
3
+ --
4
+ -- That version described the standalone update as "replace the files and keep a backup
5
+ -- under .nextblock-backup/". The updater now performs a real git 3-way merge instead:
6
+ -- both template versions are committed into the project's own object database under
7
+ -- refs/nextblock/{base,head}, and the diff between them is applied with `git apply --3way`.
8
+ -- A developer's edits to framework files are preserved and only genuine overlaps conflict.
9
+ -- The copy-and-back-up path survives only as the fallback for a project with no git repo,
10
+ -- no commits, or a dirty tree.
11
+ --
12
+ -- 020 is already applied everywhere and never replays, so the copy is corrected here as
13
+ -- targeted, idempotent string replacements rather than a full re-write of the body: each
14
+ -- replace() is a no-op once the old sentence is gone, so re-running changes nothing.
15
+ -- Data-only; no schema change.
16
+
17
+ DO $body$
18
+ DECLARE
19
+ v_en_post integer;
20
+ v_fr_post integer;
21
+ BEGIN
22
+ SELECT id INTO v_en_post
23
+ FROM public.posts WHERE language_id = 1 AND slug = 'how-updating-works'
24
+ ORDER BY id LIMIT 1;
25
+
26
+ SELECT id INTO v_fr_post
27
+ FROM public.posts WHERE language_id = 2 AND slug = 'comment-fonctionnent-les-mises-a-jour'
28
+ ORDER BY id LIMIT 1;
29
+
30
+ ---------------------------------------------------------------------------
31
+ -- English
32
+ ---------------------------------------------------------------------------
33
+ IF v_en_post IS NOT NULL THEN
34
+ UPDATE public.blocks
35
+ SET content = jsonb_set(
36
+ content,
37
+ '{html_content}',
38
+ to_jsonb(
39
+ replace(
40
+ replace(
41
+ replace(
42
+ content->>'html_content',
43
+ -- 1. the "if something goes wrong" bullet
44
+ '<li><strong>Standalone projects:</strong> every framework file the update replaces is copied first into a timestamped folder under <code>.nextblock-backup/</code> in your project. Nothing is deleted, so files you added yourself are never removed.</li>',
45
+ '<li><strong>Standalone projects:</strong> the update is applied as a <strong>git 3-way merge</strong> into your working tree &mdash; nothing is committed for you. Review it with <code>git diff</code>, and undo the whole thing with <code>git reset --hard HEAD</code>. Nothing is ever deleted, so files you added yourself are never removed.</li>'
46
+ ),
47
+ -- 2. the "you customised a framework file" paragraph
48
+ '<p>If you have customised a file that NextBlock owns &mdash; something under <code>app/</code>, <code>components/</code> or <code>lib/</code> &mdash; the update will replace it and back up your version. Diff the backup afterwards to bring your change forward. Customisations that live in your own new files, in the CMS, or in <code>.env</code> are never affected.</p>',
49
+ '<p>If you have customised a file that NextBlock owns &mdash; something under <code>app/</code>, <code>components/</code> or <code>lib/</code> &mdash; <strong>your edit is kept</strong>. The update merges the upstream change into your version, and only a change that genuinely overlaps yours conflicts, with ordinary <code>&lt;&lt;&lt;&lt;&lt;&lt;&lt; ours</code> / <code>&gt;&gt;&gt;&gt;&gt;&gt;&gt; theirs</code> markers. List them with <code>git diff --name-only --diff-filter=U</code> and resolve with <code>git checkout --theirs</code> or <code>--ours</code>. Customisations in your own files, in the CMS, or in <code>.env</code> are never touched at all.</p>'
50
+ ),
51
+ -- 3. the managed-cloud section
52
+ '<p>Your project is a standalone Next.js app, so new framework code is fetched from the published <code>create-nextblock</code> package on npm &mdash; the exact artifact your project was scaffolded from, versioned in lockstep with the release. NextBlock refreshes the files it owns, merges the new dependency versions into your <code>package.json</code>, runs <code>npm install</code>, and then applies migrations.</p>',
53
+ '<p>Your project is a standalone Next.js app with no upstream to pull from, so new framework code comes from the published <code>create-nextblock</code> package on npm &mdash; the exact artifact your project was scaffolded from, versioned in lockstep with the release. NextBlock fetches both your current version and the new one, and applies the difference between them as a <strong>git 3-way merge</strong>, so the update behaves exactly like a <code>git pull</code>: files you never touched update silently, files you customised keep your changes. It then merges the new dependency versions into your <code>package.json</code>, runs <code>npm install</code>, and applies migrations.</p><p>This needs a git repository with at least one commit and a clean working tree &mdash; commit your work before updating. Without that there is nothing to merge against, so the files are copied instead and anything replaced is kept under <code>.nextblock-backup/</code>.</p>'
54
+ )
55
+ )
56
+ ),
57
+ updated_at = now()
58
+ WHERE post_id = v_en_post
59
+ AND block_type = 'text';
60
+ END IF;
61
+
62
+ ---------------------------------------------------------------------------
63
+ -- French
64
+ ---------------------------------------------------------------------------
65
+ IF v_fr_post IS NOT NULL THEN
66
+ UPDATE public.blocks
67
+ SET content = jsonb_set(
68
+ content,
69
+ '{html_content}',
70
+ to_jsonb(
71
+ replace(
72
+ replace(
73
+ replace(
74
+ content->>'html_content',
75
+ '<li><strong>Projets autonomes :</strong> chaque fichier remplac&eacute; est d''abord copi&eacute; dans un dossier horodat&eacute; sous <code>.nextblock-backup/</code> dans votre projet. Rien n''est supprim&eacute; : les fichiers que vous avez ajout&eacute;s ne disparaissent jamais.</li>',
76
+ '<li><strong>Projets autonomes :</strong> la mise &agrave; jour est appliqu&eacute;e comme une <strong>fusion git &agrave; trois voies</strong> dans votre copie de travail &mdash; rien n''est valid&eacute; &agrave; votre place. Examinez-la avec <code>git diff</code>, et annulez tout avec <code>git reset --hard HEAD</code>. Rien n''est jamais supprim&eacute; : les fichiers que vous avez ajout&eacute;s ne disparaissent jamais.</li>'
77
+ ),
78
+ '<p>Si vous avez personnalis&eacute; un fichier appartenant &agrave; NextBlock &mdash; sous <code>app/</code>, <code>components/</code> ou <code>lib/</code> &mdash; la mise &agrave; jour le remplacera en sauvegardant votre version. Comparez ensuite la sauvegarde pour reporter votre modification. Les personnalisations qui vivent dans vos propres fichiers, dans le CMS ou dans <code>.env</code> ne sont jamais affect&eacute;es.</p>',
79
+ '<p>Si vous avez personnalis&eacute; un fichier appartenant &agrave; NextBlock &mdash; sous <code>app/</code>, <code>components/</code> ou <code>lib/</code> &mdash; <strong>votre modification est conserv&eacute;e</strong>. La mise &agrave; jour fusionne le changement amont dans votre version, et seul un changement qui chevauche r&eacute;ellement le v&ocirc;tre entre en conflit, avec les marqueurs habituels <code>&lt;&lt;&lt;&lt;&lt;&lt;&lt; ours</code> / <code>&gt;&gt;&gt;&gt;&gt;&gt;&gt; theirs</code>. Listez-les avec <code>git diff --name-only --diff-filter=U</code> et r&eacute;solvez avec <code>git checkout --theirs</code> ou <code>--ours</code>. Les personnalisations dans vos propres fichiers, dans le CMS ou dans <code>.env</code> ne sont jamais touch&eacute;es.</p>'
80
+ ),
81
+ '<p>Votre projet est une application Next.js autonome : le nouveau code provient donc du paquet <code>create-nextblock</code> publi&eacute; sur npm &mdash; exactement l''artefact &agrave; partir duquel votre projet a &eacute;t&eacute; g&eacute;n&eacute;r&eacute;, versionn&eacute; en phase avec la release. NextBlock rafra&icirc;chit les fichiers qui lui appartiennent, fusionne les nouvelles versions de d&eacute;pendances dans votre <code>package.json</code>, lance <code>npm install</code>, puis applique les migrations.</p>',
82
+ '<p>Votre projet est une application Next.js autonome sans d&eacute;p&ocirc;t amont &agrave; tirer : le nouveau code provient donc du paquet <code>create-nextblock</code> publi&eacute; sur npm &mdash; exactement l''artefact &agrave; partir duquel votre projet a &eacute;t&eacute; g&eacute;n&eacute;r&eacute;, versionn&eacute; en phase avec la release. NextBlock r&eacute;cup&egrave;re votre version actuelle et la nouvelle, puis applique la diff&eacute;rence entre les deux comme une <strong>fusion git &agrave; trois voies</strong> : la mise &agrave; jour se comporte donc exactement comme un <code>git pull</code> &mdash; les fichiers que vous n''avez jamais touch&eacute;s se mettent &agrave; jour silencieusement, ceux que vous avez personnalis&eacute;s conservent vos changements. Elle fusionne ensuite les nouvelles versions de d&eacute;pendances dans votre <code>package.json</code>, lance <code>npm install</code> et applique les migrations.</p><p>Cela n&eacute;cessite un d&eacute;p&ocirc;t git avec au moins un commit et une copie de travail propre &mdash; validez votre travail avant de mettre &agrave; jour. Sans cela il n''y a rien contre quoi fusionner : les fichiers sont alors copi&eacute;s et tout ce qui est remplac&eacute; est conserv&eacute; sous <code>.nextblock-backup/</code>.</p>'
83
+ )
84
+ )
85
+ ),
86
+ updated_at = now()
87
+ WHERE post_id = v_fr_post
88
+ AND block_type = 'text';
89
+ END IF;
90
+ END
91
+ $body$;
@@ -1,94 +1,94 @@
1
- -- 00000000000022_updating_article_accuracy.sql
2
- -- Three accuracy fixes to the "How Updating NextBlock Works" article
3
- -- (seeded in 00000000000020, first corrected in 00000000000021).
4
- --
5
- -- 0. The merge is performed with `git merge-file`, not `git apply --3way`. The latter
6
- -- implies --index: it stages its result (so `git diff` shows the developer nothing),
7
- -- requires every path to be tracked (one gitignored framework path aborted the whole
8
- -- update), and requires the worktree to match the index. merge-file touches no git
9
- -- state at all. Consequently the resolution commands 021 shipped are wrong: there are
10
- -- no index stages, so `git checkout --theirs/--ours` does not apply. The conflict
11
- -- markers are ordinary text; `git checkout -- <file>` discards one file's merge.
12
- --
13
- -- 1. "A conflicted merge is aborted automatically" was true of only ONE path. The
14
- -- monorepo/fork path does abort and restore the tree, because the merge belongs to
15
- -- upstream. The standalone path deliberately LEAVES the conflict in the working tree,
16
- -- because it is the developer's own repository and resolving it is the whole point.
17
- -- The bullet now states both.
18
- -- 2. The Docker section claimed `npm run update` refreshes the schema. It does not, by
19
- -- design: the self-hosted stack ships its own migration runner (the `migrate` service
20
- -- in docker-compose.yml, which tracks applied versions in a different table), so the
21
- -- updater stages the SQL and hands off to `npm run docker:up` rather than applying it
22
- -- twice through two different trackers.
23
- --
24
- -- Same targeted, idempotent replace() approach as 021 — a no-op once the old sentence is
25
- -- gone. Data-only; no schema change.
26
-
27
- DO $body$
28
- DECLARE
29
- v_en_post integer;
30
- v_fr_post integer;
31
- BEGIN
32
- SELECT id INTO v_en_post
33
- FROM public.posts WHERE language_id = 1 AND slug = 'how-updating-works'
34
- ORDER BY id LIMIT 1;
35
-
36
- SELECT id INTO v_fr_post
37
- FROM public.posts WHERE language_id = 2 AND slug = 'comment-fonctionnent-les-mises-a-jour'
38
- ORDER BY id LIMIT 1;
39
-
40
- IF v_en_post IS NOT NULL THEN
41
- UPDATE public.blocks
42
- SET content = jsonb_set(
43
- content,
44
- '{html_content}',
45
- to_jsonb(
46
- replace(
47
- replace(
48
- replace(
49
- content->>'html_content',
50
- -- 021 shipped index-based resolution commands; the merge no longer
51
- -- uses the git index, so they do not apply.
52
- '<strong>your edit is kept</strong>. The update merges the upstream change into your version, and only a change that genuinely overlaps yours conflicts, with ordinary <code>&lt;&lt;&lt;&lt;&lt;&lt;&lt; ours</code> / <code>&gt;&gt;&gt;&gt;&gt;&gt;&gt; theirs</code> markers. List them with <code>git diff --name-only --diff-filter=U</code> and resolve with <code>git checkout --theirs</code> or <code>--ours</code>.',
53
- '<strong>your edit is kept</strong>. The update merges the upstream change into your version, and only a change that genuinely overlaps yours conflicts &mdash; the updater lists those files, and each one carries ordinary <code>&lt;&lt;&lt;&lt;&lt;&lt;&lt; your version</code> / <code>&gt;&gt;&gt;&gt;&gt;&gt;&gt; NextBlock</code> markers. Edit them as you would any conflict, or run <code>git checkout -- &lt;file&gt;</code> to discard the merge for that one file.'
54
- ),
55
- '<li><strong>A conflicted merge</strong> is aborted automatically &mdash; your working tree is left exactly as it was, with instructions printed for resolving it by hand.</li>',
56
- '<li><strong>A conflict</strong> behaves differently by install, on purpose. On a fork or clone the upstream merge is <em>aborted</em> and your working tree is left exactly as it was. On a standalone project the conflict is <em>left in place</em> for you to resolve &mdash; it is your own repository, and that is the point &mdash; and <code>git reset --hard HEAD</code> backs the whole update out.</li>'
57
- ),
58
- '<p>The first command refreshes the application, its dependencies and the schema; the second rebuilds and restarts the containers. Your database and media live in Docker volumes and are never touched by either step &mdash; <code>docker:up</code> rebuilds images, not data.</p>',
59
- '<p>The first command updates the application and its dependencies and stages the new migrations; the second rebuilds the containers <em>and applies those migrations</em>. The self-hosted stack runs its own migration service, so the updater hands the schema step to it rather than applying the same SQL through two different trackers. Your database and media live in Docker volumes and are never touched by either command &mdash; <code>docker:up</code> rebuilds images, not data.</p>'
60
- )
61
- )
62
- ),
63
- updated_at = now()
64
- WHERE post_id = v_en_post
65
- AND block_type = 'text';
66
- END IF;
67
-
68
- IF v_fr_post IS NOT NULL THEN
69
- UPDATE public.blocks
70
- SET content = jsonb_set(
71
- content,
72
- '{html_content}',
73
- to_jsonb(
74
- replace(
75
- replace(
76
- replace(
77
- content->>'html_content',
78
- '<strong>votre modification est conserv&eacute;e</strong>. La mise &agrave; jour fusionne le changement amont dans votre version, et seul un changement qui chevauche r&eacute;ellement le v&ocirc;tre entre en conflit, avec les marqueurs habituels <code>&lt;&lt;&lt;&lt;&lt;&lt;&lt; ours</code> / <code>&gt;&gt;&gt;&gt;&gt;&gt;&gt; theirs</code>. Listez-les avec <code>git diff --name-only --diff-filter=U</code> et r&eacute;solvez avec <code>git checkout --theirs</code> ou <code>--ours</code>.',
79
- '<strong>votre modification est conserv&eacute;e</strong>. La mise &agrave; jour fusionne le changement amont dans votre version, et seul un changement qui chevauche r&eacute;ellement le v&ocirc;tre entre en conflit &mdash; la commande liste ces fichiers, et chacun porte les marqueurs habituels <code>&lt;&lt;&lt;&lt;&lt;&lt;&lt; your version</code> / <code>&gt;&gt;&gt;&gt;&gt;&gt;&gt; NextBlock</code>. Modifiez-les comme n''importe quel conflit, ou lancez <code>git checkout -- &lt;fichier&gt;</code> pour abandonner la fusion sur ce seul fichier.'
80
- ),
81
- '<li><strong>Une fusion en conflit</strong> est annul&eacute;e automatiquement &mdash; votre copie de travail reste intacte, avec les instructions pour r&eacute;soudre &agrave; la main.</li>',
82
- '<li><strong>Un conflit</strong> se comporte diff&eacute;remment selon l''installation, volontairement. Sur un fork ou un clone, la fusion amont est <em>annul&eacute;e</em> et votre copie de travail reste intacte. Sur un projet autonome, le conflit est <em>laiss&eacute; en place</em> pour que vous le r&eacute;solviez &mdash; c''est votre d&eacute;p&ocirc;t, et c''est tout l''int&eacute;r&ecirc;t &mdash; et <code>git reset --hard HEAD</code> annule toute la mise &agrave; jour.</li>'
83
- ),
84
- '<p>La premi&egrave;re commande met &agrave; jour l''application, ses d&eacute;pendances et le sch&eacute;ma ; la seconde reconstruit et red&eacute;marre les conteneurs. Votre base de donn&eacute;es et vos m&eacute;dias vivent dans des volumes Docker et ne sont touch&eacute;s ni par l''une ni par l''autre &mdash; <code>docker:up</code> reconstruit des images, pas des donn&eacute;es.</p>',
85
- '<p>La premi&egrave;re commande met &agrave; jour l''application et ses d&eacute;pendances et pr&eacute;pare les nouvelles migrations ; la seconde reconstruit les conteneurs <em>et applique ces migrations</em>. La pile auto-h&eacute;berg&eacute;e dispose de son propre service de migration : la mise &agrave; jour lui confie donc l''&eacute;tape sch&eacute;ma plut&ocirc;t que d''appliquer le m&ecirc;me SQL via deux suivis diff&eacute;rents. Votre base de donn&eacute;es et vos m&eacute;dias vivent dans des volumes Docker et ne sont touch&eacute;s par aucune des deux commandes &mdash; <code>docker:up</code> reconstruit des images, pas des donn&eacute;es.</p>'
86
- )
87
- )
88
- ),
89
- updated_at = now()
90
- WHERE post_id = v_fr_post
91
- AND block_type = 'text';
92
- END IF;
93
- END
94
- $body$;
1
+ -- 00000000000022_updating_article_accuracy.sql
2
+ -- Three accuracy fixes to the "How Updating NextBlock Works" article
3
+ -- (seeded in 00000000000020, first corrected in 00000000000021).
4
+ --
5
+ -- 0. The merge is performed with `git merge-file`, not `git apply --3way`. The latter
6
+ -- implies --index: it stages its result (so `git diff` shows the developer nothing),
7
+ -- requires every path to be tracked (one gitignored framework path aborted the whole
8
+ -- update), and requires the worktree to match the index. merge-file touches no git
9
+ -- state at all. Consequently the resolution commands 021 shipped are wrong: there are
10
+ -- no index stages, so `git checkout --theirs/--ours` does not apply. The conflict
11
+ -- markers are ordinary text; `git checkout -- <file>` discards one file's merge.
12
+ --
13
+ -- 1. "A conflicted merge is aborted automatically" was true of only ONE path. The
14
+ -- monorepo/fork path does abort and restore the tree, because the merge belongs to
15
+ -- upstream. The standalone path deliberately LEAVES the conflict in the working tree,
16
+ -- because it is the developer's own repository and resolving it is the whole point.
17
+ -- The bullet now states both.
18
+ -- 2. The Docker section claimed `npm run update` refreshes the schema. It does not, by
19
+ -- design: the self-hosted stack ships its own migration runner (the `migrate` service
20
+ -- in docker-compose.yml, which tracks applied versions in a different table), so the
21
+ -- updater stages the SQL and hands off to `npm run docker:up` rather than applying it
22
+ -- twice through two different trackers.
23
+ --
24
+ -- Same targeted, idempotent replace() approach as 021 — a no-op once the old sentence is
25
+ -- gone. Data-only; no schema change.
26
+
27
+ DO $body$
28
+ DECLARE
29
+ v_en_post integer;
30
+ v_fr_post integer;
31
+ BEGIN
32
+ SELECT id INTO v_en_post
33
+ FROM public.posts WHERE language_id = 1 AND slug = 'how-updating-works'
34
+ ORDER BY id LIMIT 1;
35
+
36
+ SELECT id INTO v_fr_post
37
+ FROM public.posts WHERE language_id = 2 AND slug = 'comment-fonctionnent-les-mises-a-jour'
38
+ ORDER BY id LIMIT 1;
39
+
40
+ IF v_en_post IS NOT NULL THEN
41
+ UPDATE public.blocks
42
+ SET content = jsonb_set(
43
+ content,
44
+ '{html_content}',
45
+ to_jsonb(
46
+ replace(
47
+ replace(
48
+ replace(
49
+ content->>'html_content',
50
+ -- 021 shipped index-based resolution commands; the merge no longer
51
+ -- uses the git index, so they do not apply.
52
+ '<strong>your edit is kept</strong>. The update merges the upstream change into your version, and only a change that genuinely overlaps yours conflicts, with ordinary <code>&lt;&lt;&lt;&lt;&lt;&lt;&lt; ours</code> / <code>&gt;&gt;&gt;&gt;&gt;&gt;&gt; theirs</code> markers. List them with <code>git diff --name-only --diff-filter=U</code> and resolve with <code>git checkout --theirs</code> or <code>--ours</code>.',
53
+ '<strong>your edit is kept</strong>. The update merges the upstream change into your version, and only a change that genuinely overlaps yours conflicts &mdash; the updater lists those files, and each one carries ordinary <code>&lt;&lt;&lt;&lt;&lt;&lt;&lt; your version</code> / <code>&gt;&gt;&gt;&gt;&gt;&gt;&gt; NextBlock</code> markers. Edit them as you would any conflict, or run <code>git checkout -- &lt;file&gt;</code> to discard the merge for that one file.'
54
+ ),
55
+ '<li><strong>A conflicted merge</strong> is aborted automatically &mdash; your working tree is left exactly as it was, with instructions printed for resolving it by hand.</li>',
56
+ '<li><strong>A conflict</strong> behaves differently by install, on purpose. On a fork or clone the upstream merge is <em>aborted</em> and your working tree is left exactly as it was. On a standalone project the conflict is <em>left in place</em> for you to resolve &mdash; it is your own repository, and that is the point &mdash; and <code>git reset --hard HEAD</code> backs the whole update out.</li>'
57
+ ),
58
+ '<p>The first command refreshes the application, its dependencies and the schema; the second rebuilds and restarts the containers. Your database and media live in Docker volumes and are never touched by either step &mdash; <code>docker:up</code> rebuilds images, not data.</p>',
59
+ '<p>The first command updates the application and its dependencies and stages the new migrations; the second rebuilds the containers <em>and applies those migrations</em>. The self-hosted stack runs its own migration service, so the updater hands the schema step to it rather than applying the same SQL through two different trackers. Your database and media live in Docker volumes and are never touched by either command &mdash; <code>docker:up</code> rebuilds images, not data.</p>'
60
+ )
61
+ )
62
+ ),
63
+ updated_at = now()
64
+ WHERE post_id = v_en_post
65
+ AND block_type = 'text';
66
+ END IF;
67
+
68
+ IF v_fr_post IS NOT NULL THEN
69
+ UPDATE public.blocks
70
+ SET content = jsonb_set(
71
+ content,
72
+ '{html_content}',
73
+ to_jsonb(
74
+ replace(
75
+ replace(
76
+ replace(
77
+ content->>'html_content',
78
+ '<strong>votre modification est conserv&eacute;e</strong>. La mise &agrave; jour fusionne le changement amont dans votre version, et seul un changement qui chevauche r&eacute;ellement le v&ocirc;tre entre en conflit, avec les marqueurs habituels <code>&lt;&lt;&lt;&lt;&lt;&lt;&lt; ours</code> / <code>&gt;&gt;&gt;&gt;&gt;&gt;&gt; theirs</code>. Listez-les avec <code>git diff --name-only --diff-filter=U</code> et r&eacute;solvez avec <code>git checkout --theirs</code> ou <code>--ours</code>.',
79
+ '<strong>votre modification est conserv&eacute;e</strong>. La mise &agrave; jour fusionne le changement amont dans votre version, et seul un changement qui chevauche r&eacute;ellement le v&ocirc;tre entre en conflit &mdash; la commande liste ces fichiers, et chacun porte les marqueurs habituels <code>&lt;&lt;&lt;&lt;&lt;&lt;&lt; your version</code> / <code>&gt;&gt;&gt;&gt;&gt;&gt;&gt; NextBlock</code>. Modifiez-les comme n''importe quel conflit, ou lancez <code>git checkout -- &lt;fichier&gt;</code> pour abandonner la fusion sur ce seul fichier.'
80
+ ),
81
+ '<li><strong>Une fusion en conflit</strong> est annul&eacute;e automatiquement &mdash; votre copie de travail reste intacte, avec les instructions pour r&eacute;soudre &agrave; la main.</li>',
82
+ '<li><strong>Un conflit</strong> se comporte diff&eacute;remment selon l''installation, volontairement. Sur un fork ou un clone, la fusion amont est <em>annul&eacute;e</em> et votre copie de travail reste intacte. Sur un projet autonome, le conflit est <em>laiss&eacute; en place</em> pour que vous le r&eacute;solviez &mdash; c''est votre d&eacute;p&ocirc;t, et c''est tout l''int&eacute;r&ecirc;t &mdash; et <code>git reset --hard HEAD</code> annule toute la mise &agrave; jour.</li>'
83
+ ),
84
+ '<p>La premi&egrave;re commande met &agrave; jour l''application, ses d&eacute;pendances et le sch&eacute;ma ; la seconde reconstruit et red&eacute;marre les conteneurs. Votre base de donn&eacute;es et vos m&eacute;dias vivent dans des volumes Docker et ne sont touch&eacute;s ni par l''une ni par l''autre &mdash; <code>docker:up</code> reconstruit des images, pas des donn&eacute;es.</p>',
85
+ '<p>La premi&egrave;re commande met &agrave; jour l''application et ses d&eacute;pendances et pr&eacute;pare les nouvelles migrations ; la seconde reconstruit les conteneurs <em>et applique ces migrations</em>. La pile auto-h&eacute;berg&eacute;e dispose de son propre service de migration : la mise &agrave; jour lui confie donc l''&eacute;tape sch&eacute;ma plut&ocirc;t que d''appliquer le m&ecirc;me SQL via deux suivis diff&eacute;rents. Votre base de donn&eacute;es et vos m&eacute;dias vivent dans des volumes Docker et ne sont touch&eacute;s par aucune des deux commandes &mdash; <code>docker:up</code> reconstruit des images, pas des donn&eacute;es.</p>'
86
+ )
87
+ )
88
+ ),
89
+ updated_at = now()
90
+ WHERE post_id = v_fr_post
91
+ AND block_type = 'text';
92
+ END IF;
93
+ END
94
+ $body$;