Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
68 changes: 34 additions & 34 deletions .reports/embedded-react-sdk.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,62 +4,62 @@

```ts

import { AfterErrorContext } from '@gusto/embedded-api-v-2025-11-15/hooks/types';
import { AfterErrorHook } from '@gusto/embedded-api-v-2025-11-15/hooks/types';
import { AfterSuccessContext } from '@gusto/embedded-api-v-2025-11-15/hooks/types';
import { AfterSuccessHook } from '@gusto/embedded-api-v-2025-11-15/hooks/types';
import { Agencies } from '@gusto/embedded-api-v-2025-11-15/models/components/childsupportdata';
import { AfterErrorContext } from '@gusto/embedded-api-v-2026-02-01/hooks/types';
import { AfterErrorHook } from '@gusto/embedded-api-v-2026-02-01/hooks/types';
import { AfterSuccessContext } from '@gusto/embedded-api-v-2026-02-01/hooks/types';
import { AfterSuccessHook } from '@gusto/embedded-api-v-2026-02-01/hooks/types';
import { Agencies } from '@gusto/embedded-api-v-2026-02-01/models/components/childsupportdata';
import { AnchorHTMLAttributes } from 'react';
import { AriaAttributes } from 'react';
import { BeforeCreateRequestContext } from '@gusto/embedded-api-v-2025-11-15/hooks/types';
import { BeforeCreateRequestHook } from '@gusto/embedded-api-v-2025-11-15/hooks/types';
import { BeforeRequestContext } from '@gusto/embedded-api-v-2025-11-15/hooks/types';
import { BeforeRequestHook } from '@gusto/embedded-api-v-2025-11-15/hooks/types';
import { BeforeCreateRequestContext } from '@gusto/embedded-api-v-2026-02-01/hooks/types';
import { BeforeCreateRequestHook } from '@gusto/embedded-api-v-2026-02-01/hooks/types';
import { BeforeRequestContext } from '@gusto/embedded-api-v-2026-02-01/hooks/types';
import { BeforeRequestHook } from '@gusto/embedded-api-v-2026-02-01/hooks/types';
import { ButtonHTMLAttributes } from 'react';
import { Compensation } from '@gusto/embedded-api-v-2025-11-15/models/components/compensation';
import { Compensation } from '@gusto/embedded-api-v-2026-02-01/models/components/compensation';
import { ComponentType } from 'react';
import { ContractorAddress } from '@gusto/embedded-api-v-2025-11-15/models/components/contractoraddress';
import { ContractorAddress } from '@gusto/embedded-api-v-2026-02-01/models/components/contractoraddress';
import { Control } from 'react-hook-form';
import { CustomTypeOptions } from 'i18next';
import { default as default_2 } from 'react';
import { Employee } from '@gusto/embedded-api-v-2025-11-15/models/components/employee';
import { EmployeeAddress } from '@gusto/embedded-api-v-2025-11-15/models/components/employeeaddress';
import { EmployeeBankAccount } from '@gusto/embedded-api-v-2025-11-15/models/components/employeebankaccount';
import { EmployeeFederalTax } from '@gusto/embedded-api-v-2025-11-15/models/components/employeefederaltax';
import { EmployeeOnboardingStatus as EmployeeOnboardingStatus_2 } from '@gusto/embedded-api-v-2025-11-15/models/components/employeeonboardingstatus';
import { EmployeePaymentMethod } from '@gusto/embedded-api-v-2025-11-15/models/components/employeepaymentmethod';
import { EmployeeStateTaxesList } from '@gusto/embedded-api-v-2025-11-15/models/components/employeestatetaxeslist';
import { EmployeeStateTaxQuestion } from '@gusto/embedded-api-v-2025-11-15/models/components/employeestatetaxquestion';
import { EmployeeWorkAddress } from '@gusto/embedded-api-v-2025-11-15/models/components/employeeworkaddress';
import { Employee } from '@gusto/embedded-api-v-2026-02-01/models/components/employee';
import { EmployeeAddress } from '@gusto/embedded-api-v-2026-02-01/models/components/employeeaddress';
import { EmployeeBankAccount } from '@gusto/embedded-api-v-2026-02-01/models/components/employeebankaccount';
import { EmployeeFederalTax } from '@gusto/embedded-api-v-2026-02-01/models/components/employeefederaltax';
import { EmployeeOnboardingStatus as EmployeeOnboardingStatus_2 } from '@gusto/embedded-api-v-2026-02-01/models/components/employeeonboardingstatus';
import { EmployeePaymentMethod } from '@gusto/embedded-api-v-2026-02-01/models/components/employeepaymentmethod';
import { EmployeeStateTaxesList } from '@gusto/embedded-api-v-2026-02-01/models/components/employeestatetaxeslist';
import { EmployeeStateTaxQuestion } from '@gusto/embedded-api-v-2026-02-01/models/components/employeestatetaxquestion';
import { EmployeeWorkAddress } from '@gusto/embedded-api-v-2026-02-01/models/components/employeeworkaddress';
import { FallbackProps } from 'react-error-boundary';
import { FieldsetHTMLAttributes } from 'react';
import { FieldValues } from 'react-hook-form';
import { FlsaStatusType } from '@gusto/embedded-api-v-2025-11-15/models/components/flsastatustype';
import { FlsaStatusType } from '@gusto/embedded-api-v-2026-02-01/models/components/flsastatustype';
import { FocusEvent as FocusEvent_2 } from 'react';
import { Form } from '@gusto/embedded-api-v-2025-11-15/models/components/form';
import { Form } from '@gusto/embedded-api-v-2026-02-01/models/components/form';
import { FunctionComponent } from 'react';
import { Garnishment } from '@gusto/embedded-api-v-2025-11-15/models/components/garnishment';
import { GarnishmentType } from '@gusto/embedded-api-v-2025-11-15/models/components/garnishment';
import { Garnishment } from '@gusto/embedded-api-v-2026-02-01/models/components/garnishment';
import { GarnishmentType } from '@gusto/embedded-api-v-2026-02-01/models/components/garnishment';
import { HTMLAttributes } from 'react';
import { InputHTMLAttributes } from 'react';
import { Job } from '@gusto/embedded-api-v-2025-11-15/models/components/job';
import { Job } from '@gusto/embedded-api-v-2026-02-01/models/components/job';
import { JSX } from 'react';
import { JSXElementConstructor } from 'react';
import { Location as Location_2 } from '@gusto/embedded-api-v-2025-11-15/models/components/location';
import { MinimumWage } from '@gusto/embedded-api-v-2025-11-15/models/components/minimumwage';
import { PaymentPeriod } from '@gusto/embedded-api-v-2025-11-15/models/components/garnishmentchildsupport';
import { PaymentUnit } from '@gusto/embedded-api-v-2025-11-15/models/components/compensation';
import { PayrollPayPeriodType } from '@gusto/embedded-api-v-2025-11-15/models/components/payrollpayperiodtype';
import { PaySchedulePreviewPayPeriod } from '@gusto/embedded-api-v-2025-11-15/models/components/payschedulepreviewpayperiod';
import { PayScheduleShow } from '@gusto/embedded-api-v-2025-11-15/models/components/payscheduleshow';
import { PolicyType as PolicyType_2 } from '@gusto/embedded-api-v-2025-11-15/models/components/timeoffpolicy';
import { Location as Location_2 } from '@gusto/embedded-api-v-2026-02-01/models/components/location';
import { MinimumWage } from '@gusto/embedded-api-v-2026-02-01/models/components/minimumwage';
import { PaymentPeriod } from '@gusto/embedded-api-v-2026-02-01/models/components/garnishmentchildsupport';
import { PaymentUnit } from '@gusto/embedded-api-v-2026-02-01/models/components/compensation';
import { PayrollPayPeriodType } from '@gusto/embedded-api-v-2026-02-01/models/components/payrollpayperiodtype';
import { PaySchedulePreviewPayPeriod } from '@gusto/embedded-api-v-2026-02-01/models/components/payschedulepreviewpayperiod';
import { PayScheduleShow } from '@gusto/embedded-api-v-2026-02-01/models/components/payscheduleshow';
import { PolicyType as PolicyType_2 } from '@gusto/embedded-api-v-2026-02-01/models/components/timeoffpolicy';
import { QueryClient } from '@tanstack/react-query';
import { ReactElement } from 'react';
import { ReactNode } from 'react';
import { Ref } from 'react';
import { RefObject } from 'react';
import { SelectHTMLAttributes } from 'react';
import { Signatory } from '@gusto/embedded-api-v-2025-11-15/models/components/signatory';
import { Signatory } from '@gusto/embedded-api-v-2026-02-01/models/components/signatory';
import { SyntheticEvent } from 'react';
import { TableHTMLAttributes } from 'react';
import { TextareaHTMLAttributes } from 'react';
Expand Down
26 changes: 13 additions & 13 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ npm run sdk-app # Dev build with HMR

Or for a production SDK build:

```
```bash
npm run sdk-app-prod # Production build (uses built dist/)
```

Expand Down Expand Up @@ -64,7 +64,7 @@ Use Field components from `src/components/Common/Fields/` inside `FormProvider`.

### Component Organization

```
```text
src/components/
├── Common/ # Shared UI primitives and Field components
│ ├── Fields/ # Form-connected Field components (use for forms)
Expand All @@ -76,33 +76,33 @@ src/components/
└── Flow/ # Multi-step flow orchestration
```

### API Layer (`@gusto/embedded-api-v-2025-11-15`)
### API Layer (`@gusto/embedded-api-v-2026-02-01`)

All API calls go through `@gusto/embedded-api-v-2025-11-15` with React Query hooks and Zod schema validation.
All API calls go through `@gusto/embedded-api-v-2026-02-01` with React Query hooks and Zod schema validation.

Import paths:

- `@gusto/embedded-api-v-2025-11-15/react-query/<operation>` — React Query hooks
- `@gusto/embedded-api-v-2025-11-15/models/components/<name>` — Entity types
- `@gusto/embedded-api-v-2025-11-15/models/operations/<name>` — Request/response types
- `@gusto/embedded-api-v-2025-11-15/models/errors/<name>` — Error types
- `@gusto/embedded-api-v-2026-02-01/react-query/<operation>` — React Query hooks
- `@gusto/embedded-api-v-2026-02-01/models/components/<name>` — Entity types
- `@gusto/embedded-api-v-2026-02-01/models/operations/<name>` — Request/response types
- `@gusto/embedded-api-v-2026-02-01/models/errors/<name>` — Error types

Hook naming: `use<Resource><Action>Suspense` (queries), `use<Resource><Action>Mutation` (mutations)

#### Auto-invalidation on mutation success

The `QueryClient` produced by `createSdkQueryClient` (in `src/contexts/ApiProvider/createSdkQueryClient.ts`) sets a global mutation default: on any successful mutation under the `['@gusto/embedded-api-v-2025-11-15']` key, it invalidates **every** SDK query. Both `ApiProvider` (production) and `GustoTestProvider` (tests) use this factory, so the behavior is identical in both environments.
The `QueryClient` produced by `createSdkQueryClient` (in `src/contexts/ApiProvider/createSdkQueryClient.ts`) sets a global mutation default: on any successful mutation under the `['@gusto/embedded-api-v-2026-02-01']` key, it invalidates **every** SDK query. Both `ApiProvider` (production) and `GustoTestProvider` (tests) use this factory, so the behavior is identical in both environments.

Implications when writing SDK code:

- **Do not call `queryClient.invalidateQueries(...)` after a successful `@gusto/embedded-api-v-2025-11-15` mutation.** It's redundant — the global `onSuccess` already invalidated the entire SDK namespace. Just `await mutateAsync(...)` and the next render's queries refetch automatically.
- **Do not call `queryClient.invalidateQueries(...)` after a successful `@gusto/embedded-api-v-2026-02-01` mutation.** It's redundant — the global `onSuccess` already invalidated the entire SDK namespace. Just `await mutateAsync(...)` and the next render's queries refetch automatically.
- This is why `usePaymentMethodList`, `useEmployeeCompensation`, etc. don't manually invalidate after their delete/update mutations.
- If a partner brings their own `QueryClient` to `ApiProvider`, the defaults are **not** applied to it — they're responsible for matching the contract if they want this behavior. Don't paper over that with manual invalidation in hooks; treat it as their responsibility.
- If you need to invalidate _more narrowly_ (e.g. you only want one query to refetch, not the whole namespace), that's a code smell — most likely the global invalidate is already doing what you want.

### Provider Stack

```
```text
GustoProvider → ComponentsProvider → ThemeProvider → LocaleProvider / I18nextProvider → ApiProvider → {children}
```

Expand All @@ -112,7 +112,7 @@ All user-facing text uses i18next. Run `npm run i18n:generate` after changing tr

### Partner hooks (`composeErrorHandler` / `composeSubmitHandler`)

Exported headless hooks build `errorHandling` with **`composeErrorHandler`** (not a React hook). For multi-form screens, **`composeSubmitHandler`** coordinates validation + ordered submits and returns `{ handleSubmit, errorHandling }` aggregated across those forms. The result plugs back into `composeErrorHandler` when partners need extra `@gusto/embedded-api-v-2025-11-15` queries or screen-level submit state in the same error surface — see [docs/hooks/hooks.md](docs/hooks/hooks.md).
Exported headless hooks build `errorHandling` with **`composeErrorHandler`** (not a React hook). For multi-form screens, **`composeSubmitHandler`** coordinates validation + ordered submits and returns `{ handleSubmit, errorHandling }` aggregated across those forms. The result plugs back into `composeErrorHandler` when partners need extra `@gusto/embedded-api-v-2026-02-01` queries or screen-level submit state in the same error surface — see [docs/hooks/hooks.md](docs/hooks/hooks.md).

### Component & Feature Conventions

Expand All @@ -136,7 +136,7 @@ Durable conventions that apply SDK-wide to any component or feature:

Three-repo architecture with sibling directories:

```
```text
~/workspace/
├── zenpayroll/ # Core Rails app
├── gws-flows/ # Rails API proxy for local SDK testing
Expand Down
18 changes: 9 additions & 9 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,26 +78,26 @@ src/components/
└── Flow/ # Multi-step flow orchestration
```

### API Layer (`@gusto/embedded-api-v-2025-11-15`)
### API Layer (`@gusto/embedded-api-v-2026-02-01`)

All API calls go through `@gusto/embedded-api-v-2025-11-15` with React Query hooks and Zod schema validation.
All API calls go through `@gusto/embedded-api-v-2026-02-01` with React Query hooks and Zod schema validation.

Import paths:

- `@gusto/embedded-api-v-2025-11-15/react-query/<operation>` — React Query hooks
- `@gusto/embedded-api-v-2025-11-15/models/components/<name>` — Entity types
- `@gusto/embedded-api-v-2025-11-15/models/operations/<name>` — Request/response types
- `@gusto/embedded-api-v-2025-11-15/models/errors/<name>` — Error types
- `@gusto/embedded-api-v-2026-02-01/react-query/<operation>` — React Query hooks
- `@gusto/embedded-api-v-2026-02-01/models/components/<name>` — Entity types
- `@gusto/embedded-api-v-2026-02-01/models/operations/<name>` — Request/response types
- `@gusto/embedded-api-v-2026-02-01/models/errors/<name>` — Error types

Hook naming: `use<Resource><Action>Suspense` (queries), `use<Resource><Action>Mutation` (mutations)

#### Auto-invalidation on mutation success

The `QueryClient` produced by `createSdkQueryClient` (in `src/contexts/ApiProvider/createSdkQueryClient.ts`) sets a global mutation default: on any successful mutation under the `['@gusto/embedded-api-v-2025-11-15']` key, it invalidates **every** SDK query. Both `ApiProvider` (production) and `GustoTestProvider` (tests) use this factory, so the behavior is identical in both environments.
The `QueryClient` produced by `createSdkQueryClient` (in `src/contexts/ApiProvider/createSdkQueryClient.ts`) sets a global mutation default: on any successful mutation under the `['@gusto/embedded-api-v-2026-02-01']` key, it invalidates **every** SDK query. Both `ApiProvider` (production) and `GustoTestProvider` (tests) use this factory, so the behavior is identical in both environments.

Implications when writing SDK code:

- **Do not call `queryClient.invalidateQueries(...)` after a successful `@gusto/embedded-api-v-2025-11-15` mutation.** It's redundant — the global `onSuccess` already invalidated the entire SDK namespace. Just `await mutateAsync(...)` and the next render's queries refetch automatically.
- **Do not call `queryClient.invalidateQueries(...)` after a successful `@gusto/embedded-api-v-2026-02-01` mutation.** It's redundant — the global `onSuccess` already invalidated the entire SDK namespace. Just `await mutateAsync(...)` and the next render's queries refetch automatically.
- This is why `usePaymentMethodList`, `useEmployeeCompensation`, etc. don't manually invalidate after their delete/update mutations.
- If a partner brings their own `QueryClient` to `ApiProvider`, the defaults are **not** applied to it — they're responsible for matching the contract if they want this behavior. Don't paper over that with manual invalidation in hooks; treat it as their responsibility.
- If you need to invalidate _more narrowly_ (e.g. you only want one query to refetch, not the whole namespace), that's a code smell — most likely the global invalidate is already doing what you want.
Expand All @@ -114,7 +114,7 @@ All user-facing text uses i18next. Run `npm run i18n:generate` after changing tr

### Partner hooks (`composeErrorHandler` / `composeSubmitHandler`)

Exported headless hooks build `errorHandling` with **`composeErrorHandler`** (not a React hook). For multi-form screens, **`composeSubmitHandler`** coordinates validation + ordered submits and returns `{ handleSubmit, errorHandling }` aggregated across those forms. The result plugs back into `composeErrorHandler` when partners need extra `@gusto/embedded-api-v-2025-11-15` queries or screen-level submit state in the same error surface — see [docs/hooks/hooks.md](docs/hooks/hooks.md).
Exported headless hooks build `errorHandling` with **`composeErrorHandler`** (not a React hook). For multi-form screens, **`composeSubmitHandler`** coordinates validation + ordered submits and returns `{ handleSubmit, errorHandling }` aggregated across those forms. The result plugs back into `composeErrorHandler` when partners need extra `@gusto/embedded-api-v-2026-02-01` queries or screen-level submit state in the same error surface — see [docs/hooks/hooks.md](docs/hooks/hooks.md).

### Component & Feature Conventions

Expand Down
Loading
Loading