Skip to content

[CSM Portal] add cross-case call request search and dashboard widget support - #1345

Merged
rksk merged 4 commits into
wso2-open-operations:mainfrom
rksk:csm-call-requests-search
Aug 4, 2026
Merged

[CSM Portal] add cross-case call request search and dashboard widget support#1345
rksk merged 4 commits into
wso2-open-operations:mainfrom
rksk:csm-call-requests-search

Conversation

@rksk

@rksk rksk commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

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

  • Add a standalone, cross-case call request search through the Go entity-service and CSM BFF.
  • Add call_request as 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

  • Entity-service: new SearchAllCallRequests method on CallRequestService, backed by a new call to the SN integration service's POST /call-requests/search-all; reuses the existing CallRequestView/SearchCallRequestsResponse types (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.
  • BFF: new POST /call-requests/search route on CaseHandler, 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/search doesn't collide with the existing case-scoped path, which lives at /cases/{id}/call-requests/search. Added call_request to the dashboard package's resource-type enum and validation map.
  • Webapp: added call_request to BeWidgetResourceType, a WIDGET_RESOURCE_CONFIG entry (searchEndpoint: /call-requests/search), and a CallRequestWidgetList renderer — 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.yaml updated 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

  • Unit tests: existing entity-service and BFF test suites pass unchanged (go test ./...); extended the BFF's mock entity client for the new interface method.
  • Integration tests: manually verified live through the full stack (entity-service → Ballerina proxy → real ServiceNow DEV tenant) — filtering by a real case's assignee returns exactly that case's 3 known call requests, consistently at the entity-service, BFF, and webapp layers. Also verified in a real browser: a dashboard widget using resourceType: call_request renders the 3 rows and clicking one navigates to the correct case detail page.

Security checks

  • Followed secure coding standards? yes
  • Ran FindSecurityBugs plugin and verified report? N/A — Go/TypeScript, not Java; go vet and pnpm lint both ran clean on the changed files.
  • Confirmed no keys/passwords/tokens/secrets committed? yes

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 dashboard WIDGET_RESOURCE_CONFIG/WIDGET_LIST_RENDERERS exhaustive-map pattern for wiring up the new resource type on the frontend.

Summary by CodeRabbit

  • New Features
    • Added cross-case call-request search with filtering by assignee and state.
    • Added sorting by creation, update, or scheduled time, with pagination support.
    • Added dashboard widgets for displaying call requests, including status and scheduled-time details.
    • Call-request rows can navigate directly to their associated case.

…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.
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@rksk, you've reached your PR review limit, so we couldn't start this review.

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 @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 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 configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: adb8843d-cfe2-4499-953f-73f5afc95436

📥 Commits

Reviewing files that changed from the base of the PR and between 61f0ffb and 97af836.

📒 Files selected for processing (4)
  • apps/csm-portal/backend/internal/handler/cases.go
  • apps/csm-portal/webapp/src/features/csm-dashboard/components/DashboardWidgetTile.tsx
  • apps/csm-portal/webapp/src/features/csm-dashboard/config/widgetListConfig.tsx
  • entity-service/openapi.yaml
📝 Walkthrough

Walkthrough

Adds paginated cross-case call-request search through entity-service and the CSM Portal. Adds filtering, sorting, and validation. Adds call_request dashboard widget support with search configuration, row rendering, and case navigation.

Changes

Cross-case call-request search

Layer / File(s) Summary
Entity-service search contracts and ServiceNow flow
entity-service/internal/domain/entity.go, entity-service/internal/service/..., entity-service/openapi.yaml
Adds filtering, sorting, pagination, validation, ServiceNow request mapping, and response conversion for cross-case call-request searches.
Entity-service endpoint wiring
entity-service/internal/handler/call_request_handler.go, entity-service/internal/server/routes.go
Exposes POST /call-requests/search-all through the call-request handler and service route.
CSM Portal search proxy
apps/csm-portal/backend/internal/handler/cases.go, apps/csm-portal/backend/internal/entity/customer.go, apps/csm-portal/backend/cmd/server/main.go, apps/csm-portal/backend/openapi.yaml, apps/csm-portal/backend/internal/handler/helpers_test.go
Adds the authenticated POST /call-requests/search proxy. It validates request size and JSON, forwards the payload, maps errors, and returns the entity-service response.
Call-request dashboard widget
apps/csm-portal/backend/internal/dashboard/*, apps/csm-portal/webapp/src/api/backend/types.ts, apps/csm-portal/webapp/src/features/csm-dashboard/config/*
Adds the call_request resource type, search configuration, display fields, case navigation, preview metadata, and list rendering.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested labels: Type/New Feature

Suggested reviewers: rashmika998

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes: cross-case call request search and dashboard widget support.
Description check ✅ Passed The description covers the purpose, goals, approach, user story, release note, testing, security, documentation, dependencies, and environment.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.
✨ 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.

…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.
@rksk
rksk marked this pull request as ready for review August 4, 2026 04:10
@rksk
rksk requested a review from Rashmika998 August 4, 2026 04:13

@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

🤖 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

📥 Commits

Reviewing files that changed from the base of the PR and between 858a6f8 and 61f0ffb.

📒 Files selected for processing (16)
  • apps/csm-portal/backend/cmd/server/main.go
  • apps/csm-portal/backend/internal/dashboard/registry.go
  • apps/csm-portal/backend/internal/dashboard/widgets.go
  • apps/csm-portal/backend/internal/entity/customer.go
  • apps/csm-portal/backend/internal/handler/cases.go
  • apps/csm-portal/backend/internal/handler/helpers_test.go
  • apps/csm-portal/backend/openapi.yaml
  • apps/csm-portal/webapp/src/api/backend/types.ts
  • apps/csm-portal/webapp/src/features/csm-dashboard/config/widgetListConfig.tsx
  • apps/csm-portal/webapp/src/features/csm-dashboard/config/widgetResourceConfig.ts
  • entity-service/internal/domain/entity.go
  • entity-service/internal/handler/call_request_handler.go
  • entity-service/internal/server/routes.go
  • entity-service/internal/service/interfaces.go
  • entity-service/internal/service/sn_call_request_service.go
  • entity-service/openapi.yaml

Comment thread apps/csm-portal/backend/internal/handler/cases.go Outdated
Comment thread apps/csm-portal/backend/openapi.yaml
Comment thread apps/csm-portal/webapp/src/features/csm-dashboard/config/widgetListConfig.tsx Outdated
Comment thread entity-service/openapi.yaml Outdated
- 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.
Rashmika998
Rashmika998 previously approved these changes Aug 4, 2026
…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.
@rksk
rksk merged commit 701e286 into wso2-open-operations:main Aug 4, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants