proposal-system/web
Adam Moussa 1f55a59445
fix(web): apply Phase 4 code-review findings (10 correctness + 4 cleanup)
Correctness:
- State-transition mutations now invalidate every cached view via
  invalidateProposalViews (detail + line items + lists + stats + admin
  dashboard) — approving no longer leaves a stale queue for the
  5-minute staleTime
- Presigned S3 PUT moved to proposals/api.ts with res.ok check — a
  rejected upload is no longer confirmed as uploaded
- toCustomerRequest always sends contactEmail ('' clears); API create
  path normalizes empty->null to match the update path — customer
  emails can now be cleared from the UI
- Shared Number-based numeric form fields (domain/shared/formFields):
  '12abc' no longer silently coerces to 12 in the pricing library
- Customer create/update invalidate customersKeys.all so cached search
  autocompletes see new customers
- AdminWorkspace clears dirty right after a successful implicit save,
  before approve — no false unsaved-changes prompt when approve fails
- ProposalFormPage submit gate and missing-fields caption derive from
  ONE checks list (missing customer is now listed)
- Empty states gated on !err in ProposalListPage/AdminDashboard — no
  contradictory error + 'no proposals' UI
- VendorDataPanel migrated to useVendorProposals (kills the divergent
  ['vendorProposals', id] cache key and the inline apiClient query)
- useCustomerList/usePricingLibraryList get keepPreviousData — no
  TablePagination out-of-range flash on page change

Cleanup:
- Dead speculative hooks removed (useCreate/BulkUpdate/DeleteLineItem,
  useUpdateProposal, useProposalHistory/Audit, lineItemRowFormSchema,
  toUpdateLineItemEntry); tests moved to the live save path
  (useSaveProposalWorkspace)
- Shared useDebouncedValue hook replaces 4 drifted inline debounce
  copies (one leaked its timer on unmount, two hardcoded 300ms);
  DEBOUNCE_AUTOCOMPLETE=300 named
- Fix: WEB-H5 / WEB-H6 finding-ID markers restored at the relocated
  onError handlers (CLAUDE.md traceability)
- shared/api-contracts gains an exports map; /schemas resolver alias
  deduplicated from 3 copies to the tsconfig paths mapping

Verify: tsc clean, vitest 51/51 (tests updated to pin the new
invalidation/mapper behavior + new '12abc' rejection test),
vite build OK, dotnet 166/166.
2026-07-13 19:06:08 -04:00
..
src fix(web): apply Phase 4 code-review findings (10 correctness + 4 cleanup) 2026-07-13 19:06:08 -04:00
.env.example Implement Phases 2-5: Frontend, AI/RAG, PDF Generation (#22) 2026-05-17 13:06:23 -04:00
index.html feat(web): adopt SHOC design system and shell layout (ADR 0003) 2026-07-13 16:47:17 -04:00
package-lock.json feat(web): domain-layer conventions doc + react-hook-form deps (Phase 4 prep) 2026-07-13 17:47:05 -04:00
package.json feat(web): domain-layer conventions doc + react-hook-form deps (Phase 4 prep) 2026-07-13 17:47:05 -04:00
tsconfig.json fix(web): apply Phase 4 code-review findings (10 correctness + 4 cleanup) 2026-07-13 19:06:08 -04:00
vite.config.ts fix(web): apply Phase 4 code-review findings (10 correctness + 4 cleanup) 2026-07-13 19:06:08 -04:00
vitest.config.ts fix(web): apply Phase 4 code-review findings (10 correctness + 4 cleanup) 2026-07-13 19:06:08 -04:00