Skip to content

feat(customer-portal): add change request and call request modules - #1314

Merged
Rashmika998 merged 2 commits into
wso2-open-operations:dev-app-csm-portalfrom
Rashmika998:feature/customer-portal-backend-v2-batch5
Jul 31, 2026
Merged

Rashmika998 merged 2 commits into
wso2-open-operations:dev-app-csm-portalfrom
Rashmika998:feature/customer-portal-backend-v2-batch5

Conversation

@Rashmika998

@Rashmika998 Rashmika998 commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds 9 more endpoints to apps/customer-portal/backend-v2 (35 total), both ServiceNow-only:

  • Change requests: POST /change-requests, POST /change-requests/search, GET /change-requests/{id}, PATCH /change-requests/{id}, GET /change-requests/{id}/approvals, POST /change-requests/{id}/approvals/decision.
  • Call requests: POST /call-requests, POST /call-requests/search, PATCH /call-requests/{id}.

Both create/update endpoints use restricted portal request DTOs, continuing the case-update pattern:

  • ChangeRequestCreateRequest excludes groupId/assignedEngineerId (support assignment), requestedById (an arbitrary "on behalf of" WSO2 user id), and workNote (internal annotation).
  • ChangeRequestUpdateRequest excludes case/project/deployment relinking and assignedEngineerId/assignedTeamId, plus state itself — state transitions go through isCustomerApproved/isCustomerReviewed/requestApproval instead, which are kept since they're the customer's own approval actions.
  • CallRequestUpdateRequest excludes meetingDate/assignee/notes/plan/attendees/actionItems/actualDurationMin — entity-service's own doc comment calls these "agent-side fields, set when an engineer schedules or concludes the call." Still exposed on the read side so the customer can see the outcome.

Two design notes now called out explicitly in CLAUDE.md so they don't get misapplied later:

  • PATCH /deployed-products/{id}'s deploymentId field looks similar to the excluded relinking fields above but isn't restricted — entity-service documents it as an IDOR-style scope guard the caller supplies voluntarily, not a relinking mechanism. Read the entity-service doc comment before restricting a field, don't pattern-match on field shape alone.
  • PATCH /cases/{id} requires exactly one primary field; PATCH /change-requests/{id} requires at least one — both per entity-service's own doc comments, which differ. Verified in testing below that both validation rules are enforced correctly and independently.

Also updates openapi.yaml (9 new paths, ~24 new schemas), README.md, and CLAUDE.md.

Test plan

  • go build ./..., go vet ./..., gofmt -l . all clean
  • gosec -fmt=text ./... reports 0 issues
  • openapi.yaml validated as well-formed YAML with all 9 new paths/schemas present
  • Manually verified: missing required fields (subject, state) → 400; change-request PATCH at-least-one rule and call-request PATCH required-state rule both enforced; invalid approval decision value → 400; invalid UUID path params → 400; valid requests against an unreachable upstream map cleanly to 500 (no leakage)
  • Wire up against a real running entity-service instance (ServiceNow data source required for every route in this PR)

Linked issues

Closes wso2-enterprise/wso2-digital-team-project-management#863
Closes wso2-enterprise/wso2-digital-team-project-management#864
Closes wso2-enterprise/wso2-digital-team-project-management#865
Closes wso2-enterprise/wso2-digital-team-project-management#866
Closes wso2-enterprise/wso2-digital-team-project-management#867
Closes wso2-enterprise/wso2-digital-team-project-management#868
Closes wso2-enterprise/wso2-digital-team-project-management#869
Closes wso2-enterprise/wso2-digital-team-project-management#870
Closes wso2-enterprise/wso2-digital-team-project-management#871

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added customer portal support for creating, searching, viewing, and updating change requests.
    • Added change-request approval tracking and decision submission.
    • Added call-request creation, search, scheduling updates, and cancellation support.
    • Added authentication, request validation, and customer-editable field restrictions.
  • Documentation
    • Updated API documentation with new routes, request formats, response schemas, and usage examples.

Adds 9 more endpoints to backend-v2 (35 total), both ServiceNow-only:

- Change requests: POST /change-requests, POST /change-requests/search,
  GET /change-requests/{id}, PATCH /change-requests/{id},
  GET /change-requests/{id}/approvals,
  POST /change-requests/{id}/approvals/decision.
- Call requests: POST /call-requests, POST /call-requests/search,
  PATCH /call-requests/{id}.

Both create/update endpoints use restricted portal request DTOs,
continuing the pattern from case updates:

- ChangeRequestCreateRequest excludes groupId/assignedEngineerId
  (support team/engineer assignment), requestedById (an arbitrary
  "on behalf of" WSO2 user id), and workNote (internal annotation).
- ChangeRequestUpdateRequest excludes case/project/deployment relinking,
  assignedEngineerId/assignedTeamId, and state — state transitions go
  through the dedicated isCustomerApproved/isCustomerReviewed/
  requestApproval fields instead, which are the customer's own approval
  actions and are kept.
- CallRequestUpdateRequest excludes meetingDate/assignee/notes/plan/
  attendees/actionItems/actualDurationMin — entity-service's own doc
  comment labels these "agent-side fields, set when an engineer
  schedules or concludes the call." Still exposed on the read side
  (CallRequestSummary) so the customer can see the outcome.

PATCH /deployed-products/{id}'s deploymentId field is the deliberate
counter-example already in this backend: it looks similar (an id
referencing another resource) but isn't restricted, since
entity-service documents it as an IDOR-style scope guard, not a
relinking field — CLAUDE.md now calls this distinction out explicitly
so it isn't misapplied by pattern-matching on field shape alone.

PATCH /cases/{id} requires exactly one primary field (entity-service's
own doc comment says so); PATCH /change-requests/{id} requires at least
one (its own doc comment says that instead) — CLAUDE.md now flags that
these validation rules are per-entity, not a shared convention to copy
blindly.

Also updates openapi.yaml (9 new paths, ~24 new schemas), README.md,
and CLAUDE.md.

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

coderabbitai Bot commented Jul 31, 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: 50 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 Plus

Run ID: 62a906a8-7248-4b5d-8ff0-6e11557635ec

📥 Commits

Reviewing files that changed from the base of the PR and between e8f5cf8 and f699e07.

📒 Files selected for processing (2)
  • apps/customer-portal/backend-v2/internal/entity/types.go
  • apps/customer-portal/backend-v2/internal/handler/call_requests.go
📝 Walkthrough

Walkthrough

Backend-v2 now supports nine authenticated change-request and call-request routes. The change includes typed entity models, portal DTO mappings, validation, handlers, route registration, OpenAPI schemas, and documentation.

Changes

Customer request API integration

Layer / File(s) Summary
API and entity contracts
apps/customer-portal/backend-v2/openapi.yaml, apps/customer-portal/backend-v2/internal/entity/types.go
Added typed contracts for change requests, call requests, approvals, references, pagination, scheduling, and updates. Added the corresponding OpenAPI operations and schemas.
Entity clients and portal mappings
apps/customer-portal/backend-v2/internal/entity/change_requests.go, apps/customer-portal/backend-v2/internal/entity/call_requests.go, apps/customer-portal/backend-v2/internal/dto/change_request.go, apps/customer-portal/backend-v2/internal/dto/call_request.go
Added entity-service methods and DTO mappings for creation, search, retrieval, updates, and approval workflows. Customer update fields exclude internal and agent-controlled fields.
Handlers and route wiring
apps/customer-portal/backend-v2/internal/handler/change_requests.go, apps/customer-portal/backend-v2/internal/handler/call_requests.go, apps/customer-portal/backend-v2/cmd/server/main.go
Added authentication, UUID and body validation, entity-service delegation, error mapping, response serialization, and authenticated route registration.
Architecture and endpoint documentation
apps/customer-portal/backend-v2/CLAUDE.md, apps/customer-portal/backend-v2/README.md
Updated the route inventory, module descriptions, endpoint documentation, curl examples, and field-validation guidance.

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

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant ChangeRequestHandler
  participant EntityClient
  participant ServiceNow
  Client->>ChangeRequestHandler: Send change-request operation
  ChangeRequestHandler->>EntityClient: Validate and delegate request
  EntityClient->>ServiceNow: Send typed HTTP request
  ServiceNow-->>EntityClient: Return typed response
  EntityClient-->>ChangeRequestHandler: Return entity result
  ChangeRequestHandler-->>Client: Return mapped portal response
Loading

Possibly related PRs

Suggested labels: Area/Backend

Suggested reviewers: cloby99, dilshanfardil

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the implementation and test plan but omits most required template sections, including purpose, goals, documentation, security checks, and test environment. Complete the required template sections, or mark them N/A with brief explanations where they do not apply.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: adding change-request and call-request modules to the customer portal.
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.

@github-actions github-actions Bot added App/Customer Portal Type/New Feature Represents a request or task for a new feature labels Jul 31, 2026
@Rashmika998

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

🧹 Nitpick comments (1)
apps/customer-portal/backend-v2/internal/handler/change_requests.go (1)

30-52: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding handler tests for the new endpoints.

The local interface makes the handler easy to fake. Table-driven tests for the 401 path, the UUID guard, the "at least one field" guard, the decision-value guard, and the upstream-error mapping would lock in the validation cardinality described in CLAUDE.md. The same gap exists in internal/handler/call_requests.go.

🤖 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/customer-portal/backend-v2/internal/handler/change_requests.go` around
lines 30 - 52, The new change-request endpoints lack handler coverage for
validation and error behavior. Add table-driven tests using a fake
entityChangeRequestClient to cover the 401 path, UUID validation,
at-least-one-field validation, decision-value validation, and upstream-error
mapping; add equivalent coverage for the corresponding handlers in
call_requests.go, following the cardinality requirements in CLAUDE.md.
🤖 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/customer-portal/backend-v2/internal/entity/types.go`:
- Around line 969-984: The SearchChangeRequestsFilters fields ClosedStartDate
and ClosedEndDate currently decode directly as time.Time and reject non-RFC3339
client values. Change these fields to string-compatible optional representations
that preserve absent, null, and provided-value states, while keeping
SearchChangeRequestsRequest decoding successful for client-supplied date
strings.

In `@apps/customer-portal/backend-v2/internal/handler/call_requests.go`:
- Around line 64-70: The call-request handlers must enforce the required OpenAPI
body fields before invoking the entity service. In CreateCallRequest, validate
caseId with uuidRe, require a non-empty reason and utcTimes, and require
durationInMinutes to be positive; in SearchCallRequests, validate caseId with
uuidRe before calling the service. Reject invalid payloads using the existing
bad-request response pattern.

---

Nitpick comments:
In `@apps/customer-portal/backend-v2/internal/handler/change_requests.go`:
- Around line 30-52: The new change-request endpoints lack handler coverage for
validation and error behavior. Add table-driven tests using a fake
entityChangeRequestClient to cover the 401 path, UUID validation,
at-least-one-field validation, decision-value validation, and upstream-error
mapping; add equivalent coverage for the corresponding handlers in
call_requests.go, following the cardinality requirements in CLAUDE.md.
🪄 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: a733a3e9-2584-4034-94e0-75fe5e57bc30

📥 Commits

Reviewing files that changed from the base of the PR and between d85bf42 and e8f5cf8.

📒 Files selected for processing (11)
  • apps/customer-portal/backend-v2/CLAUDE.md
  • apps/customer-portal/backend-v2/README.md
  • apps/customer-portal/backend-v2/cmd/server/main.go
  • apps/customer-portal/backend-v2/internal/dto/call_request.go
  • apps/customer-portal/backend-v2/internal/dto/change_request.go
  • apps/customer-portal/backend-v2/internal/entity/call_requests.go
  • apps/customer-portal/backend-v2/internal/entity/change_requests.go
  • apps/customer-portal/backend-v2/internal/entity/types.go
  • apps/customer-portal/backend-v2/internal/handler/call_requests.go
  • apps/customer-portal/backend-v2/internal/handler/change_requests.go
  • apps/customer-portal/backend-v2/openapi.yaml

Comment thread apps/customer-portal/backend-v2/internal/entity/types.go
Comment thread apps/customer-portal/backend-v2/internal/handler/call_requests.go
…ation

Address CodeRabbit findings on PR wso2-open-operations#1314:
- SearchChangeRequestsFilters.ClosedStartDate/ClosedEndDate were *time.Time,
  causing json.Unmarshal to reject non-RFC3339 client values before reaching
  entity-service; changed to *string per this file's established convention
  for filter/date fields.
- CreateCallRequest and SearchCallRequests didn't validate required body
  fields (caseId UUID, reason, utcTimes, durationInMinutes), unlike the
  change-request handlers which already guard Subject/Decision.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@Rashmika998
Rashmika998 merged commit 9a76e25 into wso2-open-operations:dev-app-csm-portal Jul 31, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

App/Customer Portal Type/New Feature Represents a request or task for a new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants