Skip to content

319 item splitting and granular allocation - #331

Merged
ND68 merged 9 commits into
mainfrom
319-item-splitting-and-granular-allocation
Apr 14, 2026
Merged

ND68 merged 9 commits into
mainfrom
319-item-splitting-and-granular-allocation

Conversation

@ezraexe

@ezraexe ezraexe commented Apr 11, 2026

Copy link
Copy Markdown
Contributor

Description

Resolves ticket number: #319

Explain what your code changes:

  • lineItemService.ts:
  • Added method to split line item with $transaction
  • Contains validations to make sure the item is valid

[lineItemId]/route.ts:

  • Added POST request following the other api routes and calling the new method (splitLineItem()) in lineItemservices.ts

LineItemChipGroup.tsx:

  • Added Split by Quantity button, under the conditions taht the item is unallocated and has quantity > 1
  • Sending messages via toast
  • Added 'isSplitLoading' to prevent race conditions from double clicking(would previously add twice if accidentally cliekd twice in rapid succession)

List the steps you took to test your code:

Added mock information into Allocation View and tested splits
image

  • Added prevention of splitting decimals
  • Fixed race condition by locking button once clicked / isLoading

Checklist

  • The ticket is mentioned above
  • The changes fulfill the success criteria of the ticket
  • The changes were self-reviewed
  • A review was requested

@ezraexe
ezraexe requested a review from ND68 April 11, 2026 11:56
@ezraexe ezraexe linked an issue Apr 11, 2026 that may be closed by this pull request
@netlify

netlify Bot commented Apr 11, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for hope-for-haiti ready!

Name Link
🔨 Latest commit e448eb5
🔍 Latest deploy log https://app.netlify.com/projects/hope-for-haiti/deploys/69dd928b7737db0008c1f388
😎 Deploy Preview https://deploy-preview-331--hope-for-haiti.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@greptile-apps

greptile-apps Bot commented Apr 11, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR implements a "Split by Quantity" feature that splits an unallocated line item into multiple sub-items whose quantities sum to the original, backed by a transactional service method with a FOR UPDATE row-lock, full server-side validation, and a client-side UI gated on allocation state and quantity > 1.

One P1 fix is needed before merge:

  • Array(n) crash in numSplits onChange (LineItemChipGroup.tsx ~line 346): the Number.isInteger guard is applied to the per-item quantity inputs but was omitted for the split-count input, so typing 2.5 passes the >= 2 && <= 7 range check and triggers RangeError: Invalid array length.

PR Checklist areas needing improvement (score: 82/100):

  • Move splitSchema to module scope (matches existing updateSchema convention).
  • Add missing newline at end of route.ts.

Confidence Score: 4/5

One P1 runtime crash in the split-count input needs fixing before merge.

The service layer and API handler are well-structured with proper transactions, row-locking, and validation. The single P1 bug — Array(n) throwing a RangeError on a non-integer split-count value — is isolated to the UI and easy to fix. All prior review concerns about decimal validation and color tokens have been addressed.

src/components/chips/LineItemChipGroup.tsx — missing Number.isInteger guard in the numSplits onChange handler.

Important Files Changed

Filename Overview
src/services/lineItemService.ts Adds splitLineItem with proper $transaction, FOR UPDATE row-lock, thorough validation, and spreading of non-id/relation fields into new items. Logic is sound; Promise.all inside the interactive transaction is safe on PostgreSQL.
src/app/api/generalItems/[generalItemId]/lineItems/[lineItemId]/route.ts Adds POST handler with auth, permission check, and Zod validation; splitSchema should live at module scope rather than inside the handler.
src/components/chips/LineItemChipGroup.tsx Adds split UI with isSplitLoading guard and client-side sum validation; Array(n) crash when a non-integer is typed into the "Number of Splits" field is a P1 bug.

Sequence Diagram

sequenceDiagram
    participant U as User (LineItemChip UI)
    participant C as splitItem()
    participant API as POST /api/generalItems/:gId/lineItems/:lId
    participant SVC as LineItemService.splitLineItem()
    participant DB as PostgreSQL

    U->>C: clicks Split (button disabled until sum == item.quantity)
    C->>API: POST { quantities: number[] }
    API->>API: auth + permission check
    API->>API: splitSchema.safeParse(body)
    API->>SVC: splitLineItem(lineItemId, generalItemId, quantities)
    SVC->>DB: BEGIN TRANSACTION
    SVC->>DB: SELECT ... FOR UPDATE (row lock)
    SVC->>DB: findUnique(lineItem) + allocation + donorOffer.state
    SVC->>DB: validate (not archived, not allocated, sum == quantity)
    SVC->>DB: UPDATE lineItem SET quantity = quantities[0]
    SVC->>DB: CREATE new LineItems for quantities[1..n] (Promise.all)
    DB-->>SVC: { original, newItem[] }
    SVC->>DB: COMMIT
    SVC-->>API: { original, newItem[] }
    API-->>C: 200 { original, newItem[] }
    C->>U: updateItem() + toast.success
Loading

Reviews (2): Last reviewed commit: "updated with split between 2-7" | Re-trigger Greptile

Comment thread src/components/chips/LineItemChipGroup.tsx
Comment thread src/components/chips/LineItemChipGroup.tsx Outdated
@ND68

ND68 commented Apr 11, 2026

Copy link
Copy Markdown
Collaborator

Changes look great, splitting quantities works well.

However, we had some requirement changes after this ticket was assigned. The current implementation allows users to split one line item into two. We want to allow users to split a line item into however many line items they want. Please alter the current implementation to have a field asking how many line items the user would like to split the selected line item into. Based on the number they input, have that number of fields pop up, so that the user can submit a specified number for each line item they are planning to create.

For example, if the user inputs 4, we should have 4 fields pop up:

Line Item 1: ____
Line Item 2: ____
Line Item 3: ____
Line Item 4: ____

4 is including the original line item selected, so Line Item 1 is really just altering the selected line item, while the other are creating duplicate line items of inputted quantity.

For data validation, ensure that all inputted quantities are positive, and the split up quantities add up to the original amount. We also want to cap the number of splits the user can make at a time. So have the # of splits field range be between 2-7.

@ND68

ND68 commented Apr 13, 2026

Copy link
Copy Markdown
Collaborator

@greptileai

Comment thread src/components/chips/LineItemChipGroup.tsx
@ND68

ND68 commented Apr 14, 2026

Copy link
Copy Markdown
Collaborator

great work with all the data validations, feature works flawlessly

@ND68
ND68 merged commit 2c728d3 into main Apr 14, 2026
5 checks passed
@ND68
ND68 deleted the 319-item-splitting-and-granular-allocation branch April 14, 2026 01:07
@ND68 ND68 linked an issue Apr 14, 2026 that may be closed by this pull request
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.

UI Styling Inconsistency Fixes Item Splitting and Granular Allocation

2 participants