avivijay19 opened a new pull request, #6487:
URL: https://github.com/apache/fineract/pull/6487
## Description
Moves the write side of `GroupsApiResource` and `CentersApiResource` to the
typed `CommandDispatcher` (same pattern as FINERACT-2288 Staff and the
Meetings/Notes migrations): one request DTO, `Command` and `CommandHandler` per
action, typed services (`GroupingTypesWriteService`, `GroupRolesWriteService`),
programmatic Jakarta validation, and per-command authorization in
`SecurityConfig` through a query-parameter-aware request matcher for the
`?command=` endpoints (existing `ACTIVATE_GROUP`, `ASSOCIATECLIENTS_GROUP`, …
authorities). The bulk-import handlers dispatch typed requests; the
client-transfer and collection-sheet services each gain one typed adapter
method (`transferClientsBetweenGroups(request)`,
`saveGroupCollectionSheet(request)`), other callers untouched. The legacy path
— the 22 `@CommandType` handlers (including
`TransferClientsBetweenGroupsCommandHandler`) plus the unreferenced
`UnassignStaffFromCenterCommandHandler`, the Gson validators,
`GroupingTypesWritePlat
formService`, `GroupRolesWritePlatformService`, the `CommandWrapperBuilder`
group/center builders and the hand-written `GroupsApiResourceSwagger` /
`CentersApiResourceSwagger` stubs — is removed.
Request and write-response schemas are now generated from the real classes,
and the read schemas reference the real DTOs (`GroupGeneralData`, `CenterData`,
`GroupsPageResponse`, `CentersPageResponse`, `AccountSummaryCollectionData`)
instead of the stubs — this closes the gaps reported in FINERACT-2832
(`accountNo` on the list items; `staffId`, `centerId`, `clientMembers`,
`datatables` on the create request) by construction. The read endpoints
themselves are unchanged: they keep the existing JSON serializer, `?fields=`
support and date format; their `READ_GROUP` / `READ_CENTER` check moves from
the resource into `SecurityConfig`, scoped to the routes these two resources
serve.
Wire contract: same URLs, methods, query parameters and `?command=` values,
same field names, dates, validation rules and error-body shape. Verified with
the existing integration suites (GroupTest, CenterIntegrationTest,
LoanReschedulingWithinCenterTest, GroupSavingsIntegrationTest,
GroupLoanIntegrationTest, MakercheckerTest, AccountNumberPreferencesTest) and
by exercising every write endpoint and `?command=` value over HTTP, including
the roles, client-transfer, collection-sheet and bulk-import paths, which have
no integration suite.
Deliberate differences, consistent with the other CommandDispatcher
migrations:
- maker-checker no longer applies to `*_GROUP` / `*_CENTER` tasks, and the
legacy webhook events for `GROUP` / `CENTER` no longer fire;
- audit is written to `m_command` instead of `m_portfolio_command_source`;
- unknown keys in a request body are ignored instead of rejected with 400;
- validation errors keep the `{"errors":[{parameterName,…}]}` shape but
carry the constraint's `org.apache.fineract.portfolio.group.<parameter>.<rule>`
globalisation codes instead of `validation.msg.group.<parameter>.…`; the
unsupported-`?command=` error lists the real command values (the legacy list
was incomplete and contained the typo `updateassignRole`);
- `PUT /groups/{id}` and `PUT /centers/{id}` with an explicit `"staffId":
null` / `"centerId": null` no longer unassign — use `?command=unassignStaff` /
`disassociateGroups` as before;
- `DELETE /groups/{id}` and `?command=unassignStaff` previously returned
`officeId` and `groupId` swapped; they now carry the correct values;
- `POST /groups` accepts `centerId` without `officeId` (the office is taken
from the centre), matching what the service always did;
- `?command=transferClients` rejects an empty `clients` list with 400
(legacy silently did nothing);
- `?command=generateCollectionSheet` now requires `READ_GROUP` /
`READ_CENTER` (legacy checked authentication only);
- OpenAPI schema names change (`PostGroupsRequest` → `GroupCreateRequest`,
`GetGroupsGroupIdResponse` → `GroupGeneralData`, …), so the api-compatibility
check reports renames.
Authorization hardening for these two resources: the matchers accept a
`?command=` value with surrounding whitespace and a trailing slash on the path,
exactly as the resource and Jersey do, so a request cannot reach the handler
without passing the matcher. Note for follow-up: the matchers of the
already-migrated Staff/Meetings/Notes resources do not tolerate a trailing
slash while Jersey does; that is outside this ticket.
Also worth knowing: a `?command=` request with no body now gets a 400 (the
typed request must be present; send `{}` for `unassignRole` / `unassignStaff`),
where the legacy resource tolerated an empty body; and a missing `roleId` on
`updateRole` / `unassignRole` still 500s exactly as on develop.
Observed while testing, not changed here: `?command=generateCollectionSheet`
on both `/groups/{id}` and `/centers/{id}` fails on PostgreSQL with `operator
does not exist: boolean = integer` (`CollectionSheetReadPlatformServiceImpl`),
on develop as well.
## Checklist
- [x] Write the commit message as described in
https://github.com/apache/fineract/#pull-requests
- [x] Acknowledge that we will not review PRs that are not passing the build
- [x] Create/update unit or integration tests
- [x] Follow coding conventions
- [x] Add required Swagger annotation and update API documentation
- [x] Submission is not a "code dump"
- [x] Run the full CI locally
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]