[CSM Portal] add Problem management list and detail views - #1193
Conversation
Adds a Problems tab to the Operations page and a dedicated problem
detail page, sourced end-to-end from a new backing-service GET
/problems/{id} resource. The existing search resource only returned
id/number/subject, so opening a problem needed a way to fetch the
full record including its linked incidents.
Renders linked incidents as distinct, individually clickable entries
(a genuine one-to-many relationship) and handles an origin-record
reference that isn't always guaranteed to be a case.
📝 WalkthroughWalkthroughAdds end-to-end ServiceNow problem detail retrieval, including entity-service and CSM backend APIs, frontend search and filtering, Operations navigation, and a read-only problem detail page with linked records and resolution data. ChangesProblem detail API stack
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant OperationsUI
participant CSMBackend
participant EntityService
participant ServiceNow
OperationsUI->>CSMBackend: GET /problems/{id}
CSMBackend->>EntityService: GET /problems/{id}
EntityService->>ServiceNow: GET /problems/{sysid}
ServiceNow-->>EntityService: Problem detail payload
EntityService-->>CSMBackend: ProblemDetail JSON
CSMBackend-->>OperationsUI: ProblemDetail JSON
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 golangci-lint (2.12.2)level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies" 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 |
|
@coderabbitai resume |
✅ Action performedReviews resumed. |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
entity-service/internal/handler/problem_handler.go (1)
61-62: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueExplicitly set the HTTP status code.
While
json.NewEncoder(w).Encodeimplicitly writes a200 OKstatus upon the first write, explicitly callingw.WriteHeader(http.StatusOK)improves clarity and maintains consistency with other handlers (likeSearchProblems).♻️ Proposed refactor
w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) _ = json.NewEncoder(w).Encode(result)🤖 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/handler/problem_handler.go` around lines 61 - 62, Update the response-writing flow in the problem handler to explicitly call w.WriteHeader(http.StatusOK) before encoding result with json.NewEncoder(w).Encode. Preserve the existing JSON content type and response body behavior, matching the status handling used by SearchProblems.apps/csm-portal/webapp/src/features/csm-operations/pages/ProblemDetailPage.tsx (1)
188-198: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicate grid layout object across three cards.
The same
gridTemplateColumnsgridsxobject is repeated verbatim for Overview, Linked records, and Resolution. Extracting it once avoids drift if the column layout changes later.♻️ Proposed extraction
+const METACELL_GRID_SX = { + display: "grid", + gap: 2, + gridTemplateColumns: { + xs: "1fr", + sm: "repeat(2, minmax(0, 1fr))", + md: "repeat(3, minmax(0, 1fr))", + }, +} as const;Then reuse
sx={METACELL_GRID_SX}at each of the three call sites instead of the inline literal.Also applies to: 221-231, 272-282
🤖 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 `@apps/csm-portal/webapp/src/features/csm-operations/pages/ProblemDetailPage.tsx` around lines 188 - 198, Extract the repeated grid layout object used by the Overview, Linked records, and Resolution cards into a shared METACELL_GRID_SX constant in ProblemDetailPage, then replace all three inline sx objects with sx={METACELL_GRID_SX}. Preserve the existing responsive grid values unchanged.
🤖 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/webapp/src/features/csm-operations/components/ProblemsTab.tsx`:
- Around line 141-154: Make the clickable TableRow in the ProblemsTab rendering
keyboard-operable: add an appropriate row role and tabIndex, and handle Enter
and Space in onKeyDown to navigate to the same problem detail URL as onClick.
Preserve mouse navigation and prevent default behavior for activated keys.
In `@entity-service/internal/domain/entity.go`:
- Around line 2711-2714: Rename the timestamp fields and JSON tags in
entity-service/internal/domain/entity.go:2711-2714 from ResolvedAt, OpenedAt,
and ClosedAt to ResolvedOn, OpenedOn, and ClosedOn; update
entity-service/internal/service/sn_problem_service.go:186-188 to initialize the
new fields while retaining the existing source values; and rename the
corresponding schema properties to resolvedOn, openedOn, and closedOn in
entity-service/openapi.yaml:6241-6252 and
apps/csm-portal/backend/openapi.yaml:7095-7106.
In `@entity-service/openapi.yaml`:
- Around line 6219-6222: Update the linkedIncidents property in the relevant
OpenAPI schema to include nullable: true, preserving its existing array type and
CaseNumberRef item reference.
---
Nitpick comments:
In
`@apps/csm-portal/webapp/src/features/csm-operations/pages/ProblemDetailPage.tsx`:
- Around line 188-198: Extract the repeated grid layout object used by the
Overview, Linked records, and Resolution cards into a shared METACELL_GRID_SX
constant in ProblemDetailPage, then replace all three inline sx objects with
sx={METACELL_GRID_SX}. Preserve the existing responsive grid values unchanged.
In `@entity-service/internal/handler/problem_handler.go`:
- Around line 61-62: Update the response-writing flow in the problem handler to
explicitly call w.WriteHeader(http.StatusOK) before encoding result with
json.NewEncoder(w).Encode. Preserve the existing JSON content type and response
body behavior, matching the status handling used by SearchProblems.
🪄 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: 179c9566-0231-4de0-85f9-28e4fd81bc3b
📒 Files selected for processing (24)
apps/csm-portal/backend/cmd/server/main.goapps/csm-portal/backend/internal/entity/entity.goapps/csm-portal/backend/internal/handler/helpers_test.goapps/csm-portal/backend/internal/handler/problems.goapps/csm-portal/backend/internal/handler/problems_test.goapps/csm-portal/backend/openapi.yamlapps/csm-portal/webapp/src/App.tsxapps/csm-portal/webapp/src/api/backend/types.tsapps/csm-portal/webapp/src/constants/apiConstants.tsapps/csm-portal/webapp/src/features/csm-operations/api/useGetProblem.tsapps/csm-portal/webapp/src/features/csm-operations/api/useSearchProblems.tsapps/csm-portal/webapp/src/features/csm-operations/components/ProblemsFilterBar.tsxapps/csm-portal/webapp/src/features/csm-operations/components/ProblemsTab.tsxapps/csm-portal/webapp/src/features/csm-operations/pages/OperationsPage.tsxapps/csm-portal/webapp/src/features/csm-operations/pages/ProblemDetailPage.test.tsxapps/csm-portal/webapp/src/features/csm-operations/pages/ProblemDetailPage.tsxapps/csm-portal/webapp/src/features/csm-operations/utils/__tests__/problems.test.tsapps/csm-portal/webapp/src/features/csm-operations/utils/problems.tsentity-service/internal/domain/entity.goentity-service/internal/handler/problem_handler.goentity-service/internal/server/routes.goentity-service/internal/service/interfaces.goentity-service/internal/service/sn_problem_service.goentity-service/openapi.yaml
Purpose
The CSM portal has no way to view Problem records. The existing search resource only returns id/number/subject, so there is no way to open a problem and see its full detail, including which incidents it links back to.
Goals
Adds Problem management to the CSM portal: a Problems tab (list + filters) on the Operations page, and a dedicated problem detail page, backed by a new
GET /problems/{id}resource across the entity-service and CSM backend.Approach
GET /problems/{id}resource on the backing data source, alongside the existing search resource.useGetProblem/useSearchProblemshooks, aProblemsTab+ProblemsFilterBaron the Operations page, and aProblemDetailPagereachable via a new route fromApp.tsx.Notable UX detail: a problem can link to multiple incidents, and the detail page renders each as its own distinct, clickable entry rather than collapsing them into a single reference. It also tolerates an origin-record reference that isn't guaranteed to be a Case.
Verified end-to-end against real data through the full stack (entity-service -> backend -> webapp), including a live browser check with a real login confirming a problem's linked incidents render correctly as separate entries.
A corresponding change on the backing data source side is tracked separately, outside this repo.
User stories
As a CS engineer, I can open a problem from the Operations page and see its full detail, including which incidents it is linked to, so I can triage without leaving the portal.
Release note
Adds Problem management (list + detail) to the CSM portal.
Documentation
N/A - internal CSM-portal feature, no external-facing docs impact.
Training
N/A
Certification
N/A - no certification content affected.
Marketing
N/A
Automation tests
Backend: handler tests for the new
GET /problems/{id}route (success, not-found, upstream error) using an in-package mock entity client. Webapp: unit tests for the problems util module and a component test forProblemDetailPagecovering the multi-incident rendering and the non-Case origin reference.Exercised the full chain (entity-service -> CSM backend -> webapp) against real data in a live browser session with a real login.
Security checks
go vetand eslint instead, both cleanSamples
N/A
Related PRs
None
Migrations (if applicable)
N/A - no schema migrations; additive API resource only.
Test environment
Verified locally against a real backing-data-source DEV environment, Node/pnpm + Go toolchain on macOS, Chrome (real login flow).
Learning
N/A
Note on PR size: this diff spans three components (entity-service, CSM backend, webapp) that are intentionally coupled - the webapp calls the new backend endpoint which calls the new entity-service endpoint - so it is one PR of 24 files rather than a split stack. One file (
ProblemDetailPage.tsx, ~325 changed lines) is slightly over the usual per-file review size and may get summarized rather than line-by-line review.Summary by CodeRabbit