Skip to content

Conversation

@chrisgacsal
Copy link
Collaborator

@chrisgacsal chrisgacsal commented Apr 14, 2025

Overview

Add database schme for plan add-on assigments.

Summary by CodeRabbit

  • New Features

    • Introduced support for associating add-ons with plans via a new "plan add-ons" entity.
    • Added the ability to create, query, update, and delete plan add-ons, including bulk operations.
    • Enabled linking and managing add-ons directly within plans and vice versa.
    • Added support for filtering, ordering, and paginating plan add-ons.
    • Implemented cascade delete for plan add-ons when related plans or add-ons are deleted.
  • Database Changes

    • Added a new table for plan add-ons with relevant indexes and foreign key constraints.
    • Enabled storage of annotations and metadata for plan add-ons.
  • Chores

    • Extended schema mixins to support annotations with optimized indexing.

@chrisgacsal chrisgacsal self-assigned this Apr 14, 2025
@chrisgacsal chrisgacsal requested a review from a team as a code owner April 14, 2025 12:03
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 14, 2025

📝 Walkthrough

Walkthrough

This change introduces a new PlanAddon entity and its associated database schema, linking Plan and Addon entities with a join table and supporting fields. It updates the Ent ORM codebase to support full CRUD operations, queries, mutations, and edge management for PlanAddon, including eager loading, ordering, filtering, and pagination. The migration scripts create and drop the new plan_addons table with appropriate indexes and constraints. The Plan and Addon schemas are extended with edges to PlanAddon, and the client, transaction, and runtime code are updated to integrate the new entity. Mixins and predicates are also introduced or updated to support the new features.

Changes

File(s) Change Summary
openmeter/ent/schema/planaddon.go Adds new PlanAddon schema with fields, edges to Plan and Addon, and a unique index.
openmeter/ent/db/planaddon.go, openmeter/ent/db/planaddon/planaddon.go, openmeter/ent/db/planaddon/where.go Implements PlanAddon entity struct, schema constants, predicates, and edge logic.
openmeter/ent/db/planaddon_create.go, openmeter/ent/db/planaddon_update.go, openmeter/ent/db/planaddon_delete.go, openmeter/ent/db/planaddon_query.go Adds builder patterns for PlanAddon CRUD, upsert, query, update, and delete operations.
openmeter/ent/db/predicate/predicate.go Adds PlanAddon predicate function type.
openmeter/ent/db/migrate/schema.go, tools/migrate/migrations/20250415105134_plan_addons.up.sql, tools/migrate/migrations/20250415105134_plan_addons.down.sql Introduces plan_addons table schema, foreign keys, indexes, and migration scripts.
openmeter/ent/db/client.go, openmeter/ent/db/tx.go, openmeter/ent/db/expose.go Integrates PlanAddon client into main client, transaction, and expose code.
openmeter/ent/db/runtime.go Initializes PlanAddon schema, mixins, validators, and default values at runtime.
openmeter/ent/db/setorclear.go Adds SetOrClear methods for PlanAddonUpdate/PlanAddonUpdateOne.
openmeter/ent/db/addon.go, openmeter/ent/db/addon/addon.go, openmeter/ent/db/addon/where.go, openmeter/ent/db/addon_create.go, openmeter/ent/db/addon_query.go, openmeter/ent/db/addon_update.go Adds "plans" edge to Addon, supporting PlanAddon relations, queries, predicates, and mutation logic.
openmeter/ent/db/plan.go, openmeter/ent/db/plan/plan.go, openmeter/ent/db/plan/where.go, openmeter/ent/db/plan_create.go, openmeter/ent/db/plan_query.go, openmeter/ent/db/plan_update.go Adds "addons" edge to Plan, supporting PlanAddon relations, queries, predicates, and mutation logic.
openmeter/ent/db/mutation.go Adds PlanAddonMutation and extends AddonMutation/PlanMutation for new edges.
openmeter/ent/db/paginate.go Adds Paginate method for PlanAddonQuery.
openmeter/ent/db/ent.go Updates column validation to include planaddon table.
openmeter/ent/db/hook/hook.go Adds PlanAddonFunc mutator adapter.
openmeter/ent/schema/addon.go, openmeter/ent/schema/productcatalog.go Adds edges from Addon to PlanAddon ("plans") and from Plan to PlanAddon ("addons") with cascade delete.
pkg/framework/entutils/mixins.go Adds AnnotationsMixin for JSONB annotations and index.

Possibly related PRs

  • openmeterio/openmeter#2658: Adds API endpoints and routing stubs for managing PlanAddon assignments, which directly complements this PR by implementing the service layer for the PlanAddon entity and its relationships.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (1.64.8)

Error: you are using a configuration file for golangci-lint v2 with golangci-lint v1: please use golangci-lint v2
Failed executing command with error: you are using a configuration file for golangci-lint v2 with golangci-lint v1: please use golangci-lint v2

🔧 SQLFluff (3.3.0)
tools/migrate/migrations/20250415105134_plan_addons.down.sql

User Error: No dialect was specified. You must configure a dialect or specify one on the command line using --dialect after the command. Available dialects:
ansi, athena, bigquery, clickhouse, databricks, db2, duckdb, exasol, greenplum, hive, impala, mariadb, materialize, mysql, oracle, postgres, redshift, snowflake, soql, sparksql, sqlite, starrocks, teradata, trino, tsql, vertica

tools/migrate/migrations/20250415105134_plan_addons.up.sql

User Error: No dialect was specified. You must configure a dialect or specify one on the command line using --dialect after the command. Available dialects:
ansi, athena, bigquery, clickhouse, databricks, db2, duckdb, exasol, greenplum, hive, impala, mariadb, materialize, mysql, oracle, postgres, redshift, snowflake, soql, sparksql, sqlite, starrocks, teradata, trino, tsql, vertica


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8ff5adb and 2512f0a.

⛔ Files ignored due to path filters (1)
  • tools/migrate/migrations/atlas.sum is excluded by !**/*.sum
📒 Files selected for processing (36)
  • openmeter/ent/db/addon.go (3 hunks)
  • openmeter/ent/db/addon/addon.go (4 hunks)
  • openmeter/ent/db/addon/where.go (1 hunks)
  • openmeter/ent/db/addon_create.go (3 hunks)
  • openmeter/ent/db/addon_query.go (8 hunks)
  • openmeter/ent/db/addon_update.go (7 hunks)
  • openmeter/ent/db/client.go (13 hunks)
  • openmeter/ent/db/ent.go (2 hunks)
  • openmeter/ent/db/expose.go (1 hunks)
  • openmeter/ent/db/hook/hook.go (1 hunks)
  • openmeter/ent/db/migrate/schema.go (3 hunks)
  • openmeter/ent/db/mutation.go (20 hunks)
  • openmeter/ent/db/paginate.go (1 hunks)
  • openmeter/ent/db/plan.go (3 hunks)
  • openmeter/ent/db/plan/plan.go (4 hunks)
  • openmeter/ent/db/plan/where.go (1 hunks)
  • openmeter/ent/db/plan_create.go (3 hunks)
  • openmeter/ent/db/plan_query.go (8 hunks)
  • openmeter/ent/db/plan_update.go (7 hunks)
  • openmeter/ent/db/planaddon.go (1 hunks)
  • openmeter/ent/db/planaddon/planaddon.go (1 hunks)
  • openmeter/ent/db/planaddon/where.go (1 hunks)
  • openmeter/ent/db/planaddon_create.go (1 hunks)
  • openmeter/ent/db/planaddon_delete.go (1 hunks)
  • openmeter/ent/db/planaddon_query.go (1 hunks)
  • openmeter/ent/db/planaddon_update.go (1 hunks)
  • openmeter/ent/db/predicate/predicate.go (1 hunks)
  • openmeter/ent/db/runtime.go (2 hunks)
  • openmeter/ent/db/setorclear.go (1 hunks)
  • openmeter/ent/db/tx.go (2 hunks)
  • openmeter/ent/schema/addon.go (1 hunks)
  • openmeter/ent/schema/planaddon.go (1 hunks)
  • openmeter/ent/schema/productcatalog.go (1 hunks)
  • pkg/framework/entutils/mixins.go (2 hunks)
  • tools/migrate/migrations/20250415105134_plan_addons.down.sql (1 hunks)
  • tools/migrate/migrations/20250415105134_plan_addons.up.sql (1 hunks)
✅ Files skipped from review due to trivial changes (3)
  • tools/migrate/migrations/20250415105134_plan_addons.down.sql
  • tools/migrate/migrations/20250415105134_plan_addons.up.sql
  • openmeter/ent/db/planaddon/where.go
🚧 Files skipped from review as they are similar to previous changes (30)
  • openmeter/ent/schema/addon.go
  • openmeter/ent/schema/productcatalog.go
  • openmeter/ent/db/tx.go
  • openmeter/ent/db/ent.go
  • openmeter/ent/db/addon/where.go
  • openmeter/ent/db/expose.go
  • openmeter/ent/db/addon.go
  • openmeter/ent/db/paginate.go
  • openmeter/ent/db/plan_create.go
  • pkg/framework/entutils/mixins.go
  • openmeter/ent/db/predicate/predicate.go
  • openmeter/ent/db/plan/where.go
  • openmeter/ent/db/addon/addon.go
  • openmeter/ent/db/setorclear.go
  • openmeter/ent/db/runtime.go
  • openmeter/ent/db/addon_query.go
  • openmeter/ent/db/addon_create.go
  • openmeter/ent/schema/planaddon.go
  • openmeter/ent/db/hook/hook.go
  • openmeter/ent/db/planaddon_delete.go
  • openmeter/ent/db/migrate/schema.go
  • openmeter/ent/db/plan/plan.go
  • openmeter/ent/db/plan.go
  • openmeter/ent/db/plan_update.go
  • openmeter/ent/db/plan_query.go
  • openmeter/ent/db/planaddon_update.go
  • openmeter/ent/db/addon_update.go
  • openmeter/ent/db/planaddon/planaddon.go
  • openmeter/ent/db/planaddon.go
  • openmeter/ent/db/planaddon_create.go
⏰ Context from checks skipped due to timeout of 90000ms (9)
  • GitHub Check: CI
  • GitHub Check: Quickstart
  • GitHub Check: E2E
  • GitHub Check: Lint
  • GitHub Check: Developer environment
  • GitHub Check: Commit hooks
  • GitHub Check: Test
  • GitHub Check: Build
  • GitHub Check: Analyze (go)
🔇 Additional comments (32)
openmeter/ent/db/mutation.go (20)

49-49: New import for PlanAddon.
No functional or logical concerns here.


108-108: Declaration of TypePlanAddon constant.
Naming is consistent with existing entity constants.


146-148: New fields in AddonMutation for "plans" edge.
These additions properly track added, removed, and cleared plan IDs.


917-970: Accessor and mutator methods for the "plans" edge in AddonMutation.
Standard Ent patterns for adding, removing, clearing, and resetting the edge.


1433-1439: Adding the "plans" edge to the list of AddedEdges.
Implementation looks correct and follows Ent conventions.


1456-1461: Retrieving Added Edge IDs for "plans".
No issues with the logic or data structures.


1474-1480: Marking "plans" as removed edges.
Approach is consistent with Ent's edge removal mechanics.


1497-1502: RemovedPlansIDs method implementation.
Correctly manages removal of plan IDs.


1515-1521: ClearedEdges for "plans".
No concerns regarding this clearing logic.


1534-1535: EdgeCleared for "plans".
The check is straightforward and aligns with Ent norms.


1557-1559: ResetPlans method.
Implementation correctly reinitializes the underlying fields.


36870-36872: Introducing new "addons" tracking fields in PlanMutation.
No issues found with field naming or structure.


37592-37648: Methods to manage "addons" edge in PlanMutation.
Add, remove, clear, and reset logic is standard.


38085-38091: Adding "addons" to the AddedEdges in PlanMutation.
Implementation looks sound.


38108-38113: AddedIDs for the "addons" edge.
Correctly retrieves newly set addon IDs.


38126-38132: Marking "addons" as removed edges.
Consistent with removal logic for other edges.


38149-38154: RemovedAddonsIDs function.
Implementation follows Ent edge removal patterns.


38167-38173: Clearing the "addons" edge.
No issues with the cleared logic.


38186-38187: EdgeCleared check for the "addons" edge.
Works as expected.


38219-39253: New PlanAddonMutation struct and associated field/edge methods.
Comprehensive and consistent with Ent standards for a new entity.
No concurrency, correctness, or security issues identified.

openmeter/ent/db/client.go (11)

48-48: Well-structured import for PlanAddon package

The import of the planaddon package is correctly placed alphabetically among related imports.


128-129: Properly documented PlanAddon client field

The PlanAddon field is correctly added to the Client struct with appropriate documentation comment following the established pattern in the codebase.


191-191: Client initialization for PlanAddon correctly implemented

The PlanAddon client is properly initialized in the Client's init method, following the pattern used for other entity clients.


324-324: Transaction support for PlanAddon properly implemented

The PlanAddon field is correctly initialized in the Tx() method to support transactional operations.


384-384: BeginTx transaction support for PlanAddon properly implemented

The PlanAddon field is correctly initialized in the BeginTx() method to support custom transaction options.


432-433: Hook registration for PlanAddon correctly implemented

The PlanAddon entity is properly included in the list of entities that can have hooks applied to them via the Use() method.


454-455: Interceptor registration for PlanAddon correctly implemented

The PlanAddon entity is properly included in the list of entities that can have query interceptors applied to them via the Intercept() method.


527-528: Mutation support for PlanAddon properly implemented

The case for PlanAddonMutation is correctly added to the Mutate() method to support mutations on PlanAddon entities.


678-692: Bidirectional relationship edge implementation for Addon to PlanAddon

The QueryPlans method is correctly implemented in the AddonClient to establish the bidirectional relationship between Addon and PlanAddon entities. The method uses the proper SQL graph traversal to find related PlanAddon entities.


5744-5908: Complete PlanAddonClient implementation is well structured

The PlanAddonClient implementation follows the established pattern in the codebase with all the necessary CRUD operations, query builders, edge traversals, hooks, and interceptors. It correctly implements:

  1. Standard methods like Create, Update, Delete
  2. Bulk operations
  3. Edge traversal queries for related Plan and Addon entities
  4. Hook and interceptor registration
  5. Mutation handling

This implementation provides a complete interface for interacting with PlanAddon entities.


7682-7683: Hook and interceptor registration in struct definitions

The PlanAddon entity is correctly added to both the hooks and inters structs to support the global hook and interceptor registration system.

Also applies to: 7696-7697

openmeter/ent/db/planaddon_query.go (1)

1-719: Auto-generated code looks correct.

This file is auto-generated by the ent framework and implements the query builder for the new PlanAddon entity. It properly supports all standard query operations including:

  • Filtering, sorting, and pagination
  • Edge traversal to Plan and Addon entities
  • Eager loading with WithPlan() and WithAddon()
  • Group-by and aggregation functionality
  • Proper error handling for not-found cases

No issues found in the generated code.

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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 generate docstrings to generate docstrings for this 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.

@chrisgacsal chrisgacsal marked this pull request as draft April 14, 2025 12:04
@chrisgacsal chrisgacsal added the release-note/ignore Ignore this change when generating release notes label Apr 14, 2025
@chrisgacsal chrisgacsal marked this pull request as ready for review April 14, 2025 12:05
Copy link
Contributor

@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: 2

🧹 Nitpick comments (10)
openmeter/ent/schema/planaddon.go (1)

42-44: Fix typo in from_plan_phase field comment

There's a typo in the comment for the from_plan_phase field that changes its meaning.

  field.String("from_plan_phase").
-     Comment("The key identifier of the plan phase from the add-on is available fro purchase."),
+     Comment("The key identifier of the plan phase from which the add-on is available for purchase."),
openmeter/ent/db/setorclear.go (1)

2214-2226: Ensure test coverage for new SetOrClearMetadata methods.

These additions for handling nil by clearing the metadata (and setting it otherwise) correctly mirror the existing pattern used throughout the file. They look good. Please ensure there is adequate test coverage to verify the clearing behavior when nil is passed.

openmeter/ent/db/planaddon.go (2)

43-44: Fix typographical error in docstring.

The phrase “fro purchase” is presumably intended to be “for purchase.” Consider correcting the docstring for clarity.

-// The key identifier of the plan phase from the add-on is available fro purchase.
+// The key identifier of the plan phase from which the add-on is available for purchase.

45-46: Clarify docstring for MaxQuantity.

The docstring uses text related to add-on identifiers, which is likely a copy-paste error. It should reflect the meaning of max quantity.

-// The add-on identifier the plan is assigned to.
+// The maximum quantity for this plan add-on.
openmeter/ent/db/mutation.go (1)

917-969: Introduce AddPlanIDs, RemovePlanIDs and similar methods.
While functionally correct, the docstrings may cause mild confusion by referring to “plans” as part of the “PlanAddon” edge. Consider clarifying these docstrings for readability.

openmeter/ent/db/planaddon_update.go (1)

31-41: Ensure proper validation of Metadata before persisting.

While storing metadata in JSON is convenient, ensure size constraints and untrusted input are handled appropriately upstream.

openmeter/ent/db/planaddon/where.go (1)

183-191: Check Metadata null checks for alignment with schema.

MetadataIsNil() and MetadataNotNil() assume the column might be null. Confirm that the schema column for metadata (JSON) is indeed nullable and that no data loss occurs when toggling between nil and non-nil.

openmeter/ent/db/planaddon_create.go (3)

28-39: Consider additional client-side checks for JSON fields.
These setters for metadata (lines 34-39) and other JSON fields (like annotations) simply set the values. If there's any requirement or schema validation logic for these JSON fields, consider adding a lightweight client-side validation before assignment.


558-589: Evaluate impact of ignoring fields on upsert conflicts.
The UpdateNewValues() method (lines 558–589) deliberately ignores some fields (including ID, Namespace, CreatedAt, PlanID, AddonID) on conflicts. Confirm that ignoring these fields aligns with your domain logic, ensuring you neither overwrite critical attributes nor leave them stale when an upsert occurs.


818-875: Validate behavior for high-volume bulk insert operations.
The Save() method in PlanAddonCreateBulk (lines 818–875) handles multiple builders. For large bulk inserts, consider transaction size limitations. If the dataset is huge, you might need a batching strategy or to ensure the underlying DB can handle it within a single transaction.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4e69a68 and 8a7c23c.

⛔ Files ignored due to path filters (1)
  • tools/migrate/migrations/atlas.sum is excluded by !**/*.sum
📒 Files selected for processing (35)
  • openmeter/ent/db/addon.go (3 hunks)
  • openmeter/ent/db/addon/addon.go (4 hunks)
  • openmeter/ent/db/addon/where.go (1 hunks)
  • openmeter/ent/db/addon_create.go (3 hunks)
  • openmeter/ent/db/addon_query.go (8 hunks)
  • openmeter/ent/db/addon_update.go (7 hunks)
  • openmeter/ent/db/client.go (13 hunks)
  • openmeter/ent/db/ent.go (2 hunks)
  • openmeter/ent/db/expose.go (1 hunks)
  • openmeter/ent/db/hook/hook.go (1 hunks)
  • openmeter/ent/db/migrate/schema.go (3 hunks)
  • openmeter/ent/db/mutation.go (20 hunks)
  • openmeter/ent/db/paginate.go (1 hunks)
  • openmeter/ent/db/plan.go (3 hunks)
  • openmeter/ent/db/plan/plan.go (4 hunks)
  • openmeter/ent/db/plan/where.go (1 hunks)
  • openmeter/ent/db/plan_create.go (3 hunks)
  • openmeter/ent/db/plan_query.go (8 hunks)
  • openmeter/ent/db/plan_update.go (7 hunks)
  • openmeter/ent/db/planaddon.go (1 hunks)
  • openmeter/ent/db/planaddon/planaddon.go (1 hunks)
  • openmeter/ent/db/planaddon/where.go (1 hunks)
  • openmeter/ent/db/planaddon_create.go (1 hunks)
  • openmeter/ent/db/planaddon_delete.go (1 hunks)
  • openmeter/ent/db/planaddon_query.go (1 hunks)
  • openmeter/ent/db/planaddon_update.go (1 hunks)
  • openmeter/ent/db/predicate/predicate.go (1 hunks)
  • openmeter/ent/db/runtime.go (2 hunks)
  • openmeter/ent/db/setorclear.go (1 hunks)
  • openmeter/ent/db/tx.go (2 hunks)
  • openmeter/ent/schema/addon.go (1 hunks)
  • openmeter/ent/schema/planaddon.go (1 hunks)
  • openmeter/ent/schema/productcatalog.go (1 hunks)
  • tools/migrate/migrations/20250414115940_plan_addons.down.sql (1 hunks)
  • tools/migrate/migrations/20250414115940_plan_addons.up.sql (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (30)
openmeter/ent/db/expose.go (4)
openmeter/ent/db/planaddon.go (2)
  • PlanAddon (19-51)
  • PlanAddon (87-106)
openmeter/ent/schema/planaddon.go (5)
  • PlanAddon (15-17)
  • PlanAddon (19-23)
  • PlanAddon (25-49)
  • PlanAddon (51-66)
  • PlanAddon (68-83)
api/api.gen.go (1)
  • PlanAddon (4763-4794)
openmeter/ent/db/client.go (1)
  • NewPlanAddonClient (5750-5752)
openmeter/ent/db/tx.go (3)
openmeter/ent/db/planaddon.go (2)
  • PlanAddon (19-51)
  • PlanAddon (87-106)
openmeter/ent/schema/planaddon.go (5)
  • PlanAddon (15-17)
  • PlanAddon (19-23)
  • PlanAddon (25-49)
  • PlanAddon (51-66)
  • PlanAddon (68-83)
openmeter/ent/db/client.go (2)
  • PlanAddonClient (5745-5747)
  • NewPlanAddonClient (5750-5752)
openmeter/ent/db/ent.go (1)
openmeter/ent/db/planaddon/planaddon.go (2)
  • Table (47-47)
  • ValidColumn (82-89)
openmeter/ent/schema/productcatalog.go (2)
openmeter/ent/db/planaddon.go (2)
  • PlanAddon (19-51)
  • PlanAddon (87-106)
openmeter/ent/schema/planaddon.go (5)
  • PlanAddon (15-17)
  • PlanAddon (19-23)
  • PlanAddon (25-49)
  • PlanAddon (51-66)
  • PlanAddon (68-83)
openmeter/ent/db/predicate/predicate.go (5)
openmeter/ent/db/planaddon.go (2)
  • PlanAddon (19-51)
  • PlanAddon (87-106)
openmeter/ent/schema/planaddon.go (5)
  • PlanAddon (15-17)
  • PlanAddon (19-23)
  • PlanAddon (25-49)
  • PlanAddon (51-66)
  • PlanAddon (68-83)
api/client/javascript/src/client/schemas.ts (1)
  • PlanAddon (9828-9828)
api/api.gen.go (1)
  • PlanAddon (4763-4794)
api/client/go/client.gen.go (1)
  • PlanAddon (4459-4490)
openmeter/ent/db/hook/hook.go (2)
openmeter/ent/db/mutation.go (1)
  • PlanAddonMutation (38220-38244)
openmeter/ent/db/ent.go (2)
  • Value (65-65)
  • Mutation (76-76)
openmeter/ent/db/plan/where.go (4)
openmeter/ent/db/predicate/predicate.go (2)
  • Plan (207-207)
  • PlanAddon (210-210)
openmeter/ent/db/plan/plan.go (3)
  • Table (50-50)
  • AddonsTable (59-59)
  • AddonsColumn (64-64)
openmeter/ent/db/planaddon/planaddon.go (1)
  • Table (47-47)
openmeter/ent/db/planaddon.go (2)
  • PlanAddon (19-51)
  • PlanAddon (87-106)
openmeter/ent/db/addon_query.go (5)
openmeter/ent/db/planaddon_query.go (1)
  • PlanAddonQuery (22-34)
openmeter/ent/db/planaddon/planaddon.go (2)
  • FieldID (17-17)
  • FieldAddonID (37-37)
openmeter/ent/db/addon.go (2)
  • Addon (18-54)
  • Addon (97-116)
openmeter/ent/db/plan.go (1)
  • Plans (315-315)
openmeter/ent/db/planaddon/where.go (2)
  • ID (14-16)
  • AddonID (104-106)
openmeter/ent/db/runtime.go (1)
openmeter/ent/db/planaddon/planaddon.go (1)
  • ValueScanner (107-109)
openmeter/ent/db/addon/where.go (3)
openmeter/ent/db/predicate/predicate.go (2)
  • Addon (10-10)
  • PlanAddon (210-210)
openmeter/ent/db/addon/addon.go (3)
  • Table (55-55)
  • PlansTable (64-64)
  • PlansColumn (69-69)
openmeter/ent/db/planaddon/planaddon.go (1)
  • Table (47-47)
openmeter/ent/db/plan_create.go (3)
openmeter/ent/db/planaddon/where.go (1)
  • ID (14-16)
openmeter/ent/db/plan/plan.go (5)
  • Table (50-50)
  • AddonsTable (59-59)
  • Columns (75-90)
  • AddonsColumn (64-64)
  • FieldID (16-16)
openmeter/ent/db/planaddon/planaddon.go (3)
  • Table (47-47)
  • Columns (65-79)
  • FieldID (17-17)
openmeter/ent/db/planaddon_delete.go (4)
openmeter/ent/db/ent.go (4)
  • Hook (64-64)
  • IsConstraintError (363-369)
  • ConstraintError (347-350)
  • NotFoundError (280-282)
openmeter/ent/db/mutation.go (1)
  • PlanAddonMutation (38220-38244)
openmeter/ent/db/predicate/predicate.go (1)
  • PlanAddon (210-210)
openmeter/ent/db/planaddon/planaddon.go (2)
  • Table (47-47)
  • Label (15-15)
openmeter/ent/db/plan.go (4)
openmeter/ent/db/addon.go (1)
  • Addons (327-327)
openmeter/ent/db/planaddon.go (2)
  • PlanAddon (19-51)
  • PlanAddon (87-106)
openmeter/ent/db/ent.go (1)
  • NotLoadedError (326-328)
openmeter/ent/db/planaddon_query.go (1)
  • PlanAddonQuery (22-34)
openmeter/ent/db/migrate/schema.go (3)
openmeter/ent/db/planaddon/where.go (1)
  • Name (89-91)
openmeter/ent/db/addon/addon.go (2)
  • Table (55-55)
  • Columns (80-96)
openmeter/ent/db/plan/plan.go (2)
  • Table (50-50)
  • Columns (75-90)
openmeter/ent/db/addon_update.go (2)
openmeter/ent/db/addon/addon.go (3)
  • Table (55-55)
  • PlansTable (64-64)
  • PlansColumn (69-69)
openmeter/ent/db/planaddon/planaddon.go (1)
  • Table (47-47)
openmeter/ent/db/plan/plan.go (4)
openmeter/ent/db/subscription/subscription.go (6)
  • ByAddonsCount (254-258)
  • OrderOption (144-144)
  • ByAddons (261-265)
  • Table (54-54)
  • AddonsTable (84-84)
  • AddonsColumn (89-89)
openmeter/ent/db/addon/addon.go (2)
  • OrderOption (146-146)
  • Table (55-55)
openmeter/ent/db/planaddon/planaddon.go (2)
  • OrderOption (113-113)
  • Table (47-47)
openmeter/ent/db/migrate/schema.go (1)
  • AddonsTable (31-75)
openmeter/ent/db/setorclear.go (1)
openmeter/ent/db/planaddon_update.go (2)
  • PlanAddonUpdate (19-23)
  • PlanAddonUpdateOne (279-284)
openmeter/ent/db/addon/addon.go (3)
openmeter/ent/db/plan/plan.go (1)
  • Table (50-50)
openmeter/ent/db/planaddon/planaddon.go (1)
  • Table (47-47)
openmeter/ent/db/migrate/schema.go (1)
  • PlansTable (1638-1672)
openmeter/ent/schema/planaddon.go (6)
openmeter/ent/db/planaddon.go (2)
  • PlanAddon (19-51)
  • PlanAddon (87-106)
openmeter/ent/schema/notification.go (1)
  • AnnotationsValueScanner (347-368)
openmeter/ent/db/plan.go (2)
  • Plan (17-51)
  • Plan (94-113)
openmeter/ent/schema/productcatalog.go (5)
  • Plan (16-18)
  • Plan (20-25)
  • Plan (27-42)
  • Plan (44-56)
  • Plan (58-66)
openmeter/ent/db/addon.go (2)
  • Addon (18-54)
  • Addon (97-116)
openmeter/ent/schema/addon.go (5)
  • Addon (16-18)
  • Addon (20-24)
  • Addon (26-51)
  • Addon (53-68)
  • Addon (70-85)
openmeter/ent/schema/addon.go (2)
openmeter/ent/db/planaddon.go (2)
  • PlanAddon (19-51)
  • PlanAddon (87-106)
openmeter/ent/schema/planaddon.go (5)
  • PlanAddon (15-17)
  • PlanAddon (19-23)
  • PlanAddon (25-49)
  • PlanAddon (51-66)
  • PlanAddon (68-83)
openmeter/ent/db/planaddon.go (3)
openmeter/ent/db/ent.go (2)
  • NotFoundError (280-282)
  • NotLoadedError (326-328)
openmeter/ent/db/planaddon/planaddon.go (6)
  • Label (15-15)
  • FieldMaxQuantity (41-41)
  • FieldPlanID (35-35)
  • FieldAddonID (37-37)
  • FieldFromPlanPhase (39-39)
  • FieldAnnotations (33-33)
openmeter/ent/db/client.go (1)
  • NewPlanAddonClient (5750-5752)
openmeter/ent/db/plan_update.go (3)
openmeter/ent/db/planaddon/where.go (1)
  • ID (14-16)
openmeter/ent/db/plan/plan.go (4)
  • Table (50-50)
  • AddonsTable (59-59)
  • AddonsColumn (64-64)
  • FieldID (16-16)
openmeter/ent/db/planaddon/planaddon.go (2)
  • Table (47-47)
  • FieldID (17-17)
openmeter/ent/db/plan_query.go (6)
openmeter/ent/db/planaddon_query.go (1)
  • PlanAddonQuery (22-34)
openmeter/ent/db/plan/plan.go (1)
  • FieldID (16-16)
openmeter/ent/db/planaddon/planaddon.go (2)
  • FieldID (17-17)
  • FieldPlanID (35-35)
openmeter/ent/db/predicate/predicate.go (2)
  • Plan (207-207)
  • PlanAddon (210-210)
openmeter/ent/db/plan/where.go (1)
  • ID (14-16)
openmeter/ent/db/planaddon/where.go (2)
  • ID (14-16)
  • PlanID (99-101)
openmeter/ent/db/planaddon/planaddon.go (2)
openmeter/ent/db/addon/addon.go (19)
  • FieldID (19-19)
  • FieldNamespace (21-21)
  • FieldMetadata (23-23)
  • FieldCreatedAt (25-25)
  • FieldUpdatedAt (27-27)
  • FieldDeletedAt (29-29)
  • FieldName (31-31)
  • FieldDescription (33-33)
  • FieldAnnotations (47-47)
  • Columns (80-96)
  • ByID (149-151)
  • OrderOption (146-146)
  • ByNamespace (154-156)
  • ByCreatedAt (159-161)
  • ByUpdatedAt (164-166)
  • ByDeletedAt (169-171)
  • ByName (174-176)
  • ByDescription (179-181)
  • ByAnnotations (214-216)
openmeter/ent/db/plan/plan.go (17)
  • FieldID (16-16)
  • FieldNamespace (18-18)
  • FieldMetadata (20-20)
  • FieldCreatedAt (22-22)
  • FieldUpdatedAt (24-24)
  • FieldDeletedAt (26-26)
  • FieldName (28-28)
  • FieldDescription (30-30)
  • Columns (75-90)
  • ByID (129-131)
  • OrderOption (126-126)
  • ByNamespace (134-136)
  • ByCreatedAt (139-141)
  • ByUpdatedAt (144-146)
  • ByDeletedAt (149-151)
  • ByName (154-156)
  • ByDescription (159-161)
openmeter/ent/db/mutation.go (2)
openmeter/ent/db/plan/plan.go (3)
  • EdgePhases (44-44)
  • EdgeAddons (46-46)
  • EdgeSubscriptions (48-48)
openmeter/ent/db/planaddon/planaddon.go (1)
  • EdgeAddon (45-45)
openmeter/ent/db/client.go (4)
openmeter/ent/db/planaddon_query.go (1)
  • PlanAddonQuery (22-34)
openmeter/ent/db/planaddon_create.go (1)
  • PlanAddonCreate (21-26)
openmeter/ent/db/planaddon_update.go (1)
  • PlanAddonUpdate (19-23)
openmeter/ent/db/planaddon_delete.go (1)
  • PlanAddonDelete (16-20)
openmeter/ent/db/planaddon_query.go (3)
openmeter/ent/db/plan_query.go (1)
  • PlanQuery (24-37)
openmeter/ent/db/addon_query.go (1)
  • AddonQuery (24-37)
openmeter/ent/db/planaddon/where.go (5)
  • Name (89-91)
  • PlanID (99-101)
  • IDIn (29-31)
  • ID (14-16)
  • AddonID (104-106)
openmeter/ent/db/planaddon_update.go (5)
openmeter/ent/db/mutation.go (1)
  • PlanAddonMutation (38220-38244)
openmeter/ent/db/predicate/predicate.go (1)
  • PlanAddon (210-210)
openmeter/ent/db/planaddon/where.go (7)
  • UpdatedAt (79-81)
  • DeletedAt (84-86)
  • Name (89-91)
  • Description (94-96)
  • FromPlanPhase (109-111)
  • MaxQuantity (114-116)
  • ID (14-16)
openmeter/ent/db/plan/plan.go (6)
  • UpdateDefaultUpdatedAt (110-110)
  • FieldID (16-16)
  • FieldUpdatedAt (24-24)
  • FieldDeletedAt (26-26)
  • FieldName (28-28)
  • FieldDescription (30-30)
openmeter/ent/db/planaddon/planaddon.go (8)
  • UpdateDefaultUpdatedAt (99-99)
  • FieldID (17-17)
  • FieldUpdatedAt (25-25)
  • FieldDeletedAt (27-27)
  • FieldName (29-29)
  • FieldDescription (31-31)
  • FieldFromPlanPhase (39-39)
  • FieldMaxQuantity (41-41)
openmeter/ent/db/planaddon/where.go (6)
openmeter/ent/db/addon/where.go (7)
  • ID (15-17)
  • Namespace (70-72)
  • CreatedAt (75-77)
  • UpdatedAt (80-82)
  • DeletedAt (85-87)
  • Name (90-92)
  • Description (95-97)
openmeter/ent/db/plan/where.go (7)
  • ID (14-16)
  • Namespace (69-71)
  • CreatedAt (74-76)
  • UpdatedAt (79-81)
  • DeletedAt (84-86)
  • Name (89-91)
  • Description (94-96)
openmeter/ent/db/planaddon.go (2)
  • PlanAddon (19-51)
  • PlanAddon (87-106)
openmeter/ent/db/predicate/predicate.go (3)
  • PlanAddon (210-210)
  • Plan (207-207)
  • Addon (10-10)
openmeter/ent/db/plan/plan.go (8)
  • FieldID (16-16)
  • FieldNamespace (18-18)
  • FieldCreatedAt (22-22)
  • FieldUpdatedAt (24-24)
  • FieldDeletedAt (26-26)
  • FieldName (28-28)
  • FieldDescription (30-30)
  • Table (50-50)
openmeter/ent/db/planaddon/planaddon.go (16)
  • FieldID (17-17)
  • FieldNamespace (19-19)
  • FieldCreatedAt (23-23)
  • FieldUpdatedAt (25-25)
  • FieldDeletedAt (27-27)
  • FieldName (29-29)
  • FieldDescription (31-31)
  • FieldPlanID (35-35)
  • FieldAddonID (37-37)
  • FieldFromPlanPhase (39-39)
  • FieldMaxQuantity (41-41)
  • Table (47-47)
  • PlanTable (49-49)
  • PlanColumn (54-54)
  • AddonTable (56-56)
  • AddonColumn (61-61)
openmeter/ent/db/planaddon_create.go (3)
openmeter/ent/db/addon/addon.go (10)
  • FieldID (19-19)
  • FieldNamespace (21-21)
  • FieldMetadata (23-23)
  • FieldCreatedAt (25-25)
  • FieldUpdatedAt (27-27)
  • FieldDeletedAt (29-29)
  • FieldName (31-31)
  • FieldDescription (33-33)
  • ValueScanner (128-130)
  • FieldAnnotations (47-47)
openmeter/ent/db/plan/plan.go (8)
  • FieldID (16-16)
  • FieldNamespace (18-18)
  • FieldMetadata (20-20)
  • FieldCreatedAt (22-22)
  • FieldUpdatedAt (24-24)
  • FieldDeletedAt (26-26)
  • FieldName (28-28)
  • FieldDescription (30-30)
openmeter/ent/db/planaddon/planaddon.go (14)
  • FieldID (17-17)
  • FieldNamespace (19-19)
  • FieldMetadata (21-21)
  • FieldCreatedAt (23-23)
  • FieldUpdatedAt (25-25)
  • FieldDeletedAt (27-27)
  • FieldName (29-29)
  • FieldDescription (31-31)
  • ValueScanner (107-109)
  • FieldAnnotations (33-33)
  • FieldFromPlanPhase (39-39)
  • FieldMaxQuantity (41-41)
  • FieldPlanID (35-35)
  • FieldAddonID (37-37)
⏰ Context from checks skipped due to timeout of 90000ms (10)
  • GitHub Check: Quickstart
  • GitHub Check: E2E
  • GitHub Check: CI
  • GitHub Check: Test
  • GitHub Check: Migration Checks
  • GitHub Check: Lint
  • GitHub Check: Developer environment
  • GitHub Check: Commit hooks
  • GitHub Check: Build
  • GitHub Check: Analyze (go)
🔇 Additional comments (147)
openmeter/ent/db/tx.go (2)

77-78: Good implementation of the PlanAddon client field

The addition of the PlanAddon field to the Tx struct follows the established pattern for other entity clients, maintaining consistency in the codebase's transaction handling approach.


260-260: Correct initialization of PlanAddon client

The initialization of the PlanAddon client in the init method follows the same pattern as other entity clients, ensuring consistent transaction behavior across all entities.

openmeter/ent/db/ent.go (2)

48-48: Good import addition for planaddon package

The import of the planaddon package is necessary for the column validation logic that follows later in the file.


149-149: Correct integration with column validation system

The addition of the planaddon.Table to the column validation mapping ensures that columns from the plan_addons table can be validated properly, maintaining data integrity.

openmeter/ent/db/plan/where.go (2)

776-785: Well-implemented HasAddons predicate function

The HasAddons function properly implements the HasEdge predicate on the "addons" edge, creating a step with the correct source table, field ID, and edge type (O2M) that references the plan_addons table and column. This enables filtering plans that have associated addons.


787-797: Correctly implemented HasAddonsWith predicate function

The HasAddonsWith function extends the basic addons relationship filtering by allowing additional predicates on the PlanAddon entities. This enables more complex queries like finding plans with addons that meet specific criteria, following the same pattern used for other entity relationships.

openmeter/ent/db/plan/plan.go (4)

45-46: Good addition of the EdgeAddons constant

The addition of the EdgeAddons constant follows the naming convention used for other edge names in the codebase, maintaining consistency.


58-64: Well-structured constants for PlanAddon relationship

These constants properly define the table and column names for the PlanAddon relationship, following the same pattern used for other entity relationships. The comments are also clear and informative.


207-219: Good implementation of ordering functions

The ByAddonsCount and ByAddons functions provide useful options for ordering query results based on PlanAddon relationships, consistent with similar functions for other entity types.


241-247: Well-implemented helper function for addons graph traversal

The newAddonsStep function correctly sets up the graph traversal step for the addons relationship, with proper source, destination, and edge type configuration. This function is essential for the predicate and ordering functions that leverage this relationship.

openmeter/ent/db/planaddon/planaddon.go (1)

1-201: Well-structured auto-generated code for PlanAddon entity

This auto-generated file establishes the foundation for the PlanAddon entity, defining constants, fields, validators, and ordering functions that follow the same patterns observed in similar entity files like plan.go and addon.go. The code correctly sets up the relationship structure between PlanAddon and its related Plan and Addon entities.

The file includes:

  • Constants for field names, edge names, and table details (lines 13-62)
  • SQL column definitions (lines 64-79)
  • Field validation functions (lines 91-106)
  • Ordering functions for various fields (lines 115-173)
  • Relationship navigation functions via ByPlanField and ByAddonField (lines 175-187)
tools/migrate/migrations/20250414115940_plan_addons.down.sql (1)

1-12: Clean migration rollback script

The SQL down migration correctly follows best practices by:

  1. Dropping indexes before dropping their associated table
  2. Using explicit DROP statements with clear naming conventions
  3. Including comments that explain each statement's purpose

This ensures a clean rollback of the plan_addons table and all its associated indexes when needed.

openmeter/ent/db/expose.go (1)

152-153: Proper integration of PlanAddon client in transaction system

The addition of the PlanAddon client follows the established pattern in the codebase for integrating new entity types into the transaction system. This change correctly instantiates a new PlanAddon client with the provided configuration, enabling transactional operations on PlanAddon entities.

openmeter/ent/schema/addon.go (1)

59-62: Well-defined edge from Addon to PlanAddon with cascade delete

This new edge properly establishes a relationship between Addon and PlanAddon entities with appropriate cascade delete behavior. When an Addon is deleted, all associated PlanAddon entries will be automatically removed, maintaining referential integrity.

The annotation with entsql.Cascade follows the same pattern used for other edges in this schema, ensuring consistency in the data model's behavior.

openmeter/ent/schema/productcatalog.go (1)

50-53: Well-implemented relationship with proper cascade deletion behavior.

The edge from Plan to PlanAddon is correctly defined with cascade delete behavior, ensuring that when a Plan is deleted, all associated add-on assignments are removed automatically. This maintains referential integrity in the database.

openmeter/ent/db/hook/hook.go (1)

372-382: Correctly implemented hook adapter for PlanAddon mutations.

The PlanAddonFunc implementation follows the established pattern in the codebase for defining hook adapters. The type and its Mutate method properly handle type checking and error reporting consistent with other entities.

openmeter/ent/db/addon/where.go (1)

802-823: Well-implemented predicates for querying plan-addon relationships.

These predicates correctly implement the HasEdge functionality for the new "plans" edge, allowing for both simple existence checks (HasPlans) and complex conditional queries (HasPlansWith). The implementation follows the established pattern in the codebase and uses the correct table and column references.

openmeter/ent/db/predicate/predicate.go (1)

209-221: Correctly implemented predicate type for PlanAddon entities.

The PlanAddon function type and PlanAddonOrErr helper follow the established pattern in the codebase. The error handling implementation correctly checks for nil errors before applying the predicate, maintaining consistency with other entity types.

openmeter/ent/db/addon.go (5)

60-61: New edge looks consistent with the schema design

The addition of the Plans field to AddonEdges correctly establishes the relationship between Addons and Plans via the new PlanAddon entity. This bidirectional relationship allows traversing from Addons to Plans effectively.


66-66: Update to loadedTypes is consistent with the new edge

The size expansion of loadedTypes from 2 to 3 properly accommodates the new Plans edge addition, maintaining the eager-loading tracking functionality.


78-85: PlansOrErr method follows standard pattern

This method correctly implements the error handling pattern for edge access, consistent with other similar methods in the codebase (like RatecardsOrErr). It properly checks if the Plans edge was loaded during eager-loading before allowing access.


90-90: Index update maintains correct order for edge checks

The index update for SubscriptionAddonsOrErr is necessary due to the insertion of the new Plans edge in the middle of the array. This maintains the correct relationship between the edge loading state and the loadedTypes tracking array.


240-243: QueryPlans method integrates correctly with Client API

The new QueryPlans method follows the established pattern for edge traversal queries. It delegates to the appropriate client method, maintaining the architecture's separation of concerns.

openmeter/ent/db/paginate.go (2)

1452-1495: Paginate implementation follows consistent pattern

The Paginate method for PlanAddonQuery correctly implements the standard pagination logic found throughout the codebase. This implementation:

  1. Gets limit and offset from the page
  2. Resets previous pagination settings
  3. Creates query duplicates for count and paging operations
  4. Handles the zero-value page case appropriately
  5. Applies pagination and returns the result with proper error handling

The implementation is consistent with all other entity types, which is essential for maintainable code.


1497-1498: Type check ensures interface compliance

The type check ensures that PlanAddonQuery implements the pagination.Paginator interface, which is a good practice for compile-time verification of interface compliance. This matches the pattern used for all other entity types.

openmeter/ent/db/plan.go (5)

57-58: New edge establishes bidirectional relationship

The addition of the Addons field to PlanEdges complements the corresponding Plans field in AddonEdges, establishing a proper bidirectional relationship through the new PlanAddon entity. This allows for efficient traversal in both directions.


63-63: Expanded loadedTypes array supports new edge

The size increase of loadedTypes from 2 to 3 properly accommodates the addition of the Addons edge while maintaining the edge loading state tracking functionality.


75-82: AddonsOrErr implements consistent access pattern

This method follows the standard edge access pattern by checking if the edge was loaded before allowing access. This maintains consistency with other similar methods in the codebase and prevents unintended access to edges that weren't loaded.


87-87: Index update preserves correct edge access order

Updating the index check in SubscriptionsOrErr from 1 to 2 is necessary due to the insertion of the new Addons edge. This ensures that the correct index in loadedTypes is checked for the Subscriptions edge.


231-234: QueryAddons method completes the API

The new QueryAddons method completes the API for the Plan-PlanAddon relationship, allowing for traversal queries from Plan to its assigned Addons. This implementation follows the standard pattern used throughout the codebase.

openmeter/ent/db/runtime.go (2)

39-39: Import of the new PlanAddon package looks good.

This is a necessary import to support the new PlanAddon schema being added.


1104-1137: PlanAddon schema initialization correctly implements the entity's required fields.

The implementation follows the same pattern used for other entities in the file, properly initializing:

  • Mixin fields
  • Namespace field with validator
  • Timestamp fields with default values
  • Annotations field with value scanner
  • PlanID and AddonID fields with validators
  • ID field with default value

This will enable proper database operations for the plan addon assignments.

openmeter/ent/db/migrate/schema.go (3)

1673-1743: Well-structured schema definition for PlanAddons

The new PlanAddonsColumns and PlanAddonsTable definitions follow the project's established patterns, with comprehensive column definitions, appropriate constraints, and well-configured indexes. The indexes are particularly well-designed, including the unique composite index on namespace, plan_id, and addon_id with a deleted_at condition, which prevents duplicate relationships while supporting soft deletion.


2397-2397: Correctly adding table to the Tables slice

The table has been appropriately added to the centralized Tables slice, ensuring it's included in schema operations.


2448-2449: Proper foreign key references setup

The foreign key references are correctly initialized in the init function, establishing the relationships between PlanAddons and their related tables (AddonsTable and PlansTable).

openmeter/ent/db/addon_create.go (3)

17-17: Proper import of the planaddon package

The addition of the planaddon import is necessary for establishing the relationship with the new PlanAddon entity.


207-220: Well-implemented methods for adding plan relationships to addons

These methods follow the established pattern for adding edges between entities:

  1. AddPlanIDs allows adding relationships by IDs
  2. AddPlans provides a convenience method for adding relationships by entity references

This maintains consistency with other relationship methods in the codebase.


460-475: Correctly implemented edge creation in createSpec

The implementation for handling "plans" edges in the createSpec method follows the established pattern in the codebase:

  1. Checks if there are any plan IDs specified in the mutation
  2. Creates an appropriate EdgeSpec with the correct relationship type and target
  3. Adds edge target nodes for each plan ID
  4. Appends the edge to the spec's Edges
openmeter/ent/db/plan_create.go (3)

16-16: Appropriate import for the planaddon package

The import of the planaddon package is necessary for establishing the bidirectional relationship between Plan and PlanAddon entities.


200-213: Well-implemented methods for adding addon relationships to plans

These methods provide a clean API for establishing relationships between plans and addons:

  1. AddAddonIDs for adding relationships by IDs
  2. AddAddons as a convenience method for adding relationships by entity references

The implementation is consistent with other relationship methods in the codebase.


437-452: Properly implemented edge creation in createSpec

The implementation for handling "addons" edges in the createSpec method correctly:

  1. Checks for the presence of addon IDs in the mutation
  2. Creates an appropriate EdgeSpec with the correct relationship type and target
  3. Adds edge target nodes for each addon ID
  4. Appends the edge to the spec's Edges

This ensures that the relationships between plans and addons are properly stored in the database.

openmeter/ent/schema/planaddon.go (4)

1-17: Looks good: New PlanAddon entity introduced correctly

The structure and declaration of the new PlanAddon entity follows the project's pattern for defining Ent schemas, appropriately extending the ent.Schema interface.


19-23: LGTM: Resource mixin correctly applied

Using the ResourceMixin from entutils is a good practice as it likely provides common fields and behaviors across entities in the system.


51-66: LGTM: Edge definitions properly establish bidirectional relationships

The edge definitions correctly establish the bidirectional relationships between PlanAddon and both Plan and Addon entities, using Ref to reference the appropriate edges in the other schemas. The field, required, immutable and unique constraints are appropriate for this relationship type.


68-83: LGTM: Well-designed indexes for query performance

The indexes are well-designed for query optimization:

  1. A unique index on namespace, plan_id, addon_id with a deleted_at IS NULL condition to enforce uniqueness of active records
  2. A GIN index on the annotations jsonb field for efficient queries on that column

Both will help with query performance in real-world usage.

openmeter/ent/db/addon_query.go (8)

17-19: LGTM: Appropriate import added

The planaddon import has been correctly added to support the new PlanAddon functionality.


30-32: LGTM: AddonQuery struct properly updated

The withPlans field has been correctly added to the AddonQuery struct to support eager loading of related PlanAddon entities.


92-112: LGTM: QueryPlans method implemented correctly

The QueryPlans method follows the same pattern as other query methods in the file, properly setting up the SQL graph traversal from Addon to PlanAddon entities.


329-330: LGTM: Clone method updated appropriately

The Clone method has been updated to include cloning the withPlans field, which is necessary for the method to work correctly with the new field.


348-357: LGTM: WithPlans method implemented correctly

The WithPlans method follows the same pattern as other similar methods, allowing for eager loading of the plans edge with optional configuration.


448-451: LGTM: loadedTypes array size updated

The loadedTypes array size has been increased from 2 to 3 to accommodate the new withPlans field.


482-488: LGTM: Plan loading logic added correctly

The code correctly checks for the withPlans query and loads the related PlanAddon entities if specified.


531-560: LGTM: loadPlans method implemented correctly

The loadPlans method follows the same pattern as other similar methods, handling the loading of related PlanAddon entities for Addon entities.

tools/migrate/migrations/20250414115940_plan_addons.up.sql (2)

1-19: LGTM: Table creation SQL well structured

The SQL for creating the plan_addons table is well structured with appropriate column types, constraints, and foreign key references. The CASCADE behavior on DELETE is appropriate for maintaining referential integrity.


20-29: LGTM: Appropriate indexes created

The migration creates appropriate indexes for the plan_addons table:

  1. A GIN index on the annotations jsonb column
  2. A unique index on the id column
  3. An index on the namespace column for faster filtering
  4. A unique composite index on namespace and id
  5. A unique conditional index on namespace, plan_id, and addon_id for non-deleted records

These indexes will improve query performance and enforce data integrity.

openmeter/ent/db/addon/addon.go (3)

50-70: LGTM: Constants for the plans edge properly defined

The constants for the plans edge (EdgePlans, PlansTable, PlansInverseTable, PlansColumn) are correctly defined following the same pattern as other edge constants in the file.


232-245: LGTM: Order functions for plans added correctly

The ByPlansCount and ByPlans functions follow the same pattern as similar functions for other edges, providing ways to order query results based on plans.


266-272: LGTM: newPlansStep helper function properly implemented

The newPlansStep function correctly sets up the SQL graph step for the plans edge, following the same pattern as other similar functions.

openmeter/ent/db/plan_query.go (8)

17-17: Good addition of the planaddon import.
This aligns with the new functionality for handling plan add-ons.


31-31: New field for eager-loading withAddons.
Storing the *PlanAddonQuery reference follows the same pattern used for phases and subscriptions, enabling eager-loading and better readability.


92-112: New QueryAddons method.
This mirrors the existing query methods for phases and subscriptions, ensuring consistent ent‐style chaining for the “addons” edge.


329-329: Cloning withAddons.
Carrying over the state for the withAddons field in Clone() preserves query behavior and prevents subtle bugs when reusing the query builder.


348-357: Introduced WithAddons eager-loading.
This method parallels WithPhases and WithSubscriptions, making the code more uniform and promoting a straightforward API for combined entity retrieval.


448-450: Tracking addons in loadedTypes.
Adding pq.withAddons != nil ensures that addons are recognized as loaded edges, which is necessary for correct assignment in subsequent logic.


482-488: Conditional loading of addons.
The check ensures we only load the “addons” edge if requested, optimizing performance and preventing unnecessary database queries.


529-558: loadAddons implementation.
This code properly matches the existing convention for loading edges via a foreign key, ensuring that each PlanAddon is accurately mapped back to its parent Plan.

openmeter/ent/db/planaddon_delete.go (1)

1-89: PlanAddon deletion workflow.
All methods—PlanAddonDelete, PlanAddonDeleteOne, Where, Exec, and sqlExec—are well structured and align with ent’s standard delete patterns. Consider adding unit tests specifically covering edge cases such as attempting to remove non-existent records or constraint-violating scenarios to strengthen reliability.

openmeter/ent/db/addon_update.go (13)

16-16: Importing planaddon.
This is required for referencing the new PlanAddon relationships from this update builder.


209-213: AddPlanIDs for bulk association.
Adding plan add-ons by ID aligns with ent’s approach. No issues found.


215-222: AddPlans convenience method.
Extracting IDs and forwarding to AddPlanIDs is consistent, providing a friendlier API.


265-269: ClearPlans method.
Clearing all plan add-ons ensures we can detach all related PlanAddon edges in a single call.


271-275: RemovePlanIDs method.
This targeted removal of specific plan add-on references enhances update granularity.


277-284: RemovePlans convenience method.
Similar to AddPlans, this is a straightforward extension that extracts IDs for removal.


470-514: Edge handling for plans in sqlSave.
The logic is well-aligned with ent’s pattern for clearing, removing, and adding edges. Ensure any external constraints (such as references to PlanAddon) are handled consistently.


754-758: UpdateOne: AddPlanIDs.
Mirroring the multi-update approach, this method cleanly enables single-entity plan add-on associations by ID.


760-767: UpdateOne: AddPlans.
The direct acceptance of PlanAddon pointers keeps the convenience approach for single-entity updates.


810-814: UpdateOne: ClearPlans.
Removing all plan add-ons from the single Addon entity remains consistent with multi-entity patterns.


816-820: UpdateOne: RemovePlanIDs.
Removing specific plan add-on references by ID remains straightforward and consistent.


822-829: UpdateOne: RemovePlans.
As with other convenience methods, wrapping ID extraction fosters consistency in the API.


990-1034: Edge specification in sqlSave.
The approach parallels the multi-entity update logic for clearing, removing, and adding plan add-ons. This remains consistent with the ent codebase patterns.

openmeter/ent/db/plan_update.go (13)

15-15: Importing planaddon.
Enables referencing the PlanAddon entity for plan-related add-on logic.


196-200: AddAddonIDs method.
Allows attaching references to existing plan add-ons via their IDs.


202-209: AddAddons convenience method.
Accepts PlanAddon objects and funnels them into AddAddonIDs. Straightforward and consistent.


252-256: ClearAddons method.
A full removal of associated add-on edges, ensuring a complete reset of plan add-ons.


258-262: RemoveAddonIDs method.
Offers precise control over which add-ons are detached from the plan.


264-271: RemoveAddons convenience method.
Mirrors the approach for removal by extracting IDs from PlanAddon objects.


442-486: Edge handling for addons in sqlSave.
Implements the clearing, removing, and adding pattern in line with other edges like phases and subscriptions. This consistency benefits maintainability.


714-718: UpdateOne: AddAddonIDs.
Matches the multi-update pattern, enabling attaching add-on IDs to a single plan record.


720-727: UpdateOne: AddAddons.
Accepts and processes PlanAddon objects, offering convenience for single-plan use cases.


770-774: UpdateOne: ClearAddons.
Ensures that all existing plan add-ons are fully detached from the single plan in an atomic operation.


776-780: UpdateOne: RemoveAddonIDs.
Removes a subset of add-ons from a single plan by referencing IDs.


782-789: UpdateOne: RemoveAddons.
Similar to RemoveAddonIDs, simplifying the process by extracting IDs from PlanAddon objects.


990-1034: Edge specification within UpdateOne sqlSave.
Properly handles the entire add-ons lifecycle—clearing, removing, and adding—mirroring the multi-entity update logic.

openmeter/ent/db/setorclear.go (4)

2228-2240: Check nil-handling consistency for DeletedAt fields.

The methods SetOrClearDeletedAt confirm to the established pattern of clearing the field on nil. This is consistent and correct. Adding unit tests to confirm that passing nil reliably clears the deleted timestamp would be beneficial.


2242-2254: Good practice for optional description field.

Using SetOrClearDescription for the optional string field prevents storing empty strings and keeps the meaning of “no description” consistent. This is well-aligned with the rest of the file.


2256-2268: Maintain consistent approach with Annotations.

Similar to the other methods, handling the Annotations map with a clear if nil is passed is consistent and clear. This is well-written.


2270-2282: Validate integer constraints for MaxQuantity.

The SetOrClearMaxQuantity methods are correct in concept. Consider adding validation (e.g., requiring non-negative values) if relevant to the domain. Otherwise, these changes appear solid.

openmeter/ent/db/planaddon.go (7)

1-2: Auto-generated file notice.

These lines contain the typical Ent generator disclaimer. No action needed.


3-16: File structure follows Ent conventions.

The package imports and the references to internal dependencies are standard and necessary. Looks good.


64-84: Edge accessors appear consistent with ENT patterns.

The PlanOrErr and AddonOrErr functions handle both “not loaded” and “not found” scenarios correctly. This is a standard ENT approach.


86-106: scanValues logic looks conventionally correct.

The code type-checks columns properly, matching them with the corresponding fields. No issues to report here.


108-204: assignValues systematically handles each field.

Each branch checks for the appropriate type and unmarshals JSON (for metadata, annotations). The error-handling approach is thorough. Looks good.


229-238: Unwrap method is standard for post-transaction usage.

This is the built-in Ent pattern to ensure queries proceed with the correct driver after a transaction closes. No issues here.


240-288: String method is clear and informative.

Constructing a readable representation of the entity fields is helpful for debugging. The approach is fine.

openmeter/ent/db/mutation.go (19)

49-49: Add planaddon import.
The added import for planaddon is consistent with the new PlanAddon entity usage.


108-108: Declare new TypePlanAddon.
This string constant aligns well with the newly introduced PlanAddon entity.


146-148: Add Plan-related collections in AddonMutation.
These fields (plans, removedplans, clearedplans) appear correct for tracking PlanAddon references.


1433-1433: Return plans edge in AddedEdges().
These lines follow the typical Ent pattern for collecting newly set edges.

Also applies to: 1437-1439


1456-1461: Return plans edge IDs in AddedIDs().
Implementation matches Ent conventions.


1474-1480: Track removedplans in RemovedEdges().
Implementation remains consistent with Ent mutation logic.


1497-1502: Implement RemovedIDs() for plans.
Reusing the removedplans set is aligned with Ent’s approach to edge removals.


1515-1521: Include plans in ClearedEdges().
Logic is consistent for tracking cleared edges.


1534-1535: Check if plans edge is cleared.
The method follows the same pattern used for other edges.


1557-1559: Call m.ResetPlans() in ResetEdge().
This code properly resets the relevant maps/flags for the plans edge.


36870-36872: Add addons fields to PlanMutation.
Naming matches the newly introduced PlanAddon relationship.


37592-37645: Add methods for addons in PlanMutation.
Includes relevant add/remove/clear for the PlanAddon edge. No issues noted.


38085-38091: Collect addons in AddedEdges().
Implementation is standard for capturing edges in Ent.


38108-38113: Provide addons IDs in AddedIDs().
Logic is consistent with how other edges handle ID retrieval.


38126-38132: Reflect removed addons in RemovedEdges().
Matches Ent’s edge removal pattern.


38149-38154: Return removed addons IDs in RemovedIDs().
Implementation is correct for tracking removals.


38167-38173: Return cleared addons in ClearedEdges().
This properly identifies the cleared edge.


38186-38187: Check addons edge clearance.
Straightforward boolean check, no issues.


38219-39379: Introduce PlanAddonMutation struct and fields.
The structure follows Ent’s standard approach for managing a new entity’s fields and edges (Plan and Addon). It accurately covers creation, update, and clearing logic.

openmeter/ent/db/client.go (11)

48-48: Import statement correctly added for the new PlanAddon schema.

The addition of the planaddon import statement follows the same pattern as other entity imports in the file.


128-129: PlanAddon client field correctly added to the Client struct.

The field includes proper documentation that follows the same pattern as other client fields in the struct, maintaining code consistency.


191-191: Client initialization for PlanAddon correctly implemented.

The initialization follows the same pattern as other client initializations in the init() method.


324-324: PlanAddon properly added to the transaction client initialization.

This ensures that PlanAddon operations can be part of database transactions, which is essential for maintaining data consistency when PlanAddon entities are created/modified alongside other entities.


384-384: PlanAddon properly added to the BeginTx transaction initialization.

Consistent with the previous transaction implementation, ensuring transactional integrity when using explicit transaction options.


432-433: PlanAddon client added to the mutation hooks system.

This allows the PlanAddon entity to leverage the hooks system for implementing custom logic before/after database operations.


454-455: PlanAddon client added to the query interceptors system.

This correctly integrates the PlanAddon entity with the query interceptor mechanism, enabling query transformations and custom query behaviors.


527-528: Added mutation handler for PlanAddon in the core Mutate method.

This ensures that PlanAddon mutations are correctly processed through the central mutation system.


678-692: QueryPlans method correctly implemented in AddonClient.

This method properly establishes the relationship between Addon and Plan entities through the PlanAddon join entity, using the correct edge definition for many-to-many relationship.


5744-5907: Complete PlanAddonClient implementation with all necessary methods.

The implementation follows the standard pattern for ent clients, including:

  • Constructor and configuration methods
  • CRUD operations (Create, Update, Delete, Query)
  • Query methods for traversing relationships to Plan and Addon entities
  • Hook and interceptor support
  • Mutation handling

This ensures that PlanAddon entities can be fully managed through the database layer.


7682-7682: PlanAddon added to hooks and interceptors collections.

This ensures that global hook and interceptor configurations apply to PlanAddon operations alongside other entity types.

Also applies to: 7696-7696

openmeter/ent/db/planaddon_query.go (4)

21-34: Auto-generated struct definition looks consistent.

The PlanAddonQuery struct layout follows the standard Ent pattern for query builders, including context, ordering, and predicates. This approach appears logically consistent and maintainable.


67-87: Eager loading with QueryPlan method is well-defined.

This method properly sets up a many-to-one edge to the Plan entity, ensuring a correct step path for neighbor resolution. The code uses sqlgraph.NewStep to traverse edges, which aligns with Ent’s best practices.


89-109: Eager loading with QueryAddon method is properly structured.

Similar to QueryPlan, this method accurately configures a many-to-one path to the Addon entity. No issues found with concurrency or correctness.


407-450: Efficient loading of associated Plan and Addon entities.

The loadPlan and loadAddon helpers effectively batch-related foreign-key lookups, reducing multiple round trips. Verify that all relevant fields are tested to ensure the correct foreign-key references.

Would you like a script to query usage of these loader functions throughout the codebase to confirm their coverage?

openmeter/ent/db/planaddon_update.go (2)

44-61: Check DeletedAt usage in partial updates.

Providing both SetDeletedAt(t) and ClearDeletedAt() suggests partial soft-deletion logic. Validate that this aligns with business requirements to handle deletion states consistently.


189-195: Automatic UpdatedAt defaults.

The defaults() function sets UpdatedAt to planaddon.UpdateDefaultUpdatedAt(). Confirm that manual user input for UpdatedAt is either preserved or overridden in line with your intent.

openmeter/ent/db/planaddon/where.go (3)

1-66: Predicate functions are comprehensive and consistent.

The various ID-based equality and range predicates (e.g., IDIn, IDGT) follow the typical Ent pattern and appear correct. No changes needed.


68-181: String field predicates offer thorough coverage.

The Namespace and Name fields—along with their variations (Contains, HasPrefix, etc.)—provide flexible querying. Ensure these are fully tested for any case-folding uses.


718-762: Relationship filters using HasPlan and HasAddon are well-structured.

These edge-based predicates allow flexible filtering of PlanAddon by associated Plan or Addon. The usage of newPlanStep() and newAddonStep() is in line with Ent’s recommended approach.

openmeter/ent/db/planaddon_create.go (4)

197-211: Validate default value usage for core fields.
The defaults() method sets created_at, updated_at, and id if they're missing. Confirm that there's no case in which the default ID assignment might conflict in large or distributed environments (e.g., if IDs are derived from UUID generation, ensure collisions do not occur).


213-258: Check strictness of required fields and edges.
Required fields such as namespace, created_at, updated_at, name, plan_id, addon_id, and from_plan_phase are enforced here. Required edges for plan and addon (lines 252–255) are also enforced. Verify that these constraints match actual business requirements—omitting the plan or add-on is disallowed at this level.


286-375: Ensure consistent error handling for plan/addon edge conflicts.
When building the spec in createSpec(), any conflict or constraint error (e.g., a non-existent plan or add-on reference) will be surfaced by sqlgraph.CreateNode. Make sure upstream logic handles these errors gracefully—especially if referencing plans/add-ons that might not exist (e.g., in concurrency scenarios).


899-919: Confirm conflict resolution strategy.
Using OnConflict for bulk inserts is powerful, but it can also introduce complexity, especially when upserting many records simultaneously. Confirm that your chosen resolution strategy (ResolveWithNewValues, Ignore, or DoNothing) is consistent with desired application behavior and won't mask critical data inconsistencies.

@chrisgacsal chrisgacsal force-pushed the feat/productcatalog branch 2 times, most recently from d1dfc17 to 4915cdf Compare April 14, 2025 12:16
Copy link
Contributor

@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: 1

♻️ Duplicate comments (1)
openmeter/ent/db/planaddon_update.go (1)

129-154: Validate max_quantity input.

Similar to the previous comment on potential domain errors with negative or excessively large values, ensure that SetMaxQuantity and AddMaxQuantity do not accept invalid inputs.

🧹 Nitpick comments (3)
openmeter/ent/db/setorclear.go (1)

2256-2268: SetOrClearAnnotations ensures flexible usage
These methods provide an easy way to remove existing annotations if nil is passed, which is helpful in scenarios where annotations must be explicitly cleared.

You might consider adding a small doc comment clarifying that passing an empty map vs. a nil pointer are handled differently (the latter clears, while the former sets an empty map).

openmeter/ent/db/client.go (1)

5790-5801: Consider adding a test for the complex new client implementation

While the generated code itself is reliable, it would be valuable to add tests specifically for the PlanAddon client to ensure that the relationships between Plan, PlanAddon, and Addon entities work as expected in practice, especially the bidirectional navigation.

openmeter/ent/db/planaddon_create.go (1)

618-770: Consider concurrency implications for upsert operations.

When performing upserts with fields like updated_at, concurrently modified entities might lose their latest updates if multiple transactions resolve conflicts using outdated values. Evaluate whether you need optimistic locking or version checks for high-concurrency environments.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8a7c23c and 4915cdf.

⛔ Files ignored due to path filters (1)
  • tools/migrate/migrations/atlas.sum is excluded by !**/*.sum
📒 Files selected for processing (35)
  • openmeter/ent/db/addon.go (3 hunks)
  • openmeter/ent/db/addon/addon.go (4 hunks)
  • openmeter/ent/db/addon/where.go (1 hunks)
  • openmeter/ent/db/addon_create.go (3 hunks)
  • openmeter/ent/db/addon_query.go (8 hunks)
  • openmeter/ent/db/addon_update.go (7 hunks)
  • openmeter/ent/db/client.go (13 hunks)
  • openmeter/ent/db/ent.go (2 hunks)
  • openmeter/ent/db/expose.go (1 hunks)
  • openmeter/ent/db/hook/hook.go (1 hunks)
  • openmeter/ent/db/migrate/schema.go (3 hunks)
  • openmeter/ent/db/mutation.go (20 hunks)
  • openmeter/ent/db/paginate.go (1 hunks)
  • openmeter/ent/db/plan.go (3 hunks)
  • openmeter/ent/db/plan/plan.go (4 hunks)
  • openmeter/ent/db/plan/where.go (1 hunks)
  • openmeter/ent/db/plan_create.go (3 hunks)
  • openmeter/ent/db/plan_query.go (8 hunks)
  • openmeter/ent/db/plan_update.go (7 hunks)
  • openmeter/ent/db/planaddon.go (1 hunks)
  • openmeter/ent/db/planaddon/planaddon.go (1 hunks)
  • openmeter/ent/db/planaddon/where.go (1 hunks)
  • openmeter/ent/db/planaddon_create.go (1 hunks)
  • openmeter/ent/db/planaddon_delete.go (1 hunks)
  • openmeter/ent/db/planaddon_query.go (1 hunks)
  • openmeter/ent/db/planaddon_update.go (1 hunks)
  • openmeter/ent/db/predicate/predicate.go (1 hunks)
  • openmeter/ent/db/runtime.go (2 hunks)
  • openmeter/ent/db/setorclear.go (1 hunks)
  • openmeter/ent/db/tx.go (2 hunks)
  • openmeter/ent/schema/addon.go (1 hunks)
  • openmeter/ent/schema/planaddon.go (1 hunks)
  • openmeter/ent/schema/productcatalog.go (1 hunks)
  • tools/migrate/migrations/20250414115940_plan_addons.down.sql (1 hunks)
  • tools/migrate/migrations/20250414115940_plan_addons.up.sql (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (13)
  • openmeter/ent/db/expose.go
  • tools/migrate/migrations/20250414115940_plan_addons.down.sql
  • openmeter/ent/schema/addon.go
  • openmeter/ent/db/tx.go
  • openmeter/ent/db/ent.go
  • openmeter/ent/db/hook/hook.go
  • openmeter/ent/db/plan.go
  • openmeter/ent/schema/productcatalog.go
  • openmeter/ent/db/planaddon_delete.go
  • openmeter/ent/db/addon_query.go
  • openmeter/ent/db/addon_create.go
  • tools/migrate/migrations/20250414115940_plan_addons.up.sql
  • openmeter/ent/db/planaddon/planaddon.go
🧰 Additional context used
🧬 Code Graph Analysis (21)
openmeter/ent/db/addon/where.go (3)
openmeter/ent/db/predicate/predicate.go (2)
  • Addon (10-10)
  • PlanAddon (210-210)
openmeter/ent/db/addon/addon.go (3)
  • Table (55-55)
  • FieldID (19-19)
  • PlansTable (64-64)
openmeter/ent/db/planaddon/planaddon.go (2)
  • Table (47-47)
  • FieldID (17-17)
openmeter/ent/db/predicate/predicate.go (5)
openmeter/ent/db/planaddon.go (2)
  • PlanAddon (19-51)
  • PlanAddon (87-106)
openmeter/ent/schema/planaddon.go (5)
  • PlanAddon (15-17)
  • PlanAddon (19-23)
  • PlanAddon (25-49)
  • PlanAddon (51-66)
  • PlanAddon (68-83)
api/client/javascript/src/client/schemas.ts (1)
  • PlanAddon (9828-9828)
api/api.gen.go (1)
  • PlanAddon (4763-4794)
api/client/go/client.gen.go (1)
  • PlanAddon (4459-4490)
openmeter/ent/db/plan/where.go (4)
openmeter/ent/db/subscription/where.go (2)
  • HasAddons (892-900)
  • HasAddonsWith (903-912)
openmeter/ent/db/predicate/predicate.go (2)
  • Plan (207-207)
  • PlanAddon (210-210)
openmeter/ent/db/plan/plan.go (4)
  • Table (50-50)
  • FieldID (16-16)
  • AddonsTable (59-59)
  • AddonsColumn (64-64)
openmeter/ent/db/planaddon/planaddon.go (2)
  • Table (47-47)
  • FieldID (17-17)
openmeter/ent/db/paginate.go (6)
openmeter/ent/db/planaddon_query.go (1)
  • PlanAddonQuery (22-34)
openmeter/ent/db/predicate/predicate.go (1)
  • PlanAddon (210-210)
openmeter/ent/schema/planaddon.go (5)
  • PlanAddon (15-17)
  • PlanAddon (19-23)
  • PlanAddon (25-49)
  • PlanAddon (51-66)
  • PlanAddon (68-83)
api/api.gen.go (1)
  • PlanAddon (4763-4794)
api/client/go/client.gen.go (1)
  • PlanAddon (4459-4490)
openmeter/ent/db/ent.go (1)
  • Count (204-208)
openmeter/ent/db/addon_update.go (6)
openmeter/ent/db/planaddon.go (2)
  • PlanAddon (19-51)
  • PlanAddon (87-106)
openmeter/ent/db/planaddon/where.go (1)
  • ID (14-16)
openmeter/ent/db/addon/addon.go (5)
  • Table (55-55)
  • PlansTable (64-64)
  • Columns (80-96)
  • PlansColumn (69-69)
  • FieldID (19-19)
openmeter/ent/db/plan/plan.go (3)
  • Table (50-50)
  • Columns (75-90)
  • FieldID (16-16)
openmeter/ent/db/planaddon/planaddon.go (3)
  • Table (47-47)
  • Columns (65-79)
  • FieldID (17-17)
openmeter/ent/db/migrate/schema.go (1)
  • PlansTable (1638-1672)
openmeter/ent/db/migrate/schema.go (3)
openmeter/ent/db/planaddon/where.go (1)
  • Name (89-91)
openmeter/ent/db/addon/addon.go (3)
  • Table (55-55)
  • Columns (80-96)
  • PlansTable (64-64)
openmeter/ent/db/plan/plan.go (2)
  • Table (50-50)
  • Columns (75-90)
openmeter/ent/schema/planaddon.go (4)
openmeter/ent/db/addon/addon.go (1)
  • ValueScanner (128-130)
openmeter/ent/db/planaddon/planaddon.go (1)
  • ValueScanner (107-109)
openmeter/ent/schema/notification.go (1)
  • AnnotationsValueScanner (347-368)
openmeter/ent/db/plan.go (2)
  • Plan (17-51)
  • Plan (94-113)
openmeter/ent/db/runtime.go (1)
openmeter/ent/db/planaddon/planaddon.go (1)
  • ValueScanner (107-109)
openmeter/ent/db/plan/plan.go (4)
openmeter/ent/db/subscription/subscription.go (6)
  • ByAddonsCount (254-258)
  • OrderOption (144-144)
  • ByAddons (261-265)
  • Table (54-54)
  • AddonsTable (84-84)
  • AddonsColumn (89-89)
openmeter/ent/db/addon/addon.go (2)
  • OrderOption (146-146)
  • Table (55-55)
openmeter/ent/db/planaddon/planaddon.go (2)
  • OrderOption (113-113)
  • Table (47-47)
openmeter/ent/db/migrate/schema.go (1)
  • AddonsTable (31-75)
openmeter/ent/db/addon/addon.go (3)
openmeter/ent/db/plan/plan.go (1)
  • Table (50-50)
openmeter/ent/db/planaddon/planaddon.go (1)
  • Table (47-47)
openmeter/ent/db/migrate/schema.go (1)
  • PlansTable (1638-1672)
openmeter/ent/db/plan_create.go (1)
openmeter/ent/db/planaddon/planaddon.go (1)
  • FieldID (17-17)
openmeter/ent/db/plan_query.go (7)
openmeter/ent/db/planaddon_query.go (1)
  • PlanAddonQuery (22-34)
openmeter/ent/db/plan/plan.go (4)
  • Table (50-50)
  • FieldID (16-16)
  • AddonsTable (59-59)
  • AddonsColumn (64-64)
openmeter/ent/db/planaddon/planaddon.go (3)
  • Table (47-47)
  • FieldID (17-17)
  • FieldPlanID (35-35)
openmeter/ent/db/plan.go (2)
  • Plan (17-51)
  • Plan (94-113)
openmeter/ent/db/predicate/predicate.go (2)
  • Plan (207-207)
  • PlanAddon (210-210)
openmeter/ent/db/planaddon.go (2)
  • PlanAddon (19-51)
  • PlanAddon (87-106)
openmeter/ent/db/planaddon/where.go (2)
  • ID (14-16)
  • PlanID (99-101)
openmeter/ent/db/planaddon.go (6)
openmeter/ent/db/ent.go (3)
  • NotFoundError (280-282)
  • NotLoadedError (326-328)
  • Value (65-65)
openmeter/ent/db/addon/addon.go (1)
  • Label (17-17)
openmeter/ent/db/plan/plan.go (1)
  • Label (14-14)
openmeter/ent/db/planaddon/planaddon.go (2)
  • Label (15-15)
  • FieldMaxQuantity (41-41)
openmeter/ent/db/client.go (1)
  • NewPlanAddonClient (5750-5752)
openmeter/ent/db/planaddon_update.go (1)
  • PlanAddonUpdateOne (279-284)
openmeter/ent/db/setorclear.go (1)
openmeter/ent/db/planaddon_update.go (2)
  • PlanAddonUpdate (19-23)
  • PlanAddonUpdateOne (279-284)
openmeter/ent/db/plan_update.go (3)
openmeter/ent/db/planaddon/where.go (1)
  • ID (14-16)
openmeter/ent/db/plan/plan.go (4)
  • Table (50-50)
  • AddonsTable (59-59)
  • AddonsColumn (64-64)
  • FieldID (16-16)
openmeter/ent/db/planaddon/planaddon.go (2)
  • Table (47-47)
  • FieldID (17-17)
openmeter/ent/db/mutation.go (3)
openmeter/ent/db/plan/plan.go (5)
  • EdgePhases (44-44)
  • EdgeAddons (46-46)
  • EdgeSubscriptions (48-48)
  • FieldDescription (30-30)
  • FieldName (28-28)
openmeter/ent/db/planaddon/planaddon.go (7)
  • FieldDescription (31-31)
  • FieldMaxQuantity (41-41)
  • FieldPlanID (35-35)
  • FieldAddonID (37-37)
  • FieldName (29-29)
  • FieldFromPlanPhase (39-39)
  • EdgeAddon (45-45)
openmeter/ent/db/planaddon/where.go (6)
  • Name (89-91)
  • Description (94-96)
  • PlanID (99-101)
  • AddonID (104-106)
  • FromPlanPhase (109-111)
  • MaxQuantity (114-116)
openmeter/ent/db/client.go (3)
openmeter/ent/db/planaddon/where.go (1)
  • ID (14-16)
openmeter/ent/db/planaddon/planaddon.go (1)
  • FieldID (17-17)
openmeter/ent/db/planaddon_create.go (1)
  • PlanAddonCreate (21-26)
openmeter/ent/db/planaddon_query.go (3)
openmeter/ent/db/plan_query.go (1)
  • PlanQuery (24-37)
openmeter/ent/db/addon_query.go (1)
  • AddonQuery (24-37)
openmeter/ent/db/planaddon/where.go (5)
  • Name (89-91)
  • PlanID (99-101)
  • IDIn (29-31)
  • ID (14-16)
  • AddonID (104-106)
openmeter/ent/db/planaddon/where.go (3)
openmeter/ent/db/predicate/predicate.go (3)
  • PlanAddon (210-210)
  • Plan (207-207)
  • Addon (10-10)
openmeter/ent/db/plan/plan.go (9)
  • FieldID (16-16)
  • FieldNamespace (18-18)
  • FieldCreatedAt (22-22)
  • FieldUpdatedAt (24-24)
  • FieldDeletedAt (26-26)
  • FieldName (28-28)
  • FieldDescription (30-30)
  • FieldMetadata (20-20)
  • Table (50-50)
openmeter/ent/db/planaddon/planaddon.go (18)
  • FieldID (17-17)
  • FieldNamespace (19-19)
  • FieldCreatedAt (23-23)
  • FieldUpdatedAt (25-25)
  • FieldDeletedAt (27-27)
  • FieldName (29-29)
  • FieldDescription (31-31)
  • FieldPlanID (35-35)
  • FieldAddonID (37-37)
  • FieldFromPlanPhase (39-39)
  • FieldMaxQuantity (41-41)
  • FieldMetadata (21-21)
  • FieldAnnotations (33-33)
  • Table (47-47)
  • PlanTable (49-49)
  • PlanColumn (54-54)
  • AddonTable (56-56)
  • AddonColumn (61-61)
openmeter/ent/db/planaddon_update.go (4)
openmeter/ent/db/mutation.go (1)
  • PlanAddonMutation (38220-38244)
openmeter/ent/db/predicate/predicate.go (1)
  • PlanAddon (210-210)
openmeter/ent/db/planaddon/where.go (7)
  • UpdatedAt (79-81)
  • DeletedAt (84-86)
  • Name (89-91)
  • Description (94-96)
  • FromPlanPhase (109-111)
  • MaxQuantity (114-116)
  • ID (14-16)
openmeter/ent/db/planaddon/planaddon.go (4)
  • FieldUpdatedAt (25-25)
  • FieldDeletedAt (27-27)
  • FieldName (29-29)
  • FieldDescription (31-31)
openmeter/ent/db/planaddon_create.go (5)
openmeter/ent/db/mutation.go (1)
  • PlanAddonMutation (38220-38244)
openmeter/ent/db/planaddon/where.go (11)
  • ID (14-16)
  • CreatedAt (74-76)
  • UpdatedAt (79-81)
  • Namespace (69-71)
  • Name (89-91)
  • PlanID (99-101)
  • AddonID (104-106)
  • FromPlanPhase (109-111)
  • DeletedAt (84-86)
  • Description (94-96)
  • MaxQuantity (114-116)
openmeter/ent/db/addon/addon.go (14)
  • DefaultCreatedAt (112-112)
  • DefaultUpdatedAt (114-114)
  • DefaultID (126-126)
  • NamespaceValidator (110-110)
  • FieldID (19-19)
  • FieldNamespace (21-21)
  • FieldMetadata (23-23)
  • FieldCreatedAt (25-25)
  • FieldUpdatedAt (27-27)
  • FieldDeletedAt (29-29)
  • FieldName (31-31)
  • FieldDescription (33-33)
  • ValueScanner (128-130)
  • FieldAnnotations (47-47)
openmeter/ent/db/plan/plan.go (12)
  • DefaultCreatedAt (106-106)
  • DefaultUpdatedAt (108-108)
  • DefaultID (122-122)
  • NamespaceValidator (104-104)
  • FieldID (16-16)
  • FieldNamespace (18-18)
  • FieldMetadata (20-20)
  • FieldCreatedAt (22-22)
  • FieldUpdatedAt (24-24)
  • FieldDeletedAt (26-26)
  • FieldName (28-28)
  • FieldDescription (30-30)
openmeter/ent/db/planaddon/planaddon.go (18)
  • DefaultCreatedAt (95-95)
  • DefaultUpdatedAt (97-97)
  • DefaultID (105-105)
  • NamespaceValidator (93-93)
  • FieldID (17-17)
  • FieldNamespace (19-19)
  • FieldMetadata (21-21)
  • FieldCreatedAt (23-23)
  • FieldUpdatedAt (25-25)
  • FieldDeletedAt (27-27)
  • FieldName (29-29)
  • FieldDescription (31-31)
  • ValueScanner (107-109)
  • FieldAnnotations (33-33)
  • FieldFromPlanPhase (39-39)
  • FieldMaxQuantity (41-41)
  • FieldPlanID (35-35)
  • FieldAddonID (37-37)
⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: E2E
  • GitHub Check: CI
  • GitHub Check: Lint
  • GitHub Check: Developer environment
  • GitHub Check: Commit hooks
  • GitHub Check: Test
  • GitHub Check: Analyze (go)
🔇 Additional comments (112)
openmeter/ent/db/plan/where.go (2)

776-785: Well-implemented HasAddons predicate function.

The implementation correctly establishes the HasEdge predicate on the "addons" edge, following the same pattern as other edge predicates in this file. It properly uses the one-to-many relationship and the correct table/column constants.


787-797: Well-implemented HasAddonsWith predicate function with variadic parameters.

This function correctly extends the basic HasAddons functionality by allowing additional filtering conditions through predicate.PlanAddon parameters. The implementation follows the same pattern as other similar functions in the file (e.g., HasPhasesWith, HasSubscriptionsWith).

openmeter/ent/db/runtime.go (2)

39-39: Import addition for the new PlanAddon schema.

This import is correctly added to support the PlanAddon schema being initialized in the file.


1104-1137: Proper initialization of PlanAddon schema definitions.

The code correctly initializes the PlanAddon schema with appropriate field descriptors, validators, and default values. It follows the same pattern as other entity types, ensuring consistency throughout the codebase.

openmeter/ent/db/predicate/predicate.go (1)

209-221: New PlanAddon predicate functions added correctly.

The addition of the PlanAddon type and PlanAddonOrErr function follows the established pattern in the codebase. The error handling is consistent with other similar functions, properly checking for nil errors and adding them to the SQL selector.

openmeter/ent/db/addon/where.go (1)

802-823: Added functions for querying Plans relationships.

The HasPlans and HasPlansWith functions are correctly implemented to enable filtering Addons based on their relationship with Plans. They utilize the standard SQL graph operations consistent with other relationship queries in the codebase.

openmeter/ent/db/addon.go (4)

60-66: Added Plans field to AddonEdges and updated loadedTypes array.

The Plans field and the update to the loadedTypes array size are necessary to accommodate the new relationship between Addon and PlanAddon. The loadedTypes increase from 2 to 3 correctly accounts for the additional edge being tracked.


78-85: Added PlansOrErr method to check if Plans edge is loaded.

This method follows the pattern used by other similar methods in the struct, correctly checking if the Plans edge has been loaded before returning the result.


90-90: Updated index in SubscriptionAddonsOrErr method.

This correctly updates the index check from the old value to account for the addition of the Plans edge in the loadedTypes array.


240-243: Added QueryPlans method to navigate to related PlanAddons.

This method enables querying the "plans" edge of the Addon entity, consistent with the other edge query methods. It correctly uses the client to perform the query.

openmeter/ent/db/paginate.go (2)

1452-1495: Implementation looks correct and consistent with other Paginate methods.

The new Paginate method for PlanAddonQuery follows the established pattern in the codebase, correctly implementing pagination functionality for the new PlanAddon entity. The method properly handles pagination parameters, counting, and result retrieval.


1497-1498: Type check confirms interface implementation.

This type assertion verifies that PlanAddonQuery implements the pagination.Paginator interface, which is a good practice to ensure type safety at compile time.

openmeter/ent/db/migrate/schema.go (4)

1673-1688: Well-structured schema definition for plan_addons table.

The column definitions for the new plan_addons table are comprehensive and include all necessary fields:

  • Standard metadata columns (id, namespace, timestamps, etc.)
  • Annotations stored as JSONB for flexible metadata
  • Relationship fields (addon_id and plan_id)
  • Business logic fields (from_plan_phase and max_quantity)

The schema design follows the conventions established in other tables.


1689-1743: Table schema includes appropriate indexes and foreign key constraints.

The schema definition includes:

  • Proper primary key on the id column
  • Foreign key constraints to both addons and plans tables with CASCADE behavior
  • Efficient indexes including a unique composite index on namespace/plan_id/addon_id
  • GIN index on the JSONB annotations field for performance

This design will ensure data integrity and query performance.


2397-2397: PlanAddonsTable is correctly added to the Tables slice.

The new table is properly included in the global Tables slice, ensuring it will be part of the generated database schema.


2448-2449: Foreign key references are properly established.

The foreign key references between the plan_addons table and the addons/plans tables are correctly established in the init function.

openmeter/ent/db/plan_create.go (3)

15-16: Import of the new planaddon package added

The addition of the import statement for the planaddon package is necessary to support the new relationship between Plan and PlanAddon entities.


200-213: Methods added to support relationship with PlanAddon entities

These two new methods follow the same pattern as the existing AddPhaseIDs and AddPhases methods, maintaining consistency in the codebase. The implementation correctly handles the conversion from PlanAddon objects to IDs and properly chains method calls.


437-452: Relationship handling in createSpec method

This added code block correctly implements the edge specification for the PlanAddon relationship, following the same pattern as the existing code for phases and subscriptions. The implementation properly sets up the O2M (one-to-many) relationship between Plan and PlanAddon entities.

openmeter/ent/schema/planaddon.go (4)

15-17: New PlanAddon schema struct defined

The creation of the PlanAddon schema struct establishes the foundation for the plan add-on assignments database schema, implementing the core objective of this PR.


19-23: ResourceMixin used for common fields

Good use of the ResourceMixin to inherit common fields and behavior, promoting code reuse and maintaining consistency with other schema definitions in the codebase.


51-66: Bidirectional relationships established

The edges are correctly defined to create bidirectional relationships between PlanAddon and both Plan and Addon entities. The use of Required, Immutable, and Unique constraints ensures data integrity.


68-83: Indexes defined for performance and data integrity

Well-structured indexes that will enhance query performance and enforce data constraints:

  1. A unique composite index on namespace, plan_id, and addon_id with a condition to exclude deleted records
  2. A GIN index on the annotations field optimized for PostgreSQL's jsonb type
openmeter/ent/db/plan/plan.go (4)

45-46: Added EdgeAddons constant

This constant correctly defines the string identifier for the addons edge name in mutations, maintaining consistency with other edge definitions.


58-64: Added constants for the addons relationship

These constants properly define the table names and column for the relationship between Plan and PlanAddon entities, following the same pattern used for other relationships.


207-219: Methods added for ordering by addons

These methods provide the ability to order Plan entities by their associated addons, enhancing query capabilities. The implementation follows the established pattern in the codebase.


241-247: Added step function for the addons edge

This function correctly creates a new step for navigating the addons edge in SQL graph queries, defining the source table, target table, and edge properties.

openmeter/ent/db/addon/addon.go (4)

50-51: Added EdgePlans constant

This constant correctly defines the string identifier for the plans edge name in mutations, maintaining consistency with the other edge definitions in the file.


63-69: Added constants for the plans relationship

These constants properly define the table names and column for the relationship between Addon and PlanAddon entities, following the same pattern used for other relationships in the file.


232-244: Methods added for ordering by plans

These methods provide the ability to order Addon entities by their associated plans, enhancing query capabilities. The implementation follows the established pattern in the codebase for similar ordering functions.


266-272: Added step function for the plans edge

This function correctly creates a new step for navigating the plans edge in SQL graph queries, defining the source table, target table, and edge properties. It maintains consistency with the implementation of other step functions in the file.

openmeter/ent/db/addon_update.go (9)

16-16: No concerns with the new import.
This import is required for referencing PlanAddon relationships in this file.


209-213: Implementation appears consistent with ent's edge management.
No issues found. This method properly adds plan IDs to the update builder.


215-222: Good approach for bulk additions.
This method systematically extracts IDs from PlanAddon objects and reuses AddPlanIDs.


265-269: No concerns.
Clearing the plans edge is implemented with consistency to the ent approach.


271-275: Edge removal approach is correct.
This removes the relationship by plan IDs, aligning with ent practices.


277-284: Standard pattern for ent.
Your code extracts IDs from PlanAddon objects and calls RemovePlanIDs, ensuring consistent usage.


470-482: Edge clearing logic recognized.
Properly handles removing all plan edges on update if requested.


483-498: Conditional edge removal logic is correct.
Removes specific plan edges only if they have not been cleared en masse.


499-514: Bulk addition of plan edges is correct.
Adds plan nodes to the edge spec, consistently reflecting ent's O2M approach.

openmeter/ent/db/plan_query.go (8)

17-17: Import is valid.
This import is required to manage planaddon queries from this package.


31-31: New field added for addons.
Storing a pointer to PlanAddonQuery allows chaining to the relevant edge.


92-112: Comprehensive query method.
This method follows ent's pattern for edge queries and ensures the correct O2M step.


329-329: Clone logic is consistent.
Retaining the withAddons state ensures the cloned query includes all relevant edges.


348-357: Eager-loading implementation looks correct.
Allows optional configuration of the PlanAddonQuery, matching ent's standard approach.


448-452: Tracking loaded edges.
Including withAddons in the loadedTypes array appropriately flags that edge as loaded.


482-488: Eager-loading for addons.
Properly calls loadAddons and appends the resulting PlanAddon entities to the plan edges.


529-558: Method pattern consistent with similar load functions.
Leverages the foreign key matching on plan_id to fetch related PlanAddons.

openmeter/ent/db/plan_update.go (13)

15-15: New planaddon import.
Required for referencing the PlanAddon edges in plan update entities.


196-201: Edge addition API.
This is consistent with the ent pattern for linking Plan to PlanAddon by ID.


202-209: Synchronous approach for adding multiple PlanAddons.
Extracting IDs from the slice ensures reusability with AddAddonIDs.


252-256: Edge clearing logic is straightforward.
Removes all addon references from a plan when invoked.


258-262: Removes addons by ID.
Consistent approach to removing specific edges without a full clear.


264-271: Bulk removing addons by entity references.
Implementation matches the pattern used in the file for other edges.


442-486: Edge handling in sqlSave.
Successfully manages clearing, removing, and adding addon edges with proper checks.

If you have time, consider verifying concurrency scenarios by running tests that simulate concurrent updates to ensure no race conditions are introduced.


714-718: Adding add-on IDs logic.
Mirrors the approach in PlanUpdate, providing consistent usage for single-entity updates.


720-727: Synchronous approach for single entity.
Adds PlanAddon references by extracting IDs and calling AddAddonIDs.


770-774: Clear addons for single entity update.
Effectively sets up to remove all PlanAddon edges for this plan instance.


776-780: Removes add-on references by ID.
Maintains consistency with the multi-edge approach in PlanUpdateOne.


782-789: Entity-based removal approach.
Extracts the IDs from the add-on entities, matching the established pattern.


990-1034: Ensures correct handling of addons in single-entity updates.
Covers clearing, removing, and adding edges, consistent with the ent framework approach.

Consider adding test coverage to check for constraints on repeated PlanAddons or concurrency issues.

openmeter/ent/db/setorclear.go (4)

2214-2226: Consistency of SetOrClearMetadata for PlanAddonUpdate and PlanAddonUpdateOne
The SetOrClearMetadata methods follow a clear pattern of setting the metadata if non-nil or clearing it otherwise. This is consistent with the rest of the file and provides a concise way to handle optional updates.


2228-2240: SetOrClearDeletedAt matches expected null-handling
These methods correctly clear or set the deleted_at field based on whether the provided value is nil. This pattern cleanly differentiates between a missing field and an explicit null.


2242-2254: SetOrClearDescription for PlanAddon
The logic for conditionally clearing or assigning the description on nil input is consistent and intuitive. This adheres to the standard approach seen in other SetOrClear methods.


2270-2282: SetOrClearMaxQuantity handles optional integer semantics
Like the other methods, this pattern is clear. It ensures the field is properly unset when nil is given. Overall, the approach is consistent and meets the requirements for optional integer fields.

openmeter/ent/db/planaddon.go (9)

18-51: Well-structured PlanAddon entity definition
The PlanAddon struct fields comprehensively reflect the schema requirements, including optional fields (DeletedAt, Description, MaxQuantity) and proper types for complex fields like Annotations and Metadata. This design appears consistent with other entities in the codebase.


53-62: Edges struct is consistent with Ent’s edge-loading conventions
The PlanAddonEdges struct includes the expected references (Plan, Addon) and a loadedTypes array to indicate which edges were fetched. This aligns well with Ent's recommended pattern.


64-84: PlanOrErr / AddonOrErr edge checks
These methods properly distinguish between an edge that’s not loaded and one that’s loaded yet missing in the database, using NotLoadedError and NotFoundError. Good error reporting.


86-106: scanValues method covers all PlanAddon columns
The method clearly enumerates known fields (e.g., FieldMaxQuantity) and assigns suitable data holders (e.g., sql.NullInt64). This is consistent with standard Ent code generation and ensures proper scanning of each column.


108-204: assignValues method robustly handles JSON deserialization
This method accounts for potential JSON parsing errors (e.g., for metadata) and ensures valid type checks. The approach of assigning DeletedAt, Description, and MaxQuantity via pointers is correct and safe.


206-210: Value method for dynamic columns
Exposing Value(name string) (ent.Value, error) is a helpful feature for retrieving fields by name. No red flags here.


212-227: QueryPlan / QueryAddon and Update methods
These methods integrate the newly introduced PlanAddon with the Ent client for relationship queries and updates, ensuring consistency with typical Ent-based usage.


229-238: Unwrap method clarifies transactional context
Unwrap transitions a PlanAddon entity from a transactional to a non-transactional context once the transaction is closed, which is the standard Ent approach.


240-288: String method and PlanAddons slice
The String method forms a readable representation of the entity’s fields. Additionally, the PlanAddons slice type is an idiomatic way to handle lists of PlanAddon objects.

openmeter/ent/db/mutation.go (20)

49-49: Import for planaddon looks good.
No issues identified.


108-108: Constant definition is consistent.
This aligns with existing naming for entity types.


146-148: Addition of fields for tracking PlanAddon edges is sound.
These additions neatly follow the Ent pattern for edge state tracking.


917-970: Edge methods for “plans” in AddonMutation are standard.
They conform to Ent’s typical approach for many-to-many relationships. Consider adding tests to ensure “plans” are correctly attached/detached.


1433-1439: Edge detection in AddedEdges is correct.
No concerns—this is standard Ent behavior for capturing newly linked edges.


1456-1461: Retrieving added Plan IDs is consistent.
Implementation is minimal and appropriate.


1474-1480: RemovedEdges logic is correct.
It properly reports the “plans” edge when removed.


1497-1502: Removed Plan IDs are tracked as expected.
No issues found.


1515-1521: ClearedEdges logic is consistent.
It adequately handles the cleared “plans” edge.


1534-1535: EdgeCleared check is correct.
Returns the correct bool for cleared plan edges.


1557-1559: Resets “plans” edge as expected.
Implementation aligns with Ent patterns.


36870-36872: New edge fields for PlanMutation appear correct.
This adds tracking for the “addons” relationship.


37592-37646: Methods for AddonIDs in PlanMutation follow Ent’s structure.
Everything looks good. Suggest verifying coverage with integration tests.


38085-38091: PlanMutation.AddedEdges logic is fine.
Detecting newly linked addons is straightforward and consistent.


38108-38113: AddedIDs switch case for plan.EdgeAddons is correct.
No concerns here.


38126-38135: RemovedEdges handling for “addons” is consistent.
Implementation mirrors the rest of the codebase.


38149-38154: RemovedAddonsIDs retrieval is valid.
This logic properly accumulates removed add-on IDs.


38167-38173: ClearedEdges for “addons” looks good.
It cleanly captures the scenario where all add-ons are cleared.


38186-38187: EdgeCleared for plan.EdgeAddons is accurate.
Implements the standard edge-clearing pattern.


38219-39380: PlanAddonMutation logic is comprehensive and follows Ent’s patterns.
No structural issues noted. Ensure tests cover newly introduced fields (e.g., max_quantity, annotations) and confirm that no sensitive PII is stored in plain text.

openmeter/ent/db/client.go (10)

48-48: Looks good: Added import for PlanAddon

The import statement for the new PlanAddon module has been properly added.


128-129: Appropriate client field addition

The PlanAddon client field has been properly added to the Client struct with appropriate comments following the existing pattern.


191-191: Client properly initialized

The PlanAddon client is correctly initialized in the init method, maintaining consistency with other client initializations.


324-324: Transaction support properly implemented

The PlanAddon client is correctly added to both transaction initialization methods (Tx and BeginTx), ensuring proper transaction support for the new entity.

Also applies to: 384-384


432-433: Hook and interceptor registration properly implemented

The PlanAddon client is correctly registered with the hooks and interceptors mechanisms, ensuring that custom behaviors can be attached to PlanAddon operations.

Also applies to: 454-455


527-528: Mutation handling properly implemented

The PlanAddon entity is correctly integrated into the mutation handling mechanism, allowing it to participate in database operations through the central client.


678-692: Bidirectional relationship properly implemented

The QueryPlans method in AddonClient creates a bidirectional relationship between Addon and PlanAddon entities, allowing navigation from an addon to its associated plans.


5744-5907: Comprehensive PlanAddon client implementation

The PlanAddonClient is thoroughly implemented with all necessary methods:

  • Standard CRUD operations (Create, Update, Delete)
  • Bulk operations
  • Query capabilities
  • Edge navigation to related entities (Plan, Addon)
  • Hooks and interceptors support

This follows the consistent pattern used throughout the codebase for entity clients.


7682-7683: Hooks and interceptors correctly registered

PlanAddon is properly added to the hooks and interceptors structs, ensuring that the global hooks and interceptors registration will work correctly for this new entity.

Also applies to: 7696-7697


5852-5882: Well-implemented edge query methods

The QueryPlan and QueryAddon methods are properly implemented to allow navigation from a PlanAddon to its associated Plan and Addon entities. This follows the established pattern in the codebase and will allow for efficient querying of related entities.

openmeter/ent/db/planaddon_query.go (2)

21-630: Check for missing Paginate method mentioned in summary.

The AI-generated summary references a new Paginate method, but it’s not present in this file. Ensure the summary is accurate, or confirm whether the actual implementation was committed.

Likely an incorrect or invalid review comment.


21-630: Looks good overall.

All standard Ent query-building functionalities appear correctly implemented. The struct, edge queries, and eager-loading logic follow best practices for Ent’s code generation.

openmeter/ent/db/planaddon_update.go (1)

18-276: Consider adding unit tests for update methods.

Although these builders are generated, it’s beneficial to validate that fields like deleted_at, max_quantity, etc., are updated as intended, and edges aren’t improperly cleared. Consider adding coverage in your test suite.

openmeter/ent/db/planaddon/where.go (1)

1-778: All predicates look good.

These generated predicates comprehensively cover filter operations on PlanAddon fields and edges, adhering to Ent standards.

openmeter/ent/db/planaddon_create.go (4)

213-258: Great job adding robust validation checks.

Requiring fields like namespace, name, plan_id, addon_id, and from_plan_phase ensures data completeness and consistency upon creation. The explicit checks in the check function are beneficial for preventing invalid inserts.


249-250: Confirm necessity of the from_plan_phase requirement.

Currently, the code mandates that the from_plan_phase field is always set. If there's a scenario where a Plan Add-on can be created without a phase, consider allowing this field to be optional.


198-211: Default value logic is well-structured.

Automatically setting default created_at, updated_at, and id fields through defaults() is a clean approach. Remember to confirm that DefaultCreatedAt(), DefaultUpdatedAt(), and DefaultID() are declared properly in the planaddon package to avoid runtime errors.


594-607: Note potential MySQL limitation for DoNothing.

The DoNothing clause is only supported by SQLite and PostgreSQL. If MySQL support is required, this code path may not produce the desired effect. Ensure that your deployment environment aligns with this assumption, or consider an alternative conflict resolution strategy for MySQL.

@chrisgacsal chrisgacsal force-pushed the feat/productcatalog branch 2 times, most recently from ea8fa05 to ddf486b Compare April 14, 2025 13:26
Copy link
Contributor

@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: 0

♻️ Duplicate comments (3)
openmeter/ent/db/planaddon_update.go (1)

129-154: Consider validating max_quantity to prevent domain issues.

Methods such as SetMaxQuantity, AddMaxQuantity, and ClearMaxQuantity handle updates to max_quantity but there's no explicit validation to prevent negative or otherwise invalid values. This mirrors the concern raised in previous reviews.

openmeter/ent/db/planaddon/where.go (1)

113-116: Revisit range validations on MaxQuantity.

While this file only defines the predicate by which you can filter PlanAddon records via their max_quantity, there's still no direct domain validation. If you anticipate disallowing negative or extremely large values, consider adding a validator at the schema level or within create/update logic.

openmeter/ent/db/planaddon_create.go (1)

126-138: Add validation for max_quantity boundaries.

Like in the update builder, there is no explicit constraint preventing negative or large values. Since SetMaxQuantity and SetNillableMaxQuantity are crucial entry points, reusing or adding domain logic here would protect from invalid assignments.

🧹 Nitpick comments (4)
openmeter/ent/db/addon_update.go (1)

470-514: Handling 'plans' edges in sqlSave.

Implementation follows the existing One-to-Many handling approach for edges.

Consider verifying that one Addon can indeed have multiple PlanAddon records. If a true many-to-many relationship is needed, you might configure an M2M edge instead of O2M.

openmeter/ent/db/planaddon.go (1)

241-288: String method offers a thorough representation of PlanAddon.

  1. Provides a readable debug or logging view.
  2. Minor grammar nit: line 43's field doc commentary says “available fro purchase” instead of “available for purchase.” Consider updating the doc.
- // The key identifier of the plan phase from the add-on is available fro purchase.
+ // The key identifier of the plan phase from which the add-on is available for purchase.
openmeter/ent/db/mutation.go (1)

38209-39379: Add PlanAddonMutation

This large addition follows ent’s standard mutation framework for PlanAddon fields and edges.

We recommend ensuring robust test coverage (create, update, clear) for PlanAddon and its edges. Let us know if you need assistance in creating a test outline or opening a new issue to track test coverage.

openmeter/ent/db/planaddon_create.go (1)

140-152: Evaluate user-supplied ID risks.

Allowing external calls to SetID (or SetNillableID) can lead to key collisions if those IDs are not guaranteed unique outside the DB. If user-supplied IDs are intended, consider checks or fallback generation to avoid potential duplication.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4915cdf and ddf486b.

⛔ Files ignored due to path filters (1)
  • tools/migrate/migrations/atlas.sum is excluded by !**/*.sum
📒 Files selected for processing (35)
  • openmeter/ent/db/addon.go (3 hunks)
  • openmeter/ent/db/addon/addon.go (4 hunks)
  • openmeter/ent/db/addon/where.go (1 hunks)
  • openmeter/ent/db/addon_create.go (3 hunks)
  • openmeter/ent/db/addon_query.go (8 hunks)
  • openmeter/ent/db/addon_update.go (7 hunks)
  • openmeter/ent/db/client.go (13 hunks)
  • openmeter/ent/db/ent.go (2 hunks)
  • openmeter/ent/db/expose.go (1 hunks)
  • openmeter/ent/db/hook/hook.go (1 hunks)
  • openmeter/ent/db/migrate/schema.go (3 hunks)
  • openmeter/ent/db/mutation.go (20 hunks)
  • openmeter/ent/db/paginate.go (1 hunks)
  • openmeter/ent/db/plan.go (3 hunks)
  • openmeter/ent/db/plan/plan.go (4 hunks)
  • openmeter/ent/db/plan/where.go (1 hunks)
  • openmeter/ent/db/plan_create.go (3 hunks)
  • openmeter/ent/db/plan_query.go (8 hunks)
  • openmeter/ent/db/plan_update.go (7 hunks)
  • openmeter/ent/db/planaddon.go (1 hunks)
  • openmeter/ent/db/planaddon/planaddon.go (1 hunks)
  • openmeter/ent/db/planaddon/where.go (1 hunks)
  • openmeter/ent/db/planaddon_create.go (1 hunks)
  • openmeter/ent/db/planaddon_delete.go (1 hunks)
  • openmeter/ent/db/planaddon_query.go (1 hunks)
  • openmeter/ent/db/planaddon_update.go (1 hunks)
  • openmeter/ent/db/predicate/predicate.go (1 hunks)
  • openmeter/ent/db/runtime.go (2 hunks)
  • openmeter/ent/db/setorclear.go (1 hunks)
  • openmeter/ent/db/tx.go (2 hunks)
  • openmeter/ent/schema/addon.go (1 hunks)
  • openmeter/ent/schema/planaddon.go (1 hunks)
  • openmeter/ent/schema/productcatalog.go (1 hunks)
  • tools/migrate/migrations/20250414132348_plan_addons.down.sql (1 hunks)
  • tools/migrate/migrations/20250414132348_plan_addons.up.sql (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • tools/migrate/migrations/20250414132348_plan_addons.down.sql
🚧 Files skipped from review as they are similar to previous changes (15)
  • openmeter/ent/schema/addon.go
  • openmeter/ent/db/tx.go
  • openmeter/ent/db/hook/hook.go
  • openmeter/ent/db/predicate/predicate.go
  • openmeter/ent/db/ent.go
  • openmeter/ent/db/expose.go
  • openmeter/ent/schema/productcatalog.go
  • openmeter/ent/db/plan/where.go
  • openmeter/ent/db/plan/plan.go
  • openmeter/ent/db/plan.go
  • openmeter/ent/db/plan_query.go
  • openmeter/ent/db/addon_create.go
  • openmeter/ent/db/addon_query.go
  • openmeter/ent/db/addon.go
  • openmeter/ent/db/planaddon/planaddon.go
🧰 Additional context used
🧬 Code Graph Analysis (17)
openmeter/ent/db/paginate.go (4)
openmeter/ent/db/planaddon_query.go (1)
  • PlanAddonQuery (22-34)
openmeter/ent/db/planaddon.go (2)
  • PlanAddon (19-51)
  • PlanAddon (87-106)
openmeter/ent/schema/planaddon.go (5)
  • PlanAddon (15-17)
  • PlanAddon (19-23)
  • PlanAddon (25-49)
  • PlanAddon (51-66)
  • PlanAddon (68-83)
openmeter/ent/db/ent.go (1)
  • Count (204-208)
openmeter/ent/schema/planaddon.go (2)
openmeter/ent/db/planaddon/planaddon.go (1)
  • ValueScanner (107-109)
openmeter/ent/schema/notification.go (1)
  • AnnotationsValueScanner (347-368)
openmeter/ent/db/migrate/schema.go (3)
openmeter/ent/db/addon/where.go (1)
  • Name (90-92)
openmeter/ent/db/plan/where.go (1)
  • Name (89-91)
openmeter/ent/db/planaddon/where.go (1)
  • Name (89-91)
openmeter/ent/db/addon_update.go (5)
openmeter/ent/db/plan/where.go (1)
  • ID (14-16)
openmeter/ent/db/planaddon/where.go (1)
  • ID (14-16)
openmeter/ent/db/addon/addon.go (4)
  • Table (55-55)
  • PlansTable (64-64)
  • PlansColumn (69-69)
  • FieldID (19-19)
openmeter/ent/db/plan/plan.go (2)
  • Table (50-50)
  • FieldID (16-16)
openmeter/ent/db/planaddon/planaddon.go (2)
  • Table (47-47)
  • FieldID (17-17)
openmeter/ent/db/plan_create.go (4)
openmeter/ent/db/planaddon.go (2)
  • PlanAddon (19-51)
  • PlanAddon (87-106)
openmeter/ent/db/planaddon/where.go (1)
  • ID (14-16)
openmeter/ent/db/plan/plan.go (5)
  • Table (50-50)
  • AddonsTable (59-59)
  • Columns (75-90)
  • AddonsColumn (64-64)
  • FieldID (16-16)
openmeter/ent/db/planaddon/planaddon.go (3)
  • Table (47-47)
  • Columns (65-79)
  • FieldID (17-17)
openmeter/ent/db/addon/where.go (3)
openmeter/ent/db/predicate/predicate.go (2)
  • Addon (10-10)
  • PlanAddon (210-210)
openmeter/ent/db/addon/addon.go (3)
  • Table (55-55)
  • PlansTable (64-64)
  • PlansColumn (69-69)
openmeter/ent/db/planaddon/planaddon.go (1)
  • Table (47-47)
openmeter/ent/db/runtime.go (1)
openmeter/ent/db/planaddon/planaddon.go (1)
  • ValueScanner (107-109)
openmeter/ent/db/mutation.go (3)
openmeter/ent/db/plan/plan.go (5)
  • EdgePhases (44-44)
  • EdgeAddons (46-46)
  • EdgeSubscriptions (48-48)
  • FieldDescription (30-30)
  • FieldName (28-28)
openmeter/ent/db/planaddon/planaddon.go (7)
  • FieldDescription (31-31)
  • FieldMaxQuantity (41-41)
  • FieldPlanID (35-35)
  • FieldAddonID (37-37)
  • FieldName (29-29)
  • FieldFromPlanPhase (39-39)
  • EdgeAddon (45-45)
openmeter/ent/db/planaddon/where.go (6)
  • Name (89-91)
  • Description (94-96)
  • PlanID (99-101)
  • AddonID (104-106)
  • FromPlanPhase (109-111)
  • MaxQuantity (114-116)
openmeter/ent/db/planaddon_delete.go (5)
openmeter/ent/db/ent.go (2)
  • IsConstraintError (363-369)
  • ConstraintError (347-350)
openmeter/ent/db/mutation.go (1)
  • PlanAddonMutation (38220-38244)
openmeter/ent/db/planaddon.go (2)
  • PlanAddon (19-51)
  • PlanAddon (87-106)
openmeter/ent/db/predicate/predicate.go (1)
  • PlanAddon (210-210)
openmeter/ent/db/planaddon/planaddon.go (3)
  • Table (47-47)
  • FieldID (17-17)
  • Label (15-15)
openmeter/ent/db/planaddon.go (5)
openmeter/ent/db/ent.go (3)
  • NotFoundError (280-282)
  • NotLoadedError (326-328)
  • Value (65-65)
openmeter/ent/db/addon/addon.go (1)
  • ValueScanner (128-130)
openmeter/ent/db/planaddon/planaddon.go (1)
  • ValueScanner (107-109)
openmeter/ent/db/client.go (1)
  • NewPlanAddonClient (5750-5752)
openmeter/ent/db/planaddon_update.go (1)
  • PlanAddonUpdateOne (279-284)
openmeter/ent/db/plan_update.go (4)
openmeter/ent/db/planaddon.go (2)
  • PlanAddon (19-51)
  • PlanAddon (87-106)
openmeter/ent/db/planaddon/where.go (1)
  • ID (14-16)
openmeter/ent/db/plan/plan.go (4)
  • Table (50-50)
  • AddonsTable (59-59)
  • AddonsColumn (64-64)
  • FieldID (16-16)
openmeter/ent/db/planaddon/planaddon.go (2)
  • Table (47-47)
  • FieldID (17-17)
openmeter/ent/db/setorclear.go (1)
openmeter/ent/db/planaddon_update.go (2)
  • PlanAddonUpdate (19-23)
  • PlanAddonUpdateOne (279-284)
openmeter/ent/db/planaddon_query.go (5)
openmeter/ent/db/planaddon/planaddon.go (3)
  • OrderOption (113-113)
  • FieldID (17-17)
  • FieldPlanID (35-35)
openmeter/ent/db/plan_query.go (1)
  • PlanQuery (24-37)
openmeter/ent/db/addon_query.go (1)
  • AddonQuery (24-37)
openmeter/ent/db/planaddon/where.go (5)
  • Name (89-91)
  • PlanID (99-101)
  • IDIn (29-31)
  • ID (14-16)
  • AddonID (104-106)
openmeter/ent/db/plan.go (2)
  • Plan (17-51)
  • Plan (94-113)
openmeter/ent/db/client.go (6)
openmeter/ent/db/planaddon_query.go (1)
  • PlanAddonQuery (22-34)
openmeter/ent/db/planaddon/where.go (1)
  • ID (14-16)
openmeter/ent/db/planaddon/planaddon.go (1)
  • FieldID (17-17)
openmeter/ent/db/planaddon_create.go (1)
  • PlanAddonCreate (21-26)
openmeter/ent/db/planaddon_update.go (1)
  • PlanAddonUpdate (19-23)
openmeter/ent/db/planaddon_delete.go (1)
  • PlanAddonDelete (16-20)
openmeter/ent/db/planaddon_update.go (4)
openmeter/ent/db/mutation.go (1)
  • PlanAddonMutation (38220-38244)
openmeter/ent/db/predicate/predicate.go (1)
  • PlanAddon (210-210)
openmeter/ent/db/planaddon/where.go (7)
  • UpdatedAt (79-81)
  • DeletedAt (84-86)
  • Name (89-91)
  • Description (94-96)
  • FromPlanPhase (109-111)
  • MaxQuantity (114-116)
  • ID (14-16)
openmeter/ent/db/planaddon/planaddon.go (6)
  • FieldUpdatedAt (25-25)
  • FieldDeletedAt (27-27)
  • FieldName (29-29)
  • FieldDescription (31-31)
  • FieldFromPlanPhase (39-39)
  • FieldMaxQuantity (41-41)
openmeter/ent/db/planaddon/where.go (5)
openmeter/ent/db/addon/where.go (9)
  • ID (15-17)
  • IDEQ (20-22)
  • IDNEQ (25-27)
  • Namespace (70-72)
  • CreatedAt (75-77)
  • UpdatedAt (80-82)
  • DeletedAt (85-87)
  • Name (90-92)
  • Description (95-97)
openmeter/ent/db/plan/where.go (9)
  • ID (14-16)
  • IDEQ (19-21)
  • IDNEQ (24-26)
  • Namespace (69-71)
  • CreatedAt (74-76)
  • UpdatedAt (79-81)
  • DeletedAt (84-86)
  • Name (89-91)
  • Description (94-96)
openmeter/ent/db/predicate/predicate.go (3)
  • PlanAddon (210-210)
  • Plan (207-207)
  • Addon (10-10)
openmeter/ent/db/plan/plan.go (8)
  • FieldID (16-16)
  • FieldNamespace (18-18)
  • FieldCreatedAt (22-22)
  • FieldUpdatedAt (24-24)
  • FieldDeletedAt (26-26)
  • FieldName (28-28)
  • FieldDescription (30-30)
  • FieldMetadata (20-20)
openmeter/ent/db/planaddon/planaddon.go (13)
  • FieldID (17-17)
  • FieldNamespace (19-19)
  • FieldCreatedAt (23-23)
  • FieldUpdatedAt (25-25)
  • FieldDeletedAt (27-27)
  • FieldName (29-29)
  • FieldDescription (31-31)
  • FieldPlanID (35-35)
  • FieldAddonID (37-37)
  • FieldFromPlanPhase (39-39)
  • FieldMaxQuantity (41-41)
  • FieldMetadata (21-21)
  • FieldAnnotations (33-33)
openmeter/ent/db/planaddon_create.go (3)
openmeter/ent/db/mutation.go (1)
  • PlanAddonMutation (38220-38244)
openmeter/ent/db/planaddon/where.go (11)
  • ID (14-16)
  • CreatedAt (74-76)
  • UpdatedAt (79-81)
  • Namespace (69-71)
  • Name (89-91)
  • PlanID (99-101)
  • AddonID (104-106)
  • FromPlanPhase (109-111)
  • DeletedAt (84-86)
  • Description (94-96)
  • MaxQuantity (114-116)
openmeter/ent/db/planaddon/planaddon.go (11)
  • FieldID (17-17)
  • FieldNamespace (19-19)
  • FieldCreatedAt (23-23)
  • FieldUpdatedAt (25-25)
  • FieldDeletedAt (27-27)
  • FieldName (29-29)
  • FieldDescription (31-31)
  • FieldFromPlanPhase (39-39)
  • FieldMaxQuantity (41-41)
  • FieldPlanID (35-35)
  • FieldAddonID (37-37)
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: E2E
  • GitHub Check: CI
  • GitHub Check: Developer environment
  • GitHub Check: Lint
  • GitHub Check: Test
  • GitHub Check: Analyze (go)
🔇 Additional comments (112)
openmeter/ent/db/runtime.go (2)

39-39: Correct import for PlanAddon package.

The import for the planaddon package is correctly added at the appropriate alphabetical position in the import list.


1104-1137: Well-structured schema initialization for PlanAddon entity.

The initialization code for the PlanAddon schema follows the established pattern used for other entities in the codebase. It properly:

  • Initializes mixin fields
  • Sets up field descriptors (namespace, created_at, updated_at, annotations, etc.)
  • Configures validators for required fields (namespace, plan_id, addon_id)
  • Establishes default values for automatically populated fields (created_at, updated_at, id)

This implementation provides proper database schema support for the plan-addon relationships as specified in the PR objectives.

openmeter/ent/db/planaddon_delete.go (11)

1-4: Consistent package setup and imports.
All initial directives appear coherent, and no issues are found with the file header or package statements.


5-13: Imports are well-organized and appropriate.
The selected imports for context, SQL dialect, and predicates align well with the deletion logic.


15-20: PlanAddonDelete struct is straightforward.
Structuring the deletion builder with config, hooks, and a mutation object is a standard approach to encapsulate delete logic.


22-26: Clear predicate handling in Where method.
Appending predicates to the underlying mutation ensures flexible filtering criteria before deletion.


28-31: Exec method properly returns affected row count.
Returning the number of deleted entities can help upstream logic verify successful deletions or handle edge cases.


33-40: ExecX provides a panic variant.
Offering a convenience function that panics on error can be handy for test or script scenarios, although it should be used cautiously in production contexts.


42-57: Robust handling of constraint errors in sqlExec.
Converting constraint errors into a dedicated ConstraintError struct ensures consistent error messaging and handling.


59-62: PlanAddonDeleteOne builder complements multi-entity deletion.
This struct neatly composes a single-entity delete operation on top of PlanAddonDelete, maintaining intuitive naming.


64-68: Predicate chaining for single-entity deletion.
Allowing additional filters here provides flexibility in refining or combining predicates for the one-entity scenario.


70-81: Exec for single-entity deletion distinguishes missing entities.
Returning a NotFoundError when no rows match is helpful for error handling and user feedback.


83-88: ExecX similarly provides a panic variant for single-entity deletion.
This logic follows the consistent pattern of deferring an error up for cases where a direct panic is more suitable.

openmeter/ent/db/planaddon_query.go (10)

1-2: Auto-generated Code Notice
These lines indicate that the file is generated by the Ent framework. Direct edits here will be overwritten on regeneration. If changes are required, modify the Ent schema and re-run code generation.


21-34: PlanAddonQuery Struct
Defines the query builder structure for PlanAddon entities. Fields for context, ordering, eager loading, and predicates are standard Ent patterns. No immediate issues.


36-65: Predicate and Pagination Methods
Methods like Where, Limit, Offset, Unique, Order are typical for building conditional/paginated queries. Consider verifying behavior when users supply negative or zero limits/offsets to ensure consistent results.

Would you like a script to scan the codebase for usage of these methods and identify any potential misuses of negative or zero inputs?


67-109: M2O Edge Query Methods
QueryPlan and QueryAddon appropriately handle edges to Plan and Addon. This is a clear Ent pattern for traversing relationships. Nothing concerning here.


111-289: Entity Retrieval Methods
First, Only, All, IDs, Count, Exist, etc., consistently follow Ent’s approach to retrieving data. Error-handling logic for not-found or not-singular cases is standard.


291-331: Cloning and Eager-Loading
The Clone method ensures queries can be re-used safely. WithPlan and WithAddon elegantly handle eager loading. No issues to flag.


333-509: Grouping, Selecting, and Preparing Queries
GroupBy, Select, and the internal prepareQuery/sqlAll methods demonstrate solid usage of Ent’s query customization and eager-loading hooks. Appears consistent and maintainable.


511-602: Query Specifications
sqlCount, querySpec, and sqlQuery properly structure the SQL selection process for PlanAddon entities. This is the standard Ent flow with no evident issues.


604-628: Transactional Locking Methods
ForUpdate and ForShare implement row-level locking. Verify your backing database dialect supports these lock modes. If not, runtime errors or ignored locks might occur.

Would you like a script to check for dialect usages across the codebase to ensure these methods are safely used only where supported?


630-718: GroupBy/Select Builders
PlanAddonGroupBy and PlanAddonSelect provide advanced grouping and selective retrieval. These methods align with Ent’s aggregator patterns. No issues found.

openmeter/ent/db/addon/addon.go (4)

50-51: New edge definition for Plans relation is properly defined.

The new constants for the Plans edge follow the established naming pattern and correctly define the relationships between Addon and PlanAddon entities.


63-69: Table and column definitions for Plans relation are correctly implemented.

These constants properly define the database structure for the plan_addons table and the relationships between the entities, maintaining consistency with the existing pattern used for other relationships.


232-244: Ordering functions for Plans relation follow the established pattern.

The ByPlansCount and ByPlans functions enable ordering Addon entities based on their associated plans, following the same implementation pattern as the existing ordering functions for other relations.


266-272: Helper function for Plans step creation is correctly implemented.

The newPlansStep function properly creates a SQL graph step for the plans relation, defining a one-to-many relationship from Addon to PlanAddon with the appropriate table and column names.

openmeter/ent/db/addon/where.go (2)

802-811: HasPlans predicate is correctly implemented.

This predicate function properly implements the HasEdge functionality for the "plans" edge, enabling filtering of Addon entities that have associated PlanAddon records. The implementation follows the established pattern used for other edge predicates.


814-823: HasPlansWith predicate provides advanced filtering capabilities.

This function extends the basic edge predicate with the ability to apply additional conditions to the related PlanAddon entities. It correctly uses the existing newPlansStep function and follows the same implementation pattern as other similar predicates in the codebase.

openmeter/ent/db/paginate.go (2)

1452-1495: Paginate method for PlanAddonQuery follows the established pattern.

The pagination implementation for PlanAddonQuery maintains consistency with other entity types in the codebase. It correctly handles:

  • Resetting previous pagination settings
  • Creating separate queries for counting and fetching items
  • Removing ordering for the count query (optimization)
  • Handling zero-value pagination (returning all items)
  • Setting appropriate limit and offset values
  • Properly constructing the response with items, count, and page info

This implementation ensures consistent pagination behavior across entity types.


1498-1498: Type check ensures interface compliance.

This type assertion confirms that PlanAddonQuery properly implements the pagination.Paginator interface, ensuring type safety and consistency with the pagination framework.

openmeter/ent/db/migrate/schema.go (4)

1681-1696: Well-defined columns for the PlanAddons table.

These fields align properly with the PlanAddon entity requirements, including metadata, timestamps, and references to plan/addon IDs. No issues detected regarding data types or constraints.


1697-1751: PlanAddonsTable and its foreign keys look consistent.

The foreign keys correctly reference Addons and Plans tables with cascade deletions, matching the intended one-to-many relationship design.


2405-2405: Good inclusion of PlanAddonsTable in the global Tables list.

Adding it ensures this table is recognized and managed by the migration engine.


2456-2457: Assigning RefTable to AddonsTable and PlansTable.

The foreign key references are now fully wired, so migrations will properly enforce integrity between PlanAddons and its parent entities.

openmeter/ent/db/plan_create.go (4)

16-16: Import of planaddon package.

This import is necessary to reference the PlanAddon entity in the newly added methods. Implementation is correct.


200-204: AddAddonIDs method.

Implements the standard Ent pattern for appending related edge IDs. This function is succinct and aligns with established approaches for entgenerated builders.


206-213: AddAddons method.

Collects PlanAddon's IDs and correctly defers to AddAddonIDs, following Ent's typical chaining pattern. No changes needed.


437-452: EdgeSpec for the Plan→PlanAddon relationship.

The one-to-many edge logic is defined properly, ensuring the plan_addons table is linked via plan.AddonsColumn to plan.AddonsTable. No issues spotted.

openmeter/ent/schema/planaddon.go (2)

42-43: Typographical correction needed.

Please change "fro" to "for" in the comment to avoid any confusion.
[duplicate_comment, suggest_nitpick]


45-47: Accurate comment for max_quantity.

Thank you for aligning the comment with its actual purpose. The field now clearly explains its meaning.

openmeter/ent/db/addon_update.go (3)

16-16: Import statement for planaddon looks clean and purposeful.


209-222: AddPlanIDs/AddPlans methods appear consistent with Ent patterns.

No issues found. The methods clearly handle adding references to PlanAddon by ID or entity.


265-284: ClearPlans/RemovePlanIDs/RemovePlans methods are structurally correct.

These methods properly manage the edge relationships, following typical Ent conventions.

tools/migrate/migrations/20250414132348_plan_addons.up.sql (2)

1-19: Creation of the "plan_addons" table looks correct.

The columns and foreign key constraints, including cascade on delete, appear suitable for this relationship.
If soft-deletion or partial cleanup is needed, confirm that "ON DELETE CASCADE" aligns with your data lifecycle.


20-29: Index definitions and uniqueness constraints are well-structured.

Use of GIN on "annotations" and covering unique indexes will help query performance and data integrity.

openmeter/ent/db/plan_update.go (7)

15-15: Importing planaddon ensures PlanAddon references are properly recognized.


196-209: AddAddonIDs/AddAddons methods for PlanUpdate.

Logic follows Ent conventions for establishing O2M edges toward PlanAddon.


252-271: ClearAddons/RemoveAddonIDs/RemoveAddons methods for PlanUpdate.

Standard approach to clearing or removing edge relationships. No issues detected.


442-486: sqlSave adjustments for "addons" in PlanUpdate.

The update specification and edge clearing/addition logic appear consistent with Ent’s pattern for edge management.


714-727: AddAddonIDs/AddAddons in PlanUpdateOne.

Mirrors the PlanUpdate approach to support single-entity updates. Implementation is straightforward.


770-789: ClearAddons/RemoveAddonIDs/RemoveAddons in PlanUpdateOne.

Correctly facilitates edge removal for single-entity plan updates, matching Ent’s idiomatic patterns.


990-1034: sqlSave logic for "addons" in PlanUpdateOne.

The edge clearing and addition mirror PlanUpdate’s logic, ensuring consistency in the single-entity workflow.

openmeter/ent/db/setorclear.go (10)

2214-2219: Implementation of SetOrClearMetadata for PlanAddonUpdate looks good.

This pattern of conditionally setting or clearing the field based on a nil check is consistent and straightforward.


2221-2226: Implementation of SetOrClearMetadata for PlanAddonUpdateOne is consistent.

Mirrors the behavior of the PlanAddonUpdate variant. Good job maintaining parity across these update types.


2228-2233: SetOrClearDeletedAt for PlanAddonUpdate is clear and concise.

The logic ensures a field is cleared if nil is passed, and set otherwise. This approach is efficient and matches the established pattern.


2235-2240: SetOrClearDeletedAt for PlanAddonUpdateOne correctly parallels the multi-update logic.

Good adherence to the established nil-check pattern.


2242-2247: SetOrClearDescription for PlanAddonUpdate is well-defined.

No issues spotted. Consistent usage of Clear/Set based on nil input.


2249-2254: SetOrClearDescription for PlanAddonUpdateOne parallels the bulk update version.

Implementation details are sound and match other methods in this file.


2256-2261: SetOrClearAnnotations for PlanAddonUpdate is straightforward.

No concerns; code is aligned with typical ent update patterns.


2263-2268: SetOrClearAnnotations for PlanAddonUpdateOne matches the multi-update version.

Maintains the same clear-or-set logic effectively.


2270-2275: SetOrClearMaxQuantity for PlanAddonUpdate follows the nil-check convention well.

Good job ensuring consistent logic across all fields.


2277-2282: SetOrClearMaxQuantity for PlanAddonUpdateOne is consistent with the rest of the file.

This method accurately mirrors the helper for PlanAddonUpdate, ensuring uniform behavior.

openmeter/ent/db/planaddon.go (11)

5-16: Imports and package declaration appear appropriate.

These imports (including ent, sql, and supporting packages) are necessary for your entity logic. The overall structure aligns with ent’s typical conventions.


53-84: Definition of PlanAddonEdges effectively captures the Plan and Addon relationships.

  1. The helper methods (PlanOrErr, AddonOrErr) properly check for loaded edges vs. not found scenarios.
  2. Edge-lazy-loading errors appear aligned with ent’s NotFoundError and NotLoadedError usage.

86-106: scanValues method is structurally consistent with ent’s scanning logic.

  1. The switch case approach for each column is clear.
  2. Storing each field in a typed pointer is standard practice in ent, aligning well for assignment.

108-204: assignValues method properly assigns scanned SQL fields to PlanAddon.

  1. Good error handling (e.g., unexpected types raise an error).
  2. The JSON unmarshal for Metadata is appropriate, though consider verifying whether partial or malformed JSON is addressed upstream.

206-210: Value method is a clear accessor for dynamic query mods.

Ent uses this mechanism for columns included via additional selects or modifiers. No issues noted.


212-215: QueryPlan method leverages NewPlanAddonClient for the plan edge.

Straightforward usage of ent’s edge query pattern.


217-220: QueryAddon method aligns with ent’s default approach to querying edges.

Ensures the add-on edge can be traversed easily from a PlanAddon.


222-227: Update method returning PlanAddonUpdateOne is standard ent.

This is how ent typically provides updating capabilities for single entities.


229-239: Unwrap method ensures safe usage outside of a transaction context.

No issues. The panic condition is typical if not in a transactional driver context.


290-292: PlanAddons type is a helpful slice alias.

Enables easy handling of multiple PlanAddon objects in ent queries and iteration.


18-51:

Details

❓ Verification inconclusive

Definition of PlanAddon struct is comprehensive.

  1. Field coverage (ID, Namespace, Metadata, etc.) looks correct and consistent with the schema references.
  2. Consider verifying that CreatedAt, UpdatedAt, and DeletedAt are managed as expected in upstream or downstream logic (e.g., creation timestamps, soft-deletes).

Would you like to confirm existence of tests or references ensuring these timestamps are properly populated and maintained?


🏁 Script executed:

#!/bin/bash
# Search for PlanAddon references in tests to confirm coverage
rg "PlanAddon" -A 10

Length of output: 81570


Timestamps and Default Handling Verification for PlanAddon

The PlanAddon struct appears to comprehensively cover all the expected schema fields. In particular, the timestamp fields (CreatedAt, UpdatedAt, and DeletedAt) are set up through the Ent mixin and runtime configuration (e.g. setting planaddon.DefaultCreatedAt in openmeter/ent/db/runtime.go), which suggests that default assignment and update logic are in place. However, our search shows that while there are many references to PlanAddon (including in router files and update builders), explicit tests that validate the correct population and maintenance of these timestamps—especially for soft-deletes using DeletedAt—are not clearly evident.

Review Points:

  • Default Values & Updates: The runtime and update functions (as seen in files like openmeter/ent/db/runtime.go and openmeter/ent/db/planaddon_update.go) seem to correctly implement default timestamping for creation and updates.
  • Test Coverage: Although references to PlanAddon exist in test and router files (which currently return http.StatusNotImplemented), there is an absence of explicit tests verifying that CreatedAt, UpdatedAt, and DeletedAt behave correctly through the full lifecycle (creation, modification, and soft-deletion).

Recommendation:
Please confirm (or add, if missing) comprehensive test cases to verify that:

  • CreatedAt is properly assigned on entity creation.
  • UpdatedAt is updated on modifications.
  • The soft-delete behavior (via DeletedAt) operates as expected in upstream and downstream logic.
openmeter/ent/db/mutation.go (19)

49-49: Add planaddon import

The addition of this import is consistent with the new PlanAddon entity introduced in the schema.


108-108: Introduce TypePlanAddon constant

Defining a new constant for PlanAddon aligns with the new entity. No issues found.


146-148: Add fields for 'plans' in AddonMutation

These new fields (plans, removedplans, clearedplans) correctly set up the internal state for plan relationships.


917-970: Implement 'plans' edge mutation methods for Addon

Methods (AddPlanIDs, RemovePlanIDs, etc.) are standard for managing edges in ent. Logic looks correct.


1433-1439: Add 'plans' to AddedEdges in AddonMutation

Appending the plans edge in AddedEdges is consistent with ent conventions.


1456-1461: Include 'plans' in AddedIDs for AddonMutation

Retrieving newly added plan IDs matches the pattern for ent edge management.


1474-1480: Track removed 'plans' in RemovedEdges

Identifying removed plan edges aligns with ent mutation patterns.


1497-1502: Return removed 'plans' IDs

Properly enumerating IDs removed from plans ensures consistent edge logic.


1515-1521: List cleared 'plans' under ClearedEdges

Capturing cleared plan edges is correct and consistent with ent.


1534-1535: Check if 'plans' edge was cleared

This condition properly tests for the cleared state of the plans edge.


1557-1559: Reset 'plans' edge

Resetting the plans edge data aligns with ent’s reset pattern for edges.


36870-36872: Add 'addons' fields in PlanMutation

Introducing addons, removedaddons, and clearedaddons fields sets up the internal bookkeeping for the Plan → PlanAddon relationship.


37592-37645: Implement 'addons' edge mutation methods for Plan

These methods (AddAddonIDs, RemoveAddonIDs, ClearAddons, etc.) follow ent patterns for managing a related entity.


38085-38091: Add 'addons' to AddedEdges in PlanMutation

Appending the addons edge in the AddedEdges slice maintains consistency with other edges.


38108-38113: Return 'addons' edge IDs

Gathering addon IDs for the newly added edges is correctly implemented.


38126-38132: Include 'addons' in RemovedEdges

Properly tracks addons that have been removed from the plan.


38149-38154: Retrieve removed 'addons' IDs

Returning IDs for removed addons is aligned with ent’s approach.


38167-38173: Mark cleared 'addons' in ClearedEdges

Captures the scenario where all addons are cleared from a plan.


38186-38187: Check if 'addons' edge is cleared

Verifies whether the addons edge was cleared during the mutation.

openmeter/ent/db/client.go (12)

48-48: Import of the PlanAddon schema looks correct.

The import statement for the PlanAddon package is correctly added, which is necessary for the new PlanAddon client functionality.


128-129: Client struct field declaration follows consistent pattern.

The PlanAddon field is properly added to the Client struct with appropriate documentation comment. The field follows the same pattern as other entity clients in the struct.


191-191: Client initialization correctly implemented.

The initialization of the PlanAddon client in the init method is correctly implemented, consistent with other client initializations.


324-324: Transaction client properly included.

The PlanAddon client is properly included in the transaction creation, ensuring it's available within transaction contexts.


384-384: BeginTx method properly updated.

The PlanAddon client is correctly included in the BeginTx method, maintaining consistency with the Tx method.


432-433: Hook and interceptor registration properly updated.

The PlanAddon client is correctly added to the hooks and interceptors registration methods, ensuring that hooks and interceptors can be applied to PlanAddon operations.

Also applies to: 454-455


527-528: Mutation handling correctly implemented.

The case for PlanAddonMutation is properly added to the Mutate method, allowing the Client to handle mutations for PlanAddon entities.


678-692: Addon-PlanAddon relationship correctly established.

The QueryPlans method on AddonClient allows querying PlanAddon entities related to an Addon. The implementation follows the standard pattern for relationship queries in ent.


5744-5907: PlanAddonClient implementation is comprehensive and correctly structured.

The PlanAddonClient implementation includes:

  1. Standard CRUD operations (Create, Update, Delete)
  2. Query methods for fetching entities
  3. Relationship query methods (QueryPlan, QueryAddon)
  4. Support for hooks and interceptors
  5. Mutation handling

The implementation is consistent with other client implementations in the codebase.


5852-5866: Relationship query methods are properly implemented.

The QueryPlan and QueryAddon methods are correctly implemented to allow traversal of relationships from PlanAddon to Plan and Addon entities. These methods are essential for the proper functioning of the ORM and follow the established patterns in the codebase.

Also applies to: 5868-5882


5687-5701: Plan-PlanAddon relationship correctly established.

The relationship from Plan to PlanAddon is correctly implemented, allowing Plan entities to access their related PlanAddons. This complements the Addon-PlanAddon relationship, establishing the complete many-to-many relationship.


7682-7683: Hook and interceptor registries properly updated.

The hooks and interceptors structs are correctly updated to include PlanAddon, ensuring hooks and interceptors can be applied to PlanAddon operations.

Also applies to: 7696-7697

openmeter/ent/db/planaddon_update.go (2)

197-206: Good job enforcing integrity on required edges.

The check() function ensures you cannot simultaneously clear a required unique edge (e.g. Plan) and add an ID for that same edge. This prevents ambiguous or conflicting updates and enhances data integrity.


189-195: Appropriate use of default timestamp assignment.

Calling pau.defaults() before save automatically sets updated_at using planaddon.UpdateDefaultUpdatedAt(). This is a neat approach to consistently maintain fresh timestamps on each update.

openmeter/ent/db/planaddon/where.go (2)

718-739: Good implementation of edge predicates.

HasPlan and HasPlanWith leverage the M2O relationship for PlanAddon. This ent-generated code is straightforward yet powerful, allowing refined queries on associated Plan entities.


764-777: Clear logical grouping support.

Providing And, Or, and Not for PlanAddon predicates empowers complex queries with minimal overhead. This is a core ent advantage and well-structured in your generation.

openmeter/ent/db/planaddon_create.go (3)

28-32: Namespace setting is handled cleanly.

The SetNamespace method is concise and consistent, and the corresponding validator in check() enforces that required field. Good practice for ensuring valid data early.


197-211: Well-handled defaults for created_at, updated_at, and id.

Automatic assignment of these fields in defaults() ensures newly created records always maintain consistent timestamps and IDs. This is a strong adherence to best practices in schema management.


251-256: Excellent validations for required edges.

Throwing a validation error if the required edges plan or addon are missing aligns with Ent's concept of domain correctness. This approach helps immensely in preventing orphaned or invalid references.

@chrisgacsal chrisgacsal force-pushed the feat/productcatalog branch from ddf486b to 8ff5adb Compare April 15, 2025 10:20
Copy link
Contributor

@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: 0

🧹 Nitpick comments (5)
openmeter/ent/schema/planaddon.go (1)

28-45: Typo in the comment for from_plan_phase.
Line 39 has the phrase “…is available fro purchase.” This likely should read “available for purchase.”

-  Comment("The key identifier of the plan phase from the add-on is available fro purchase."),
+  Comment("The key identifier of the plan phase from the add-on is available for purchase."),
openmeter/ent/db/planaddon_create.go (4)

28-45: Consider Consistency in JSON Field Types

You’ve defined metadata as map[string]string and annotations as map[string]interface{}. This is valid, but consider whether merging these into a single, consistently typed JSON structure applies better to your business logic. It may help reduce confusion around how data is stored in each field.


46-86: Validate Soft-Delete Approach

The deleted_at field is being set explicitly, implying a soft-delete mechanism. Ensure you have (or plan to implement) a consistent approach to querying and filtering out “deleted” records across the codebase if the entity is meant to be logically removed. Otherwise, it could be overlooked in normal queries.


177-191: Automatic Timestamp Updates

This builder sets created_at and updated_at only upon creation. If you intend to keep updated_at in sync with updates, consider an ent hook or an Update mutation extension so updated_at is updated automatically on subsequent modifications.


793-826: Bulk Upsert Caution

When using PlanAddonCreateBulk with OnConflict, verify that the expected conflicts are well-defined (e.g., unique constraints on critical columns). Otherwise, multiple insertion attempts might bypass the intended upsert logic or produce unexpected merges.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ddf486b and 8ff5adb.

⛔ Files ignored due to path filters (1)
  • tools/migrate/migrations/atlas.sum is excluded by !**/*.sum
📒 Files selected for processing (36)
  • openmeter/ent/db/addon.go (3 hunks)
  • openmeter/ent/db/addon/addon.go (4 hunks)
  • openmeter/ent/db/addon/where.go (1 hunks)
  • openmeter/ent/db/addon_create.go (3 hunks)
  • openmeter/ent/db/addon_query.go (8 hunks)
  • openmeter/ent/db/addon_update.go (7 hunks)
  • openmeter/ent/db/client.go (13 hunks)
  • openmeter/ent/db/ent.go (2 hunks)
  • openmeter/ent/db/expose.go (1 hunks)
  • openmeter/ent/db/hook/hook.go (1 hunks)
  • openmeter/ent/db/migrate/schema.go (3 hunks)
  • openmeter/ent/db/mutation.go (20 hunks)
  • openmeter/ent/db/paginate.go (1 hunks)
  • openmeter/ent/db/plan.go (3 hunks)
  • openmeter/ent/db/plan/plan.go (4 hunks)
  • openmeter/ent/db/plan/where.go (1 hunks)
  • openmeter/ent/db/plan_create.go (3 hunks)
  • openmeter/ent/db/plan_query.go (8 hunks)
  • openmeter/ent/db/plan_update.go (7 hunks)
  • openmeter/ent/db/planaddon.go (1 hunks)
  • openmeter/ent/db/planaddon/planaddon.go (1 hunks)
  • openmeter/ent/db/planaddon/where.go (1 hunks)
  • openmeter/ent/db/planaddon_create.go (1 hunks)
  • openmeter/ent/db/planaddon_delete.go (1 hunks)
  • openmeter/ent/db/planaddon_query.go (1 hunks)
  • openmeter/ent/db/planaddon_update.go (1 hunks)
  • openmeter/ent/db/predicate/predicate.go (1 hunks)
  • openmeter/ent/db/runtime.go (2 hunks)
  • openmeter/ent/db/setorclear.go (1 hunks)
  • openmeter/ent/db/tx.go (2 hunks)
  • openmeter/ent/schema/addon.go (1 hunks)
  • openmeter/ent/schema/planaddon.go (1 hunks)
  • openmeter/ent/schema/productcatalog.go (1 hunks)
  • pkg/framework/entutils/mixins.go (1 hunks)
  • tools/migrate/migrations/20250415101830_plan_addons.down.sql (1 hunks)
  • tools/migrate/migrations/20250415101830_plan_addons.up.sql (1 hunks)
✅ Files skipped from review due to trivial changes (4)
  • tools/migrate/migrations/20250415101830_plan_addons.down.sql
  • tools/migrate/migrations/20250415101830_plan_addons.up.sql
  • openmeter/ent/db/planaddon_update.go
  • openmeter/ent/db/planaddon/where.go
🚧 Files skipped from review as they are similar to previous changes (25)
  • openmeter/ent/db/expose.go
  • openmeter/ent/db/predicate/predicate.go
  • openmeter/ent/db/tx.go
  • openmeter/ent/schema/addon.go
  • openmeter/ent/schema/productcatalog.go
  • openmeter/ent/db/ent.go
  • openmeter/ent/db/addon.go
  • openmeter/ent/db/addon_create.go
  • openmeter/ent/db/plan/where.go
  • openmeter/ent/db/paginate.go
  • openmeter/ent/db/plan_create.go
  • openmeter/ent/db/runtime.go
  • openmeter/ent/db/hook/hook.go
  • openmeter/ent/db/plan.go
  • openmeter/ent/db/plan/plan.go
  • openmeter/ent/db/addon_query.go
  • openmeter/ent/db/plan_query.go
  • openmeter/ent/db/plan_update.go
  • openmeter/ent/db/setorclear.go
  • openmeter/ent/db/migrate/schema.go
  • openmeter/ent/db/planaddon_delete.go
  • openmeter/ent/db/addon/addon.go
  • openmeter/ent/db/addon/where.go
  • openmeter/ent/db/planaddon.go
  • openmeter/ent/db/client.go
🧰 Additional context used
🧬 Code Graph Analysis (3)
pkg/framework/entutils/mixins.go (2)
api/api.gen.go (1)
  • Annotations (903-903)
pkg/models/annotation.go (1)
  • Annotations (3-3)
openmeter/ent/schema/planaddon.go (4)
openmeter/ent/db/planaddon.go (2)
  • PlanAddon (19-47)
  • PlanAddon (83-100)
pkg/framework/entutils/mixins.go (12)
  • IDMixin (80-82)
  • IDMixin (85-97)
  • IDMixin (99-103)
  • NamespaceMixin (120-122)
  • NamespaceMixin (125-131)
  • NamespaceMixin (133-137)
  • MetadataMixin (140-142)
  • MetadataMixin (145-153)
  • AnnotationsMixin (156-158)
  • AnnotationsMixin (161-169)
  • TimeMixin (172-174)
  • TimeMixin (177-189)
openmeter/ent/schema/productcatalog.go (5)
  • Plan (16-18)
  • Plan (20-25)
  • Plan (27-42)
  • Plan (44-56)
  • Plan (58-66)
openmeter/ent/schema/addon.go (5)
  • Addon (16-18)
  • Addon (20-24)
  • Addon (26-51)
  • Addon (53-68)
  • Addon (70-85)
openmeter/ent/db/planaddon/planaddon.go (2)
openmeter/ent/db/addon/addon.go (16)
  • FieldID (19-19)
  • FieldNamespace (21-21)
  • FieldMetadata (23-23)
  • FieldAnnotations (47-47)
  • FieldCreatedAt (25-25)
  • FieldUpdatedAt (27-27)
  • FieldDeletedAt (29-29)
  • ValidColumn (99-106)
  • Columns (80-96)
  • ByID (149-151)
  • OrderOption (146-146)
  • ByNamespace (154-156)
  • ByCreatedAt (159-161)
  • ByUpdatedAt (164-166)
  • ByDeletedAt (169-171)
  • Table (55-55)
openmeter/ent/db/plan/plan.go (15)
  • FieldID (16-16)
  • FieldNamespace (18-18)
  • FieldMetadata (20-20)
  • FieldCreatedAt (22-22)
  • FieldUpdatedAt (24-24)
  • FieldDeletedAt (26-26)
  • ValidColumn (93-100)
  • Columns (75-90)
  • ByID (129-131)
  • OrderOption (126-126)
  • ByNamespace (134-136)
  • ByCreatedAt (139-141)
  • ByUpdatedAt (144-146)
  • ByDeletedAt (149-151)
  • Table (50-50)
⏰ Context from checks skipped due to timeout of 90000ms (9)
  • GitHub Check: Test
  • GitHub Check: Quickstart
  • GitHub Check: Lint
  • GitHub Check: E2E
  • GitHub Check: Developer environment
  • GitHub Check: CI
  • GitHub Check: Build
  • GitHub Check: Commit hooks
  • GitHub Check: Analyze (go)
🔇 Additional comments (47)
pkg/framework/entutils/mixins.go (1)

155-169: Looks consistent with existing JSON mixins.
This new AnnotationsMixin parallels the existing MetadataMixin and cleanly introduces the annotations field, using the correct jsonb schema type for PostgreSQL.

openmeter/ent/schema/planaddon.go (4)

1-13: File structure and imports look good.
The package declaration and imports are organized correctly for an Ent schema file.


14-26: Well-structured Mixin usage.
Defining PlanAddon with existing mixins (IDMixin, NamespaceMixin, MetadataMixin, AnnotationsMixin, TimeMixin) ensures consistent fields such as id, namespace, metadata, annotations, and timestamps.


47-62: Edges correctly map to Plan and Addon entities.
Defining edge.From("plan", Plan.Type)... and edge.From("addon", Addon.Type)... ensures that each PlanAddon row references both sides. The requirement and immutability constraints make sense.


64-79: Appropriate indexing strategy.
The partial unique index (deleted_at IS NULL) and GIN index on annotations are aligned with Ent best practices for partial indexing and JSONB queries.

openmeter/ent/db/addon_update.go (7)

16-16: New import for PlanAddon usage.
Importing planaddon is necessary to manage the “plans” edge.


209-223: AddPlanIDs/AddPlans methods
Implementing these edge-management methods follows Ent conventions and looks correct.


265-284: ClearPlans/RemovePlanIDs/RemovePlans methods
Edge removal logic is consistent with Ent’s approach to clearing or removing relationships.


470-514: Edge clearing and adding logic for “plans”
Use of _spec.Edges.Clear and _spec.Edges.Add for the plans edge is correct.


754-768: Adding “plans” in UpdateOne
These methods ensure you can append PlanAddon entity references in a single update operation.


810-830: Clearing/removing “plans” in UpdateOne
Matches the expected pattern for edge operations in one-off updates.


1045-1089: SQL edge specification for “plans”
This block properly handles the O2M relationship updates in the underlying SQL spec.

openmeter/ent/db/planaddon/planaddon.go (1)

1-176: The PlanAddon schema looks well-structured and follows established patterns.

The file defines a complete schema for the new PlanAddon entity, properly establishing the many-to-many relationship between Plan and Addon entities. The constants, field definitions, and ordering functions follow the same patterns used in other entity definitions within the codebase (like Plan and Addon).

The schema includes important fields:

  • Standard fields like ID, namespace, metadata, annotations, and timestamps
  • Foreign keys to Plan and Addon entities
  • Additional fields like fromPlanPhase and maxQuantity to control the relationship

The implementation of ByPlanField and ByAddonField functions enables ordering by related entity fields, which will be useful for building complex queries.

openmeter/ent/db/planaddon_query.go (8)

21-34: Good implementation of the PlanAddonQuery structure.

The PlanAddonQuery structure follows the repository pattern as seen throughout the codebase, with appropriate fields for configuration, context, ordering, predicates, and eager loading of related entities.


67-87: The Plan edge traversal is correctly implemented.

The QueryPlan method properly establishes the relationship between PlanAddon and Plan entities, enabling traversal from PlanAddon to its associated Plan. The SQL graph traversal is correctly configured with the appropriate cardinality (M2O).


89-109: The Addon edge traversal is correctly implemented.

The QueryAddon method properly establishes the relationship between PlanAddon and Addon entities, enabling traversal from PlanAddon to its associated Addon. The SQL graph traversal is correctly configured with the appropriate cardinality (M2O).


311-331: Eager loading implementation is thorough and efficient.

The WithPlan and WithAddon methods enable efficient eager loading of related entities, following the standard pattern used elsewhere in the codebase. The implementation allows for additional configuration of the eager-loaded queries, which provides flexibility for complex data retrieval scenarios.


407-450: Efficient implementation of eager loading in sqlAll.

The loadedTypes array and edge loading logic in sqlAll properly handle the loading of related Plan and Addon entities. The implementation correctly handles assignment of the loaded entities to the appropriate edges on the PlanAddon entity.


452-509: Foreign key loading functions are properly implemented.

The loadPlan and loadAddon methods efficiently load related entities using a batched approach, collecting all foreign keys first and then executing a single query for each relationship type. This pattern optimizes database access by reducing the number of queries needed.


604-628: Transaction control methods are implemented correctly.

The ForUpdate and ForShare methods provide proper transaction isolation control, with special handling for PostgreSQL dialect. This ensures that the query methods can be used safely in concurrent environments.


630-718: GroupBy and Select functionality follows consistent patterns.

The PlanAddonGroupBy and PlanAddonSelect implementations follow the same patterns used elsewhere in the codebase, providing consistent APIs for aggregation and projection operations. The sqlScan methods properly handle the transformation of SQL results into the requested Go types.

openmeter/ent/db/mutation.go (20)

49-49: No issues found with the new planaddon import.


108-108: Constant definition appears consistent with existing naming conventions.


146-148: New edge fields for plans in AddonMutation look properly aligned with the existing pattern.


917-970: Edge-handling methods for plans in AddonMutation follow standard ent mutation design.


1433-1442: Inclusion of plans edge in AddedEdges() is consistent and correct.


1456-1461: Retrieving plans edge IDs via case addon.EdgePlans is properly implemented.


1474-1480: RemovedEdges() logic for plans matches ent’s mutation pattern.


1497-1502: RemovedIDs implementation for plans is consistent with ent standards.


1515-1521: ClearedEdges() correctly accounts for the plans edge.


1534-1535: EdgeCleared check for plans is accurate.


1557-1559: ResetPlans() call in ResetEdge is properly integrated.


36870-36872: New edge fields (addons, etc.) in PlanMutation follow the established naming pattern.


37592-37645: Methods for managing addons on PlanMutation adhere to the ent mutation structure.


38085-38091: Including addons in AddedEdges() is correctly implemented for PlanMutation.


38108-38113: AddedIDs retrieval for the addons edge matches ent conventions.


38126-38132: RemovedEdges logic for addons is consistent.


38149-38154: RemovedIDs for addons in PlanMutation is implemented as expected.


38167-38173: ClearedEdges check for the addons edge is aligned with ent patterns.


38186-38187: EdgeCleared returning clearedaddons is straightforward and correct.


38209-39252: Comprehensive PlanAddonMutation implementation looks correct and follows ent’s standard approach.
If metadata and annotations fields are user-supplied, consider verifying that they do not store sensitive or malicious data.

openmeter/ent/db/planaddon_create.go (6)

1-26: File Header & Struct Definition Look Good

This file is auto-generated by Ent, which is standard practice. The struct definition for PlanAddonCreate is consistent with typical Ent builder patterns for new entities. No issues here.


88-105: Edge Existence in Transactions

SetPlanID and SetAddonID don’t confirm whether related Plan or Addon entities actually exist. You might consider wrapping these calls in an application-level transaction (or use ent’s transactional approach) to ensure references to non-existent entities are caught earlier, especially if your schema or database constraints allow creation without a strict foreign key.


106-132: Highlighting Custom ID Usage

Though you provide an explicit SetID, the defaults method generates a new ID if none is set. This is a flexible approach. Just be mindful of potential ID collisions and ensure the application or database constraints handle uniqueness if user-supplied IDs become common.


193-235: Thorough Required Field Validation

The check() method admirably enforces required fields, including namespace, plan_id, addon_id, and from_plan_phase. Ensuring this robust server-side validation is a key advantage of Ent.


339-373: Confirm Underlying Unique Constraints for Upsert

OnConflict logic presumes you have a unique index/constraint (for example, on id or a composite key). If the database schema lacks a suitable uniqueness definition, the upsert may not behave as expected.


707-792: Bulk Creation Aligns with Ent Best Practices

PlanAddonCreateBulk properly batches mutations and provides an escape for constraint errors, which is standard for large-scale inserts. The chain of hooks and mutations is set up correctly.

@chrisgacsal chrisgacsal force-pushed the feat/productcatalog branch from 8ff5adb to 2512f0a Compare April 15, 2025 10:53
@chrisgacsal chrisgacsal merged commit 61f7761 into main Apr 15, 2025
28 checks passed
@chrisgacsal chrisgacsal deleted the feat/productcatalog branch April 15, 2025 11:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-note/ignore Ignore this change when generating release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants