From fef9242e50492a67e484953e1cf82ef890e800bd Mon Sep 17 00:00:00 2001 From: Thunpisit Amnuaikiatloet Date: Sun, 3 May 2026 17:36:43 +0700 Subject: [PATCH] fix: lint errors + FTS5 external-content migration (matches upstream PR #49 + PR #50) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cherry-picks both upstream fixes: - PR #49 (closes #47) — 7 ESLint errors blocking CI on fresh install - PR #50 (closes #48) — switch articles_fts from contentless to external-content FTS5; UPDATE/DELETE on article_localizations no longer throws SQLITE_ERROR Migration 0011 already applied to live D1 (same database serves both repos). Co-Authored-By: Claude Opus 4.7 --- drizzle/0011_fts5_external_content.sql | 73 +++++++++++++++++++ drizzle/meta/_journal.json | 7 ++ .../components/consent/CookieBanner.svelte | 1 + src/lib/components/seo/Seo.svelte | 11 ++- src/lib/server/webhooks/index.ts | 4 +- .../(cms)/cms/dashboard/+page.server.ts | 2 +- src/routes/(cms)/cms/media/+page.svelte | 5 +- .../(www)/[locale]/[...slug]/+page.svelte | 1 + 8 files changed, 99 insertions(+), 5 deletions(-) create mode 100644 drizzle/0011_fts5_external_content.sql diff --git a/drizzle/0011_fts5_external_content.sql b/drizzle/0011_fts5_external_content.sql new file mode 100644 index 0000000..fa2e77d --- /dev/null +++ b/drizzle/0011_fts5_external_content.sql @@ -0,0 +1,73 @@ +-- Fix #48: switch articles_fts from a contentless FTS5 table to an +-- external-content table (content='article_localizations', +-- content_rowid='rowid'). +-- +-- The contentless pattern from migration 0002 requires the +-- ('delete', old.rowid, …all column values…) tuple to **exactly +-- match** what's stored in the index. Any drift — different +-- normalization, trailing newline, prior failed REPLACE — makes the +-- delete-trigger fail with SQLITE_ERROR. UPDATE inherits that fault. +-- After-effect on the CMS: editors couldn't update or delete an +-- article_localizations row once any drift had occurred. +-- +-- The external-content pattern lets the trigger reference rowid +-- alone: +-- INSERT INTO articles_fts(articles_fts, rowid) VALUES('delete', old.rowid); +-- — no column values to match against, so drift becomes a non-issue. +-- And `rebuild` can recover from any inconsistency without dropping +-- the table. +-- +-- Migration steps: +-- 1. Drop the old triggers (must happen before dropping the table). +-- 2. Drop the old virtual table. +-- 3. Recreate as external-content. +-- 4. Rebuild the index from article_localizations in one shot. +-- 5. Recreate triggers using the simpler delete pattern. + +DROP TRIGGER IF EXISTS articles_fts_ai; +--> statement-breakpoint +DROP TRIGGER IF EXISTS articles_fts_ad; +--> statement-breakpoint +DROP TRIGGER IF EXISTS articles_fts_au; +--> statement-breakpoint +DROP TABLE IF EXISTS articles_fts; +--> statement-breakpoint + +CREATE VIRTUAL TABLE IF NOT EXISTS articles_fts USING fts5( + title, + excerpt, + body, + locale UNINDEXED, + article_id UNINDEXED, + content = 'article_localizations', + content_rowid = 'rowid', + tokenize = 'unicode61 remove_diacritics 2' +); +--> statement-breakpoint + +-- Build the index from current state. With external-content, this +-- reads from article_localizations directly (the `content =` link +-- above tells FTS5 where to look). +INSERT INTO articles_fts(articles_fts) VALUES('rebuild'); +--> statement-breakpoint + +-- Triggers — simpler than before because external-content tables +-- only need rowid for delete (the source-of-truth values come from +-- the linked table itself). + +CREATE TRIGGER IF NOT EXISTS articles_fts_ai AFTER INSERT ON article_localizations BEGIN + INSERT INTO articles_fts(rowid, title, excerpt, body, locale, article_id) + VALUES (new.rowid, new.title, COALESCE(new.excerpt, ''), new.body, new.locale, new.article_id); +END; +--> statement-breakpoint + +CREATE TRIGGER IF NOT EXISTS articles_fts_ad AFTER DELETE ON article_localizations BEGIN + INSERT INTO articles_fts(articles_fts, rowid) VALUES('delete', old.rowid); +END; +--> statement-breakpoint + +CREATE TRIGGER IF NOT EXISTS articles_fts_au AFTER UPDATE ON article_localizations BEGIN + INSERT INTO articles_fts(articles_fts, rowid) VALUES('delete', old.rowid); + INSERT INTO articles_fts(rowid, title, excerpt, body, locale, article_id) + VALUES (new.rowid, new.title, COALESCE(new.excerpt, ''), new.body, new.locale, new.article_id); +END; diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json index 1960032..336d92d 100644 --- a/drizzle/meta/_journal.json +++ b/drizzle/meta/_journal.json @@ -78,6 +78,13 @@ "when": 1777709468165, "tag": "0010_windy_carmella_unuscione", "breakpoints": true + }, + { + "idx": 11, + "version": "6", + "when": 1778060000000, + "tag": "0011_fts5_external_content", + "breakpoints": true } ] } \ No newline at end of file diff --git a/src/lib/components/consent/CookieBanner.svelte b/src/lib/components/consent/CookieBanner.svelte index 3742bee..9ada8ff 100644 --- a/src/lib/components/consent/CookieBanner.svelte +++ b/src/lib/components/consent/CookieBanner.svelte @@ -46,6 +46,7 @@

{m.cookie_banner_title()}

{m.cookie_banner_body()} + {m.cookie_banner_learn_more()}

{#if detailsOpen} diff --git a/src/lib/components/seo/Seo.svelte b/src/lib/components/seo/Seo.svelte index f04141f..0431ba6 100644 --- a/src/lib/components/seo/Seo.svelte +++ b/src/lib/components/seo/Seo.svelte @@ -88,9 +88,16 @@ {/if} - + {#each jsonLd as ld, i (i)} - {@html ` escaped --> + {@html '