fix: use INSERT OR REPLACE with docs preservation instead of ON CONFLICT

ON CONFLICT DO UPDATE caused FTS5 trigger conflicts ("database disk
image is malformed") in CI. Reverted to INSERT OR REPLACE but now
reads existing npm_readme/ai_documentation_summary/ai_summary_generated_at
before saving and carries them through the replace.

Conceived by Romuald Członkowski - https://www.aiadvisors.pl/en

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
czlonkowski
2026-03-26 13:53:32 +01:00
parent 657d5ab60c
commit ab2dc9824e

View File

@@ -34,8 +34,13 @@ export class NodeRepository {
* Supports both core and community nodes via optional community fields
*/
saveNode(node: ParsedNode & Partial<CommunityNodeFields>): void {
// Preserve existing npm_readme and ai_documentation_summary on upsert
const existing = this.db.prepare(
'SELECT npm_readme, ai_documentation_summary, ai_summary_generated_at FROM nodes WHERE node_type = ?'
).get(node.nodeType) as { npm_readme?: string; ai_documentation_summary?: string; ai_summary_generated_at?: string } | undefined;
const stmt = this.db.prepare(`
INSERT INTO nodes (
INSERT OR REPLACE INTO nodes (
node_type, package_name, display_name, description,
category, development_style, is_ai_tool, is_trigger,
is_webhook, is_versioned, is_tool_variant, tool_variant_of,
@@ -43,37 +48,9 @@ export class NodeRepository {
properties_schema, operations, credentials_required,
outputs, output_names,
is_community, is_verified, author_name, author_github_url,
npm_package_name, npm_version, npm_downloads, community_fetched_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON CONFLICT(node_type) DO UPDATE SET
package_name = excluded.package_name,
display_name = excluded.display_name,
description = excluded.description,
category = excluded.category,
development_style = excluded.development_style,
is_ai_tool = excluded.is_ai_tool,
is_trigger = excluded.is_trigger,
is_webhook = excluded.is_webhook,
is_versioned = excluded.is_versioned,
is_tool_variant = excluded.is_tool_variant,
tool_variant_of = excluded.tool_variant_of,
has_tool_variant = excluded.has_tool_variant,
version = excluded.version,
documentation = excluded.documentation,
properties_schema = excluded.properties_schema,
operations = excluded.operations,
credentials_required = excluded.credentials_required,
outputs = excluded.outputs,
output_names = excluded.output_names,
is_community = excluded.is_community,
is_verified = excluded.is_verified,
author_name = excluded.author_name,
author_github_url = excluded.author_github_url,
npm_package_name = excluded.npm_package_name,
npm_version = excluded.npm_version,
npm_downloads = excluded.npm_downloads,
community_fetched_at = excluded.community_fetched_at,
updated_at = CURRENT_TIMESTAMP
npm_package_name, npm_version, npm_downloads, community_fetched_at,
npm_readme, ai_documentation_summary, ai_summary_generated_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`);
stmt.run(
@@ -105,7 +82,11 @@ export class NodeRepository {
node.npmPackageName || null,
node.npmVersion || null,
node.npmDownloads || 0,
node.communityFetchedAt || null
node.communityFetchedAt || null,
// Preserve existing docs data on upsert
existing?.npm_readme || null,
existing?.ai_documentation_summary || null,
existing?.ai_summary_generated_at || null
);
}