Skip to content

fix(purchasing): stale supplier processes in bill of process dropdown after deletion (#1210)#1213

Open
carbon-agent wants to merge 1 commit into
mainfrom
fix/supplier-process-stale-dropdown
Open

fix(purchasing): stale supplier processes in bill of process dropdown after deletion (#1210)#1213
carbon-agent wants to merge 1 commit into
mainfrom
fix/supplier-process-stale-dropdown

Conversation

@carbon-agent

@carbon-agent carbon-agent commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

Problem

Closes #1210. When a supplier process is deleted (or created/edited) and the user navigates back to the bill of process, the deleted supplier still appears in the dropdown until a hard page refresh.

Root cause

useSupplierProcesses (in SupplierProcess.tsx) loaded data with React Router's useFetcher, which fetches once on mount and then holds its result. Navigating back to the bill of process reused the stale fetcher data. The create/edit/delete clientActions only cleared the cache with setQueryData(key, null) before the mutation ran, which the still-mounted fetcher never observed.

Fix

  • SupplierProcess.tsx — read through the shared window.clientCache QueryClient via TanStack useQuery, keyed by the same supplierProcessesQuery(processId) the clientActions target. An invalidation now reactively refetches the mounted dropdown. enabled: Boolean(processId) preserves the existing empty-processId guard (an empty segment would 404 the API route).
  • $supplierId.processes.{new,$id,delete.$id}.tsx — switch each clientAction from a pre-mutation setQueryData(key, null) to invalidateQueries in a finally after serverAction() commits, so the refetch reflects post-mutation data instead of racing the write. The delete route scopes invalidation to the processId from the request URL instead of clearing all supplierProcesses queries.

This follows the repo's established clientLoader/clientAction + window.clientCache invalidation pattern (same key factory as the api+/purchasing.supplier-processes.$processId route's clientLoader).

Acceptance criteria

  • Deleted supplier processes no longer appear in the bill of process dropdown
  • No page refresh needed to see the updated supplier list
  • Follows existing repo patterns with clientLoader/clientAction

Verification

  • pnpm exec turbo run typecheck --filter=erp — passes
  • pnpm exec biome lint on the 4 changed files — clean

Supersedes the closed #1189, which carried ~4k lines of unrelated approval-workflow changes. This branch is a clean re-implementation off current main with only the supplier-process fix, plus an ordering improvement (invalidate after the mutation commits).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Supplier processes now refresh automatically after creating, updating, or deleting a process.
    • Prevented stale or prematurely cleared process lists after changes.
    • Improved error handling when supplier process data cannot be loaded.
    • Supplier process data is no longer requested when no process is selected.

…n bill of process (#1210)

Deleting (or creating/editing) a supplier process left stale rows in the
bill-of-process supplier dropdown until a hard page refresh.

Root cause: `useSupplierProcesses` loaded via `useFetcher`, which fetches
once on mount and holds its result. Navigating back to the bill of process
reused the stale fetcher data, and the create/edit/delete `clientAction`s
only cleared the cache with `setQueryData(key, null)` before the mutation —
which the still-mounted fetcher never observed.

Fix:
- Read through the shared `window.clientCache` QueryClient via TanStack
  `useQuery` (same key `supplierProcessesQuery(processId)` the clientActions
  target), so an invalidation reactively refetches the mounted dropdown.
  `enabled: Boolean(processId)` keeps the disabled-empty-processId guard.
- Change the create/edit/delete `clientAction`s to `invalidateQueries` in a
  `finally` AFTER `serverAction()` commits, so the refetch sees post-mutation
  data instead of racing the write. Delete scopes to the `processId` from the
  request URL rather than nuking every supplierProcesses query.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added erp complexity: low Low-complexity PR labels Jul 23, 2026
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9527ae2b-4ed8-4b05-8246-ddb21e2dbb0f

📥 Commits

Reviewing files that changed from the base of the PR and between dec68c2 and a020f2a.

📒 Files selected for processing (4)
  • apps/erp/app/components/Form/SupplierProcess.tsx
  • apps/erp/app/routes/x+/supplier+/$supplierId.processes.$id.tsx
  • apps/erp/app/routes/x+/supplier+/$supplierId.processes.delete.$id.tsx
  • apps/erp/app/routes/x+/supplier+/$supplierId.processes.new.tsx

📝 Walkthrough

Walkthrough

Supplier process loading now uses TanStack Query, and create, edit, and delete actions invalidate the matching supplier-process cache after server actions complete.

Changes

Supplier Process Query Cache

Layer / File(s) Summary
Query-backed supplier process loading
apps/erp/app/components/Form/SupplierProcess.tsx
useSupplierProcesses now fetches through useQuery, handles non-OK responses, disables fetching without a process ID, and derives its list from query data.
Mutation cache invalidation
apps/erp/app/routes/x+/supplier+/$supplierId.processes.$id.tsx, apps/erp/app/routes/x+/supplier+/$supplierId.processes.new.tsx, apps/erp/app/routes/x+/supplier+/$supplierId.processes.delete.$id.tsx
Create, edit, and delete actions replace optimistic cache clearing with post-action query invalidation and no longer destructure unused route parameters.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested labels: checks: passing

Suggested reviewers: barbinbrad, aashu0148

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR covers #1189, but it does not address #1210's supersession-aware picking logic and filtering requirements. Implement the picking-list supersession handling from #1210, including Stock Only/No Stock filtering, successor substitution, and effectivity/conversion logic.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is specific and matches the supplier-process cache invalidation fix, even though it only mentions deletion.
Out of Scope Changes check ✅ Passed The changes stay focused on supplier-process query caching and mutation invalidation, with no unrelated additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/supplier-process-stale-dropdown

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.

@github-actions github-actions Bot added the checks: passing CI checks passed label Jul 23, 2026
@vercel

vercel Bot commented Jul 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
carbon Ready Ready Preview, Comment Jul 23, 2026 4:39pm

Request Review

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

Labels

checks: passing CI checks passed complexity: low Low-complexity PR erp

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Picking Lists Do Not Honor Item Supersession

1 participant