Skip to content

Bug: Import pipeline does not create mentions relationships for nodespace:// links#869

Merged
malibio merged 2 commits into
mainfrom
feature/issue-868-bulk-mentions-import
Feb 1, 2026
Merged

Bug: Import pipeline does not create mentions relationships for nodespace:// links#869
malibio merged 2 commits into
mainfrom
feature/issue-868-bulk-mentions-import

Conversation

@malibio

@malibio malibio commented Feb 1, 2026

Copy link
Copy Markdown
Collaborator

Closes #868

Implement bulk creation of mention relationships during markdown import.
The import pipeline now transforms inter-file links to nodespace:// format
AND creates the corresponding mention relationships, enabling the
"Mentioned by" panel to work correctly for imported documents.

Changes:
- Add LinkTransformResult struct and transform_links_in_nodes_with_mentions()
  to collect (source_id, target_id) pairs during link transformation
- Add bulk_create_mentions() to SurrealStore following bulk_add_to_collections
  pattern with idempotency checks and self-reference filtering
- Update import pipeline Phase 1 to collect mentions during link transformation
- Add Step 5 to Phase 2 to bulk-create mention relationships after node insertion
- Add 14 new tests: 9 for mention collection, 5 for bulk_create_mentions

Edge cases handled:
- Self-references are filtered (source == target)
- Dead links produce no mentions (file not in import batch)
- External URLs (http, https, mailto, etc.) produce no mentions
- Existing nodespace:// links DO produce mentions (handles re-imports)
- Idempotent: duplicate mentions are detected and skipped

Co-Authored-By: Claude <noreply@anthropic.com>
@malibio

malibio commented Feb 1, 2026

Copy link
Copy Markdown
Collaborator Author

Code Review: PR #869 - Bulk Mentions Creation for Import Pipeline

Review Type: Initial Review
Reviewer: Principal Engineer AI


Requirements Validation (Issue #868)

Criterion Status Notes
transform_links_in_nodes() returns mentions pairs New function transform_links_in_nodes_with_mentions() added, original preserved for backward compat
bulk_create_mentions() added to SurrealStore Follows bulk_add_to_collections pattern
Import pipeline collects mentions during Phase 1 Line 670-680 in import.rs
Import pipeline creates mentions in Phase 2 (Step 5) Line 825-835 in import.rs
Self-references are excluded Filtered at both Rust level and SurrealStore
Invalid targets handled gracefully Dead links produce no mentions
Unit tests for bulk_create_mentions() 5 tests added
Unit tests for mention collection 9 tests added

All acceptance criteria met.


Code Review Findings

Architectural Assessment

🟢 Well-Structured Design: The implementation correctly follows the existing patterns in the codebase:

  • bulk_create_mentions() mirrors bulk_add_to_collections() pattern
  • transform_links_in_nodes_with_mentions() preserves the original API while extending functionality
  • Clean separation between link transformation and mention collection

🟢 Defense in Depth for Self-References: Self-references are filtered at multiple layers:

  1. In transform_links_in_nodes_with_mentions() (markdown.rs:251-256)
  2. In bulk_create_mentions() (surreal_store.rs:5232-5240)

This is good defensive programming - the SurrealStore should not trust callers blindly.

Code Quality

🟢 Excellent Documentation: Both new functions have comprehensive doc comments explaining purpose, arguments, return values, and implementation notes.

🟢 Comprehensive Test Coverage: 14 new tests cover:

  • Basic mention creation
  • Idempotency
  • Self-reference filtering
  • Empty input handling
  • Multiple mentions in batch
  • External URLs (no mentions)
  • Anchor links (no mentions)
  • Dead links (no mentions)
  • Existing nodespace:// links (DO produce mentions for re-imports)
  • Multiple nodes with multiple links

Suggestions for Improvement

🟡 [Improvement] bulk_create_mentions return value semantics

File: /packages/core/src/db/surreal_store.rs:5280-5281

// Return count of attempted mentions (actual created count would require parsing results)
Ok(valid_mentions.len())

The comment acknowledges this returns "attempted" rather than "actually created" count. While this follows the same pattern as bulk_add_to_collections, it could be misleading for callers. Consider:

  1. Renaming to attempted_count in docs/variable names for clarity, OR
  2. Parsing the query results to return actual created count (would require more complex result handling)

For now, the comment makes this clear, so this is acceptable.


🟢 [Nit] Code duplication in link transformation

File: /packages/core/src/mcp/handlers/markdown.rs:203-216 and 233-261

transform_links_in_nodes() and transform_links_in_nodes_with_mentions() have similar structure. Could potentially refactor the original to call the new one and discard the result:

pub fn transform_links_in_nodes(...) {
    let _ = transform_links_in_nodes_with_mentions(nodes, file_to_root_id, current_file_path, "");
}

However, this would add unnecessary overhead when mentions are not needed, so keeping them separate is a reasonable tradeoff for performance.


🟢 [Nit] Unstaged formatting changes

There are unstaged changes that appear to be rustfmt adjustments. These should be committed as part of the PR or run quality:fix before merge.


Security Assessment

No SQL Injection Risk: The SurrealDB query uses backtick-quoted identifiers for UUIDs (node:\{uuid}``), which is the correct pattern for safe interpolation.

No Secrets Exposure: No hardcoded credentials or sensitive data.

Input Validation: UUIDs are validated through the existing type system; self-references are explicitly filtered.


Performance Assessment

Batch Processing: Uses single transaction for all mentions (follows established pattern)

Idempotency Check Pattern: Uses LET + IF pattern to check existence before creating, avoiding duplicate relationship errors

Debug Logging: Includes timing information for performance monitoring


Test Results

All 14 new tests pass:

  • 5 tests for bulk_create_mentions in surreal_store.rs
  • 9 tests for mention collection in markdown_test.rs

Recommendation

✅ APPROVE

This is a well-implemented feature that:

  1. Solves the reported bug (mentions not created during import)
  2. Follows established codebase patterns
  3. Has comprehensive test coverage
  4. Handles all edge cases identified in the issue
  5. Is properly documented

The code is ready to merge after addressing the minor formatting changes (run quality:fix and commit).

@malibio malibio left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review complete. Recommendation: APPROVE. See detailed review comment above.

- Applied rustfmt formatting to test assertions
- Refactored transform_links_in_nodes to delegate to transform_links_in_nodes_with_mentions (DRY)
- Removed unused transform_links_in_content and transform_single_link functions

Addresses reviewer recommendations from PR #869 review.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@malibio

malibio commented Feb 1, 2026

Copy link
Copy Markdown
Collaborator Author

Review Feedback Addressed

Changes Made:

  • Applied rustfmt formatting to test assertions in surreal_store.rs and markdown_test.rs
  • Applied DRY refactor - transform_links_in_nodes() now delegates to transform_links_in_nodes_with_mentions() instead of duplicating logic
  • Removed dead code - transform_links_in_content() and transform_single_link() functions were removed as they're no longer used

Skipped Recommendations:

  • ⏭️ Return value semantics for bulk_create_mentions - Already well-documented in comments, follows existing pattern of bulk_add_to_collections

Test Results:

All 9 mention collection tests pass after the DRY refactor.

Re-Review Decision: NO RE-REVIEW NEEDED

The changes are:

  1. Pure formatting fixes (rustfmt)
  2. Straightforward DRY refactor with no logic changes
  3. Dead code removal

All tests pass and no new functionality was added.

🤖 Generated with Claude Code

@malibio malibio merged commit 440ce45 into main Feb 1, 2026
@malibio malibio deleted the feature/issue-868-bulk-mentions-import branch February 1, 2026 23:04
@malibio

malibio commented Feb 1, 2026

Copy link
Copy Markdown
Collaborator Author

Review Feedback Addressed

Changes in commit 6bb781c:

Addressed (1):

  • Applied rustfmt formatting to test assertions

Addressed (1) - User requested:

  • Applied DRY principle: transform_links_in_nodes() now delegates to transform_links_in_nodes_with_mentions()
  • Removed unused functions: transform_links_in_content() and transform_single_link()
  • Code reduction: -46 lines

⏭️ Skipped (1):

  • Return value semantics improvement - Already documented in code comments, follows existing pattern

Test Impact: All 14 new tests run in ~50ms total (negligible impact on test suite)

malibio added a commit that referenced this pull request Feb 4, 2026
…pace:// links (#869)

* Add bulk mentions creation to import pipeline (#868)

Implement bulk creation of mention relationships during markdown import.
The import pipeline now transforms inter-file links to nodespace:// format
AND creates the corresponding mention relationships, enabling the
"Mentioned by" panel to work correctly for imported documents.

Changes:
- Add LinkTransformResult struct and transform_links_in_nodes_with_mentions()
  to collect (source_id, target_id) pairs during link transformation
- Add bulk_create_mentions() to SurrealStore following bulk_add_to_collections
  pattern with idempotency checks and self-reference filtering
- Update import pipeline Phase 1 to collect mentions during link transformation
- Add Step 5 to Phase 2 to bulk-create mention relationships after node insertion
- Add 14 new tests: 9 for mention collection, 5 for bulk_create_mentions

Edge cases handled:
- Self-references are filtered (source == target)
- Dead links produce no mentions (file not in import batch)
- External URLs (http, https, mailto, etc.) produce no mentions
- Existing nodespace:// links DO produce mentions (handles re-imports)
- Idempotent: duplicate mentions are detected and skipped

Co-Authored-By: Claude <noreply@anthropic.com>

* Address review: Apply formatting and DRY refactor

- Applied rustfmt formatting to test assertions
- Refactored transform_links_in_nodes to delegate to transform_links_in_nodes_with_mentions (DRY)
- Removed unused transform_links_in_content and transform_single_link functions

Addresses reviewer recommendations from PR #869 review.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
malibio added a commit that referenced this pull request Feb 5, 2026
…pace:// links (#869)

* Add bulk mentions creation to import pipeline (#868)

Implement bulk creation of mention relationships during markdown import.
The import pipeline now transforms inter-file links to nodespace:// format
AND creates the corresponding mention relationships, enabling the
"Mentioned by" panel to work correctly for imported documents.

Changes:
- Add LinkTransformResult struct and transform_links_in_nodes_with_mentions()
  to collect (source_id, target_id) pairs during link transformation
- Add bulk_create_mentions() to SurrealStore following bulk_add_to_collections
  pattern with idempotency checks and self-reference filtering
- Update import pipeline Phase 1 to collect mentions during link transformation
- Add Step 5 to Phase 2 to bulk-create mention relationships after node insertion
- Add 14 new tests: 9 for mention collection, 5 for bulk_create_mentions

Edge cases handled:
- Self-references are filtered (source == target)
- Dead links produce no mentions (file not in import batch)
- External URLs (http, https, mailto, etc.) produce no mentions
- Existing nodespace:// links DO produce mentions (handles re-imports)
- Idempotent: duplicate mentions are detected and skipped

Co-Authored-By: Claude <noreply@anthropic.com>

* Address review: Apply formatting and DRY refactor

- Applied rustfmt formatting to test assertions
- Refactored transform_links_in_nodes to delegate to transform_links_in_nodes_with_mentions (DRY)
- Removed unused transform_links_in_content and transform_single_link functions

Addresses reviewer recommendations from PR #869 review.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
malibio added a commit that referenced this pull request Feb 26, 2026
…pace:// links (#869)

* Add bulk mentions creation to import pipeline (#868)

Implement bulk creation of mention relationships during markdown import.
The import pipeline now transforms inter-file links to nodespace:// format
AND creates the corresponding mention relationships, enabling the
"Mentioned by" panel to work correctly for imported documents.

Changes:
- Add LinkTransformResult struct and transform_links_in_nodes_with_mentions()
  to collect (source_id, target_id) pairs during link transformation
- Add bulk_create_mentions() to SurrealStore following bulk_add_to_collections
  pattern with idempotency checks and self-reference filtering
- Update import pipeline Phase 1 to collect mentions during link transformation
- Add Step 5 to Phase 2 to bulk-create mention relationships after node insertion
- Add 14 new tests: 9 for mention collection, 5 for bulk_create_mentions

Edge cases handled:
- Self-references are filtered (source == target)
- Dead links produce no mentions (file not in import batch)
- External URLs (http, https, mailto, etc.) produce no mentions
- Existing nodespace:// links DO produce mentions (handles re-imports)
- Idempotent: duplicate mentions are detected and skipped

Co-Authored-By: Claude <noreply@anthropic.com>

* Address review: Apply formatting and DRY refactor

- Applied rustfmt formatting to test assertions
- Refactored transform_links_in_nodes to delegate to transform_links_in_nodes_with_mentions (DRY)
- Removed unused transform_links_in_content and transform_single_link functions

Addresses reviewer recommendations from PR #869 review.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Import pipeline does not create mentions relationships for nodespace:// links

1 participant