[Customer Portal][BE] Add instance-based search endpoints for projects, deployments, and products - #459
Conversation
📝 WalkthroughWalkthroughAdds instance search support: new instance-focused types and mapping, three POST instance-search API endpoints, an entity-layer Changes
Sequence Diagram(s)sequenceDiagram
actor Client
participant Service as Service Layer
participant Entity as Entity Module
participant Backend as csEntityClient
Client->>Service: POST /{scope}/{id}/instances/search\n(InstanceSearchPayload)
activate Service
Service->>Service: extract auth (idToken)\nmap filters (startDate,endDate) + id-specific array
Service->>Entity: searchInstances(idToken, payload)
activate Entity
Entity->>Backend: POST /instances/search\n(transformed payload, auth headers)
activate Backend
Backend-->>Entity: InstancesResponse
deactivate Backend
Entity-->>Service: InstancesResponse | error
deactivate Entity
Service->>Service: mapInstancesResponse(response)
Service-->>Client: 200|400|401|403|500 with mapped body
deactivate Service
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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: 3
🧹 Nitpick comments (1)
apps/customer-portal/backend/modules/entity/types.bal (1)
979-996: Mutual exclusivity constraint is documented but not enforced.The comments indicate that
projectIds,deploymentIds, anddeployedProductIdsare mutually exclusive, but there's no constraint annotation to enforce this. If simultaneous presence of multiple ID arrays could cause unexpected behavior, consider adding server-side validation in the service layer.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/customer-portal/backend/modules/entity/types.bal` around lines 979 - 996, The InstanceSearchPayload documents that projectIds, deploymentIds, and deployedProductIds are mutually exclusive but there is no enforcement; add server-side validation wherever InstanceSearchPayload is consumed (the instance search handler/service) to check these three fields (projectIds, deploymentIds, deployedProductIds) and ensure at most one is present/non-empty, returning a clear validation error (400) if more than one is supplied; update unit/integration tests for the instance search flow to cover conflicting arrays.
🤖 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`:
- Around line 1044-1051: The InstancesResponse record type is missing the open
rest field used for forward compatibility; update the InstancesResponse type
definition (symbol: InstancesResponse) to include the rest field `json...;`
(consistent with DeploymentsResponse and DeployedProductsResponse) so additional
unknown JSON fields from the entity service won’t break deserialization.
In `@apps/customer-portal/backend/openapi.yaml`:
- Around line 275-307: The 200 responses for the instance-search endpoints only
declare "Ok" with no response body; update the OpenAPI contract to return a
documented paginated instance list by changing the "200" responses for the
/projects/{id}/instances/search endpoint (operationId:
postProjectsIdInstancesSearch) to include content: application/json with schema:
$ref: '#/components/schemas/InstancesResponse', and add the missing
components.schemas entries for Instance and InstancesResponse (e.g.,
InstancesResponse should include items: { type: array, items: { $ref:
'#/components/schemas/Instance' } } plus pagination fields) so the success body
(including empty results) is fully specified and reference these new schemas
from the other instance-search endpoints as well.
In `@apps/customer-portal/backend/service.bal`:
- Around line 625-629: The scoped search calls (e.g., the call to
entity:searchInstances) currently overwrite the entire filters record, dropping
startDate/endDate; modify the call to merge/clone the existing payload.filters
and only set the scoped id array (projectIds / deploymentIds /
deployedProductIds) so startDate and endDate are preserved. Concretely, create a
new filters record from payload.filters (or default {}) and assign
filters.projectIds = [id] (or the appropriate id field) then pass that filters
object into the entity:searchInstances (and the analogous search calls at the
other two sites) along with payload.pagination; reference InstanceSearchPayload,
filters, startDate, endDate, projectIds, and entity:searchInstances to locate
the changes.
---
Nitpick comments:
In `@apps/customer-portal/backend/modules/entity/types.bal`:
- Around line 979-996: The InstanceSearchPayload documents that projectIds,
deploymentIds, and deployedProductIds are mutually exclusive but there is no
enforcement; add server-side validation wherever InstanceSearchPayload is
consumed (the instance search handler/service) to check these three fields
(projectIds, deploymentIds, deployedProductIds) and ensure at most one is
present/non-empty, returning a clear validation error (400) if more than one is
supplied; update unit/integration tests for the instance search flow to cover
conflicting arrays.
🪄 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: 36fcc9b4-e60e-4787-b1c2-39718779639c
📒 Files selected for processing (6)
apps/customer-portal/backend/modules/entity/entity.balapps/customer-portal/backend/modules/entity/types.balapps/customer-portal/backend/modules/types/types.balapps/customer-portal/backend/openapi.yamlapps/customer-portal/backend/service.balapps/customer-portal/backend/utils.bal
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/customer-portal/backend/service.bal (1)
450-489:⚠️ Potential issue | 🟠 MajorPreserve filter behavior on the existing deployment/product search routes.
These handlers now forward only the scoped ID plus pagination. That changes
/projects/{id}/deployments/searchand/deployments/{id}/products/searchfrom filtered searches to full scoped list calls for any client still relying on the previous request filters. Keep merging the supported filters here, or version the contract instead of changing the behavior in place.Also applies to: 2363-2400
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/customer-portal/backend/service.bal` around lines 450 - 489, The handler resource function post projects/[entity:IdString id]/deployments/search is currently overwriting client-sent filters by only passing projectIds and pagination to entity:searchDeployments; preserve previous behavior by merging payload.filters (if present) with the forced filter projectIds: [id] before calling entity:searchDeployments (e.g., construct a filters object that spreads payload.filters and then sets/merges projectIds to include id), then pass that merged filters plus payload.pagination; apply the same merge fix to the analogous /deployments/{id}/products/search handler so existing clients' filters are honored while still scoping by the path id.
🧹 Nitpick comments (1)
apps/customer-portal/backend/service.bal (1)
608-673: Factor the three instance-search handlers into one helper.The new project/deployment/deployed-product handlers duplicate the same payload shaping, status mapping, and
mapInstancesResponse(...)flow. Centralizing that logic will make future filter or status changes much less likely to drift between scopes.Also applies to: 866-931, 2597-2663
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/customer-portal/backend/service.bal` around lines 608 - 673, Duplicate instance-search logic across the project/deployment/deployed-product handlers should be consolidated into a single helper to avoid drift; create a helper (e.g., handleInstancesSearch) that accepts the caller context values (userInfo, targetId, payload) and encapsulates the payload shaping, calling entity:searchInstances, status-to-response mapping (forbidden, unauthorized, bad request, other errors), logging, and final mapInstancesResponse(...) return; replace the duplicated blocks in resource function post projects/[entity:IdString id]/instances/search and the analogous project/deployment/deployed-product handlers with calls to this helper so all shared behavior (including customError messages and use of getStatusCode(instances)) is centralized.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@apps/customer-portal/backend/service.bal`:
- Around line 450-489: The handler resource function post
projects/[entity:IdString id]/deployments/search is currently overwriting
client-sent filters by only passing projectIds and pagination to
entity:searchDeployments; preserve previous behavior by merging payload.filters
(if present) with the forced filter projectIds: [id] before calling
entity:searchDeployments (e.g., construct a filters object that spreads
payload.filters and then sets/merges projectIds to include id), then pass that
merged filters plus payload.pagination; apply the same merge fix to the
analogous /deployments/{id}/products/search handler so existing clients' filters
are honored while still scoping by the path id.
---
Nitpick comments:
In `@apps/customer-portal/backend/service.bal`:
- Around line 608-673: Duplicate instance-search logic across the
project/deployment/deployed-product handlers should be consolidated into a
single helper to avoid drift; create a helper (e.g., handleInstancesSearch) that
accepts the caller context values (userInfo, targetId, payload) and encapsulates
the payload shaping, calling entity:searchInstances, status-to-response mapping
(forbidden, unauthorized, bad request, other errors), logging, and final
mapInstancesResponse(...) return; replace the duplicated blocks in resource
function post projects/[entity:IdString id]/instances/search and the analogous
project/deployment/deployed-product handlers with calls to this helper so all
shared behavior (including customError messages and use of
getStatusCode(instances)) is centralized.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: ec66acc7-4dc7-4968-9354-a4c4ed601959
📒 Files selected for processing (2)
apps/customer-portal/backend/modules/entity/types.balapps/customer-portal/backend/service.bal
There was a problem hiding this comment.
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 (1)
apps/customer-portal/backend/modules/types/types.bal (1)
611-639:⚠️ Potential issue | 🟠 MajorKeep
DeployedProductbackward-compatible while adding instance search.The new instance-search endpoints are additive, but slimming
DeployedProducthere meansapps/customer-portal/backend/utils.bal:270-304now stops returning the oldinstanceCount/instancesdata on the existing deployed-products endpoints. That is a contract change for current callers, so this needs deprecation/versioning or a separate migration step instead of landing as part of an additive PR.Based on learnings, validate public API surfaces and corresponding mapping logic across all BAL file changes.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/customer-portal/backend/modules/types/types.bal` around lines 611 - 639, The DeployedProduct type was slimmed and removed the existing instanceCount/instances fields causing a breaking contract; restore backward compatibility by either (A) reintroducing the instanceCount:int? and instances:Instance[]? fields into DeployedProduct and mark them deprecated in comments, or (B) create a new DeployedProductV2 (or similar) that adds the new instance-search fields while leaving the original DeployedProduct unchanged; then update the mapping logic that builds deployed-product responses (the code that previously populated instanceCount and instances in apps/customer-portal/backend/utils.bal) to continue filling the original fields for existing endpoints and populate the new type/fields only for the new instance-search endpoints. Ensure all public API mapping functions reference the correct type to avoid changing responses for current callers.
🤖 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`:
- Around line 979-996: InstanceSearchPayload documents projectIds,
deploymentIds, and deployedProductIds as mutually exclusive but the payload is
forwarded unchanged by searchInstances(...), so add validation before
forwarding: in the code path that receives an InstanceSearchPayload (e.g.,
inside searchInstances or the caller that forwards it upstream), count how many
of payload.filters?.projectIds, payload.filters?.deploymentIds, and
payload.filters?.deployedProductIds are non-empty and if more than one is
present return/throw a bad-request validation error; alternatively refactor
InstanceSearchPayload into a discriminated union/record variants where only one
of the three scoped-filter fields exists and update callers to use the new
variant. Ensure the validation runs before any upstream/post call to avoid
sending ambiguous queries.
---
Outside diff comments:
In `@apps/customer-portal/backend/modules/types/types.bal`:
- Around line 611-639: The DeployedProduct type was slimmed and removed the
existing instanceCount/instances fields causing a breaking contract; restore
backward compatibility by either (A) reintroducing the instanceCount:int? and
instances:Instance[]? fields into DeployedProduct and mark them deprecated in
comments, or (B) create a new DeployedProductV2 (or similar) that adds the new
instance-search fields while leaving the original DeployedProduct unchanged;
then update the mapping logic that builds deployed-product responses (the code
that previously populated instanceCount and instances in
apps/customer-portal/backend/utils.bal) to continue filling the original fields
for existing endpoints and populate the new type/fields only for the new
instance-search endpoints. Ensure all public API mapping functions reference the
correct type to avoid changing responses for current callers.
🪄 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: 9e2a4e2f-ecb9-47a2-88a4-76a0a5fa705c
📒 Files selected for processing (3)
apps/customer-portal/backend/modules/entity/types.balapps/customer-portal/backend/modules/types/types.balapps/customer-portal/backend/utils.bal
7740378
into
wso2-open-operations:dev-app-customer-portal-v1.0.x
Summary
This PR introduces instance-based search endpoints for projects, deployments, and products.
Endpoints Added
Changes
Functionality
These endpoints enable:
Reason
Instance-level data retrieval was not previously exposed via API.
These endpoints provide:
Testing
Impact
Summary by CodeRabbit
New Features
Improvements