Skip to content

refactor(policy): decouple sort field/direction mapping and add SQL-level sort defaults#3402

Merged
dsm20 merged 35 commits into
mainfrom
sort-proto-refactor
May 4, 2026
Merged

refactor(policy): decouple sort field/direction mapping and add SQL-level sort defaults#3402
dsm20 merged 35 commits into
mainfrom
sort-proto-refactor

Conversation

@dsm20

@dsm20 dsm20 commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

refactor(policy): decouple sort field/direction mapping and add SQL-level sort defaults

Proposed Changes

Fixes a silent bug where providing a sort direction with an UNSPECIFIED field caused the direction to be discarded. Refactors the Go sort mappers to be pure enum-to-string translators, moves all default logic into SQL via CTEs, and documents all default behavior at the proto level.

Bug Fixed

Get*SortParams previously coupled field and direction mapping. When the sort field was UNSPECIFIED, both field AND direction were returned as empty strings (return "", ""), silently discarding any user-provided direction. A user sending field=UNSPECIFIED, direction=ASC would get created_at DESC instead of created_at ASC.

Sort Defaults

All defaults are now resolved in SQL via a CTE:

  • field UNSPECIFIED defaults to created_at
  • direction UNSPECIFIED defaults to DESC
  • both UNSPECIFIED or sort omitted defaults to created_at DESC
  • id ASC tiebreaker on all queries for deterministic ordering

Changes

Go Sort Mappers -- service/policy/db/utils.go

  • getSortDirection: UNSPECIFIED now returns "" (was "ASC"), with explicit fallthrough for readability
  • Added 8 get*SortField helpers: pure enum-to-string translators, one per resource, UNSPECIFIED returns ""
  • Refactored 8 GetSortParams: delegate to getSortField and getSortDirection independently. Removed sort[0] == nil guard (proto never produces nil in repeated fields). Signature unchanged, call sites unchanged.

SQL Queries -- service/policy/db/queries/*.sql

Added CTE-based sort default resolution to all 9 list queries (8 RPCs):

WITH params AS (
    SELECT
        COALESCE(NULLIF(@sort_field::text, ''), 'created_at') AS resolved_field,
        COALESCE(NULLIF(@sort_direction::text, ''), 'DESC') AS resolved_direction
)

Also added id ASC tiebreaker and p.resolved_field, p.resolved_direction to GROUP BY where needed.

Affected queries: listNamespaces, listAttributesDetail, listAttributesSummary, listObligations, listRegisteredResources, listKeyAccessServers, listKeys, listSubjectConditionSets, listSubjectMappings

Proto Docs -- all List*Request sort field comments

Replaced vague "the service applies its default ordering" with explicit defaults:

// Sort defaults:
//   - direction UNSPECIFIED defaults to DESC for the specified field
//   - field UNSPECIFIED defaults to created_at with the specified direction
//   - both UNSPECIFIED or sort omitted defaults to created_at DESC

Unit Tests -- service/policy/db/utils_test.go

Updated all 8 test functions:

  • Removed nil element test cases (proto handles this)
  • Added "UNSPECIFIED field with ASC/DESC preserves direction" test cases
  • Added "both UNSPECIFIED returns empty strings" test cases
  • Updated "unspecified direction" expectations from "ASC" to ""

Integration Tests -- service/integration/*_test.go

Replaced 8 FallsBackToDefault tests with 24 targeted default tests (3 per RPC):

  • SortByUnspecifiedField_DefaultsToCreatedAt: field UNSPECIFIED + explicit ASC, expects created_at ASC
  • SortByUnspecifiedDirection_DefaultsToDESC: explicit created_at + direction UNSPECIFIED, expects created_at DESC
  • SortByBothUnspecified_DefaultsToCreatedAtDESC: both UNSPECIFIED, expects created_at DESC

Checklist

  • I have added or updated unit tests
  • I have added or updated integration tests (if appropriate)
  • I have added or updated documentation

Testing Instructions

Unit tests: go test ./service/policy/db/... -run "Sort"

Summary by CodeRabbit

Release Notes

  • Improvements

    • Standardized list operation sorting behavior across all endpoints: sort defaults to created_at DESC when omitted, created_at with specified direction when field is unspecified, and DESC with specified field when direction is unspecified.
    • Enhanced validation: sort field and direction parameters now strictly enforce defined enum values.
  • Documentation

    • Updated API documentation to clarify consistent sort defaults and behavior across all list operations.

dsm20 added 4 commits April 27, 2026 11:20
removed endpoint-specific behavior comment/doc from enum. this behavior may change between endpoints and shouldn't be established as the de facto standard. kept the note referring the behavior documentation to the specific list request
each field in the __Sort messages now has defined_only which only allows defined enum values to be passed in
all comments for the sort field are now standardized to declare unspecified maps to ASC, and no sort + unspecified maps to the specific default ordering of the endpoint
@dsm20
dsm20 requested review from a team as code owners April 27, 2026 15:42
@dsm20
dsm20 marked this pull request as draft April 27, 2026 15:42
@coderabbitai

coderabbitai Bot commented Apr 27, 2026

Copy link
Copy Markdown

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

Standardizes list-sorting semantics and validation: removes the global note treating UNSPECIFIED as ASC, adds per-request defaulting docs, enforces enum-defined-only validation on sort fields/directions in multiple protos, and changes Go/SQL helpers to let query SQL determine per-request default ordering.

Changes

Cohort / File(s) Summary
Protos: validation & docs
service/policy/attributes/attributes.proto, service/policy/kasregistry/key_access_server_registry.proto, service/policy/namespaces/namespaces.proto, service/policy/obligations/obligations.proto, service/policy/registeredresources/registered_resources.proto, service/policy/selectors.proto, service/policy/subjectmapping/subject_mapping.proto
Added (buf.validate.field).enum.defined_only = true to sort field and direction enums; updated inline List*Request.sort comments to document conditional defaulting for direction/field UNSPECIFIED and overall fallback.
Go: DB helpers & tests
service/policy/db/utils.go, service/policy/db/utils_test.go
Split field->column and direction resolution into separate helpers; getSortDirection returns "" for UNSPECIFIED so SQL applies defaults; removed sort[0]==nil guards; updated table-driven tests to new semantics.
SQL queries & generated SQL Go
service/policy/db/queries/*.sql, service/policy/db/*.sql.go (attributes, key_access_server_registry, namespaces, obligations, registered_resources, subject_mappings)
Introduce WITH params CTE to compute resolved_field/resolved_direction, CROSS JOIN params, use p.resolved_* in ORDER BY, adjust tie-breakers (many to id ASC), and renumber LIMIT/OFFSET placeholders with matching Go arg/struct ordering changes.
Integration tests
service/integration/*.go (attributes_test.go, kas_registry_*.go, namespaces_test.go, obligations_test.go, registered_resources_test.go, subject_mappings_test.go)
Replaced single unspecified-field fallback tests with split cases validating: field UNSPECIFIED preserves explicit Direction (e.g., ASC) by falling back to created_at, Direction UNSPECIFIED defaults to DESC for an explicit field, and both UNSPECIFIED (or omitted) default to created_at DESC.
OpenAPI & gRPC docs
docs/openapi/policy/.../*.openapi.yaml, docs/grpc/index.html
Removed global note that treated UNSPECIFIED as ASC; standardized per-List* docs with a “Sort defaults” block describing how direction/field/omission resolve to defaults (overall fallback created_at DESC).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Client as Client
  participant API as API Handler
  participant GoSvc as Go Sorting Helpers
  participant DB as PostgreSQL
  Client->>API: List request (optional sort)
  API->>GoSvc: pass sort param array
  alt sort omitted
    GoSvc->>DB: call SQL with empty sort params
    DB->>DB: params CTE -> resolved_field=created_at, resolved_direction=DESC
  else field specified, direction UNSPECIFIED
    GoSvc->>DB: pass resolved_field=<col>, resolved_direction=""
    DB->>DB: params CTE -> resolved_direction = ASC for provided field
  else field UNSPECIFIED, direction specified
    GoSvc->>DB: pass resolved_field=created_at, resolved_direction=<ASC|DESC>
  end
  DB->>API: rows ordered per p.resolved_field / p.resolved_direction
  API->>Client: return ordered list
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

comp:db, size/xl

Suggested reviewers

  • c-r33d
  • alkalescent
  • jakedoublev

Poem

🐰 I hop through proto, SQL, and doc,

I nudge UNSPECIFIED to mind the clock,
Field defaults to created_at when lone,
Direction waits — DESC when none is shown,
Carrots for order, tidy as a rock.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.71% 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 summarizes the primary change: refactoring sort field/direction mapping in the policy service and implementing SQL-level sort defaults.
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 sort-proto-refactor

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.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request improves the robustness and clarity of the policy service API definitions. By enforcing strict enum validation on sorting parameters and unifying the documentation for default sorting behaviors, the changes ensure more predictable API interactions and better developer experience.

Highlights

  • Validation Updates: Added defined_only validation to all sort field and direction enums across policy services to ensure only valid enum values are accepted.
  • Documentation Cleanup: Standardized and clarified documentation regarding default sorting behavior when fields or directions are omitted or set to UNSPECIFIED.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Ignored Files
  • Ignored by pattern: docs/openapi/**/* (9)
    • docs/openapi/authorization/authorization.openapi.yaml
    • docs/openapi/policy/attributes/attributes.openapi.yaml
    • docs/openapi/policy/kasregistry/key_access_server_registry.openapi.yaml
    • docs/openapi/policy/namespaces/namespaces.openapi.yaml
    • docs/openapi/policy/objects.openapi.yaml
    • docs/openapi/policy/obligations/obligations.openapi.yaml
    • docs/openapi/policy/registeredresources/registered_resources.openapi.yaml
    • docs/openapi/policy/selectors.openapi.yaml
    • docs/openapi/policy/subjectmapping/subject_mapping.openapi.yaml
  • Ignored by pattern: protocol/**/* (9)
    • protocol/go/authorization/authorization.pb.go
    • protocol/go/policy/attributes/attributes.pb.go
    • protocol/go/policy/kasregistry/key_access_server_registry.pb.go
    • protocol/go/policy/namespaces/namespaces.pb.go
    • protocol/go/policy/objects.pb.go
    • protocol/go/policy/obligations/obligations.pb.go
    • protocol/go/policy/registeredresources/registered_resources.pb.go
    • protocol/go/policy/selectors.pb.go
    • protocol/go/policy/subjectmapping/subject_mapping.pb.go
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.


The proto files were cleaned with care, To make the sorting logic fair. With validation now in place, No bad values leave a trace.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions github-actions Bot added comp:policy Policy Configuration ( attributes, subject mappings, resource mappings, kas registry) docs Documentation size/s labels Apr 27, 2026

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request standardizes sorting documentation across various list APIs and introduces buf.validate.field constraints to ensure enum values are defined in the protobuf definitions. While the standardization is helpful, the changes removed specific default ordering details (such as created_at DESC) from several proto files and the generated HTML documentation. Feedback focuses on restoring these specific implementation details to maintain API transparency for consumers.

Comment thread service/policy/kasregistry/key_access_server_registry.proto Outdated
Comment thread service/policy/kasregistry/key_access_server_registry.proto Outdated
Comment thread service/policy/obligations/obligations.proto Outdated
Comment thread service/policy/registeredresources/registered_resources.proto Outdated
Comment thread service/policy/subjectmapping/subject_mapping.proto Outdated
@github-actions

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 181.632422ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 104.0184ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 404.560033ms
Throughput 247.18 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 45.220457923s
Average Latency 451.084575ms
Throughput 110.57 requests/second

Signed-off-by: Diego <74568547+dsm20@users.noreply.github.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 the current code and only fix it if needed.

Inline comments:
In `@docs/grpc/index.html`:
- Line 7506: The docs claim that each List* request defines default ordering but
the endpoint docs only say the service applies a default without specifying what
it is; update the documentation so that for every List* request and endpoint
referenced (any docs mentioning the 'sort' field or the UNSPECIFIED enum value)
you explicitly state the implemented default ordering used when 'sort' is
omitted or 'field' == UNSPECIFIED — e.g., "default order: <field>
ascending/descending" — and ensure the List* request comment and the endpoint
description use the same precise wording so clients have a deterministic,
reproducible default for pagination; search for occurrences of 'sort',
'UNSPECIFIED', and "default ordering" in the generated docs and edit the List*
request and corresponding endpoint sections to include the concrete default
order.
🪄 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: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: ad4776be-1dd5-431f-826c-786c1ee83415

📥 Commits

Reviewing files that changed from the base of the PR and between d1097ea and 3c44053.

⛔ Files ignored due to path filters (9)
  • protocol/go/authorization/authorization.pb.go is excluded by !**/*.pb.go
  • protocol/go/policy/attributes/attributes.pb.go is excluded by !**/*.pb.go
  • protocol/go/policy/kasregistry/key_access_server_registry.pb.go is excluded by !**/*.pb.go
  • protocol/go/policy/namespaces/namespaces.pb.go is excluded by !**/*.pb.go
  • protocol/go/policy/objects.pb.go is excluded by !**/*.pb.go
  • protocol/go/policy/obligations/obligations.pb.go is excluded by !**/*.pb.go
  • protocol/go/policy/registeredresources/registered_resources.pb.go is excluded by !**/*.pb.go
  • protocol/go/policy/selectors.pb.go is excluded by !**/*.pb.go
  • protocol/go/policy/subjectmapping/subject_mapping.pb.go is excluded by !**/*.pb.go
📒 Files selected for processing (17)
  • docs/grpc/index.html
  • docs/openapi/authorization/authorization.openapi.yaml
  • docs/openapi/policy/attributes/attributes.openapi.yaml
  • docs/openapi/policy/kasregistry/key_access_server_registry.openapi.yaml
  • docs/openapi/policy/namespaces/namespaces.openapi.yaml
  • docs/openapi/policy/objects.openapi.yaml
  • docs/openapi/policy/obligations/obligations.openapi.yaml
  • docs/openapi/policy/registeredresources/registered_resources.openapi.yaml
  • docs/openapi/policy/selectors.openapi.yaml
  • docs/openapi/policy/subjectmapping/subject_mapping.openapi.yaml
  • service/policy/attributes/attributes.proto
  • service/policy/kasregistry/key_access_server_registry.proto
  • service/policy/namespaces/namespaces.proto
  • service/policy/obligations/obligations.proto
  • service/policy/registeredresources/registered_resources.proto
  • service/policy/selectors.proto
  • service/policy/subjectmapping/subject_mapping.proto
💤 Files with no reviewable changes (1)
  • docs/openapi/policy/objects.openapi.yaml

Comment thread docs/grpc/index.html
@github-actions

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 147.892609ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 76.500806ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 357.261417ms
Throughput 279.91 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 36.237822312s
Average Latency 360.689007ms
Throughput 137.98 requests/second

trying to resolve versioning issue with buf on local setup
@github-actions

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 171.579791ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 96.690836ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 407.094849ms
Throughput 245.64 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 43.959830535s
Average Latency 437.663666ms
Throughput 113.74 requests/second

@dsm20
dsm20 marked this pull request as ready for review April 27, 2026 19:05
Comment thread service/policy/attributes/attributes.proto Outdated
the bug:

Get*SortParams previously returned "", "" when field was unspecified, ignoring the user's direction preference. This was a logic error causing silent disregarding of direction in the case the sort field was unspecified.

the fix:

getSortDirection now maps UNSPECIFIED to "", instead of ASC. Added new helper, get*SortField, which maps sort fields to strings, with the same handling for unspecified as getSortDirection, mapping unspecified field to "".

This marks a new approach where the SQL handles all the defaults, the go layer simply maps unspecified fields to empty strings which are then handled in SQL.

Added Get*SortParams wrapper that first checks if there is a *Sort struct (to account for the no-sort behavior of created_at DESC, or "", "" in Go. This function calls get*SortField and get*SortDirection and returns their values. This function is called in namespaces.go or equivalent to build the query.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 the current code and only fix it if needed.

Inline comments:
In `@service/policy/db/utils.go`:
- Around line 78-85: Add targeted unit tests for GetNamespacesSortParams in
service/policy/db/utils_test.go that assert the new independent resolution
behavior: call GetNamespacesSortParams with (1) a slice containing a
NamespacesSort having a concrete field and SORT_DIRECTION_UNSPECIFIED and assert
it returns (resolvedField, "") using getNamespacesSortField(expected) semantics,
(2) a slice containing a NamespacesSort with field UNSPECIFIED and direction
DESC and assert it returns ("", "DESC") (i.e., getSortDirection(expected)
result), and (3) a slice containing a nil element and assert it returns ("", "")
to preserve current behavior; reference GetNamespacesSortParams,
getNamespacesSortField, and getSortDirection in test assertions and run go test
./... to verify.
🪄 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: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: d0d61bb1-acfe-4adc-95ea-9045a42d81df

📥 Commits

Reviewing files that changed from the base of the PR and between 5342049 and 406427d.

📒 Files selected for processing (1)
  • service/policy/db/utils.go

Comment thread service/policy/db/utils.go
@github-actions

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 148.997825ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 71.634358ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 344.244091ms
Throughput 290.49 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 33.79032894s
Average Latency 336.400734ms
Throughput 147.97 requests/second

@github-actions

Copy link
Copy Markdown
Contributor

same changes as namespaces: add get*SortField helper that correctly maps unspecified to "", removed nil verification from Get*SortParams (not needed)
shortened prefix, was failing in CI because the prefix + timestamp was too long(?)
@github-actions

github-actions Bot commented May 1, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actions Bot commented May 1, 2026

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 158.25904ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 87.953384ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 417.686684ms
Throughput 239.41 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 42.681573673s
Average Latency 425.405267ms
Throughput 117.15 requests/second

@github-actions

github-actions Bot commented May 1, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actions Bot commented May 1, 2026

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 200.55031ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 106.997381ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 420.554221ms
Throughput 237.78 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 44.94602501s
Average Latency 447.553828ms
Throughput 111.24 requests/second

@dsm20
dsm20 marked this pull request as ready for review May 1, 2026 18:44
@github-actions

github-actions Bot commented May 1, 2026

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/grpc/index.html`:
- Around line 8868-8872: Update the "Sort defaults" paragraph in the docs (the
block that lists "direction UNSPECIFIED defaults..." and "field UNSPECIFIED
defaults...") to explicitly mention the SQL deterministic tie-breaker by adding
a short line such as "Tiebreaker: id ASC" after the existing defaults; apply the
same edit to every other matching "Sort defaults" occurrence in the document so
the pagination docs and implementation (id ASC tie-breaker) are aligned.

In `@docs/openapi/policy/attributes/attributes.openapi.yaml`:
- Around line 760-764: The shared enum schema policy.SortDirection currently
includes request-level default/fallback ordering guidance; remove that
fallback-ordering semantics from the policy.SortDirection description so it only
generically defines the enum values (e.g., ASC, DESC, UNSPECIFIED) and their
meaning, and ensure any default-ordering matrix or fallback behavior remains
documented only on the request-level field ListAttributesRequest.sort (update
that request's docs if needed). Locate and edit the description text in the
policy.SortDirection schema and delete the sentences about endpoint
defaults/fallback ordering, leaving only neutral enum documentation.

In `@docs/openapi/policy/kasregistry/key_access_server_registry.openapi.yaml`:
- Around line 1646-1651: The documentation for ListKeyAccessServersRequest.sort
explains defaulting rules but those defaults are not exposed on the flattened
query parameters; update the OpenAPI spec so the same default behavior is copied
to the GET query params "sort.field" and "sort.direction" (or add a clear note
in the /key-access-servers operation description) so OpenAPI consumers see: (1)
direction UNSPECIFIED defaults to DESC for the specified field, (2) field
UNSPECIFIED defaults to created_at with the specified direction, and (3) both
UNSPECIFIED or omitted defaults to created_at DESC; reference
ListKeyAccessServersRequest.sort, the query params sort.field and
sort.direction, and the /key-access-servers operation when making the change.
🪄 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: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4fc2a726-8220-49be-9bba-d6a280c1e412

📥 Commits

Reviewing files that changed from the base of the PR and between 07a7bb7 and 3fdd587.

⛔ Files ignored due to path filters (6)
  • protocol/go/policy/attributes/attributes.pb.go is excluded by !**/*.pb.go
  • protocol/go/policy/kasregistry/key_access_server_registry.pb.go is excluded by !**/*.pb.go
  • protocol/go/policy/namespaces/namespaces.pb.go is excluded by !**/*.pb.go
  • protocol/go/policy/obligations/obligations.pb.go is excluded by !**/*.pb.go
  • protocol/go/policy/registeredresources/registered_resources.pb.go is excluded by !**/*.pb.go
  • protocol/go/policy/subjectmapping/subject_mapping.pb.go is excluded by !**/*.pb.go
📒 Files selected for processing (32)
  • docs/grpc/index.html
  • docs/openapi/policy/attributes/attributes.openapi.yaml
  • docs/openapi/policy/kasregistry/key_access_server_registry.openapi.yaml
  • docs/openapi/policy/namespaces/namespaces.openapi.yaml
  • docs/openapi/policy/obligations/obligations.openapi.yaml
  • docs/openapi/policy/registeredresources/registered_resources.openapi.yaml
  • docs/openapi/policy/subjectmapping/subject_mapping.openapi.yaml
  • service/integration/attributes_test.go
  • service/integration/kas_registry_key_test.go
  • service/integration/kas_registry_test.go
  • service/integration/namespaces_test.go
  • service/integration/obligations_test.go
  • service/integration/registered_resources_test.go
  • service/integration/subject_mappings_test.go
  • service/policy/attributes/attributes.proto
  • service/policy/db/attributes.sql.go
  • service/policy/db/key_access_server_registry.sql.go
  • service/policy/db/namespaces.sql.go
  • service/policy/db/obligations.sql.go
  • service/policy/db/queries/attributes.sql
  • service/policy/db/queries/key_access_server_registry.sql
  • service/policy/db/queries/namespaces.sql
  • service/policy/db/queries/obligations.sql
  • service/policy/db/queries/registered_resources.sql
  • service/policy/db/queries/subject_mappings.sql
  • service/policy/db/registered_resources.sql.go
  • service/policy/db/subject_mappings.sql.go
  • service/policy/kasregistry/key_access_server_registry.proto
  • service/policy/namespaces/namespaces.proto
  • service/policy/obligations/obligations.proto
  • service/policy/registeredresources/registered_resources.proto
  • service/policy/subjectmapping/subject_mapping.proto

Comment thread docs/grpc/index.html
Comment thread docs/openapi/policy/attributes/attributes.openapi.yaml
Comment thread service/integration/attributes_test.go

@c-r33d c-r33d 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.

Looks good overall, I would add a couple nil checks around db utils methods when calling sort[0].Get.... While the Get methods are nil safe, it's probably good to have a small test where the Sort[] has one nil object.

dsm20 added 2 commits May 4, 2026 09:28
unit tests passing in nil for sort, which resolves to the default "", ""
@github-actions

github-actions Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor

X-Test Failure Report

@github-actions

github-actions Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 145.824586ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 68.950926ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 343.745741ms
Throughput 290.91 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 33.079586823s
Average Latency 329.534791ms
Throughput 151.15 requests/second

@github-actions

github-actions Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 175.284822ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 91.795489ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 435.066967ms
Throughput 229.85 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 42.630041961s
Average Latency 424.542103ms
Throughput 117.29 requests/second

makes a listRPC request with no sort field, which in turn passes getSort() an empty array, defaulting to the params "", "" via get*SortParams helper
@github-actions

github-actions Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actions Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 147.011514ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 94.893946ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 410.350821ms
Throughput 243.69 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 42.010989414s
Average Latency 418.714808ms
Throughput 119.02 requests/second

@github-actions

github-actions Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor

⚠️ Govulncheck found vulnerabilities ⚠️

The following modules have known vulnerabilities:

  • tests-bdd

See the workflow run for details.

@github-actions

github-actions Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor

Comment thread service/policy/db/utils.go
Comment thread service/policy/db/utils.go
@dsm20
dsm20 added this pull request to the merge queue May 4, 2026
Merged via the queue into main with commit fe2bc07 May 4, 2026
39 checks passed
dsm20 added a commit that referenced this pull request May 4, 2026
#3402 added more integration tests that needed cleanup calls
JBCongdon pushed a commit to JBCongdon/platform that referenced this pull request May 24, 2026
…ests, add test cleanup (opentdf#3403)

## Proposed Changes

Consolidates integration test helpers across all policy sort test
suites, adds proper test cleanup, and adds tiebreaker-specific
integration tests that verify the `id ASC` fallback produces
deterministic ordering.

## Changes

### Integration Test Helpers -- service/integration/utils.go

- `forceDeleteRows`: hard-deletes rows by ID via raw SQL, bypassing the
API's soft-delete/deactivate limitation for test cleanup
- `forceCreatedAtTie`: sets `created_at` to a fixed timestamp for given
IDs, guaranteeing that the `ORDER BY` tiebreaker (`id ASC`) determines
sort order

### Integration Test Consolidation -- service/integration/*_test.go

- Refactored `createSortTest*` helpers from `(label string)` to
`(prefixes []string)` across all RPCs, giving each test explicit control
over resource names
- Added `defer` cleanup calls to all sort integration tests via
`deleteSortTest*` helpers
- Added `Test_List*_SortTieBreaker_CreatedAtWithIDFallback` for all 8
RPCs: Namespaces, Attributes, KeyAccessServers, KasKeys, Obligations,
RegisteredResources, SubjectMappings, SubjectConditionSets

### Tiebreaker Test Strategy

Each tiebreaker test:
1. Creates 3 resources
2. Forces identical `created_at` timestamps via `forceCreatedAtTie`
3. Sorts the UUIDs lexicographically to get expected order
4. Lists with `created_at ASC` and asserts rows match the UUID-sorted
order

This proves the `id ASC` tiebreaker added in opentdf#3402 produces
deterministic results when the primary sort column ties.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Release Notes

* **Tests**
* Standardized sort test helpers across integration tests to ensure
consistent attribute, key, namespace, obligation, and resource creation
with deterministic timestamps.
* Added tie-breaker tests to validate deterministic ordering behavior
when creation timestamps are equal.
* Enhanced test utilities for database cleanup and timestamp management.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp:policy Policy Configuration ( attributes, subject mappings, resource mappings, kas registry) docs Documentation size/s

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants