feat(api): standardize query params to snake_case#110
Conversation
Migrate all 18 multi-word query parameter names from camelCase to snake_case across 4 list endpoints (rules, limits, audit-events, transaction-validations), aligning with Lerian API conventions already followed by Midaz and Matcher. Changes: - Struct tags: query:"sortBy" -> query:"sort_by" (18 params) - Sort field values: createdAt -> created_at (5 values) - Validation whitelists updated (HTTP + model layers) - Repository sort mappers updated (4 repos) - Cursor functions updated for snake_case sort fields - Swagger @param annotations + regenerated docs - OpenAPI spec updated - Error messages use snake_case for query param references - All unit, integration, and E2E tests updated Bonus fixes (beyond migration scope): - Added missing WEEKLY/CUSTOM to limit_type Swagger enum - Added missing Enums() to transaction_type in audit handler - Fixed "end_date must be after" -> "must be on or after" wording Breaking change: camelCase query params no longer accepted. No clients in production — coordinated deploy with console.
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughRenamed many API query parameters from camelCase to snake_case across OpenAPI/Swagger specs, handler annotations, HTTP input tags, validators, models, repository sort handling, services, and tests; adjusted sort-field enums/defaults and expanded limit/transaction-type enums; updated cursor/sort parsing to use snake_case. Changes
Comment |
📊 Unit Test Coverage Report:
|
| Metric | Value |
|---|---|
| Overall Coverage | 82.9% |
| Threshold | 85% |
Coverage by Package
| Package | Coverage |
|---|---|
tracer/internal/adapters/cel |
81.9% |
tracer/internal/adapters/http/in/middleware |
55.1% |
tracer/internal/adapters/http/in |
81.8% |
tracer/internal/adapters/postgres/db |
50.0% |
tracer/internal/adapters/postgres |
77.2% |
tracer/internal/services/cache |
95.6% |
tracer/internal/services/command |
78.9% |
tracer/internal/services/query |
79.8% |
tracer/internal/services/workers |
80.1% |
tracer/internal/services |
47.4% |
tracer/internal/testhelper |
0.0% |
tracer/pkg/clock |
50.0% |
tracer/pkg/contextutil |
100.0% |
tracer/pkg/hash |
100.0% |
tracer/pkg/logging |
100.0% |
tracer/pkg/migration |
89.0% |
tracer/pkg/model |
95.0% |
tracer/pkg/net/http |
88.3% |
tracer/pkg/resilience |
97.8% |
tracer/pkg/sanitize |
87.1% |
tracer/pkg/validation |
50.0% |
tracer/pkg |
96.6% |
Generated by Go PR Analysis workflow
🔒 Security Scan Results —
|
| Severity | Library | Vulnerability | Installed | Fixed | Title |
|---|---|---|---|---|---|
| 🟠 HIGH | go.opentelemetry.io/otel/sdk |
CVE-2026-39883 | v1.42.0 | 1.43.0 | opentelemetry-go: BSD kenv command not using absolute pat... |
Docker Image Scan
| Severity | Vulnerability | Title |
|---|---|---|
| CRITICAL/HIGH | CVE-2026-39883 | opentelemetry-go: BSD kenv command not using absolute path enables PATH hijac... |
Docker Hub Health Score Compliance
⚠️ Policies — 3/4 met
| Policy | Status |
|---|---|
| Default non-root user | ✅ Passed |
| No fixable critical/high CVEs | |
| No high-profile vulnerabilities | ✅ Passed |
| No AGPL v3 licenses | ✅ Passed |
⚠️ Some Docker Hub health score policies are not met. Review the table above.
There was a problem hiding this comment.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
tests/integration/07_audit_events_test.go (1)
1453-1464:⚠️ Potential issue | 🟡 MinorFail fast on request/response errors in this updated query path.
This block still drops the
http.NewRequestand JSON decode errors, and it never assertsauditResp.StatusCode. With the query-param rename, a malformed request or 4xx response will show up later as a misleading “no events found” failure instead of the real cause.🔧 Tighten the assertions in this block
url := fmt.Sprintf("%s/v1/audit-events?event_type=TRANSACTION_VALIDATED&account_id=%s", baseURL, accountID) -auditReq, _ := http.NewRequest(http.MethodGet, url, nil) +auditReq, err := http.NewRequest(http.MethodGet, url, nil) +require.NoError(t, err) auditReq.Header.Set("X-API-Key", apiKey) auditResp, err := testutil.HTTPClient.Do(auditReq) require.NoError(t, err) defer auditResp.Body.Close() +require.Equal(t, http.StatusOK, auditResp.StatusCode) var auditResult struct { AuditEvents []map[string]any `json:"auditEvents"` } -json.NewDecoder(auditResp.Body).Decode(&auditResult) +err = json.NewDecoder(auditResp.Body).Decode(&auditResult) +require.NoError(t, err)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/integration/07_audit_events_test.go` around lines 1453 - 1464, The test currently ignores errors from http.NewRequest and json.Unmarshal and doesn't assert the HTTP status, which can hide request/response failures; update the audit query block to check and require no error from http.NewRequest when creating auditReq, assert auditResp.StatusCode is the expected 200 (or expected success code) after the Do call, and require.NoError on json.NewDecoder(auditResp.Body).Decode(&auditResult) so failures surface immediately (referencing auditReq, auditResp, and the json.Decode call to locate the lines to change).internal/adapters/postgres/limit_repository.go (1)
56-72: 🧹 Nitpick | 🔵 TrivialMake the sort-field whitelist immutable.
This package-level map can be mutated by any file in
internal/adapters/postgres, which means the ORDER BY allowlist and cursor validation behavior can change at runtime or leak between tests.rule_repository.goalready uses a switch for the same mapping; mirroring that here keeps the whitelist read-only.♻️ Suggested refactor
-// limitSortFieldToColumn maps API snake_case sort fields to database column names. -var limitSortFieldToColumn = map[string]string{ - "created_at": "created_at", - "updated_at": "updated_at", - "max_amount": "max_amount", - "name": "name", -} - // mapLimitSortFieldToColumn converts a sort field to its database column name. // Returns the column name if valid, otherwise returns empty string. func mapLimitSortFieldToColumn(sortField string) string { - if col, ok := limitSortFieldToColumn[sortField]; ok { - return col - } - - return "" + switch sortField { + case "created_at": + return "created_at" + case "updated_at": + return "updated_at" + case "max_amount": + return "max_amount" + case "name": + return "name" + default: + return "" + } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/adapters/postgres/limit_repository.go` around lines 56 - 72, The package-level mutable map limitSortFieldToColumn allows external mutation; replace map-based lookup in mapLimitSortFieldToColumn with a switch-based whitelist (like rule_repository.go) so the allowed sort fields are hard-coded and immutable at runtime; update mapLimitSortFieldToColumn to return the appropriate column names via a switch on sortField ("created_at", "updated_at", "max_amount", "name") and remove or make the map private/unreferenced to prevent tests or other files from mutating the allowlist.internal/adapters/http/in/transaction_validation_handler.go (1)
225-378: 🛠️ Refactor suggestion | 🟠 MajorMove this input validation block into a
*_validation.gofile.This PR expands the validation surface, but
ListTransactionValidationsInputplusValidate/SetDefaultsstill live intransaction_validation_handler.go. Keeping that logic beside the other adapter validation files will make this handler easier to maintain.As per coding guidelines, "Put input validation logic in separate
*_validation.gofiles".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/adapters/http/in/transaction_validation_handler.go` around lines 225 - 378, Extract the entire ListTransactionValidationsInput type and all related validation functions (SetDefaults, Validate, validateDecision, validateDates, validateUUIDFilters, validateTransactionType and the helper validateUUID) into a new *_validation.go file (e.g., transaction_validation_validation.go) within the same package; remove them from transaction_validation_handler.go; ensure the new file imports the same dependencies (uuid, fmt, errors, validation, model, ValidationError type) and preserves identical signatures so existing references to ListTransactionValidationsInput and its methods continue to compile.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@internal/adapters/http/in/audit_event_handler.go`:
- Around line 61-66: Swagger parameter annotations in audit_event_handler.go
wrongly mark resource_id, segment_id, and portfolio_id as Format(uuid) which
conflicts with existing fixture values like "txn-12345", "seg-001", and
"port-001"; update the comment annotations for the parameters (resource_id,
segment_id, portfolio_id) in the audit event handler’s Swagger block to remove
the Format(uuid) qualifier (leave them as plain string query params or document
a relaxed pattern) so the generated OpenAPI contract accepts the actual non-UUID
values.
In `@internal/adapters/http/in/audit_event_validation.go`:
- Around line 159-182: Remove the ",omitempty" suffix from the query struct tags
on the audit query fields so they match other adapters; update the tags for
StartDate, EndDate, EventType, Action, Result, ResourceType, ResourceID,
ActorType, ActorID, AccountID, SegmentID, PortfolioID, TransactionType,
MatchedRuleID, Limit, Cursor, SortBy and SortOrder by replacing
query:"field_name,omitempty" with query:"field_name" in the validation struct
(the one containing those fields) so Fiber v2 parsing and project conventions
remain consistent.
In `@internal/adapters/http/in/limit_handler_test.go`:
- Line 607: Tests in limit_handler_test.go expect snake_case field names
("account_id", "transaction_type") but the validator helper
formatLimitScopeFieldError (which calls toLimitScopeJSONFieldName) returns
camelCase ("accountId", "transactionType"); update the test expectations to
match the actual output by changing the asserted field names in the failing
cases to "accountId" and "transactionType" (or alternatively change
toLimitScopeJSONFieldName/formatLimitScopeFieldError to return snake_case if you
prefer that behavior) so the assertions align with the validator's actual error
strings.
In `@internal/adapters/http/in/query_params_snake_case_test.go`:
- Around line 133-159: The test only covers camelCase rejection for
ListRulesInput; add equivalent negative tests for ListLimitsInput,
ListAuditEventsInput, and ListTransactionValidationsInput similar to
TestListRulesInput_CamelCaseIgnored: for each input type create a test (e.g.,
TestListLimitsInput_CamelCaseIgnored, TestListAuditEventsInput_CamelCaseIgnored,
TestListTransactionValidationsInput_CamelCaseIgnored) that mounts a fiber GET
handler using c.QueryParser(&input), issues an httptest request with legacy
camelCase query params (e.g., sortBy, sortOrder, accountId or other relevant
camelCase params used by that input), decodes the JSON response into a
map[string]interface{} and asserts camelCase-derived keys (like "SortBy",
"SortOrder", "AccountID" or the specific exported field names for that input)
are empty or nil to ensure camelCase params are ignored after the snake_case
migration.
In `@internal/adapters/postgres/audit_event_repository_test.go`:
- Around line 1087-1100: The tests currently assert that unknown or legacy sort
keys (the cases named "unknown field falls back to created_at", "camelCase
createdAt is rejected and falls back to default", and "camelCase eventType is
rejected and falls back to default") silently fall back to "created_at"; instead
update these test cases to expect the repository to reject invalid sortBy values
via the sort allowlist (i.e., assert an error/validation failure or that the
cursor construction fails) rather than remapping to "created_at". Locate the
tests by the sortBy variable values ("unknown_field", "createdAt", "eventType")
and update their expected outcomes accordingly, and apply the same change to the
similar cases at the other occurrence (lines referenced 1137-1145).
In `@internal/adapters/postgres/limit_repository_test.go`:
- Around line 2024-2048: The test TestGetSortValueFromLimit_SnakeCase currently
uses assert.NotEmpty which can pass when getSortValueFromLimit falls back to
created_at; update the test to assert the exact expected sort value for each
case by calling getSortValueFromLimit(lmt, tt.sortBy) and comparing it to the
precise value you expect (e.g., the created_at/updated_at/max_amount/name values
derived from testLimit()), or alternatively consolidate these cases into
TestGetSortValueFromLimit to reuse its explicit expected-value assertions;
reference TestGetSortValueFromLimit_SnakeCase, getSortValueFromLimit, and
testLimit when making the change.
In `@tests/integration/02_rules_scope_filter_test.go`:
- Around line 305-334: The test expectations use snake_case field names but the
validation formatter function toScopeJSONFieldName returns camelCase names;
update the failing test cases (the table entries with expectMsg "account_id",
"segment_id", "portfolio_id", "merchant_id", "transaction_type") to use the
camelCase names ("accountId", "segmentId", "portfolioId", "merchantId",
"transactionType") so the tests match the output of toScopeJSONFieldName, or
alternatively change toScopeJSONFieldName to emit snake_case if you prefer that
canonical format (ensure any other callers are updated accordingly).
---
Outside diff comments:
In `@internal/adapters/http/in/transaction_validation_handler.go`:
- Around line 225-378: Extract the entire ListTransactionValidationsInput type
and all related validation functions (SetDefaults, Validate, validateDecision,
validateDates, validateUUIDFilters, validateTransactionType and the helper
validateUUID) into a new *_validation.go file (e.g.,
transaction_validation_validation.go) within the same package; remove them from
transaction_validation_handler.go; ensure the new file imports the same
dependencies (uuid, fmt, errors, validation, model, ValidationError type) and
preserves identical signatures so existing references to
ListTransactionValidationsInput and its methods continue to compile.
In `@internal/adapters/postgres/limit_repository.go`:
- Around line 56-72: The package-level mutable map limitSortFieldToColumn allows
external mutation; replace map-based lookup in mapLimitSortFieldToColumn with a
switch-based whitelist (like rule_repository.go) so the allowed sort fields are
hard-coded and immutable at runtime; update mapLimitSortFieldToColumn to return
the appropriate column names via a switch on sortField ("created_at",
"updated_at", "max_amount", "name") and remove or make the map
private/unreferenced to prevent tests or other files from mutating the
allowlist.
In `@tests/integration/07_audit_events_test.go`:
- Around line 1453-1464: The test currently ignores errors from http.NewRequest
and json.Unmarshal and doesn't assert the HTTP status, which can hide
request/response failures; update the audit query block to check and require no
error from http.NewRequest when creating auditReq, assert auditResp.StatusCode
is the expected 200 (or expected success code) after the Do call, and
require.NoError on json.NewDecoder(auditResp.Body).Decode(&auditResult) so
failures surface immediately (referencing auditReq, auditResp, and the
json.Decode call to locate the lines to 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: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: bc5833de-93f2-42d1-b282-c81d02490252
📒 Files selected for processing (51)
api/docs.goapi/openapi.yamlapi/swagger.jsonapi/swagger.yamlinternal/adapters/http/in/audit_event_handler.gointernal/adapters/http/in/audit_event_handler_test.gointernal/adapters/http/in/audit_event_validation.gointernal/adapters/http/in/limit_handler.gointernal/adapters/http/in/limit_handler_test.gointernal/adapters/http/in/limit_validation.gointernal/adapters/http/in/limit_validation_test.gointernal/adapters/http/in/pagination_validation.gointernal/adapters/http/in/pagination_validation_test.gointernal/adapters/http/in/query_params_snake_case_test.gointernal/adapters/http/in/rule_handler.gointernal/adapters/http/in/rule_handler_test.gointernal/adapters/http/in/rule_validation.gointernal/adapters/http/in/rule_validation_test.gointernal/adapters/http/in/transaction_validation_handler.gointernal/adapters/http/in/transaction_validation_handler_test.gointernal/adapters/postgres/audit_event_repository.gointernal/adapters/postgres/audit_event_repository_test.gointernal/adapters/postgres/limit_repository.gointernal/adapters/postgres/limit_repository_test.gointernal/adapters/postgres/rule_repository.gointernal/adapters/postgres/rule_repository_test.gointernal/adapters/postgres/transaction_validation_repository.gointernal/adapters/postgres/transaction_validation_repository_test.gointernal/services/query/list_limits_test.gointernal/services/query/list_rules.gointernal/services/query/list_rules_test.gointernal/services/query/list_transaction_validations_test.gopkg/model/audit_event_filters.gopkg/model/audit_event_filters_test.gopkg/model/limit.gopkg/model/limit_test.gopkg/model/rule_test.gopkg/model/transaction_validation_filters.gopkg/model/transaction_validation_filters_test.gopkg/validation/datetime_test.gotests/end2end/steps/audit_steps.gotests/end2end/support/client.gotests/integration/01_validation_get_error_codes_test.gotests/integration/01_validation_test.gotests/integration/02_rules_error_codes_test.gotests/integration/02_rules_management_test.gotests/integration/02_rules_scope_filter_test.gotests/integration/03_limits_management_test.gotests/integration/04_limits_scope_filter_test.gotests/integration/07_audit_events_error_codes_test.gotests/integration/07_audit_events_test.go
- Remove Format(uuid) from resource_id Swagger annotation (string field) - Change mapSortField default from "created_at" to "" (align with other repos) - Add camelCase rejection tests for limits, audit-events, and validations - Use exact value assertions in TestGetSortValueFromLimit_SnakeCase
Re: Security Scan — CVE-2026-39883The Root cause: Resolution path: Dependabot has already opened PRs in
Once these are merged and a new Action: Awaiting |
There was a problem hiding this comment.
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 `@internal/adapters/http/in/query_params_snake_case_test.go`:
- Around line 178-179: The test currently ignores JSON decode errors when
calling json.NewDecoder(resp.Body).Decode(&result), which can mask failures;
update the tests (the uses of variable result and the Decode call) to capture
the returned error and assert it succeeds (e.g., require.NoError(t, err) or
assert.NoError) immediately after Decode so the test fails if the response body
is not valid JSON. Ensure you apply this change to all three occurrences around
the Decode calls in query_params_snake_case_test.go.
- Around line 18-19: Remove the "Task 9:" prefix from the test comment and
rewrite it to state the intent directly — e.g., "Tests that verify snake_case
query parameters are bound correctly by Fiber's QueryParser; these tests
exercise struct tags via Fiber's query binding." Update the comment in
query_params_snake_case_test.go to be self-explanatory and avoid any task/ticket
references.
In `@internal/adapters/postgres/limit_repository_test.go`:
- Around line 1994-1997: Remove the transient "Task 5:" prefix from the section
header so it reads only "snake_case migration tests for limitSortFieldToColumn,
getSortValueFromLimit, and validateCursorSortValue"; locate the header above the
tests that reference the functions limitSortFieldToColumn,
getSortValueFromLimit, and validateCursorSortValue and update the comment
line(s) to a plain, intent-focused header without any task or ticket id.
🪄 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: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 57796018-9884-40b5-9b91-6fd9cbe6fc7b
📒 Files selected for processing (9)
api/docs.goapi/openapi.yamlapi/swagger.jsonapi/swagger.yamlinternal/adapters/http/in/audit_event_handler.gointernal/adapters/http/in/query_params_snake_case_test.gointernal/adapters/postgres/audit_event_repository.gointernal/adapters/postgres/audit_event_repository_test.gointernal/adapters/postgres/limit_repository_test.go
- Remove task ID references from test comments (Task 5, Task 9) - Add require.NoError on JSON decode in camelCase rejection tests
There was a problem hiding this comment.
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 `@internal/adapters/http/in/query_params_snake_case_test.go`:
- Around line 133-237: Combine the four duplicate tests
(TestListRulesInput_CamelCaseIgnored, TestListLimitsInput_CamelCaseIgnored,
TestListAuditEventsInput_CamelCaseIgnored,
TestListTransactionValidationsInput_CamelCaseIgnored) into a single table-driven
test (e.g., TestCamelCaseParamsIgnored) that iterates cases containing: a
descriptive name, the input struct type to bind (ListRulesInput,
ListLimitsInput, ListAuditEventsInput, ListTransactionValidationsInput), the
request URL/query string to send, and the list of expected fields that should
remain unset; for each case spin up the same Fiber handler that does var input
<type>; c.QueryParser(&input); return c.JSON(input), call app.Test with the case
URL, decode response into map[string]interface{}, and assert the specified keys
are empty or nil; preserve descriptive case names and avoid using uuid.New() or
time.Now() in test data (use fixed literals as in the current tests).
- Around line 239-274: The tests only assert that snake_case sort fields are
accepted; add negative tests to ensure legacy camelCase names are rejected by
Validate() to prevent regressions. For each existing positive test
(TestListRulesInput_SnakeCaseSortByValidation,
TestListLimitsInput_SnakeCaseSortByValidation,
TestListAuditEventsInput_SnakeCaseSortByValidation,
TestListTransactionValidationsInput_SnakeCaseSortByValidation) add a
corresponding case passing the legacy camelCase sort key (e.g., "createdAt",
"maxAmount", "eventType", "processingTimeMs") into the same input types
(ListRulesInput, ListLimitsInput, ListAuditEventsInput,
ListTransactionValidationsInput) and assert that input.Validate() returns an
error (use assert.Error or equivalent) so validation explicitly rejects those
legacy names.
In `@internal/adapters/postgres/limit_repository_test.go`:
- Around line 2024-2046: TestGetSortValueFromLimit_SnakeCase duplicates
assertions already covered by TestGetSortValueFromLimit for the same sort keys;
merge them into a single table-driven test to avoid duplication and drift by
consolidating both test cases into one test (e.g., combine
TestGetSortValueFromLimit_SnakeCase into TestGetSortValueFromLimit) that
iterates over the same entries and calls getSortValueFromLimit with the
testLimit() fixture, ensuring expected values use
lmt.CreatedAt.Format(time.RFC3339Nano), lmt.UpdatedAt.Format(time.RFC3339Nano),
lmt.MaxAmount.String(), and lmt.Name so all sort-key permutations are validated
in one place.
🪄 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: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: be552fad-705b-464a-a514-0a4f433bd383
📒 Files selected for processing (2)
internal/adapters/http/in/query_params_snake_case_test.gointernal/adapters/postgres/limit_repository_test.go
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
internal/adapters/postgres/limit_repository.go (1)
457-487: 🧹 Nitpick | 🔵 TrivialKeep cursor/request sort comparison at the same abstraction level.
cursor.SortByis still the API-facing sort token, butrequestedSortByhas already been converted to a DB column name. The comparison works only because the mapping is currently identity. If one API field ever stops matching its column name, pagination will start rejecting valid cursors. Compare API fields to API fields (or mapped columns to mapped columns) consistently here.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/adapters/postgres/limit_repository.go` around lines 457 - 487, The cursor vs request sort comparison mixes abstractions: cursor.SortBy is an API-facing token while requestedSortBy has been converted to a DB column; make the comparison at the same abstraction level by converting requestedSortBy back to an API field (or converting both to DB columns consistently). Update the mismatch check to compare cursor.SortBy to the API-facing requested sort (e.g., mappedRequestedSortField obtained via a reverse helper like mapLimitColumnToField or an explicit reverse map), and compare orderDir and requestedOrderDir after normalizing case (strings.ToUpper) so both checks use the same representation (use identifiers cursor.SortBy, requestedSortBy, sortColumn, mapLimitSortFieldToColumn, mapLimitColumnToField, orderDir, requestedOrderDir).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@internal/adapters/http/in/query_params_snake_case_test.go`:
- Around line 133-237: The tests (TestListRulesInput_CamelCaseIgnored,
TestListLimitsInput_CamelCaseIgnored, TestListAuditEventsInput_CamelCaseIgnored,
TestListTransactionValidationsInput_CamelCaseIgnored) currently assert the JSON
map which can be affected by struct json/omitempty behavior; change each test to
decode the response body into the concrete input struct used in the handler
(ListRulesInput, ListLimitsInput, ListAuditEventsInput,
ListTransactionValidationsInput) or capture the bound struct directly from the
handler, then assert the struct fields are zero-valued (empty string or nil as
appropriate) to prove c.QueryParser ignored camelCase keys; keep the same
request URLs and assertions about specific fields (e.g., SortBy, SortOrder,
AccountID, LimitType, StartDate, EventType) but target the concrete struct
fields rather than a map[string]interface{}.
In `@internal/adapters/postgres/audit_event_repository.go`:
- Around line 578-586: mapSortField currently returns an empty string for
unmapped fields which can produce malformed SQL; change its signature from
mapSortField(field string) string to mapSortField(field string) (string, error)
and return a clear validation error for unknown fields (e.g.,
fmt.Errorf("invalid sort field: %s", field)). Update all callers in
AuditEventRepository that rely on mapSortField (cursor encoding and query
builder paths) to handle the error: validate sortBy via mapSortField before
building the ORDER BY or encoding the cursor and propagate/return the
invalid-sort error to the caller instead of proceeding with an empty mapping.
In `@tests/integration/01_validation_get_error_codes_test.go`:
- Around line 551-555: Update the stale expectation in the test case named
"startDate-after-endDate": change the wantMsg field from "start_date must be
before or equal to end_date" to the corrected message "end_date must be on or
after start_date" so the test matches the new validation wording; locate the
test case by its name and modify the wantMsg string accordingly.
---
Outside diff comments:
In `@internal/adapters/postgres/limit_repository.go`:
- Around line 457-487: The cursor vs request sort comparison mixes abstractions:
cursor.SortBy is an API-facing token while requestedSortBy has been converted to
a DB column; make the comparison at the same abstraction level by converting
requestedSortBy back to an API field (or converting both to DB columns
consistently). Update the mismatch check to compare cursor.SortBy to the
API-facing requested sort (e.g., mappedRequestedSortField obtained via a reverse
helper like mapLimitColumnToField or an explicit reverse map), and compare
orderDir and requestedOrderDir after normalizing case (strings.ToUpper) so both
checks use the same representation (use identifiers cursor.SortBy,
requestedSortBy, sortColumn, mapLimitSortFieldToColumn, mapLimitColumnToField,
orderDir, requestedOrderDir).
🪄 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: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: e358fe47-66ad-4214-8dc0-d0c9205b6ccf
📒 Files selected for processing (51)
api/docs.goapi/openapi.yamlapi/swagger.jsonapi/swagger.yamlinternal/adapters/http/in/audit_event_handler.gointernal/adapters/http/in/audit_event_handler_test.gointernal/adapters/http/in/audit_event_validation.gointernal/adapters/http/in/limit_handler.gointernal/adapters/http/in/limit_handler_test.gointernal/adapters/http/in/limit_validation.gointernal/adapters/http/in/limit_validation_test.gointernal/adapters/http/in/pagination_validation.gointernal/adapters/http/in/pagination_validation_test.gointernal/adapters/http/in/query_params_snake_case_test.gointernal/adapters/http/in/rule_handler.gointernal/adapters/http/in/rule_handler_test.gointernal/adapters/http/in/rule_validation.gointernal/adapters/http/in/rule_validation_test.gointernal/adapters/http/in/transaction_validation_handler.gointernal/adapters/http/in/transaction_validation_handler_test.gointernal/adapters/postgres/audit_event_repository.gointernal/adapters/postgres/audit_event_repository_test.gointernal/adapters/postgres/limit_repository.gointernal/adapters/postgres/limit_repository_test.gointernal/adapters/postgres/rule_repository.gointernal/adapters/postgres/rule_repository_test.gointernal/adapters/postgres/transaction_validation_repository.gointernal/adapters/postgres/transaction_validation_repository_test.gointernal/services/query/list_limits_test.gointernal/services/query/list_rules.gointernal/services/query/list_rules_test.gointernal/services/query/list_transaction_validations_test.gopkg/model/audit_event_filters.gopkg/model/audit_event_filters_test.gopkg/model/limit.gopkg/model/limit_test.gopkg/model/rule_test.gopkg/model/transaction_validation_filters.gopkg/model/transaction_validation_filters_test.gopkg/validation/datetime_test.gotests/end2end/steps/audit_steps.gotests/end2end/support/client.gotests/integration/01_validation_get_error_codes_test.gotests/integration/01_validation_test.gotests/integration/02_rules_error_codes_test.gotests/integration/02_rules_management_test.gotests/integration/02_rules_scope_filter_test.gotests/integration/03_limits_management_test.gotests/integration/04_limits_scope_filter_test.gotests/integration/07_audit_events_error_codes_test.gotests/integration/07_audit_events_test.go
gandalf-at-lerian
left a comment
There was a problem hiding this comment.
Good PR — well-scoped, consistent migration across all 4 list endpoints. Tests are solid, especially the new query_params_snake_case_test.go that validates Fiber binding directly. A few things:
Bug — inconsistent error message in limit_handler.go:678
The handler error translation still says:
"limitType must be one of [DAILY, WEEKLY, MONTHLY, CUSTOM, PER_TRANSACTION]"
But the query param is now limit_type. The validation layer (limit_validation.go) was correctly updated to limit_type must be one of..., but this handler-level message was missed. Should be limit_type for consistency.
Minor — resource_id lost UUID format in Swagger docs
Old: resourceId had Format(uuid) in the swagger annotation + description said "(UUID)".
New: resource_id has neither — description just says "Filter by resource ID" and no Format annotation.
The struct validation still has validate:"omitempty,uuid" so it's enforced server-side, but the OpenAPI spec no longer documents the UUID constraint. If this was intentional (maybe resource_id can be non-UUID in some contexts), ignore. If not, add back the Format(uuid) annotation.
Everything else is clean — struct tags, sort field whitelists, repository mappers, cursor encoding, error messages, swagger generated docs all align. The bonus fixes (WEEKLY/CUSTOM enum, transaction_type enum on audit handler, "must be on or after" wording) are good catches.
Carlao-LERIAN
left a comment
There was a problem hiding this comment.
Thanks for the review, Gandalf! Addressing both points:
1. limitType error message in limit_handler.go:681
This is intentionally limitType (camelCase). This error path handles POST/PATCH body validation via ErrLimitInvalidType from Limit.Validate() — the JSON body field is "limitType" (camelCase per Lerian convention). The query param validation in limit_validation.go:241 correctly uses "limit_type" (snake_case). Two different error paths, two correct casing conventions.
To verify: ErrLimitInvalidType is returned by model.Limit.Validate() (domain entity, called on create/update), not by query param parsing.
2. resource_id lost Format(uuid)
Intentional — addressed in commit 0da6c66 per CodeRabbit finding. The resource_id field is typed as string in pkg/model/audit_event.go:171 and while all current values happen to be UUIDs (rule/limit/transaction IDs), the OpenAPI spec was over-constraining by declaring Format(uuid). Server-side validation still enforces UUID via validate:"omitempty,uuid" struct tag. If we want to re-add the OpenAPI constraint, we can — but it was a deliberate relaxation to match the domain model type.
If you prefer Format(uuid) back for documentation accuracy (since server validates UUID anyway), happy to re-add it.
Carlao-LERIAN
left a comment
There was a problem hiding this comment.
Good catch on pushing back, but after tracing the code I can confirm the handler is correct:
Two separate error constants:
ErrLimitInvalidType(TRC-0122) — raised bymodel.Limit.Validate()atlimit.go:728→ body validation (POST/PATCH). JSON field =limitTypeErrLimitInvalidTypeFilter(TRC-0134) — raised byListLimitsFilter.Validate()atlimit.go:927→ query param validation (GET). Query param =limit_type
Handler at line 678 only catches TRC-0122 (ErrLimitInvalidType). The query param error TRC-0134 (ErrLimitInvalidTypeFilter) is handled by the validation layer in limit_validation.go:241 which already returns "limit_type must be one of [DAILY WEEKLY MONTHLY CUSTOM PER_TRANSACTION]" (snake_case).
grep -n "ErrLimitInvalidTypeFilter" internal/adapters/http/in/limit_handler.go returns empty — the handler never sees the query param error.
So "limitType" at line 681 is correct — it refers to the JSON body field name.
gandalf-at-lerian
left a comment
There was a problem hiding this comment.
Approved. All snake_case changes are consistent across handlers, models, and tests. The two points I initially flagged (limitType in error message and Format(uuid) removal) are both correct by design — limitType refers to the JSON body field (camelCase per convention), and relaxing Format(uuid) on resource_id aligns the OpenAPI spec with the domain model type (string) while server-side validation still enforces UUID via struct tags. Well-structured PR — 51 files, clean test coverage, breaking change properly documented.
…ion_type, date range) Unit tests: - WEEKLY/CUSTOM limit_type validation in CreateLimitInput and ListLimitsInput - transaction_type enum validation for audit events (valid + invalid) - Date range validation (start < end, same date, start > end) Integration tests: - Filter limits by WEEKLY and CUSTOM limit_type - Invalid transaction_type on audit events endpoint returns error - Cross-endpoint date range validation consistency (audit-events + validations) Handler tests: - limit_type=WEEKLY and limit_type=CUSTOM pass filter to service - transaction_type filter propagation in audit event handler - Invalid transaction_type returns 400
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@internal/adapters/http/in/audit_event_handler_test.go`:
- Around line 388-434: Update TestListAuditEventsInput_DateRangeValidation to
assert the specific validation error code "TRC-0023" when tt.wantErr is true:
after calling ListAuditEventsInput.Validate(), require.Error(t, err) and then
either use errors.As / a type assertion to extract the project's error type (the
error returned by ListAuditEventsInput.Validate()) and assert the error's Code()
(or equivalent field) equals "TRC-0023", rather than only matching the error
message; keep the existing message containment check if desired but make the
code equality check the authoritative assertion.
- Around line 337-358: The test
TestAuditEventHandler_ListAuditEvents_InvalidTransactionType currently only
checks for a non-empty 400 body, which is too weak; update the test for
handler.ListAuditEvents to assert the exact error payload/fields returned (e.g.
JSON error code, message or validation field) when transaction_type is invalid —
parse resp.Body as JSON and assert specific values such as an "error" or
"message" string containing "invalid transaction_type" or a specific error
code/field name expected by your API contract to ensure regressions in error
mapping are caught.
In `@internal/adapters/http/in/limit_handler_test.go`:
- Around line 654-660: The test currently uses assert.Len before indexing the
slice response.Limits inside the expectedBody closure (variable
ListLimitsResponse) which can panic if the length is wrong; change assert.Len to
require.Len in that closure and in the other occurrence around lines 687-693 so
the test fails immediately on length mismatch before the code indexes
response.Limits[0], referencing the expectedBody function and the
ListLimitsResponse/response.Limits slice when making the replacement.
In `@tests/integration/03_limits_management_test.go`:
- Around line 975-1035: The test TestLimits_ListLimits_FilterByWeeklyType
currently only asserts that every returned item has LimitType "WEEKLY" but
doesn't verify the created limit is included; update the test to assert the
created limit (use createdLimit.ID or createdLimit.Name from the createdLimit
variable) appears in listResult.Limits (e.g., scan listResult.Limits for a
matching ID/Name and require it was found), and mirror the same change in the
other test that creates a CUSTOM limit (use its createdLimit identifier) so both
tests confirm the created record survived the filter rather than just validating
the type.
In `@tests/integration/07_audit_events_error_codes_test.go`:
- Around line 699-709: The test currently only checks for any 400 with non-empty
error fields; update the assertions in
tests/integration/07_audit_events_error_codes_test.go (inside the loop that
checks endpoints using ep.name and errResp) to explicitly require
errResp["code"] == "TRC-0023" (and keep the existing message assertion),
replacing the generic assert.NotEmpty on errResp["code"] with an equality check
so both endpoints must return the specific date-range error code "TRC-0023".
🪄 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: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 5c0d52ed-f467-48ac-a9ae-d49d541664c0
📒 Files selected for processing (5)
internal/adapters/http/in/audit_event_handler_test.gointernal/adapters/http/in/limit_handler_test.gointernal/adapters/http/in/limit_validation_test.gotests/integration/03_limits_management_test.gotests/integration/07_audit_events_error_codes_test.go
- Add require.NotEmpty before iterating Limits in WEEKLY/CUSTOM filter tests - Use past dates in cross-endpoint date range test (avoid future date validators) - Replace weak NotEmpty assertions with exact per-endpoint code/message checks
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 `@tests/integration/07_audit_events_error_codes_test.go`:
- Line 588: Replace the unordered assertion helper with the required ordered
assertion helper: change calls using assert.Equal that check ordered HTTP
responses (e.g., the assertion comparing resp.StatusCode and the response body
like the line asserting "assert.Equal(t, http.StatusOK, resp.StatusCode, ... ,
string(respBody))" and the other occurrences referenced around the sort_by
checks) to use require.Equal instead; update the imports if necessary to use
require from the testify/require package and ensure the tests fail fast on
mismatch for the ordered content checks at those locations (also apply the same
replace for the other mentioned occurrences at the same pattern).
🪄 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: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 1f49fb2c-ec90-44b3-9ff3-a1e880e179fd
📒 Files selected for processing (2)
tests/integration/03_limits_management_test.gotests/integration/07_audit_events_error_codes_test.go
Changed transaction_validation_handler.go:345 from "start_date must be before or equal to end_date" to "end_date must be on or after start_date" for consistency with audit_event_validation.go and both model-layer validators.
…tion tests Fail-fast on status code mismatches instead of continuing with invalid response body assertions.
- Assert TRC-0001 error code in invalid transaction_type handler test - Assert TRC-0023 error code in date range validation test - Use require.Len before indexing slices (panic prevention) - Verify created limit ID appears in WEEKLY/CUSTOM filter results
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
internal/adapters/http/in/audit_event_handler_test.go (1)
166-170:⚠️ Potential issue | 🟡 MinorAssert the invalid
event_typeerror contract explicitly.Line 167 currently accepts any non-empty 400 body, so this can pass even if code/title mapping regresses. Please parse JSON and assert the expected error code/title (same pattern used in nearby error tests).
Suggested patch
expectedBody: func(t *testing.T, body []byte) { - // Validator returns "auditeventtype" (lowercase) in error message - bodyStr := string(body) - assert.True(t, len(bodyStr) > 0, "Expected non-empty error message") + var errResp map[string]any + err := json.Unmarshal(body, &errResp) + require.NoError(t, err, "response should be valid JSON") + assert.Equal(t, "TRC-0001", errResp["code"]) + assert.Equal(t, "Validation Error", errResp["title"]) + assert.NotEmpty(t, errResp["message"]) },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/adapters/http/in/audit_event_handler_test.go` around lines 166 - 170, The test's expectedBody closure currently only checks for a non-empty 400 response; update the closure (expectedBody) to parse the response JSON and explicitly assert the error contract for an invalid event_type: unmarshal body into the same error response shape used by nearby tests and assert error.Code equals the expected validation code (e.g., "INVALID_FIELD" or whatever other tests use) and error.Title or error.Detail contains the normalized field name "auditeventtype" or "event_type" as the other tests assert; use the same assertion helpers/patterns used by adjacent error tests to keep consistency with the API error format.
♻️ Duplicate comments (1)
tests/integration/03_limits_management_test.go (1)
942-972:⚠️ Potential issue | 🟠 MajorAssert that the created DAILY limit is actually returned.
This still passes on an empty page or any unrelated DAILY records, so it doesn't prove the new
limit_type=DAILYfilter returns the record created by this test.💡 Tighten the assertion
var listResp listLimitsResponse err = json.Unmarshal(respBody, &listResp) require.NoError(t, err) + require.NotEmpty(t, listResp.Limits, "Expected at least one DAILY limit in results") + found := false for _, limit := range listResp.Limits { assert.Equal(t, "DAILY", limit.LimitType, "All returned limits should be DAILY") + if limit.ID == limitID { + found = true + } } + require.True(t, found, "Created DAILY limit should appear in filtered results")🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/integration/03_limits_management_test.go` around lines 942 - 972, The test TestLimits_ListLimits_FilterByLimitType currently only checks that returned entries are DAILY but not that the specific created limit (created via createTestLimit and cleaned with cleanupLimit) is present; update the assertions to verify that listLimitsResponse (listResp) contains an entry whose ID equals the created limitID and that that entry's LimitType is "DAILY" (i.e., iterate listResp.Limits and assert one item has matching ID == limitID and LimitType == "DAILY"), ensuring the test fails if the specific created record is not returned.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@internal/adapters/http/in/audit_event_validation.go`:
- Around line 166-167: The audit filter is still being validated as a UUID which
conflicts with the intended plain-string contract: update the ResourceID field's
validation tag in internal/adapters/http/in/audit_event_validation.go (the
ResourceID struct field) to remove the "uuid" rule (e.g., use
validate:"omitempty" or no validate tag) so non-UUID resource identifiers are
accepted; ensure the change aligns with ListAuditEventsInput's domain typing in
audit_event_handler.go.
In `@internal/adapters/http/in/query_params_snake_case_test.go`:
- Line 121: Change the HTTP status assertions in the tests from assert.Equal to
require.Equal so tests fail fast on unexpected HTTP status codes; specifically,
replace calls like assert.Equal(t, fiber.StatusOK, resp.StatusCode) with
require.Equal(t, fiber.StatusOK, resp.StatusCode) (and similarly for other
status checks in the same test file) to ensure the test stops before attempting
to decode or assert response body fields when resp.StatusCode is wrong.
In `@internal/adapters/postgres/limit_repository.go`:
- Around line 192-195: List() currently preserves filters.SortBy into local
sortBy and later passes that into buildNextCursor(), but applyCursorFilter() can
switch pagination to the decoded cursor’s sort settings; update
applyCursorFilter() to return the resolved sort field (or expose the decoded
cursor's SortBy) and overwrite the local sortBy with that returned value before
calling buildNextCursor() so the next cursor is encoded with the actual sort
used; apply the same change for the other call sites where buildNextCursor() is
fed the original filters.SortBy (e.g., the other List pagination paths).
In `@tests/integration/03_limits_management_test.go`:
- Around line 1055-1065: The test uses hard-coded future dates
(customStart/customEnd) and a non-deterministic uniqueName, which makes it
time-sensitive; replace the literals by deriving a stable, non-expiring window
from testutil.FixedTime() (e.g., start = testutil.FixedTime().Add(...) and end =
start.Add(...)) and build uniqueName with testutil.MustDeterministicUUID(seed)
or testutil.RandomSuffix replacement per guidelines; update the variables
referenced (uniqueName, customStart, customEnd) used in the createLimitRequest
(LimitType "CUSTOM") so they are deterministic and stable across runs.
---
Outside diff comments:
In `@internal/adapters/http/in/audit_event_handler_test.go`:
- Around line 166-170: The test's expectedBody closure currently only checks for
a non-empty 400 response; update the closure (expectedBody) to parse the
response JSON and explicitly assert the error contract for an invalid
event_type: unmarshal body into the same error response shape used by nearby
tests and assert error.Code equals the expected validation code (e.g.,
"INVALID_FIELD" or whatever other tests use) and error.Title or error.Detail
contains the normalized field name "auditeventtype" or "event_type" as the other
tests assert; use the same assertion helpers/patterns used by adjacent error
tests to keep consistency with the API error format.
---
Duplicate comments:
In `@tests/integration/03_limits_management_test.go`:
- Around line 942-972: The test TestLimits_ListLimits_FilterByLimitType
currently only checks that returned entries are DAILY but not that the specific
created limit (created via createTestLimit and cleaned with cleanupLimit) is
present; update the assertions to verify that listLimitsResponse (listResp)
contains an entry whose ID equals the created limitID and that that entry's
LimitType is "DAILY" (i.e., iterate listResp.Limits and assert one item has
matching ID == limitID and LimitType == "DAILY"), ensuring the test fails if the
specific created record is not returned.
🪄 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: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: ca53f9d4-4e24-4505-92db-98fd2aa40b1c
📒 Files selected for processing (51)
api/docs.goapi/openapi.yamlapi/swagger.jsonapi/swagger.yamlinternal/adapters/http/in/audit_event_handler.gointernal/adapters/http/in/audit_event_handler_test.gointernal/adapters/http/in/audit_event_validation.gointernal/adapters/http/in/limit_handler.gointernal/adapters/http/in/limit_handler_test.gointernal/adapters/http/in/limit_validation.gointernal/adapters/http/in/limit_validation_test.gointernal/adapters/http/in/pagination_validation.gointernal/adapters/http/in/pagination_validation_test.gointernal/adapters/http/in/query_params_snake_case_test.gointernal/adapters/http/in/rule_handler.gointernal/adapters/http/in/rule_handler_test.gointernal/adapters/http/in/rule_validation.gointernal/adapters/http/in/rule_validation_test.gointernal/adapters/http/in/transaction_validation_handler.gointernal/adapters/http/in/transaction_validation_handler_test.gointernal/adapters/postgres/audit_event_repository.gointernal/adapters/postgres/audit_event_repository_test.gointernal/adapters/postgres/limit_repository.gointernal/adapters/postgres/limit_repository_test.gointernal/adapters/postgres/rule_repository.gointernal/adapters/postgres/rule_repository_test.gointernal/adapters/postgres/transaction_validation_repository.gointernal/adapters/postgres/transaction_validation_repository_test.gointernal/services/query/list_limits_test.gointernal/services/query/list_rules.gointernal/services/query/list_rules_test.gointernal/services/query/list_transaction_validations_test.gopkg/model/audit_event_filters.gopkg/model/audit_event_filters_test.gopkg/model/limit.gopkg/model/limit_test.gopkg/model/rule_test.gopkg/model/transaction_validation_filters.gopkg/model/transaction_validation_filters_test.gopkg/validation/datetime_test.gotests/end2end/steps/audit_steps.gotests/end2end/support/client.gotests/integration/01_validation_get_error_codes_test.gotests/integration/01_validation_test.gotests/integration/02_rules_error_codes_test.gotests/integration/02_rules_management_test.gotests/integration/02_rules_scope_filter_test.gotests/integration/03_limits_management_test.gotests/integration/04_limits_scope_filter_test.gotests/integration/07_audit_events_error_codes_test.gotests/integration/07_audit_events_test.go
Changed customStartDate/customEndDate from 2026-11 to 2099-11 so the test remains valid regardless of when it runs.
|
@coderabbitai resolve |
✅ Actions performedComments resolved and changes approved. |
Summary
Motivation
Tracer was the only Lerian service using camelCase in query parameters. This creates cognitive friction and silent bugs when developers copy patterns between services.
Scope
Breaking Change
Yes — camelCase query params are no longer accepted. No clients in production. Console BFF needs coordinated update (separate PR).
Bonus Fixes (beyond migration scope)
WEEKLYandCUSTOMtolimit_typeSwagger enumEnums(CARD, WIRE, PIX, CRYPTO)totransaction_typein audit handlerValidation
make lint— 0 issuesgo vet ./...— passgoimports -l .— cleangofmt -l .— cleanmake generate-docs— passmake test-unit— all passmake test-integration— all pass (testcontainers)make test-e2e— all pass (Godog BDD)Test plan
🤖 Generated with Claude Code