Skip to content

refactor: move the invoice flow query and mutation options to core - #1901

Open
gabrielseco wants to merge 7 commits into
refactor/core-client-factoryfrom
refactor/core-query-options
Open

gabrielseco wants to merge 7 commits into
refactor/core-client-factoryfrom
refactor/core-query-options

Conversation

@gabrielseco

@gabrielseco gabrielseco commented Nov 5, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Moves the API calls behind the invoice schedule flow into the private core package as plain option objects that any framework can use. Behavior and the public API of @remoteoss/remote-flows are unchanged.

Why

Phase 2 of the Angular support plan (#1833). The query keys, request calls and payload building for this flow are the same in every framework, and today the Angular spike rewrites them next to the React hooks. Sharing them means one place to change. Stacked on #1900.

What changed

Toggle details
  • New packages/core/src/api/ with three files:
    • employment.ts: employmentOptions(client, employmentId, queryParams?)
    • contractorCurrencies.ts: contractorCurrenciesOptions(client, employmentId)
    • invoiceSchedules.ts: invoiceSchedulesOptions(client, employmentId) and the four mutations createInvoiceScheduleMutation, updateInvoiceScheduleMutation, skipInvoiceScheduleMutation and previewContractorInvoiceMutation, each taking client.
  • They return plain objects (queryKey, queryFn, retry; or mutationFn), the shape useQuery and useMutation accept. select and enabled stay with the caller, as before. Query keys are unchanged, so the React Query cache behaves as it did.
  • A correction to the plan: queryOptions and mutationOptions are not exported by @tanstack/query-core; they only exist in each framework package. So core does not depend on TanStack at all here, and the React side wraps the object with queryOptions(...) where it needs the typed key. The plan text is updated separately.
  • The React hooks keep their names and signatures: useEmploymentQuery, useContractorCurrencies, invoiceSchedulesOptions, useCreateInvoiceSchedule, useUpdateInvoiceSchedule, useSkipInvoiceSchedule and usePreviewContractorInvoice now spread or pass the core options.
  • Test change: useOnboardingJsonSchemaVersion.test.tsx replaces the whole @/src/client module with a few functions, and its employment lookup relied on failing under that mock. Core calls the SDK through its own import, so the lookup got real data and the flow took a different path. I added a mock of the core SDK module to that one file so the lookup fails as before. The test bodies are unchanged. That whole-module mock is a legacy pattern the testing rules discourage; replacing it is a separate cleanup.
  • No new tests: the hooks are covered by the existing flow tests, which use MSW. Core can't import the test helpers under src/ by design.
  • Public API: no change. Checked on a production build: no reference to the core package is left in dist, and check-exports passes.

Screenshots

N/A

Related Resources

Testing

The same checks CI runs pass locally: the lint command (exit 0), type-check (both configs), the full vitest suite (135 files, 1732 tests), a production build and check-exports.

  • Tested against the example/ app in a browser
  • Feature flag: N/A

Note

Medium Risk
Refactors shared React Query wiring and mutation helpers for employment and invoice-schedule flows; intended as behavior-preserving but any mismatch in options or client binding could affect API calls or caching.

Overview
Moves employment, contractor currencies, and invoice-schedule queryKey / queryFn / mutationFn definitions into packages/core as plain objects, plus selectors for currency lists, currency codes, and the first “editable” invoice schedule. The public @remoteoss/remote-flows hooks keep the same names; they now withClient-wrap the core query factories and use createClientMutation so the context Client is injected and callers still get mutateAsyncOrThrow without double-wrapping.

React invoice-schedule code stops inlining SDK calls and payload builders for those endpoints; onboarding and standalone invoice flows use the mutation hooks’ built-in mutateAsyncOrThrow directly.

Exports: core’s index now surfaces the new API helpers and drops INVOICE_SCHEDULE_STATUS and buildInvoicePreviewPayload from the package surface (they stay internal to core where needed).

Tests: core adds selector unit tests; app adds createClientMutation tests and mocks @remoteoss/remote-flows-core/client/sdk.gen in the onboarding json-schema version test so behavior stays aligned with the old module mock.

Reviewed by Cursor Bugbot for commit 0a423f6. Bugbot is set up for automated code reviews on this repo. Configure here.

@github-actions

github-actions Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

📦 Bundle Size Report

Metric Current Previous Change Status
Total (gzip) 246.1 kB 246.06 kB +37 B (+0.0%) 🔴
Total (raw) 679.61 kB 679.41 kB +200 B (+0.0%) 🔴
CSS (gzip) 22.03 kB 22.03 kB 0 B (0%) 🟢
CSS (raw) 114.89 kB 114.89 kB 0 B (0%) 🟢

Size Limits

  • ✅ Total gzipped: 246.1 kB / 350 kB (70.3%)
  • ✅ Total raw: 679.61 kB / 850 kB (80.0%)
  • ✅ CSS gzipped: 22.03 kB / 25 kB (88.1%)

Largest Files (Top 5)

  1. index.esm-wIkXrqU6.js - 11.4 kB (0 B (0%))
  2. styles.css - 11.02 kB (0 B (0%))
  3. index.css - 11.02 kB (0 B (0%))
  4. src-DWQ3Qhux.js - 7.78 kB (new)
  5. internals-DDgJcT1J.js - 6.14 kB (new)
View All Files (314 total)
File Size (gzip) Change
index.esm-wIkXrqU6.js 11.4 kB 0 B (0%)
styles.css 11.02 kB 0 B (0%)
index.css 11.02 kB 0 B (0%)
src-DWQ3Qhux.js 7.78 kB new
internals-DDgJcT1J.js 6.14 kB new
hooks-DwbEziK_.js 5.8 kB new
sdk.gen-DLkAkGD7.js 5.67 kB new
index.js 5.36 kB -7 B (-0.1%)
flows/Onboarding/hooks.js 4.69 kB -2 B (-0.0%)
FieldSetField-WpzfZshX.js 4.57 kB new

✅ Bundle size check passed

@github-actions

github-actions Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Deploy preview for remote-flows ready!

Project:remote-flows
Status: ✅  Deploy successful!
Preview URL:https://remote-flows-atqmbrxyt-remotecom.vercel.app
Latest Commit:0a423f6

Deployed with vercel-action

@github-actions

github-actions Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Deploy preview for adp-cost-calculator ready!

Project:adp-cost-calculator
Status: ✅  Deploy successful!
Preview URL:https://adp-cost-calculator-5rs479dtz-remotecom.vercel.app
Latest Commit:0a423f6

Deployed with vercel-action

@github-actions

github-actions Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

📊 Coverage Report

✅ Coverage increased! 🎉

Metric Current Previous Change Status
Lines 90.38% 90.38% 0% ⚪
Statements 90.27% 90.26% +0.02% 🟢
Functions 89.34% 89.29% +0.05% 🟢
Branches 82.04% 82.01% +0.03% 🟢

Detailed Breakdown

Lines Coverage
  • Covered: 5903 / 6531
  • Coverage: 90.38%
  • Change: 0% (15 lines)
Statements Coverage
  • Covered: 5978 / 6622
  • Coverage: 90.27%
  • Change: +0.02% (20 statements)
Functions Coverage
  • Covered: 1575 / 1763
  • Coverage: 89.34%
  • Change: +0.05% (8 functions)
Branches Coverage
  • Covered: 3650 / 4449
  • Coverage: 82.04%
  • Change: +0.03% (-1 branches)

✅ Coverage check passed

…options

# Conflicts:
#	src/common/invoice-schedules/api.ts
The invoice schedule helpers moved to domains/invoice-schedule, so the query options import them from there. The preview payload builder is only used inside core, so it is no longer exported from the package entry.
Add `withClient` and `createClientMutation` so a core options factory becomes a
hook in one line. The mutation hook also returns `mutateAsyncOrThrow`, memoized
on the stable `mutate`, so flow hooks no longer wrap each mutation themselves.

Move the response unwrapping and the "editable schedule" status rule into core
selectors next to the queries they read, and use them from the invoice schedule
and contractor currencies hooks.
@gabrielseco
gabrielseco marked this pull request as ready for review November 6, 2026 12:16

This branch has not been deployed

No deployments
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