Conversation
📝 WalkthroughWalkthroughA new boolean column Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Adapter
participant DB
Client->>Adapter: UpsertRunDetailedLines(charge, run, lines)
Adapter->>DB: BEGIN txn
Adapter->>DB: DELETE FROM charge_usage_based_run_detailed_line WHERE ...
Adapter->>DB: INSERT INTO charge_usage_based_run_detailed_line (...) VALUES (...)
Adapter->>DB: UPDATE charge_usage_based_runs SET detailed_lines_present = true WHERE ...
DB-->>Adapter: COMMIT
Adapter-->>Client: success
sequenceDiagram
participant Client
participant Adapter
participant DB
Client->>Adapter: FetchDetailedLines(realizations[])
Adapter->>DB: SELECT detailed_lines_present FROM charge_usage_based_runs WHERE run_id IN (...)
DB-->>Adapter: rows with detailed_lines_present flags
Adapter->>DB: (if detailed_lines_present=true) SELECT detailed-line rows for those runs
DB-->>Adapter: detailed-line rows (only for flagged runs)
Adapter-->>Client: realizations populated with DetailedLines Some(lines) or None() per flag
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@openmeter/billing/charges/usagebased/adapter/detailedline.go`:
- Around line 76-79: In FetchDetailedLines, when a run's ID isn't found in
detailedLinesPresentByRunID (the current branch with "if !found { continue }"),
explicitly clear any stale in-memory detailed lines for that realization (e.g.,
set charge.Realizations[idx].DetailedLines to nil or an empty slice) before
continuing; update the code that iterates runs/realizations (reference:
detailedLinesPresentByRunID, run.ID.ID, charge.Realizations[idx].DetailedLines,
FetchDetailedLines) so missing persisted run metadata cannot leave a stale
Some(...) DetailedLines behind.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 5903d44b-e910-4891-9f01-303ebc23a951
⛔ Files ignored due to path filters (9)
openmeter/ent/db/chargeusagebasedruns.gois excluded by!**/ent/db/**openmeter/ent/db/chargeusagebasedruns/chargeusagebasedruns.gois excluded by!**/ent/db/**openmeter/ent/db/chargeusagebasedruns/where.gois excluded by!**/ent/db/**openmeter/ent/db/chargeusagebasedruns_create.gois excluded by!**/ent/db/**openmeter/ent/db/chargeusagebasedruns_update.gois excluded by!**/ent/db/**openmeter/ent/db/migrate/schema.gois excluded by!**/ent/db/**openmeter/ent/db/mutation.gois excluded by!**/ent/db/**openmeter/ent/db/runtime.gois excluded by!**/ent/db/**tools/migrate/migrations/atlas.sumis excluded by!**/*.sum,!**/*.sum
📒 Files selected for processing (6)
openmeter/billing/charges/usagebased/adapter/detailedline.goopenmeter/billing/charges/usagebased/adapter/detailedline_test.goopenmeter/billing/charges/usagebased/adapter/realizationrun.goopenmeter/ent/schema/chargesusagebased.gotools/migrate/migrations/20260429140129_add_usage_based_run_detailed_lines_present.down.sqltools/migrate/migrations/20260429140129_add_usage_based_run_detailed_lines_present.up.sql
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@openmeter/billing/charges/usagebased/adapter/detailedline.go`:
- Around line 153-162: Replace the generic Update().Where(...).Save() with an
ID-targeted update to ensure the row is actually modified: call
tx.db.ChargeUsageBasedRuns.UpdateOneID(runID.ID).SetDetailedLinesPresent(true).Save(ctx)
and handle the returned error explicitly (return err), and if you want clearer
failure semantics convert ent NotFound errors into a descriptive error (e.g.,
"ChargeUsageBasedRuns not found for runID") so a missing row doesn’t silently
appear successful; keep the Namespace and ChargeID checks by validating the
loaded entity after Save (compare returned entity's Namespace/ChargeID to
runID.Namespace/chargeID.ID) and return an error if they don’t match.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 22ee3087-696a-4656-979d-5a2e8febedab
📒 Files selected for processing (2)
openmeter/billing/charges/usagebased/adapter/detailedline.goopenmeter/billing/charges/usagebased/adapter/detailedline_test.go
Rating now owns detailed line conversion so that calculations can use the usagebased detailed line format. This patch also unifies detailed line fetching by making rating expand the detailed lines as needed. This removes the redundant codepath from statemachine/run.
This patch adds a safety feature to the usagebased runs, that makes sure that we properly report if detailed lines are persisted for a run or not. This ensures that we are not in an inconsistent state for prior runs.
e2c9f28 to
88dd7ad
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (1)
openmeter/billing/charges/usagebased/adapter/detailedline.go (1)
153-162:⚠️ Potential issue | 🟠 MajorDon’t let the run-flag update silently no-op.
Line 153 currently uses
Update().Where(...).Save(ctx)and ignores the affected-row count. If that predicate matches zero rows, the method still returns success,DetailedLinesPresentstaysfalse, and a laterFetchDetailedLineswill hide persisted lines behindmo.None(). This PR’s safety contract really wants that update to fail hard instead.Suggested fix
- if _, err := tx.db.ChargeUsageBasedRuns.Update(). - Where( - dbchargeusagebasedruns.NamespaceEQ(runID.Namespace), - dbchargeusagebasedruns.ChargeIDEQ(chargeID.ID), - dbchargeusagebasedruns.ID(runID.ID), - ). - SetDetailedLinesPresent(true). - Save(ctx); err != nil { + if _, err := tx.db.ChargeUsageBasedRuns.UpdateOneID(runID.ID). + Where( + dbchargeusagebasedruns.NamespaceEQ(runID.Namespace), + dbchargeusagebasedruns.ChargeIDEQ(chargeID.ID), + ). + SetDetailedLinesPresent(true). + Save(ctx); err != nil { return err }#!/bin/bash set -euo pipefail # Verify the generated Ent builders expose the expected Save/Where semantics. rg -n -C2 'type ChargeUsageBasedRunsUpdate struct|func \(.*ChargeUsageBasedRunsUpdate\) Save\(|type ChargeUsageBasedRunsUpdateOne struct|func \(.*ChargeUsageBasedRunsUpdateOne\) Save\(|func \(.*ChargeUsageBasedRunsUpdateOne\) Where\(' openmeter/ent/dbExpected result:
ChargeUsageBasedRunsUpdate.Save(...)shows the bulk-update path, whileChargeUsageBasedRunsUpdateOne.Save(...)andWhere(...)exist on the single-row builder so a missing row becomes an error instead of a silent success.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@openmeter/billing/charges/usagebased/adapter/detailedline.go` around lines 153 - 162, The current bulk update using ChargeUsageBasedRuns.Update().Where(...).SetDetailedLinesPresent(true).Save(ctx) can silently no-op if zero rows match; change to the single-row builder so a missing run errors: use ChargeUsageBasedRuns.UpdateOneID(runID.ID) (and still include NamespaceEQ/ChargeIDEQ checks via Where if desired) or use ChargeUsageBasedRuns.UpdateOne(...) so that calling Save(ctx) will return an error when the target row doesn't exist; update the call site in the transaction code to use the UpdateOne* builder instead of Update() and handle the returned error as before.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@openmeter/billing/charges/usagebased/adapter/detailedline.go`:
- Around line 153-162: The current bulk update using
ChargeUsageBasedRuns.Update().Where(...).SetDetailedLinesPresent(true).Save(ctx)
can silently no-op if zero rows match; change to the single-row builder so a
missing run errors: use ChargeUsageBasedRuns.UpdateOneID(runID.ID) (and still
include NamespaceEQ/ChargeIDEQ checks via Where if desired) or use
ChargeUsageBasedRuns.UpdateOne(...) so that calling Save(ctx) will return an
error when the target row doesn't exist; update the call site in the transaction
code to use the UpdateOne* builder instead of Update() and handle the returned
error as before.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 75ec9e6e-4e35-4765-a10a-eabbb0e82bd7
⛔ Files ignored due to path filters (9)
openmeter/ent/db/chargeusagebasedruns.gois excluded by!**/ent/db/**openmeter/ent/db/chargeusagebasedruns/chargeusagebasedruns.gois excluded by!**/ent/db/**openmeter/ent/db/chargeusagebasedruns/where.gois excluded by!**/ent/db/**openmeter/ent/db/chargeusagebasedruns_create.gois excluded by!**/ent/db/**openmeter/ent/db/chargeusagebasedruns_update.gois excluded by!**/ent/db/**openmeter/ent/db/migrate/schema.gois excluded by!**/ent/db/**openmeter/ent/db/mutation.gois excluded by!**/ent/db/**openmeter/ent/db/runtime.gois excluded by!**/ent/db/**tools/migrate/migrations/atlas.sumis excluded by!**/*.sum,!**/*.sum
📒 Files selected for processing (6)
openmeter/billing/charges/usagebased/adapter/detailedline.goopenmeter/billing/charges/usagebased/adapter/detailedline_test.goopenmeter/billing/charges/usagebased/adapter/realizationrun.goopenmeter/ent/schema/chargesusagebased.gotools/migrate/migrations/20260429140129_add_usage_based_run_detailed_lines_present.down.sqltools/migrate/migrations/20260429140129_add_usage_based_run_detailed_lines_present.up.sql
✅ Files skipped from review due to trivial changes (2)
- openmeter/ent/schema/chargesusagebased.go
- tools/migrate/migrations/20260429140129_add_usage_based_run_detailed_lines_present.up.sql
🚧 Files skipped from review as they are similar to previous changes (2)
- tools/migrate/migrations/20260429140129_add_usage_based_run_detailed_lines_present.down.sql
- openmeter/billing/charges/usagebased/adapter/realizationrun.go
Overview
Safety measure: only mark detailed lines as expanded when the persisted
run records that detailed lines were written at least once. Treating
unknown detailed lines as an empty set can make
late-event rating overcharge.
Notes for reviewer
Summary by CodeRabbit
New Features
Bug Fixes
Tests
Chores