Skip to content

Fix offer uploads showing success when row validation fails. - #378

Open
Theerth1 wants to merge 2 commits into
mainfrom
theerth/372-fix-offer-upload-errors
Open

Theerth1 wants to merge 2 commits into
mainfrom
theerth/372-fix-offer-upload-errors

Conversation

@Theerth1

Copy link
Copy Markdown
Contributor

Description

Resolves ticket number: #372

Explain what your code changes:

Trace (as per gh issue ask):

  • src/app/api/donorOffers/route.ts and src/app/api/donorOffers/[donorOfferId]/route.ts returned {success:false, errors:[...]} with an implicit HTTP 200 on row-validation failure (never a thrown exception, never a non-200 status). The finalize-preview branch ([donorOfferId]/route.ts:226-230) discarded the whole result and returned only {donorOfferItems:[]}, dropping errors server-side before the client ever saw them.
  • useFileUpload.ts and useApiClient.ts (the two hooks both upload pages use) only checked response.ok to decide success/failure. Since the API always returned 200, a success:false body was always read as success.
  • Row numbers in error messages were computed from the post-filter array index (index + 1), which didn't account for the header row and got thrown off even more whenever a blank row was filtered out ahead of a bad row.

Changes:

  • Both API routes now return 422 when result.success === false.
  • useApiClient now reads an errors array off failed responses and attaches it to the thrown error.
  • Both upload pages (Create Offer, Finalize Offer) now show every row error (not just one), block Preview/Create/Finalize while errors exist, and show the real server error on save failure instead of a generic message.
  • Each parsed row is now tagged with its true Excel row number immediately after parsing, before any filtering so error messages like "Row 4" now match what's visible in Excel.

List the steps you took to test your code:

  1. tsc --noEmit (0 errors) and eslint (clean) on all changed files.
  2. Hit all 8 flows (create/finalize × preview/save × broken/clean sheet) directly against the real API with a logged-in session, using CSVs built to match the issue's repro (blank required field) plus a deliberately-placed blank row to exercise the row-numbering fix. For every "broken save" case, re-queried the donor offer's state from Postgres afterward to confirm nothing was actually persisted; for "clean save," confirmed the state genuinely flipped to FINALIZED.
  3. Drove the actual browser UI (real file input, real form) to confirm the error list renders, the Preview/Create/Finalize buttons are disabled while errors exist, and the success modal only appears after a real save.

Checklist

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

@Theerth1
Theerth1 requested a review from ezraexe October 17, 2026 03:29
@netlify

netlify Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for hope-for-haiti ready!

Name Link
🔨 Latest commit 18895a4
🔍 Latest deploy log https://app.netlify.com/projects/hope-for-haiti/deploys/6ad2ee5f57ba50732067ccaf
😎 Deploy Preview https://deploy-preview-378--hope-for-haiti.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

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

@greptile-apps

greptile-apps Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Disclaimer: This comment was AI-generated and is not necessarily completely accurate. Please take code comments with a grain of salt.

RetriggerView in GreptileConfidence Score: 4/5

[Medium impact] Fixes validation error reporting in donor offer uploads.

The PR appears safe to merge, with a non-blocking correction needed for XLSX row numbers.

Findings

  1. P2 Excel row numbers remain wrong ▶

Summary

The PR makes failed row checks return HTTP 422 and shows the server's errors instead of a success message.

  • Offer uploads show row errors instead of reporting success.
  • Upload errors point to the matching spreadsheet row.

Review score: 90/100.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Upload CSV or XLSX] --> B[Parse and tag rows]
  B --> C[Check required fields]
  C -->|Invalid rows| D[Return HTTP 422 and errors]
  D --> E[Show row errors]
  C -->|Valid preview| F[Show preview]
  C -->|Valid save| G[Save offer]
  G --> H[Show success]
Loading

Reviews (1) · Last reviewed commit: "Fix offer uploads showing success when r..." · Reviewed by Greptile

Comment thread src/services/fileService.ts Outdated
Comment on lines +435 to +436
const skipResult = skipEmptyRows(XLSX.utils.sheet_to_csv(sheet));
skipped = skipResult.skipped;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Excel row numbers remain wrong

When an XLSX sheet starts below row 1, sheet_to_csv omits blank rows before the sheet's used range. skipEmptyRows cannot count those rows, so a header at row 3 and invalid data at row 4 produce “row 2.” Users are still pointed to the wrong cells. Include the starting row from the sheet's !ref when calculating __excelRow in both parsers.

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