feat(policy): add sort support to ListSubjectConditionSets API#3272
feat(policy): add sort support to ListSubjectConditionSets API#3272
Conversation
📝 WalkthroughWalkthroughAdds single-field sorting for ListSubjectConditionSets: proto/OpenAPI/docs updates, new sort enum/message, helper to map proto sort to SQL, conditional ORDER BY in the query for created_at/updated_at with tie-breakers, and unit + integration tests validating sorts and fallbacks. Changes
Sequence DiagramsequenceDiagram
participant Client as Client
participant Service as Service Handler
participant Utils as Sort Utils
participant SQL as Query Builder
participant DB as PostgreSQL
Client->>Service: ListSubjectConditionSets(request with optional sort)
Service->>Utils: GetSubjectConditionSetsSortParams(request.sort)
Utils-->>Service: (sortField, sortDirection) or ("","")
Service->>SQL: Execute listSubjectConditionSets(sortField, sortDirection, offset, limit)
SQL->>DB: SELECT ... ORDER BY (CASE on sortField & sortDirection), scs.created_at DESC, scs.id ASC LIMIT/OFFSET
DB-->>SQL: Rows ordered
SQL-->>Service: Result rows
Service-->>Client: ListSubjectConditionSetsResponse
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 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. Comment |
Summary of ChangesHello, 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 introduces sorting capabilities to the ListSubjectConditionSets API, enabling more flexible data retrieval. The changes include updates to the protocol buffers, database query logic, and the application layer to map and apply sort parameters. This enhancement maintains backward compatibility while providing a robust mechanism for ordering results by creation or update timestamps. Highlights
🧠 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
Using Gemini Code AssistThe 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
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 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 data flows in rows so neat, With timestamps guiding every beat. From oldest past to newest day, Our sorting logic leads the way. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces sorting capabilities for SubjectConditionSets, allowing results to be ordered by creation or update timestamps. The implementation includes updates to the protobuf definitions, SQL queries, and database utility functions, along with comprehensive integration and unit tests. The review feedback suggests improving test stability by replacing or extending time.Sleep calls, ensuring Go version compatibility for loop syntax, and refactoring the SQL ORDER BY logic for better readability and maintenance.
X-Test Failure Reportopentdf |
Benchmark results, click to expandBenchmark authorization.GetDecisions Results:
Benchmark authorization.v2.GetMultiResourceDecision Results:
Benchmark Statistics
Bulk Benchmark Results
TDF3 Benchmark Results:
|
Benchmark results, click to expandBenchmark authorization.GetDecisions Results:
Benchmark authorization.v2.GetMultiResourceDecision Results:
Benchmark Statistics
Bulk Benchmark Results
TDF3 Benchmark Results:
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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 16535-16550: The documentation entry for
SORT_SUBJECT_CONDITION_SETS_TYPE_UNSPECIFIED is missing its fallback semantics;
update the enum comment for SORT_SUBJECT_CONDITION_SETS_TYPE_UNSPECIFIED in the
proto (or the source that generates docs) to explicitly state that the server
will treat UNSPECIFIED as "created_at DESC" (i.e., sort by created_at
descending) and then regenerate the gRPC docs so the generated HTML table
includes that description next to SORT_SUBJECT_CONDITION_SETS_TYPE_UNSPECIFIED.
In `@service/integration/subject_mappings_test.go`:
- Around line 2574-2604: createSortTestSubjectConditionSets currently leaves
three SubjectConditionSet rows behind; modify it to register a cleanup that
deletes the created IDs after the test finishes by capturing the ids slice and
calling the delete operation in s.T().Cleanup. Specifically, after creating each
SubjectConditionSet (via PolicyClient.CreateSubjectConditionSet) capture the
created.GetId() into ids and then register s.T().Cleanup(func() { for _, id :=
range ids { _ = s.db.PolicyClient.DeleteSubjectConditionSet(s.ctx, id) } }) (or
use the existing deletion helper if present) so the helper cleans up its created
SubjectConditionSet rows automatically.
🪄 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: 1016e002-3fe0-4d39-a4d9-d8c50912bdc0
⛔ Files ignored due to path filters (1)
protocol/go/policy/subjectmapping/subject_mapping.pb.gois excluded by!**/*.pb.go
📒 Files selected for processing (10)
docs/grpc/index.htmldocs/openapi/policy/subjectmapping/subject_mapping.openapi.yamlservice/integration/subject_mappings_test.goservice/policy/db/queries/subject_mappings.sqlservice/policy/db/subject_mappings.goservice/policy/db/subject_mappings.sql.goservice/policy/db/utils.goservice/policy/db/utils_test.goservice/policy/subjectmapping/subject_condition_set_test.goservice/policy/subjectmapping/subject_mapping.proto
e9d1a0d to
b14043d
Compare
Benchmark results, click to expandBenchmark authorization.GetDecisions Results:
Benchmark authorization.v2.GetMultiResourceDecision Results:
Benchmark Statistics
Bulk Benchmark Results
TDF3 Benchmark Results:
|
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 `@service/policy/selectors.proto`:
- Around line 62-63: The inline comment for SORT_DIRECTION_UNSPECIFIED is
misleadingly absolute; update the comment for the enum value
SORT_DIRECTION_UNSPECIFIED in the SortDirection enum so it does not state an
unconditional default (e.g., change "// defaults to ASC" to a conditional
phrasing like "// treated as ASC when a sort field is provided; actual fallback
may be defined per-request" or remove the default note entirely), and ensure any
concrete defaulting behavior is documented on the request-level List* fields
rather than on the enum value.
🪄 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: 9db5b9a1-a41a-4812-b4af-e5d765d3bf25
⛔ Files ignored due to path filters (2)
protocol/go/policy/selectors.pb.gois excluded by!**/*.pb.goprotocol/go/policy/subjectmapping/subject_mapping.pb.gois excluded by!**/*.pb.go
📒 Files selected for processing (7)
docs/grpc/index.htmldocs/openapi/policy/attributes/attributes.openapi.yamldocs/openapi/policy/namespaces/namespaces.openapi.yamldocs/openapi/policy/selectors.openapi.yamldocs/openapi/policy/subjectmapping/subject_mapping.openapi.yamlservice/policy/selectors.protoservice/policy/subjectmapping/subject_mapping.proto
getSortDirection helper already added in listAttributes PR, will need to resolve conflicts when both merge. GetSubjectConditionSetSortParams helper added in utils.go. Wired sort params through DB layer, changed SQL, and regenerated sqlc
utils_test.go
added test in utils_test.go covering nil, empty, unspecified, created_at, updated_at with ASC/DESC. added sort validation cases to pre-existing ListSubjectConditionSetsRequest protovalidate tests (1 item valid, 2 items valid)
same with other APIs, this test gets a standalone function to deal with the 3 required tests for protovalidation
in subject_mappings_test.go (where the SCS integ. tests live), added a helper createSortTestSubjectConditionSets() for the 5 SCS sort tests: created_at ASC/DESC, updated_at ASC/DESC, and unspecified/falls to default. Only one helper needed because all tests are time-based.
SortDirection enum gets expanded comments for clarity, and ListSCSRequest in subject_mappings.proto gets comment clarifying how this endpoint handles defaults/unspecified.
test helper function for subject mappings (on main) and this branch were in the same spot and conflicting. this should keep both and resolve the issue. also regen protos which was conflicting as well
7a62e09 to
dc38494
Compare
Benchmark results, click to expandBenchmark authorization.GetDecisions Results:
Benchmark authorization.v2.GetMultiResourceDecision Results:
Benchmark Statistics
Bulk Benchmark Results
TDF3 Benchmark Results:
|
last PR (merged) introduced constants for created_at and updated_at (goconst was getting mad)
Benchmark results, click to expandBenchmark authorization.GetDecisions Results:
Benchmark authorization.v2.GetMultiResourceDecision Results:
Benchmark Statistics
Bulk Benchmark Results
TDF3 Benchmark Results:
|
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
service/policy/selectors.proto (1)
62-63:⚠️ Potential issue | 🟡 MinorRemove the stale unconditional default note on
SORT_DIRECTION_UNSPECIFIED.The new enum-level doc is endpoint-neutral, but the inline
// defaults to ASCstill reads as a global default and conflicts with the request-level fallback model described just above.Based on learnings: keep `SortDirection` endpoint-neutral and document concrete fallback/default ordering on request-level `List*` fields, not enum value docs.Suggested doc fix
- SORT_DIRECTION_UNSPECIFIED = 0; // defaults to ASC + SORT_DIRECTION_UNSPECIFIED = 0;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@service/policy/selectors.proto` around lines 62 - 63, Remove the stale inline note on SORT_DIRECTION_UNSPECIFIED in the SortDirection enum: delete the "// defaults to ASC" comment so the enum remains endpoint-neutral; instead ensure any concrete fallback/default ordering is documented on the request-level List* fields (e.g., ListPolicies, ListRules) where the endpoint-specific behavior is defined.service/integration/subject_mappings_test.go (1)
2713-2743:⚠️ Potential issue | 🟡 MinorClean up the helper-created subject condition sets.
This helper still leaves three unmapped rows behind on every call. Because the suite reuses one database across methods, those leftovers make later list/prune tests more order-dependent than they need to be.
Suggested cleanup registration
func (s *SubjectMappingsSuite) createSortTestSubjectConditionSets(label string) []string { const count = 3 ids := make([]string, count) + s.T().Cleanup(func() { + for _, id := range ids { + if id != "" { + _, _ = s.db.PolicyClient.DeleteSubjectConditionSet(s.ctx, id) + } + } + }) for i := range count { if i > 0 { time.Sleep(5 * time.Millisecond) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@service/integration/subject_mappings_test.go` around lines 2713 - 2743, createSortTestSubjectConditionSets currently leaves created SubjectConditionSet rows behind; after creating the IDs via s.db.PolicyClient.CreateSubjectConditionSet in createSortTestSubjectConditionSets, register cleanup to remove them (either immediately delete each created id or call s.T().Cleanup with a closure that iterates ids and calls s.db.PolicyClient.DeleteSubjectConditionSet(s.ctx, id) / appropriate delete method) so the test suite database is left clean; reference createSortTestSubjectConditionSets, s.db.PolicyClient.CreateSubjectConditionSet and the corresponding delete method (e.g., DeleteSubjectConditionSet) when implementing the teardown.
🤖 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_test.go`:
- Around line 519-584: Add a new test case to
Test_GetSubjectConditionSetsSortParams: include a cases entry for UPDATED_AT
with Direction policy.SortDirection_SORT_DIRECTION_ASC so the
SubjectConditionSetsSort mapping covers both ASC and DESC; specifically add a
slice element in the cases array that sets sort to
[]*subjectmapping.SubjectConditionSetsSort{{Field:
subjectmapping.SortSubjectConditionSetsType_SORT_SUBJECT_CONDITION_SETS_TYPE_UPDATED_AT,
Direction: policy.SortDirection_SORT_DIRECTION_ASC}} and expectedField
"updated_at" and expectedDir "ASC" to mirror the existing UPDATED_AT DESC case.
---
Duplicate comments:
In `@service/integration/subject_mappings_test.go`:
- Around line 2713-2743: createSortTestSubjectConditionSets currently leaves
created SubjectConditionSet rows behind; after creating the IDs via
s.db.PolicyClient.CreateSubjectConditionSet in
createSortTestSubjectConditionSets, register cleanup to remove them (either
immediately delete each created id or call s.T().Cleanup with a closure that
iterates ids and calls s.db.PolicyClient.DeleteSubjectConditionSet(s.ctx, id) /
appropriate delete method) so the test suite database is left clean; reference
createSortTestSubjectConditionSets, s.db.PolicyClient.CreateSubjectConditionSet
and the corresponding delete method (e.g., DeleteSubjectConditionSet) when
implementing the teardown.
In `@service/policy/selectors.proto`:
- Around line 62-63: Remove the stale inline note on SORT_DIRECTION_UNSPECIFIED
in the SortDirection enum: delete the "// defaults to ASC" comment so the enum
remains endpoint-neutral; instead ensure any concrete fallback/default ordering
is documented on the request-level List* fields (e.g., ListPolicies, ListRules)
where the endpoint-specific behavior is defined.
🪄 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: a4da4aba-ef6d-4fc3-aa43-fc102d23ac81
⛔ Files ignored due to path filters (2)
protocol/go/policy/selectors.pb.gois excluded by!**/*.pb.goprotocol/go/policy/subjectmapping/subject_mapping.pb.gois excluded by!**/*.pb.go
📒 Files selected for processing (14)
docs/grpc/index.htmldocs/openapi/policy/attributes/attributes.openapi.yamldocs/openapi/policy/namespaces/namespaces.openapi.yamldocs/openapi/policy/selectors.openapi.yamldocs/openapi/policy/subjectmapping/subject_mapping.openapi.yamlservice/integration/subject_mappings_test.goservice/policy/db/queries/subject_mappings.sqlservice/policy/db/subject_mappings.goservice/policy/db/subject_mappings.sql.goservice/policy/db/utils.goservice/policy/db/utils_test.goservice/policy/selectors.protoservice/policy/subjectmapping/subject_condition_set_test.goservice/policy/subjectmapping/subject_mapping.proto
updated_at ASC was missing, now there is full coverage
Benchmark results, click to expandBenchmark authorization.GetDecisions Results:
Benchmark authorization.v2.GetMultiResourceDecision Results:
Benchmark Statistics
Bulk Benchmark Results
TDF3 Benchmark Results:
|
|
Resolves DSPX-2686
Proposed Changes
ListSubjectConditionSetsRPC, following thepattern established in feat(policy): add sort support to ListAttributes API #3223 (ListAttributes) and feat(policy): add sort ListSubjectMappings API #3255 (ListSubjectMappings)
created_at,updated_at(ASC/DESC), withbackward-compatible fallback to
created_at DESCChanges
Proto —
service/policy/subjectmapping/subject_mapping.protoSortSubjectConditionSetsTypeenum (UNSPECIFIED,CREATED_AT,UPDATED_AT)SubjectConditionSetsSortmessage (field + direction)repeated SubjectConditionSetsSort sort = 11onListSubjectConditionSetsRequestwithmax_items = 1constraintSQL —
service/policy/db/queries/subject_mappings.sqllistSubjectConditionSetsqueryscs.created_at DESC+ tiebreakerscs.id ASCGo —
service/policy/db/utils.go+service/policy/db/subject_mappings.goGetSubjectConditionSetsSortParams(): maps enum to SQL-compatible field/directionstrings
ListSubjectConditionSetshandler wired to call mapper and pass params to sqlc queryTests
direction)
using
createSortTestSubjectConditionSetssuite helperTest_ListSubjectConditionSetsRequest_Sort)Notes
otdfctl --sortflag deferred to a follow-up, consistent with feat(policy): Add sort support to ListNamespaces API #3192, feat(policy): add sort support to ListAttributes API #3223, and feat(policy): add sort ListSubjectMappings API #3255Checklist
Testing Instructions
Summary by CodeRabbit
New Features
Documentation
Tests