Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rework node query to apply correct visibility rules as with tree traversal and listing #204

Merged
merged 1 commit into from
Oct 10, 2024

Conversation

Southclaws
Copy link
Owner

@Southclaws Southclaws commented Oct 10, 2024

When "Visibility rules" were implemented, I neglected to apply the logic to "Node Get" operations and only to tree traversal and mutations.

This meant that a page that was published which had un-published child pages were visible to anyone. Un-published pages included those that were: unlisted, draft or in-review.

This fix applies the same visibility rules so when a page (node) is requested, the children are returned with the following logic:

  • if the child page is visibility: published, include it in the response
  • otherwise, only include it if the child node's owner account is the requesting session account

This ensures:

  • published pages are still always included in a NodeGet operation
  • authors who are drafting new pages or submitting new pages for review can see their drafts/submissions as child nodes of any node they read
  • other users cannot see drafts and submissions of nodes they read

Also in this PR:

  • node repository is now split into reader/writer to fit DDD-esque separation of concerns design that the rest of the codebase is moving towards
  • library node/page tests updated a bit to be more readable and make use of newer helper assertion functions (tests.Ok etc)

…ersal and listing

also improve tests for library nodes
Copy link

vercel bot commented Oct 10, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

2 Skipped Deployments
Name Status Preview Comments Updated (UTC)
storyden ⬜️ Ignored (Inspect) Visit Preview Oct 10, 2024 0:16am
storyden-homepage ⬜️ Ignored (Inspect) Visit Preview Oct 10, 2024 0:16am

Copy link

coderabbitai bot commented Oct 10, 2024

📝 Walkthrough

Walkthrough

This pull request involves significant structural changes to the library's database handling. It removes the database struct and Repository interface, replacing them with new node_querier and node_writer components. The changes affect various files across the application, updating method signatures and dependencies to reflect the new architecture. Additionally, new test files have been added to validate the functionality of node operations, while existing tests for the datagraph functionality have been removed.

Changes

File Path Change Summary
app/resources/library/db.go Deleted database struct and associated CRUD methods.
app/resources/library/library.go Deleted Repository interface and related functional options.
app/resources/library/node_children/db.go Updated nr field type from library.Repository to *node_querier.Querier.
app/resources/library/node_querier/node_querier.go Introduced Querier struct and methods for querying nodes.
app/resources/library/node_writer/node_writer.go Introduced Writer struct and methods for node mutations.
app/resources/resources.go Removed import of library, added imports for node_querier and node_writer.
app/resources/seed/seed.go Updated to use *node_writer.Writer for node_repo.
app/services/asset/analyse/analyse.go Updated nodereader field from library.Repository to *node_querier.Querier.
app/services/asset/analyse/pdf.go Modified analysePDF method to use Probe instead of GetByID.
app/services/asset/asset_upload/uploader.go Updated nodewriter field from library.Repository to *node_writer.Writer.
app/services/library/node_mutate/node.go Refactored to use node_writer interface instead of library interface.
app/services/library/node_read/reader.go Updated nodereader field from library.Repository to *node_querier.Querier.
app/services/library/node_visibility/visibility.go Updated fields to use *node_querier.Querier and *node_writer.Writer.
app/services/library/nodetree/nodetree.go Refactored to use nodeQuerier and nodeWriter.
app/services/link/fetcher/fetcher.go Removed library.Repository from New constructor.
app/services/link/scrape_job/scrape.go Updated nodes field to *node_writer.Writer.
app/services/semdex/index_job/indexer.go Updated nodeRepo field to *node_querier.Querier.
app/services/semdex/semdexer/refhydrate/hydrator.go Added nodeQuerier field of type *node_querier.Querier.
app/services/semdex/summarise_job/summariser.go Updated nodeRepo field to *node_writer.Writer.
tests/datagraph/datagraph_test.go Deleted file containing unit tests for datagraph.
tests/library/children/children_test.go Introduced children_test.go with TestLibraryNodeChildren.
tests/library/deletion/deletion_test.go Introduced deletion_test.go for node deletion functionality.
tests/library/helpers.go Added UniqueNode function for generating unique identifiers.
tests/library/visibility/visibility_test.go Modified TestNodesVisibility to change context variable from ctx to root.

Possibly related PRs

  • implement marks for library nodes #193: Involves modifications to the database struct and Repository interface, updating method signatures to use QueryKey, which aligns with the changes made in this PR regarding the removal of the database struct and its CRUD methods.

🐰 In the forest, where rabbits play,
New structures bloom, bright as day.
No more database, a fresh new start,
With node_querier and writer at heart.
Hopping through code, we cheer and delight,
For changes like these make our future bright! 🌟


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 10

🧹 Outside diff range and nitpick comments (12)
tests/library/helpers.go (1)

8-14: LGTM with suggestions: Consider edge cases and test flexibility.

The UniqueNode function effectively generates a unique node for testing purposes. However, consider the following improvements:

  1. Add input validation for the name parameter to handle empty strings or invalid characters.
  2. Consider implementing a max length for the generated slug to avoid potential issues with very long identifiers.
  3. For increased test flexibility, consider adding an option to provide a custom slug or use a deterministic slug generation for specific test cases.

Here's a suggested implementation incorporating these improvements:

func UniqueNode(name string, opts ...func(*openapi.NodeInitialProps)) openapi.NodeInitialProps {
	if name == "" {
		name = "unnamed_node"
	}
	slug := name + "_" + uuid.NewString()
	if len(slug) > 100 {
		slug = slug[:100]
	}
	node := openapi.NodeInitialProps{
		Name: name,
		Slug: &slug,
	}
	for _, opt := range opts {
		opt(&node)
	}
	return node
}

// Usage example:
// customSlug := UniqueNode("test", func(n *openapi.NodeInitialProps) {
//     *n.Slug = "custom_slug"
// })

This implementation adds input validation, limits the slug length, and allows for custom modifications through optional functional parameters.

app/resources/library/node_children/db.go (1)

Line range hint 1-72: Summary of changes and potential impact.

The changes in this file reflect a shift from using a generic library.Repository to a more specific *node_querier.Querier. This change is consistently applied to both the database struct and the New function. The Move function remains unchanged, which suggests that the Querier interface likely provides similar functionality to the previous Repository interface.

These changes may have broader implications:

  1. Other parts of the codebase that interact with this package might need to be updated to use the new Querier.
  2. The Repository interface might need to be reviewed to ensure it still accurately represents the abstraction needed.
  3. There might be performance or behavior changes due to the use of Querier instead of Repository, which should be verified through testing.

Overall, this change appears to be part of a larger refactoring effort to improve the specificity and possibly the performance of database operations. Ensure that comprehensive testing is performed to validate that existing functionality is maintained and that any performance improvements are measurable.

app/services/semdex/semdexer/refhydrate/hydrator.go (1)

54-54: LGTM: Hydrate method updated correctly

The Hydrate method has been appropriately updated to use the new nodeQuerier.Probe method instead of the previous library.GetByID. This change aligns with the PR objectives and is consistent with the other modifications in the file.

Consider enhancing the error handling to provide more context:

if err != nil {
    return nil, fault.Wrap(err, fctx.With(ctx, fctx.With("kind", "node")))
}

This addition would make debugging easier by specifying which kind of item (node) caused the error.

tests/library/children/children_test.go (3)

1-18: Consider aligning the package name with the directory structure.

The package is named datagraph_test, but the file is located in tests/library/children. It might be more appropriate to name the package children_test or library_test to better reflect its location and purpose.


30-36: Good test context setup, but contains unused code.

The test context and session setup look good, following appropriate practices for end-to-end testing. However, there's an unused commented-out variable iurl that should be removed to keep the code clean.

Consider removing the unused commented-out variable:

-			// iurl := "https://picsum.photos/500/500"

37-77: Well-structured node creation and relationship testing.

The test effectively creates three nodes and establishes the correct parent-child relationships between them. The use of UUIDs for unique slugs and proper error checking after each operation are good practices.

To improve readability, consider adding a comment before each node creation to clearly indicate the intended hierarchy structure.

Add comments to clarify the node hierarchy:

+			// Create root node
 			name1 := "test-node-1"
 			slug1 := name1 + uuid.NewString()
 			node1, err := cl.NodeCreateWithResponse(ctx, openapi.NodeInitialProps{
 				Name: name1,
 				Slug: &slug1,
 			}, session)
 			tests.Ok(t, err, node1)

-			// Add a child node
+			// Create first child node (node1 -> node2)
 			name2 := "test-node-2"
 			slug2 := name2 + uuid.NewString()
 			node2, err := cl.NodeCreateWithResponse(ctx, openapi.NodeInitialProps{
 				Name: name2,
 				Slug: &slug2,
 			}, session)
 			tests.Ok(t, err, node2)

+			// Establish relationship: node1 -> node2
 			cadd, err := cl.NodeAddNodeWithResponse(ctx, slug1, slug2, session)
 			tests.Ok(t, err, cadd)

 			r.Equal(node1.JSON200.Id, cadd.JSON200.Id)

-			// Add another child to this child
-			// node1
-			// |- node2
-			//    |- node3
+			// Create second child node (node1 -> node2 -> node3)
 			name3 := "test-node-3"
 			slug3 := name3 + uuid.NewString()
 			node3, err := cl.NodeCreateWithResponse(ctx, openapi.NodeInitialProps{
 				Name: name3,
 				Slug: &slug3,
 			}, session)
 			tests.Ok(t, err, node3)

+			// Establish relationship: node2 -> node3
 			cadd, err = cl.NodeAddNodeWithResponse(ctx, slug2, slug3, session)
 			tests.Ok(t, err, cadd)

 			r.Equal(node2.JSON200.Id, cadd.JSON200.Id)
app/resources/seed/seed.go (1)

Line range hint 1-89: Summary of changes and potential impact

The modifications in this file reflect a significant architectural shift in how node operations are handled:

  1. The import change from library to node_writer indicates a move towards more specialized components.
  2. The New function's node_repo parameter type change from library.Repository to *node_writer.Writer aligns with this new approach.

These changes are consistent with the PR's objective of reworking the node query functionality. However, they may have broader implications:

  • The use of a concrete type (*node_writer.Writer) instead of an interface could impact the flexibility of the codebase.
  • Other parts of the system that relied on the library.Repository interface might need adjustments.

Ensure that these changes are consistently applied throughout the codebase and that all affected components are updated accordingly.

tests/library/deletion/deletion_test.go (3)

1-122: LGTM! Consider adding package documentation.

The overall structure of the test file is well-organized and follows good testing practices. The use of parallel testing and dependency injection is commendable.

Consider adding a package comment at the beginning of the file to provide an overview of the test suite's purpose and structure. For example:

// Package deletion_test provides integration tests for the node deletion functionality
// in the library. It tests various scenarios of deleting nodes in a tree structure,
// ensuring that the deletion logic maintains the integrity of the tree.
package deletion_test

41-65: LGTM! Consider adding an assertion for node1.

The test case for deleting a leaf node is well-structured and covers the basic scenario effectively.

To make the test more comprehensive, consider adding an assertion to verify that node1's state remains unchanged after the deletion of node3. This would ensure that the deletion operation doesn't have unexpected side effects on the root node. For example:

node1get, err := cl.NodeGetWithResponse(ctx, node1.JSON200.Slug, session)
tests.Ok(t, err, node1get)
a.Len(node1get.JSON200.Children, 1, "node1 should still have one child (node2)")

67-91: LGTM! Consider adding an assertion for node3.

The test case for deleting a parent node with a target is well-structured and effectively tests the scenario.

To make the test more robust, consider adding an assertion to directly verify node3's new parent after the deletion of node2. This would ensure that the child node is correctly reassigned. For example:

node3get, err := cl.NodeGetWithResponse(ctx, node3.JSON200.Slug, session)
tests.Ok(t, err, node3get)
a.NotNil(node3get.JSON200.Parent, "node3 should have a parent")
a.Equal(node1.JSON200.Id, node3get.JSON200.Parent.Id, "node3's new parent should be node1")
app/services/library/node_visibility/visibility.go (1)

Line range hint 72-74: Implement event emission and notifications for published nodes

The TODO comment indicates that when a node's visibility changes to Published, events should be emitted, and notifications sent. Implementing this ensures users are informed about new published content.

Would you like assistance in generating the code to emit events and send notifications, or should we open a new GitHub issue to track this task?

app/resources/library/node_querier/node_querier.go (1)

103-103: Address the TODO: Implement a lightweight Node representation for probing

The Probe method is intended for quick existence checks without loading related edges. Implementing a slimmed-down version of the Node struct or adjusting the query to exclude unnecessary fields can improve performance.

Would you like assistance in refactoring the Probe method to enhance efficiency? I can help develop a minimal Node struct or modify the query accordingly.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between a5006a2 and cb2892b.

📒 Files selected for processing (24)
  • app/resources/library/db.go (0 hunks)
  • app/resources/library/library.go (0 hunks)
  • app/resources/library/node_children/db.go (1 hunks)
  • app/resources/library/node_querier/node_querier.go (1 hunks)
  • app/resources/library/node_writer/node_writer.go (1 hunks)
  • app/resources/resources.go (2 hunks)
  • app/resources/seed/seed.go (2 hunks)
  • app/services/asset/analyse/analyse.go (2 hunks)
  • app/services/asset/analyse/pdf.go (1 hunks)
  • app/services/asset/asset_upload/uploader.go (4 hunks)
  • app/services/library/node_mutate/node.go (11 hunks)
  • app/services/library/node_read/reader.go (2 hunks)
  • app/services/library/node_visibility/visibility.go (4 hunks)
  • app/services/library/nodetree/nodetree.go (6 hunks)
  • app/services/link/fetcher/fetcher.go (0 hunks)
  • app/services/link/scrape_job/scrape.go (2 hunks)
  • app/services/semdex/index_job/indexer.go (5 hunks)
  • app/services/semdex/semdexer/refhydrate/hydrator.go (2 hunks)
  • app/services/semdex/summarise_job/summariser.go (5 hunks)
  • tests/datagraph/datagraph_test.go (0 hunks)
  • tests/library/children/children_test.go (1 hunks)
  • tests/library/deletion/deletion_test.go (1 hunks)
  • tests/library/helpers.go (1 hunks)
  • tests/library/visibility/visibility_test.go (10 hunks)
💤 Files with no reviewable changes (4)
  • app/resources/library/db.go
  • app/resources/library/library.go
  • app/services/link/fetcher/fetcher.go
  • tests/datagraph/datagraph_test.go
🧰 Additional context used
🔇 Additional comments (67)
tests/library/helpers.go (1)

3-6: LGTM: Imports are appropriate and necessary.

The imports are well-chosen for the function's requirements. The openapi package from the project and the uuid package from Google are both relevant to the UniqueNode function's implementation.

app/services/semdex/summarise_job/summariser.go (4)

12-12: LGTM: Import statement added correctly.

The new import for the node_writer package is consistent with the changes made in the rest of the file.


22-22: LGTM: Struct field updated appropriately.

The replacement of nodeRepo with nodeWriter is consistent with the architectural changes mentioned in the PR objectives. The use of a pointer type for nodeWriter is appropriate for a complex type like Writer.


32-32: LGTM: Function signature and struct initialization updated correctly.

The changes to the newSummariseConsumer function signature and the corresponding struct initialization are consistent with the modifications made to the summariseConsumer struct. The parameter type and field assignment correctly reflect the new nodeWriter field.

Also applies to: 41-41


55-55: LGTM with a suggestion: Method call updated correctly, but review error handling.

The update to use i.nodeWriter.Update with node_writer.WithDescription is consistent with the architectural changes. However, please review the error handling to ensure it's still appropriate for the new nodeWriter.Update method, as its error semantics might differ from the previous nodeRepo.Update.

To verify the error handling, please run the following script:

app/services/asset/analyse/pdf.go (1)

25-25: LGTM. Verify implications of using Probe instead of GetByID.

The change from GetByID to Probe aligns with the PR objective of applying correct visibility rules. This modification likely improves how nodes are accessed or validated.

To ensure this change doesn't introduce unintended side effects, please verify:

  1. Error handling: Confirm that Probe returns the same error types as GetByID.
  2. Performance: Check if Probe has any performance implications compared to GetByID.
  3. Visibility rules: Ensure that Probe correctly applies the intended visibility rules.

Run the following script to compare the implementations of GetByID and Probe:

app/resources/library/node_children/db.go (2)

13-13: LGTM: New import added for node_querier package.

The addition of this import is consistent with the changes made to the database struct and New function. It's good to see that the node_querier package is part of the same project structure.


23-23: Approve New function signature change, but verify Repository interface.

The update to the New function signature is consistent with the changes made to the database struct. It's good that the function still returns a Repository interface, maintaining the abstraction.

Please verify if the Repository interface needs to be updated to reflect any changes in the methods of node_querier.Querier. Run the following script to compare the methods:

#!/bin/bash
# Description: Compare methods of Repository interface and node_querier.Querier

# Test: Extract and compare method signatures
echo "Repository interface methods:"
ast-grep --lang go --pattern 'type Repository interface {
  $$$
}' | sed -n '/type Repository interface {/,/}/p' | grep -v '^\s*$' | grep -v '}'

echo "\nnode_querier.Querier methods:"
ast-grep --lang go --pattern 'type Querier struct {
  $$$
}' | sed -n '/type Querier struct {/,/}/p' | grep -v '^\s*$' | grep -v '}'
app/services/link/scrape_job/scrape.go (4)

14-14: LGTM: Import statement addition is appropriate.

The addition of the node_writer package import is consistent with the changes made to the scrapeConsumer struct and its methods. This import is necessary to support the new nodeWriter field.


30-35: LGTM: Constructor updated consistently with struct changes.

The modifications to the newScrapeConsumer function signature and struct initialization are consistent with the changes made to the scrapeConsumer struct.

To ensure this change doesn't break any existing code, please run the following script:

#!/bin/bash
# Description: Check for any calls to the old constructor signature

# Test: Search for calls to newScrapeConsumer with the old signature
rg --type go "newScrapeConsumer\(.+,\s*\w+\s*library\.Repository\)"

If this search returns results, it may indicate areas of the code that need to be updated to use the new constructor signature.


55-55: LGTM: Method call updated consistently with struct changes.

The replacement of s.nodes.Update with s.nodeWriter.Update is consistent with the changes made to the scrapeConsumer struct. The use of node_writer.WithContentLinks instead of library.WithContentLinks suggests a change in package structure or functionality.

To ensure the WithContentLinks function in the node_writer package has the same functionality as the previous library.WithContentLinks, please run the following script:

#!/bin/bash
# Description: Compare the WithContentLinks functions in library and node_writer packages

# Test: Search for the WithContentLinks function in the library package
echo "library.WithContentLinks:"
ast-grep --lang go --pattern 'func WithContentLinks($_) $_'

# Test: Search for the WithContentLinks function in the node_writer package
echo "node_writer.WithContentLinks:"
ast-grep --lang go --pattern 'func WithContentLinks($_) $_'

Compare the results to ensure that the functionality of WithContentLinks is preserved in the node_writer package.


22-24: LGTM: Struct field change improves code organization.

The replacement of nodes library.Repository with nodeWriter *node_writer.Writer aligns with the PR objectives and potentially improves code organization by using a dedicated writer for node operations.

To ensure this change doesn't negatively impact other parts of the codebase, please run the following script:

If these searches return results, it may indicate areas of the code that need to be updated to use the new nodeWriter field.

✅ Verification successful

Verification Successful: No remaining references to nodes library.Repository.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining usages of the old 'nodes' field in the codebase

# Test: Search for any remaining references to 'nodes library.Repository'
rg --type go "nodes\s+library\.Repository"

# Test: Search for any method calls on the old 'nodes' field
rg --type go "s\.nodes\."

Length of output: 3649

app/services/asset/analyse/analyse.go (2)

11-11: LGTM: Import statement added for node_querier package

The addition of the import statement for the node_querier package is consistent with the changes made to the Analyser struct and its constructor. This import is necessary to support the new *node_querier.Querier type.


20-20: LGTM: Analyser struct and constructor updated to use node_querier.Querier

The changes to the Analyser struct and its constructor are consistent with the new import and reflect a shift from using library.Repository to *node_querier.Querier. This change likely represents an architectural improvement, possibly moving to a more specialized querying component.

To ensure these changes don't negatively impact other parts of the codebase, please run the following verification script:

This script will help identify any areas of the codebase that might need attention due to these changes.

Also applies to: 27-27

✅ Verification successful

Verification Successful: No remaining references to library.Repository

The verification script did not find any remaining uses of library.Repository in the codebase. The changes to the Analyser struct and its constructor have been successfully applied without introducing any inconsistencies elsewhere.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining uses of library.Repository that might need updating

# Test 1: Search for any remaining uses of library.Repository
echo "Searching for remaining uses of library.Repository:"
rg --type go "library\.Repository"

# Test 2: Check for any files that might need updating due to the Analyser changes
echo "Checking for files that might need updating due to Analyser changes:"
rg --type go "analyse\.Analyser|analyse\.New"

Length of output: 529

app/services/semdex/semdexer/refhydrate/hydrator.go (3)

17-17: LGTM: New import added correctly

The new import for node_querier is correctly added and aligns with the changes made to the Hydrator struct and its methods.


24-26: LGTM: Hydrator struct updated correctly

The Hydrator struct has been appropriately modified to replace the library field with a nodeQuerier field. This change aligns with the PR objectives and is consistent with the other modifications in the file.


32-37: LGTM: New function updated correctly

The New function has been properly updated to reflect the changes in the Hydrator struct. The function signature and struct initialization are consistent with the new nodeQuerier field, replacing the previous library dependency.

app/services/asset/asset_upload/uploader.go (4)

15-15: LGTM: New import aligns with architectural changes.

The addition of the node_writer import is consistent with the shift from library.Repository to a more specialized *node_writer.Writer. This change supports better modularity in the codebase.


68-68: LGTM: Method call updated to use node_writer package.

The update from library.WithAssets to node_writer.WithAssets is consistent with the architectural changes. This maintains the functionality while adhering to the new structure.

To ensure the WithAssets function in the node_writer package has the correct signature and functionality, please run the following verification:

#!/bin/bash
# Check the definition of WithAssets in the node_writer package
ast-grep --lang go --pattern 'func WithAssets($_) $_' app/resources/library/node_writer

35-35: LGTM: Constructor signature updated correctly.

The New function signature has been properly updated to match the changes in the Uploader struct. This ensures consistency in the use of *node_writer.Writer.

To ensure all callers of this function have been updated, please run the following verification:

#!/bin/bash
# Find all calls to the New function in the asset_upload package
rg --type go -e "New\s*\(" app/services/asset/asset_upload

26-26: Approve change and verify impact on node writing operations.

The update from library.Repository to *node_writer.Writer aligns with the PR's objective of reworking node queries. This change likely provides more specific and efficient node writing capabilities.

To ensure this change doesn't introduce unintended side effects, please run the following verification:

✅ Verification successful

Verification Successful: All usages of nodewriter have been correctly updated.

No issues found in the codebase regarding the nodewriter field.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify that all usages of the nodewriter field are updated correctly
rg --type go -e "nodewriter\." app/services/asset/asset_upload

Length of output: 456

tests/library/children/children_test.go (1)

20-29: Well-structured test setup using dependency injection.

The test function is appropriately named and set to run in parallel. The use of fx.Invoke for dependency injection is a good practice, allowing for a clean and maintainable test setup.

app/services/semdex/index_job/indexer.go (4)

14-14: LGTM: Import statement added correctly.

The new import for the node_querier package is consistent with the changes made in the struct and methods.


41-41: LGTM: Constructor function updated correctly.

The changes in the newIndexConsumer function are consistent with the struct modification. Both the parameter and the field assignment have been updated to use the new nodeQuerier *node_querier.Querier.

To ensure this change doesn't break any existing code, please run the following verification:

#!/bin/bash
# Search for calls to newIndexConsumer function
rg --type go "newIndexConsumer\("

Also applies to: 55-55


75-75: LGTM: Method call updated to use new querier.

The change from i.nodeRepo.GetByID(ctx, id) to i.nodeQuerier.Probe(ctx, id) is consistent with the new querying approach. However, the change in method name from GetByID to Probe might indicate a difference in functionality.

To ensure compatibility and correct behavior, please verify the following:

  1. Check that the Probe method returns the same type of result as the previous GetByID method.
  2. Confirm that the Probe method handles errors in the same way as GetByID.

You can use the following command to inspect the Probe method:


26-26: LGTM: Struct field updated to use new querier.

The change from nodeRepo library.Repository to nodeQuerier *node_querier.Querier aligns with the new querying approach. This shift in data access pattern is consistent with the PR objectives.

To ensure this change doesn't negatively impact other parts of the codebase, please run the following verification:

app/resources/seed/seed.go (2)

14-14: Import change reflects architectural shift

The replacement of the library import with node_writer aligns with the PR's objective of reworking the node query functionality. This change suggests a move towards more specialized components for handling node operations.


61-61: Verify impact of node_repo type change

The node_repo parameter type has changed from library.Repository to *node_writer.Writer. This change aligns with the new import and suggests a shift towards a more concrete implementation for node writing operations.

While this may provide more direct access to writing functionalities, it could potentially reduce flexibility in terms of dependency injection.

Please verify that this change doesn't negatively impact other parts of the codebase that might have depended on the more abstract library.Repository interface. Run the following script to check for any remaining usages of library.Repository:

app/resources/resources.go (2)

24-27: Import changes align with PR objectives

The addition of node_querier and node_writer imports, along with the removal of the general library import, aligns well with the PR objective of reworking node query functionality. This change indicates a more granular approach to handling node-related operations.


72-73: Build function updates reflect improved node handling

The replacement of library.New with node_querier.New and node_writer.New in the Build function reflects the shift towards more specific node-related functionalities. This change is consistent with the PR objectives and should provide better granularity in handling node operations.

tests/library/deletion/deletion_test.go (1)

93-119: LGTM! Comprehensive test case.

The test case for deleting a parent node without a target is well-structured and comprehensive. It effectively verifies that:

  1. The parent node (node2) is deleted.
  2. The child node (node3) is moved to the root level.
  3. The original parent (node1) no longer has any children.

The assertions cover all necessary aspects of the operation, ensuring the tree structure is maintained correctly after the deletion.

tests/library/visibility/visibility_test.go (7)

28-41: Improved context naming and session management

The changes in this segment enhance the clarity and organization of the test setup:

  1. Renaming the context parameter from ctx to root better reflects its scope.
  2. Introduction of session variables (adminSession, authorSession, randoSession) improves readability and maintainability.

These modifications will make the tests easier to understand and maintain.


49-52: Consistent context and session usage in "public_only" test

The changes in this segment maintain consistency with the earlier modifications:

  1. Using root instead of ctx for the context in node creation.
  2. Utilizing the pre-defined session variables instead of creating new sessions inline.

These changes improve the readability and consistency of the test case.


72-77: Consistent context and session usage in "public_filter_by_author" test

The changes in this segment follow the same pattern as the previous test case:

  1. Using root for the context in node creation.
  2. Utilizing pre-defined session variables.

This consistency across test cases improves the overall readability and maintainability of the test suite.


96-104: Improved clarity in "admin_change_visibility" test with added comment

The changes in this segment continue the pattern of consistent context and session usage. Additionally:

  1. A valuable comment has been added explaining the expected behavior of this test case.
  2. The comment highlights that the admin should not be able to list a node in draft status, which is crucial for understanding the test's purpose.

These changes not only maintain consistency but also improve the test's documentation, making it easier for developers to understand the intended behavior.


Line range hint 124-232: Consistent application of context and session changes across multiple test cases

The changes in this large segment demonstrate a consistent application of the modifications seen earlier:

  1. All occurrences of ctx have been replaced with root for context.
  2. Pre-defined session variables are used consistently across all test cases.

This consistency spans multiple test cases including "author_change_visibility", "author_can_view_own_drafts", "admin_lists_in_review_but_not_drafts", "author_submits_for_review", and "author_submmits_unlisted".

The uniform application of these changes across the entire test file significantly improves its overall consistency and readability.


248-253: Consistent changes in "visibility_affects_children" test while maintaining test integrity

The changes in this segment continue the pattern of using root for context and pre-defined session variables. Importantly:

  1. The core logic of the test case remains unchanged, ensuring that the visibility rules for parent-child relationships are still being tested correctly.
  2. The modifications do not alter the intent or coverage of the test, maintaining its validity and importance in the test suite.

These changes improve consistency while preserving the crucial checks for visibility inheritance in the node hierarchy.


263-287: Excellent addition of "only_author_sees_non_published_children" test case

This new test case is a valuable addition to the visibility test suite:

  1. It explicitly tests the visibility of non-published (draft) child nodes for different user roles (author, random authenticated user, guest).
  2. The test covers an important edge case in the visibility rules that wasn't directly addressed in previous tests.
  3. The logic is comprehensive, checking visibility for the node owner, other authenticated users, and guests separately.

This addition enhances the overall coverage of the visibility rules and helps ensure that the system correctly handles the visibility of draft child nodes in various scenarios. Great job on improving the test suite!

app/services/library/node_read/reader.go (2)

23-23: Type change for nodereader aligns with new implementation

Updating the nodereader field and constructor parameter to use *node_querier.Querier reflects the updated architecture and ensures consistency throughout the code.

Also applies to: 30-30


44-50: Verify behavior when opts is empty

When there is no account session, the opts slice remains empty. Please verify that calling q.nodereader.Get with an empty opts slice does not cause unintended behavior or errors.

If necessary, consider handling the no-session case explicitly or ensuring that q.nodereader.Get can safely handle empty options.

app/services/library/node_visibility/visibility.go (1)

68-68: Ensure consistency with child nodes when updating visibility

When updating a node's visibility using m.nodeWriter.Update, consider if child nodes should also have their visibility updated to maintain consistency across the node hierarchy.

To verify if child nodes require visibility updates, you can check for child nodes associated with the current node:

Please replace REPLACE_WITH_NODE_ID with the actual node ID to run the script.

app/resources/library/node_querier/node_querier.go (1)

66-87: 🛠️ Refactor suggestion

Ensure visibility rules are consistently applied and optimized

The visibility filtering in the WithNodes clause correctly enforces the visibility rules based on whether the requestingAccount is provided. However, the logic could be further optimized.

Consider simplifying the conditionals or using predefined predicates to improve readability and maintainability. Additionally, ensure that the visibility conditions are thoroughly tested to prevent any unauthorized data access.

Would you like assistance in refactoring the visibility logic or creating tests to verify the correctness of these rules?

app/resources/library/node_writer/node_writer.go (1)

139-145: Ensure consistent error handling with fmsg.WithDesc

When wrapping constraint errors, you use fmsg.WithDesc to provide a user-friendly message. To maintain consistency across the codebase, verify that fmsg.WithDesc is used uniformly with appropriate descriptions. This helps in providing clear and actionable error messages to users.

Run the following script to check fmsg.WithDesc usage:

✅ Verification successful

Consistent usage of fmsg.WithDesc confirmed.

All instances of fmsg.WithDesc in the codebase utilize appropriate descriptions, ensuring uniform and clear error handling.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify consistent usage of fmsg.WithDesc in error handling.

# Test: Search for all instances of fmsg.WithDesc in Go files.
rg --type go 'fmsg\.WithDesc\('

Length of output: 6708

app/services/library/nodetree/nodetree.go (10)

13-14: Import necessary packages for node querying and writing

The additions of node_querier and node_writer packages are appropriate and necessary for the specialized node operations introduced.


35-36: Update service struct with nodeQuerier and nodeWriter

The service struct now includes nodeQuerier and nodeWriter, providing a clearer separation of concerns compared to the previous generic library.Repository.


67-67: Retrieve the child node using nodeQuerier

The retrieval of the child node now correctly utilizes s.nodeQuerier.Get, aligning with the updated architecture.


72-72: Retrieve the parent node using nodeQuerier

The parent node is now fetched using s.nodeQuerier.Get, which is consistent with the new modular design.


91-91: Update child node to sever circular relationship if necessary

The use of s.nodeWriter.Update with node_writer.WithChildNodeRemove properly handles the potential circular relationship by removing the parent node from the child’s children.


98-98: Add child node to the new parent using nodeWriter

Adding the child node to the new parent via s.nodeWriter.Update with node_writer.WithChildNodeAdd is correctly implemented.


120-120: Retrieve the child node in Sever method using nodeQuerier

In the Sever method, fetching the child node with s.nodeQuerier.Get maintains consistency with the rest of the service.


125-125: Retrieve the parent node in Sever method using nodeQuerier

Similarly, retrieving the parent node using s.nodeQuerier.Get aligns with the updated design.


134-134: Update parent node to remove child link in Sever method

The use of s.nodeWriter.Update with node_writer.WithChildNodeRemove effectively removes the child node from the parent’s children, properly executing the sever operation.


40-49: Verify all calls to the updated New constructor function

The New function signature has been updated to accept nodeQuerier, nodeWriter, and accountQuery. Ensure all instances where nodetree.New is called are updated to match the new signature to prevent potential runtime errors.

Run the following script to locate and review all calls to nodetree.New:

app/services/library/node_mutate/node.go (14)

21-22: New Imports for node_querier and node_writer Added

The imports for node_querier and node_writer have been correctly added to support the new modular architecture.


64-71: Updated Opts Method to Use node_writer.Option

The Opts method in the Partial struct has been updated to return []node_writer.Option and use node_writer options. This refactoring aligns with the new design and is correctly implemented.


77-78: Service Struct Now Includes nodeQuerier and nodeWriter Fields

The service struct has been updated to include *node_querier.Querier and *node_writer.Writer, replacing the previous library.Repository. This change supports the updated node handling logic.


88-89: Constructor Function Updated to Initialize New Fields

The New function correctly initializes the new nodeQuerier and nodeWriter fields, and the service struct assignments are appropriately updated.

Also applies to: 98-99


141-141: Assets Added Using node_writer.WithAssets

Assets from the asset sources are correctly appended to the options using node_writer.WithAssets.


150-150: Link Added to Options Using node_writer.WithLink

The link node is correctly added to the options using node_writer.WithLink.


154-154: Node Creation Now Uses nodeWriter.Create

The Create method now utilizes s.nodeWriter.Create, which aligns with the new architecture.


179-179: Node Retrieval Updated to Use nodeQuerier.Get

The Update method now retrieves the node using s.nodeQuerier.Get, reflecting the refactored design.


201-201: Assets Added Using node_writer.WithAssets

Assets are appended to the options using node_writer.WithAssets, consistent with the earlier changes.


223-223: Link Added to Options Using node_writer.WithLink

The link is appended to the options using node_writer.WithLink, similar to the change in the Create method.


227-227: Node Update Now Uses nodeWriter.Update

The Update method now calls s.nodeWriter.Update, aligning with the updated architecture.


252-252: Node Retrieval in Delete Method Updated

The Delete method now uses s.nodeQuerier.Get to retrieve the node, reflecting the architectural changes.


273-273: Node Deletion Now Uses nodeWriter.Delete

The node is now deleted using s.nodeWriter.Delete, consistent with the refactored node handling.


281-281: Updated applyOpts Method to Use node_querier

The applyOpts method now uses s.nodeQuerier.Get to retrieve the parent node and appends the parent to the options using node_writer.WithParent. This change is correctly implemented.

"github.com/Southclaws/storyden/internal/ent"
"github.com/Southclaws/storyden/internal/ent/node"
)

type database struct {
db *ent.Client
nr library.Repository
nr *node_querier.Querier
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Resolve remaining library.Repository references.

The change to replace library.Repository with *node_querier.Querier has not been fully applied. The following files still reference library.Repository and need to be updated accordingly:

  • app/resources/tag/repo.go
  • app/resources/settings/repo.go
  • app/resources/library/node_traversal/traversal.go
  • app/resources/profile/profile_search/search.go
  • app/resources/library/node_children/children.go
  • app/resources/asset/asset.go
  • app/resources/post/thread_writer/writer.go
  • app/resources/collection/repo.go
  • app/resources/post/thread/repo.go
  • app/resources/post/post_search/repo.go
  • app/resources/post/category/repo.go
  • app/resources/account/authentication/repo.go
  • app/resources/post/reply/repo.go

Please update these files to ensure consistent dependency injection across the codebase.

🔗 Analysis chain

Approve change to database struct, but verify impact.

The change from library.Repository to *node_querier.Querier for the nr field reflects a more specific dependency injection. This is generally a good practice as it provides clearer intentions and potentially better type safety.

Please ensure that this change is consistently applied throughout the codebase. Run the following script to check for any remaining uses of library.Repository:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for remaining uses of library.Repository

# Test: Search for library.Repository usage
rg --type go 'library\.Repository'

Length of output: 12882

Comment on lines +1 to +80
package datagraph_test

import (
"context"
"testing"

"github.com/google/uuid"
"github.com/stretchr/testify/require"
"go.uber.org/fx"

"github.com/Southclaws/storyden/app/resources/account/account_writer"
"github.com/Southclaws/storyden/app/resources/seed"
"github.com/Southclaws/storyden/app/transports/http/middleware/session"
"github.com/Southclaws/storyden/app/transports/http/openapi"
"github.com/Southclaws/storyden/internal/integration"
"github.com/Southclaws/storyden/internal/integration/e2e"
"github.com/Southclaws/storyden/tests"
)

func TestLibraryNodeChildren(t *testing.T) {
t.Parallel()

integration.Test(t, nil, e2e.Setup(), fx.Invoke(func(
lc fx.Lifecycle,
ctx context.Context,
cl *openapi.ClientWithResponses,
cj *session.Jar,
aw *account_writer.Writer,
) {
lc.Append(fx.StartHook(func() {
r := require.New(t)

ctx, _ := e2e.WithAccount(ctx, aw, seed.Account_001_Odin)
session := e2e.WithSession(ctx, cj)

// iurl := "https://picsum.photos/500/500"

name1 := "test-node-1"
slug1 := name1 + uuid.NewString()
node1, err := cl.NodeCreateWithResponse(ctx, openapi.NodeInitialProps{
Name: name1,
Slug: &slug1,
}, session)
tests.Ok(t, err, node1)

// Add a child node

name2 := "test-node-2"
slug2 := name2 + uuid.NewString()
node2, err := cl.NodeCreateWithResponse(ctx, openapi.NodeInitialProps{
Name: name2,
Slug: &slug2,
}, session)
tests.Ok(t, err, node2)

cadd, err := cl.NodeAddNodeWithResponse(ctx, slug1, slug2, session)
tests.Ok(t, err, cadd)

r.Equal(node1.JSON200.Id, cadd.JSON200.Id)

// Add another child to this child
// node1
// |- node2
// |- node3

name3 := "test-node-3"
slug3 := name3 + uuid.NewString()
node3, err := cl.NodeCreateWithResponse(ctx, openapi.NodeInitialProps{
Name: name3,
Slug: &slug3,
}, session)
tests.Ok(t, err, node3)

cadd, err = cl.NodeAddNodeWithResponse(ctx, slug2, slug3, session)
tests.Ok(t, err, cadd)

r.Equal(node2.JSON200.Id, cadd.JSON200.Id)
}))
}))
}
Copy link

@coderabbitai coderabbitai bot Oct 10, 2024

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider adding more test cases for completeness.

While the current test covers the basic functionality of node creation and parent-child relationships, it would be beneficial to add more test cases to ensure comprehensive coverage. Consider adding tests for:

  1. Attempting to create a node with a duplicate slug.
  2. Trying to establish a circular relationship (e.g., making a parent node a child of its own child).
  3. Verifying that a node cannot be added as a child to multiple parents.
  4. Testing the behavior when adding a non-existent node as a child.
  5. Checking the system's response to invalid input (e.g., empty names or slugs).

These additional test cases would help ensure the robustness of the node hierarchy system.

Copy link
Owner Author

Choose a reason for hiding this comment

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

all these cases are already tested in other tests

Copy link

Choose a reason for hiding this comment

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

@Southclaws, understood. Thanks for clarifying that these cases are already tested in other tests.


✏️ Learnings added
Learnt from: Southclaws
PR: Southclaws/storyden#204
File: tests/library/children/children_test.go:1-80
Timestamp: 2024-10-10T12:29:02.898Z
Learning: The test cases for duplicate slugs, circular relationships, multiple parent assignments, adding non-existent nodes, and invalid inputs are already covered in other tests in the codebase.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Comment on lines +24 to +27
"github.com/Southclaws/storyden/app/resources/library/node_querier"
"github.com/Southclaws/storyden/app/resources/library/node_search"
"github.com/Southclaws/storyden/app/resources/library/node_traversal"
"github.com/Southclaws/storyden/app/resources/library/node_writer"
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Incomplete Refactoring Detected

Several files still import or utilize the old library resource. Please ensure all dependencies are updated to use node_querier and node_writer to maintain consistency and prevent potential issues.

  • app/services/library/perms.go
  • app/services/semdex/summarise_job/summariser.go
  • app/resources/library/node_traversal/db.go
  • (and others as identified)
🔗 Analysis chain

Verify impact on dependent code

The changes from library to node_querier and node_writer seem to be part of a larger refactoring effort. While these changes look good, it's important to ensure that all code previously depending on the library resource has been updated to use the new node_querier and node_writer resources.

To verify this, please run the following script:

This script will help identify any areas of the codebase that might still be using the old library resource and need updating.

Also applies to: 72-73

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining usage of the old library resource

# Test 1: Search for any remaining imports of the old library package
echo "Checking for remaining imports of the old library package:"
rg --type go 'github\.com/Southclaws/storyden/app/resources/library"$'

# Test 2: Search for any remaining usage of library.New
echo "Checking for remaining usage of library.New:"
rg --type go 'library\.New'

# Test 3: Search for any files that might need updating to use node_querier or node_writer
echo "Files that might need updating to use node_querier or node_writer:"
rg --type go -l 'library\.' | xargs -I {} echo "File: {}"

Length of output: 5086

Comment on lines +31 to +32
nodeQuerier *node_querier.Querier,
nodeWriter *node_writer.Writer,
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider using interfaces for dependency injection

Injecting interfaces instead of concrete types for nodeQuerier and nodeWriter in the New function enhances testability and decouples the Controller from specific implementations.

Apply this diff to modify the function signature and struct fields:

 type Controller struct {
 	accountQuery *account_querier.Querier
-	nodeQuerier  *node_querier.Querier
-	nodeWriter   *node_writer.Writer
+	nodeQuerier  node_querier.QuerierInterface
+	nodeWriter   node_writer.WriterInterface
 	nc           node_children.Repository
 }

 func New(
 	accountQuery *account_querier.Querier,
-	nodeQuerier *node_querier.Querier,
-	nodeWriter *node_writer.Writer,
+	nodeQuerier node_querier.QuerierInterface,
+	nodeWriter node_writer.WriterInterface,
 	nc node_children.Repository,
 ) *Controller {

This change allows for easier mocking and testing of the Controller by injecting different implementations of nodeQuerier and nodeWriter.

Committable suggestion was skipped due to low confidence.

Comment on lines +50 to +65
query.
WithOwner(func(aq *ent.AccountQuery) {
aq.WithAccountRoles(func(arq *ent.AccountRolesQuery) { arq.WithRole() })
}).
WithAssets().
WithLink(func(lq *ent.LinkQuery) {
lq.WithAssets().Order(link.ByCreatedAt(sql.OrderDesc()))
}).
WithParent(func(cq *ent.NodeQuery) {
cq.
WithAssets().
WithOwner(func(aq *ent.AccountQuery) {
aq.WithAccountRoles(func(arq *ent.AccountRolesQuery) { arq.WithRole() })
})
})

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider optimizing eager loading of related entities to improve performance

In the Get method, multiple related entities are eagerly loaded using WithOwner, WithAssets, WithLink, and WithParent. While this ensures all related data is available, it could lead to performance issues, especially with large datasets or deep relationships.

Evaluate whether all these relations are necessary for every retrieval. If not all related data is needed in every case, consider loading only the required relations or using lazy loading to defer loading until the data is actually needed.

}

// Probe does not pull edges, only the node itself, it's fast for quick checks.
// TODO: Provide a more slimmed-down invariant of Node struct for this purpose.
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Typo in comment: 'invariant' should be 'variant' or 'version'

In the TODO comment on line 103, the term "invariant" seems out of context. It likely should be "variant" or "version".

-// TODO: Provide a more slimmed-down invariant of Node struct for this purpose.
+// TODO: Provide a more slimmed-down variant of Node struct for this purpose.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// TODO: Provide a more slimmed-down invariant of Node struct for this purpose.
// TODO: Provide a more slimmed-down variant of Node struct for this purpose.

Comment on lines +76 to +81
func WithContent(v datagraph.Content) Option {
return func(c *ent.NodeMutation) {
c.SetContent(v.HTML())
c.SetDescription(v.Short())
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Clarify the scope of WithContent to avoid unexpected side effects

The WithContent option function sets both the Content and Description fields. This might be unexpected for users who assume it only sets the Content. Consider separating the description logic into a separate WithDescription option or clearly document that WithContent also sets the description based on the content provided.

Comment on lines +152 to +176
func (w *Writer) Update(ctx context.Context, qk library.QueryKey, opts ...Option) (*library.Node, error) {
// NOTE: Should be a probe not a full read. Query is necessary because of
// the Mark being used (id or slug) for updates. Cannot use UpdateOneID.
pre, err := w.querier.Get(ctx, qk)
if err != nil {
return nil, fault.Wrap(err, fctx.With(ctx))
}

update := w.db.Node.Update()
update.Where(qk.Predicate())

mutate := update.Mutation()
for _, fn := range opts {
fn(mutate)
}

err = update.Exec(ctx)
if err != nil {
return nil, fault.Wrap(err, fctx.With(ctx))
}

qk = library.QueryKey{mark.NewQueryKeyID(pre.Mark.ID())}

return w.querier.Get(ctx, qk)
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider optimizing the Update method to avoid unnecessary reads

The Update method first retrieves the node using w.querier.Get before performing the update. This additional read operation may impact performance, especially under heavy load. If the primary goal is to update existing nodes and ensure they exist, consider using UpdateOne with appropriate error handling to perform the update without the initial fetch.

Comment on lines +183 to +184
_, err := delete.Exec(ctx)
if err != nil {
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove unnecessary assignment to the blank identifier

In the Delete method, the result of delete.Exec(ctx) is assigned to the blank identifier _, but Exec returns only an error. The assignment is unnecessary and can be omitted.

Apply this diff to simplify the code:

-	_, err := delete.Exec(ctx)
+	err := delete.Exec(ctx)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
_, err := delete.Exec(ctx)
if err != nil {
err := delete.Exec(ctx)
if err != nil {

Comment on lines +178 to +189
func (w *Writer) Delete(ctx context.Context, qk library.QueryKey) error {
delete := w.db.Node.Delete()

delete.Where(qk.Predicate())

_, err := delete.Exec(ctx)
if err != nil {
return fault.Wrap(err, fctx.With(ctx))
}

return nil
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Avoid shadowing built-in functions with variable names

In the Delete method, the variable delete shadows Go's built-in delete function. While this doesn't cause an error, it's best practice to avoid using names that shadow built-ins to prevent potential confusion and maintain code clarity.

Apply this diff to rename the variable:

-func (w *Writer) Delete(ctx context.Context, qk library.QueryKey) error {
-	delete := w.db.Node.Delete()
-	delete.Where(qk.Predicate())
-	_, err := delete.Exec(ctx)
+func (w *Writer) Delete(ctx context.Context, qk library.QueryKey) error {
+	del := w.db.Node.Delete()
+	del.Where(qk.Predicate())
+	_, err := del.Exec(ctx)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func (w *Writer) Delete(ctx context.Context, qk library.QueryKey) error {
delete := w.db.Node.Delete()
delete.Where(qk.Predicate())
_, err := delete.Exec(ctx)
if err != nil {
return fault.Wrap(err, fctx.With(ctx))
}
return nil
}
func (w *Writer) Delete(ctx context.Context, qk library.QueryKey) error {
del := w.db.Node.Delete()
del.Where(qk.Predicate())
_, err := del.Exec(ctx)
if err != nil {
return fault.Wrap(err, fctx.With(ctx))
}
return nil
}

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.

1 participant