Skip to content

MXWAR-82: fix(groups): staffId, externalId and dates silently dropped in create and edit group API calls#110

Open
adity-a34 wants to merge 2 commits into
openMF:devfrom
adity-a34:MXWAR-82-fix-groups-silent-field-drop
Open

MXWAR-82: fix(groups): staffId, externalId and dates silently dropped in create and edit group API calls#110
adity-a34 wants to merge 2 commits into
openMF:devfrom
adity-a34:MXWAR-82-fix-groups-silent-field-drop

Conversation

@adity-a34
Copy link
Copy Markdown

@adity-a34 adity-a34 commented Apr 25, 2026

Description

The generated PostGroupsRequest and PutGroupsGroupIdRequest types from fineract.yaml are missing several fields the Fineract API actually accepts. This caused two silent data-loss bugs:

  • CreateGroups.tsx => staffId, externalId, submittedOnDate, and activationDate were commented out to satisfy TypeScript and never sent to the API.
  • EditGroups.tsx => the full payload was built correctly but only { name } was passed to groupsApi.update13(), discarding everything else.

Fix: extended the generated types locally in types.ts with ExtendedPostGroupsRequest and ExtendedPutGroupsRequest, and updated both components to pass the complete payload.

Related issues and discussion

[MXWAR-82](https://mifosforge.jira.com/browse/MXWAR-82)

Screenshots, if any

Before: Edit Group PUT payload:
Screenshot 2026-04-25 101819

{ "name": "Bug Test grp" }

After: Edit Group PUT payload:
Screenshot 2026-04-25 102813

{
  "name": "Bug Test grp", "staffId": 1, "externalId": "EXT-111",
  "submittedOnDate": "08 April 2026", "activationDate": "24 April 2026",
  "dateFormat": "dd MMMM yyyy", "locale": "en"
}

Checklist

  • If you have multiple commits please combine them into one commit by squashing them.
  • Read and understood the contribution guidelines at CONTRIBUTING.md.

Summary by CodeRabbit

  • New Features
    • Group creation and editing now include extra metadata: staff assignment, external identifiers, submission and activation dates.
    • Activation date is submitted only for active groups when provided; date values are normalized and requests now include consistent date format and locale settings for reliable handling.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 25, 2026

📝 Walkthrough

Walkthrough

The pull request extends group create/update payloads by adding two extended request interfaces with optional fields (staffId, externalId, submittedOnDate, activationDate, dateFormat, locale). Create and edit handlers now build and send these extended-typed payloads, normalizing and conditionally including fields before API calls.

Changes

Cohort / File(s) Summary
Type Definitions
src/pages/groups/types.ts
Added ExtendedPostGroupsRequest and ExtendedPutGroupsRequest that extend generated API request types with optional fields: staffId, externalId, submittedOnDate, activationDate, dateFormat, locale.
Create handler
src/pages/groups/CreateGroups.tsx
Create payload now includes optional fields (converts staffId to number or undefined, trims and maps empty externalId to undefined), conditionally includes activationDate only when active and provided, normalizes dates via inputToFineractDate, sets dateFormat/locale, and casts to ExtendedPostGroupsRequest.
Edit handler
src/pages/groups/groups-view/group-actions/EditGroups.tsx
Edit form initializes externalId from fetched data; on submit constructs a strongly typed ExtendedPutGroupsRequest including name, locale, dateFormat, optional staffId, optional normalized submittedOnDate/activationDate, maps empty externalId to undefined, and sends the full payload to the API (instead of only name).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped in code with careful paws,
Trimmed the strings and fixed the laws,
Dates aligned in tidy rows,
Staff and IDs in gentle throes,
Groups now sprout where harmony grows.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main fix: addressing silently dropped optional fields (staffId, externalId, dates) in group create and edit API calls.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
src/pages/groups/groups-view/group-actions/EditGroups.tsx (1)

40-40: ⚠️ Potential issue | 🟡 Minor

externalId is never prefilled, and there is no way to clear an existing one.

The effect at lines 44–71 deliberately skips populating externalId from groupData (per the comment on line 66), so a user editing a group cannot see the current value. Combined with the conditional at line 95 (if (externalId.trim()) only adds it to the payload when non‑empty), this means:

  1. A user who only wants to change name but happens to type an externalId to "see what's there" will overwrite the existing one.
  2. There is no way for a user to clear an existing externalId through this form (empty input ⇒ field omitted ⇒ server keeps the old value).

Recommend prefilling from groupData.externalId (extending ExtendedGroupResponse if it isn't there yet) so the form reflects current state, and treating an explicit empty string as "clear" rather than "skip" if that operation is supported by the API.

Also applies to: 66-66, 95-95

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

In `@src/pages/groups/groups-view/group-actions/EditGroups.tsx` at line 40, The
form never pre-fills or lets users clear externalId: update the component to
initialize and sync externalId from groupData by setting useState to
groupData.externalId (and in the useEffect that currently skips externalId) and
ensure ExtendedGroupResponse includes externalId so TypeScript knows the
property exists; when building the update payload (where externalId is currently
only added under if (externalId.trim())), change the logic to always include
externalId (allowing an explicit empty string to be sent to clear the value) or
explicitly send null/empty per the API contract instead of omitting the field.
🧹 Nitpick comments (2)
src/pages/groups/groups-view/group-actions/EditGroups.tsx (1)

84-97: Drop the Record<string, unknown> indirection and type the payload directly.

Typing the payload as Record<string, unknown> and then casting to ExtendedPutGroupsRequest at the call site bypasses the type safety the new interface was introduced to provide. Since every field is optional on ExtendedPutGroupsRequest, you can declare the payload with that type and drop the cast.

♻️ Suggested refactor
-      const payload: Record<string, unknown> = {
+      const payload: ExtendedPutGroupsRequest = {
         name: name.trim(),
         locale: 'en',
         dateFormat: 'dd MMMM yyyy',
       }

       if (staffId) payload.staffId = Number(staffId)
       const sub = inputToFineractDate(submittedOn)
       if (sub) payload.submittedOnDate = sub
       const act = inputToFineractDate(activationOn)
       if (act) payload.activationDate = act
       if (externalId.trim()) payload.externalId = externalId.trim()

-      await groupsApi.update13(Number(id), payload as ExtendedPutGroupsRequest)
+      await groupsApi.update13(Number(id), payload)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/groups/groups-view/group-actions/EditGroups.tsx` around lines 84 -
97, The payload is currently declared as Record<string, unknown> then cast to
ExtendedPutGroupsRequest which defeats type safety; change the declaration of
payload to be typed as ExtendedPutGroupsRequest directly (e.g., const payload:
ExtendedPutGroupsRequest = { ... }) and keep the existing conditional
assignments for staffId, submittedOn/activationOn (using inputToFineractDate),
and externalId, then call groupsApi.update13(Number(id), payload) without a cast
so the compiler ensures the shape matches ExtendedPutGroupsRequest.
src/pages/groups/types.ts (1)

59-75: Optional: deduplicate the shared optional fields.

ExtendedPostGroupsRequest and ExtendedPutGroupsRequest declare an identical set of six optional fields. Extracting a shared mixin keeps them in sync if/when the workaround is updated as the upstream OpenAPI spec evolves.

♻️ Suggested refactor
+interface GroupRequestExtras {
+  staffId?: number
+  externalId?: string
+  submittedOnDate?: string
+  activationDate?: string
+  dateFormat?: string
+  locale?: string
+}
+
-export interface ExtendedPostGroupsRequest extends PostGroupsRequest {
-  staffId?: number
-  externalId?: string
-  submittedOnDate?: string
-  activationDate?: string
-  dateFormat?: string
-  locale?: string
-}
-
-export interface ExtendedPutGroupsRequest extends PutGroupsGroupIdRequest {
-  staffId?: number
-  externalId?: string
-  submittedOnDate?: string
-  activationDate?: string
-  dateFormat?: string
-  locale?: string
-}
+export interface ExtendedPostGroupsRequest
+  extends PostGroupsRequest,
+    GroupRequestExtras {}
+
+export interface ExtendedPutGroupsRequest
+  extends PutGroupsGroupIdRequest,
+    GroupRequestExtras {}

It would also be worth leaving a short comment near these interfaces (mirroring the one above ExtendedGroupResponse) explaining that the generated PostGroupsRequest / PutGroupsGroupIdRequest types are missing fields the Fineract API actually accepts — so future maintainers know why the local extension exists.

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

In `@src/pages/groups/types.ts` around lines 59 - 75, Both
ExtendedPostGroupsRequest and ExtendedPutGroupsRequest duplicate the same six
optional fields; create a shared mixin/interface (e.g., GroupsRequestExtras)
declaring staffId, externalId, submittedOnDate, activationDate, dateFormat,
locale and have ExtendedPostGroupsRequest and ExtendedPutGroupsRequest extend
that mixin instead of repeating the fields; also add a short comment above these
interfaces (mirroring the note above ExtendedGroupResponse) explaining this
local extension exists because the generated PostGroupsRequest /
PutGroupsGroupIdRequest types omit fields accepted by the Fineract API.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/pages/groups/CreateGroups.tsx`:
- Around line 80-93: The create handler currently sends ISO dates while
declaring dateFormat 'dd MMMM yyyy', so convert form date inputs using
inputToFineractDate before calling groupsApi.create8: pass submittedOnDate:
inputToFineractDate(formData.submittedOnDate) (it's required) and
activationDate: formData.active && formData.activationDate ?
inputToFineractDate(formData.activationDate) : undefined; keep
staffId/externalId coercions as before and cast to ExtendedPostGroupsRequest;
then add an end-to-end verification (manual step or test) that the create
payload contains staffId/externalId/submittedOnDate/activationDate and that
retrieveOne15 returns those persisted values.

---

Outside diff comments:
In `@src/pages/groups/groups-view/group-actions/EditGroups.tsx`:
- Line 40: The form never pre-fills or lets users clear externalId: update the
component to initialize and sync externalId from groupData by setting useState
to groupData.externalId (and in the useEffect that currently skips externalId)
and ensure ExtendedGroupResponse includes externalId so TypeScript knows the
property exists; when building the update payload (where externalId is currently
only added under if (externalId.trim())), change the logic to always include
externalId (allowing an explicit empty string to be sent to clear the value) or
explicitly send null/empty per the API contract instead of omitting the field.

---

Nitpick comments:
In `@src/pages/groups/groups-view/group-actions/EditGroups.tsx`:
- Around line 84-97: The payload is currently declared as Record<string,
unknown> then cast to ExtendedPutGroupsRequest which defeats type safety; change
the declaration of payload to be typed as ExtendedPutGroupsRequest directly
(e.g., const payload: ExtendedPutGroupsRequest = { ... }) and keep the existing
conditional assignments for staffId, submittedOn/activationOn (using
inputToFineractDate), and externalId, then call groupsApi.update13(Number(id),
payload) without a cast so the compiler ensures the shape matches
ExtendedPutGroupsRequest.

In `@src/pages/groups/types.ts`:
- Around line 59-75: Both ExtendedPostGroupsRequest and ExtendedPutGroupsRequest
duplicate the same six optional fields; create a shared mixin/interface (e.g.,
GroupsRequestExtras) declaring staffId, externalId, submittedOnDate,
activationDate, dateFormat, locale and have ExtendedPostGroupsRequest and
ExtendedPutGroupsRequest extend that mixin instead of repeating the fields; also
add a short comment above these interfaces (mirroring the note above
ExtendedGroupResponse) explaining this local extension exists because the
generated PostGroupsRequest / PutGroupsGroupIdRequest types omit fields accepted
by the Fineract API.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: b37bccc8-83ec-4671-984b-fd7f5e67f731

📥 Commits

Reviewing files that changed from the base of the PR and between 7117d04 and e2f1d78.

📒 Files selected for processing (3)
  • src/pages/groups/CreateGroups.tsx
  • src/pages/groups/groups-view/group-actions/EditGroups.tsx
  • src/pages/groups/types.ts

Comment thread src/pages/groups/CreateGroups.tsx
@adity-a34 adity-a34 force-pushed the MXWAR-82-fix-groups-silent-field-drop branch from e2f1d78 to 49eaf0e Compare April 25, 2026 05:27
@adity-a34
Copy link
Copy Markdown
Author

recheck @coderabbitai

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 25, 2026

Only users with a collaborator, contributor, member, or owner role can interact with CodeRabbit.

… calls

Signed-off-by: Aditya Tiwari <adityatiwari342005@gmail.com>
@adity-a34 adity-a34 force-pushed the MXWAR-82-fix-groups-silent-field-drop branch from 49eaf0e to d0c838b Compare April 25, 2026 06:36
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/pages/groups/groups-view/group-actions/EditGroups.tsx (1)

66-66: ⚠️ Potential issue | 🟡 Minor

Edge case: users cannot clear an existing externalId through this form.

Per the comment, externalId is intentionally left blank on initial load, and line 95 only adds externalId to the payload when the trimmed value is non-empty. Net effect: a user who wants to remove an existing external ID has no way to do so through this form (submitting an empty field is a no-op rather than a clear). If clearing isn't a supported workflow, consider initializing the field with the current value (group.externalId) so the user at least sees what's stored and edits it explicitly.

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

In `@src/pages/groups/groups-view/group-actions/EditGroups.tsx` at line 66, The
form currently leaves externalId blank and only adds it to the payload when
trimmed value is non-empty, preventing users from clearing an existing
externalId; update the EditGroups form so externalId is initialized with
group.externalId (so users see and can edit the current value) and/or change the
submit logic in the onSubmit handler to include externalId in the payload even
when it's an empty string (or explicitly send null) so submitting an empty field
clears the stored value; locate the externalId input state and the
payload-building code in EditGroups (where group.externalId and the trimmed
check are used) and implement one of these fixes to allow clearing.
🧹 Nitpick comments (3)
src/pages/groups/CreateGroups.tsx (1)

85-94: Date format issue resolved — payload now matches dateFormat.

inputToFineractDate correctly converts the HTML <Input type="date"> ISO output to the dd MMMM yyyy format declared in the payload, matching the edit handler. One minor follow-up: externalId: formData.externalId || undefined will still send a whitespace-only string (e.g. " "), whereas EditGroups.tsx uses externalId.trim() (line 95). Consider mirroring the trim here for consistency.

♻️ Proposed minor tweak
-        externalId: formData.externalId || undefined,
+        externalId: formData.externalId.trim() || undefined,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/groups/CreateGroups.tsx` around lines 85 - 94, The payload may
include whitespace-only externalId because CreateGroups uses "externalId:
formData.externalId || undefined"; update this to mirror EditGroups by trimming
the value before deciding to send it (use formData.externalId?.trim() and fall
back to undefined) so the externalId field in the ExtendedPostGroupsRequest only
contains a meaningful non-empty string or undefined.
src/pages/groups/types.ts (1)

64-85: Optional: deduplicate the shared extension fields.

Both ExtendedPostGroupsRequest and ExtendedPutGroupsRequest declare the exact same six optional fields. Consider extracting them to a shared type to keep the two in sync if more fields are discovered later.

♻️ Proposed refactor
+interface ExtendedGroupsRequestFields {
+  staffId?: number
+  externalId?: string
+  submittedOnDate?: string
+  activationDate?: string
+  dateFormat?: string
+  locale?: string
+}
+
 export interface ExtendedPostGroupsRequest extends PostGroupsRequest {
-  staffId?: number
-  externalId?: string
-  submittedOnDate?: string
-  activationDate?: string
-  dateFormat?: string
-  locale?: string
-}
+}
+export interface ExtendedPostGroupsRequest
+  extends PostGroupsRequest,
+    ExtendedGroupsRequestFields {}
 
-export interface ExtendedPutGroupsRequest extends PutGroupsGroupIdRequest {
-  staffId?: number
-  externalId?: string
-  submittedOnDate?: string
-  activationDate?: string
-  dateFormat?: string
-  locale?: string
-}
+export interface ExtendedPutGroupsRequest
+  extends PutGroupsGroupIdRequest,
+    ExtendedGroupsRequestFields {}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/groups/types.ts` around lines 64 - 85, Both
ExtendedPostGroupsRequest and ExtendedPutGroupsRequest declare the same six
optional fields; extract those shared fields into a single reusable type (e.g.,
GroupRequestExtras or GroupRequestCommon) and have ExtendedPostGroupsRequest and
ExtendedPutGroupsRequest extend their original bases plus that new shared type
so the fields are declared only once and stay in sync (update the declarations
for ExtendedPostGroupsRequest and ExtendedPutGroupsRequest to use the new shared
type).
src/pages/groups/groups-view/group-actions/EditGroups.tsx (1)

84-97: Fix looks good; consider typing payload directly to drop the cast.

The full-payload submit correctly resolves the silent drop on update. Minor: declaring payload as Record<string, unknown> and then casting at the call site bypasses compile-time checks for field name/type mistakes. You can type it as ExtendedPutGroupsRequest from the start and still conditionally assign optional fields.

♻️ Proposed refactor
-      const payload: Record<string, unknown> = {
+      const payload: ExtendedPutGroupsRequest = {
         name: name.trim(),
         locale: 'en',
         dateFormat: 'dd MMMM yyyy',
       }

       if (staffId) payload.staffId = Number(staffId)
       const sub = inputToFineractDate(submittedOn)
       if (sub) payload.submittedOnDate = sub
       const act = inputToFineractDate(activationOn)
       if (act) payload.activationDate = act
       if (externalId.trim()) payload.externalId = externalId.trim()

-      await groupsApi.update13(Number(id), payload as ExtendedPutGroupsRequest)
+      await groupsApi.update13(Number(id), payload)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/groups/groups-view/group-actions/EditGroups.tsx` around lines 84 -
97, The payload variable is currently typed as Record<string, unknown> and then
cast at groupsApi.update13, which hides type errors; change the declaration of
payload to use ExtendedPutGroupsRequest directly, keep the same conditional
assignments (staffId, submittedOn -> inputToFineractDate, activationOn ->
inputToFineractDate, externalId) and ensure optional fields use the correct
property names (e.g., submittedOnDate, activationDate) so you can call
groupsApi.update13(Number(id), payload) without a cast.
🤖 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 `@src/pages/groups/groups-view/group-actions/EditGroups.tsx`:
- Line 66: The form currently leaves externalId blank and only adds it to the
payload when trimmed value is non-empty, preventing users from clearing an
existing externalId; update the EditGroups form so externalId is initialized
with group.externalId (so users see and can edit the current value) and/or
change the submit logic in the onSubmit handler to include externalId in the
payload even when it's an empty string (or explicitly send null) so submitting
an empty field clears the stored value; locate the externalId input state and
the payload-building code in EditGroups (where group.externalId and the trimmed
check are used) and implement one of these fixes to allow clearing.

---

Nitpick comments:
In `@src/pages/groups/CreateGroups.tsx`:
- Around line 85-94: The payload may include whitespace-only externalId because
CreateGroups uses "externalId: formData.externalId || undefined"; update this to
mirror EditGroups by trimming the value before deciding to send it (use
formData.externalId?.trim() and fall back to undefined) so the externalId field
in the ExtendedPostGroupsRequest only contains a meaningful non-empty string or
undefined.

In `@src/pages/groups/groups-view/group-actions/EditGroups.tsx`:
- Around line 84-97: The payload variable is currently typed as Record<string,
unknown> and then cast at groupsApi.update13, which hides type errors; change
the declaration of payload to use ExtendedPutGroupsRequest directly, keep the
same conditional assignments (staffId, submittedOn -> inputToFineractDate,
activationOn -> inputToFineractDate, externalId) and ensure optional fields use
the correct property names (e.g., submittedOnDate, activationDate) so you can
call groupsApi.update13(Number(id), payload) without a cast.

In `@src/pages/groups/types.ts`:
- Around line 64-85: Both ExtendedPostGroupsRequest and ExtendedPutGroupsRequest
declare the same six optional fields; extract those shared fields into a single
reusable type (e.g., GroupRequestExtras or GroupRequestCommon) and have
ExtendedPostGroupsRequest and ExtendedPutGroupsRequest extend their original
bases plus that new shared type so the fields are declared only once and stay in
sync (update the declarations for ExtendedPostGroupsRequest and
ExtendedPutGroupsRequest to use the new shared type).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 627f3c38-4e37-4000-9494-7b6b161fcf20

📥 Commits

Reviewing files that changed from the base of the PR and between e2f1d78 and d0c838b.

📒 Files selected for processing (3)
  • src/pages/groups/CreateGroups.tsx
  • src/pages/groups/groups-view/group-actions/EditGroups.tsx
  • src/pages/groups/types.ts

…alId, init and clear externalId in edit

Signed-off-by: Aditya Tiwari <adityatiwari342005@gmail.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/pages/groups/CreateGroups.tsx (1)

162-173: ⚠️ Potential issue | 🟡 Minor

Activation date input should be required when active is checked.

The submitted-on input (Line 193) is required, but the activation date input has no required attribute. With active=true and an empty activationDate, the payload becomes { active: true, activationDate: undefined }, which Fineract will reject server-side — surfacing as a generic alert to the user instead of inline form validation. Since the field is conditionally rendered only when active is checked, marking it required is safe and matches the form-level handling of submittedOnDate.

🛡️ Proposed fix
               <Input
                 type="date"
                 value={formData.activationDate}
                 onChange={e =>
                   setFormData(p => ({ ...p, activationDate: e.target.value }))
                 }
+                required
               />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/groups/CreateGroups.tsx` around lines 162 - 173, The activation
date input rendered when formData.active is true is missing the required
attribute, causing server-side rejections; update the conditional block in
CreateGroups (the Input with value={formData.activationDate} and onChange that
calls setFormData) to include required so the browser enforces entry when active
is checked, matching the submittedOnDate behavior and preventing undefined
activationDate in the payload.
🧹 Nitpick comments (1)
src/pages/groups/CreateGroups.tsx (1)

81-94: Optional: declare the payload as a typed const instead of casting.

The edit handler in EditGroups.tsx uses const payload: ExtendedPutGroupsRequest = { ... } (per the relevant snippet), which lets TypeScript catch property typos and shape drift. The as ExtendedPostGroupsRequest assertion here disables that check — for example, a typo like staffID would compile silently. Aligning with the edit-side style also makes the two flows easier to compare.

♻️ Proposed refactor
-      await groupsApi.create8({
+      const payload: ExtendedPostGroupsRequest = {
         name: formData.name,
         officeId: Number(formData.officeId),
         active: formData.active,
         staffId: formData.staffId ? Number(formData.staffId) : undefined,
         externalId: formData.externalId.trim() || undefined,
         submittedOnDate: inputToFineractDate(formData.submittedOnDate),
         activationDate:
           formData.active && formData.activationDate
             ? inputToFineractDate(formData.activationDate)
             : undefined,
         dateFormat: 'dd MMMM yyyy',
         locale: 'en',
-      } as ExtendedPostGroupsRequest)
+      }
+      await groupsApi.create8(payload)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/groups/CreateGroups.tsx` around lines 81 - 94, Create a properly
typed payload const instead of using a type assertion on the API call: build a
const payload: ExtendedPostGroupsRequest = { name: formData.name, officeId:
Number(formData.officeId), active: formData.active, staffId: formData.staffId ?
Number(formData.staffId) : undefined, externalId: formData.externalId.trim() ||
undefined, submittedOnDate: inputToFineractDate(formData.submittedOnDate),
activationDate: formData.active && formData.activationDate ?
inputToFineractDate(formData.activationDate) : undefined, dateFormat: 'dd MMMM
yyyy', locale: 'en' } and then call groupsApi.create8(payload); this preserves
the existing conversions/logic (staffId, externalId, activationDate) while
letting TypeScript validate the shape instead of using the as
ExtendedPostGroupsRequest cast.
🤖 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 `@src/pages/groups/CreateGroups.tsx`:
- Around line 162-173: The activation date input rendered when formData.active
is true is missing the required attribute, causing server-side rejections;
update the conditional block in CreateGroups (the Input with
value={formData.activationDate} and onChange that calls setFormData) to include
required so the browser enforces entry when active is checked, matching the
submittedOnDate behavior and preventing undefined activationDate in the payload.

---

Nitpick comments:
In `@src/pages/groups/CreateGroups.tsx`:
- Around line 81-94: Create a properly typed payload const instead of using a
type assertion on the API call: build a const payload: ExtendedPostGroupsRequest
= { name: formData.name, officeId: Number(formData.officeId), active:
formData.active, staffId: formData.staffId ? Number(formData.staffId) :
undefined, externalId: formData.externalId.trim() || undefined, submittedOnDate:
inputToFineractDate(formData.submittedOnDate), activationDate: formData.active
&& formData.activationDate ? inputToFineractDate(formData.activationDate) :
undefined, dateFormat: 'dd MMMM yyyy', locale: 'en' } and then call
groupsApi.create8(payload); this preserves the existing conversions/logic
(staffId, externalId, activationDate) while letting TypeScript validate the
shape instead of using the as ExtendedPostGroupsRequest cast.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 004d5adc-6132-463f-86dc-8cbc5ef0bc40

📥 Commits

Reviewing files that changed from the base of the PR and between d0c838b and 966a8a9.

📒 Files selected for processing (3)
  • src/pages/groups/CreateGroups.tsx
  • src/pages/groups/groups-view/group-actions/EditGroups.tsx
  • src/pages/groups/types.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/pages/groups/groups-view/group-actions/EditGroups.tsx

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant