Fix Phase 3 + Phase 4 create payload shapes to match backend schemas - #12
Fix Phase 3 + Phase 4 create payload shapes to match backend schemas#12KDwevedi wants to merge 9 commits into
Conversation
Backend schema is registered as RAINMAKER-PGR.ServiceDefs (dash). Verified on naipepea, bomet — no underscore variant exists. Fixes #1 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…yload common-masters.Designation requires description and expects department as string[]. Configurator was sending neither — creation returned INVALID_REQUEST_TYPE1 and INVALID_REQUEST_REQUIRED2. - Designation / DesignationExcelRow: add description, change department to string[] to match schema - createDesignation: pass description through - parseDesignationExcel: accept description column (fallback to name), split department on commas to allow multi-department assignments Fixes #2 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
RAINMAKER-PGR.ServiceDefs schema requires `name` (not `serviceName`) and `keywords`. Configurator was sending `serviceName` (rejected as extraneous) and no `keywords` — creation returned INVALID_REQUEST_ADDITIONALPROPERTIES3 and REQUIRED1/2 errors. - ComplaintType / ComplaintTypeExcelRow: rename serviceName→name, add keywords - createComplaintType / getComplaintTypes: swap field names in payloads - parseComplaintTypeExcel: accept name column (fallback to legacy serviceName alias for existing templates), accept keywords column (default to name.toLowerCase() comma-split) - Phase3Page preview + progress list: use type.name - localization service: rename serviceName param to name for consistency Fixes #3 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
HRMS service rejects any _create payload without user.dob with NotNull.employeeRequest.employees[0].user.dob. Configurator's buildEmployee omitted it entirely, so every Phase 4 employee import failed on the first row. - EmployeeExcelRow: add optional dob column - buildEmployee: accept dob input; default to 1990-01-01 UTC when neither form nor sheet provided one, with a comment explaining why - parseEmployeeExcel: accept dob/DOB/dateOfBirth columns - Phase4Page: thread dob from Excel row into buildEmployee Future cleanup: surface dob as a proper form field / optional-per-employee in the Excel template generator. Fixes #4 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ 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 |
tenant.tenants schema requires `tenantId` in the `data` object (in
addition to the MDMS wrapper's tenantId). It stores the parent/root
tenant the city lives under — for `ke.testzone` that's `ke`.
Configurator was omitting it, so every Phase 1 upload returned:
{"code":"INVALID_REQUEST_REQUIRED1","message":"required key [tenantId] not found"}
Set tenantId = stateTenantId (the session tenant, which is the root).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Adding a 5th fix: Backend response pre-fix: {"Errors":[{"code":"INVALID_REQUEST_REQUIRED1","message":"required key [tenantId] not found"}]}Commit Rebuilt + redeployed on naipepea — new bundle |
/boundary/_search returns boundary *entities* by code and doesn't walk the hierarchy. Phase 4 called it expecting a full tree and got 0 results even though boundaries were present. The correct endpoint is /boundary-relationships/_search with query params (tenantId, hierarchyType, includeChildren=true). Swap to it. Side effects: - flattenBoundaries: dedupe by code because the relationships endpoint returns each child twice under its parent (known backend quirk) - carry hierarchyType down from the TenantBoundary wrapper into each flattened boundary, since the children don't always have it set Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
6th commit added: Verified on naipepea: post-fix bundle |
The previous fix (11004e0) updated parseDesignationExcel + service + types to include description, but Phase3Page was still mapping the parsed row to a subset {code, name, department, active} — stripping description before handing to createDesignations. Result: designation creates kept silently 4xx'ing with "required key [description] not found" even on the latest bundle. Adding description to the shape sent into createDesignations. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The boundary-service sometimes returns "already exists" / "DUPLICATE" errors for rows that never actually persisted (stale cache between the boundary-service and the eventually-consistent Kafka persister). The current FE catches any error string containing "already exists" and returns true, which makes Phase 2 silently claim success while leaving nothing in the DB — Phase 4 then reports "Boundaries: 0 loaded" on a tree the user thought they just built. Swap the blanket swallow for verify-then-swallow: on "already exists" errors, search for the record. If found, swallow (idempotent re-run is fine). If not, throw a clearer error so the UI can surface the real problem. Same treatment for createBoundaryEntity and createBoundaryRelationship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Phase 2 never fired /boundary-relationships/_create calls in the most recent live walk — root cause is createHierarchy casting the backend response to a single BoundaryHierarchy when it's actually an array. selectedHierarchy.hierarchyType then came out undefined, and createBoundary's `if (boundary.hierarchyType && boundary.boundaryType)` guard skipped the relationship call for all 4 boundaries. Unwrap the array before returning. Phase 3 is still silently 400'ing "required key [description] not found" even with the f897c97 fix in place. The bundle has the right code path, but the live request somehow lacks the field. Add a console.log of the payload handed to createDesignations so the next failed walk surfaces exactly what the browser is sending — will remove once diagnosed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Superseded by work targeting the extracted |
Summary
Walked the configurator onboarding flow end-to-end against a live naipepea backend on 2026-04-21. Phase 1 (Tenant) and Phase 2 (Boundaries) worked. Phase 3 (Departments / Designations / Complaint Types) and Phase 4 (Employees) were broken — the FE was sending payloads that the backend rejected.
All four bugs are FE-only. The backend schemas are the source of truth; the FE just needs to match them.
Fixes (4 commits, one per bug)
a7782a17RAINMAKER_PGR.ServiceDefs→RAINMAKER-PGR.ServiceDefs(1-line config)11004e05description, changedepartmenttostring[]36213af3serviceName→name, add requiredkeywordsdd309bdauser.dob(HRMS Java@NotNull)Each commit is self-contained and reviewable in under 5 minutes.
Reproduction (before this PR)
Verification
Will re-walk the full onboarding flow with a disposable tenant (
ke.bananaland-<timestamp>) against naipepea after merge to confirm all four phases complete end-to-end. Dummy data cleanup via the same SQL pattern used in the pre-PR verification (available on request).Test plan
descriptioncolumn → falls back toname(backwards compat)keywordscolumn → auto-generated fromname.toLowerCase().split(/\s+/).join(',')serviceNamecolumn header → parser falls back, still worksdobcolumn → parsed and threaded throughFollow-ups (out of scope here)
mdmsService.create*off the live MDMS schema definition via/mdms-v2/schema/v1/_searchinstead of hand-written field lists. Design inNai Pepea/issues/FIX-PLAN.md(Layer B). Would have caught all three of Add local-setup: Docker Compose dev environment #1-feat: add Keycloak auth adapter for Google SSO #3 at FE-build time.generateUsername()inhrmsServiceis effectively dead code — HRMS overridesuserNamewithemployee.codeon create. Worth a docstring note or removal.Closes #1, closes #2, closes #3, closes #4.