From c8fac06f24f166ebc4650edbafa3e08613e2d511 Mon Sep 17 00:00:00 2001 From: mleku Date: Wed, 3 Dec 2025 10:42:32 +0000 Subject: [PATCH] lint and correct cypher query code --- .claude/settings.local.json | 3 ++- pkg/neo4j/save-event.go | 11 ++++++++++- pkg/neo4j/social-event-processor.go | 16 ++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/.claude/settings.local.json b/.claude/settings.local.json index d97d4c8..0c9e3b5 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -167,7 +167,8 @@ "Bash(GOROOT=/home/mleku/go node run_wasm_tests.mjs:*)", "Bash(./orly:*)", "Bash(./orly -version:*)", - "Bash(./orly --version:*)" + "Bash(./orly --version:*)", + "Bash(GOOS=js GOARCH=wasm go test:*)" ], "deny": [], "ask": [] diff --git a/pkg/neo4j/save-event.go b/pkg/neo4j/save-event.go index 80887b9..4e555e8 100644 --- a/pkg/neo4j/save-event.go +++ b/pkg/neo4j/save-event.go @@ -154,13 +154,22 @@ CREATE (e)-[:AUTHORED_BY]->(a) paramName := fmt.Sprintf("eTag_%d", eTagIndex) params[paramName] = tagValue - // Add WITH clause before first OPTIONAL MATCH to transition from CREATE to MATCH + // Add WITH clause before OPTIONAL MATCH + // This is required because: + // 1. Cypher doesn't allow MATCH after CREATE without WITH + // 2. Cypher doesn't allow MATCH after FOREACH without WITH + // So we need WITH before EVERY OPTIONAL MATCH, not just the first if needsWithClause { cypher += ` // Carry forward event and author nodes for tag processing WITH e, a ` needsWithClause = false + } else { + // After a FOREACH, we need WITH to transition back to MATCH + cypher += ` +WITH e, a +` } cypher += fmt.Sprintf(` diff --git a/pkg/neo4j/social-event-processor.go b/pkg/neo4j/social-event-processor.go index d5d5379..eb20811 100644 --- a/pkg/neo4j/social-event-processor.go +++ b/pkg/neo4j/social-event-processor.go @@ -236,6 +236,7 @@ func (p *SocialEventProcessor) processReport(ctx context.Context, ev *event.E) e } // Create REPORTS relationship + // Note: WITH is required between CREATE and MERGE in Cypher cypher := ` // Create event tracking node CREATE (evt:ProcessedSocialEvent { @@ -248,6 +249,9 @@ func (p *SocialEventProcessor) processReport(ctx context.Context, ev *event.E) e superseded_by: null }) + // WITH required to transition from CREATE to MERGE + WITH evt + // Create or get reporter and reported users MERGE (reporter:NostrUser {pubkey: $reporter_pubkey}) MERGE (reported:NostrUser {pubkey: $reported_pubkey}) @@ -293,12 +297,15 @@ type UpdateContactListParams struct { // updateContactListGraph performs atomic graph update for contact list changes func (p *SocialEventProcessor) updateContactListGraph(ctx context.Context, params UpdateContactListParams) error { + // Note: WITH is required between CREATE and MERGE in Cypher cypher := ` // Mark old event as superseded (if exists) OPTIONAL MATCH (old:ProcessedSocialEvent {event_id: $old_event_id}) SET old.superseded_by = $new_event_id // Create new event tracking node + // WITH required after OPTIONAL MATCH + SET before CREATE + WITH old CREATE (new:ProcessedSocialEvent { event_id: $new_event_id, event_kind: 3, @@ -309,6 +316,9 @@ func (p *SocialEventProcessor) updateContactListGraph(ctx context.Context, param superseded_by: null }) + // WITH required to transition from CREATE to MERGE + WITH new + // Get or create author node MERGE (author:NostrUser {pubkey: $author_pubkey}) @@ -369,12 +379,15 @@ type UpdateMuteListParams struct { // updateMuteListGraph performs atomic graph update for mute list changes func (p *SocialEventProcessor) updateMuteListGraph(ctx context.Context, params UpdateMuteListParams) error { + // Note: WITH is required between CREATE and MERGE in Cypher cypher := ` // Mark old event as superseded (if exists) OPTIONAL MATCH (old:ProcessedSocialEvent {event_id: $old_event_id}) SET old.superseded_by = $new_event_id // Create new event tracking node + // WITH required after OPTIONAL MATCH + SET before CREATE + WITH old CREATE (new:ProcessedSocialEvent { event_id: $new_event_id, event_kind: 10000, @@ -385,6 +398,9 @@ func (p *SocialEventProcessor) updateMuteListGraph(ctx context.Context, params U superseded_by: null }) + // WITH required to transition from CREATE to MERGE + WITH new + // Get or create author node MERGE (author:NostrUser {pubkey: $author_pubkey})