Skip to content

Conversation

@ajtmccarty
Copy link
Contributor

@ajtmccarty ajtmccarty commented Nov 11, 2025

part of IFC-1942

adds created/updated_at/by metadata to nodes when created, read, and deleted
mostly updates logic in the cypher queries to create, delete, and read a node from the database to support the new metadata on edges (from_user_id and to_user_id) and Nodes (updated_at, updated_by, created_at, created_by)

logic for writing the data correctly during a non-create update will come later after Attributes and Relationships have the new metadata fully incorporated

@github-actions github-actions bot added the group/backend Issue related to the backend (API Server, Git Agent) label Nov 11, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 11, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (4)
  • main
  • stable
  • develop
  • release-.*

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ajtm-11102025-node-create-read-metadata

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codspeed-hq
Copy link

codspeed-hq bot commented Nov 11, 2025

CodSpeed Performance Report

Merging #7629 will not alter performance

Comparing ajtm-11102025-node-create-read-metadata (b6fda32) with stable (280578b)1

Summary

✅ 10 untouched

Footnotes

  1. No successful run was found on ajtm-immutable-metadata (69c7608) during the generation of this report, so stable (9907bad) was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@ajtmccarty ajtmccarty force-pushed the ajtm-11102025-node-create-read-metadata branch from 4ed6377 to b4ffb64 Compare November 12, 2025 14:22
@ajtmccarty ajtmccarty force-pushed the ajtm-11102025-node-create-read-metadata branch from b4ffb64 to ba0f573 Compare November 12, 2025 15:36
@ajtmccarty ajtmccarty marked this pull request as ready for review November 12, 2025 16:35
@ajtmccarty ajtmccarty requested a review from a team as a code owner November 12, 2025 16:35

EVENT_NAMESPACE = "infrahub"

SYSTEM_USER_ID = "__system__"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

default "user ID" to use for updated/created_by/at metadata updates

Copy link
Contributor Author

Choose a reason for hiding this comment

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

new, very simple base class to use on Node, Attribute, and Relationship classes to track the new metadata


raise InitializationError("The node has not been saved yet and doesn't have an id")

def get_updated_at(self) -> Timestamp | None:
Copy link
Contributor Author

Choose a reason for hiding this comment

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

replaced by version in MetadataBase

if (fields and name in fields) or not fields:
attr: BaseAttribute = getattr(self, name)
updated_attribute = await attr.save(at=update_at, db=db)
attr = self.get_attribute(name=name)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

just a more type-hint friendly way of getting an Attribute or RelationshipManager for a node

result = query.get_result()

if result and result.get("rb.branch") == branch.name:
await update_relationships_to([result.get("rb_id")], to=delete_at, db=db)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm trying to remove this wherever I find them
the NodeDeleteQuery should handle this at the database level inside of its cypher query instead of requiring this extra processing in memory and a separate trip to the database

Comment on lines +225 to +233
if self.branch.is_default or self.branch.is_global:
self.params["node_prop"].update(
{
"created_at": at.to_string(),
"created_by": self.user_id,
"updated_at": at.to_string(),
"updated_by": self.user_id,
}
)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

we only add these properties to the Node vertex if we are on the default or global branch to make querying for metadata on those branches faster than on user-created branches

Comment on lines +242 to 257
attr_edge_prop_str = "{ branch: attr.branch, branch_level: attr.branch_level, status: attr.status, from: $at, from_user_id: $user_id }"
attr_vertex_prop_str = "{ uuid: attr.uuid, name: attr.name, branch_support: attr.branch_support"
if self.branch.is_default or self.branch.is_global:
attr_vertex_prop_str += ", created_at: $at, created_by: $user_id, updated_at: $at, updated_by: $user_id"
attr_vertex_prop_str += " }"

rel_edge_prop_str = "{ branch: rel.branch, branch_level: rel.branch_level, status: rel.status, from: $at, from_user_id: $user_id }"
rel_edge_prop_str_hierarchy = (
"{ branch: rel.branch, branch_level: rel.branch_level, "
"status: rel.status, hierarchy: rel.hierarchical, from: $at, from_user_id: $user_id }"
)
rel_vertex_prop_str = "{ uuid: rel.uuid, name: rel.name, branch_support: rel.branch_support"
if self.branch.is_default or self.branch.is_global:
rel_vertex_prop_str += ", created_at: $at, created_by: $user_id, updated_at: $at, updated_by: $user_id"
rel_vertex_prop_str += " }"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

mostly refactoring to move a bunch of repeated property create strings into one place
and add the updated/created_by/at metadata to them

Comment on lines +622 to +624
WHERE r.branch = $branch
SET r.to = $at
SET r.to_user_id = $user_id
Copy link
Contributor Author

Choose a reason for hiding this comment

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

now handles setting the to time on edges that used to be handled in the update_relationships_to function


def _add_updated_metadata_to_query(self, branch_filter_str: str) -> None:
if self.branch.is_default or self.branch.is_global:
last_update_query = """
Copy link
Contributor Author

Choose a reason for hiding this comment

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

we can use this very simple addition to the query on the default or global branch

WITH *, n.updated_at AS updated_at, n.updated_by AS updated_by
"""
else:
last_update_query = """
Copy link
Contributor Author

Choose a reason for hiding this comment

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

we have to use this more complex query on a user-created branch b/c we have to look at every edge under the node to find its latest update_at/by

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

group/backend Issue related to the backend (API Server, Git Agent)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants