Skip to content

[Customer Portal][Backend] Add change request details endpoint and support soft delete in deployed product update - #276

Merged
sacheeramesh merged 3 commits into
wso2-open-operations:customer-portal-milestone-1from
Rashmika998:customer-portal-milestone-1-projects
Mar 2, 2026
Merged

sacheeramesh merged 3 commits into
wso2-open-operations:customer-portal-milestone-1from
Rashmika998:customer-portal-milestone-1-projects

Conversation

@Rashmika998

@Rashmika998 Rashmika998 commented Mar 2, 2026 •

Copy link
Copy Markdown
Contributor

Description

This PR introduces a new endpoint to retrieve change request details and enhances the deployed product update endpoint to support soft delete functionality.

Changes

1️⃣ Add Change Request Details Endpoint

  • Added endpoint to retrieve detailed information for a specific change request
  • Implemented validation and proper not-found handling
  • Ensured consistent response structure
  • Integrated service-layer logic

Reason:
Detailed change request information was not previously exposed via API. This endpoint enables:

  • Viewing complete change request data
  • Supporting UI detail pages
  • Improving change management workflows

2️⃣ Support Soft Delete in Deployed Product Update

  • Enhanced deployed product update endpoint to support soft delete
  • Introduced flag-based deactivation instead of physical deletion
  • Updated persistence logic accordingly
  • Ensured existing references remain intact

Reason:
Soft delete ensures:

  • Data integrity
  • Historical tracking
  • Avoidance of orphaned references
  • Safer lifecycle management of deployed products

Impact

  • New endpoint added (non-breaking enhancement)
  • Deployed product update logic enhanced
  • No physical deletions performed; records are marked inactive instead

Testing

  • Verified change request details retrieval
  • Tested not-found scenarios
  • Confirmed soft delete flag updates correctly
  • Validated no hard delete occurs
  • Performed regression testing on deployed product workflows

Related PRs

Summary by CodeRabbit

  • New Features

    • New endpoint to fetch detailed change request information.
    • New response format combining change request details with descriptive, plan and approval fields.
  • Improvements

    • Change requests now include product association and use typed/planned date fields.
    • Case search supports a "createdByMe" flag; mappings updated to include product and planned dates.
  • Bug Fixes

    • Validation added to prevent invalid deployed product update combinations.
  • Other

    • Choice list item IDs now accept string or int; deployed product payload gains optional active flag.

@coderabbitai

coderabbitai Bot commented Mar 2, 2026 •

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds a GET change-request-by-id endpoint, new ChangeRequestResponse types and mappings, date/product field changes, deployed-product update payload validation, and entity-level fetch logic. Several new functions and types appear duplicated in their respective files.

Changes

Cohort / File(s) Summary
Entity Types & Models
apps/customer-portal/backend/modules/entity/types.bal, apps/customer-portal/backend/modules/types/types.bal
Added ChangeRequestResponse (extends ChangeRequest), added product field, changed startDate/endDate to date-typed/planned fields, updated ChoiceListItem.id to `int
Entity Logic
apps/customer-portal/backend/modules/entity/entity.bal
Added `public isolated function getChangeRequestDetails(string idToken, string changeRequestId) returns ChangeRequestResponse
Validation Utilities
apps/customer-portal/backend/modules/entity/utils.bal
Added public isolated function validateDeployedProductUpdatePayload(DeployedProductUpdatePayload) returns string? with rules for active, cores, and tps. Function added twice in file.
Service API
apps/customer-portal/backend/service.bal
Added resource GET change-requests/[id] that authenticates, calls entity:getChangeRequestDetails, handles 401/403/404/500, returns mapped ChangeRequestResponse, and invokes inline deployed-product payload validation before updates.
Mapping & Helpers
apps/customer-portal/backend/utils.bal
Added public isolated function mapChangeRequestResponse(entity:ChangeRequestResponse) returns types:ChangeRequestResponse mapping entity response to API response shape, including planned dates, product and related entities.
Manifest
Ballerina.toml
Manifest file present in diff context (no substantive content changes reported).

Sequence Diagram

sequenceDiagram
    participant Client
    participant Service as Service API
    participant Auth as Auth Handler
    participant Entity as Entity Module
    participant Remote as Remote API

    Client->>Service: GET /change-requests/[id]
    Service->>Auth: Authenticate user
    alt Authentication Failed
        Auth-->>Service: 401 Unauthorized
        Service-->>Client: 401 Unauthorized
    else Authenticated
        Auth-->>Service: User context
        Service->>Entity: getChangeRequestDetails(idToken, id)
        Entity->>Remote: GET /change-requests/[id]
        alt Request Successful
            Remote-->>Entity: ChangeRequestResponse
            Entity-->>Service: ChangeRequestResponse
            Service->>Service: mapChangeRequestResponse()
            Service-->>Client: 200 ChangeRequestResponse
        else Not Found
            Remote-->>Entity: 404 Not Found
            Entity-->>Service: Error
            Service-->>Client: 404 Not Found
        else Forbidden
            Remote-->>Entity: 403 Forbidden
            Entity-->>Service: Error
            Service-->>Client: 403 Forbidden
        end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

Type/New Feature

Suggested reviewers

  • shayanmalinda
  • sacheeramesh

Poem

🐰 I hopped through code to fetch a request by id,
Dates and products now travel side by side,
Validators nibble cores and tps with care,
Mappers stitch responses tidy and fair,
Hooray — the change request hops safely there!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The PR description covers key changes and reasoning but deviates significantly from the template structure, missing Purpose, Goals, Approach, User stories, Release notes, and other required sections. Restructure the description to follow the template: add Purpose/Goals/Approach sections, include user stories, release notes, documentation links, and verification details for all required sections.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes both main changes: adding a change request details endpoint and supporting soft delete in deployed product updates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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 and usage tips.

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/customer-portal/backend/modules/entity/utils.bal`:
- Around line 233-248: The validator
validateDeployedProductUpdatePayload(DeployedProductUpdatePayload) is currently
isolated and never invoked; make it public (remove isolated and mark public) and
call it from the deployed-product PATCH handler immediately after parsing the
request payload; if the function returns a non-empty string, return an
http:BadRequest with that message (matching the pattern used by other endpoints
like deployment/case/call-request) so the request is rejected when validation
fails.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d4fbe2b and e001be8.

📒 Files selected for processing (6)
  • apps/customer-portal/backend/modules/entity/entity.bal
  • apps/customer-portal/backend/modules/entity/types.bal
  • apps/customer-portal/backend/modules/entity/utils.bal
  • apps/customer-portal/backend/modules/types/types.bal
  • apps/customer-portal/backend/service.bal
  • apps/customer-portal/backend/utils.bal

Comment thread apps/customer-portal/backend/modules/entity/utils.bal Outdated

@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

🧹 Nitpick comments (1)
apps/customer-portal/backend/utils.bal (1)

714-756: Consider extracting shared change-request field mapping.

mapChangeRequestResponse() and mapChangeRequestSearchResponse() now duplicate a large common mapping block, which increases drift risk over time.

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/customer-portal/backend/modules/entity/types.bal`:
- Line 269: item.id is declared as int|string so the direct comparisons at the
filter (the unsafe expression comparing item.id != entity:caseStateIds.closed &&
item.id != entity:caseStateIds.solutionProposed) can fail when item.id is a
string; normalize item.id to a consistent type before comparing (e.g., call
item.id.toString() or cast the constants to strings) so both comparisons use the
same representation; update the condition that references item.id, and mirror
the normalization approach used later in the select clause (where
item.id.toString() is used) to ensure filtering correctly excludes
caseStateIds.closed and caseStateIds.solutionProposed.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e001be8 and eed9049.

📒 Files selected for processing (5)
  • apps/customer-portal/backend/modules/entity/types.bal
  • apps/customer-portal/backend/modules/entity/utils.bal
  • apps/customer-portal/backend/modules/types/types.bal
  • apps/customer-portal/backend/service.bal
  • apps/customer-portal/backend/utils.bal
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/customer-portal/backend/modules/entity/utils.bal

Comment thread apps/customer-portal/backend/modules/entity/types.bal

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

🧹 Nitpick comments (1)
apps/customer-portal/backend/utils.bal (1)

715-757: Extract shared change-request mapping to reduce drift risk.

mapChangeRequestResponse duplicates most of the reference/date/state/impact mapping already present in mapChangeRequestSearchResponse. A small shared helper for common fields would reduce future divergence bugs.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/customer-portal/backend/utils.bal` around lines 715 - 757,
mapChangeRequestResponse duplicates much of the reference/date/state/impact
mapping found in mapChangeRequestSearchResponse; extract the shared mapping into
a small helper (e.g., mapCommonChangeRequestFields or buildChangeRequestBase)
that accepts a ChangeRequestResponse (or its common subset) and returns the
common mapped fields (project, case, deployment, deployedProduct, product,
state, impact, id/number/title/dates/duration/flags/etc.); then have
mapChangeRequestResponse and mapChangeRequestSearchResponse call that helper and
merge any function-specific fields (description, justification, etc.) to avoid
future drift and keep naming consistent with the existing symbols
mapChangeRequestResponse and mapChangeRequestSearchResponse.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@apps/customer-portal/backend/utils.bal`:
- Around line 715-757: mapChangeRequestResponse duplicates much of the
reference/date/state/impact mapping found in mapChangeRequestSearchResponse;
extract the shared mapping into a small helper (e.g.,
mapCommonChangeRequestFields or buildChangeRequestBase) that accepts a
ChangeRequestResponse (or its common subset) and returns the common mapped
fields (project, case, deployment, deployedProduct, product, state, impact,
id/number/title/dates/duration/flags/etc.); then have mapChangeRequestResponse
and mapChangeRequestSearchResponse call that helper and merge any
function-specific fields (description, justification, etc.) to avoid future
drift and keep naming consistent with the existing symbols
mapChangeRequestResponse and mapChangeRequestSearchResponse.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eed9049 and 682b89e.

📒 Files selected for processing (1)
  • apps/customer-portal/backend/utils.bal

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

App/Customer Portal Area/Backend Type/Improvement Marks enhancements or improvements to existing features

Projects

Status: Staging Deployed

Development

Successfully merging this pull request may close these issues.

2 participants