[CSM Portal] Show project-contact access status (has access / why not) - #1320
Rashmika998 merged 4 commits into
Conversation
Project contacts search now reports whether each row would actually grant its person visibility into the project's cases, not just whether they're listed: customerContactPresent, emailMatchesLogin, grantsCaseAccess. Mirrors the per-email diagnostic view (ProjectContactDiagnosticUtils) but computed inline on the existing project-scoped ProjectUtils query (SN update set 1262-S1222-T90-CST-SajithE, additive only), so listing a project's contacts stays a single query instead of one per contact. Entity-service: threads the three fields through snProjectContact and domain.ProjectContact; GetProjectContact inherits them for free since it reuses SearchProjectContacts. BFF openapi.yaml documents the same fields (pass-through, no Go change needed there). CSM webapp: ProjectContactsTab gets an Access column with a colored chip (Has access / No access) and an inline reason distinguishing "no linked contact record" from the harder-to-spot "linked but invited under a different email" case. Registration state also gets a colored chip, mirroring the customer portal's own registered=success/invited=warning convention. Falls back to the old id-presence heuristic when the backend predates these fields, so independent layer deploys degrade gracefully.
A comment named ServiceNow directly, which cs-tools' vendor-neutrality convention keeps out of anything but the entity-service's SN adapter package. Rephrased generically; no behavior change.
|
Warning Review limit reached
Next review available in: 33 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. 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 (8)
📝 WalkthroughWalkthroughChangesThe entity service now exposes contact presence, login-email matching, and effective case-access fields. The CSM portal consumes these fields and displays registration and access status, including reasons for unavailable access. Project contact access status
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant ServiceNow
participant EntityService
participant BackendAPI
participant ProjectContactsTab
ServiceNow->>EntityService: Return project contacts and access metadata
EntityService->>BackendAPI: Expose mapped ProjectContact fields
BackendAPI->>ProjectContactsTab: Provide contact records
ProjectContactsTab->>ProjectContactsTab: Derive and render registration and access status
Possibly related PRs
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 |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
apps/csm-portal/webapp/src/features/csm-projects/components/ProjectContactsTab.test.tsx (1)
185-217: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd a test for the "no linked contact record" reason under the new-format fields.
The tests cover
grantsCaseAccess: true(Has access) and the email-mismatch case (customerContactPresent: true,emailMatchesLogin: false). No test setscustomerContactPresent: falsetogether withgrantsCaseAccess: falseandemailMatchesLogindefined. That branch inderiveAccessStatus(ProjectContactsTab.tsx, Lines 70-73) currently reaches the same "No linked contact record" text only through the separate old-heuristic "Orphaned" path in existing tests, so a regression in this specific new-format branch would not be caught.🤖 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-projects/components/ProjectContactsTab.test.tsx` around lines 185 - 217, Add a focused test in ProjectContactsTab.test.tsx for deriveAccessStatus’s new-format no-linked-contact branch: use a contact with customerContactPresent false, grantsCaseAccess false, and emailMatchesLogin defined, then assert the No access state and the “No linked contact record” reason. Keep it distinct from the existing Orphaned/old-heuristic coverage.
🤖 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/openapi.yaml`:
- Around line 6418-6434: Update the inline item schema under
ProjectContactSearchResponse.contacts to include customerContactPresent,
emailMatchesLogin, and grantsCaseAccess, or replace the duplicate schema with a
$ref to ProjectContact so the search response documents the complete runtime
payload.
---
Nitpick comments:
In
`@apps/csm-portal/webapp/src/features/csm-projects/components/ProjectContactsTab.test.tsx`:
- Around line 185-217: Add a focused test in ProjectContactsTab.test.tsx for
deriveAccessStatus’s new-format no-linked-contact branch: use a contact with
customerContactPresent false, grantsCaseAccess false, and emailMatchesLogin
defined, then assert the No access state and the “No linked contact record”
reason. Keep it distinct from the existing Orphaned/old-heuristic coverage.
🪄 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: 5bf63d0b-a1f5-4828-bce4-aa73d978abdb
📒 Files selected for processing (8)
apps/csm-portal/backend/openapi.yamlapps/csm-portal/webapp/src/api/backend/types.tsapps/csm-portal/webapp/src/features/csm-projects/components/ProjectContactsTab.test.tsxapps/csm-portal/webapp/src/features/csm-projects/components/ProjectContactsTab.tsxentity-service/internal/domain/entity.goentity-service/internal/service/sn_project_service.goentity-service/internal/service/sn_project_service_test.goentity-service/openapi.yaml
…ess status emailMatchesLogin is removed from the project-contact access-status fields. A real customer's invited email always matches their registered account's email; the two only diverge for integration/system accounts, which aren't the audience this signals for. grantsCaseAccess now mirrors customerContactPresent directly instead of requiring both.
…d ProjectContact ProjectContactSearchResponse.contacts.items was a separate inline object schema instead of a $ref to ProjectContact, so it silently fell out of sync with the actual response shape (missing the three access-status fields added earlier in this PR). Replaced with a $ref, matching how the entity-service's own openapi.yaml already documents the equivalent response. No runtime change: the BFF already passes the entity-service response through byte-for-byte.
Purpose
The CSM portal's project-contacts list showed who's listed as a contact on a project, but not whether that person could actually see the project's cases. A contact record can be linked yet still fail the customer portal's own access rule (invited under one email, registered under a different one) — a fault a support engineer has no way to spot today short of manually cross-checking two fields per row.
Goals
Surface per-row access status on the project-contacts list: is a contact record linked at all, does the invited email match the linked account's own email, and would this row actually grant its person visibility into the project's cases — plus a visible reason when it wouldn't.
Approach
snProjectContact/domain.ProjectContactgain three fields —customerContactPresent,emailMatchesLogin,grantsCaseAccess— computed by the backing data source per contact row and threaded straight through.GetProjectContactinherits them for free since it reusesSearchProjectContacts's mapped result.openapi.yamldocuments the same three fields (pure pass-through, no Go code change needed there).ProjectContactsTabgets a new Access column — a colored chip ("Has access" / "No access") with an inline reason distinguishing "no linked contact record" from the harder-to-spot "linked but invited under a different email" case. Registration state also gets a colored chip (registered=success, invited=warning), mirroring the customer portal's own convention for that same concept. Falls back to the previous id-presence-only heuristic when the three new fields are absent, so this and the entity-service can deploy independently without one making the other render nonsense.User stories
As a CS engineer, when a customer reports they can't see a project's cases, I can open that project's Contacts tab and immediately see which listed contact rows would actually grant access today, and why the ones that don't are failing (no linked account vs. an email mismatch) — without manually cross-referencing two ServiceNow-adjacent fields per row.
Release note
The project Contacts tab now shows an Access status per contact (Has access / No access, with a reason), and a colored registration-state chip, instead of only listing names.
Documentation
N/A — internal CSM portal feature, no external documentation to update.
Training
N/A
Certification
N/A — no certification exam impact.
Marketing
N/A
Automation tests
Security checks
Samples
N/A
Related PRs
Follow-up to #1287 (merged) and #1317 (merged) — the project-contacts tab those shipped only listed name/email/roles/registration; this adds the access-status dimension.
Migrations (if applicable)
N/A — additive fields only, no schema change on this side.
Test environment
Go (repo-pinned toolchain), Node/pnpm (repo-pinned), local
go build/go test,tsc -b,vitest.Learning
N/A
Summary by CodeRabbit