Skip to content

feat(api): expose charge system intent#4612

Open
turip wants to merge 1 commit into
mainfrom
feat/charge-patch-source-routing
Open

feat(api): expose charge system intent#4612
turip wants to merge 1 commit into
mainfrom
feat/charge-patch-source-routing

Conversation

@turip

@turip turip commented Jun 30, 2026

Copy link
Copy Markdown
Member

Summary

Adds a system_intent read model to v3 customer charge responses for charges whose customer-facing intent is manually overridden while the original lifecycle controller remains system-owned.

Behavior

  • Top-level charge fields continue to represent the effective customer-facing intent.
  • system_intent is returned only when a manual override shadows a system lifecycle-controller intent.
  • Freshly created manually managed charges do not receive system_intent, because there is no shadowed system intent.
  • The shadowed system intent includes the overridable fields and optional deleted_at, so API consumers can see background system updates even while a manual override is active.

Validation

  • make gen-api
  • make generate
  • make etoe

Summary by CodeRabbit

  • New Features
    • Charge responses now include additional system-derived details when an override is active, helping show more complete charge information.
  • Bug Fixes
    • Improved charge data mapping so flat-fee and usage-based charges return the expected override-related details.
  • Tests
    • Expanded billing override coverage to verify the new charge details appear correctly and remain absent where they should not.

@turip turip requested a review from a team as a code owner June 30, 2026 12:03
@turip turip added area/billing release-note/misc Miscellaneous changes labels Jun 30, 2026
@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7df3b31e-9653-49f7-8bd2-671e659999ae

📥 Commits

Reviewing files that changed from the base of the PR and between 79c88f3 and 781b54b.

⛔ Files ignored due to path filters (1)
  • api/v3/openapi.yaml is excluded by !**/openapi.yaml
📒 Files selected for processing (7)
  • api/spec/packages/aip-client-javascript/src/index.ts
  • api/spec/packages/aip-client-javascript/src/models/schemas.ts
  • api/spec/packages/aip-client-javascript/src/models/types.ts
  • api/spec/packages/aip/src/customers/charges/charges.tsp
  • api/v3/api.gen.go
  • api/v3/handlers/customers/charges/convert.go
  • e2e/billinginvoice_override_test.go

📝 Walkthrough

Walkthrough

Adds ChargeFlatFeeSystemIntent and ChargeUsageBasedSystemIntent models to the TypeSpec API spec, generated TypeScript types/Zod schemas, and Go API converters. Both flat-fee and usage-based charge responses gain an optional system_intent field populated when an active manual override exists, and e2e tests validate its presence, fields, and absence.

Changes

System Intent for Charge Overrides

Layer / File(s) Summary
TypeSpec model definitions
api/spec/packages/aip/src/customers/charges/charges.tsp
Defines ChargeFlatFeeSystemIntent and ChargeUsageBasedSystemIntent via PickProperties, and adds optional system_intent fields to ChargeFlatFee and ChargeUsageBased with Lifecycle.Read visibility.
Generated TypeScript interfaces and re-exports
api/spec/packages/aip-client-javascript/src/models/types.ts, api/spec/packages/aip-client-javascript/src/index.ts
Adds the two new system-intent interfaces, extends ChargeFlatFee/ChargeUsageBased with optional system_intent, relocates ChargePagePaginatedResponse, and updates the index re-export list.
Generated Zod schemas
api/spec/packages/aip-client-javascript/src/models/schemas.ts
Adds chargeFlatFeeSystemIntent and chargeUsageBasedSystemIntent Zod schemas, extends chargeFlatFee/chargeUsageBased with optional system_intent, and relocates charge union and chargePagePaginatedResponse exports.
Go charge-to-API converters
api/v3/handlers/customers/charges/convert.go
Implements toAPIBillingChargeFlatFeeSystemIntent and toAPIBillingChargeUsageBasedSystemIntent helpers and wires SystemIntent population into both converter functions.
E2E test assertions
e2e/billinginvoice_override_test.go
Captures system amounts from pre-edit lines, adds SystemIntent field assertions for updated/deleted flat-fee charges, and asserts absence of SystemIntent for kept/created flat-fees and usage-based charges.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • openmeterio/openmeter#4586: Directly related — adds flat-fee manual delete override support and the deleted_at/override intent data that the new system_intent field and e2e assertions build on.

Suggested labels

release-note/feature

Suggested reviewers

  • chrisgacsal
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.27% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: exposing charge system intent in the API.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/charge-patch-source-routing

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

❤️ Share

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

@greptile-apps

greptile-apps Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR exposes shadowed system charge intent in v3 charge responses. The main changes are:

  • New system_intent response models for flat-fee and usage-based charges.
  • Go conversion logic that maps the system-owned base intent when a manual override is active.
  • Regenerated OpenAPI and TypeScript SDK response types.
  • E2E assertions for flat-fee invoice override system intent.

Confidence Score: 4/5

The usage-based charge read path needs a fix before merging.

  • Overridden system-owned usage-based charges can now convert the shadowed base price.
  • Domain prices like dynamic and package are valid in billing, but toAPIBillingPrice rejects them.
  • That error can make charge list or get requests fail instead of returning the effective charge.

api/v3/handlers/customers/charges/convert.go

Important Files Changed

Filename Overview
api/v3/handlers/customers/charges/convert.go Adds system_intent mapping; usage-based base price conversion can fail for domain price types outside the v3 response union.
api/spec/packages/aip/src/customers/charges/charges.tsp Adds response-only TypeSpec models and optional charge fields for system intent.
api/v3/openapi.yaml Regenerates v3 OpenAPI schemas for the new charge system intent fields.
api/spec/packages/aip-client-javascript/src/models/types.ts Regenerates TypeScript interfaces for charge system intent response shapes.
api/spec/packages/aip-client-javascript/src/models/schemas.ts Regenerates Zod schemas for the new charge system intent response shapes.
e2e/billinginvoice_override_test.go Adds flat-fee system intent checks for invoice override flows.

Fix All in Claude Code Fix All in Codex

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
api/v3/handlers/customers/charges/convert.go:170
**Unsupported Base Prices Break Reads**

When a manual override shadows a system-owned usage-based charge whose base subscription price is `dynamic` or `package`, this new `system_intent` path converts the base price through `toAPIBillingPrice`, which returns `unsupported price type`. The top-level response could previously serialize the effective override price, but now listing or getting that charge can fail the whole request instead of returning the charge.

Reviews (1): Last reviewed commit: "feat(api): expose charge system intent" | Re-trigger Greptile


baseIntent := intent.GetBaseIntent()

price, err := toAPIBillingPrice(baseIntent.Price)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Unsupported Base Prices Break Reads

When a manual override shadows a system-owned usage-based charge whose base subscription price is dynamic or package, this new system_intent path converts the base price through toAPIBillingPrice, which returns unsupported price type. The top-level response could previously serialize the effective override price, but now listing or getting that charge can fail the whole request instead of returning the charge.

Prompt To Fix With AI
This is a comment left during a code review.
Path: api/v3/handlers/customers/charges/convert.go
Line: 170

Comment:
**Unsupported Base Prices Break Reads**

When a manual override shadows a system-owned usage-based charge whose base subscription price is `dynamic` or `package`, this new `system_intent` path converts the base price through `toAPIBillingPrice`, which returns `unsupported price type`. The top-level response could previously serialize the effective override price, but now listing or getting that charge can fail the whole request instead of returning the charge.

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code Fix in Codex

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants