[Customer Entity] Add GET /cases/{id} with enriched CaseView response - #822
Conversation
…ses/{id} and search responses
…PI spec with CaseView response
📝 WalkthroughWalkthroughThe PR adds enriched case view types (CaseView, SearchCaseView and reference types), updates repository reads to join related tables and return these views, changes service method signatures, and updates the OpenAPI schemas and a startup log message. ChangesCase Enrichment with Related Entity Details
Sequence DiagramsequenceDiagram
participant Client
participant CaseService
participant CaseRepository
participant Database
Client->>CaseService: GetCaseByID(id)
CaseService->>CaseRepository: GetCaseByID(id)
CaseRepository->>Database: SELECT c JOIN users, projects, deployments, deployed_products, products, product_versions
Database-->>CaseRepository: enriched case row
CaseRepository-->>CaseService: domain.CaseView
CaseService-->>Client: domain.CaseView
Client->>CaseService: SearchCases(req)
CaseService->>CaseRepository: SearchCases(req)
CaseRepository->>Database: COUNT(*) and SELECT with JOINs + dynamic WHERE
Database-->>CaseRepository: count and enriched rows
CaseRepository-->>CaseService: []domain.SearchCaseView, total
CaseService-->>Client: SearchCasesResponse with CaseSearchView items
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 golangci-lint (2.12.2)level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies" 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 |
|
@coderabbitai review |
✅ Action performedReview finished.
|
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 (2)
entity-service/internal/repository/case_repo.go (1)
289-333:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winDrop
user_nameand
SearchCasesintentionally omits those fields from the response, but this query still reads them for every row and discards them viaignoredUserID/ignoredEmail. On the bulk search path that widens PII access without changing the payload.Suggested diff
- `SELECT c.id, c.number, c.wso2_id, - c.subject, c.description, c.priority, c.issue_type, c.state, - c.created_at, c.updated_at, c.closed_at, - u.id, u.first_name || ' ' || u.last_name, u.user_name, u.email, - p.id, p.name, - d.id, d.name, - dp.id, prod.name || COALESCE(' ' || pv.version, '') + `SELECT c.id, c.number, c.wso2_id, + c.subject, c.description, c.priority, c.issue_type, c.state, + c.created_at, c.updated_at, c.closed_at, + u.id, u.first_name || ' ' || u.last_name, + p.id, p.name, + d.id, d.name, + dp.id, prod.name || COALESCE(' ' || pv.version, '') FROM cases c %s %s ORDER BY %s %s NULLS LAST, c.id LIMIT $%d OFFSET $%d`,- var cv domain.CaseView - var ignoredUserID, ignoredEmail string + var cv domain.CaseView if err := rows.Scan( &cv.ID, &cv.Number, &cv.Wso2ID, &cv.Subject, &cv.Description, &cv.Priority, &cv.IssueType, &cv.State, &cv.CreatedAt, &cv.UpdatedAt, &cv.ClosedAt, - &cv.CreatedByDetails.ID, &cv.CreatedByDetails.DisplayName, &ignoredUserID, &ignoredEmail, + &cv.CreatedByDetails.ID, &cv.CreatedByDetails.DisplayName, &cv.ProjectDetails.ID, &cv.ProjectDetails.Name, &cv.DeploymentDetails.ID, &cv.DeploymentDetails.Name, &cv.DeployedProductDetails.ID, &cv.DeployedProductDetails.DisplayName,Based on PR objectives,
/cases/searchis only supposed to exposecreatedBy.idandcreatedBy.displayName.🤖 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/repository/case_repo.go` around lines 289 - 333, The SELECT in dataQuery currently fetches user_name and email and then discards them into ignoredUserID/ignoredEmail in the rows.Scan, widening PII access; update the SQL string (the formatted query used to build dataQuery) to remove the two fields for the created-by user (user_name and email) and then remove the corresponding ignoredUserID and ignoredEmail from the rows.Scan call so Scan maps directly into CreatedByDetails.ID and CreatedByDetails.DisplayName; ensure the order of selected columns still matches the Scan arguments (see dataQuery, rows.Scan, ignoredUserID, ignoredEmail).entity-service/openapi.yaml (1)
968-1084:⚠️ Potential issue | 🟠 Major | ⚡ Quick winMark the guaranteed fields as required in the new schemas.
The Go/domain models make all of these fields mandatory except
closedAtand the GET-onlyUserRef.userId/UserRef.email. Withoutrequired, generated clients will treatcreatedBy,project,deployment,deployedProduct, and the core scalar fields as optional even though the service always populates them.Suggested diff
UserRef: type: object + required: [id, displayName] properties: id: type: string format: uuid @@ EntityRef: type: object + required: [id, name] properties: id: type: string format: uuid @@ DeployedProductRef: type: object + required: [id, displayName] properties: id: type: string format: uuid @@ CaseView: type: object + required: + - id + - number + - wso2Id + - subject + - description + - priority + - issueType + - state + - createdAt + - updatedAt + - createdBy + - project + - deployment + - deployedProduct properties: id: type: string format: uuidBased on learnings, the entity API contract is expected to guarantee non-optional response fields.
🤖 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 968 - 1084, Add JSON Schema "required" arrays to the new OpenAPI schemas so guaranteed response fields are non-optional: for UserRef mark id and displayName as required (do not mark userId or email), for EntityRef mark id and name required, for DeployedProductRef mark id and displayName required, for Case mark all core scalar fields and ids as required (e.g. id, number, wso2Id, createdBy, projectId, deploymentId, deployedProductId, subject, description, priority, issueType, state, createdAt, updatedAt — leave closedAt nullable/omitted), and for CaseView mark the response fields as required (e.g. id, number, wso2Id, subject, description, priority, issueType, state, createdAt, updatedAt, createdBy, project, deployment, deployedProduct — leave closedAt nullable); update the schemas UserRef, EntityRef, DeployedProductRef, Case, and CaseView accordingly so generated clients treat these fields as required.Source: Learnings
🤖 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/openapi.yaml`:
- Line 300: The OpenAPI spec currently reuses CaseView for both GET /cases/{id}
and /cases/search which hides that the two operations expose different createdBy
shapes; define two separate response schemas (e.g., CaseView and CaseSearchView)
under components.schemas with the differing createdBy sub-schemas
(CaseView.createdBy contains userId and email; CaseSearchView.createdBy contains
id and displayName), then update the response $ref for the GET /cases/{id}
operation (operationId like getCaseById) to point to CaseView and update the
/cases/search response (operationId like searchCases) to point to
CaseSearchView, and also replace any other $ref occurrences (the other instance
around the same schema reference) so generated clients see the redaction
boundary.
---
Outside diff comments:
In `@entity-service/internal/repository/case_repo.go`:
- Around line 289-333: The SELECT in dataQuery currently fetches user_name and
email and then discards them into ignoredUserID/ignoredEmail in the rows.Scan,
widening PII access; update the SQL string (the formatted query used to build
dataQuery) to remove the two fields for the created-by user (user_name and
email) and then remove the corresponding ignoredUserID and ignoredEmail from the
rows.Scan call so Scan maps directly into CreatedByDetails.ID and
CreatedByDetails.DisplayName; ensure the order of selected columns still matches
the Scan arguments (see dataQuery, rows.Scan, ignoredUserID, ignoredEmail).
In `@entity-service/openapi.yaml`:
- Around line 968-1084: Add JSON Schema "required" arrays to the new OpenAPI
schemas so guaranteed response fields are non-optional: for UserRef mark id and
displayName as required (do not mark userId or email), for EntityRef mark id and
name required, for DeployedProductRef mark id and displayName required, for Case
mark all core scalar fields and ids as required (e.g. id, number, wso2Id,
createdBy, projectId, deploymentId, deployedProductId, subject, description,
priority, issueType, state, createdAt, updatedAt — leave closedAt
nullable/omitted), and for CaseView mark the response fields as required (e.g.
id, number, wso2Id, subject, description, priority, issueType, state, createdAt,
updatedAt, createdBy, project, deployment, deployedProduct — leave closedAt
nullable); update the schemas UserRef, EntityRef, DeployedProductRef, Case, and
CaseView accordingly so generated clients treat these fields as required.
🪄 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: 1a6e70d8-e5ec-44d3-834c-f844e67aeb05
📒 Files selected for processing (6)
entity-service/cmd/api/main.goentity-service/internal/domain/entity.goentity-service/internal/repository/case_repo.goentity-service/internal/service/case_service.goentity-service/internal/service/interfaces.goentity-service/openapi.yaml
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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/domain/entity.go`:
- Around line 405-409: Change the search-result user reference to remove PII:
replace usages of UserIDEmailRef (and any struct named SearchCaseView or fields
named CreatedBy/createdBy that currently use email) with a compact reference
containing only ID and DisplayName (e.g., UserIDDisplayRef or struct fields ID
and DisplayName) so search/list endpoints do not expose emails; update the
struct definition(s) in entity.go (the current UserIDEmailRef and any duplicate
around the 460-477 region) and adjust SearchCaseView's CreatedBy type
accordingly, then mirror the same schema change in entity-service/openapi.yaml
so the /cases/search contract only returns {id, displayName} while GET
/cases/{id} can still return userId/email.
🪄 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: 6645b366-bb3c-4d07-832e-577833e085a6
📒 Files selected for processing (3)
entity-service/internal/domain/entity.goentity-service/internal/repository/case_repo.goentity-service/openapi.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
- entity-service/internal/repository/case_repo.go
- GET /cases/{id} now references CaseView (enriched FK objects) instead
of the flat Case schema, matching entity-service PR wso2-open-operations#822
- CaseSearchResponse items now reference CaseSearchView
- Add UserRef, UserIDEmailRef, EntityRef, DeployedProductRef, CaseView,
and CaseSearchView schemas
- nextStates (portal-injected) lives on CaseView only; removed from Case
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
GET /cases/{id}endpoint returning an enrichedCaseViewwith display refs forcreatedBy,project,deployment, anddeployedProductPOST /cases/searchresponse updated to use CaseView (search returns createdByDetails withidanddisplayNameonly; GET returns full userId and email too)port"Summary by CodeRabbit
New Features
Documentation
Chores