Skip to content

[CSM] fix: nest Comment.createdBy and map SN type strings to domain enum - #1037

Merged
Rashmika998 merged 3 commits into
wso2-open-operations:v2from
Rashmika998:fix/comment-createdby-nested
Jul 3, 2026
Merged

Rashmika998 merged 3 commits into
wso2-open-operations:v2from
Rashmika998:fix/comment-createdby-nested

Conversation

@Rashmika998

@Rashmika998 Rashmika998 commented Jul 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Replaces the flat createdBy, createdByFirstName, createdByLastName, createdByFullName fields on Comment with a single nested createdBy object ({ id, firstName, lastName, fullName }) — matching the shape already used by CaseComment
  • Types Comment.Type as CommentType instead of string, and maps SN plural type strings ("comments", "work_notes") back to the canonical domain values ("comment", "work_note", "activity") via a reverse lookup map
  • Applies to both GET /conversations/{id}/messages and POST /cases/{id}/comments/search responses in the CSM portal

Test plan

  • POST /comments/search (entity service) returns createdBy as a nested object with id/firstName/lastName/fullName
  • Comment type field returns "comment" / "work_note" / "activity" (not "comments" / "work_notes")
  • CSM portal GET /conversations/{id}/messages and POST /cases/{id}/comments/search both reflect the new shapes
  • All backend tests pass (make test)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Comment author details are now returned in a structured format with separate ID, first name, last name, and full name fields.
    • Comment types are now standardized across the app for more consistent display and handling.
  • Bug Fixes

    • Improved consistency when loading comments so author and type information is mapped correctly in returned results.

Rashmika998 and others added 2 commits July 3, 2026 22:12
The flat createdBy/createdByFirstName/createdByLastName/createdByFullName
fields are replaced with a single nested createdBy object carrying id,
firstName, lastName, and fullName — matching the shape already used by
CaseComment. OpenAPI schemas updated in both entity-service and csm-portal.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
SN returns plural strings ("comments", "work_notes") which are now mapped
to the canonical domain values ("comment", "work_note", "activity") via a
reverse map. Comment.Type is typed as CommentType instead of plain string.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 3, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

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

Next review available in: 53 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

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

Run ID: 2796f237-6d8c-4e88-98cc-0601c236cf96

📥 Commits

Reviewing files that changed from the base of the PR and between 39dfb19 and 8fad7f8.

📒 Files selected for processing (1)
  • entity-service/internal/service/sn_comment_service.go
📝 Walkthrough

Walkthrough

Comment author metadata is refactored from flat string/name fields into a structured object (CommentUserRef/nested createdBy) across entity-service's domain model, ServiceNow comment/case services, entity-service OpenAPI spec, and csm-portal OpenAPI spec. A new comment-type reverse-lookup map is also introduced.

Changes

Structured comment author refactor

Layer / File(s) Summary
Domain model and type mapping
entity-service/internal/domain/entity.go, entity-service/internal/service/sn_case_service.go
Comment.Type becomes CommentType and CreatedBy becomes a CommentUserRef struct; a new snCommentTypeToCommentType map reverse-maps ServiceNow type strings to CommentType.
ServiceNow comment service wiring
entity-service/internal/service/sn_comment_service.go
SearchComments maps comment Type via the new lookup and populates CreatedBy using CommentUserRef (ID/first/last/full name).
Entity-service OpenAPI schema updates
entity-service/openapi.yaml
Adds CommentUserRef schema; CaseComment.createdBy and Comment.createdBy now reference it instead of flat string/name fields.
CSM portal ConversationMessage schema update
apps/csm-portal/backend/openapi.yaml
ConversationMessage.createdBy becomes a nested object with id, firstName, lastName, fullName, replacing separate flat fields.

Estimated code review effort: 2 (Simple) | ~15 minutes

Possibly related PRs

  • wso2-open-operations/cs-tools#1034: Both PRs touch the ConversationMessage payload shape in the CSM portal OpenAPI, with this PR refactoring createdBy into a structured object.

Suggested labels: Type/Improvement

Suggested reviewers: dilshanfardil, cloby99

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers summary and tests, but it omits most required template sections like Purpose, Goals, Approach, and Release note. Fill in the template sections, especially Purpose, Goals, Approach, User stories, Release note, Documentation, Security checks, and other applicable fields.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Title matches the main change: nesting Comment.createdBy and mapping ServiceNow type strings to the domain enum.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.

rksk
rksk previously approved these changes Jul 3, 2026

@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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
entity-service/openapi.yaml (1)

4521-4529: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Comment.type still lacks an enum and its description is stale.

Unlike the sibling CaseComment.type (Line 3190-3192, enum: [work_note, comment, activity]), Comment.type remains an unconstrained string whose description still references the old plural SN token work_notes rather than the canonical domain value work_note. Given the domain model now maps to the canonical CommentType enum (comment, work_note, activity), the schema should match for API-contract clarity and generated client type-safety.

📝 Proposed fix
         type:
           type: string
-          description: Comment type (e.g. comment, work_notes).
+          enum: [work_note, comment, activity]
+          description: Comment type.
🤖 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/openapi.yaml` around lines 4521 - 4529, Update the
Comment.type schema in openapi.yaml so it matches the canonical CommentType
values used by CaseComment.type and the domain model. Add the enum for comment,
work_note, and activity, and revise the description to remove the stale
work_notes wording and reflect the canonical token names. Locate the Comment
schema near the createdOn/createdBy fields and keep the contract consistent with
the sibling CaseComment.type definition.
apps/csm-portal/backend/openapi.yaml (1)

4117-4134: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

CaseComment.createdBy should be a nested user ref. apps/csm-portal/backend/openapi.yaml:4117 still documents createdBy as a string, but this schema is reused by the case comment create/search responses and should match the entity-service payload (id, firstName, lastName, fullName). Update the portal schema to the object shape so the contract stays aligned.

🤖 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/backend/openapi.yaml` around lines 4117 - 4134, The
CaseComment schema still defines createdBy as a string, but it should match the
nested user payload used by the entity-service responses. Update the CaseComment
object in openapi.yaml so createdBy uses the user reference shape with id,
firstName, lastName, and fullName, and make sure any create/search response
schemas that reuse CaseComment continue to align with that object structure.
♻️ Duplicate comments (1)
entity-service/internal/service/sn_comment_service.go (1)

90-90: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Unmapped SN type resolves to empty string.

snCommentTypeToCommentType[c.Type] yields the zero value domain.CommentType("") for any c.Type not exactly "comments", "work_notes", or "activity" — this includes singular forms that sn_case_service.go's equivalent switch (Line 730/732) explicitly normalizes. This can surface an invalid type in the GET /conversations/{id}/messages response.

🤖 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_comment_service.go` at line 90, The type
mapping in snCommentService’s comment conversion is too strict and can fall back
to an empty domain.CommentType for unrecognized ServiceNow values. Update the
logic around snCommentTypeToCommentType usage in snComment_service.go so c.Type
is normalized the same way as in sn_case_service.go (for example,
singular/plural variants) before assigning commentType, and ensure any unmapped
value is handled with a safe default or explicit validation instead of returning
an empty string.
🧹 Nitpick comments (2)
entity-service/internal/service/sn_case_service.go (1)

680-685: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate type-mapping logic (map vs. switch).

The same SN-type-to-CommentType mapping is now implemented twice: once as snCommentTypeToCommentType (Lines 680-685) and once as an inline switch (Lines 728-738), with differing behavior (the switch handles singular forms and has a default; the map does not). Consolidating into a single helper function used by both call sites would prevent this kind of divergence.

♻️ Suggested consolidation
-var snCommentTypeToCommentType = map[string]domain.CommentType{
-	"comments":   domain.CommentTypeComment,
-	"work_notes": domain.CommentTypeWorkNote,
-	"activity":   domain.CommentTypeActivity,
-}
+func mapSNCommentType(snType string) domain.CommentType {
+	switch snType {
+	case "comments", "comment":
+		return domain.CommentTypeComment
+	case "work_notes", "work_note":
+		return domain.CommentTypeWorkNote
+	case "activity":
+		return domain.CommentTypeActivity
+	default:
+		return domain.CommentTypeComment
+	}
+}

Then replace the switch at Line 728-738 and the map lookup in sn_comment_service.go with calls to mapSNCommentType(c.Type).

Also applies to: 728-738

🤖 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 680 - 685,
The SN-type-to-CommentType conversion is duplicated and has drifted between the
map and the inline switch. Introduce a single helper like mapSNCommentType and
use it from both the snCommentTypeToCommentType lookup and the switch-based path
in sn_case_service.go/sn_comment_service.go so the singular/plural handling and
default fallback stay consistent. Remove the separate map/switch logic after
wiring both call sites to the shared helper.
apps/csm-portal/backend/openapi.yaml (1)

5058-5060: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

ConversationMessage.type not constrained to the domain CommentType values.

The domain Comment.Type field is now typed as CommentType (per the PR), but this schema still documents type as a free-form string without an enum. Consider adding enum: [comment, work_note, activity] to match CaseComment.type (line 4126) and keep client-generated types accurate.

🤖 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/backend/openapi.yaml` around lines 5058 - 5060, The
ConversationMessage.type schema is still a free-form string and should be
constrained to the CommentType domain values. Update the ConversationMessage
definition in the OpenAPI schema to add the enum values used by
CaseComment.type, so generated clients reflect the actual type contract. Use the
ConversationMessage and CaseComment schema entries as the references when making
the change.
🤖 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/service/sn_case_service.go`:
- Around line 680-685: The SN comment type mapping can return the zero value for
unexpected API values, causing an empty domain comment type. Update the lookup
in the SN comment handling path that uses snCommentTypeToCommentType and add an
ok check on c.Type; when the type is unknown, default to
domain.CommentTypeComment instead of using the map result directly. Keep the fix
near the mapping/lookup symbols snCommentTypeToCommentType and the SN comment
conversion logic so it is applied consistently.

---

Outside diff comments:
In `@apps/csm-portal/backend/openapi.yaml`:
- Around line 4117-4134: The CaseComment schema still defines createdBy as a
string, but it should match the nested user payload used by the entity-service
responses. Update the CaseComment object in openapi.yaml so createdBy uses the
user reference shape with id, firstName, lastName, and fullName, and make sure
any create/search response schemas that reuse CaseComment continue to align with
that object structure.

In `@entity-service/openapi.yaml`:
- Around line 4521-4529: Update the Comment.type schema in openapi.yaml so it
matches the canonical CommentType values used by CaseComment.type and the domain
model. Add the enum for comment, work_note, and activity, and revise the
description to remove the stale work_notes wording and reflect the canonical
token names. Locate the Comment schema near the createdOn/createdBy fields and
keep the contract consistent with the sibling CaseComment.type definition.

---

Duplicate comments:
In `@entity-service/internal/service/sn_comment_service.go`:
- Line 90: The type mapping in snCommentService’s comment conversion is too
strict and can fall back to an empty domain.CommentType for unrecognized
ServiceNow values. Update the logic around snCommentTypeToCommentType usage in
snComment_service.go so c.Type is normalized the same way as in
sn_case_service.go (for example, singular/plural variants) before assigning
commentType, and ensure any unmapped value is handled with a safe default or
explicit validation instead of returning an empty string.

---

Nitpick comments:
In `@apps/csm-portal/backend/openapi.yaml`:
- Around line 5058-5060: The ConversationMessage.type schema is still a
free-form string and should be constrained to the CommentType domain values.
Update the ConversationMessage definition in the OpenAPI schema to add the enum
values used by CaseComment.type, so generated clients reflect the actual type
contract. Use the ConversationMessage and CaseComment schema entries as the
references when making the change.

In `@entity-service/internal/service/sn_case_service.go`:
- Around line 680-685: The SN-type-to-CommentType conversion is duplicated and
has drifted between the map and the inline switch. Introduce a single helper
like mapSNCommentType and use it from both the snCommentTypeToCommentType lookup
and the switch-based path in sn_case_service.go/sn_comment_service.go so the
singular/plural handling and default fallback stay consistent. Remove the
separate map/switch logic after wiring both call sites to the shared helper.
🪄 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: bfa6b1cd-af54-4377-aee0-c560bff990c1

📥 Commits

Reviewing files that changed from the base of the PR and between 93ffdcd and 39dfb19.

📒 Files selected for processing (5)
  • apps/csm-portal/backend/openapi.yaml
  • entity-service/internal/domain/entity.go
  • entity-service/internal/service/sn_case_service.go
  • entity-service/internal/service/sn_comment_service.go
  • entity-service/openapi.yaml

Comment thread entity-service/internal/service/sn_case_service.go
An ok check guards the snCommentTypeToCommentType lookup so an unexpected
value from the SN API never produces an empty type in the response.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Rashmika998
Rashmika998 merged commit 265fd90 into wso2-open-operations:v2 Jul 3, 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.

3 participants