Skip to content

feat(api): add code filter to currency and sort option#4348

Merged
borosr merged 5 commits into
mainfrom
feat/currencies-v3-api-filters
May 14, 2026
Merged

feat(api): add code filter to currency and sort option#4348
borosr merged 5 commits into
mainfrom
feat/currencies-v3-api-filters

Conversation

@borosr
Copy link
Copy Markdown
Collaborator

@borosr borosr commented May 11, 2026

Overview

Extend the GET /api/v3/openmeter/currencies endpoint with filter code and sort query params.

Notes for review

List the currencies

curl --request GET \
  --url 'http://localhost:8888/api/v3/openmeter/currencies?filter%5Bcode%5D%5Beq%5D=USD' 

Summary by CodeRabbit

  • New Features

    • Currency listing supports a new sort query (code default, name) with asc/desc.
    • Added filtering by currency code and improved combined handling of custom + standard currencies.
    • Better validation and clearer error responses for invalid sort or filter parameters.
  • Tests

    • Added comprehensive unit tests covering listing, sorting, code filtering, and custom-only paths.

Review Change Stack

Review Change Stack

@borosr borosr requested a review from tothandras May 11, 2026 21:57
@borosr borosr self-assigned this May 11, 2026
@borosr borosr requested a review from a team as a code owner May 11, 2026 21:57
@borosr borosr added the release-note/ignore Ignore this change when generating release notes label May 11, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 11, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds code-based filtering and a sortable sort query to currencies listing, updating API spec, generated types, handler parsing, adapter queries, service models, in-memory filtering/sorting, and tests.

Changes

Currencies List Sorting and Filtering

Layer / File(s) Summary
API spec and generated types
api/spec/packages/aip/src/currencies/operations.tsp, api/v3/api.gen.go
API spec adds sort query parameter (supports code default and name) and suppresses the doc-decorator on type. Generated Go types add Sort to params, Code filter field, middleware binds sort before filter parsing, and embedded swagger updated.
HTTP handler request parsing
api/v3/handlers/currencies/list.go
Parses sort into OrderBy and Order with validation errors scoped to sort; parses filter.code and filter.type into request fields with per-field error reporting.
Database adapter query logic
openmeter/currencies/adapter/currencies.go
ListCustomCurrencies applies optional code filter to the DB query and computes ordering dynamically from OrderBy/Order with defaults.
Service data models and validation
openmeter/currencies/models.go
Adds OrderBy type and constants, extends ListCurrenciesInput with optional Code, OrderBy, and Order, and updates Validate() to check them.
Service business logic and sorting
openmeter/currencies/service/service.go
Service filters fiat currencies in-memory by code predicate, merges custom currencies, then sorts the combined list by name or code and applies descending direction when requested.
Filter package in-memory matcher
pkg/filter/filter.go, pkg/filter/filter_test.go
Adds FilterString.Match and LoFilterPredicate for in-memory string evaluation, returns ErrOperationNotSupported for certain SQL-like ops, and includes comprehensive table-driven tests.
Service unit tests
openmeter/currencies/service/service_test.go
Tests cover combined listing, custom-only path, code filtering (Eq, In, Ne), ordering by name/code, descending order, and invalid OrderBy validation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • openmeterio/openmeter#4322: Refactors the Common string field filter type that this PR uses for currency code filtering.
  • openmeterio/openmeter#4164: Adds deep-object string filtering to list endpoints using the same shared filter utilities (filters.Parse, filter.ApplyToQuery, pkg/filter.FilterString).

Suggested labels

release-note/feature

Suggested reviewers

  • tothandras
  • solkimicreb
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% 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 accurately captures the main changes: adding a code filter and sort option to the currency API endpoint.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/currencies-v3-api-filters

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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

❤️ Share

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

Copy link
Copy Markdown
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
openmeter/currencies/models.go (1)

55-72: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Validate Order alongside OrderBy in ListCurrenciesInput.Validate().

Right now invalid Order values can pass validation. Adding an explicit check keeps request handling deterministic and consistent with OrderBy.

Suggested fix
 func (i ListCurrenciesInput) Validate() error {
 	var errs []error
@@
 	if err := i.OrderBy.Validate(); err != nil {
 		errs = append(errs, err)
 	}
+
+	switch i.Order {
+	case "", "asc", "desc":
+		// ok
+	default:
+		errs = append(errs, fmt.Errorf("invalid order: %s", i.Order))
+	}
 
 	return errors.Join(errs...)
 }
🤖 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 `@openmeter/currencies/models.go` around lines 55 - 72,
ListCurrenciesInput.Validate currently validates OrderBy but not Order, so
invalid Order values can slip through; update ListCurrenciesInput.Validate to
also validate the Order field (when non-nil) by calling its validation method
(e.g., i.Order.Validate()) and appending any error to errs with context (for
example fmt.Errorf("order: %w", err)), similarly to how FilterType and OrderBy
are handled, then return errors.Join(errs...).
🤖 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.

Inline comments:
In `@api/v3/handlers/currencies/convert.go`:
- Around line 22-24: The check for unsupported operators on the currency code
uses a plain errors.New, causing inconsistent API error mapping; replace the
errors.New returned in the f.Neq != nil branch with the same validation error
helper used elsewhere (models.NewNillableGenericValidationError) so the API
returns a ValidationIssue—update the return inside the f.Neq check to call
models.NewNillableGenericValidationError with the appropriate field/key ("code")
and message stating only "eq" and "oeq" are supported to mirror other validation
branches.

---

Outside diff comments:
In `@openmeter/currencies/models.go`:
- Around line 55-72: ListCurrenciesInput.Validate currently validates OrderBy
but not Order, so invalid Order values can slip through; update
ListCurrenciesInput.Validate to also validate the Order field (when non-nil) by
calling its validation method (e.g., i.Order.Validate()) and appending any error
to errs with context (for example fmt.Errorf("order: %w", err)), similarly to
how FilterType and OrderBy are handled, then return errors.Join(errs...).
🪄 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: aa0e4a5e-c376-4689-9079-937ee15866e7

📥 Commits

Reviewing files that changed from the base of the PR and between de21763 and 2d30eda.

⛔ Files ignored due to path filters (1)
  • api/v3/openapi.yaml is excluded by !**/openapi.yaml
📒 Files selected for processing (8)
  • api/spec/packages/aip/src/currencies/operations.tsp
  • api/v3/api.gen.go
  • api/v3/handlers/currencies/convert.go
  • api/v3/handlers/currencies/list.go
  • openmeter/currencies/adapter/currencies.go
  • openmeter/currencies/models.go
  • openmeter/currencies/service/service.go
  • openmeter/currencies/service/service_test.go

Comment thread api/v3/handlers/currencies/convert.go Outdated
Comment thread api/spec/packages/aip/src/currencies/operations.tsp Outdated
Copy link
Copy Markdown
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

🧹 Nitpick comments (1)
openmeter/currencies/models.go (1)

52-53: ⚡ Quick win

Validate Order in ListCurrenciesInput.Validate() as well.

Nice addition overall. OrderBy is validated, but Order (Line 53) is currently unchecked in the same validator path (Line 75-77), which can let invalid sort direction values slip through from non-HTTP callers. Worth validating both fields together here.

Also applies to: 75-77

🤖 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 `@openmeter/currencies/models.go` around lines 52 - 53, The
ListCurrenciesInput.Validate() currently checks OrderBy but not the Order field,
so update the validator to validate Order as well (together with OrderBy) —
within ListCurrenciesInput.Validate() verify that Order (type sortx.Order) is a
valid sort direction and return an error if not; use the same validation
approach/mechanism used for OrderBy (or a helper like sortx.ValidateOrder /
existing enum checks) so invalid sort directions cannot be passed from non-HTTP
callers, referencing the ListCurrenciesInput struct and its OrderBy and Order
fields.
🤖 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.

Inline comments:
In `@pkg/filter/filter.go`:
- Around line 345-370: The likeMatch function mishandles SQL-style escapes (\,
\% \_ \\) because it treats every character independently; update the loop in
likeMatch to detect a backslash and look ahead (if i+1 < len(pattern)) and when
the next rune is '%', '_', or '\' treat that next character as a literal (emit
regexp.QuoteMeta for the next char) and advance i by 2; otherwise fall through
to the existing switch for '%' -> ".*", '_' -> '.', and default ->
regexp.QuoteMeta for the current character, preserving the (?i) fold prefix and
^/$ anchors and returning the final regexp.MatchString as before.

---

Nitpick comments:
In `@openmeter/currencies/models.go`:
- Around line 52-53: The ListCurrenciesInput.Validate() currently checks OrderBy
but not the Order field, so update the validator to validate Order as well
(together with OrderBy) — within ListCurrenciesInput.Validate() verify that
Order (type sortx.Order) is a valid sort direction and return an error if not;
use the same validation approach/mechanism used for OrderBy (or a helper like
sortx.ValidateOrder / existing enum checks) so invalid sort directions cannot be
passed from non-HTTP callers, referencing the ListCurrenciesInput struct and its
OrderBy and Order fields.
🪄 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: ddd74349-48b6-48b6-9e21-8418b235cd59

📥 Commits

Reviewing files that changed from the base of the PR and between 08df646 and 4f35d59.

⛔ Files ignored due to path filters (1)
  • api/v3/openapi.yaml is excluded by !**/openapi.yaml
📒 Files selected for processing (9)
  • api/spec/packages/aip/src/currencies/operations.tsp
  • api/v3/api.gen.go
  • api/v3/handlers/currencies/list.go
  • openmeter/currencies/adapter/currencies.go
  • openmeter/currencies/models.go
  • openmeter/currencies/service/service.go
  • openmeter/currencies/service/service_test.go
  • pkg/filter/filter.go
  • pkg/filter/filter_test.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • api/spec/packages/aip/src/currencies/operations.tsp
  • api/v3/handlers/currencies/list.go
  • openmeter/currencies/service/service.go
  • openmeter/currencies/service/service_test.go

Comment thread pkg/filter/filter.go Outdated
Copy link
Copy Markdown
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

🤖 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.

Inline comments:
In `@pkg/filter/filter.go`:
- Around line 322-339: The current f.And / f.Or handling short-circuits children
and can silently ignore ErrOperationNotSupported depending on child order;
change both branches to track unsupported-operation errors while still allowing
boolean short-circuiting: in And, iterate children calling child.matches, treat
non-ErrOperationNotSupported errors as before, if any child returns
ErrOperationNotSupported record that fact and continue, if any child returns
false immediately return false,nil, after loop return ErrOperationNotSupported
if recorded else true,nil; in Or, similarly record any ErrOperationNotSupported,
if any child returns true immediately return true,nil, after loop return
ErrOperationNotSupported if recorded else false,nil. Use the existing symbols
f.And, f.Or, child.matches and ErrOperationNotSupported to locate and implement
this logic.
🪄 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: c21e338d-ca54-4c67-9d3f-ef1f376c7392

📥 Commits

Reviewing files that changed from the base of the PR and between 4f35d59 and 237436a.

📒 Files selected for processing (4)
  • openmeter/currencies/service/service.go
  • openmeter/currencies/service/service_test.go
  • pkg/filter/filter.go
  • pkg/filter/filter_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • openmeter/currencies/service/service_test.go
  • pkg/filter/filter_test.go
  • openmeter/currencies/service/service.go

Comment thread pkg/filter/filter.go Outdated
@borosr borosr force-pushed the feat/currencies-v3-api-filters branch from 0c04da6 to 32f3ac6 Compare May 13, 2026 10:20
@borosr borosr force-pushed the feat/currencies-v3-api-filters branch from 32f3ac6 to 76a9f2a Compare May 14, 2026 08:43
@borosr borosr enabled auto-merge (squash) May 14, 2026 08:43
@borosr borosr merged commit 268c2bf into main May 14, 2026
28 checks passed
@borosr borosr deleted the feat/currencies-v3-api-filters branch May 14, 2026 08:50
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