Skip to content

fix(api): v3 sort by fields - #4578

Merged
tothandras merged 3 commits into
mainfrom
fix/api-sort-by
Jun 26, 2026
Merged

fix(api): v3 sort by fields#4578
tothandras merged 3 commits into
mainfrom
fix/api-sort-by

Conversation

@tothandras

@tothandras tothandras commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • Bug Fixes
    • Improved sort-field handling across multiple list views so unsupported sort values now return consistent “unsupported sort field” errors that include the supported options, instead of being inconsistently validated or handled.
    • Updated sort-field conversions for add-ons, currencies, customers, events, features, LLM costs/prices, meters, plans, subscriptions, and subscription add-ons to validate and map only allowed fields.
  • Documentation
    • Updated API documentation/comments and the served Swagger/OpenAPI output to use snake_case timestamp sort attributes (for example, created_at, updated_at).

@tothandras
tothandras requested a review from a team as a code owner June 26, 2026 10:07
@tothandras tothandras added the release-note/bug-fix Release note: Bug Fixes label Jun 26, 2026
@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds a shared unsupported-sort-field API error, per-resource sort-field converters in v3 handlers, updated list-handler wiring, and matching spec/doc updates for snake_case sort fields.

Changes

API v3 sort-field handling

Layer / File(s) Summary
Unsupported sort error constructor
api/v3/apierrors/errors_ctors.go
Adds a shared bad-request constructor for unsupported sort fields that includes the field name and supported values.
TypeSpec JSDoc helper
api/spec/packages/typespec-typescript/src/utils.tsx, api/spec/packages/typespec-typescript/src/interface-types.ts, api/spec/packages/typespec-typescript/src/request-types.ts
Adds a shared JSDoc formatter utility and switches TypeSpec code generation helpers to use it for emitted comment formatting.
Sort-field converters
api/v3/handlers/addons/convert.go, api/v3/handlers/currencies/convert.go, api/v3/handlers/customers/convert.go, api/v3/handlers/customers/charges/convert.go, api/v3/handlers/features/convert.go, api/v3/handlers/llmcost/convert.go, api/v3/handlers/meters/convert.go, api/v3/handlers/plans/convert.go, api/v3/handlers/subscriptions/convert.go, api/v3/handlers/subscriptions/subscriptionaddons/convert.go
Adds sort-field conversion helpers for multiple v3 resources and returns standardized unsupported-sort-field errors for invalid inputs.
Event sort parsing
api/v3/handlers/events/convert.go
Adds FromAPIEventSortField and routes fromAPIEventSort through it for supported event sort fields.
List handlers
api/v3/handlers/addons/list.go, api/v3/handlers/currencies/list.go, api/v3/handlers/customers/charges/list.go, api/v3/handlers/customers/list.go, api/v3/handlers/features/list.go, api/v3/handlers/llmcost/list_prices.go, api/v3/handlers/meters/list.go, api/v3/handlers/plans/list.go, api/v3/handlers/subscriptions/list.go, api/v3/handlers/subscriptions/subscriptionaddons/list.go
List handlers now call the new converters, set typed OrderBy values, and return conversion errors directly.
Sort-field docs updates
api/spec/packages/aip-client-javascript/src/models/operations/*, api/spec/packages/aip/src/*, api/v3/api.gen.go
API spec comments, client docs, and generated Swagger text update supported sort-field names to snake_case.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • openmeterio/openmeter#4211: Changes the v3 event sort-field mapping and unsupported-sort-field error path in the event request parsing flow.

Suggested reviewers

  • gergely-kurucz-konghq
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 34.48% 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 is concise and clearly points to the main change: v3 API sort-field handling.
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 fix/api-sort-by

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 26, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes v3 sort-field handling across the API. The main changes are:

  • Public sort docs now use snake_case field names.
  • List handlers now validate supported sort fields.
  • Sort converters now map public fields to backend order values.
  • Generated OpenAPI and JavaScript SDK output were refreshed.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.

Important Files Changed

Filename Overview
api/v3/handlers/meters/convert.go Maps public meter sort fields to the backend order constants.
api/spec/packages/aip/src/meters/operations.tsp Updates ListMeters sort documentation to use snake_case field names.
api/v3/handlers/subscriptions/convert.go Adds subscription sort-field validation and backend mapping.
api/v3/handlers/customers/convert.go Adds customer sort-field validation and backend mapping.
api/v3/handlers/subscriptions/subscriptionaddons/convert.go Adds subscription add-on sort-field validation.

Reviews (3): Last reviewed commit: "fix(sdk): generator" | Re-trigger Greptile

Comment thread api/v3/handlers/meters/convert.go

@coderabbitai coderabbitai Bot left a comment

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.

🧹 Nitpick comments (1)
api/v3/handlers/llmcost/convert.go (1)

207-216: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Nice clean conversion — one tiny dedup idea.

Logic looks spot on, and the docstring explaining why the field is returned unchanged is a lovely touch. 🙂

One small thing: the supported-field list lives in two places (the case labels and the variadic args to NewUnsupportedSortFieldError). If someone adds a field later, it's easy to update one and forget the other, leading to a misleading error message. Totally optional, but you could hoist it to a package-level slice and feed both:

♻️ Optional dedup
var llmCostSortFields = []string{"id", "provider.id", "model.id", "effective_from", "effective_to"}

func FromAPILlmCostSortField(ctx context.Context, field string) (string, error) {
	if slices.Contains(llmCostSortFields, field) {
		return field, nil
	}
	return "", apierrors.NewUnsupportedSortFieldError(ctx, field, llmCostSortFields...)
}

Same pattern shows up in the sibling converters, so if you like it, it travels well.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@api/v3/handlers/llmcost/convert.go` around lines 207 - 216, The supported llm
cost sort fields are duplicated in FromAPILlmCostSortField, which can cause the
switch cases and NewUnsupportedSortFieldError arguments to drift apart. Hoist
the supported values into a shared package-level slice or constant used by
FromAPILlmCostSortField, then use that same source for both the membership check
and the unsupported-field error so the allowed list stays consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@api/v3/handlers/llmcost/convert.go`:
- Around line 207-216: The supported llm cost sort fields are duplicated in
FromAPILlmCostSortField, which can cause the switch cases and
NewUnsupportedSortFieldError arguments to drift apart. Hoist the supported
values into a shared package-level slice or constant used by
FromAPILlmCostSortField, then use that same source for both the membership check
and the unsupported-field error so the allowed list stays consistent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 64ddb61a-e672-4fcc-a3d2-fc7a651f8695

📥 Commits

Reviewing files that changed from the base of the PR and between 3d4c7f0 and 25b22d4.

📒 Files selected for processing (22)
  • api/v3/apierrors/errors_ctors.go
  • api/v3/handlers/addons/convert.go
  • api/v3/handlers/addons/list.go
  • api/v3/handlers/currencies/convert.go
  • api/v3/handlers/currencies/list.go
  • api/v3/handlers/customers/charges/convert.go
  • api/v3/handlers/customers/charges/list.go
  • api/v3/handlers/customers/convert.go
  • api/v3/handlers/customers/list.go
  • api/v3/handlers/events/convert.go
  • api/v3/handlers/features/convert.go
  • api/v3/handlers/features/list.go
  • api/v3/handlers/llmcost/convert.go
  • api/v3/handlers/llmcost/list_prices.go
  • api/v3/handlers/meters/convert.go
  • api/v3/handlers/meters/list.go
  • api/v3/handlers/plans/convert.go
  • api/v3/handlers/plans/list.go
  • api/v3/handlers/subscriptions/convert.go
  • api/v3/handlers/subscriptions/list.go
  • api/v3/handlers/subscriptions/subscriptionaddons/convert.go
  • api/v3/handlers/subscriptions/subscriptionaddons/list.go

turip
turip previously approved these changes Jun 26, 2026
turip
turip previously approved these changes Jun 26, 2026
@greptile-apps

greptile-apps Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Want your agent to iterate on Greptile's feedback? Try greploops.

@coderabbitai coderabbitai Bot left a comment

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.

🧹 Nitpick comments (1)
api/spec/packages/typespec-typescript/src/utils.tsx (1)

501-520: 🩺 Stability & Availability | 🔵 Trivial

Heads up: a */ inside a doc string will break the emitted comment block.

Nice helper! One edge case worth guarding: if a TypeSpec @doc value contains */, it'll close the JSDoc block early and produce invalid TypeScript in the generated SDK. Since this text comes straight from author-controlled docs, escaping it keeps codegen robust.

🛡️ One way to escape the sequence
   if (!doc) {
     return undefined
   }
-  const trimmed = doc.trim()
+  const trimmed = doc.trim().replace(/\*\//g, '*\\/')
   if (!trimmed.includes('\n')) {

Just checked the repo—no current @doc strings contain */, so this isn't urgent. It's a low-effort defensive tweak to keep things bulletproof for the future.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@api/spec/packages/typespec-typescript/src/utils.tsx` around lines 501 - 520,
The jsdoc helper can emit invalid TypeScript when a doc string contains the
closing sequence */ because it is inserted directly into the JSDoc block. Update
jsdoc in utils.tsx to escape or neutralize that sequence before building the
comment, including both the single-line and multi-line branches, so generated
output from doc values cannot accidentally terminate the block early.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@api/spec/packages/typespec-typescript/src/utils.tsx`:
- Around line 501-520: The jsdoc helper can emit invalid TypeScript when a doc
string contains the closing sequence */ because it is inserted directly into the
JSDoc block. Update jsdoc in utils.tsx to escape or neutralize that sequence
before building the comment, including both the single-line and multi-line
branches, so generated output from doc values cannot accidentally terminate the
block early.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: bc51414c-16bc-47ee-a607-ea1ccc41abfe

📥 Commits

Reviewing files that changed from the base of the PR and between a978009 and 0aeb652.

⛔ Files ignored due to path filters (1)
  • api/v3/openapi.yaml is excluded by !**/openapi.yaml
📒 Files selected for processing (38)
  • api/spec/packages/aip-client-javascript/src/models/operations/addons.ts
  • api/spec/packages/aip-client-javascript/src/models/operations/currencies.ts
  • api/spec/packages/aip-client-javascript/src/models/operations/customers.ts
  • api/spec/packages/aip-client-javascript/src/models/operations/events.ts
  • api/spec/packages/aip-client-javascript/src/models/operations/features.ts
  • api/spec/packages/aip-client-javascript/src/models/operations/llmCost.ts
  • api/spec/packages/aip-client-javascript/src/models/operations/meters.ts
  • api/spec/packages/aip-client-javascript/src/models/operations/plans.ts
  • api/spec/packages/aip-client-javascript/src/models/operations/subscriptions.ts
  • api/spec/packages/aip-client-javascript/src/models/types.ts
  • api/spec/packages/aip/src/meters/operations.tsp
  • api/spec/packages/aip/src/subscriptions/operations.tsp
  • api/spec/packages/typespec-typescript/src/interface-types.ts
  • api/spec/packages/typespec-typescript/src/request-types.ts
  • api/spec/packages/typespec-typescript/src/utils.tsx
  • api/v3/api.gen.go
  • api/v3/apierrors/errors_ctors.go
  • api/v3/handlers/addons/convert.go
  • api/v3/handlers/addons/list.go
  • api/v3/handlers/currencies/convert.go
  • api/v3/handlers/currencies/list.go
  • api/v3/handlers/customers/charges/convert.go
  • api/v3/handlers/customers/charges/list.go
  • api/v3/handlers/customers/convert.go
  • api/v3/handlers/customers/list.go
  • api/v3/handlers/events/convert.go
  • api/v3/handlers/features/convert.go
  • api/v3/handlers/features/list.go
  • api/v3/handlers/llmcost/convert.go
  • api/v3/handlers/llmcost/list_prices.go
  • api/v3/handlers/meters/convert.go
  • api/v3/handlers/meters/list.go
  • api/v3/handlers/plans/convert.go
  • api/v3/handlers/plans/list.go
  • api/v3/handlers/subscriptions/convert.go
  • api/v3/handlers/subscriptions/list.go
  • api/v3/handlers/subscriptions/subscriptionaddons/convert.go
  • api/v3/handlers/subscriptions/subscriptionaddons/list.go
💤 Files with no reviewable changes (1)
  • api/v3/api.gen.go
✅ Files skipped from review due to trivial changes (11)
  • api/spec/packages/aip-client-javascript/src/models/operations/addons.ts
  • api/spec/packages/aip-client-javascript/src/models/operations/plans.ts
  • api/spec/packages/aip-client-javascript/src/models/operations/currencies.ts
  • api/spec/packages/aip-client-javascript/src/models/operations/meters.ts
  • api/spec/packages/aip-client-javascript/src/models/operations/features.ts
  • api/spec/packages/aip-client-javascript/src/models/operations/subscriptions.ts
  • api/v3/handlers/llmcost/convert.go
  • api/spec/packages/aip/src/meters/operations.tsp
  • api/spec/packages/aip-client-javascript/src/models/operations/llmCost.ts
  • api/spec/packages/aip-client-javascript/src/models/operations/events.ts
  • api/spec/packages/aip-client-javascript/src/models/operations/customers.ts
🚧 Files skipped from review as they are similar to previous changes (22)
  • api/v3/handlers/features/list.go
  • api/v3/handlers/llmcost/list_prices.go
  • api/v3/apierrors/errors_ctors.go
  • api/v3/handlers/meters/list.go
  • api/v3/handlers/subscriptions/convert.go
  • api/v3/handlers/customers/charges/convert.go
  • api/v3/handlers/customers/list.go
  • api/v3/handlers/addons/convert.go
  • api/v3/handlers/subscriptions/list.go
  • api/v3/handlers/addons/list.go
  • api/v3/handlers/meters/convert.go
  • api/spec/packages/aip/src/subscriptions/operations.tsp
  • api/v3/handlers/currencies/convert.go
  • api/v3/handlers/subscriptions/subscriptionaddons/convert.go
  • api/v3/handlers/subscriptions/subscriptionaddons/list.go
  • api/v3/handlers/currencies/list.go
  • api/v3/handlers/customers/charges/list.go
  • api/v3/handlers/events/convert.go
  • api/v3/handlers/plans/convert.go
  • api/v3/handlers/features/convert.go
  • api/v3/handlers/plans/list.go
  • api/v3/handlers/customers/convert.go

@tothandras
tothandras merged commit c725b4d into main Jun 26, 2026
29 checks passed
@tothandras
tothandras deleted the fix/api-sort-by branch June 26, 2026 11:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-note/bug-fix Release note: Bug Fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants