Skip to content

[Customer Entity] Add search endpoint and standardise enum field naming - #929

Merged
Rashmika998 merged 9 commits into
wso2-open-operations:v2from
cloby99:task/entity-service
Jun 24, 2026
Merged

Rashmika998 merged 9 commits into
wso2-open-operations:v2from
cloby99:task/entity-service

Conversation

@cloby99

@cloby99 cloby99 commented Jun 24, 2026

Copy link
Copy Markdown
Member

Summary

  • Add POST /change-requests/search endpoint backed by ServiceNow, following the same pattern as case search (domain types → service interface → SN service implementation → handler → route → OpenAPI spec)
  • Standardise search response total field across all data sources (SN internal totalRecords mapped to domain total)
  • Remove Key/Keys suffix from enum fields in request structs across domain, services, repositories, and OpenAPI spec (e.g. StateKeysStates, TypeKeyType)

Summary by CodeRabbit

  • New Features

    • Added change-request search, including filtering, sorting, pagination, and result details.
    • Expanded API support for case searches, case comments, and deployment searches with updated field names.
  • Bug Fixes

    • Standardized search totals to return total across responses.
    • Improved update and create flows to accept direct values like state, severity, type, and issueType instead of legacy field names.

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@cloby99, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 3 minutes and 39 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b6f28869-93c6-45f7-b53a-a4b966e89c29

📥 Commits

Reviewing files that changed from the base of the PR and between f69d9eb and 9ed75a5.

📒 Files selected for processing (3)
  • entity-service/internal/service/case_service.go
  • entity-service/internal/service/sn_change_request_service.go
  • entity-service/openapi.yaml
📝 Walkthrough

Walkthrough

The PR removes all *Key/*Keys suffixes from case, comment, and deployment request/filter/response field names across domain structs, service validation, repository SQL bindings, and the OpenAPI spec. In parallel, it adds a new ServiceNow-backed change-request search endpoint with domain types, a service interface, an SN implementation, an HTTP handler, conditional route registration, and matching OpenAPI schemas.

Changes

Field Rename Cleanup (cases, comments, deployments)

Layer / File(s) Summary
Domain struct renames and OpenAPI contract updates
entity-service/internal/domain/entity.go, entity-service/openapi.yaml, entity-service/CLAUDE.md
SearchDeploymentsRequest, SearchCasesFilters, SearchCasesResponse, UpdateCaseRequest, CreateCaseRequest, CreateCaseCommentRequest, and CommentFilters drop *Key/*Keys suffixes from field names and JSON tags. totalRecords is renamed to total. OpenAPI spec and CLAUDE.md doc are updated to match.
Service validation and response mapping
entity-service/internal/service/case_service.go, entity-service/internal/service/sn_case_service.go
All validation, enum checks, SN payload construction, and response struct assignments in CreateCase, CreateCaseComment, SearchCaseComments, UpdateCase, and SearchCases are updated to reference the renamed fields.
Repository SQL parameter binding
entity-service/internal/repository/case_repo.go, entity-service/internal/repository/deployment_repo.go
SQL argument bindings in CreateCase, CreateCaseComment, SearchCaseComments, UpdateCase, SearchCases, and SearchDeployments are updated to use the renamed request fields.

New Change-Request Search Feature

Layer / File(s) Summary
Change-request domain types and OpenAPI schemas
entity-service/internal/domain/entity.go, entity-service/openapi.yaml
Adds ChangeRequestType, ChangeRequestState, ChangeRequestImpact, sort/filter structs, SearchChangeRequestsRequest, SearchChangeRequestView, and SearchChangeRequestsResponse to domain and OpenAPI. Adds POST /change-requests/search operation to the spec.
ChangeRequestService interface and SN implementation
entity-service/internal/service/interfaces.go, entity-service/internal/service/sn_change_request_service.go
Defines the ChangeRequestService interface with SearchChangeRequests. Implements it via snChangeRequestService: defines SN DTOs and mapping tables, validates/normalizes input, extracts user token from context, translates filters/sort to SN payload, calls the integration client, and maps SN response records to domain views.
HTTP handler and route wiring
entity-service/internal/handler/change_request_handler.go, entity-service/internal/server/routes.go
Adds ChangeRequestHandler with a SearchChangeRequests HTTP method. Registers POST /change-requests/search conditionally in NewRouter only for the ServiceNow data source.

Sequence Diagram

sequenceDiagram
    participant Client
    participant ChangeRequestHandler
    participant snChangeRequestService
    participant Context
    participant IntegrationClient

    Client->>ChangeRequestHandler: POST /change-requests/search
    ChangeRequestHandler->>ChangeRequestHandler: decode SearchChangeRequestsRequest
    ChangeRequestHandler->>snChangeRequestService: SearchChangeRequests(ctx, req)
    snChangeRequestService->>Context: extract x-user-id-token
    Context-->>snChangeRequestService: userToken (or UnauthorizedError)
    snChangeRequestService->>snChangeRequestService: normalize pagination, validate filters/sort/dates
    snChangeRequestService->>snChangeRequestService: map domain states/impacts → SN numeric keys
    snChangeRequestService->>IntegrationClient: POST /change-requests/search (snPayload)
    IntegrationClient-->>snChangeRequestService: raw JSON response
    snChangeRequestService->>snChangeRequestService: unmarshal SN DTOs, normalize labels, build SearchChangeRequestView[]
    snChangeRequestService-->>ChangeRequestHandler: SearchChangeRequestsResponse{Total, Limit, Offset, ChangeRequests}
    ChangeRequestHandler-->>Client: 200 application/json
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • wso2-open-operations/cs-tools#919: Introduced the case-domain/search API contract that this PR further refactors by renaming *Key(s) fields and changing SearchCasesResponse.totalRecords to total.
  • wso2-open-operations/cs-tools#913: Directly overlaps with this PR's UpdateCaseRequest/case-filter JSON field renames between *Key/*Keys and non-*Key variants at the struct/tag and request-handling code level.
  • wso2-open-operations/cs-tools#896: Modifies UpdateCaseRequest and workState handling in domain/service/repository, the same structures this PR renames from workStateKey to workState.

Suggested labels

Type/Improvement, Area/Backend, App/CSM Portal

Suggested reviewers

  • Rashmika998
  • kasunsiyambalapitiya
  • dilshanfardil

Poem

🐇 Hopping through the fields so bright,
No more *Key suffixes in sight!
state and type and total too,
Change requests search is shiny and new.
The rabbit tidied every name,
The API contract's never the same~ 🌿

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description only includes a summary and omits most required template sections, including Purpose, Goals, Approach, and testing details. Fill in the required template sections, especially Purpose, Goals, Approach, User stories, Release note, documentation, testing, and security checks.
Docstring Coverage ⚠️ Warning Docstring coverage is 44.44% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes: a new search endpoint and enum field renaming.
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

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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 (2)
entity-service/internal/service/sn_case_service.go (2)

1019-1038: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Reject unsupported enum filters before building the SN payload.

domainStatesToSNIDs, domainSeveritiesToSNIDs, domainIssueTypesToSNIDs, and domainEngagementTypesToSNIDs silently skip unmapped values, so an invalid filter can be dropped and broaden the search. Validate each list before converting, like Types already does. As per coding guidelines: “Use validXxx maps ... to validate enum fields.”

Proposed validation
 	for _, t := range req.Filters.Types {
 		if _, ok := snCaseTypeMap[t]; !ok {
 			return domain.SearchCasesResponse{}, &apierror.ValidationError{Msg: "types contains invalid value: " + t}
 		}
 	}
+	for _, state := range req.Filters.States {
+		if _, ok := snStateIDMap[state]; !ok {
+			return domain.SearchCasesResponse{}, &apierror.ValidationError{Msg: "states contains invalid value or unsupported ServiceNow value: " + string(state)}
+		}
+	}
+	for _, severity := range req.Filters.Severities {
+		if _, ok := snSeverityIDMap[severity]; !ok {
+			return domain.SearchCasesResponse{}, &apierror.ValidationError{Msg: "severities contains invalid value or unsupported ServiceNow value: " + string(severity)}
+		}
+	}
+	for _, issueType := range req.Filters.IssueTypes {
+		if _, ok := snIssueTypeIDMap[issueType]; !ok {
+			return domain.SearchCasesResponse{}, &apierror.ValidationError{Msg: "issueTypes contains invalid value or unsupported ServiceNow value: " + string(issueType)}
+		}
+	}
+	for _, engagementType := range req.Filters.EngagementTypes {
+		if _, ok := snEngagementTypeIDMap[engagementType]; !ok {
+			return domain.SearchCasesResponse{}, &apierror.ValidationError{Msg: "engagementTypes contains invalid value or unsupported ServiceNow value: " + string(engagementType)}
+		}
+	}
 	snCaseTypes := domainTypeKeysToSN(req.Filters.Types)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@entity-service/internal/service/sn_case_service.go` around lines 1019 - 1038,
Reject unsupported enum filter values before constructing the
snCaseSearchPayload in the SN case search flow. In sn_case_service.go, add
explicit validation for req.Filters.States, req.Filters.Severities,
req.Filters.IssueTypes, and req.Filters.EngagementTypes using the corresponding
validXxx maps, similar to the existing Types check, and return a ValidationError
on any invalid value. This should happen before calling domainStatesToSNIDs,
domainSeveritiesToSNIDs, domainIssueTypesToSNIDs, and
domainEngagementTypesToSNIDs so unmapped values cannot be silently dropped.

Source: Coding guidelines


317-330: 🎯 Functional Correctness | 🟡 Minor

Update the case-type validation message The error still says typeKey; change it to type must be "support" for case creation.

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

In `@entity-service/internal/service/sn_case_service.go` around lines 317 - 330,
The case-type validation in snCaseService create flow still uses the old field
name in its error text. Update the validation message in the req.Type check
inside the case creation path to say type must be "support" for case creation,
and keep the change localized around the snCaseTypeMap / snCreateCasePayload
setup so the response matches the current API terminology.
🧹 Nitpick comments (1)
entity-service/internal/service/sn_change_request_service.go (1)

91-99: 📐 Maintainability & Code Quality | 🔵 Trivial

Remove the unused change-request type map

snCRTypeIDMap isn’t referenced anywhere in this service. snChangeRequestFilters has no type field, and the search payload never sends one, so this map is dead code.

If a type filter is planned, wire it into the payload and add validChangeRequestType validation; otherwise, drop the map.

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

In `@entity-service/internal/service/sn_change_request_service.go` around lines 91
- 99, Remove the dead code by deleting snCRTypeIDMap from
sn_change_request_service.go since it is not referenced by
snChangeRequestFilters or any payload-building path. If you intend to support a
change-request type filter later, wire that through the service methods that
build the search payload and add validation via validChangeRequestType;
otherwise keep the service focused on the existing fields only.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@entity-service/internal/domain/entity.go`:
- Around line 334-340: Restore the request enum field naming contract in
SearchDeploymentsRequest and the related request types by keeping the Key/Keys
suffix in both Go field names and JSON/OpenAPI tags, since decodeRequest will
reject documented enum inputs otherwise. Update the affected domain structs and
any matching service/repo/OpenAPI references so fields like stateKey and
typeKeys remain accepted, and only proceed with the rename if the PR explicitly
includes the approved compatibility plan and contract update. Use the existing
request type symbols (such as SearchDeploymentsRequest and the other affected
request structs) to align all layers consistently.

In `@entity-service/internal/service/case_service.go`:
- Around line 135-136: The validation error in case creation still references
the old field name, so update the message in the case creation path to mention
the accepted `type` field instead of `typeKey`. Fix the error returned from the
`CreateCase`/case validation branch in `case_service.go` so callers are told to
set `type` to "support" when `req.Type` is invalid.

In `@entity-service/internal/service/sn_change_request_service.go`:
- Around line 244-287: SearchChangeRequests currently validates states, impacts,
and sort fields but skips req.Filters.ProjectIDs, so malformed project IDs can
reach uuidsToSysids unchecked. Add validateUUIDs("projectIds",
req.Filters.ProjectIDs) near the other filter validations in
sn_change_request_service.go before building snChangeRequestSearchPayload, so
invalid IDs return an apierror.ValidationError at the service boundary.

In `@entity-service/openapi.yaml`:
- Around line 678-696: The POST /change-requests/search OpenAPI operation is
missing the required 404 response for the ServiceNow-only route, so update the
change-requests search operation in openapi.yaml to include a standard
ErrorResponse 404 entry alongside the existing 200 and 400 responses. Keep the
response block consistent with the other writable endpoints and ensure the
SearchChangeRequestsResponse operation contract matches the conditional
registration behavior.

---

Outside diff comments:
In `@entity-service/internal/service/sn_case_service.go`:
- Around line 1019-1038: Reject unsupported enum filter values before
constructing the snCaseSearchPayload in the SN case search flow. In
sn_case_service.go, add explicit validation for req.Filters.States,
req.Filters.Severities, req.Filters.IssueTypes, and req.Filters.EngagementTypes
using the corresponding validXxx maps, similar to the existing Types check, and
return a ValidationError on any invalid value. This should happen before calling
domainStatesToSNIDs, domainSeveritiesToSNIDs, domainIssueTypesToSNIDs, and
domainEngagementTypesToSNIDs so unmapped values cannot be silently dropped.
- Around line 317-330: The case-type validation in snCaseService create flow
still uses the old field name in its error text. Update the validation message
in the req.Type check inside the case creation path to say type must be
"support" for case creation, and keep the change localized around the
snCaseTypeMap / snCreateCasePayload setup so the response matches the current
API terminology.

---

Nitpick comments:
In `@entity-service/internal/service/sn_change_request_service.go`:
- Around line 91-99: Remove the dead code by deleting snCRTypeIDMap from
sn_change_request_service.go since it is not referenced by
snChangeRequestFilters or any payload-building path. If you intend to support a
change-request type filter later, wire that through the service methods that
build the search payload and add validation via validChangeRequestType;
otherwise keep the service focused on the existing fields only.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f3a468f8-76e8-484a-a90f-66305620c6f6

📥 Commits

Reviewing files that changed from the base of the PR and between e98d69c and f69d9eb.

📒 Files selected for processing (11)
  • entity-service/CLAUDE.md
  • entity-service/internal/domain/entity.go
  • entity-service/internal/handler/change_request_handler.go
  • entity-service/internal/repository/case_repo.go
  • entity-service/internal/repository/deployment_repo.go
  • entity-service/internal/server/routes.go
  • entity-service/internal/service/case_service.go
  • entity-service/internal/service/interfaces.go
  • entity-service/internal/service/sn_case_service.go
  • entity-service/internal/service/sn_change_request_service.go
  • entity-service/openapi.yaml

Comment thread entity-service/internal/domain/entity.go
Comment thread entity-service/internal/service/case_service.go Outdated
Comment thread entity-service/internal/service/sn_change_request_service.go
Comment thread entity-service/openapi.yaml
@Rashmika998
Rashmika998 merged commit d6c9c40 into wso2-open-operations:v2 Jun 24, 2026
1 check passed
shayanmalinda pushed a commit that referenced this pull request Jun 24, 2026
…fix, add change-requests search

- Remove Key/Keys suffix from all enum request fields to match entity service:
  stateKey→state, severityKey→severity, workStateKey→workState (PATCH case),
  typeKey→type, issueTypeKey→issueType (create case/comment),
  typeKeys→types, stateKeys→states, severityKeys→severities,
  engagementTypeKeys→engagementTypes, issueTypeKeys→issueTypes (case search),
  deploymentTypeKeys→deploymentTypes (deployment search)
- Update PatchCase handler to read state/workState from new JSON field names
- Update CreateCaseComment handler to read type from new JSON field name
- Add POST /change-requests/search endpoint: entity client method, handler,
  interface, mock, tests, route registration, and openapi spec
- Update openapi.yaml, README.md, and CLAUDE.md throughout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
shayanmalinda added a commit that referenced this pull request Jun 24, 2026
[CSM Portal][BE] align with entity service PR #929: drop Key/Keys suffix, add change-requests search
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants