[CSM Portal] add cross-case call request search and dashboard widget support - #1345
Conversation
…support Adds a standalone call request search (across all cases, filterable by assignee/state) through the Go entity-service and CSM BFF, and wires it up as a new "call_request" dashboard widget resource type on both the backend and webapp, so a widget can list an engineer's call requests across their cases with click-through to the owning case.
|
Warning Review limit reached
Next review available in: 15 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the 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 reviews. How do review 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 refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughAdds paginated cross-case call-request search through entity-service and the CSM Portal. Adds filtering, sorting, and validation. Adds ChangesCross-case call-request search
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 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 |
…sts/search
The BFF and FE now use the flat /call-requests/search path for the
cross-case call request search (no collision -- the existing case-scoped
search lives at /cases/{id}/call-requests/search). The entity service's
own endpoint stays /call-requests/search-all, unchanged, to stay distinct
from its own case-scoped sibling path.
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 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 `@apps/csm-portal/backend/internal/handler/cases.go`:
- Around line 914-917: Update the request validation in the handler around
json.Valid to require that the body is a non-null JSON object before forwarding
it to the entity service. Reject null and other valid non-object JSON values
with the existing bad-request response, while preserving acceptance of valid
JSON objects.
In `@apps/csm-portal/backend/openapi.yaml`:
- Around line 2302-2350: Restore POST /call-requests/search-all in the OpenAPI
contract as a deprecated compatibility alias for the existing
searchAllCallRequests operation. Mirror the request body and responses from
/call-requests/search, mark the alias deprecated, and retain
/call-requests/search as the canonical endpoint.
In
`@apps/csm-portal/webapp/src/features/csm-dashboard/config/widgetListConfig.tsx`:
- Around line 490-491: Update the scheduled column rendering near the scheduled
Typography element to preserve the hour and minute from cr.scheduleTime by using
a date-and-time formatter instead of formatDate, or rename the column label to
“Scheduled date” if only the date should remain displayed.
In `@entity-service/openapi.yaml`:
- Around line 6805-6816: Update the CallRequestSort schema’s field and order
properties to document their runtime defaults: updatedOn for field and desc for
order, while preserving their existing enums and optionality. Include the
defaults in the property definitions and descriptions so generated clients
reflect SearchAllCallRequests behavior.
🪄 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 Plus
Run ID: 5dda672a-bd51-4676-b633-59a454a0449b
📒 Files selected for processing (16)
apps/csm-portal/backend/cmd/server/main.goapps/csm-portal/backend/internal/dashboard/registry.goapps/csm-portal/backend/internal/dashboard/widgets.goapps/csm-portal/backend/internal/entity/customer.goapps/csm-portal/backend/internal/handler/cases.goapps/csm-portal/backend/internal/handler/helpers_test.goapps/csm-portal/backend/openapi.yamlapps/csm-portal/webapp/src/api/backend/types.tsapps/csm-portal/webapp/src/features/csm-dashboard/config/widgetListConfig.tsxapps/csm-portal/webapp/src/features/csm-dashboard/config/widgetResourceConfig.tsentity-service/internal/domain/entity.goentity-service/internal/handler/call_request_handler.goentity-service/internal/server/routes.goentity-service/internal/service/interfaces.goentity-service/internal/service/sn_call_request_service.goentity-service/openapi.yaml
- Reject non-object JSON (e.g. a bare "null" body) on the cross-case call request search route by reusing isJSONObjectOrEmpty, the same guard SearchTasks already uses for its own standalone search -- json.Valid alone let a null body through as an unfiltered search. - Show date + time (not just date) in the call request widget's "Scheduled" column, so same-day calls stay distinguishable. - Document the search's default sort field/order (updatedOn/desc) in the entity service's OpenAPI schema, matching runtime behavior.
…aleString Large counts (e.g. 1000+) rendered as an unbroken string of digits with no thousands separator. Applies to the visible number and the tile's aria-label alike, so both stay in sync.
Purpose
The CSM portal only supported searching call requests within a single case. There was no way to see call requests across all of a CS engineer's cases (e.g. for a dashboard tile listing pending call requests), and dashboard widget config had no resource type for call requests at all.
Goals
call_requestas a supported dashboard widget resource type, so a dashboard config can define a widget that lists call requests with click-through to the owning case.Approach
SearchAllCallRequestsmethod onCallRequestService, backed by a new call to the SN integration service'sPOST /call-requests/search-all; reuses the existingCallRequestView/SearchCallRequestsResponsetypes (same shape as the existing case-scoped search). Extracted the existing response-mapping loop into a shared helper used by both the case-scoped and cross-case search paths.POST /call-requests/searchroute onCaseHandler, forwarding to the entity service's/call-requests/search-all(which keeps its own "-all" suffix to stay distinct from its own case-scoped sibling path). The BFF's flat/call-requests/searchdoesn't collide with the existing case-scoped path, which lives at/cases/{id}/call-requests/search. Addedcall_requestto the dashboard package's resource-type enum and validation map.call_requesttoBeWidgetResourceType, aWIDGET_RESOURCE_CONFIGentry (searchEndpoint: /call-requests/search), and aCallRequestWidgetListrenderer — each row's click destination is the owning case (/cases/{case.id}), since call requests have a real detail page (the parent case) unlike some other resource types.openapi.yamlupdated in both the entity-service and BFF for the new paths/schemas.User stories
As a CS engineer, I want a dashboard widget that shows call requests across all my cases (not just one case at a time), so I can track pending/scheduled calls at a glance and jump straight to the relevant case.
Release note
Adds a cross-case call request search endpoint and a corresponding dashboard widget resource type with case click-through.
Documentation
N/A — internal API/dashboard-config addition, no external-facing docs.
Automation tests
go test ./...); extended the BFF's mock entity client for the new interface method.resourceType: call_requestrenders the 3 rows and clicking one navigates to the correct case detail page.Security checks
go vetandpnpm lintboth ran clean on the changed files.Related PRs
Depends on a corresponding Ballerina entity-service change (adding the new standalone search endpoint this PR's entity-service layer calls), tracked separately in a private repo.
Migrations
N/A
Test environment
Local Go entity-service and BFF, local webapp dev server, tested against a real backing ServiceNow DEV tenant via the Ballerina proxy layer, with a real browser session.
Learning
Mirrored this codebase's existing standalone-vs-case-scoped search split (
searchTasks/searchCaseTasks) for the new call-request search, and the existing dashboardWIDGET_RESOURCE_CONFIG/WIDGET_LIST_RENDERERSexhaustive-map pattern for wiring up the new resource type on the frontend.Summary by CodeRabbit